this is the class you have to define to hook
setup() defines the list of hooks as an array of hashes for exported functions, simply use :function => function name for arbitrary hook, :module => 'module.dll', :rva => 0x1234, :hookname => 'myhook' (call pre_myhook/post_myhook) :abi can be :stdcall (windows standard export), :fastcall or :thiscall, leave empty for cdecl if pre_<function> is defined, it is called whenever the function is entered, via a bpx (int3) if post_<function> is defined, it is called whenever the function exists, with a bpx on the return address setup at func entry the pre_hook receives all arguments to the original function
change them with patch_arg(argnr, newval) read memory with @dbg.memory_read_int(ptr), or @dbg.memory[ptr, length] skip the function call with finish(fake_retval) (!) needs a correct :abi & param count !
the post_hook receives the function return value
change it with patch_ret(newval)
# File samples/dbg-apihook.rb, line 201 def init_prerun puts "hooks ready, save a file in notepad" end
# File samples/dbg-apihook.rb, line 219 def post_WriteFile(retval, arglistcopy) # we can patch the API return value with this #patch_retval(42) # finish messing with the args: fake the nrofbyteswritten #handle, pbuf, size, pwritten, overlap = arglistcopy size, pwritten = arglistcopy.values_at(2, 3) written = @dbg.memory_read_int(pwritten) if written == size # if written everything, patch the value so that the program dont detect our intervention @dbg.memory_write_int(pwritten, written+2) end puts "write retval: #{retval}, written: #{written} bytes" end
# File samples/dbg-apihook.rb, line 205 def pre_WriteFile(handle, pbuf, size, pwritten, overlap) # we can skip the function call with this #finish(28) # spy on the api / trace calls bufdata = @dbg.memory[pbuf, size] puts "writing #{bufdata.inspect}" # but we can also mess with the args # ex: skip first 2 bytes of the buffer patch_arg(1, pbuf+2) patch_arg(2, size-2) end
# File samples/dbg-apihook.rb, line 197 def setup [{ :function => 'WriteFile', :abi => :stdcall }] end