dex文件解析(1)

CommonUtils

#!/usr/bin/env python
#coding:utf-8

def byte_to_buma(val):
    binVal = bin(val)[2:].zfill(8)
    if binVal[0:1] == ‘0‘:
        return val
    sb = ‘‘
    for i in range(7):
        if binVal[i+1:i+2] == ‘0‘:
            sb += ‘1‘
        else:
            sb += ‘0‘

    return -(int(sb, 2) + 1)

def word_to_buma(val):
    binVal = bin(val)[2:].zfill(16)
    if binVal[0:1] == ‘0‘:
        return val
    sb = ‘‘
    for i in range(15):
        if binVal[i+1:i+2] == ‘0‘:
            sb += ‘1‘
        else:
            sb += ‘0‘

    return -(int(sb, 2) + 1)

def dword_to_buma(val):
    binVal = bin(val)[2:].zfill(32)
    if binVal[0:1] == ‘0‘:
        return val
    sb = ‘‘
    for i in range(31):
        if binVal[i+1:i+2] == ‘0‘:
            sb += ‘1‘
        else:
            sb += ‘0‘

    return -(int(sb, 2) + 1)

OpCode

#!/usr/bin/env python
#coding:utf-8

def getOpCode(opcode):
    """
    参考: dalvik-bytecode
    """
    if opcode == 0x00 : return ‘10x‘, ‘nop‘
    if opcode == 0x01 : return ‘12x‘, ‘move vA, vB‘
    if opcode == 0x02 : return ‘22x‘, ‘move/from16 vAA, vBBBB‘
    if opcode == 0x03 : return ‘32x‘, ‘move/16 vAAAA, vBBBB‘
    if opcode == 0x04 : return ‘12x‘, ‘move-wide vA, vB‘
    if opcode == 0x05 : return ‘22x‘, ‘move-wide/from16 vAA, vBBBB‘
    if opcode == 0x06 : return ‘32x‘, ‘move-wide/16 vAAAA, vBBBB‘
    if opcode == 0x07 : return ‘12x‘, ‘move-object vA, vB‘
    if opcode == 0x08 : return ‘22x‘, ‘move-object/from16 vAA, vBBBB‘
    if opcode == 0x09 : return ‘32x‘, ‘move-object/16 vAAAA, vBBBB‘
    if opcode == 0xa : return ‘11x‘, ‘move-result vAA‘
    if opcode == 0xb : return ‘11x‘, ‘move-result-wide vAA‘
    if opcode == 0xc : return ‘11x‘, ‘move-result-object vAA‘
    if opcode == 0xd : return ‘11x‘, ‘move-exception vAA‘
    if opcode == 0xe : return ‘10x‘, ‘return-void‘
    if opcode == 0xf : return ‘11x‘, ‘return vAA‘
    if opcode == 0x10 : return ‘11x‘, ‘return-wide‘
    if opcode == 0x11 : return ‘11x‘, ‘return-object vAA‘
    if opcode == 0x12 : return ‘11n‘, ‘const/4 vA, #+B‘
    if opcode == 0x13 : return ‘21s‘, ‘const/16 vAA, #+BBBB‘
    if opcode == 0x14 : return ‘31i‘, ‘const vAA, #+BBBBBBBB‘
    if opcode == 0x15 : return ‘21h‘, ‘const/high16 vAA, #+BBBB0000‘
    if opcode == 0x16 : return ‘21s‘, ‘const-wide/16 vAA, #+BBBB‘
    if opcode == 0x17 : return ‘31i‘, ‘const-wide/32 vAA, #+BBBBBBBB‘
    if opcode == 0x18 : return ‘51l‘, ‘const-wide vAA, #+BBBBBBBBBBBBBBBB‘
    if opcode == 0x19 : return ‘21h‘, ‘const-wide/high16 vAA, #+BBBB000000000000‘
    if opcode == 0x1a : return ‘21c‘, ‘const-string vAA, [email protected]‘
    if opcode == 0x1b : return ‘31c‘, ‘const-string/jumbo vAA, [email protected]‘
    if opcode == 0x1c : return ‘21c‘, ‘const-class vAA, [email protected]‘
    if opcode == 0x1d : return ‘11x‘, ‘monitor-enter vAA‘
    if opcode == 0x1e : return ‘11x‘, ‘monitor-exit vAA‘
    if opcode == 0x1f : return ‘21c‘, ‘check-cast vAA, [email protected]‘
    if opcode == 0x20 : return ‘22c‘, ‘instance-of vA, vB, [email protected]‘
    if opcode == 0x21 : return ‘12x‘, ‘array-length vA, vB‘
    if opcode == 0x22 : return ‘21c‘, ‘new-instance vAA, [email protected]‘
    if opcode == 0x23 : return ‘22c‘, ‘new-array vA, vB, [email protected]‘
    if opcode == 0x24 : return ‘35c‘, ‘filled-new-array {vD, vE, vF, vG, vA}, [email protected]‘
    if opcode == 0x25 : return ‘3rc‘, ‘filled-new-array/range {vCCCC .. vNNNN}, [email protected]‘
    if opcode == 0x26 : return ‘31t‘, ‘fill-array-data vAA, +BBBBBBBB‘
    if opcode == 0x27 : return ‘11x‘, ‘throw vAA‘
    if opcode == 0x28 : return ‘10t‘, ‘goto +AA‘
    if opcode == 0x29 : return ‘20t‘, ‘goto/16 +AAAA‘
    if opcode == 0x2a : return ‘30t‘, ‘goto/32 +AAAAAAAA‘
    if opcode == 0x2b : return ‘31t‘, ‘packed-switch vAA, +BBBBBBBB‘
    if opcode == 0x2c : return ‘31t‘, ‘sparse-switch vAA, +BBBBBBBB‘
    if opcode >= 0x2d and opcode <= 0x31 : return ‘23x‘, ‘cmpkind vAA, vBB, vCC‘
    if opcode >= 0x32 and opcode <= 0x37 : return ‘22t‘, ‘if-test vA, vB, +CCCC‘
    if opcode >= 0x38 and opcode <= 0x3d : return ‘21t‘, ‘if-testz vAA, +BBBB‘
    if opcode >= 0x3e and opcode <= 0x43 : return ‘10x‘, ‘unused‘
    if opcode >= 0x44 and opcode <= 0x51 : return ‘23x‘, ‘arrayop vAA, vBB, vCC‘
    if opcode >= 0x52 and opcode <= 0x5f : return ‘22c‘, ‘iinstanceop vA, vB, [email protected]‘
    if opcode >= 0x60 and opcode <= 0x6d: return ‘21c‘, ‘sstaticop vAA, [email protected]‘
    if opcode >= 0x6e and opcode <= 0x72 : return ‘35c‘, ‘invoke-kind {vD, vE, vF, vG, vA}, [email protected]‘
    if opcode == 0x73 : return ‘10x‘, ‘unused‘
    if opcode >= 0x74 and opcode <= 0x78 : return ‘3rc‘, ‘invoke-kind/range {vCCCC .. vNNNN}, [email protected]‘
    if opcode >= 0x79 and opcode <= 0x7a : return ‘10x‘, ‘unused‘
    if opcode >= 0x7b and opcode <= 0x8f : return ‘12x‘, ‘unop vA, vB‘
    if opcode >= 0x90 and opcode <= 0xaf : return ‘23x‘, ‘binop vAA, vBB, vCC‘
    if opcode >= 0xb0 and opcode <= 0xcf : return ‘12x‘, ‘binop/2addr vA, vB‘
    if opcode >= 0xd0 and opcode <= 0xd7 : return ‘22s‘, ‘binop/lit16 vA, vB, #+CCCC‘
    if opcode >= 0xd8 and opcode <= 0xe2 : return ‘22b‘, ‘binop/lit8 vAA, vBB, #+CC‘
    if opcode >= 0xe3 and opcode <= 0xfe : return ‘10x‘, ‘unused‘
    if opcode == 0x00ff : return ‘41c‘, ‘const-class/jumbo vAAAA, [email protected]‘
    if opcode == 0x01ff : return ‘41c‘, ‘check-cast/jumbo vAAAA, [email protected]‘
    if opcode == 0x02ff : return ‘52c‘, ‘instance-of/jumbo vAAAA, vBBBB, [email protected]‘
    if opcode == 0x03ff : return ‘41c‘, ‘new-instance/jumbo vAAAA, [email protected]BBBBBBBB‘
    if opcode == 0x04ff : return ‘52c‘, ‘new-array/jumbo vAAAA, vBBBB, [email protected]‘
    if opcode == 0x05ff : return ‘52rc‘, ‘filled-new-array/jumbo {vCCCC .. vNNNN}, [email protected]‘
    if opcode >= 0x06ff and opcode <= 0x13ff: return ‘52c‘, ‘iinstanceop/jumbo vAAAA, vBBBB, [email protected]‘
    if opcode >= 0x14ff and opcode <= 0x21ff: return ‘41c‘, ‘sstaticop/jumbo vAAAA, [email protected]‘
    if opcode >= 0x22ff and opcode <= 0x26ff: return ‘5rc‘, ‘invoke-kind/jumbo {vCCCC .. vNNNN}, [email protected]‘

