Class: Indis::VMMap
- Inherits:
-
Object
- Object
- Indis::VMMap
- Defined in:
- lib/indis-core/vmmap.rb
Overview
VMMap provides access to target’s virtaul memory address space
Instance Method Summary collapse
- #[](range) ⇒ Object
-
#address_valid?(ofs) ⇒ Boolean
True if the address belongs to some segment.
-
#byte_at(ofs) ⇒ Fixnum
A byte value at given virtual address.
-
#bytes_at(ofs, size) ⇒ Array<Fixnum>
A list of bytes at given virtual address span.
-
#entity_at(ofs) ⇒ Indis::Entity
An entity mapped to given address.
-
#has_unmapped(ofs, size) ⇒ Object
True if the given range contains no entities.
-
#initialize(target) ⇒ VMMap
constructor
A new instance of VMMap.
-
#map(e) ⇒ Object
Maps an entity (based on its offset).
-
#map!(e) ⇒ Object
Forcefully maps an entity (based on its offset) unmapping any other entities in the same address range.
-
#section_at(ofs) ⇒ Indis::Section
A section at given address or nil.
-
#segment_at(ofs) ⇒ Indis::Segment
A segment at given address or nil.
Constructor Details
#initialize(target) ⇒ VMMap
Returns a new instance of VMMap.
23 24 25 26 |
# File 'lib/indis-core/vmmap.rb', line 23 def initialize(target) @target = target @blocks = {} end |
Instance Method Details
#[](ofs) ⇒ Indis::Entity #[](range) ⇒ Array<Indis::Entity,nil,Fixnum>
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/indis-core/vmmap.rb', line 115 def [](range) return entity_at(range) if range.is_a?(Fixnum) raise ArgumentError, "Unknown argument type #{range.class}" unless range.is_a?(Range) seg = segment_at(range.begin) raise ArgumentError, "No segment mapped at #{range.begin}" unless seg range_max = range.exclude_end? ? range.last-1 : range.last raise ArgumentError, "Segment #{seg} at #{range.begin}, but segment #{segment_at(range_max)} at #{range.end}" unless seg == segment_at(range_max) a = Array.new(range_max - range.begin + 1) ofs = range.begin range_begin = range.begin seg_vmaddr = seg.vmaddr begin b = @blocks[ofs] if b a[ofs-range_begin] = b ofs += b.size else a[ofs-range_begin] = seg.bytes[ofs-seg_vmaddr].ord ofs += 1 end end while ofs <= range_max a end |
#address_valid?(ofs) ⇒ Boolean
Returns True if the address belongs to some segment.
42 43 44 |
# File 'lib/indis-core/vmmap.rb', line 42 def address_valid?(ofs) segment_at(ofs) != nil end |
#byte_at(ofs) ⇒ Fixnum
Returns a byte value at given virtual address.
47 48 49 50 51 52 53 54 55 |
# File 'lib/indis-core/vmmap.rb', line 47 def byte_at(ofs) seg = segment_at(ofs) return nil unless seg sect = section_at(ofs) # TODO: optimize here s = sect || seg s.bytes[ofs-s.vmaddr].ord end |
#bytes_at(ofs, size) ⇒ Array<Fixnum>
Returns a list of bytes at given virtual address span.
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/indis-core/vmmap.rb', line 58 def bytes_at(ofs, size) seg = segment_at(ofs) return nil unless seg sect = section_at(ofs) # TODO: optimize here s = sect || seg st = ofs-s.vmaddr ed = st + size s.bytes[st...ed].unpack('C*') end |
#entity_at(ofs) ⇒ Indis::Entity
Returns an entity mapped to given address.
71 72 73 |
# File 'lib/indis-core/vmmap.rb', line 71 def entity_at(ofs) @blocks[ofs] end |
#has_unmapped(ofs, size) ⇒ Object
Returns True if the given range contains no entities.
76 77 78 79 |
# File 'lib/indis-core/vmmap.rb', line 76 def has_unmapped(ofs, size) size.times { |o| return false if entity_at(ofs+o) } true end |
#map(e) ⇒ Object
Maps an entity (based on its offset).
83 84 85 86 |
# File 'lib/indis-core/vmmap.rb', line 83 def map(e) raise ArgumentError, "Tried to map #{e} at #{e.vmaddr}+#{e.size} on top of #{self[e.vmaddr...(e.vmaddr+e.size)]}" unless has_unmapped(e.vmaddr, e.size) @blocks[e.vmaddr] = e end |
#map!(e) ⇒ Object
Forcefully maps an entity (based on its offset) unmapping any other entities in the same address range
90 91 92 93 94 95 96 97 98 99 |
# File 'lib/indis-core/vmmap.rb', line 90 def map!(e) (e.vmaddr...(e.vmaddr+e.size)).each do |ofs| b = @blocks[ofs] if b b.unmap @blocks[ofs] = nil end end map(e) end |
#section_at(ofs) ⇒ Indis::Section
Returns a section at given address or nil.
34 35 36 37 38 39 |
# File 'lib/indis-core/vmmap.rb', line 34 def section_at(ofs) seg = segment_at(ofs) return nil unless seg seg.sections.each.find { |s| (s.vmaddr...s.vmaddr+s.vmsize).include? ofs } end |
#segment_at(ofs) ⇒ Indis::Segment
Returns a segment at given address or nil.
29 30 31 |
# File 'lib/indis-core/vmmap.rb', line 29 def segment_at(ofs) @target.segments.each.find { |s| (s.vmaddr...s.vmaddr+s.vmsize).include? ofs } end |