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

#initialize(filename) ⇒ Target

Returns 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

#architectureIndis::BinaryArchitecture::Arcitecture (readonly)

Returns 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

#formatIndis::BinaryFormat::Format (readonly)

Returns binary format of the target.

Returns:



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

def format
  @format
end

#ioIO (readonly)

Returns 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

#segmentsArray<Indis::Segment>

Returns list of all processed segments.

Returns:



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

def segments
  @segments
end

#symbolsArray<Indis::Symbol>

Returns list of all processed symbols.

Returns:



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

def symbols
  @symbols
end

#vmmapIndis::VMMap (readonly)

Returns virtual memory map.

Returns:



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

def vmmap
  @vmmap
end

Instance Method Details

#loadObject

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

#meta?Boolean

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

#publish_event(event, *args) ⇒ Object

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

#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

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

#subscribe_for_event(event, listener) ⇒ Object

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