Class: Indis::Target

Inherits:
Object
  • Object
show all
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)

Instance Method Summary (collapse)

Constructor Details

- (Target) initialize(filename)

A new instance of Target

Parameters:

  • filename (String)

    target binary file name

Raises:

  • (AttributeError)

    if the file does not exist

  • (RuntimeError)

    if there is no known format for magic or there are several matching formats



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

- (Indis::BinaryArchitecture::Arcitecture) architecture (readonly)

Binary architecture of the target

Returns:

  • (Indis::BinaryArchitecture::Arcitecture)

    binary architecture of the target



33
34
35
# File 'lib/indis-core/target.rb', line 33

def architecture
  @architecture
end

- (Indis::BinaryFormat::Format) format (readonly)

Binary format of the target

Returns:



31
32
33
# File 'lib/indis-core/target.rb', line 31

def format
  @format
end

- (IO) io (readonly)

IO object for target binary

Returns:

  • (IO)

    IO object for target binary



29
30
31
# File 'lib/indis-core/target.rb', line 29

def io
  @io
end

- (Array<Indis::Segment>) segments

List of all processed segments

Returns:



37
38
39
# File 'lib/indis-core/target.rb', line 37

def segments
  @segments
end

- (Array<Indis::Symbol>) symbols

List of all processed symbols

Returns:



39
40
41
# File 'lib/indis-core/target.rb', line 39

def symbols
  @symbols
end

- (Indis::VMMap) vmmap (readonly)

Virtual memory map

Returns:



35
36
37
# File 'lib/indis-core/target.rb', line 35

def vmmap
  @vmmap
end

Instance Method Details

- (Object) load

Perform format load and set up a vm map

Raises:

  • (RuntimeError)


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

- (Boolean) meta?

TODO:

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.

Returns:

  • (Boolean)

    True if the target is a meta target



85
86
87
# File 'lib/indis-core/target.rb', line 85

def meta?
  @subtargets && @subtargets.length > 0
end

- (Object) publish_event(event, *args)

Post an event with optional payload. All events queue up until #load ends

Parameters:

  • event (Symbol)

    event name



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

- (Indis::Symbol?) resolve_symbol_at_address(vmaddr)

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

Parameters:

  • vmaddr (Fixnum)

    virtual address

Returns:



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

- (Object) subscribe_for_event(event, listener)

External class can subscribe for events happening with target

Parameters:

  • event (Symbol)

    event name

  • listener

    event listener



93
94
95
# File 'lib/indis-core/target.rb', line 93

def subscribe_for_event(event, listener)
  subscriptions_array(event) << listener
end