class Metasm::WinOS::Thread::Context

Public Class Methods

new(thread, kind=:all) click to toggle source
# 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

Public Instance Methods

[](k) click to toggle source
# File metasm/os/windows.rb, line 1440
def [](k)
        case k.to_s
        when /^[cdefgs]s$/i
                @context["seg#{k}"]
        when /^st(\d?)$/i
                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+)$/i
                v = @context['xmm'][$1.to_i]
                (v.hi << 64) | v.lo
        when /^mmx?(\d)$/i
                # XXX probably in st(0/7)
                @context['xmm'][$1.to_i].lo
        else
                @context[k]
        end
end
[]=(k, v) click to toggle source
# File metasm/os/windows.rb, line 1461
def []=(k, v)
        case k.to_s
        when /^[cdefgs]s$/i
                @context["seg#{k}"] = v
        when /^st(\d?)$/i
                # 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+)$/i
                kk = @context['xmm'][$1.to_i]
                kk.lo = v & ((1<<64)-1)
                kk.hi = (v>>64) & ((1<<64)-1)
        when /^mmx?(\d)$/i
                # XXX st(7-$1) ?
                @context['xmm'][$1.to_i].lo = v
        else
                @context[k] = v
        end
        WinAPI.send(@setcontext, @handle, @context)
end
c_struct() click to toggle source

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
method_missing(m, *a) click to toggle source
Calls superclass method
# 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() click to toggle source

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