class Metasm::PTraceContext_Ia32

Constants

C_STRUCT

Public Class Methods

new(ptrace, pid=ptrace.pid) click to toggle source
Calls superclass method Metasm::PTrace.new
# File metasm/os/linux.rb, line 830
def initialize(ptrace, pid=ptrace.pid)
        super(ptrace, :dup)
        @pid = pid
        @cp = ptrace.cp
        init
end

Public Instance Methods

do_getregs() click to toggle source
# File metasm/os/linux.rb, line 868
def do_getregs
        st = cp.alloc_c_struct('user_regs_struct_ia32')
        getregs(st)
        st
end
do_getxmm() click to toggle source
# File metasm/os/linux.rb, line 878
def do_getxmm
        st = cp.alloc_c_struct('user_fxsr_struct_ia32')
        getfpxregs(st)
        st
end
do_setregs(st=@gpr_st) click to toggle source
# File metasm/os/linux.rb, line 874
def do_setregs(st=@gpr_st)
        setregs(st)
end
do_setxmm(st=@xmm_st) click to toggle source
# File metasm/os/linux.rb, line 884
def do_setxmm(st=@xmm_st)
        setfpxregs(st)
end
get_reg(r) click to toggle source
# File metasm/os/linux.rb, line 888
def get_reg(r)
        r = r.downcase if r == 'ORIG_EAX' or r == 'ORIG_RAX'
        rs = r.to_sym
        if @gpr[rs]
                @gpr_st ||= do_getregs
                @gpr_st[rs]
        elsif o = @gpr_peek[rs]
                peekusr(o)
        elsif o = @gpr_sub[rs]
                v = get_reg(o[0])
                v >>= o[2] if o[2]
                v &= o[1]
        elsif @xmm[rs]
                @xmm_st ||= do_getxmm
                @xmm_st[rs]
        else
                case r.to_s
                when /^st(\d?)$/i
                        i = $1.to_i
                        @xmm_st ||= do_getxmm
                        fu = @xmm_st.st_space
                        [fu[4*i], fu[4*i+1], fu[4*i+2]].pack('L*').unpack('D').first        # XXX
                when /^mmx?(\d)$/i
                        i = $1.to_i
                        @xmm_st ||= do_getxmm
                        fu = @xmm_st.st_space
                        fu[4*i] | (fu[4*i + 1] << 32)
                when /^xmm(\d+)$/i
                        i = $1.to_i
                        @xmm_st ||= do_getxmm
                        fu = @xmm_st.xmm_space
                        fu[4*i] | (fu[4*i + 1] << 32) | (fu[4*i + 2] << 64) | (fu[4*i + 3] << 96)
                # TODO when /^ymm(\d+)$/i
                else raise "unknown register name #{r}"
                end
        end
end
gpr_sub_init() click to toggle source

:bh => [:ebx, 0xff, 8] XXX similar to Reg.symbolic… DRY

# File metasm/os/linux.rb, line 852
def gpr_sub_init
        ret = {}
        %w[a b c d].each { |r|
                b = "e#{r}x".to_sym
                ret["#{r}x".to_sym] = [b, 0xffff]
                ret["#{r}l".to_sym] = [b, 0xff]
                ret["#{r}h".to_sym] = [b, 0xff, 8]
        }
        %w[sp bp si di].each { |r|
                b = "e#{r}".to_sym
                ret[r.to_sym] = [b, 0xffff]
        }
        ret[:orig_rax] = [:orig_eax, 0xffff_ffff]
        ret
end
init() click to toggle source
# File metasm/os/linux.rb, line 837
def init
        @gpr = @@gpr_ia32 ||= [:ebx, :ecx, :edx, :esi, :edi, :ebp, :eax,
                :ds, :es, :fs, :gs, :orig_eax, :eip, :cs, :eflags,
                :esp, :ss].inject({}) { |h, r| h.update r => true }
        @gpr_peek = @@gpr_peek_ia32 ||= (0..7).inject({}) { |h, i|
                h.update "dr#{i}".to_sym => REGS_I386["DR#{i}"] }
        @gpr_sub = @@gpr_sub_ia32 ||= gpr_sub_init
        @xmm = @@xmm_ia32 ||= [:cwd, :swd, :twd, :fop, :fip, :fcs, :foo,
                :fos, :mxcsr].inject({}) { |h, r| h.update r => true }
        @cp.parse C_STRUCT if not @cp.toplevel.struct['user_regs_struct_ia32']
        @gpr_st = @xmm_st = nil
end
set_reg(r, v) click to toggle source
# File metasm/os/linux.rb, line 926
def set_reg(r, v)
        r = r.downcase if r == 'ORIG_EAX' or r == 'ORIG_RAX'
        rs = r.to_sym
        if @gpr[rs]
                @gpr_st ||= do_getregs
                @gpr_st[rs] = v
                do_setregs
        elsif o = @gpr_peek[rs]
                pokeusr(o, v)
        elsif o = @gpr_sub[rs]
                vo = get_reg(o[0])
                msk = o[1]
                v &= o[1]
                if o[2]
                        msk <<= o[2]
                        v <<= o[2]
                end
                v |= vo & ~msk
                set_reg(o[0], v)
        elsif @xmm[rs]
                @xmm_st ||= do_getxmm
                @xmm_st[rs] = v
                do_setxmm
        else
                case r.to_s
                when /^st(\d?)$/i
                        i = $1.to_i
                        @xmm_st ||= do_getxmm
                        fu = @xmm_st.st_space
                        fu[4*i], fu[4*i+1], fu[4*i+2] = [v, -1].pack('DL').unpack('L*')     # XXX
                        do_setxmm
                when /^mmx?(\d)$/i
                        i = $1.to_i
                        @xmm_st ||= do_getxmm
                        fu = @xmm_st.st_space
                        fu[4*i] = v & 0xffff_ffff
                        fu[4*i + 1] = (v >> 32) & 0xffff_ffff
                        do_setxmm
                when /^xmm(\d+)$/i
                        i = $1.to_i
                        @xmm_st ||= do_getxmm
                        fu = @xmm_st.xmm_space
                        fu[4*i] = v & 0xffff_ffff
                        fu[4*i + 1] = (v >> 32) & 0xffff_ffff
                        fu[4*i + 2] = (v >> 64) & 0xffff_ffff
                        fu[4*i + 3] = (v >> 96) & 0xffff_ffff
                        do_setxmm
                # TODO when /^ymm(\d+)$/i
                else raise "unknown register name #{r}"
                end
        end
end