# File metasm/os/windows.rb, line 1410 def initialize(thread, kind=:all) @handle = thread.handle tg = (thread.process ? thread.process.cpusz : 32) @getcontext = :getthreadcontext @setcontext = :setthreadcontext if tg == 32 # XXX check CS under wow64 ? @context = WinAPI.alloc_c_struct('_CONTEXT_I386') @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 else @context = WinAPI.alloc_c_struct('_CONTEXT_AMD64') @context.contextflags = WinAPI::CONTEXT_AMD64_ALL # XXX kind ? end end
# File metasm/os/windows.rb, line 1440 def [](k) case k.to_s when /^[cdefgs]s$/ @context["seg#{k}"] when /^st(\d?)$/ v = @context['st'][$1.to_i] buf = v.str[v.stroff, 10] # TODO check this, 'D' is 8byte wide buf.unpack('D')[0] # TODO when /^ymm(\d+)$/i when /^xmm(\d+)$/ v = @context['xmm'][$1.to_i] (v.hi << 64) | v.lo when /^mmx?(\d)$/ # XXX probably in st(0/7) @context['xmm'][$1.to_i].lo else @context[k] end end
# File metasm/os/windows.rb, line 1461 def []=(k, v) case k.to_s when /^[cdefgs]s$/ @context["seg#{k}"] = v when /^st(\d?)$/ # TODO check this, 'D' is 8byte wide buf = [v, 0, 0].pack('DCC') @context['st'][$1.to_i][0, 10] = buf # TODO when /^ymm(\d+)$/i when /^xmm(\d+)$/ kk = @context['xmm'][$1.to_i] kk.lo = v & ((1<<64)-1) kk.hi = (v>>64) & ((1<<64)-1) when /^mmx?(\d)$/ # XXX st(7-$1) ? @context['xmm'][$1.to_i].lo = v else @context[k] = v end WinAPI.send(@setcontext, @handle, @context) end
retrieve the actual context structure (so we can pass to API's like StackWalk64)
# File metasm/os/windows.rb, line 1430 def c_struct @context end
# File metasm/os/windows.rb, line 1483 def method_missing(m, *a) if m.to_s[-1] == = return super(m, *a) if a.length != 1 send '[]=', m.to_s[0...-1], a[0] else return super(m, *a) if a.length != 0 send '[]', m end end
update the context to reflect the current thread reg values call only when the thread is suspended
# File metasm/os/windows.rb, line 1436 def update WinAPI.send(@getcontext, @handle, @context) end