Class: Indis::Target
- Inherits:
-
Object
- Object
- Indis::Target
- Defined in:
- lib/indis-core/target.rb
Overview
The main entry point for indis. Target describes a given binary, performs format matching, loading the binary into memory and primary processing.
Instance Attribute Summary collapse
-
#architecture ⇒ Indis::BinaryArchitecture::Arcitecture
readonly
Binary architecture of the target.
-
#format ⇒ Indis::BinaryFormat::Format
readonly
Binary format of the target.
-
#io ⇒ IO
readonly
IO object for target binary.
-
#segments ⇒ Array<Indis::Segment>
List of all processed segments.
-
#symbols ⇒ Array<Indis::Symbol>
List of all processed symbols.
-
#vmmap ⇒ Indis::VMMap
readonly
Virtual memory map.
Instance Method Summary collapse
-
#initialize(filename) ⇒ Target
constructor
A new instance of Target.
-
#load ⇒ Object
Perform format load and set up a vm map.
-
#meta? ⇒ Boolean
A target can consist of several other targets (e.g. fat mach-o).
-
#publish_event(event, *args) ⇒ Object
Post an event with optional payload.
-
#resolve_symbol_at_address(vmaddr) ⇒ Indis::Symbol?
Resolves a symbol at given virtual address.
-
#subscribe_for_event(event, listener) ⇒ Object
External class can subscribe for events happening with target.
Constructor Details
#initialize(filename) ⇒ Target
Returns a new instance of Target.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/indis-core/target.rb', line 44 def initialize(filename) raise ArgumentError, "File does not exist" unless FileTest.file?(filename) @filename = filename @io = StringIO.new(File.open(filename).read().force_encoding('BINARY')) magic = @io.read(4).unpack('V')[0] @io.seek(-4, IO::SEEK_CUR) fmts = BinaryFormat.known_formats.map { |f| f if f.magic == magic }.compact raise RuntimeError, "Unknown format for magic #{magic.to_s(16)}" if fmts.length == 0 raise RuntimeError, "Several possible formats: #{fmts}" if fmts.length > 1 @format_class = fmts.first @format_load_complete = false end |
Instance Attribute Details
#architecture ⇒ Indis::BinaryArchitecture::Arcitecture (readonly)
Returns binary architecture of the target.
33 34 35 |
# File 'lib/indis-core/target.rb', line 33 def architecture @architecture end |
#format ⇒ Indis::BinaryFormat::Format (readonly)
Returns binary format of the target.
31 32 33 |
# File 'lib/indis-core/target.rb', line 31 def format @format end |
#io ⇒ IO (readonly)
Returns IO object for target binary.
29 30 31 |
# File 'lib/indis-core/target.rb', line 29 def io @io end |
#segments ⇒ Array<Indis::Segment>
Returns list of all processed segments.
37 38 39 |
# File 'lib/indis-core/target.rb', line 37 def segments @segments end |
#symbols ⇒ Array<Indis::Symbol>
Returns list of all processed symbols.
39 40 41 |
# File 'lib/indis-core/target.rb', line 39 def symbols @symbols end |
#vmmap ⇒ Indis::VMMap (readonly)
Returns virtual memory map.
35 36 37 |
# File 'lib/indis-core/target.rb', line 35 def vmmap @vmmap end |
Instance Method Details
#load ⇒ Object
Perform format load and set up a vm map
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/indis-core/target.rb', line 62 def load raise RuntimeError, "Already loaded" unless @format_class @format = @format_class.new(self, @io) @format_class = nil archClass = BinaryArchitecture.known_archs[@format.architecture] raise RuntimeError, "Architecture not defined" unless archClass @architecture = archClass.new(self) @vmmap = VMMap.new(self) @format_load_complete = true replay_queue publish_event :target_load_complete self end |
#meta? ⇒ Boolean
implement meta targets
A target can consist of several other targets (e.g. fat mach-o). In such a case the target is meta
. It does not have any segments, sections or vmmap, but it has one or several subtargets.
85 86 87 |
# File 'lib/indis-core/target.rb', line 85 def @subtargets && @subtargets.length > 0 end |
#publish_event(event, *args) ⇒ Object
Post an event with optional payload. All events queue up until #load ends
100 101 102 103 104 105 106 |
# File 'lib/indis-core/target.rb', line 100 def publish_event(event, *args) if @format_load_complete == true subscriptions_array(event).each { |s| s.send(event, *args) } else enqueue_event(event, args) end end |
#resolve_symbol_at_address(vmaddr) ⇒ Indis::Symbol?
Resolves a symbol at given virtual address. Targe does so by first checking the locally available symbols, and falls back to format specific resolver if nothing found
114 115 116 117 118 119 120 |
# File 'lib/indis-core/target.rb', line 114 def resolve_symbol_at_address(vmaddr) s = @symbols.find { |sym| sym.vmaddr == vmaddr } return s if s s = @format.resolve_symbol_at_address(vmaddr) if @format.respond_to?(:resolve_symbol_at_address) @symbols << s if s s end |
#subscribe_for_event(event, listener) ⇒ Object
External class can subscribe for events happening with target
93 94 95 |
# File 'lib/indis-core/target.rb', line 93 def subscribe_for_event(event, listener) subscriptions_array(event) << listener end |