Class: Metasm::LinuxRemoteString

Inherits:
VirtualString show all
Defined in:
lib/metasm/os/linux.rb

Instance Attribute Summary collapse

Attributes inherited from VirtualString

#addr_start, #length, #pagecache, #pagecache_len

Instance Method Summary collapse

Methods inherited from VirtualString

#=~, #[], #[]=, #cache_get_page, #empty?, #index, #invalidate, #method_missing, #page_invalid?, #read_range, #realstring, #to_str, #write_range

Constructor Details

#initialize(pid, addr_start = 0, length = nil, dbg = nil) ⇒ LinuxRemoteString

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



632
633
634
635
636
637
638
# File 'lib/metasm/os/linux.rb', line 632

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

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Metasm::VirtualString

Instance Attribute Details

#dbgObject

Returns the value of attribute dbg.



627
628
629
# File 'lib/metasm/os/linux.rb', line 627

def dbg
  @dbg
end

#pidObject

Returns the value of attribute pid.



626
627
628
# File 'lib/metasm/os/linux.rb', line 626

def pid
  @pid
end

#readfdObject

Returns the value of attribute readfd.



626
627
628
# File 'lib/metasm/os/linux.rb', line 626

def readfd
  @readfd
end

Instance Method Details

#do_ptraceObject



644
645
646
647
648
649
650
651
652
653
# File 'lib/metasm/os/linux.rb', line 644

def do_ptrace
	if dbg
		dbg.switch_context(@pid) {
			# XXX tid ?
			yield dbg.ptrace if dbg.state == :stopped
		}
	else
		PTrace.open(@pid) { |ptrace| yield ptrace }
	end
end

#dup(addr = @addr_start, len = @length) ⇒ Object



640
641
642
# File 'lib/metasm/os/linux.rb', line 640

def dup(addr = @addr_start, len = @length)
	self.class.new(@pid, addr, len, dbg)
end

#get_page(addr, len = @pagelength) ⇒ Object



660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
# File 'lib/metasm/os/linux.rb', line 660

def get_page(addr, len=@pagelength)
	do_ptrace { |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) ⇒ Object



655
656
657
658
# File 'lib/metasm/os/linux.rb', line 655

def rewrite_at(addr, data)
	# target must be stopped
	do_ptrace { |ptrace| ptrace.writemem(addr, data) }
end