Module: ECUTools::Helpers

Included in:
Disassembler
Defined in:
lib/helpers.rb

Instance Method Summary collapse

Instance Method Details

#absolute_address(relative_address) ⇒ Object



53
54
55
# File 'lib/helpers.rb', line 53

def absolute_address(relative_address)
  (base_address.to_i(16) + relative_address).to_s(16)
end

#address_descriptionsObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/helpers.rb', line 57

def address_descriptions
  return @address_descriptions if @address_descriptions
  @address_descriptions = {}
  begin
    xml = Nokogiri::XML(File.open(File.dirname(__FILE__) + "/../xml/ram/#{rom_id}.xml"))
    xml.xpath('/EvoScanDataLogger/vehicle/ecu/Mode2/DataListItem').each do |node|
      @address_descriptions[node.attr('RequestID')[2..-1]] = node.attr('Display')
    end
  rescue
    $stderr.puts "No RAM map found for this rom, skipping subroutine identification." if verbose
  end
  
  @address_descriptions
end

#base_addressObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/helpers.rb', line 35

def base_address
  return @base_address if @base_address
  $stderr.puts "Getting base address..." if verbose
  @assembly.each_with_index do |instruction,i|
    if instruction.assembly == "st r3,@r0 \|\| nop"
      match = /ld24 fp,(0x\w+)/.match(@assembly[i+1].assembly)
      if match
        @base_address = match[1]
        @assembly[i+1].comments[0] = "Assign base address to #{@base_address}" 
        return @base_address
      end
    end
  end

  $stderr.puts "WARNING: Base address unknown! Setting to 0 (THIS IS WRONG!)" if verbose
  @base_address = 0 
end

#from_hex(address) ⇒ Object



27
28
29
30
31
32
33
# File 'lib/helpers.rb', line 27

def from_hex(address)
  if address.is_a? String
    address.to_i(16)
  else
    address.to_i
  end
end

#instruction_at(address, strict = false) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/helpers.rb', line 19

def instruction_at(address, strict = false)
  address = from_hex address
  if strict and (address % 4) > 0 
    raise "Address #{address} does not fall on an instruction boundary and strict is enabled." 
  end
  @assembly[(address - (address % 4)) / 4]
end

#load_rom_xml(rom_number) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/helpers.rb', line 94

def load_rom_xml(rom_number)

  load_rom = Nokogiri::XML(File.open(File.dirname(__FILE__) + "/../xml/rom/#{rom_number}.xml"))

  load_rom.xpath('/rom/include').each do |include_tag|

    include_rom = load_rom_xml(include_tag.text)
    
    # import scalings
    include_rom.xpath('/rom/scaling').each do |scaling|
      if load_rom.xpath("/rom/scaling[@name='#{scaling.attr('name')}']").count == 0
        load_rom.xpath('/rom')[0].add_child(scaling)
      end
    end

    #import tables
    include_rom.xpath('/rom/table').each do |table|
      if load_rom.xpath("/rom/table[@name='#{table.attr('name')}']").count == 0
        load_rom.xpath('/rom')[0].add_child(table)
      end
    end

  end

  load_rom
end

#read_bytes(address, number) ⇒ Object



9
10
11
12
13
14
15
16
17
# File 'lib/helpers.rb', line 9

def read_bytes(address, number)
  bytes = []
  start = from_hex address
  number.times do |n|
    inst = instruction_at(start + n)
    bytes << inst.bytes[(start+n) % 4]
  end
  bytes
end

#rom_idObject



3
4
5
6
7
# File 'lib/helpers.rb', line 3

def rom_id
  return @rom_id if @rom_id
  $stderr.puts "Getting ROM ID..." if verbose
  @rom_id = read_bytes("5002a", 4).join
end

#rom_xmlObject



87
88
89
90
91
92
# File 'lib/helpers.rb', line 87

def rom_xml
  return @rom_xml if @rom_xml
  @rom_xml = load_rom_xml(rom_id)

  @rom_xml
end

#subroutine_descriptionsObject



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/helpers.rb', line 72

def subroutine_descriptions
  return @subroutine_descriptions if @subroutine_descriptions
  @subroutine_descriptions = {}
  begin
    xml = Nokogiri::XML(File.open(File.dirname(__FILE__) + "/../xml/code/#{rom_id}.xml"))
    xml.xpath('/rom/routine').each do |node|
      @subroutine_descriptions[node.attr('address')] = node.attr('name')
    end
  rescue
    $stderr.puts "No subroutine map found for this rom, skipping subroutine identification." if verbose
  end
  
  @subroutine_descriptions
end