metasm/os/windows.rb in metasm-1.0.2 vs metasm/os/windows.rb in metasm-1.0.3

- old
+ new

@@ -1230,28 +1230,37 @@ def debugger @debugger ||= WinDebugger.new(@pid) end attr_writer :debugger - # returns the memory address size of the target process - def addrsz - @addrsz ||= if WinAPI.respond_to?(:iswow64process) + # return 32 for 32bit process, 64 for 64bit process + # populates iswow64 + def cpusz + @cpusz ||= ( byte = 0.chr*8 - if WinAPI.iswow64process(handle, byte) + if WinAPI.respond_to?(:iswow64process) and WinAPI.iswow64process(handle, byte) + # os supports iswow64process, so target may be 64bits if byte != 0.chr*8 - 32 # target = wow64 - elsif WinAPI.iswow64process(WinAPI.getcurrentprocess, byte) and byte != 0.chr*8 - 64 # us = wow64, target is not + @iswow64 = true + 32 else + @iswow64 = false WinAPI.host_cpu.size end else WinAPI.host_cpu.size end - end + ) end + attr_accessor :iswow64 + # returns the memory address size of the target process + # if the target is a wow64 process (32bit process under a 64bit os), return 64 + def addrsz + @addrsz ||= ((cpusz == 32 and iswow64) ? 64 : cpusz) + end + def modules WinOS.list_modules(@pid) end def threads @@ -1361,11 +1370,11 @@ end attr_writer :teb_base # increment the suspend count of the target thread - stop at >0 def suspend - if WinAPI.host_cpu.size == 64 and process and process.addrsz == 32 + if WinAPI.host_cpu.size == 64 and process and process.iswow64 WinAPI.wow64suspendthread(handle) else WinAPI.suspendthread(handle) end end @@ -1398,30 +1407,24 @@ attr_writer :context class Context def initialize(thread, kind=:all) @handle = thread.handle - tg = (thread.process ? thread.process.addrsz : 32) - hcpu = WinAPI.host_cpu.shortname - case hcpu - when 'ia32', 'x64' - else raise "unsupported architecture #{tg}" - end - + tg = (thread.process ? thread.process.cpusz : 32) @getcontext = :getthreadcontext @setcontext = :setthreadcontext - case tg - when 32 + if tg == 32 + # XXX check CS under wow64 ? @context = WinAPI.alloc_c_struct('_CONTEXT_I386') - @context.contextflags = WinAPI::CONTEXT_I386_ALL - if hcpu == 'x64' + @context.contextflags = WinAPI::CONTEXT_I386_ALL # XXX kind ? + if WinAPI.host_cpu.shortname == 'x64' and thread.process and thread.process.iswow64 @getcontext = :wow64getthreadcontext @setcontext = :wow64setthreadcontext end - when 64 + else @context = WinAPI.alloc_c_struct('_CONTEXT_AMD64') - @context.contextflags = WinAPI::CONTEXT_AMD64_ALL + @context.contextflags = WinAPI::CONTEXT_AMD64_ALL # XXX kind ? end end # retrieve the actual context structure (so we can pass to API's like StackWalk64) def c_struct @@ -1803,10 +1806,10 @@ def initialize_cpu # wait until we receive the CREATE_PROCESS_DBGEVT message return if not @os_process case WinAPI.host_cpu.shortname when 'ia32', 'x64' - @cpu = Ia32.new(os_process.addrsz) + @cpu = Ia32.new(os_process.cpusz) else raise 'unsupported architecture' end end