Android Dalvik executable file format (similar to java .class)
# File metasm/exe_format/dex.rb, line 348 def initialize(endianness=:little) @endianness = endianness @encoded = EncodedData.new super() end
# File metasm/exe_format/dex.rb, line 418 def cpu_from_headers Dalvik.new(self) end
# File metasm/exe_format/dex.rb, line 408 def decode decode_header decode_strings decode_types decode_protos decode_fields decode_methods decode_classes end
# File metasm/exe_format/dex.rb, line 385 def decode_classes @encoded.ptr = @header.classdefsoff @classes = (1..@header.classdefssz).map { ClassDef.decode(self) } @classes.each { |c| next if c.classdataoff == 0 @encoded.ptr = c.classdataoff c.data = ClassData.decode(self) id = 0 (c.data.direct_methods + [0] + c.data.virtual_methods).each { |m| next id=0 if m == 0 id += m.methodid_diff m.methodid = id m.method = @methods[id] m.name = @strings[m.method.nameidx] @encoded.ptr = m.codeoff m.code = CodeItem.decode(self) next if @encoded.ptr > @encoded.length l = new_label(m.name + '@' + @types[c.classidx]) @encoded.add_export l, m.codeoff + m.code.insns_off } } end
# File metasm/exe_format/dex.rb, line 375 def decode_fields @encoded.ptr = @header.fieldidsoff @fields = (1..@header.fieldidssz).map { FieldId.decode(self) } end
# File metasm/exe_format/dex.rb, line 354 def decode_header @header = Header.decode(self) end
# File metasm/exe_format/dex.rb, line 380 def decode_methods @encoded.ptr = @header.methodidsoff @methods = (1..@header.methodidssz).map { MethodId.decode(self) } end
# File metasm/exe_format/dex.rb, line 370 def decode_protos @encoded.ptr = @header.protoidsoff @protos = (1..@header.protoidssz).map { ProtoId.decode(self) } end
# File metasm/exe_format/dex.rb, line 345 def decode_sleb(ed = @encoded) decode_uleb(ed, true) end
# File metasm/exe_format/dex.rb, line 358 def decode_strings @encoded.ptr = @header.stringidsoff so = (1..@header.stringidssz).map { StringId.decode(self) } @strings = so.map { |s| @encoded.ptr = s.off ; StringData.decode(self).str } end
# File metasm/exe_format/dex.rb, line 364 def decode_types @encoded.ptr = @header.typeidsoff tl = (1..@header.typeidssz).map { TypeId.decode(self) } @types = tl.map { |t| @strings[t.descridx] } # TODO demangle or something end
# File metasm/exe_format/dex.rb, line 330 def decode_u2(edata = @encoded) edata.decode_imm(:u16, @endianness) end
# File metasm/exe_format/dex.rb, line 331 def decode_u4(edata = @encoded) edata.decode_imm(:u32, @endianness) end
# File metasm/exe_format/dex.rb, line 334 def decode_uleb(ed = @encoded, signed=false) v = s = 0 while s < 5*7 b = ed.read(1).unpack('C').first.to_i v |= (b & 0x7f) << s break if (b&0x80) == 0 s += 7 end v = Expression.make_signed(v, s) if signed v end
# File metasm/exe_format/dex.rb, line 435 def each_section yield @encoded, 0 # @classes.each { |c| # next if not c.data # (c.data.direct_methods + c.data.virtual_methods).each { |m| # next if not m.code # next if not ed = @encoded[m.codeoff+m.code.insns_off, 2*m.code.insnssz] # yield ed, ed.export.index(0) # } # } end
# File metasm/exe_format/dex.rb, line 328 def encode_u2(val) Expression[val].encode(:u16, @endianness) end
# File metasm/exe_format/dex.rb, line 329 def encode_u4(val) Expression[val].encode(:u32, @endianness) end
# File metasm/exe_format/dex.rb, line 447 def get_default_entrypoints @classes.find_all { |c| c.data }.map { |c| (c.data.direct_methods + c.data.virtual_methods).map { |m| m.codeoff+m.code.insns_off } }.flatten end
# File metasm/exe_format/dex.rb, line 422 def init_disassembler dasm = super() @classes.each { |c| next if not c.data (c.data.direct_methods + c.data.virtual_methods).each { |m| n = @types[c.classidx] + '->' + m.name dasm.comment[m.codeoff+m.code.insns_off] = [n] } } dasm.function[:default] = @cpu.disassembler_default_func dasm end
# File metasm/exe_format/dex.rb, line 332 def sizeof_u2 ; 2 ; end
# File metasm/exe_format/dex.rb, line 333 def sizeof_u4 ; 4 ; end