Page 1 of 1

Ranged Nop

Posted: Sat Jan 01, 2022 12:17 pm
by Frouk
This is a function that allows to make ranged nop,let's say you need to clean up game code,for example from 0x493A27 to 0x493A4B but the size is 36 and you will be lazy to type db 36 times(cleaning game code can be used when you inject your code/bytes/asm into game & you don't wanna to mess with memory when injecting code),
So here's function:

Code: Select all

function MakeRangedNop(addr,addrTo)
    local size
    if addr == nil then
        return
    end
    addr = getAddress(addr)
    if addrTo == nil then
        size = getInstructionSize(addr)
    else
        addrTo = getAddress(addrTo)
        size = -(addr - addrTo) - 1
    end
    for i = 0,size do
        writeBytes(addr+i,0x90)
    end
end
To use the function type:

Code: Select all

MakeRangedNop(0x493A04,0x493A0B) --Those two addresses are examples,you can replace them and nop will execute from 0x493A04 to 0x493A0A
Function execution will be looking like this:
Before wrote: 0x493A04: A0 C8E6A900 mov al,[00A9E6C8]
0x493A09: 84 C0 test al,al
After wrote: 0x493A04: 90 nop
0x493A05: 90 nop
0x493A06: 90 nop
0x493A07: 90 nop
0x493A08: 90 nop
0x493A09: 90 nop
0x493A0A: 90 nop
Another variant of function(two functions):

Code: Select all

function MakeRangedNop(addr,addrTo)
    local size
    if addr == nil then
      return
    end
    addr = getAddress(addr)
    addrTo = getAddress(addrTo)
    if addrTo == nil then
       size = getInstructionSize(addr)
    else
        size = -(addr - addrTo)
    end
    MakeNop(addr,size)
end

function MakeNop(addr,size)
    if addr == nil then
      return
    end
    if size == 0 then
      return
    end
    addr = getAddress(addr)
    if size == nil then
       size = getInstructionSize(addr)
    end
    size = size - 1
    for i = 0,size do
      writeBytes(addr+i,0x90)
    end
end

Re: Ranged Nop

Posted: Sat Jan 01, 2022 1:15 pm
by ShyTwig16
Might I suggest making the second parameter optional, and if no size/range is given it defaults to a single instruction and so you use getInstructionSize inside the function to determine size/range.

Also you should always format your code, having everything on a single indent tends to look very messy.
For example something like this is almost unreadable:

Code: Select all

