class Metasm::WinOS::Thread::Context

Public Class Methods

new(thread, kind=:all) click to toggle source
# File metasm/os/windows.rb, line 1401
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

        @getcontext = :getthreadcontext
        @setcontext = :setthreadcontext
        case tg
        when 32
                @context = WinAPI.alloc_c_struct('_CONTEXT_I386')
                @context.contextflags = WinAPI::CONTEXT_I386_ALL
                if hcpu == 'x64'
                        @getcontext = :wow64getthreadcontext
                        @setcontext = :wow64setthreadcontext
                end
        when 64
                @context = WinAPI.alloc_c_struct('_CONTEXT_AMD64')
                @context.contextflags = WinAPI::CONTEXT_AMD64_ALL
        end
end

Public Instance Methods

[](k) click to toggle source
# File metasm/os/windows.rb, line 1437
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 1458
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 1427
def c_struct
        @context
end
method_missing(m, *a) click to toggle source
Calls superclass method
# File metasm/os/windows.rb, line 1480
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 1433
def update
        WinAPI.send(@getcontext, @handle, @context)
end