class Metasm::DEX

Android Dalvik executable file format (similar to java .class)

Constants

ACCESSIBILITY_CLASS
DEPSMAGIC
MAGIC
OBJ_TYPE
OPTMAGIC
OPT_FLAGS
TYPE
VISIBILITY

Attributes

classes[RW]
endianness[RW]
fields[RW]
header[RW]
methods[RW]
protos[RW]
strings[RW]
types[RW]

Public Class Methods

new(endianness=:little) click to toggle source
Calls superclass method Metasm::ExeFormat::new
# File metasm/exe_format/dex.rb, line 348
def initialize(endianness=:little)
        @endianness = endianness
        @encoded = EncodedData.new
        super()
end

Public Instance Methods

cpu_from_headers() click to toggle source
# File metasm/exe_format/dex.rb, line 418
def cpu_from_headers
        Dalvik.new(self)
end
decode() click to toggle source
# 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
decode_classes() click to toggle source
# 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
decode_fields() click to toggle source
# File metasm/exe_format/dex.rb, line 375
def decode_fields
        @encoded.ptr = @header.fieldidsoff
        @fields = (1..@header.fieldidssz).map { FieldId.decode(self) }
end
decode_header() click to toggle source
# File metasm/exe_format/dex.rb, line 354
def decode_header
        @header = Header.decode(self)
end
decode_methods() click to toggle source
# File metasm/exe_format/dex.rb, line 380
def decode_methods
        @encoded.ptr = @header.methodidsoff
        @methods = (1..@header.methodidssz).map { MethodId.decode(self) }
end
decode_protos() click to toggle source
# File metasm/exe_format/dex.rb, line 370
def decode_protos
        @encoded.ptr = @header.protoidsoff
        @protos = (1..@header.protoidssz).map { ProtoId.decode(self) }
end
decode_sleb(ed = @encoded) click to toggle source
# File metasm/exe_format/dex.rb, line 345
def decode_sleb(ed = @encoded) decode_uleb(ed, true) end
decode_strings() click to toggle source
# 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
decode_types() click to toggle source
# 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
decode_u2(edata = @encoded) click to toggle source
# File metasm/exe_format/dex.rb, line 330
def decode_u2(edata = @encoded) edata.decode_imm(:u16, @endianness) end
decode_u4(edata = @encoded) click to toggle source
# File metasm/exe_format/dex.rb, line 331
def decode_u4(edata = @encoded) edata.decode_imm(:u32, @endianness) end
decode_uleb(ed = @encoded, signed=false) click to toggle source
# 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
each_section() { |encoded, 0| ... } click to toggle source
# 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
encode_u2(val) click to toggle source
# File metasm/exe_format/dex.rb, line 328
def encode_u2(val) Expression[val].encode(:u16, @endianness) end
encode_u4(val) click to toggle source
# File metasm/exe_format/dex.rb, line 329
def encode_u4(val) Expression[val].encode(:u32, @endianness) end
get_default_entrypoints() click to toggle source
# 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
init_disassembler() click to toggle source
Calls superclass method Metasm::ExeFormat#init_disassembler
# 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
sizeof_u2() click to toggle source
# File metasm/exe_format/dex.rb, line 332
def sizeof_u2 ; 2 ; end
sizeof_u4() click to toggle source
# File metasm/exe_format/dex.rb, line 333
def sizeof_u4 ; 4 ; end