local function compile(template, environmentOrLoadLocalEnv, loadLocalEnv)
---- Turn the template into a string that can be run though Lua. 
---- 	Builder will be used to efficiently build the string we'll run. 
---- 	The string will use it's own builder (_ret). Each part that comprises 
---- 	_ret will be the various pieces of the template. Strings, variables 
---- 	that should be printed and functions that should be run.
if not template or template == '' then return '' end
local env = { }
if type(environmentOrLoadLocalEnv) == 'table' then
env = environmentOrLoadLocalEnv
elseif type(environmentOrLoadLocalEnv) == 'boolean' then
loadLocalEnv = environmentOrLoadLocalEnv
end
env.__index = env
setmetatable(env, { __index = _G })
if loadLocalEnv then
local i = 1
while true do
local name, value = debug.getlocal(2, i)
if not name then break end
env[name] = value
i = i + 1
end
end
local builder = { '_ret = {}\n' }
local pos = 1
local b
local func
local err
while pos < #template do
---- Look for start of a Lua block.
b = template:find('<[<%%]', pos)
if not b then
break
end
---- Check if this is a block or escaped <.
if template:sub(b-1, b-1) == '\\' then
appender(builder, template:sub(pos, b-2))
appender(builder, '<')
pos = b+1
else
---- Add all text up until this block.
appender(builder, template:sub(pos, b-1))
---- Find the end of the block.
pos = template:find('[>%%]>', b)
if not pos then
appender(builder, 'End tag missing')
break
end
runBlock(builder, template:sub(b, pos+2))
---- Skip back the >> (pos points to the start of >>).
pos = pos+2
end
end
---- Add any text after the last block. Or all of it if there
---- are no blocks.
if pos then
appender(builder, template:sub(pos, #template))
end
builder[#builder+1] = 'return table.concat(_ret)'
---- Run the Lua code we built though Lua and get the result.
func, err = load(table.concat(builder, '\n'), 'template', 't', env)
if not func then
return nil, err
end
return func()
end
Where as this is a lot easier to read:

Code: Select all

local function compile(template, environmentOrLoadLocalEnv, loadLocalEnv)
	---- Turn the template into a string that can be run though Lua. 
	---- 	Builder will be used to efficiently build the string we'll run. 
	---- 	The string will use it's own builder (_ret). Each part that comprises 
	---- 	_ret will be the various pieces of the template. Strings, variables 
	---- 	that should be printed and functions that should be run.
	if not template or template == '' then return '' end
	local env = { }
	if type(environmentOrLoadLocalEnv) == 'table' then
		env = environmentOrLoadLocalEnv
	elseif type(environmentOrLoadLocalEnv) == 'boolean' then
		loadLocalEnv = environmentOrLoadLocalEnv
	end
	env.__index = env
	setmetatable(env, { __index = _G })
	if loadLocalEnv then
		local i = 1
		while true do
			local name, value = debug.getlocal(2, i)
			if not name then break end
			env[name] = value
			i = i + 1
		end
	end
	local builder = { '_ret = {}\n' }
	local pos = 1
	local b
	local func
	local err
	while pos < #template do
		---- Look for start of a Lua block.
		b = template:find('<[<%%]', pos)
		if not b then
			break
		end
		---- Check if this is a block or escaped <.
		if template:sub(b-1, b-1) == '\\' then
			appender(builder, template:sub(pos, b-2))
			appender(builder, '<')
			pos = b+1
		else
			---- Add all text up until this block.
			appender(builder, template:sub(pos, b-1))
			---- Find the end of the block.
			pos = template:find('[>%%]>', b)
			if not pos then
				appender(builder, 'End tag missing')
				break
			end
			runBlock(builder, template:sub(b, pos+2))
			---- Skip back the >> (pos points to the start of >>).
			pos = pos+2
		end
	end
	---- Add any text after the last block. Or all of it if there
	---- are no blocks.
	if pos then
		appender(builder, template:sub(pos, #template))
	end
	builder[#builder+1] = 'return table.concat(_ret)'
	---- Run the Lua code we built though Lua and get the result.
	func, err = load(table.concat(builder, '\n'), 'template', 't', env)
	if not func then
		return nil, err
	end
	return func()
end

Re: Ranged Nop

Posted: Sat Jan 01, 2022 2:12 pm
by Frouk
ShyTwig16 wrote:
Sat Jan 01, 2022 1:15 pm
Might I suggest making the second parameter optional, and if no size/range is given it defaults to a single instruction and so you use getInstructionSize inside the function to determine size/range.

Also you should always format your code, having everything on a single indent tends to look very messy.
For example something like this is almost unreadable:

Code: Select all

local function compile(template, environmentOrLoadLocalEnv, loadLocalEnv)
---- Turn the template into a string that can be run though Lua. 
---- 	Builder will be used to efficiently build the string we'll run. 
---- 	The string will use it's own builder (_ret). Each part that comprises 
---- 	_ret will be the various pieces of the template. Strings, variables 
---- 	that should be printed and functions that should be run.
if not template or template == '' then return '' end
local env = { }
if type(environmentOrLoadLocalEnv) == 'table' then
env = environmentOrLoadLocalEnv
elseif type(environmentOrLoadLocalEnv) == 'boolean' then
loadLocalEnv = environmentOrLoadLocalEnv
end
env.__index = env
setmetatable(env, { __index = _G })
if loadLocalEnv then
local i = 1
while true do
local name, value = debug.getlocal(2, i)
if not name then break end
env[name] = value
i = i + 1
end
end
local builder = { '_ret = {}\n' }
local pos = 1
local b
local func
local err
while pos < #template do
---- Look for start of a Lua block.
b = template:find('<[<%%]', pos)
if not b then
break
end
---- Check if this is a block or escaped <.
if template:sub(b-1, b-1) == '\\' then
appender(builder, template:sub(pos, b-2))
appender(builder, '<')
pos = b+1
else
---- Add all text up until this block.
appender(builder, template:sub(pos, b-1))
---- Find the end of the block.
pos = template:find('[>%%]>', b)
if not pos then
appender(builder, 'End tag missing')
break
end
runBlock(builder, template:sub(b, pos+2))
---- Skip back the >> (pos points to the start of >>).
pos = pos+2
end
end
---- Add any text after the last block. Or all of it if there
---- are no blocks.
if pos then
appender(builder, template:sub(pos, #template))
end
builder[#builder+1] = 'return table.concat(_ret)'
---- Run the Lua code we built though Lua and get the result.
func, err = load(table.concat(builder, '\n'), 'template', 't', env)
if not func then
return nil, err
end
return func()
end
Where as this is a lot easier to read:

Code: Select all

local function compile(template, environmentOrLoadLocalEnv, loadLocalEnv)
	---- Turn the template into a string that can be run though Lua. 
	---- 	Builder will be used to efficiently build the string we'll run. 
	---- 	The string will use it's own builder (_ret). Each part that comprises 
	---- 	_ret will be the various pieces of the template. Strings, variables 
	---- 	that should be printed and functions that should be run.
	if not template or template == '' then return '' end
	local env = { }
	if type(environmentOrLoadLocalEnv) == 'table' then
		env = environmentOrLoadLocalEnv
	elseif type(environmentOrLoadLocalEnv) == 'boolean' then
		loadLocalEnv = environmentOrLoadLocalEnv
	end
	env.__index = env
	setmetatable(env, { __index = _G })
	if loadLocalEnv then
		local i = 1
		while true do
			local name, value = debug.getlocal(2, i)
			if not name then break end
			env[name] = value
			i = i + 1
		end
	end
	local builder = { '_ret = {}\n' }
	local pos = 1
	local b
	local func
	local err
	while pos < #template do
		---- Look for start of a Lua block.
		b = template:find('<[<%%]', pos)
		if not b then
			break
		end
		---- Check if this is a block or escaped <.
		if template:sub(b-1, b-1) == '\\' then
			appender(builder, template:sub(pos, b-2))
			appender(builder, '<')
			pos = b+1
		else
			---- Add all text up until this block.
			appender(builder, template:sub(pos, b-1))
			---- Find the end of the block.
			pos = template:find('[>%%]>', b)
			if not pos then
				appender(builder, 'End tag missing')
				break
			end
			runBlock(builder, template:sub(b, pos+2))
			---- Skip back the >> (pos points to the start of >>).
			pos = pos+2
		end
	end
	---- Add any text after the last block. Or all of it if there
	---- are no blocks.
	if pos then
		appender(builder, template:sub(pos, #template))
	end
	builder[#builder+1] = 'return table.concat(_ret)'
	---- Run the Lua code we built though Lua and get the result.
	func, err = load(table.concat(builder, '\n'), 'template', 't', env)
	if not func then
		return nil, err
	end
	return func()
end
Ok i'll fix as soon as possible

Re: Ranged Nop

Posted: Tue Jan 11, 2022 12:02 am
by SunBeam
Uhm.. not to burst your bubble.. but we now have "nop <amount>" in auto-assembler :D So:

Code: Select all

addr:
nop 36
..would just do that.

That's IF you know the length.

If you meant it as do_nops between start = known_address_1 and end = known_address_2, then I understand the usefulness of your Lua ;)