class Metasm::LinuxRemoteString

Attributes

dbg[RW]
pid[RW]
readfd[RW]

Public Class Methods

new(pid, addr_start=0, length=nil, dbg=nil) click to toggle source

returns a virtual string proxying the specified process memory range reads are cached (4096 aligned bytes read at once), from /proc/pid/mem writes are done directly by ptrace

Calls superclass method
# File metasm/os/linux.rb, line 726
def initialize(pid, addr_start=0, length=nil, dbg=nil)
        @pid = pid
        length ||= 1 << (dbg ? dbg.cpu.size : (LinOS.open_process(@pid).addrsz rescue 32))
        @readfd = File.open("/proc/#@pid/mem", 'rb') rescue nil
        @dbg = dbg if dbg
        super(addr_start, length)
end

Public Instance Methods

do_ptrace(needproc) { |ptrace| ... } click to toggle source
# File metasm/os/linux.rb, line 738
def do_ptrace(needproc)
        if dbg
                dbg.switch_context(@pid) {
                        st = dbg.state
                        next if st != :stopped
                        if needproc
                                # we will try to access /proc/pid/mem
                                # if the main thread is still running, fallback to ptrace.readmem instead
                                pst = (dbg.tid == @pid ? st : dbg.tid_stuff[@pid][:state])
                                if pst != :stopped
                                        savedreadfd = @readfd
                                        @readfd = nil
                                        begin
                                                yield dbg.ptrace
                                        ensure
                                                @readfd = savedreadfd
                                        end
                                else
                                        yield dbg.ptrace
                                end
                        else
                                yield dbg.ptrace
                        end
                }
        else
                PTrace.open(@pid) { |ptrace| yield ptrace }
        end
end
dup(addr = @addr_start, len = @length) click to toggle source
# File metasm/os/linux.rb, line 734
def dup(addr = @addr_start, len = @length)
        self.class.new(@pid, addr, len, dbg)
end
get_page(addr, len=@pagelength) click to toggle source
# File metasm/os/linux.rb, line 773
def get_page(addr, len=@pagelength)
        do_ptrace(true) { |ptrace|
                begin
                        if readfd and addr < (1<<63)
                                # 1<<63: ruby seek = 'too big to fit longlong', linux read = EINVAL
                                @readfd.pos = addr
                                @readfd.read len
                        elsif addr < (1<<(ptrace.host_intsize*8))
                                # can reach 1<<64 with peek_data only if ptrace accepts 64bit args
                                ptrace.readmem(addr, len)
                        end
                rescue Errno::EIO, Errno::ESRCH
                        nil
                end
        }
end
rewrite_at(addr, data) click to toggle source
# File metasm/os/linux.rb, line 767
def rewrite_at(addr, data)
        # target must be stopped
        wr = do_ptrace(false) { |ptrace| ptrace.writemem(addr, data) }
        raise "couldn't ptrace_write at #{'%x' % addr}" if not wr
end