InstrUtils

#!/usr/bin/env python
#coding:utf-8
import OpCode
import CommonUtils

class DecodedInstruction(object):
    """docstring for DecodedInstruction"""
    def __init__(self):
        super(DecodedInstruction, self).__init__()
        self.vA = None
        self.vB = None
        self.vC = None
        self.vD = None
        self.vE = None
        self.vF = None
        self.vG = None
        self.opcode = None
        self.op = None
        self.indexType = None
        self.smaliCode = None
        # DeCode.insns指令集内相对于起始地址的offset
        self.offset = None
        # 代码片段长度
        self.length = None

def dexDecodeInstruction(dexFile, dexCode, offset):
    byteCounts = offset / 4
    insns = dexCode.insns

    if insns == ‘‘:
        return None

    decodedInstruction = DecodedInstruction()
    opcode = int(insns[offset:offset+2], 16)
    formatIns, syntax = OpCode.getOpCode(opcode)

    decodedInstruction.opcode = opcode

    if formatIns == ‘10x‘:
        # Format: 00|op <=> op
        # (1) opcode=00 nop
        if opcode == 0x00:
            decodedInstruction.op = ‘nop‘
            decodedInstruction.smaliCode = ‘nop‘
            decodedInstruction.offset = offset
            decodedInstruction.length = 4

        # (2) opcode=0e return-void
        if opcode == 0x0e:
            decodedInstruction.op = ‘return-void‘
            decodedInstruction.smaliCode = ‘return-void‘
            decodedInstruction.offset = offset
            decodedInstruction.length = 4

        # (3) opcode=3e..43 unused
        if opcode >= 0x3e and opcode <= 0x43:
            decodedInstruction.op = ‘unused‘
            decodedInstruction.smaliCode = ‘unused‘
            decodedInstruction.offset = offset
            decodedInstruction.length = 4

        # (4) opcode=73 unused
        if opcode == 0x73:
            decodedInstruction.op = ‘unused‘
            decodedInstruction.smaliCode = ‘unused‘
            decodedInstruction.offset = offset
            decodedInstruction.length = 4

        # (5) opcode=79..7a unused
        if opcode >= 0x79 and opcode <= 0x7a:
            decodedInstruction.op = ‘unused‘
            decodedInstruction.smaliCode = ‘unused‘
            decodedInstruction.offset = offset
            decodedInstruction.length = 4

        # (6) opcode=e3..fe unused
        if opcode >= 0xe3 and opcode <= 0xfe:
            decodedInstruction.op = ‘unused‘
            decodedInstruction.smaliCode = ‘unused‘
            decodedInstruction.offset = offset
            decodedInstruction.length = 4

    elif formatIns == ‘12x‘: # op vA, vB
        # Format: B|A|op <=> op vA, vB
        op = ‘????‘
        # (1) opcode=01 move vA, vB
        if opcode == 0x01:
            op = ‘move‘
        # (2) opcode=04 move-wide vA, vB
        if opcode == 0x04:
            op = ‘move-wide‘
        # (3) opcode=07 move-object vA, vB
        if opcode == 0x07:
            op = ‘move-object‘
        # (4) opcode=21 array-length vA, vB
        if opcode == 0x21:
            op = ‘array-length‘
        # (5) opcode7b..8f unop vA, vB
        if opcode >= 0x7b and opcode <= 0x8f:
            unop = [‘neg-int‘, ‘not-int‘, ‘neg-long‘, ‘not-long‘, ‘neg-float‘, ‘neg-double‘, ‘int-to-long‘, ‘int-to-float‘, ‘int-to-double‘,
                    ‘long-to-int‘, ‘long-to-float‘, ‘long-to-double‘, ‘float-to-int‘, ‘float-to-long‘, ‘float-to-double‘,
                    ‘double-to-int‘, ‘double-to-long‘, ‘double-to-float‘, ‘int-to-byte‘, ‘int-to-char‘, ‘int-to-short‘]
            op = unop[opcode - 0x7b]
        # (6) opcode=b0..cf binop/2addr vA, vB
        if opcode >= 0xb0 and opcode <= 0xcf:
            ops = [‘add-int/2addr‘, ‘sub-int/2addr‘, ‘mul-int/2addr‘, ‘div-int/2addr‘, ‘rem-int/2addr‘, ‘and-int/2addr‘, ‘or-int/2addr‘, ‘xor-int/2addr‘, ‘shl-int/2addr‘, ‘shr-int/2addr‘, ‘ushr-int/2addr‘,
                     ‘add-long/2addr‘, ‘sub-long/2addr‘, ‘mul-long/2addr‘, ‘div-long/2addr‘, ‘rem-long/2addr‘, ‘and-long/2addr‘, ‘or-long/2addr‘, ‘xor-long/2addr‘, ‘shl-long/2addr‘, ‘shr-long/2addr‘,‘ushr-long/2addr‘,
                     ‘add-float/2addr‘, ‘sub-float/2addr‘, ‘mul-float/2addr‘, ‘div-float/2addr‘, ‘rem-float/2addr‘,
                     ‘add-double/2addr‘, ‘sub-double/2addr‘, ‘mul-double/2addr‘, ‘div-double/2addr‘, ‘rem-double/2addr‘]
            op = ops[opcode - 0xb0]

        B = int(insns[offset + 2:offset + 3], 16)
        A = int(insns[offset + 3:offset + 4], 16)

        decodedInstruction.op = op
        decodedInstruction.vA = A
        decodedInstruction.vB = B
        decodedInstruction.smaliCode = ‘%s v%d, v%d‘ % (op, A, B)
        decodedInstruction.offset = offset
        decodedInstruction.length = 4

    elif formatIns == ‘11n‘:
        # Format: B|A|op <=> # op vA, #+B
        # (1) opcode=12 const/4 vA, #+B
        B = int(insns[offset+2:offset+3], 16)
        A = int(insns[offset+3:offset+4], 16)

        decodedInstruction.op = ‘const/4‘
        decodedInstruction.vA = A
        decodedInstruction.B = B
        decodedInstruction.smaliCode = ‘const/4 v%d, #+%d‘ % (A, B)
        decodedInstruction.offset = offset
        decodedInstruction.length = 4

    elif formatIns == ‘11x‘:
        # Format: AA|op <=> # op vAA
        op = ‘????‘
        # (1) opcode=0a move-result vAA
        if opcode == 0x0a:
            op = ‘move-result‘
        # (2) opcode=0b move-result-wide vAA
        if opcode == 0x0b:
            op = ‘move-result-wide‘
        # (3) opcode=0c move-result-object vAA
        if opcode == 0x0c:
            op = ‘move-result-object‘
        # (4) opcode=0d move-exception vAA
        if opcode == 0x0d:
            op = ‘move-exception‘
        # (5) opcode=0f return vAA
        if opcode == 0x0f:
            op = ‘return‘
        # (6) opcode=10 return-wide vAA
        if opcode == 0x10:
            op = ‘return-wide‘
        # (7) opcode=11 return-object vAA
        if opcode == 0x11:
            op = ‘return-object‘
        # (8) opcode=1d monitor-enter vAA
        if opcode == 0x1d:
            op = ‘monitor-enter‘
        # (9) opcode=1e monitor-exit vAA
        if opcode == 0x1e:
            op = ‘monitor-exit‘
        # (10) opcode=27 throw vAA
        if opcode == 0x27:
            op = ‘throw‘

        AA = int(insns[offset + 2:offset + 4], 16)

        decodedInstruction.op = op
        decodedInstruction.vA = AA
        decodedInstruction.smaliCode = ‘%s v%d‘ % (op, AA)
        decodedInstruction.offset = offset
        decodedInstruction.length = 4

    elif formatIns == ‘10t‘:
        # Format: AA|op <=> # op +AA
        # (1) opcode=28 goto +AA
        AA = int(insns[offset + 2:offset + 4], 16)
        buma = CommonUtils.byte_to_buma(AA)

        decodedInstruction.op = ‘goto‘
        decodedInstruction.vA = AA
        decodedInstruction.smaliCode = ‘goto %s //%s‘ % (hex(offset/4+buma), hex(buma))
        decodedInstruction.offset = offset
        decodedInstruction.length = 4

    elif formatIns == ‘20t‘:
        # Format: 00|op AAAA <=> # op +vAAAA
        # (1) opcode=29 goto/16 +AAAA
        if opcode == 0x29:
            AAAA = int(insns[offset + 2:offset + 8], 16)
            buma = CommonUtils.word_to_buma(int(insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘), 16))

            decodedInstruction.op = ‘goto/16‘
            decodedInstruction.vA = AAAA
            decodedInstruction.smaliCode = ‘goto/16 %s //%s‘ % (hex(offset/4+buma), hex(buma))
            decodedInstruction.offset = offset
            decodedInstruction.length = 8

    elif formatIns == ‘20bc‘:
        # Format: AA|op BBBB <=> op AA, [email protected]
        # 无opcode
        # TODO
        pass
    elif formatIns == ‘22x‘:
        # Format: AA|op BBBB <=> op vAA, vBBBB
        op = ‘????‘
        # (1) opcode=02 move/from16 vAA, vBBBB
        if opcode == 0x02:
            op = ‘move/from16‘
        # (2) opcode=05 move-wide/from16 vAA, vBBBB
        if opcode == 0x05:
            op = ‘move-wide/from16‘
        # (3) opcode=08 move-object/from16 vAA, vBBBB
        if opcode == 0x08:
            op = ‘move-object/from16‘

        AA = int(insns[offset + 2:offset + 4], 16)
        BBBB = int(insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘), 16)

        decodedInstruction.op = op
        decodedInstruction.vA = AA
        decodedInstruction.vB = BBBB
        decodedInstruction.smaliCode = ‘%s v%d, v%s‘ % (op, AA, BBBB)
        decodedInstruction.offset = offset
        decodedInstruction.length = 8

    elif formatIns == ‘21t‘:
        # Format: AA|op BBBB <=> op vAA, +BBBB
        op = ‘????‘
        # (1) opcode=38..3d if-testz vAA, +BBBB
        if opcode >= 0x38 and opcode <= 0x3d:
            ops = [‘if-eqz‘, ‘if-nez‘, ‘if-ltz‘, ‘if-gez‘, ‘if-gtz‘, ‘if-lez‘]
            op = ops[opcode - 0x38]

        AA = int(insns[offset + 2:offset + 4], 16)
        BBBB = int(insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘), 16)

        decodedInstruction.op = op
        decodedInstruction.vA = AA
        decodedInstruction.vB = BBBB
        decodedInstruction.smaliCode = ‘%s v%d, %s //+%s‘ % (op, AA, hex(BBBB+offset/4), hex(BBBB))
        decodedInstruction.offset = offset
        decodedInstruction.length = 8

    elif formatIns == ‘21s‘:
        # Format: AA|op BBBB <=> op vAA, #+BBBB
        op = ‘????‘
        # (1) opcode=13 const/16 vAA, #_BBBB
        if opcode == 0x13:
            op = ‘const/16‘
        # (2) opcode=16 const-wide/16 vAA, #+BBBB
        if opcode == 0x16:
            op = ‘const-wide/16‘

        AA = int(insns[offset + 2:offset + 4], 16)
        BBBB = int(insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘), 16)

        decodedInstruction.op = op
        decodedInstruction.vA = AA
        decodedInstruction.vB = BBBB
        decodedInstruction.smaliCode = ‘%s v%d, #+%s‘ % (op, AA, BBBB)
        decodedInstruction.offset = offset
        decodedInstruction.length = 8

    elif formatIns == ‘21h‘:
        # Format: AA|op BBBB <=> op vAA, #+BBBB0000[00000000]
        AA = int(insns[offset + 2:offset + 4], 16)
        BBBB = insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘)

        # (1) opcode=15 const/high16 vAA, #+BBBB0000
        if opcode == 0x15:
            op = ‘const/high16‘

            decodedInstruction.op = op
            decodedInstruction.vA = AA
            decodedInstruction.vB = int(BBBB + ‘0000‘, 16)
            decodedInstruction.smaliCode = ‘%s v%d, #+%s‘ % (op, AA, int(BBBB + ‘0000‘, 16))
            decodedInstruction.offset = offset
            decodedInstruction.length = 8

        # (2) opcode=19 const-wide/high16 vAA, #+BBBB000000000000
        if opcode == 0x19:
            op = ‘const-wide/high16‘

            decodedInstruction.op = op
            decodedInstruction.vA = AA
            decodedInstruction.vB = int(BBBB + ‘000000000000‘, 16)
            decodedInstruction.smaliCode = ‘%s v%d, #+%s‘ % (op, AA, int(BBBB + ‘000000000000‘, 16))
            decodedInstruction.offset = offset
            decodedInstruction.length = 8

    elif formatIns == ‘21c‘:
        # Format: AA|op BBBB <=> op vAA, [type|field|string]@BBBB
        indexType = ‘????‘
        op = ‘????‘
        indexStr = ‘‘

        AA = int(insns[offset + 2:offset + 4], 16)
        BBBB = insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘)

        # (1) opcode=1a const-string vAA, [email protected]
        if opcode == 0x1a:
            op = ‘const-string‘
            indexType = ‘string‘
            indexStr = dexFile.getDexStringId(int(BBBB, 16))
        # (2) opcode=1c const-class vAA, [email protected]
        if opcode == 0x1c:
            op = ‘const-class‘
            indexType = ‘type‘
            indexStr = dexFile.getDexTypeId(int(BBBB, 16))
        # (3) opcode=1f check-cast vAA, [email protected]
        if opcode == 0x1f:
            op = ‘check-cast‘
            indexType = ‘type‘
            indexStr = dexFile.getDexTypeId(int(BBBB, 16))
        # (4) opcode=22 new-instance vAA, [email protected]
        if opcode == 0x22:
            op = ‘new-instance‘
            indexType = ‘type‘
            indexStr = dexFile.getDexTypeId(int(BBBB, 16))
        # (5) opcode=60..6d sstaticop vAA, [email protected]
        if opcode >= 0x60 and opcode <=0x6d:
            sstaticop = [‘sget‘, ‘sget-wide‘, ‘sget-object‘, ‘sget-boolean‘, ‘sget-byte‘, ‘sget-char‘,
                         ‘sget-char‘, ‘sget-short‘, ‘sput‘, ‘sput-wide‘, ‘sput-object‘, ‘sput-boolean‘,
                         ‘sput-byte‘, ‘sput-char‘, ‘sput-short‘]
            op = sstaticop[opcode - 0x60]
            indexType = ‘field‘
            dexFieldIdObj = dexFile.DexFieldIdList[int(BBBB, 16)]
            indexStr = dexFieldIdObj.toString(dexFile)

        decodedInstruction.op = op
        decodedInstruction.vA = AA
        decodedInstruction.vB = int(BBBB, 16)
        decodedInstruction.indexType = indexType
        decodedInstruction.smaliCode = ‘%s v%d, %[email protected]%s //%s‘ % (op, AA, indexType, BBBB, indexStr)
        decodedInstruction.offset = offset
        decodedInstruction.length = 8

    elif formatIns == ‘23x‘:
        # Format: AA|op CC|BB <=> op vAA, vBB, vCC
        op = ‘????‘
        # (1) opcode=2d..31 cmpkind vAA, vBB, vCC
        if opcode >= 0x2d and opcode <= 0x31:
            cmpkind = [‘cmpl-float‘, ‘cmpg-float‘, ‘cmpl-double‘, ‘cmpg-double‘, ‘cmp-long‘]
            op =cmpkind[opcode - 0x2d]
        # (2) opcode=44..51 arrayop vAA, vBB, vCC
        if opcode >= 0x44 and opcode <= 0x51:
            arrayop = [‘aget‘, ‘aget-wide‘, ‘aget-object‘, ‘aget-boolean‘, ‘aget-byte‘, ‘aget-char‘, ‘aget-short‘,
                       ‘aput‘, ‘aput-wide‘, ‘aput-object‘, ‘aput-boolean‘, ‘aput-byte‘, ‘aput-char‘, ‘aput-short‘]
            op = arrayop[opcode - 0x44]
        # (3) opcode=90..af binop vAA, vBB, vCC
        if opcode >= 0x90 and opcode <= 0xaf:
            binop = [‘add-int‘, ‘sub-int‘, ‘mul-int‘, ‘div-int‘, ‘rem-int‘, ‘and-int‘, ‘or-int‘, ‘xor-int‘, ‘shl-int‘, ‘shr-int‘, ‘ushr-int‘,
                     ‘add-long‘, ‘sub-long‘, ‘mul-long‘, ‘div-long‘, ‘rem-long‘, ‘and-long‘, ‘or-long‘, ‘xor-long‘, ‘shl-long‘, ‘shr-long‘, ‘ushr-long‘,
                     ‘add-float‘, ‘sub-float‘, ‘mul-float‘, ‘div-float‘, ‘rem-float‘,
                     ‘add-double‘, ‘sub-double‘, ‘mul-double‘, ‘div-double‘, ‘rem-double‘]
            op = binop[opcode - 0x90]

        AA = int(insns[offset + 2:offset + 4], 16)
        BB = int(insns[offset + 4:offset + 6], 16)
        CC = int(insns[offset + 6:offset + 8], 16)

        decodedInstruction.op = op
        decodedInstruction.vA = AA
        decodedInstruction.vB = BB
        decodedInstruction.vC = CC
        decodedInstruction.smaliCode = ‘%s v%d, v%d, v%d‘ % (op, AA, BB, CC)
        decodedInstruction.offset = offset
        decodedInstruction.length = 8

    elif formatIns == ‘22b‘:
        # Format: AA|op CC|BB <=> op vAA, vBB, #+CC
        # (1) opcode=d8..e2 binop/lit8 vAA, vBB, #+CC
        if opcode >= 0xd8 and opcode <= 0xe2:
            ops = [‘add-int/lit8‘, ‘rsub-int/lit8‘, ‘mul-int/lit8‘, ‘div-int/lit8‘, ‘rem-int/lit8‘, ‘and-int/lit8‘,
                   ‘or-int/lit8‘, ‘xor-int/lit8‘, ‘shl-int/lit8‘, ‘shr-int/lit8‘, ‘ushr-int/lit8‘]
            op = ops[opcode - 0xd8]

        AA = int(insns[offset + 2:offset + 4], 16)
        BB = int(insns[offset + 4:offset + 6], 16)
        CC = int(insns[offset + 6:offset + 8], 16)

        decodedInstruction.op = op
        decodedInstruction.vA = AA
        decodedInstruction.vB = BB
        decodedInstruction.vC = CC
        decodedInstruction.smaliCode = ‘%s v%d, v%d, #+v%d‘ % (op, AA, BB, CC)
        decodedInstruction.offset = offset
        decodedInstruction.length = 8

    elif formatIns == ‘22t‘:
        # Format: B|A|op CCCC <=> op vA, vB, +CCCC
        op = ‘????‘
        # (1) opcode=32..37 if-test vA, vB, +CCCC
        if opcode >=0x32 and opcode <= 0x37:
            ops = [‘if-eq‘, ‘if-ne‘, ‘if-lt‘, ‘if-ge‘, ‘if-gt‘, ‘if-le‘]
            op = ops[opcode - 0x32]
        B = int(insns[offset + 2: offset + 3], 16)
        A = int(insns[offset + 3: offset + 4], 16)
        CCCC = insns[offset+4:offset+8].decode(‘hex‘)[::-1].encode(‘hex‘)

        decodedInstruction.op = op
        decodedInstruction.vA = A
        decodedInstruction.vB = B
        decodedInstruction.vC = CCCC
        decodedInstruction.smaliCode = ‘%s v%d, v%d, %s // +%s‘ % (op, A, B, hex(offset/4+int(CCCC, 16)), CCCC)
        decodedInstruction.offset = offset
        decodedInstruction.length = 8

    elif formatIns == ‘22s‘:
        # Format: B|A|op CCCC <=> op vA, vB, #+CCCC
        op = ‘????‘
        # (1) opcode=d0..d7 binop/lit16 vA, vB, #+CCCC
        if opcode >= 0xd0 and opcode <= 0xd7:
            ops = [‘add-int/lit16‘, ‘rsub-int‘, ‘mul-int/lit16‘, ‘div-int/lit16‘, ‘rem-int/lit16‘, ‘and-int/lit16‘, ‘or-int/lit16‘, ‘xor-int/lit16‘]
            op = ops[opcode - 0xd0]

        B = int(insns[offset + 2: offset + 3], 16)
        A = int(insns[offset + 3: offset + 4], 16)
        CCCC = insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘)

        decodedInstruction.op = op
        decodedInstruction.vA = A
        decodedInstruction.vB = B
        decodedInstruction.vC = int(CCCC, 16)
        decodedInstruction.smaliCode = ‘%s v%d, v%d, #+%s‘ % (op, A, B, CCCC)
        decodedInstruction.offset = offset
        decodedInstruction.length = 8

    elif formatIns == ‘22c‘:
        # Format: B|A|op CCCC <=> op vA, vB, [type|field]@CCCC
        op = ‘????‘
        indexType = ‘????‘
        indexStr = ‘‘

        B = int(insns[offset + 2:offset + 3], 16)
        A = int(insns[offset + 3:offset + 4], 16)
        CCCC = insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘)

        # (1) opcode=20 instance-of vA, vB, [email protected]
        if opcode == 0x20:
            op = ‘instance-of‘
            indexType = ‘type‘
            indexStr = dexFile.DexTypeIdList[int(CCCC, 16)]
        # (2) opcode=23 new-array vA, vB, [email protected]
        if opcode == 0x23:
            op = ‘new-array‘
            indexType = ‘type‘
            indexStr = dexFile.DexTypeIdList[int(CCCC, 16)]
        # (3) opcode=52..5f iinstanceop vA, vB, [email protected]
        if opcode >= 0x52 and opcode <= 0x5f:
            iinstanceop = [‘iget‘, ‘iget-wide‘, ‘iget-object‘, ‘iget-boolean‘, ‘iget-byte‘, ‘iget-char‘, ‘iget-short‘,
                           ‘iput‘, ‘iput-wide‘, ‘iput-object‘, ‘iput-boolean‘, ‘iput-byte‘, ‘iput-char‘, ‘put-short‘]
            op = iinstanceop[opcode - 0x52]
            indexType = ‘field‘
            dexFieldIdObj = dexFile.DexFieldIdList[int(CCCC, 16)]
            indexStr = dexFieldIdObj.toString(dexFile)

        decodedInstruction.op = op
        decodedInstruction.vA = A
        decodedInstruction.vB = B
        decodedInstruction.vC = int(CCCC, 16)
        decodedInstruction.indexType = indexType
        decodedInstruction.smaliCode = ‘%s v%d, v%d %[email protected]%s //%s‘ % (op, A, B, indexType, CCCC, indexStr)
        decodedInstruction.offset = offset
        decodedInstruction.length = 8

    elif formatIns == ‘22cs‘:
        # Format: B|A|op CCCC <=> op vA, vB, [email protected]
        # 无opcode
        # TODO
        pass
    elif formatIns == ‘30t‘:
        # Format: ??|op AAAAlo AAAAhi <=> op +AAAAAAAA
        # (1) opcode=2a goto/32 +AAAAAAAA
        if opcode == 0x2a:
            AAAAAAAA = insns[offset + 2:offset + 12].decode(‘hex‘)[::-1].encode(‘hex‘)
            buma = CommonUtils.word_to_buma(int(insns[offset + 4:offset + 12].decode(‘hex‘)[::-1].encode(‘hex‘), 16))

            decodedInstruction.op = ‘goto/32‘
            decodedInstruction.vA = int(AAAAAAAA, 16)
            decodedInstruction.smaliCode = ‘goto/32 %s //%s‘ % (hex(offset/4+buma), hex(buma))
            decodedInstruction.offset = offset
            decodedInstruction.length = 12

    elif formatIns == ‘32x‘:
        # Format: ??|op AAAA BBBB <=> op vAAAA, vBBBB
        op = ‘????‘
        # (1) opcode=03 move/16 vAAAA, vBBBB
        # (2) opcode=06 move-wide/16 vAAAA, vBBBB
        # (3) opcode=09 move-object/16 vAAAA, vBBBB
        if opcode == 0x03:
            op = ‘move/16‘
        if opcode == 0x06:
            op = ‘move-wide/16‘
        if opcode == 0x09:
            op = ‘move-object/16‘
        AAAA = insns[offset + 2:offset + 6].decode(‘hex‘)[::-1].encode(‘hex‘)
        BBBB = insns[offset + 6:offset + 10].decode(‘hex‘)[::-1].encode(‘hex‘)

        decodedInstruction.op = op
        decodedInstruction.vA = int(AAAA, 16)
        decodedInstruction.vB = int(BBBB, 16)
        decodedInstruction.smaliCode = ‘%s v%s, v%s‘ % (op, AAAA, BBBB)
        decodedInstruction.offset = offset
        decodedInstruction.length = 10

    elif formatIns == ‘31i‘:
        # Format: AA|op BBBBlo BBBBhi <=> op vAA, #+BBBBBBBB
        op = ‘????‘
        # (1) opcode=14 const vAA, #+BBBBBBBB
        if opcode == 0x14:
            op = ‘const‘
        # (2) opcode=17 const-wide/32 vAA, #+BBBBBBBB
        if opcode == 0x17:
            op = ‘const-wide/32‘

        AA = int(insns[offset + 2:offset + 4], 16)
        BBBBBBBB = insns[offset + 4:offset + 12].decode(‘hex‘)[::-1].encode(‘hex‘)

        decodedInstruction.op = op
        decodedInstruction.vA = AA
        decodedInstruction.vB = int(BBBBBBBB, 16)
        decodedInstruction.smaliCode = ‘%s v%d, #+%s‘ % (op, AA, BBBBBBBB)
        decodedInstruction.offset = offset
        decodedInstruction.length = 12

    elif formatIns == ‘31t‘:
        # Format: AA|op BBBBlo BBBBhi <=> op vAA, +BBBBBBBB
        op = ‘????‘
        # (1) opcode=26 fill-array-data vAA, +BBBBBBBB
        # (2) opcode=2b packed-switch vAA, +BBBBBBBB
        # (3) opcode=2c sparse-switch vAA, +BBBBBBBB
        if opcode == 0x26:
            op = ‘fill-array-data‘
        if opcode == 0x2b:
            op = ‘packed-switch‘
        if opcode == 0x2c:
            op = ‘sparse-switch‘

        AA = int(insns[offset + 2:offset + 4], 16)
        BBBBBBBB = insns[offset + 4:offset + 12].decode(‘hex‘)[::-1].encode(‘hex‘)
        pseudo_instructions_offset = int(BBBBBBBB, 16) + byteCounts
        retVal = parsePseudoInstruction(byteCounts, insns, pseudo_instructions_offset * 4)

        decodedInstruction.op = op
        decodedInstruction.vA = AA
        decodedInstruction.vB = int(BBBBBBBB, 16)
        decodedInstruction.smaliCode = ‘%s v%d, %08x // +%s, %s‘ % (op, AA, pseudo_instructions_offset, BBBBBBBB, retVal)
        decodedInstruction.offset = offset
        decodedInstruction.length = 12

    elif formatIns == ‘31c‘:
        # Format: AA|op BBBBlo BBBBhi <=> op vAA, [email protected]
        op = ‘????‘
        indexStr = ‘‘

        AA = int(insns[offset + 2:offset + 4], 16)
        BBBBBBBB = insns[offset + 4:offset + 12].decode(‘hex‘)[::-1].encode(‘hex‘)

        # (1) opcode=1b const-string/jumbo vAA, [email protected]
        if opcode == 0x1b:
            op = ‘const-string/jumbo‘
            indexStr = dexFile.DexStringIdList[int(BBBBBBBB, 16)]

            decodedInstruction.op = op
            decodedInstruction.vA = AA
            decodedInstruction.vB = BBBBBBBB
            decodedInstruction.smaliCode = ‘%s v%d, [email protected]%s //%s‘ % (op, AA, BBBBBBBB, indexStr)
            decodedInstruction.offset = offset
            decodedInstruction.length = 12

    elif formatIns == ‘35c‘:
        # Format: A|G|op BBBB F|E|D|C
        indexType = ‘????‘
        op = ‘????‘
        indexStr = ‘‘

        A = int(insns[offset + 2:offset + 3], 16)
        G = int(insns[offset + 3:offset + 4], 16)
        BBBB = insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘)

        registerStr = insns[offset + 8:offset + 12].decode(‘hex‘)[::-1].encode(‘hex‘)
        F = int(registerStr[:1], 16)
        E = int(registerStr[1:2], 16)
        D = int(registerStr[2:3], 16)
        C = int(registerStr[3:4], 16)

        # (1) opcode=24 filled-new-array {vC, vD, vE, vF, vG}, [email protected]
        if opcode == 0x24:
            op = ‘filled-new-array‘
            indexType = ‘type‘
            indexStr = dexFile.DexTypeIdList[int(BBBB, 16)]
        # (2) opcode=62..72 invoke-kind {vC, vD, vE, vF, vG}, [email protected]
        if opcode >= 0x6e and opcode <= 0x72:
            invoke_kind = [‘invoke-virtual‘, ‘invoke-super‘, ‘invoke-direct‘, ‘invoke-static‘, ‘invoke-interface‘]
            op = invoke_kind[opcode-0x6e]
            indexType = ‘method‘
            dexMethodIdObj = dexFile.DexMethodIdList[int(BBBB, 16)]
            indexStr = dexMethodIdObj.toString(dexFile)

        registers = None
        if A == 0:  # [A=0] op {}, [email protected]
            decodedInstruction.op = op
            decodedInstruction.vA = A
            decodedInstruction.vB = int(BBBB, 16)
            decodedInstruction.indexType = indexType
            decodedInstruction.smaliCode = ‘%s {}, %[email protected]%s //%s‘ % (op, indexType, BBBB, indexStr)
            decodedInstruction.offset = offset
            decodedInstruction.length = 12

        elif A == 1:  # [A=1] op {vC}, [email protected]
            decodedInstruction.op = op
            decodedInstruction.vA = A
            decodedInstruction.vB = int(BBBB, 16)
            decodedInstruction.vC = C
            decodedInstruction.indexType = indexType
            decodedInstruction.smaliCode = ‘%s {v%d}, %[email protected]%s //%s‘ % (op, C, indexType, BBBB, indexStr)
            decodedInstruction.offset = offset
            decodedInstruction.length = 12

        elif A == 2:  # [A=2] op {vC, vD}, [email protected]
            decodedInstruction.op = op
            decodedInstruction.vA = A
            decodedInstruction.vB = int(BBBB, 16)
            decodedInstruction.vC = C
            decodedInstruction.vD = D
            decodedInstruction.indexType = indexType
            decodedInstruction.smaliCode = ‘%s {v%d, v%d}, %[email protected]%s //%s‘ % (op, C, D, indexType, BBBB, indexStr)
            decodedInstruction.offset = offset
            decodedInstruction.length = 12

        elif A == 3:  # [A=3] op {vC, vD, vE}, [email protected]
            decodedInstruction.op = op
            decodedInstruction.vA = A
            decodedInstruction.vB = int(BBBB, 16)
            decodedInstruction.vC = C
            decodedInstruction.vD = D
            decodedInstruction.vE = E
            decodedInstruction.indexType = indexType
            decodedInstruction.smaliCode = ‘%s {v%d, v%d, v%d}, %[email protected]%s //%s‘ % (op, C, D, E, indexType, BBBB, indexStr)
            decodedInstruction.offset = offset
            decodedInstruction.length = 12

        elif A == 4:  # [A=4] op {vC, vD, vE, vF}, [email protected]
            decodedInstruction.op = op
            decodedInstruction.vA = A
            decodedInstruction.vB = int(BBBB, 16)
            decodedInstruction.vC = C
            decodedInstruction.vD = D
            decodedInstruction.vE = E
            decodedInstruction.vF = F
            decodedInstruction.indexType = indexType
            decodedInstruction.smaliCode = ‘%s {v%d, v%d, v%d, v%d}, %[email protected]%s //%s‘ % (op, C, D, E, F, indexType, BBBB, indexStr)
            decodedInstruction.offset = offset
            decodedInstruction.length = 12

        elif A == 5:  # [A=5] op {vC, vD, vE, vF, vG}, [email protected]
            decodedInstruction.op = op
            decodedInstruction.vA = A
            decodedInstruction.vB = int(BBBB, 16)
            decodedInstruction.vC = C
            decodedInstruction.vD = D
            decodedInstruction.vE = E
            decodedInstruction.vF = F
            decodedInstruction.vG = G
            decodedInstruction.indexType = indexType
            decodedInstruction.smaliCode = ‘%s {v%d, v%d, v%d, v%d, %d}, %[email protected]%s //%s‘ % (op, C, D, E, F, G, indexType, BBBB, indexStr)
            decodedInstruction.offset = offset
            decodedInstruction.length = 12

    elif formatIns == ‘35ms‘:
        # Format: A|G|op BBBB F|E|D|C
        # 无opcode
        pass

    elif formatIns == ‘35mi‘:
        # Format: A|G|op BBBB F|E|D|C
        # 无opcode
        pass

    elif formatIns == ‘3rc‘:
        # Format: AA|op BBBB CCCC <=> op {vCCCC .. vNNNN} [method|type]@BBBB
        op = ‘????‘
        indexType = ‘????‘
        indexStr = ‘‘

        AA = int(insns[offset + 2:offset + 4], 16)
        BBBB = insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘)
        CCCC = int(insns[offset + 8:offset + 12].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        N = AA + CCCC - 1

        # (1) opcode=25 filled-new-array/range {vCCCC .. vNNNN}, [email protected]
        if opcode == 0x25:
            op = ‘fiiled-new-array/range‘
            indexType = ‘type‘
            indexStr = dexFile.DexTypeIdList[int(BBBB, 16)]
        # (2) opcode=74..78 invoke-kind/range {vCCCC .. vNNNN}, [email protected]
        if opcode >= 0x74 and opcode <= 0x78:
            ops = [‘invoke-virtual/range‘, ‘invoke-super/range‘, ‘invoke-direct/range‘, ‘invoke-static/range‘, ‘invoke-intenrface/range‘]
            op = ops[opcode - 0x74]
            indexType = ‘method‘
            dexMethodIdObj = dexFile.DexMethodIdList[int(BBBB, 16)]
            indexStr = dexMethodIdObj.toString(dexFile)

        registers = ‘‘
        for i in range(N):
            registers += ‘v‘ + str(CCCC + i) + ‘,‘

        decodedInstruction.op = op
        decodedInstruction.vA = AA
        decodedInstruction.vB = int(BBBB, 16)
        decodedInstruction.vC = CCCC
        decodedInstruction.indexType = indexType
        decodedInstruction.smaliCode = ‘%s {%s} %[email protected]%s //%s‘ % (op, registers, indexType, BBBB, indexStr)
        decodedInstruction.offset = offset
        decodedInstruction.length = 12

    elif formatIns == ‘3rms‘:
        # Format: AA|op BBBB CCCC <=> op {vCCCC .. vNNNN}, [email protected]
        # 无opcode
        pass
    elif formatIns == ‘3rmi‘:
        # Format: AA|op BBBB CCCC <=> op {vCCCC .. vNNNN}, [email protected]
        # 无opcode
        pass
    elif formatIns == ‘51l‘:
        # Format: AA|op BBBBlo BBBB BBBB BBBBhi <=>op vAA,#+BBBBBBBBBBBBBBBB
        # (1) opcode=18 const-wide vAA, #+BBBBBBBBBBBBBBBB
        if opcode == 0x18:
            AA = int(insns[offset+2:offset+4], 16)
            BBBBBBBBBBBBBBBB = insns[offset+4:offset+20].decode(‘hex‘)[::-1].encode(‘hex‘)

            decodedInstruction.op = ‘const-wide‘
            decodedInstruction.vA = AA
            decodedInstruction.vB = int(BBBBBBBBBBBBBBBB, 16)
            decodedInstruction.smaliCode = ‘const-wide v%d, #+%s‘ % (AA, BBBBBBBBBBBBBBBB)
            decodedInstruction.offset = offset
            decodedInstruction.length = 20

    elif formatIns == ‘33x‘:
        # Format: exop BB|AA CCCC <=> exop vAA, vBB, vCCCC
        # 无opcode
        pass
    elif formatIns == ‘32s‘:
        # Format: exop BB|AA CCCC <=> exop vAA, vBB, #+CCCC
        # 无opcode
        pass
    elif formatIns == ‘40sc‘:
        # Format: exop BBBBlo BBBBhi AAAA <=> exop AAAA, [email protected]
        # 无opcode
        pass

    ‘‘‘
    expaneded opcode
    opcode为ff,表示后面还有二级opcode
    ‘‘‘
    if opcode == 0xff:
        expanded_opcode = int(insns[offset:offset + 4].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        formatIns, _ = OpCode.getOpCode(expanded_opcode)

    if formatIns == ‘41c‘:
        expanded_opcode = int(insns[offset:offset + 4].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        # Format: exop BBBBlo BBBBhi AAAA <=> exop vAAAA, [field|type]@BBBBBBBB
        indexType = ‘????‘
        op = ‘????‘
        # (1) expanded_opcode=00ff const-class/jumbo vAAAA, [email protected]
        if expanded_opcode == 0x00ff:
            op = ‘const-class/jumbo‘
            indexType = ‘type‘
        # (2) expanded_opcode=01ff check-cast/jumbo vAAAA, [email protected]
        elif expanded_opcode == 0x01ff:
            op = ‘check-cast/jumbo‘
            indexType = ‘type‘
        # (3) expanded_opcode=03ff new-instance/jumbo vAAAA, [email protected]
        elif expanded_opcode == 0x03ff:
            op = ‘new-instance/jumbo‘
            indexType = ‘type‘
        # (4) expanded_opcode=14ff..21ff sstaticop/jumbo vAAAA, [email protected]
        elif expanded_opcode >= 0x14ff and expanded_opcode <= 0x21ff:
            ops = [‘sget/jumbo‘, ‘sget-wide/jumbo‘, ‘sget-object/jumbo‘, ‘sget-boolean/jumbo‘, ‘sget-byte/jumbo‘,
                   ‘sget-char/jumbo‘, ‘sget-short/jumbo‘, ‘sput/jumbo‘, ‘sput-wide/jumbo‘, ‘sput-object/jumbo‘,
                   ‘sput-boolean/jumbo‘, ‘sput-byte/jumbo‘, ‘sput-char/jumbo‘, ‘sput-short/jumbo‘]
            op = ops[expanded_opcode - 0x14ff]
            indexType = ‘field‘

        BBBBBBBB = int(insns[offset + 4:offset + 12].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        AAAA = int(insns[offset + 12:offset + 16].decode(‘hex‘)[::-1].encode(‘hex‘), 16)

        decodedInstruction.op = op
        decodedInstruction.vA = AAAA
        decodedInstruction.vB = BBBBBBBB
        decodedInstruction.indexType = indexType
        decodedInstruction.smaliCode = ‘%s v%d, %[email protected]%s‘ % (op, AAAA, indexType, hex(BBBBBBBB)[2:])
        decodedInstruction.offset = offset
        decodedInstruction.length = 16

    elif formatIns == ‘52c‘:
        expanded_opcode = int(insns[offset:offset + 4].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        indexType = ‘????‘
        op = ‘????‘
        # Format: exop CCCClo CCCChi AAAA BBBB <=> exop vAAAA, vBBBB, [field|type]@CCCCCCCC
        # (1) expanded_opcode=02ff instance-of/jumbo vAAAA, vBBBB, [email protected]
        if expanded_opcode == 0x02ff:
            op = ‘instance-of/jumbo‘
            indexType = ‘type‘
        # (2) expanded_opcode=04ff new-array/jumbo vAAAA, vBBBB, [email protected]
        if expanded_opcode == 0x02ff:
            op = ‘new-array/jumbo‘
            indexType = ‘type‘
        # (3) expanded_opcode=06ff..13ff    iinstanceop/jumbo vAAAA, vBBBB, [email protected]
        if expanded_opcode >= 0x06ff and expanded_opcode <= 0x13ff:
            ops = [‘iget/jumbo‘, ‘iget-wide/jumbo‘, ‘iget-object/jumbo‘, ‘iget-boolean/jumbo‘, ‘iget-byte/jumbo‘,
                   ‘iget-char/jumbo‘, ‘iget-short/jumbo‘, ‘iput/jumbo‘, ‘iput-wide/jumbo‘, ‘iput-object/jumbo‘,
                   ‘iput-boolean/jumbo‘, ‘iput-byte/jumbo‘, ‘iput-char/jumbo‘, ‘iput-short/jumbo‘]
            op = ops[expanded_opcode - 0x06ff]
            indexType = ‘field‘
        CCCCCCCC = int(insns[offset + 4:offset + 12].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        AAAA = int(insns[offset + 12:offset + 16].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        BBBB = int(insns[offset + 16:offset + 20].decode(‘hex‘)[::-1].encode(‘hex‘), 16)

        decodedInstruction.op = op
        decodedInstruction.vA = AAAA
        decodedInstruction.vB = BBBB
        decodedInstruction.vC = CCCCCCCC
        decodedInstruction.indexType = indexType
        decodedInstruction.smaliCode = ‘%s v%d, v%d %[email protected]%s‘ % (op, AAAA, BBBB, indexType, hex(CCCCCCCC)[2:])
        decodedInstruction.offset = offset
        decodedInstruction.length = 20

    elif formatIns == ‘5rc‘:
        expanded_opcode = int(insns[offset:offset + 4].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        indexType = ‘????‘
        op = ‘????‘
        # Format: exop BBBBlo BBBBhi AAAA CCCC <=> exop {vCCCC .. vNNNN}, [method|type]@BBBBBBBB
        # (1) expanded_opcode=05ff filled-new-array/jumbo {vCCCC .. vNNNN}, [email protected]
        if expanded_opcode == 0x05ff:
            op = ‘filled-new-array/jumbo‘
            indexType = ‘type‘
        # (2) expanded_opcode=22ff..26ff invoke-kind/jumbo {vCCCC .. vNNNN}, [email protected]
        if expanded_opcode >= 0x22ff and expanded_opcode <= 0x26ff:
            ops= [‘invoke-virtual/jumbo‘, ‘invoke-super/jumbo‘, ‘invoke-direct/jumbo‘,
                  ‘invoke-static/jumbo‘, ‘invoke-interface/jumbo‘]
            op = ops[expanded_opcode - 0x22ff]
            indexType = ‘method‘
        BBBBBBBB = int(insns[offset + 4:offset + 12].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        AAAA = int(insns[offset + 12:offset + 16].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        CCCC = int(insns[offset + 16:offset + 20].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        N = AAAA + CCCC - 1

        registers = ‘‘
        for i in range(N):
            registers += ‘v‘ + str(CCCC + i) + ‘,‘

        decodedInstruction.op = op
        decodedInstruction.vA = AAAA
        decodedInstruction.vB = BBBBBBBB
        decodedInstruction.vC = CCCC
        decodedInstruction.indexType = indexType
        decodedInstruction.smaliCode = ‘%s {%s} %[email protected]%s‘ % (op, registers, indexType, hex(BBBBBBBB)[2:])
        decodedInstruction.offset = offset
        decodedInstruction.length = 20

    return decodedInstruction

def parsePseudoInstruction(opcode_address, insns, offset):
    ident = insns[offset:offset+4].decode(‘hex‘)[::-1].encode(‘hex‘)
    # packed-switch-payload Format
    if ident == ‘0100‘:
        size = int(insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        first_key = int(insns[offset+8:offset+16].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        targets = []
        sb = ‘‘
        for i in range(size):
            _v = int(insns[offset+16+8*i:offset+16+8*(i+1)].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
            targets.append(_v)
            sb += ‘    \t%-16scase %d: goto %s\n‘ % (‘‘, first_key+i, hex(_v + opcode_address))
        return ‘\n‘+sb
    # sparse-switch-payload Format
    if ident == ‘0200‘:
        size = int(insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        keys = []
        targets = []
        sb = ‘‘
        for i in range(size):
            keys.append(int(insns[offset+8+8*i:offset+8+8*(i+1)].decode(‘hex‘)[::-1].encode(‘hex‘), 16))
            _v = int(insns[(offset+8+8*i)+size*8:(offset+8+8*(i+1))+size*8].decode(‘hex‘)[::-1].encode(‘hex‘), 16)

            hexNum = _v + opcode_address
            if hexNum > (0xffffffff+1):
                hexNum -= 0xffffffff+1
                tmp = hex(hexNum)
                if tmp.endswith(‘L‘):
                    tmp = tmp[:-1]
                targets.append(tmp)
            else:
                targets.append(hex(hexNum))
            sb += ‘    \t%-16scase %d: goto %s\n‘ % (‘‘, keys[i], targets[i])
        return ‘\n‘+sb
    # fill-array-data-payload Format
    if ident == ‘0300‘:
        element_width = int(insns[offset + 4:offset + 8].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        size = int(insns[offset + 8:offset + 16].decode(‘hex‘)[::-1].encode(‘hex‘), 16)
        data = []

        dataStr = ‘[‘
        for i in range(size):
            val = insns[offset + 16 + 2*element_width*i:offset + 16 + 2*element_width*(i+1)]
            data.append(val)
            dataStr += val + ‘,‘
        dataStr += ‘]‘
        return dataStr

原文地址:http://blog.51cto.com/haidragon/2131778

时间: 2024-08-06 05:32:23

dex文件解析(1)的相关文章

dex文件解析(2)

#!/usr/bin/env python #coding:utf-8 import sys import binascii import OpCode import InstrUtils MAP_ITEM_TYPE_CODES = { 0x0000 : "kDexTypeHeaderItem", 0x0001 : "kDexTypeStringIdItem", 0x0002 : "kDexTypeTypeIdItem", 0x0003 : &q

Python3解析dex文件

一.说明 1.1 背景说明 看<加密与解密>的时候反复听说"PE文件格式",到Android安全兴起就不断听说"dex文件格式".意思是看得懂的,但自己不能手解析一番总觉得不踏实,所以决定写个程序来解析一番. 本文其实算是姜维的Android逆向之旅---解析编译之后的Dex文件格式的Python实现版. 1.2 dex文件格式说明 类似exe文件是windows上的可执行文件,dex文件就是android中的可执行文件:pe格式是exe文件的格式,de

一篇文章带你搞懂DEX文件的结构

DEX文件就是Android Dalvik虚拟机运行的程序,关于DEX文件的结构的重要性我就不多说了.下面,开练! 建议:不要只看,跟着我做.看再多遍不如自己亲自实践一遍来的可靠,别问我为什么知道.泪崩ing..... 首先,我们需要自己构造一个dex文件,因为自己构造的比较简单,分析起来比较容易.等你简单的会了,难的自然也就懂了. 0x00■  构造DEX文件 首先,我们编写一个简单的Java程序,如下: public class HelloWorld { int a = 0; static

class 文件与dex文件区别 (dvm与jvm区别)及Android DVM介绍

区别一:dvm执行的是.dex格式文件  jvm执行的是.class文件   android程序编译完之后生产.class文件,然后,dex工具会把.class文件处理成.dex文件,然后把资源文件和.dex文件等打包成.apk文件.apk就是android package的意思. jvm执行的是.class文件. 区别二:dvm是基于寄存器的虚拟机  而jvm执行是基于虚拟栈的虚拟机.寄存器存取速度比栈快的多,dvm可以根据硬件实现最大的优化,比较适合移动设备. 区别三:.class文件存在很

统计JAR包DEX文件中的方法数目

 前段时间做Android项目中,一直出现方法数超过65535的问题,如果混淆后代码中的方法数目没有超过65535,可以通过 在project.properties文件中加上一行dex.force.jumbo=true,解决这个问题. 后来自己参考了网上的一些方法,写了个小工具用来统计JAR包和DEX文件中的方法数目.主要原理就是利用DEX的文件结构的文件头中有个method_ids_siz来统计方法数目. 现在分享出来,代码如下,直接拷贝编译成JAR包,然后控制台:java -jar XXX.

Android学习心得(15) --- Dex文件结构解析(1)

我在博客上发表一些我的Android学习心得,希望对大家能有帮助. 这一篇我们讲述一下Android可执行文件dex的结构解析. 参考Leb128数据类型 Android学习心得(5) --- dex数据类型LEB128 参考实例分析学习理解dex文件结构Android学习心得(15) --- Dex文件结构解析(1) 1.Dex背景 Android应用开发和Dalvik虚拟机Android应用所使用的编程语言是Java语言,在编译时使用JDK将Java源程序编程成标准的Java字节码文件. 而

Intel HEX文件解析

近期有一个需求就是为Arduino开发板做一个基于蓝牙的无线烧录程序.眼下的Arduino程序都是通过USB线连接到电脑的主机上,实际的传输过程是基于USB协议的,这个过程还是比較麻烦的.由于每次的编译完以后都须要通过一个USB线来完毕传输烧录的工作,这个还是非常麻烦的. 原理解读 在Arduino中.利用USB来完毕传输烧录大概是这么一个过程. 每一个Arduino源程序.即sketch文件,经过一系列的编译处理以后.终于会形成一个Intel HEX格式的文件.这个HEX文件事实上就一个被封装

AndroidNative层文件解析漏洞挖掘指南

| 导语 本文以手Q的一次文件解析类漏洞挖掘为例,叙述了Android Native层文件解析类型漏洞挖掘的过程 手Q这个应用从功能来说十分的庞大,如果使用类似MFFA的框架去挖掘文件解析类漏洞,效率低,而且文件入口在哪儿.如何利用脚本进行自动化都是非常大的问题.本文在一次手Q的文件解析类漏洞挖掘的过程中,提出了一种可能的解决问题的方案,妄称指南不吝赐教. 目录: 1.问题分析 2.流程图 3.so筛选 4.测试程序编写 5.test case生成 6.测试得出crash 7.未来的工作 0x0

Atitit。Tree文件解析器的原理流程与设计实现&#160;&#160;java&#160;&#160;c#&#160;php&#160;js

Atitit.Tree文件解析器的原理流程与设计实现  java  c# php js 1. 解析原理与流程1 1.1. 判断目录  ,表示服  dirFlagChar = "└├─";1 1.2. 剑豪制表符出现的位置与文件夹级别对应表1 1.3. 主要判读流程2 2. Tree结果2 3. Code----3 4. 结果5 1. 解析原理与流程 1.1. 判断目录  ,表示服  dirFlagChar = "└├─"; 其中-类似于剑豪的制表符是表示目录的..够