samples/dbg-apihook.rb in metasm-1.0.1 vs samples/dbg-apihook.rb in metasm-1.0.2
- old
+ new
@@ -15,10 +15,12 @@
#
require 'metasm'
class ApiHook
+ attr_accessor :dbg
+
# rewrite this function to list the hooks you want
# return an array of hashes
def setup
#[{ :function => 'WriteFile', :abi => :stdcall }, # standard function hook
# { :module => 'Foo.dll', :rva => 0x2433, # arbitrary code hook
@@ -31,34 +33,47 @@
if not dbg.kind_of? Metasm::Debugger
process = Metasm::OS.current.find_process(dbg)
raise 'no such process' if not process
dbg = process.debugger
end
- dbg.loadallsyms
@dbg = dbg
- setup.each { |h| setup_hook(h) }
- init_prerun if respond_to?(:init_prerun) # allow subclass to do stuff before main loop
- @dbg.run_forever
+ begin
+ setup.each { |h| setup_hook(h) }
+ init_prerun if respond_to?(:init_prerun) # allow subclass to do stuff before main loop
+ @dbg.run_forever
+ rescue Interrupt
+ @dbg.detach #rescue nil
+ end
end
# setup one function hook
def setup_hook(h)
+ @las ||= false
+ if not h[:lib] and not @las
+ @dbg.loadallsyms
+ @las = false
+ elsif h[:lib]
+ # avoid loadallsyms if specified (regexp against pathname, not exported lib name)
+ @dbg.loadsyms(h[:lib])
+ end
+
pre = "pre_#{h[:hookname] || h[:function]}"
post = "post_#{h[:hookname] || h[:function]}"
- @nargs = h[:nargs] || method(pre).arity if respond_to?(pre)
+ nargs = h[:nargs] || method(pre).arity if respond_to?(pre)
if target = h[:address]
elsif target = h[:rva]
modbase = @dbg.modulemap[h[:module]]
raise "cant find module #{h[:module]} in #{@dbg.modulemap.join(', ')}" if not modbase
target += modbase[0]
else
target = h[:function]
end
- @dbg.bpx(target) {
+ @dbg.bpx(target, false, h[:condition]) {
+ @nargs = nargs
catch(:finish) {
@cur_abi = h[:abi]
@ret_longlong = h[:ret_longlong]
if respond_to? pre
args = read_arglist
@@ -204,22 +219,22 @@
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
+ #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
end
-# name says it all
-Metasm::WinOS.get_debug_privilege
+Metasm::OS.current.get_debug_privilege if Metasm::OS.current.respond_to? :get_debug_privilege
# run our Hook engine on a running 'notepad' instance
MyHook.new('notepad')
# the script ends when notepad exits