Module dvm
[hide private]
[frames] | no frames]

Source Code for Module dvm

   1  # This file is part of Androguard. 
   2  # 
   3  # Copyright (C) 2010, Anthony Desnos <desnos at t0t0.org> 
   4  # All rights reserved. 
   5  # 
   6  # Androguard is free software: you can redistribute it and/or modify 
   7  # it under the terms of the GNU Lesser General Public License as published by 
   8  # the Free Software Foundation, either version 3 of the License, or 
   9  # (at your option) any later version. 
  10  # 
  11  # Androguard is distributed in the hope that it will be useful, 
  12  # but WITHOUT ANY WARRANTY; without even the implied warranty of   
  13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  14  # GNU Lesser General Public License for more details. 
  15  # 
  16  # You should have received a copy of the GNU Lesser General Public License 
  17  # along with Androguard.  If not, see <http://www.gnu.org/licenses/>. 
  18   
  19  import bytecode 
  20   
  21   
  22  import misc 
  23  from bytecode import SV, SVs 
  24   
  25  import sys, re, types, string 
  26  from collections import namedtuple 
  27  from struct import pack, unpack, calcsize 
  28   
  29   
  30  HEADER = [ '<QL20sLLLLLLLLLLLLLLLLLLLL', namedtuple( "HEADER", "magic checksum signature file_size header_size endian_tag link_size link_off " \ 
  31                                                                 "map_off string_ids_size string_ids_off type_ids_size type_ids_off proto_ids_size " \ 
  32                                                                 "proto_ids_off field_ids_size field_ids_off method_ids_size method_ids_off "\ 
  33                                                                 "class_defs_size class_defs_off data_size data_off" ) ] 
  34   
  35  MAP_ITEM = [ '<HHLL', namedtuple("MAP_ITEM", "type unused size offset") ] 
  36   
  37  PROTO_ID_ITEM = [ '<LLL', namedtuple("PROTO_ID_ITEM", "shorty_idx return_type_idx parameters_off" ) ] 
  38  METHOD_ID_ITEM = [ '<HHL', namedtuple("METHOD_ID_ITEM", "class_idx proto_idx name_idx" ) ] 
  39  FIELD_ID_ITEM = [ '<HHL', namedtuple("FILED_ID_ITEM", "class_idx type_idx name_idx") ] 
  40   
  41  CLASS_DEF_ITEM = [ '<LLLLLLLL', namedtuple("CLASS_DEF_ITEM", "class_idx access_flags superclass_idx interfaces_off source_file_idx annotations_off class_data_off static_values_off") ] 
  42   
  43  TRY_ITEM = [ '<LHH', namedtuple("TRY_ITEM", "start_addr insn_count handler_off" ) ] 
  44  ANNOTATIONS_DIRECTORY_ITEM = [ '<LLLL', namedtuple("ANNOTATIONS_DIRECTORY_ITEM", "class_annotations_off fields_size annotated_methods_size annotated_parameters_size") ] 
  45   
  46  TYPE_MAP_ITEM = { 
  47                    0x0    : "TYPE_HEADER_ITEM", 
  48                    0x1    : "TYPE_STRING_ID_ITEM", 
  49                    0x2    : "TYPE_TYPE_ID_ITEM", 
  50                    0x3    : "TYPE_PROTO_ID_ITEM", 
  51                    0x4    : "TYPE_FIELD_ID_ITEM", 
  52                    0x5    : "TYPE_METHOD_ID_ITEM", 
  53                    0x6    : "TYPE_CLASS_DEF_ITEM", 
  54                    0x1000 : "TYPE_MAP_LIST", 
  55                    0x1001 : "TYPE_TYPE_LIST", 
  56                    0x1002 : "TYPE_ANNOTATION_SET_REF_LIST", 
  57                    0x1003 : "TYPE_ANNOTATION_SET_ITEM", 
  58                    0x2000 : "TYPE_CLASS_DATA_ITEM", 
  59                    0x2001 : "TYPE_CODE_ITEM", 
  60                    0x2002 : "TYPE_STRING_DATA_ITEM", 
  61                    0x2003 : "TYPE_DEBUG_INFO_ITEM", 
  62                    0x2004 : "TYPE_ANNOTATION_ITEM", 
  63                    0x2005 : "TYPE_ENCODED_ARRAY_ITEM", 
  64                    0x2006 : "TYPE_ANNOTATIONS_DIRECTORY_ITEM", 
  65                  } 
  66   
  67  SPARSE_SWITCH = [ '<HH', namedtuple("SPARSE_SWITCH", "ident size") ] 
  68  PACKED_SWITCH = [ '<HHL', namedtuple("PACKED_SWITCH", "ident size first_key") ] 
  69  FILL_ARRAY_DATA = [ '<HHL', namedtuple("FILL_ARRAY_DATA", "ident element_width size") ] 
  70   
71 -class FillArrayData :
72 - def __init__(self, buff) :
73 self.format = SVs( FILL_ARRAY_DATA[0], FILL_ARRAY_DATA[1], buff[ 0 : calcsize(FILL_ARRAY_DATA[0]) ] ) 74 75 format = self.general_format.get_value() 76 self.data = buff[ calcsize(FILL_ARRAY_DATA[0]) : calcsize(FILL_ARRAY_DATA[0]) + (general_format.size * general_format.element_width ) ]
77
78 - def show(self) :
79 print self.format.get_value(), self.data
80
81 - def get_size(self) :
82 general_format = self.format.get_value() 83 return calcsize(FILL_ARRAY_DATA[0]) + ( general_format.size * general_format.element_width )
84
85 -class SparseSwitch :
86 - def __init__(self, buff) :
87 self.format = SVs( SPARSE_SWITCH[0], SPARSE_SWITCH[1], buff[ 0 : calcsize(SPARSE_SWITCH[0]) ] ) 88 self.keys = [] 89 self.targets = [] 90 91 idx = calcsize(SPARSE_SWITCH[0]) 92 for i in range(0, self.format.get_value().size) : 93 self.keys.append( unpack('<L', buff[idx:idx+4]) ) 94 idx += 4 95 96 for i in range(0, self.format.get_value().size) : 97 self.targets.append( unpack('<L', buff[idx:idx+4]) ) 98 idx += 4
99
100 - def show(self) :
101 print self.format.get_value(), self.keys, self.targets
102
103 - def get_size(self) :
104 return calcsize(SPARSE_SWITCH[0]) + (self.format.get_value().size * calcsize('<L')) * 2
105
106 -class PackedSwitch :
107 - def __init__(self, buff) :
108 self.format = SVs( PACKED_SWITCH[0], PACKED_SWITCH[1], buff[ 0 : calcsize(PACKED_SWITCH[0]) ] ) 109 self.targets = [] 110 111 idx = calcsize(PACKED_SWITCH[0]) 112 for i in range(0, self.format.get_value().size) : 113 self.targets.append( unpack('<L', buff[idx:idx+4]) ) 114 idx += 4
115
116 - def show(self) :
117 print self.format.get_value(), self.targets
118
119 - def get_size(self) :
120 return calcsize(PACKED_SWITCH[0]) + (self.format.get_value().size * calcsize('<L'))
121 122 123 DALVIK_OPCODES = { 124 0x00 : [ "10x", "nop" ], 125 0x01 : [ "12x", "move", "vA, vB", "B|A|op" ], 126 0x02 : [ "22x", "move/from16", "vAA, vBBBB", "AA|op BBBB" ], 127 0x03 : [ "32x", "move/16", "vAAAA, vBBBB", "00|op AAAA BBBB" ], 128 0x04 : [ "12x", "move-wide", "vA, vB", "B|A|op" ], 129 0x05 : [ "22x", "move-wide/from16", "vAA, vBBBB", "AA|op BBBB" ], 130 0x06 : [ "32x", "move-wide/16", "vAAAA, vBBBB", "00|op AAAA BBBB" ], 131 0x07 : [ "12x", "move-object", "vA, vB", "B|A|op" ], 132 0x08 : [ "22x", "move-object/from16", "vAA, vBBBB", "AA|op BBBB" ], 133 0x09 : [ "32x", "move-object/16", "vAAAA, vBBBB", "00|op AAAA BBBB" ], 134 0x0a : [ "11x", "move-result", "vAA", "AA|op" ], 135 0x0b : [ "11x", "move-result-wide", "vAA", "AA|op" ], 136 0x0c : [ "11x", "move-result-object", "vAA", "AA|op" ], 137 0x0d : [ "11x", "move-exception", "vAA", "AA|op" ], 138 0x0e : [ "10x", "return-void" ], 139 0x0f : [ "11x", "return", "vAA", "AA|op" ], 140 0x10 : [ "11x", "return-wide", "vAA", "AA|op" ], 141 0x11 : [ "11x", "return-object", "vAA", "AA|op" ], 142 0x12 : [ "11n", "const/4", "vA, #+B", "B|A|op" ], 143 0x13 : [ "21s", "const/16", "vAA, #+BBBB", "AA|op BBBB" ], 144 0x14 : [ "31i", "const", "vAA, #+BBBBBBBB", "AA|op BBBB BBBB" ], 145 0x15 : [ "21h", "const/high16", "vAA, #+BBBB0000", "AA|op BBBB0000" ], 146 0x16 : [ "21s", "const-wide/16", "vAA, #+BBBB", "AA|op BBBB", "AA|op BBBB" ], 147 0x17 : [ "31i", "const-wide/32", "vAA, #+BBBBBBBB", "AA|op BBBB BBBB" ], 148 0x18 : [ "51l", "const-wide", "vAA, #+BBBBBBBBBBBBBBBB", "AA|op BBBB BBBB BBBB BBBB" ], 149 0x19 : [ "21h", "const-wide/high16", "vAA, #+BBBB000000000000", "AA|op BBBB000000000000" ], 150 0x1a : [ "21c", "const-string", "vAA, string@BBBB", "AA|op BBBB" ], 151 0x1b : [ "31c", "const-string/jumbo", "vAA, string@BBBBBBBB", "AA|op BBBB BBBB" ], 152 0x1c : [ "21c", "const-class", "vAA, type@BBBB", "AA|op BBBB" ], 153 0x1d : [ "11x", "monitor-enter", "vAA", "AA|op" ], 154 0x1e : [ "11x", "monitor-exit", "vAA", "AA|op" ], 155 0x1f : [ "21c", "check-cast", "vAA, type@BBBB", "AA|op BBBB" ], 156 0x20 : [ "22c", "instance-of", "vA, vB, type@CCCC", "B|A|op CCCC" ], 157 0x21 : [ "12x", "array-length", "vA, vB", "B|A|op" ], 158 0x22 : [ "21c", "new-instance", "vAA, type@BBBB", "AA|op BBBB" ], 159 0x23 : [ "22c", "new-array", "vA, vB, type@CCCC", "B|A|op CCCC" ], 160 0x24 : [ "35c", "filled-new-array", "vD, vE, vF, vG, vA, type@CCCC", "B|A|op CCCC G|F|E|D" ], 161 0x25 : [ "3rc", "filled-new-array/range", "", "" ], 162 0x26 : [ "31t", "fill-array-data", "vAA, +BBBBBBBB ", "AA|op BBBBBBBB", FillArrayData ], 163 0x27 : [ "11x", "throw", "vAA", "B|A|op" ], 164 0x28 : [ "10t", "goto", "+AA", "AA|op"], 165 0x29 : [ "20t", "goto/16", "+AAAA", "00|op AAAA" ], 166 0x2a : [ "30t", "goto/32", "+AAAAAAAA", "00|op AAAA AAAA" ], 167 0x2b : [ "31t", "packed-switch", "vAA, +BBBBBBBB ", "AA|op BBBBBBBB", PackedSwitch ], 168 0x2c : [ "31t", "sparse-switch", "vAA +BBBBBBBB", "AA|op BBBBBBBB", SparseSwitch ], 169 0x2d : [ "23x", "cmpl-float", "vAA, vBB, vCC", "AA|op CC|BB" ], 170 0x2e : [ "23x", "cmpg-float", "vAA, vBB, vCC", "AA|op CC|BB" ], 171 0x2f : [ "23x", "cmpl-double", "vAA, vBB, vCC", "AA|op CC|BB" ], 172 0x30 : [ "23x", "cmpg-double", "vAA, vBB, vCC", "AA|op CC|BB" ], 173 0x31 : [ "23x", "cmp-long", "vAA, vBB, vCC", "AA|op CC|BB" ], 174 0x32 : [ "22t", "if-eq", "vA, vB, +CCCC", "B|A|op CCCC" ], 175 0x33 : [ "22t", "if-ne", "vA, vB, +CCCC", "B|A|op CCCC" ], 176 0x34 : [ "22t", "if-lt", "vA, vB, +CCCC", "B|A|op CCCC" ], 177 0x35 : [ "22t", "if-ge", "vA, vB, +CCCC", "B|A|op CCCC" ], 178 0x36 : [ "22t", "if-gt", "vA, vB, +CCCC", "B|A|op CCCC" ], 179 0x37 : [ "22t", "if-le", "vA, vB, +CCCC", "B|A|op CCCC" ], 180 0x38 : [ "21t", "if-eqz", "vAA, +BBBB", "AA|op BBBB" ], 181 0x39 : [ "21t", "if-nez", "vAA, +BBBB", "AA|op BBBB" ], 182 0x3a : [ "21t", "if-ltz", "vAA, +BBBB", "AA|op BBBB" ], 183 0x3b : [ "21t", "if-gez", "vAA, +BBBB", "AA|op BBBB" ], 184 0x3c : [ "21t", "if-gtz", "vAA, +BBBB", "AA|op BBBB" ], 185 0x3d : [ "21t", "if-lez", "vAA, +BBBB", "AA|op BBBB" ], 186 0x44 : [ "23x", "aget", "vAA, vBB, vCC", "AA|op CC|BB" ], 187 0x45 : [ "23x", "aget-wide", "vAA, vBB, vCC", "AA|op CC|BB" ], 188 0x46 : [ "23x", "aget-object", "vAA, vBB, vCC", "AA|op CC|BB" ], 189 0x47 : [ "23x", "aget-boolean", "vAA, vBB, vCC", "AA|op CC|BB" ], 190 0x48 : [ "23x", "aget-byte", "vAA, vBB, vCC", "AA|op CC|BB" ], 191 0x49 : [ "23x", "aget-char", "vAA, vBB, vCC", "AA|op CC|BB" ], 192 0x4a : [ "23x", "aget-short", "vAA, vBB, vCC", "AA|op CC|BB" ], 193 0x4b : [ "23x", "aput", "vAA, vBB, vCC", "AA|op CC|BB" ], 194 0x4c : [ "23x", "aput-wide", "vAA, vBB, vCC", "AA|op CC|BB" ], 195 0x4d : [ "23x", "aput-object", "vAA, vBB, vCC", "AA|op CC|BB" ], 196 0x4e : [ "23x", "aput-boolean", "vAA, vBB, vCC", "AA|op CC|BB" ], 197 0x4f : [ "23x", "aput-byte", "vAA, vBB, vCC", "AA|op CC|BB" ], 198 0x50 : [ "23x", "aput-char", "vAA, vBB, vCC", "AA|op CC|BB" ], 199 0x51 : [ "23x", "aput-short", "vAA, vBB, vCC", "AA|op CC|BB" ], 200 0x52 : [ "22c", "iget", "vA, vB, field@CCCC", "B|A|op CCCC" ], 201 0x53 : [ "22c", "iget-wide", "vA, vB, field@CCCC", "B|A|op CCCC" ], 202 0x54 : [ "22c", "iget-object", "vA, vB, field@CCCC", "B|A|op CCCC" ], 203 0x55 : [ "22c", "iget-boolean", "vA, vB, field@CCCC", "B|A|op CCCC" ], 204 0x56 : [ "22c", "iget-byte", "vA, vB, field@CCCC", "B|A|op CCCC" ], 205 0x57 : [ "22c", "iget-char", "vA, vB, field@CCCC", "B|A|op CCCC" ], 206 0x58 : [ "22c", "iget-short", "vA, vB, field@CCCC", "B|A|op CCCC" ], 207 0x59 : [ "22c", "iput", "vA, vB, field@CCCC", "B|A|op CCCC" ], 208 0x5a : [ "22c", "iput-wide", "vA, vB, field@CCCC", "B|A|op CCCC" ], 209 0x5b : [ "22c", "iput-object", "vA, vB, field@CCCC", "B|A|op CCCC" ], 210 0x5c : [ "22c", "iput-boolean", "vA, vB, field@CCCC", "B|A|op CCCC" ], 211 0x5d : [ "22c", "iput-byte", "vA, vB, field@CCCC", "B|A|op CCCC" ], 212 0x5e : [ "22c", "iput-char", "vA, vB, field@CCCC", "B|A|op CCCC" ], 213 0x5f : [ "22c", "iput-short", "vA, vB, field@CCCC", "B|A|op CCCC" ], 214 0x60 : [ "21c", "sget", "vAA, field@BBBB", "AA|op BBBB" ], 215 0x61 : [ "21c", "sget-wide", "vAA, field@BBBB", "AA|op BBBB" ], 216 0x62 : [ "21c", "sget-object", "vAA, field@BBBB", "AA|op BBBB" ], 217 0x63 : [ "21c", "sget-boolean", "vAA, field@BBBB", "AA|op BBBB" ], 218 0x64 : [ "21c", "sget-byte", "vAA, field@BBBB", "AA|op BBBB" ], 219 0x65 : [ "21c", "sget-char", "vAA, field@BBBB", "AA|op BBBB" ], 220 0x66 : [ "21c", "sget-short", "vAA, field@BBBB", "AA|op BBBB" ], 221 0x67 : [ "21c", "sput", "vAA, field@BBBB", "AA|op BBBB" ], 222 0x68 : [ "21c", "sput-wide", "vAA, field@BBBB", "AA|op BBBB" ], 223 0x69 : [ "21c", "sput-object", "vAA, field@BBBB", "AA|op BBBB" ], 224 0x6a : [ "21c", "sput-boolean", "vAA, field@BBBB", "AA|op BBBB" ], 225 0x6b : [ "21c", "sput-byte", "vAA, field@BBBB", "AA|op BBBB" ], 226 0x6c : [ "21c", "sput-char", "vAA, field@BBBB", "AA|op BBBB" ], 227 0x6d : [ "21c", "sput-short", "vAA, field@BBBB", "AA|op BBBB" ], 228 0x6e : [ "35c", "invoke-virtual", "vB{vD, vE, vF, vG, vA}, meth@CCCC", "B|A|op CCCC G|F|E|D" ], 229 0x6f : [ "35c", "invoke-super", "vB{vD, vE, vF, vG, vA}, meth@CCCC", "B|A|op CCCC G|F|E|D" ], 230 0x70 : [ "35c", "invoke-direct", "vB{vD, vE, vF, vG, vA}, meth@CCCC", "B|A|op CCCC G|F|E|D" ], 231 0x71 : [ "35c", "invoke-static", "vB{vD, vE, vF, vG, vA}, meth@CCCC", "B|A|op CCCC G|F|E|D" ], 232 0x72 : [ "35c", "invoke-interface", "vB{vD, vE, vF, vG, vA}, meth@CCCC", "B|A|op CCCC G|F|E|D" ], 233 0x74 : [ "3rc", "invoke-virtual/range", "vB{vCCCC .. vNNNN}, meth@BBBB", "AA|op BBBB CCCC" ], 234 0x75 : [ "3rc", "invoke-super/range", "vB{vCCCC .. vNNNN}, meth@BBBB", "AA|op BBBB CCCC" ], 235 0x76 : [ "3rc", "invoke-direct/range", "vB{vCCCC .. vNNNN}, meth@BBBB", "AA|op BBBB CCCC" ], 236 0x77 : [ "3rc", "invoke-static/range", "vB{vCCCC .. vNNNN}, meth@BBBB", "AA|op BBBB CCCC" ], 237 0x78 : [ "3rc", "invoke-interface/range", "vB{vCCCC .. vNNNN}, meth@BBBB", "AA|op BBBB CCCC" ], 238 0x7b : [ "12x", "neg-int", "vA, vB", "B|A|op" ], 239 0x7c : [ "12x", "not-int", "vA, vB", "B|A|op" ], 240 0x7d : [ "12x", "neg-long", "vA, vB", "B|A|op" ], 241 0x7e : [ "12x", "not-long", "vA, vB", "B|A|op" ], 242 0x7f : [ "12x", "neg-float", "vA, vB", "B|A|op" ], 243 0x80 : [ "12x", "neg-double", "vA, vB", "B|A|op" ], 244 0x81 : [ "12x", "int-to-long", "vA, vB", "B|A|op" ], 245 0x82 : [ "12x", "int-to-float", "vA, vB", "B|A|op" ], 246 0x83 : [ "12x", "int-to-double", "vA, vB", "B|A|op" ], 247 0x84 : [ "12x", "long-to-int", "vA, vB", "B|A|op" ], 248 0x85 : [ "12x", "long-to-float", "vA, vB", "B|A|op" ], 249 0x86 : [ "12x", "long-to-double", "vA, vB", "B|A|op" ], 250 0x87 : [ "12x", "float-to-int", "vA, vB", "B|A|op" ], 251 0x88 : [ "12x", "float-to-long", "vA, vB", "B|A|op" ], 252 0x89 : [ "12x", "float-to-double", "vA, vB", "B|A|op" ], 253 0x8a : [ "12x", "double-to-int", "vA, vB", "B|A|op" ], 254 0x8b : [ "12x", "double-to-long", "vA, vB", "B|A|op" ], 255 0x8c : [ "12x", "double-to-float", "vA, vB", "B|A|op" ], 256 0x8d : [ "12x", "int-to-byte", "vA, vB", "B|A|op" ], 257 0x8e : [ "12x", "int-to-char", "vA, vB", "B|A|op" ], 258 0x8f : [ "12x", "int-to-short", "vA, vB", "B|A|op" ], 259 0x90 : [ "23x", "add-int", "vAA, vBB, vCC", "AA|op CC|BB" ], 260 0x91 : [ "23x", "sub-int", "vAA, vBB, vCC", "AA|op CC|BB" ], 261 0x92 : [ "23x", "mul-int", "vAA, vBB, vCC", "AA|op CC|BB" ], 262 0x93 : [ "23x", "div-int", "vAA, vBB, vCC", "AA|op CC|BB" ], 263 0x94 : [ "23x", "rem-int", "vAA, vBB, vCC", "AA|op CC|BB" ], 264 0x95 : [ "23x", "and-int", "vAA, vBB, vCC", "AA|op CC|BB" ], 265 0x96 : [ "23x", "or-int", "vAA, vBB, vCC", "AA|op CC|BB" ], 266 0x97 : [ "23x", "xor-int", "vAA, vBB, vCC", "AA|op CC|BB" ], 267 0x98 : [ "23x", "shl-int", "vAA, vBB, vCC", "AA|op CC|BB" ], 268 0x99 : [ "23x", "shr-int", "vAA, vBB, vCC", "AA|op CC|BB" ], 269 0x9a : [ "23x", "ushr-int", "vAA, vBB, vCC", "AA|op CC|BB" ], 270 0x9b : [ "23x", "add-long", "vAA, vBB, vCC", "AA|op CC|BB" ], 271 0x9c : [ "23x", "sub-long", "vAA, vBB, vCC", "AA|op CC|BB" ], 272 0x9d : [ "23x", "mul-long", "vAA, vBB, vCC", "AA|op CC|BB" ], 273 0x9e : [ "23x", "div-long", "vAA, vBB, vCC", "AA|op CC|BB" ], 274 0x9f : [ "23x", "rem-long", "vAA, vBB, vCC", "AA|op CC|BB" ], 275 0xa0 : [ "23x", "and-long", "vAA, vBB, vCC", "AA|op CC|BB" ], 276 0xa1 : [ "23x", "or-long", "vAA, vBB, vCC", "AA|op CC|BB" ], 277 0xa2 : [ "23x", "xor-long", "vAA, vBB, vCC", "AA|op CC|BB" ], 278 0xa3 : [ "23x", "shl-long", "vAA, vBB, vCC", "AA|op CC|BB" ], 279 0xa4 : [ "23x", "shr-long", "vAA, vBB, vCC", "AA|op CC|BB" ], 280 0xa5 : [ "23x", "ushr-long", "vAA, vBB, vCC", "AA|op CC|BB" ], 281 0xa6 : [ "23x", "add-float", "vAA, vBB, vCC", "AA|op CC|BB" ], 282 0xa7 : [ "23x", "sub-float", "vAA, vBB, vCC", "AA|op CC|BB" ], 283 0xa8 : [ "23x", "mul-float", "vAA, vBB, vCC", "AA|op CC|BB" ], 284 0xa9 : [ "23x", "div-float", "vAA, vBB, vCC", "AA|op CC|BB" ], 285 0xaa : [ "23x", "rem-float", "vAA, vBB, vCC", "AA|op CC|BB" ], 286 0xab : [ "23x", "add-double", "vAA, vBB, vCC", "AA|op CC|BB" ], 287 0xac : [ "23x", "sub-double", "vAA, vBB, vCC", "AA|op CC|BB" ], 288 0xad : [ "23x", "mul-double", "vAA, vBB, vCC", "AA|op CC|BB" ], 289 0xae : [ "23x", "div-double", "vAA, vBB, vCC", "AA|op CC|BB" ], 290 0xaf : [ "23x", "rem-double", "vAA, vBB, vCC", "AA|op CC|BB" ], 291 0xb0 : [ "12x", "add-int/2addr", "vA, vB", "B|A|op" ], 292 0xb1 : [ "12x", "sub-int/2addr", "vA, vB", "B|A|op" ], 293 0xb2 : [ "12x", "mul-int/2addr", "vA, vB", "B|A|op" ], 294 0xb3 : [ "12x", "div-int/2addr", "vA, vB", "B|A|op" ], 295 0xb4 : [ "12x", "rem-int/2addr", "vA, vB", "B|A|op" ], 296 0xb5 : [ "12x", "and-int/2addr", "vA, vB", "B|A|op" ], 297 0xb6 : [ "12x", "or-int/2addr", "vA, vB", "B|A|op" ], 298 0xb7 : [ "12x", "xor-int/2addr", "vA, vB", "B|A|op" ], 299 0xb8 : [ "12x", "shl-int/2addr", "vA, vB", "B|A|op" ], 300 0xb9 : [ "12x", "shr-int/2addr", "vA, vB", "B|A|op" ], 301 0xba : [ "12x", "ushr-int/2addr", "vA, vB", "B|A|op" ], 302 0xbb : [ "12x", "add-long/2addr", "vA, vB", "B|A|op" ], 303 0xbc : [ "12x", "sub-long/2addr", "vA, vB", "B|A|op" ], 304 0xbd : [ "12x", "mul-long/2addr", "vA, vB", "B|A|op" ], 305 0xbe : [ "12x", "div-long/2addr", "vA, vB", "B|A|op" ], 306 0xbf : [ "12x", "rem-long/2addr", "vA, vB", "B|A|op" ], 307 0xc0 : [ "12x", "and-long/2addr", "vA, vB", "B|A|op" ], 308 0xc1 : [ "12x", "or-long/2addr", "vA, vB", "B|A|op" ], 309 0xc2 : [ "12x", "xor-long/2addr", "vA, vB", "B|A|op" ], 310 0xc3 : [ "12x", "shl-long/2addr", "vA, vB", "B|A|op" ], 311 0xc4 : [ "12x", "shr-long/2addr", "vA, vB", "B|A|op" ], 312 0xc5 : [ "12x", "ushr-long/2addr", "vA, vB", "B|A|op" ], 313 0xc6 : [ "12x", "add-float/2addr", "vA, vB", "B|A|op" ], 314 0xc7 : [ "12x", "sub-float/2addr", "vA, vB", "B|A|op" ], 315 0xc8 : [ "12x", "mul-float/2addr", "vA, vB", "B|A|op" ], 316 0xc9 : [ "12x", "div-float/2addr", "vA, vB", "B|A|op" ], 317 0xca : [ "12x", "rem-float/2addr", "vA, vB", "B|A|op" ], 318 0xcb : [ "12x", "add-double/2addr", "vA, vB", "B|A|op" ], 319 0xcc : [ "12x", "sub-double/2addr", "vA, vB", "B|A|op" ], 320 0xcd : [ "12x", "mul-double/2addr", "vA, vB", "B|A|op" ], 321 0xce : [ "12x", "div-double/2addr", "vA, vB", "B|A|op" ], 322 0xcf : [ "12x", "rem-double/2addr", "vA, vB", "B|A|op" ], 323 0xd0 : [ "22s", "add-int/lit16", "vA, vB, #+CCCC", "B|A|op CCCC" ], 324 0xd1 : [ "22s", "rsub-int", "vA, vB, #+CCCC", "B|A|op CCCC" ], 325 0xd2 : [ "22s", "mul-int/lit16", "vA, vB, #+CCCC", "B|A|op CCCC" ], 326 0xd3 : [ "22s", "div-int/lit16", "vA, vB, #+CCCC", "B|A|op CCCC" ], 327 0xd4 : [ "22s", "rem-int/lit16", "vA, vB, #+CCCC", "B|A|op CCCC" ], 328 0xd5 : [ "22s", "and-int/lit16", "vA, vB, #+CCCC", "B|A|op CCCC" ], 329 0xd6 : [ "22s", "or-int/lit16", "vA, vB, #+CCCC", "B|A|op CCCC" ], 330 0xd7 : [ "22s", "xor-int/lit16", "vA, vB, #+CCCC", "B|A|op CCCC" ], 331 0xd8 : [ "22b", "add-int/lit8", "vAA, vBB, #+CC", "AA|op CC|BB" ], 332 0xd9 : [ "22s", "rsub-int/lit8", "vAA, vBB, #+CC", "AA|op CC|BB" ], 333 0xda : [ "22s", "mul-int/lit8", "vAA, vBB, #+CC", "AA|op CC|BB" ], 334 0xdb : [ "22s", "div-int/lit8", "vAA, vBB, #+CC", "AA|op CC|BB" ], 335 0xdc : [ "22s", "rem-int/lit8", "vAA, vBB, #+CC", "AA|op CC|BB" ], 336 0xdd : [ "22s", "and-int/lit8", "vAA, vBB, #+CC", "AA|op CC|BB" ], 337 0xde : [ "22s", "or-int/lit8", "vAA, vBB, #+CC", "AA|op CC|BB" ], 338 0xdf : [ "22s", "xor-int/lit8", "vAA, vBB, #+CC", "AA|op CC|BB" ], 339 0xe0 : [ "22s", "shl-int/lit8", "vAA, vBB, #+CC", "AA|op CC|BB" ], 340 0xe1 : [ "22s", "shr-int/lit8", "vAA, vBB, #+CC", "AA|op CC|BB" ], 341 0xe2 : [ "22s", "ushr-int/lit8", "vAA, vBB, #+CC", "AA|op CC|BB" ], 342 } 343
344 -def readuleb128(buff) :
345 result = ord( buff.read(1) ) 346 if result > 0x7f : 347 cur = ord( buff.read(1) ) 348 result = (result & 0x7f) | ((cur & 0x7f) << 7) 349 if cur > 0x7f : 350 cur = ord( buff.read(1) ) 351 result |= (cur & 0x7f) << 14 352 if cur > 0x7f : 353 cur = ord( buff.read(1) ) 354 result |= (cur & 0x7f) << 21 355 if cur > 0x7f : 356 cur = ord( buff.read(1) ) 357 result |= cur << 28 358 359 return result
360
361 -def readsleb128(buff) :
362 result = unpack( '<b', buff.read(1) )[0] 363 364 if result <= 0x7f : 365 result = (result << 25) 366 if result > 0x7fffffff : 367 result = (0x7fffffff & result) - 0x80000000 368 result = result >> 25 369 else : 370 cur = unpack( '<b', buff.read(1) )[0] 371 result = (result & 0x7f) | ((cur & 0x7f) << 7) 372 if cur <= 0x7f : 373 result = (result << 18) >> 18 374 else : 375 cur = unpack( '<b', buff.read(1) )[0] 376 result |= (cur & 0x7f) << 14 377 if cur <= 0x7f : 378 result = (result << 11) >> 11 379 else : 380 cur = unpack( '<b', buff.read(1) )[0] 381 result |= (cur & 0x7f) << 21 382 if cur <= 0x7f : 383 result = (result << 4) >> 4 384 else : 385 cur = unpack( '<b', buff.read(1) )[0] 386 result |= cur << 28 387 388 return result
389
390 -def writeuleb128(value) :
391 remaining = value >> 7 392 393 buff = "" 394 while remaining > 0 : 395 buff += pack( "<B", ((value & 0x7f) | 0x80) ) 396 397 value = remaining 398 remaining >>= 7 399 400 buff += pack( "<B", value & 0x7f ) 401 return buff
402
403 -def writesleb128(value) :
404 remaining = value >> 7 405 hasMore = True 406 end = 0 407 buff = "" 408 409 if (value & (-sys.maxint - 1)) == 0 : 410 end = 0 411 else : 412 end = -1 413 414 while hasMore : 415 hasMore = (remaining != end) or ((remaining & 1) != ((value >> 6) & 1)) 416 tmp = 0 417 if hasMore : 418 tmp = 0x80 419 420 buff += pack( "<B", (value & 0x7f) | (tmp) ) 421 value = remaining 422 remaining >>= 7 423 424 return buff
425
426 -class HeaderItem :
427 - def __init__(self, size, buff) :
428 self.__offset = buff.get_idx() 429 self.format = SVs( HEADER[0], HEADER[1], buff.read( calcsize(HEADER[0]) ) )
430
431 - def reload(self) :
432 pass
433
434 - def get_raw(self) :
435 return [ bytecode.Buff( self.__offset, self.format.get_value_buff() ) ]
436
437 - def get_value(self) :
438 return self.format.get_value()
439
440 - def show(self) :
441 bytecode._Print("HEADER", self.format)
442
443 - def get_off(self) :
444 return self.__offset
445
446 -class AnnotationOffItem :
447 - def __init__(self, buff, cm) :
448 self.__offset = buff.get_idx() 449 self.annotation_off = SV( '<L', buff.read( 4 ) )
450
451 - def show(self) :
452 print self.annotation_off.get_value()
453
454 - def get_raw(self) :
455 return bytecode.Buff( self.__offset, self.annotation_off.get_value_buff() )
456
457 -class AnnotationSetItem :
458 - def __init__(self, buff, cm) :
459 self.__offset = buff.get_idx() 460 self.__annotation_off_item = [] 461 462 self.__size = SV( '<L', buff.read( 4 ) ) 463 for i in range(0, self.__size) : 464 self.__annotation_off_item.append( AnnotationOffItem(buff, cm) )
465
466 - def get_annotation_off_item(self) :
467 return self.__annotation_off_item
468
469 - def reload(self) :
470 pass
471
472 - def show(self) :
473 nb = 0 474 for i in self.__annotation_off_item : 475 print nb, i, 476 i.show() 477 nb = nb + 1
478
479 - def get_raw(self) :
480 return [ bytecode.Buff(self.__offset, self.__size.get_value_buff()) ] + [ i.get_raw() for i in self.__annotation_off_item ]
481
482 - def get_off(self) :
483 return self.__offset
484
485 -class FieldAnnotation :
486 - def __init__(self, buff, cm) :
487 self.__offset = buff.get_idx() 488 self.field_idx = SV('<L', buff.read( 4 ) ) 489 self.annotations_off = SV('<L', buff.read( 4 ) )
490
491 - def get_raw(self) :
492 return bytecode.Buff(self.__offset, self.field_idx.get_value_buff() + self.annotations_off.get_value_buff())
493
494 -class MethodAnnotation :
495 - def __init__(self, buff, cm) :
496 self.__offset = buff.get_idx() 497 self.method_idx = SV('<L', buff.read( 4 ) ) 498 self.annotations_off = SV('<L', buff.read( 4 ) )
499
500 - def get_raw(self) :
501 return bytecode.Buff(self.__offset, self.method_idx.get_value_buff() + self.annotations_off.get_value_buff())
502
503 -class ParameterAnnotation :
504 - def __init__(self, buff, cm) :
505 self.__offset = buff.get_idx() 506 self.method_idx = SV('<L', buff.read( 4 ) ) 507 self.annotations_off = SV('<L', buff.read( 4 ) )
508
509 - def get_raw(self) :
510 return bytecode.Buff(self.__offset, self.method_idx.get_value_buff() + self.annotations_off.get_value_buff())
511
512 -class AnnotationsDirectoryItem :
513 - def __init__(self, buff, cm) :
514 self.__offset = buff.get_idx() 515 self.format = SVs( ANNOTATIONS_DIRECTORY_ITEM[0], ANNOTATIONS_DIRECTORY_ITEM[1], buff.read( calcsize(ANNOTATIONS_DIRECTORY_ITEM[0]) ) ) 516 517 self.__field_annotations = [] 518 for i in range(0, self.format.get_value().fields_size) : 519 self.__field_annotations.append( FieldAnnotation( buff, cm ) ) 520 521 self.__method_annotations = [] 522 for i in range(0, self.format.get_value().annotated_methods_size) : 523 self.__method_annotations.append( MethodAnnotation( buff, cm ) ) 524 525 self.__parameter_annotations = [] 526 for i in range(0, self.format.get_value().annotated_parameters_size) : 527 self.__parameter_annotations.append( ParameterAnnotation( buff, cm ) )
528
529 - def reload(self) :
530 pass
531
532 - def show(self) :
533 print self.format.get_value()
534
535 - def get_raw(self) :
536 return [ bytecode.Buff( self.__offset, self.format.get_value_buff() ) ] + \ 537 [ i.get_raw() for i in self.__field_annotations ] + \ 538 [ i.get_raw() for i in self.__method_annotations ] + \ 539 [ i.get_raw() for i in self.__parameter_annotations ]
540
541 - def get_off(self) :
542 return self.__offset
543
544 -class TypeLItem :
545 - def __init__(self, buff, cm) :
546 self.__offset = buff.get_idx() 547 self.type_idx = SV( '<H', buff.read( 2 ) )
548
549 - def show(self) :
550 print self.type_idx.get_value_buff()
551
552 - def get_raw(self) :
553 return bytecode.Buff(self.__offset, self.type_idx.get_value_buff())
554
555 -class TypeList :
556 - def __init__(self, buff, cm) :
557 self.__offset = buff.get_idx() 558 559 self.pad = "" 560 if self.__offset % 4 != 0 : 561 self.pad = buff.read( self.__offset % 4 ) 562 563 self.size = SV( '<L', buff.read( 4 ) ) 564 565 self.__list = [] 566 for i in range(0, self.size) : 567 self.__list.append( TypeLItem( buff, cm ) )
568
569 - def reload(self) :
570 pass
571
572 - def show(self) :
573 nb = 0 574 for i in self.__list : 575 print nb, i, 576 i.show() 577 nb = nb + 1
578
579 - def get_raw(self) :
580 return [ bytecode.Buff( self.__offset, self.pad + self.size.get_value_buff() ) ] + [ i.get_raw() for i in self.__list ]
581
582 - def get_off(self) :
583 return self.__offset
584 585 DBG_END_SEQUENCE = 0x00 # (none) terminates a debug info sequence for a code_item 586 DBG_ADVANCE_PC = 0x01 # uleb128 addr_diff addr_diff: amount to add to address register advances the address register without emitting a positions entry 587 DBG_ADVANCE_LINE = 0x02 # sleb128 line_diff line_diff: amount to change line register by advances the line register without emitting a positions entry 588 DBG_START_LOCAL = 0x03 # uleb128 register_num 589 # uleb128p1 name_idx 590 # uleb128p1 type_idx 591 # register_num: register that will contain local name_idx: string index of the name 592 # type_idx: type index of the type introduces a local variable at the current address. Either name_idx or type_idx may be NO_INDEX to indicate that that value is unknown. 593 DBG_START_LOCAL_EXTENDED = 0x04 # uleb128 register_num uleb128p1 name_idx uleb128p1 type_idx uleb128p1 sig_idx 594 # register_num: register that will contain local 595 # name_idx: string index of the name 596 # type_idx: type index of the type 597 # sig_idx: string index of the type signature 598 # introduces a local with a type signature at the current address. Any of name_idx, type_idx, or sig_idx may be NO_INDEX to indicate that that value is unknown. ( 599 # If sig_idx is -1, though, the same data could be represented more efficiently using the opcode DBG_START_LOCAL.) 600 # Note: See the discussion under "dalvik.annotation.Signature" below for caveats about handling signatures. 601 DBG_END_LOCAL = 0x05 # uleb128 register_num 602 # register_num: register that contained local 603 # marks a currently-live local variable as out of scope at the current address 604 DBG_RESTART_LOCAL = 0x06 # uleb128 register_num 605 # register_num: register to restart re-introduces a local variable at the current address. 606 # The name and type are the same as the last local that was live in the specified register. 607 DBG_SET_PROLOGUE_END = 0x07 # (none) sets the prologue_end state machine register, indicating that the next position entry that is added should be considered the end of a 608 # method prologue (an appropriate place for a method breakpoint). The prologue_end register is cleared by any special (>= 0x0a) opcode. 609 DBG_SET_EPILOGUE_BEGIN = 0x08 # (none) sets the epilogue_begin state machine register, indicating that the next position entry that is added should be considered the beginning 610 # of a method epilogue (an appropriate place to suspend execution before method exit). The epilogue_begin register is cleared by any special (>= 0x0a) opcode. 611 DBG_SET_FILE = 0x09 # uleb128p1 name_idx 612 # name_idx: string index of source file name; NO_INDEX if unknown indicates that all subsequent line number entries make reference to this source file name, 613 # instead of the default name specified in code_item 614 DBG_Special_Opcodes_BEGIN = 0x0a # (none) advances the line and address registers, emits a position entry, and clears prologue_end and epilogue_begin. See below for description. 615 DBG_Special_Opcodes_END = 0xff 616
617 -class DBGBytecode :
618 - def __init__(self, op_value) :
619 self.__op_value = op_value 620 self.__format = []
621
622 - def get_op_value(self) :
623 return self.__op_value
624
625 - def add(self, value, ttype) :
626 self.__format.append( (value, ttype) )
627
628 - def get_raw(self) :
629 buff = self.__op_value.get_value_buff() 630 for i in self.__format : 631 if i[1] == "u" : 632 buff += writeuleb128( i[0] ) 633 elif i[1] == "s" : 634 buff += writesleb128( i[0] ) 635 return buff
636
637 - def show(self) :
638 return [ i[0] for i in self.__format ]
639
640 -class DebugInfoItem2 :
641 - def __init__(self, buff, cm) :
642 self.__offset = buff.get_idx() 643 self.__buff = buff 644 self.__CM = cm 645 self.__raw = ""
646
647 - def reload(self) :
648 n = self.__CM.get_next_offset_item( self.__offset ) 649 650 s_idx = self.__buff.get_idx() 651 self.__buff.set_idx( self.__offset ) 652 self.__raw = self.__buff.read( n - self.__offset ) 653 self.__buff.set_idx( s_idx )
654
655 - def get_raw(self) :
656 return [ bytecode.Buff(self.__offset, self.__raw) ]
657
658 - def get_off(self) :
659 return self.__offset
660
661 - def show(self) :
662 pass
663
664 -class DebugInfoItem :
665 - def __init__(self, buff, cm) :
666 self.__offset = buff.get_idx() 667 self.__line_start = readuleb128( buff ) 668 self.__parameters_size = readuleb128( buff ) 669 670 self.__parameter_names = [] 671 for i in range(0, self.__parameters_size) : 672 self.__parameter_names.append( readuleb128( buff ) ) 673 674 self.__bytecodes = [] 675 bcode = DBGBytecode( SV( '<B', buff.read(1) ) ) 676 self.__bytecodes.append( bcode ) 677 678 while bcode.get_op_value().get_value() != DBG_END_SEQUENCE : 679 bcode_value = bcode.get_op_value().get_value() 680 # print "0x%x" % bcode_value 681 682 if bcode_value == DBG_SET_PROLOGUE_END : 683 pass 684 elif bcode_value >= DBG_Special_Opcodes_BEGIN and bcode_value <= DBG_Special_Opcodes_END : 685 pass 686 elif bcode_value == DBG_ADVANCE_PC : 687 bcode.add( readuleb128( buff ), "u" ) 688 elif bcode_value == DBG_ADVANCE_LINE : 689 bcode.add( readsleb128( buff ), "s" ) 690 elif bcode_value == DBG_START_LOCAL : 691 bcode.add( readuleb128( buff ), "u" ) 692 bcode.add( readuleb128( buff ), "u" ) 693 bcode.add( readuleb128( buff ), "u" ) 694 elif bcode_value == DBG_START_LOCAL_EXTENDED : 695 bcode.add( readuleb128( buff ), "u" ) 696 bcode.add( readuleb128( buff ), "u" ) 697 bcode.add( readuleb128( buff ), "u" ) 698 bcode.add( readuleb128( buff ), "u" ) 699 elif bcode_value == DBG_END_LOCAL : 700 bcode.add( readuleb128( buff ), "u" ) 701 elif bcode_value == DBG_RESTART_LOCAL : 702 bcode.add( readuleb128( buff ), "u" ) 703 else : 704 bytecode.Exit( "unknown or not yet supported DBG bytecode 0x%x" % bcode_value ) 705 706 bcode = DBGBytecode( SV( '<B', buff.read(1) ) ) 707 self.__bytecodes.append( bcode )
708
709 - def reload(self) :
710 pass
711
712 - def show(self) :
713 print self.__line_start 714 print self.__parameters_size 715 print self.__parameter_names
716
717 - def get_raw(self) :
718 return [ bytecode.Buff( self.__offset, writeuleb128( self.__line_start ) + \ 719 writeuleb128( self.__parameters_size ) + \ 720 ''.join(writeuleb128(i) for i in self.__parameter_names) + \ 721 ''.join(i.get_raw() for i in self.__bytecodes) ) ]
722 723 724 VALUE_BYTE = 0x00 # (none; must be 0) ubyte[1] signed one-byte integer value 725 VALUE_SHORT = 0x02 # size - 1 (0..1) ubyte[size] signed two-byte integer value, sign-extended 726 VALUE_CHAR = 0x03 # size - 1 (0..1) ubyte[size] unsigned two-byte integer value, zero-extended 727 VALUE_INT = 0x04 # size - 1 (0..3) ubyte[size] signed four-byte integer value, sign-extended 728 VALUE_LONG = 0x06 # size - 1 (0..7) ubyte[size] signed eight-byte integer value, sign-extended 729 VALUE_FLOAT = 0x10 # size - 1 (0..3) ubyte[size] four-byte bit pattern, zero-extended to the right, and interpreted as an IEEE754 32-bit floating point value 730 VALUE_DOUBLE = 0x11 # size - 1 (0..7) ubyte[size] eight-byte bit pattern, zero-extended to the right, and interpreted as an IEEE754 64-bit floating point value 731 VALUE_STRING = 0x17 # size - 1 (0..3) ubyte[size] unsigned (zero-extended) four-byte integer value, interpreted as an index into the string_ids section and representing a string value 732 VALUE_TYPE = 0x18 # size - 1 (0..3) ubyte[size] unsigned (zero-extended) four-byte integer value, interpreted as an index into the type_ids section and representing a reflective type/class value 733 VALUE_FIELD = 0x19 # size - 1 (0..3) ubyte[size] unsigned (zero-extended) four-byte integer value, interpreted as an index into the field_ids section and representing a reflective field value 734 VALUE_METHOD = 0x1a # size - 1 (0..3) ubyte[size] unsigned (zero-extended) four-byte integer value, interpreted as an index into the method_ids section and representing a reflective method value 735 VALUE_ENUM = 0x1b # size - 1 (0..3) ubyte[size] unsigned (zero-extended) four-byte integer value, interpreted as an index into the field_ids section and representing the value of an enumerated type constant 736 VALUE_ARRAY = 0x1c # (none; must be 0) encoded_array an array of values, in the format specified by "encoded_array Format" below. The size of the value is implicit in the encoding. 737 VALUE_ANNOTATION = 0x1d # (none; must be 0) encoded_annotation a sub-annotation, in the format specified by "encoded_annotation Format" below. The size of the value is implicit in the encoding. 738 VALUE_NULL = 0x1e # (none; must be 0) (none) null reference value 739 VALUE_BOOLEAN = 0x1f # boolean (0..1) (none) one-bit value; 0 for false and 1 for true. The bit is represented in the value_arg. 740 741
742 -class EncodedArray :
743 - def __init__(self, buff, cm) :
744 self.size = readuleb128( buff ) 745 746 self.__values = [] 747 for i in range(0, self.size) : 748 self.__values.append( EncodedValue(buff, cm) )
749
750 - def get_raw(self) :
751 return writeuleb128( self.size ) + ''.join(i.get_raw() for i in self.__values)
752
753 - def get_values(self) :
754 return self.__values
755
756 -class EncodedValue :
757 - def __init__(self, buff, cm) :
758 self.__offset = buff.get_idx() 759 760 self.val = SV('<B', buff.read( 1 ) ) 761 self.__value_arg = self.val.get_value() >> 5 762 self.__value_type = self.val.get_value() & 0x1f 763 764 765 self.__value = "" 766 767 if self.__value_type >= VALUE_SHORT and self.__value_type < VALUE_ARRAY : 768 self.__value = buff.read( self.__value_arg + 1 ) 769 elif self.__value_type == VALUE_ARRAY : 770 self.__value = EncodedArray( buff, cm ) 771 elif self.__value_type == VALUE_BYTE : 772 self.__value = buff.read( 1 ) 773 elif self.__value_type == VALUE_NULL : 774 pass 775 elif self.__value_type == VALUE_BOOLEAN : 776 pass 777 else : 778 raise( "oops" )
779
780 - def get_raw(self) :
781 if isinstance(self.__value, str) : 782 return self.val.get_value_buff() + self.__value 783 else : 784 return self.val.get_value_buff() + self.__value.get_raw()
785
786 - def show(self) :
787 print self.val, self.__value_arg, self.__value_type, self.__value
788
789 -class AnnotationElement :
790 - def __init__(self, buff, cm) :
791 self.__offset = buff.get_idx() 792 self.name_idx = readuleb128( buff ) 793 794 self.value = EncodedValue( buff, cm )
795
796 - def get_raw(self) :
797 return [ bytecode.Buff(self.__offset, writeuleb128(self.name_idx) + self.value.get_raw()) ]
798
799 - def show(self) :
800 print self.name_idx 801 self.value.show()
802
803 -class EncodedAnnotation :
804 - def __init__(self, buff, cm) :
805 self.__offset = buff.get_idx() 806 807 self.type_idx = readuleb128( buff ) 808 self.size = readuleb128( buff ) 809 810 self.__elements = [] 811 for i in range(0, self.size) : 812 self.__elements.append( AnnotationElement( buff, cm ) )
813
814 - def get_raw(self) :
815 return [ bytecode.Buff( self.__offset, writeuleb128(self.type_idx) + writeuleb128(self.size) ) ] + \ 816 [ i.get_raw() for i in self.__elements ]
817
818 - def show(self) :
819 print self.type_idx, self.size 820 for i in self.__elements : 821 i.show()
822
823 -class AnnotationItem :
824 - def __init__(self, buff, cm) :
825 self.__offset = buff.get_idx() 826 self.visibility = SV( '<B', buff.read( 1 ) ) 827 self.annotation = EncodedAnnotation(buff, cm)
828
829 - def reload(self) :
830 pass
831
832 - def show(self) :
833 print self.visibility.get_value() 834 self.annotation.show()
835
836 - def get_raw(self) :
837 return [ bytecode.Buff(self.__offset, self.visibility.get_value_buff()) ] + self.annotation.get_raw()
838
839 - def get_off(self) :
840 return self.__offset
841
842 -class EncodedArrayItem :
843 - def __init__(self, buff, cm) :
844 self.__offset = buff.get_idx() 845 self.__value = EncodedArray( buff, cm )
846
847 - def reload(self) :
848 pass
849
850 - def show(self) :
851 pass
852
853 - def get_raw(self) :
854 return bytecode.Buff( self.__offset, self.__value.get_raw() )
855
856 - def get_off(self) :
857 return self.__offset
858
859 -class StringDataItem :
860 - def __init__(self, buff) :
861 self.__offset = buff.get_idx() 862 self.__utf16_size = readuleb128( buff ) 863 self.__data = buff.read( self.__utf16_size + 1 )
864
865 - def reload(self) :
866 pass
867
868 - def get(self) :
869 return self.__data[:-1]
870
871 - def show(self) :
872 print "%d %s" % ( self.__utf16_size, repr( self.__data ) )
873
874 - def get_off(self) :
875 return self.__offset
876
877 - def get_raw(self) :
878 return [ bytecode.Buff( self.__offset, writeuleb128( self.__utf16_size ) + self.__data ) ]
879
880 -class StringIdItem :
881 - def __init__(self, buff) :
882 self.__offset = buff.get_idx() 883 self.__string_data_off = SV( '<L', buff.read( 4 ) )
884
885 - def reload(self) :
886 pass
887
888 - def get_data_off(self) :
889 return self.__string_data_off.get_value()
890
891 - def get_raw(self) :
892 return [ bytecode.Buff( self.__offset, self.__string_data_off.get_value_buff() ) ]
893
894 - def show(self) :
895 print self.__string_data_off.get_value()
896
897 - def get_off(self) :
898 return self.__offset
899
900 -class IdItem(object) :
901 - def __init__(self, size, buff, cm, TClass) :
902 self.__elem = [] 903 for i in range(0, size) : 904 self.__elem.append( TClass(buff, cm) )
905
906 - def get(self, idx) :
907 return self.__elem[ idx ]
908
909 - def reload(self) :
910 for i in self.__elem : 911 i.reload()
912
913 - def show(self) :
914 nb = 0 915 for i in self.__elem : 916 print nb, i, 917 i.show() 918 nb = nb + 1
919
920 - def get_raw(self) :
921 return [ i.get_raw() for i in self.__elem ]
922
923 -class TypeItem :
924 - def __init__(self, buff, cm) :
925 self.__cm = cm 926 self.__offset = buff.get_idx() 927 self.__general_format = SV( '<L', buff.read( 4 ) ) 928 self.__name = None
929
930 - def reload(self) :
931 self.__name = self.__cm.get_string( self.__general_format.get_value() )
932
933 - def show(self) :
934 print self.__general_format.get_value(), self.__name
935
936 - def get_value(self) :
937 return self.__general_format.get_value()
938
939 - def get_raw(self) :
940 return bytecode.Buff( self.__offset, self.__general_format.get_value_buff() )
941
942 -class TypeIdItem :
943 - def __init__(self, size, buff, cm) :
944 self.__offset = buff.get_idx() 945 self.__type = [] 946 self.__cm = cm 947 948 for i in range(0, size) : 949 self.__type.append( TypeItem( buff, cm ) )
950
951 - def reload(self) :
952 for i in self.__type : 953 i.reload()
954
955 - def get(self, idx) :
956 return self.__type[ idx ].get_value()
957
958 - def get_raw(self) :
959 return [ i.get_raw() for i in self.__type ]
960
961 - def show(self) :
962 nb = 0 963 for i in self.__type : 964 print nb, 965 i.show() 966 nb = nb + 1
967
968 - def get_off(self) :
969 return self.__offset
970
971 -class ProtoItem :
972 - def __init__(self, buff, cm) :
973 self.__offset = buff.get_idx() 974 self.__general_format = SVs( PROTO_ID_ITEM[0], PROTO_ID_ITEM[1], buff.read( calcsize(PROTO_ID_ITEM[0]) ) ) 975 self.__shorty = None 976 self.__return = None 977 978 self.__cm = cm
979
980 - def reload(self) :
981 self.__shorty = self.__cm.get_string( self.__general_format.get_value().shorty_idx ) 982 self.__return = self.__cm.get_type( self.__general_format.get_value().return_type_idx )
983
984 - def get_shorty(self) :
985 return self.__shorty
986
987 - def get_return_type(self) :
988 return self.__return
989
990 - def show(self) :
991 print self.__shorty, self.__return, self.__general_format.get_value()
992
993 - def get_raw(self) :
994 return bytecode.Buff( self.__offset, self.__general_format.get_value_buff() )
995
996 -class ProtoIdItem :
997 - def __init__(self, size, buff, cm) :
998 self.__offset = buff.get_idx() 999 self.__proto = [] 1000 1001 for i in range(0, size) : 1002 self.__proto.append( ProtoItem(buff, cm) )
1003
1004 - def get(self, idx) :
1005 return self.__proto[ idx ]
1006
1007 - def reload(self) :
1008 for i in self.__proto : 1009 i.reload()
1010
1011 - def show(self) :
1012 nb = 0 1013 for i in self.__proto : 1014 print nb, i, 1015 i.show() 1016 nb = nb + 1
1017
1018 - def get_raw(self) :
1019 return [ i.get_raw() for i in self.__proto ]
1020
1021 - def get_off(self) :
1022 return self.__offset
1023
1024 -class FieldItem :
1025 - def __init__(self, buff, cm) :
1026 self.__offset = buff.get_idx() 1027 self.__general_format = SVs( FIELD_ID_ITEM[0], FIELD_ID_ITEM[1], buff.read( calcsize(FIELD_ID_ITEM[0]) ) ) 1028 self.__class = None 1029 self.__type = None 1030 self.__name = None 1031 1032 self.__cm = cm
1033
1034 - def reload(self) :
1035 general_format = self.__general_format.get_value() 1036 self.__class = self.__cm.get_type( general_format.class_idx ) 1037 self.__type = self.__cm.get_type( general_format.type_idx ) 1038 self.__name = self.__cm.get_string( general_format.name_idx )
1039
1040 - def get_class(self) :
1041 return self.__class
1042
1043 - def get_type(self) :
1044 return self.__type
1045
1046 - def get_name(self) :
1047 return self.__name
1048
1049 - def show(self) :
1050 print self.__class, self.__type, self.__name, self.__general_format.get_value()
1051
1052 - def get_raw(self) :
1053 return bytecode.Buff( self.__offset, self.__general_format.get_value_buff() )
1054
1055 - def get_off(self) :
1056 return self.__offset
1057
1058 -class FieldIdItem(IdItem) :
1059 - def __init__(self, size, buff, cm) :
1060 self.__offset = buff.get_idx() 1061 super(FieldIdItem, self).__init__(size, buff, cm, FieldItem)
1062
1063 - def get_off(self) :
1064 return self.__offset
1065
1066 -class MethodItem :
1067 - def __init__(self, buff, cm) :
1068 self.__offset = buff.get_idx() 1069 self.__general_format = SVs( METHOD_ID_ITEM[0], METHOD_ID_ITEM[1], buff.read( calcsize(METHOD_ID_ITEM[0]) ) ) 1070 self.__class = None 1071 self.__proto = None 1072 self.__name = None 1073 1074 self.__cm = cm
1075
1076 - def reload(self) :
1077 general_format = self.__general_format.get_value() 1078 self.__class = self.__cm.get_type( general_format.class_idx ) 1079 self.__proto = self.__cm.get_proto( general_format.proto_idx ) 1080 self.__name = self.__cm.get_string( general_format.name_idx )
1081
1082 - def get_class(self) :
1083 return self.__class
1084
1085 - def get_proto(self) :
1086 return self.__proto
1087
1088 - def get_name(self) :
1089 return self.__name
1090
1091 - def show(self) :
1092 print self.__name, self.__proto, self.__class, self.__general_format.get_value()
1093
1094 - def get_raw(self) :
1095 return bytecode.Buff( self.__offset, self.__general_format.get_value_buff() )
1096
1097 -class MethodIdItem :
1098 - def __init__(self, size, buff, cm) :
1099 self.__offset = buff.get_idx() 1100 self.methods = [] 1101 for i in range(0, size) : 1102 self.methods.append( MethodItem(buff, cm) )
1103
1104 - def get(self, idx) :
1105 return self.methods[ idx ]
1106
1107 - def reload(self) :
1108 for i in self.methods : 1109 i.reload()
1110
1111 - def show(self) :
1112 nb = 0 1113 for i in self.methods : 1114 print nb, i, 1115 i.show() 1116 nb = nb + 1
1117
1118 - def get_raw(self) :
1119 return [ i.get_raw() for i in self.methods ]
1120
1121 - def get_off(self) :
1122 return self.__offset
1123
1124 -class EncodedField :
1125 - def __init__(self, buff, cm) :
1126 self.__field_idx_diff = readuleb128( buff ) 1127 self.__access_flags = readuleb128( buff ) 1128 1129 self.__field_idx = 0 1130 1131 self.__name = None 1132 1133 self.__cm = cm
1134
1135 - def get_access(self) :
1136 return self.__access_flags
1137
1138 - def get_descriptor(self) :
1139 return self.__name[1]
1140
1141 - def get_name(self) :
1142 return self.__name[2]
1143
1144 - def adjust_idx(self, val) :
1145 self.__field_idx = self.__field_idx_diff + val
1146
1147 - def get_idx(self) :
1148 return self.__field_idx
1149
1150 - def reload(self) :
1151 self.__name = self.__cm.get_field( self.__field_idx )
1152
1153 - def get_raw(self) :
1154 return writeuleb128( self.__field_idx_diff ) + writeuleb128( self.__access_flags )
1155
1156 - def show(self) :
1157 print "\tfield_idx_diff=%d %s access_flags=%d" % (self.__field_idx_diff, self.__name, self.__access_flags)
1158
1159 -class EncodedMethod :
1160 - def __init__(self, buff, cm) :
1161 self.method_idx_diff = readuleb128( buff ) 1162 self.access_flags = readuleb128( buff ) 1163 self.code_off = readuleb128( buff ) 1164 1165 self.__method_idx = 0 1166 1167 self.__name = None 1168 self.__code = None 1169 1170 self.__cm = cm
1171
1172 - def get_access(self) :
1173 return self.access_flags
1174
1175 - def get_code(self) :
1176 return self.__code
1177
1178 - def get_descriptor(self) :
1179 return self.proto
1180
1181 - def get_name(self) :
1182 return self.__name
1183
1184 - def adjust_idx(self, val) :
1185 self.__method_idx = self.method_idx_diff + val
1186
1187 - def get_idx(self) :
1188 return self.__method_idx
1189
1190 - def reload(self) :
1191 v = self.__cm.get_method( self.__method_idx ) 1192 self.__class_name = v[0] 1193 self.proto = v[1] 1194 self.__name = v[2] 1195 1196 self.__code = self.__cm.get_code( self.code_off )
1197
1198 - def get_raw(self) :
1199 return writeuleb128( self.method_idx_diff ) + writeuleb128( self.access_flags ) + writeuleb128( self.code_off )
1200
1201 - def show(self) :
1202 print "\tmethod_idx_diff=%d %s access_flags=%d code_off=%d" % (self.method_idx_diff, self.__name, self.access_flags, self.code_off) 1203 self.__code.show()
1204
1205 -class ClassDataItem :
1206 - def __init__(self, buff, cm) :
1207 self.__offset = buff.get_idx() 1208 1209 self.__static_fields_size = readuleb128( buff ) 1210 self.__instance_fields_size = readuleb128( buff ) 1211 self.__direct_methods_size = readuleb128( buff ) 1212 self.__virtual_methods_size = readuleb128( buff ) 1213 1214 self.__static_fields = [] 1215 self.__instance_fields = [] 1216 self.__direct_methods = [] 1217 self.__virtual_methods = [] 1218 1219 1220 self.load_field( self.__static_fields_size, self.__static_fields, EncodedField, buff, cm ) 1221 self.load_field( self.__instance_fields_size, self.__instance_fields, EncodedField, buff, cm ) 1222 self.load_field( self.__direct_methods_size, self.__direct_methods, EncodedMethod, buff, cm ) 1223 self.load_field( self.__virtual_methods_size, self.__virtual_methods, EncodedMethod, buff, cm )
1224
1225 - def load_field(self, size, l, Type, buff, cm) :
1226 prev = 0 1227 for i in range(0, size) : 1228 el = Type(buff, cm) 1229 el.adjust_idx( prev ) 1230 prev = el.get_idx() 1231 1232 l.append( el )
1233
1234 - def reload(self) :
1235 for i in self.__static_fields : 1236 i.reload() 1237 1238 for i in self.__instance_fields : 1239 i.reload() 1240 1241 for i in self.__direct_methods : 1242 i.reload() 1243 1244 for i in self.__virtual_methods : 1245 i.reload()
1246
1247 - def get_off(self) :
1248 return self.__offset
1249
1250 - def get_methods(self) :
1251 return [ x for x in self.__direct_methods ] + [ x for x in self.__virtual_methods ]
1252
1253 - def get_fields(self) :
1254 return [ x for x in self.__static_fields ] + [ x for x in self.__instance_fields ]
1255
1256 - def show(self) :
1257 print "static_fields_size=%d instance_fields_size=%d direct_methods_size=%d virtual_methods_size=%d" % (self.__static_fields_size, self.__instance_fields_size, self.__direct_methods_size, self.__virtual_methods_size) 1258 1259 print "SF" 1260 for i in self.__static_fields : 1261 i.show() 1262 1263 print "IF" 1264 for i in self.__instance_fields : 1265 i.show() 1266 1267 print "DM" 1268 for i in self.__direct_methods : 1269 i.show() 1270 1271 print "VM" 1272 for i in self.__virtual_methods : 1273 i.show()
1274
1275 - def get_raw(self) :
1276 1277 buff = writeuleb128( self.__static_fields_size ) + \ 1278 writeuleb128( self.__instance_fields_size ) + \ 1279 writeuleb128( self.__direct_methods_size ) + \ 1280 writeuleb128( self.__virtual_methods_size ) + \ 1281 ''.join(i.get_raw() for i in self.__static_fields) + \ 1282 ''.join(i.get_raw() for i in self.__instance_fields) + \ 1283 ''.join(i.get_raw() for i in self.__direct_methods) + \ 1284 ''.join(i.get_raw() for i in self.__virtual_methods) 1285 1286 return [ bytecode.Buff(self.__offset, buff) ]
1287
1288 -class ClassItem :
1289 - def __init__(self, buff, cm) :
1290 self.__offset = buff.get_idx() 1291 self.__general_format = SVs( CLASS_DEF_ITEM[0], CLASS_DEF_ITEM[1], buff.read( calcsize(CLASS_DEF_ITEM[0]) ) ) 1292 self.__name = None 1293 self.__sname = None 1294 1295 self.__CM = cm
1296
1297 - def reload(self) :
1298 general_format = self.__general_format.get_value() 1299 self.__name = self.__CM.get_type( general_format.class_idx ) 1300 self.__sname = self.__CM.get_type( general_format.superclass_idx ) 1301 1302 self.__class_data_item = self.__CM.get_class_data_item( self.__general_format.get_value().class_data_off ) 1303 1304 self.__class_data_item.reload()
1305
1306 - def get_name(self) :
1307 return self.__name
1308
1309 - def get_info(self) :
1310 return "%s:%s" % (self.__name, self.__sname)
1311
1312 - def get_methods(self) :
1313 return self.__class_data_item.get_methods()
1314
1315 - def get_fields(self) :
1316 return self.__class_data_item.get_fields()
1317
1318 - def show(self) :
1319 print self.__name, self.__sname, self.__general_format.get_value() 1320 self.__class_data_item.show()
1321
1322 - def get_raw(self) :
1323 return [ bytecode.Buff( self.__offset, self.__general_format.get_value_buff() ) ]
1324
1325 -class ClassDefItem :
1326 - def __init__(self, size, buff, cm) :
1327 self.__offset = buff.get_idx() 1328 self.class_def = [] 1329 1330 for i in range(0, size) : 1331 idx = buff.get_idx() 1332 1333 class_def = ClassItem( buff, cm ) 1334 self.class_def.append( class_def ) 1335 1336 buff.set_idx( idx + calcsize(CLASS_DEF_ITEM[0]) )
1337
1338 - def export(self) :
1339 pass
1340
1341 - def get_method(self, name_class, name_method) :
1342 l = [] 1343 1344 for i in self.class_def : 1345 if i.get_name() == name_class : 1346 for j in i.get_methods() : 1347 if j.get_name() == name_method : 1348 l.append(j) 1349 1350 return l
1351
1352 - def get_names(self) :
1353 return [ x.get_name() for x in self.class_def ]
1354
1355 - def reload(self) :
1356 for i in self.class_def : 1357 i.reload()
1358
1359 - def show(self) :
1360 nb = 0 1361 for i in self.class_def : 1362 print nb, 1363 i.show() 1364 nb = nb + 1
1365
1366 - def get_raw(self) :
1367 return [ i.get_raw() for i in self.class_def ]
1368
1369 - def get_off(self) :
1370 return self.__offset
1371
1372 -class EncodedTypeAddrPair :
1373 - def __init__(self, buff) :
1374 self.__type_idx = readuleb128( buff ) 1375 self.__addr = readuleb128( buff )
1376
1377 - def get_raw(self) :
1378 return writeuleb128( self.__type_idx ) + writeuleb128( self.__addr )
1379
1380 -class EncodedCatchHandler :
1381 - def __init__(self, buff) :
1382 self.__size = readsleb128( buff ) 1383 1384 self.__handlers = [] 1385 1386 for i in range(0, abs(self.__size)) : 1387 self.__handlers.append( EncodedTypeAddrPair(buff) ) 1388 1389 if self.__size <= 0 : 1390 self.__catch_all_addr = readuleb128( buff )
1391
1392 - def show(self) :
1393 bytecode._Print("ENCODED_CATCH_HANDLER SIZE", self.__size)
1394
1395 - def get_raw(self) :
1396 buff = writesleb128( self.__size ) + ''.join(i.get_raw() for i in self.__handlers) 1397 1398 if self.__size <= 0 : 1399 buff += writeuleb128( self.__catch_all_addr ) 1400 1401 return buff
1402
1403 -class EncodedCatchHandlerList :
1404 - def __init__(self, buff) :
1405 self.__size = readuleb128( buff ) 1406 self.__list = [] 1407 1408 for i in range(0, self.__size) : 1409 self.__list.append( EncodedCatchHandler(buff) )
1410
1411 - def show(self) :
1412 bytecode._Print("ENCODED_CATCH_HANDLER_LIST SIZE", self.__size) 1413 for i in self.__list : 1414 i.show()
1415
1416 - def get_raw(self) :
1417 return writeuleb128( self.__size ) + ''.join(i.get_raw() for i in self.__list)
1418
1419 -class DalvikCode :
1420 - def __init__(self, buff) :
1421 off = buff.get_idx() 1422 while off % 4 != 0 : 1423 off += 1 1424 1425 self.__offset = off 1426 buff.set_idx( off ) 1427 #print "OFF = 0x%x %x ################################################" % (buff.get_idx(), buff.get_idx() % 4) 1428 1429 self.__off = buff.get_idx() 1430 1431 self.__registers_size = SV( '<H', buff.read( 2 ) ) 1432 self.__ins_size = SV( '<H', buff.read( 2 ) ) 1433 self.__outs_size = SV( '<H', buff.read( 2 ) ) 1434 self.__tries_size = SV( '<H', buff.read( 2 ) ) 1435 self.__debug_info_off = SV( '<L', buff.read( 4 ) ) 1436 self.__insns_size = SV( '<L', buff.read( 4 ) ) 1437 1438 1439 self.__insn = buff.read( self.__insns_size.get_value() * 2 ) 1440 1441 self.__h_special_bytecodes = {} 1442 self.__bytecodes = [] 1443 #print repr( self.__insn ) 1444 1445 ushort = calcsize( '<H' ) 1446 1447 real_j = 0 1448 j = 0 1449 while j < (self.__insns_size.get_value() * ushort) : 1450 1451 if real_j in self.__h_special_bytecodes : 1452 special_e = self.__h_special_bytecodes[ real_j ]( self.__insn[j : ] ) 1453 self.__bytecodes.append( special_e ) 1454 1455 #print "EXIT special bytecodes", special_e 1456 1457 del self.__h_special_bytecodes[ real_j ] 1458 j += special_e.get_size() 1459 else : 1460 op_value = unpack( '<B', self.__insn[j] )[0] 1461 1462 if op_value in DALVIK_OPCODES : 1463 #print real_j, "ENTER into", DALVIK_OPCODES[ op_value ][1], repr( self.__insn[j : j + int( DALVIK_OPCODES[ op_value ][0][0] ) * ushort ] ) 1464 1465 operands = [] 1466 special = None 1467 1468 if len(DALVIK_OPCODES[ op_value ]) >= 4 : 1469 if len( DALVIK_OPCODES[ op_value ][3] ) == 0 : 1470 bytecode.Exit( "opcode [ 0x%x:%s ] not yet supported" % (op_value ,DALVIK_OPCODES[ op_value ][1]) ) 1471 1472 operands, special = self._analyze_mnemonic( self.__insn[ j : j + int( DALVIK_OPCODES[ op_value ][0][0] ) * ushort ], DALVIK_OPCODES[ op_value ]) 1473 1474 if special != None : 1475 self.__h_special_bytecodes[ special[0] + real_j ] = special[1] 1476 1477 # if DALVIK_OPCODES[ op_value ][1] == "packed-switch" : 1478 # print DALVIK_OPCODES[ op_value ][1], repr( self.__insn[j : j + int( DALVIK_OPCODES[ op_value ][0][0] ) * ushort ] ), operands, special 1479 # bytecode.Exit( "test" ) 1480 1481 #print "EXIT classic bytecodes", operands, special 1482 self.__bytecodes.append( [ DALVIK_OPCODES[ op_value ][1], repr( self.__insn[j : j + int( DALVIK_OPCODES[ op_value ][0][0] ) * ushort ] ), operands ] ) 1483 1484 j += ( int( DALVIK_OPCODES[ op_value ][0][0] ) * ushort) 1485 else : 1486 bytecode.Exit( "invalid opcode [ 0x%x ]" % op_value ) 1487 1488 real_j = j / 2 1489 1490 #print "PAD", self.__tries_size.value, self.__insns_size.value, "0x%x" % buff.get_idx() 1491 #if (self.__tries_size.value > 0) : 1492 # self.__padding = SV( '<H', buff.read( 2 ) ) 1493 if (self.__insns_size.get_value() % 2 == 1) : 1494 self.__padding = SV( '<H', buff.read( 2 ) ) 1495 1496 self.__tries = [] 1497 self.__handlers = [] 1498 if self.__tries_size.get_value() > 0 : 1499 for i in range(0, self.__tries_size.get_value()) : 1500 try_item = SVs( TRY_ITEM[0], TRY_ITEM[1], buff.read( calcsize(TRY_ITEM[0]) ) ) 1501 self.__tries.append( try_item ) 1502 #print try_item 1503 1504 self.__handlers.append( EncodedCatchHandlerList( buff ) )
1505
1506 - def _analyze_mnemonic(self, buff_operands, mnemonic) :
1507 operands = [] 1508 1509 t_ops = mnemonic[3].split(' ') 1510 # print t_ops, mnemonic[2] 1511 1512 l = [] 1513 for i in buff_operands : 1514 l.append( (ord(i) & 0b11110000) >> 4 ) 1515 l.append( (ord(i) & 0b00001111) ) 1516 1517 # print l 1518 for i in t_ops : 1519 sub_ops = i.split('|') 1520 # print "SOP", sub_ops, 1521 1522 if len(sub_ops[-1]) == 2 : 1523 sub_ops = [ sub_ops[-1] ] + sub_ops[0:-1] 1524 else : 1525 sub_ops = sub_ops[2:] + sub_ops[0:2] 1526 1527 # print sub_ops 1528 1529 for sub_op in sub_ops : 1530 zero_count = string.count(sub_op, '0') 1531 1532 if zero_count == len(sub_op) : 1533 continue 1534 1535 size = ((len(sub_op) - zero_count) * 4) 1536 signed = 0 1537 1538 pos_op = string.find(mnemonic[2], sub_op) 1539 if pos_op != -1 and mnemonic[2][pos_op - 1] == '+' : 1540 signed = 1 1541 1542 ttype = "op@" 1543 if pos_op != -1 : 1544 # print pos_op 1545 t_pos_op = pos_op 1546 while pos_op > 0 and mnemonic[2][pos_op] != ' ' : 1547 pos_op = pos_op - 1 1548 1549 ttype = mnemonic[2][pos_op : t_pos_op].replace(' ', '') 1550 1551 val = self._extract( signed, l, size ) << (zero_count * 4) 1552 # print sub_op, val, l 1553 1554 operands.append( [ttype, val] ) 1555 1556 if len(l) == 0 : 1557 break 1558 1559 if len(mnemonic) == 5 : 1560 return operands, (operands[2][1], mnemonic[4]) 1561 1562 return operands, None
1563
1564 - def _extract(self, signed, l, size) :
1565 func = string.capitalize 1566 1567 if signed == 1 : 1568 func = string.lower 1569 1570 if size == 4 : 1571 return l.pop(0) 1572 elif size == 8 : 1573 return unpack('<%s' % func('B'), chr( (l.pop(0) << 4) + l.pop(0) ) )[0] 1574 elif size == 16 : 1575 return unpack('<%s' % func('H'), chr( (l.pop(0) << 4) + (l.pop(0)) ) + chr( (l.pop(0) << 4) + (l.pop(0)) ) )[0] 1576 elif size == 32 : 1577 return unpack('<%s' % func('L'), chr( (l.pop(0) << 4) + (l.pop(0)) ) + chr( (l.pop(0) << 4) + (l.pop(0)) ) + chr( (l.pop(0) << 4) + (l.pop(0)) ) + chr( (l.pop(0) << 4) + (l.pop(0)) ) )[0] 1578 else : 1579 bytecode.Exit( "invalid size [ 0x%x ]" % size )
1580
1581 - def get_bc(self) :
1582 return self.__bytecodes
1583
1584 - def get_off(self) :
1585 return self.__off
1586
1587 - def show(self) :
1588 print "*" * 80 1589 print "DALVIK_CODE :" 1590 bytecode._Print("\tREGISTERS_SIZE", self.__registers_size) 1591 bytecode._Print("\tINS_SIZE", self.__ins_size) 1592 bytecode._Print("\tOUTS_SIZE", self.__outs_size) 1593 bytecode._Print("\tTRIES_SIZE", self.__tries_size) 1594 bytecode._Print("\tDEBUG_INFO_OFF", self.__debug_info_off) 1595 bytecode._Print("\tINSNS_SIZE", self.__insns_size) 1596 1597 for i in self.__handlers : 1598 i.show() 1599 1600 print "" 1601 1602 nb = 0 1603 for i in self.__bytecodes : 1604 if type(i).__name__ == 'list' : 1605 print "\t", nb, i[0], ' '.join("%s%x" % (n[0], n[1]) for n in i[-1]) 1606 else : 1607 print "\t", nb, i.show() 1608 nb += 1 1609 1610 1611 print "*" * 80
1612
1613 - def get_raw(self) :
1614 buff = self.__registers_size.get_value_buff() + \ 1615 self.__ins_size.get_value_buff() + \ 1616 self.__outs_size.get_value_buff() + \ 1617 self.__tries_size.get_value_buff() + \ 1618 self.__debug_info_off.get_value_buff() + \ 1619 self.__insns_size.get_value_buff() + \ 1620 self.__insn 1621 1622 if (self.__insns_size.get_value() % 2 == 1) : 1623 buff += self.__padding.get_value_buff() 1624 1625 if self.__tries_size.get_value() > 0 : 1626 buff += ''.join(i.get_value_buff() for i in self.__tries) 1627 buff += self.__handlers.get_raw() 1628 1629 return bytecode.Buff( self.__offset, 1630 buff )
1631
1632 -class CodeItem :
1633 - def __init__(self, size, buff) :
1634 self.__offset = buff.get_idx() 1635 self.__code = [] 1636 1637 for i in range(0, size) : 1638 self.__code.append( DalvikCode( buff ) )
1639
1640 - def get_code(self, off) :
1641 for i in self.__code : 1642 if i.get_off() == off : 1643 return i
1644
1645 - def reload(self) :
1646 pass
1647
1648 - def show(self) :
1649 for i in self.__code : 1650 i.show()
1651
1652 - def get_raw(self) :
1653 return [ i.get_raw() for i in self.__code ]
1654
1655 - def get_off(self) :
1656 return self.__offset
1657
1658 -class MapItem :
1659 - def __init__(self, buff, cm) :
1660 self.__offset = buff.get_idx() 1661 1662 self.format = SVs( MAP_ITEM[0], MAP_ITEM[1], buff.read( calcsize( MAP_ITEM[0] ) ) ) 1663 1664 self.__item = None 1665 1666 general_format = self.format.get_value() 1667 buff.set_idx( general_format.offset ) 1668 1669 # print TYPE_MAP_ITEM[ general_format.type ], "@ 0x%x(%d) %d" % (buff.get_idx(), buff.get_idx(), general_format.size) 1670 1671 if TYPE_MAP_ITEM[ general_format.type ] == "TYPE_STRING_ID_ITEM" : 1672 self.__item = [ StringIdItem( buff ) for i in range(0, general_format.size) ] 1673 1674 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_CODE_ITEM" : 1675 self.__item = CodeItem( general_format.size, buff ) 1676 1677 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_TYPE_ID_ITEM" : 1678 self.__item = TypeIdItem( general_format.size, buff, cm ) 1679 1680 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_PROTO_ID_ITEM" : 1681 self.__item = ProtoIdItem( general_format.size, buff, cm ) 1682 1683 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_FIELD_ID_ITEM" : 1684 self.__item = FieldIdItem( general_format.size, buff, cm ) 1685 1686 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_METHOD_ID_ITEM" : 1687 self.__item = MethodIdItem( general_format.size, buff, cm ) 1688 1689 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_CLASS_DEF_ITEM" : 1690 self.__item = ClassDefItem( general_format.size, buff, cm ) 1691 1692 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_HEADER_ITEM" : 1693 self.__item = HeaderItem( general_format.size, buff ) 1694 1695 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_ANNOTATION_ITEM" : 1696 self.__item = [ AnnotationItem( buff, cm ) for i in range(0, general_format.size) ] 1697 1698 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_ANNOTATION_SET_ITEM" : 1699 self.__item = [ AnnotationSetItem( buff, cm ) for i in range(0, general_format.size) ] 1700 1701 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_ANNOTATIONS_DIRECTORY_ITEM" : 1702 self.__item = [ AnnotationsDirectoryItem( buff, cm ) for i in range(0, general_format.size) ] 1703 1704 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_TYPE_LIST" : 1705 self.__item = [ TypeList( buff, cm ) for i in range(0, general_format.size) ] 1706 1707 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_STRING_DATA_ITEM" : 1708 self.__item = [ StringDataItem( buff ) for i in range(0, general_format.size) ] 1709 1710 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_DEBUG_INFO_ITEM" : 1711 # FIXME : strange bug with sleb128 .... 1712 # self.__item = [ DebugInfoItem( buff, cm ) for i in range(0, general_format.size) ] 1713 self.__item = DebugInfoItem2( buff, cm ) 1714 1715 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_ENCODED_ARRAY_ITEM" : 1716 self.__item = [ EncodedArrayItem( buff, cm ) for i in range(0, general_format.size) ] 1717 1718 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_CLASS_DATA_ITEM" : 1719 self.__item = [ ClassDataItem(buff, cm) for i in range(0, general_format.size) ] 1720 1721 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_MAP_LIST" : 1722 pass # It's me I think !!! 1723 1724 else : 1725 bytecode.Exit( "Map item @ 0x%x(%d) is unknown" % (buff.get_idx(), buff.get_idx()) )
1726
1727 - def get_raw(self) :
1728 if self.__item == None : 1729 return [ bytecode.Buff( self.__offset, self.format.get_value_buff() ) ] 1730 else : 1731 if isinstance( self.__item, list ) : 1732 return [ bytecode.Buff( self.__offset, self.format.get_value_buff() ) ] + [ i.get_raw() for i in self.__item ] 1733 else : 1734 return [ bytecode.Buff( self.__offset, self.format.get_value_buff() ) ] + self.__item.get_raw()
1735
1736 - def get_length(self) :
1737 return calcsize( MAP_ITEM[0] )
1738
1739 - def get_type(self) :
1740 return self.format.get_value().type
1741
1742 - def get_item(self) :
1743 return self.__item
1744
1745 - def reload(self) :
1746 if self.__item != None : 1747 if isinstance( self.__item, list ): 1748 for i in self.__item : 1749 i.reload() 1750 else : 1751 self.__item.reload()
1752
1753 - def show(self) :
1754 bytecode._Print( "MAP_ITEM", self.format ) 1755 bytecode._Print( "\tTYPE_ITEM", TYPE_MAP_ITEM[ self.format.get_value().type ]) 1756 1757 if self.__item != None : 1758 if isinstance( self.__item, list ): 1759 for i in self.__item : 1760 i.show() 1761 else : 1762 self.__item.show()
1763
1764 -class CM :
1765 - def __init__(self) :
1766 self.__manage_item = {} 1767 self.__manage_item_off = []
1768
1769 - def add_type_item(self, type_item, item) :
1770 self.__manage_item[ type_item ] = item 1771 1772 if item != None : 1773 if isinstance(item, list) : 1774 for i in item : 1775 self.__manage_item_off.append( i.get_off() ) 1776 else : 1777 self.__manage_item_off.append( item.get_off() )
1778
1779 - def get_code(self, idx) :
1780 return self.__manage_item[ "TYPE_CODE_ITEM" ].get_code( idx )
1781
1782 - def get_class_data_item(self, off) :
1783 for i in self.__manage_item[ "TYPE_CLASS_DATA_ITEM" ] : 1784 if i.get_off() == off : 1785 return i 1786 1787 bytecode.Exit( "unknown class data item @ 0x%x" % off )
1788
1789 - def get_string(self, idx) :
1790 off = self.__manage_item[ "TYPE_STRING_ID_ITEM" ][idx].get_data_off() 1791 for i in self.__manage_item[ "TYPE_STRING_DATA_ITEM" ] : 1792 if i.get_off() == off : 1793 return i.get() 1794 1795 bytecode.Exit( "unknown string item @ 0x%x(%d)" % (off,idx) )
1796
1797 - def get_type(self, idx) :
1798 type = self.__manage_item[ "TYPE_TYPE_ID_ITEM" ].get( idx ) 1799 return self.get_string( type )
1800
1801 - def get_proto(self, idx) :
1802 proto = self.__manage_item[ "TYPE_PROTO_ID_ITEM" ].get( idx ) 1803 return [ proto.get_shorty(), proto.get_return_type() ]
1804
1805 - def get_field(self, idx) :
1806 field = self.__manage_item[ "TYPE_FIELD_ID_ITEM"].get( idx ) 1807 return [ field.get_class(), field.get_type(), field.get_name() ]
1808
1809 - def get_method(self, idx) :
1810 method = self.__manage_item[ "TYPE_METHOD_ID_ITEM" ].get( idx ) 1811 return [ method.get_class(), method.get_proto(), method.get_name() ]
1812
1813 - def get_next_offset_item(self, idx) :
1814 for i in self.__manage_item_off : 1815 if i > idx : 1816 return i
1817
1818 -class MapList :
1819 - def __init__(self, off, buff) :
1820 self.__CM = CM() 1821 1822 buff.set_idx( off ) 1823 1824 self.__offset = buff.get_idx() 1825 1826 self.__size = SV( '<L', buff.read( 4 ) ) 1827 1828 self.__map_item = [] 1829 for i in range(0, self.__size) : 1830 idx = buff.get_idx() 1831 1832 mi = MapItem( buff, self.__CM ) 1833 self.__map_item.append( mi ) 1834 1835 buff.set_idx( idx + mi.get_length() ) 1836 1837 self.__CM.add_type_item( TYPE_MAP_ITEM[ mi.get_type() ], mi.get_item() ) 1838 1839 for i in self.__map_item : 1840 i.reload()
1841
1842 - def get_item_type(self, ttype) :
1843 for i in self.__map_item : 1844 if TYPE_MAP_ITEM[ i.get_type() ] == ttype : 1845 return i.get_item()
1846
1847 - def show(self) :
1848 bytecode._Print("MAP_LIST SIZE", self.__size.get_value()) 1849 for i in self.__map_item : 1850 i.show()
1851
1852 - def get_raw(self) :
1853 return [ bytecode.Buff(self.__offset, self.__size.get_value_buff()) ] + \ 1854 [ x.get_raw() for x in self.__map_item ]
1855
1856 -class Data :
1857 - def __init__(self, buff) :
1858 pass
1859
1860 -class DalvikVMFormat(bytecode._Bytecode) :
1861 - def __init__(self, buff) :
1862 super(DalvikVMFormat, self).__init__( buff ) 1863 super(DalvikVMFormat, self).register( bytecode.SHOW, self.show ) 1864 1865 self.load_class()
1866
1867 - def load_class(self) :
1868 self.__header = HeaderItem( 0, self ) 1869 1870 self.__map_list = MapList( self.__header.get_value().map_off, self ) 1871 1872 self.classes = self.__map_list.get_item_type( "TYPE_CLASS_DEF_ITEM" ) 1873 self.methods = self.__map_list.get_item_type( "TYPE_METHOD_ID_ITEM" ) 1874 self.codes = self.__map_list.get_item_type( "TYPE_CODE_ITEM" )
1875
1876 - def show(self) :
1877 """Show the .class format into a human readable format""" 1878 self.__map_list.show()
1879
1880 - def _iterFlatten(self, root):
1881 if isinstance(root, (list, tuple)): 1882 for element in root : 1883 for e in self._iterFlatten(element) : 1884 yield e 1885 else: 1886 yield root
1887
1888 - def _get_raw(self) :
1889 # Due to the specific format of dalvik virtual machine, 1890 # we will get a list of raw object described by a buffer, a size and an offset 1891 # where to insert the specific buffer into the file 1892 l = self.__map_list.get_raw() 1893 1894 result = list(self._iterFlatten( l )) 1895 result = sorted(result, key=lambda x: x.offset) 1896 1897 idx = 0 1898 buff = "" 1899 for i in result : 1900 # print idx, i.offset, "--->", i.offset + i.size 1901 if idx == i.offset : 1902 buff += i.buff 1903 else : 1904 # print "PATCH @ 0x%x" % idx 1905 self.set_idx( idx ) 1906 buff += '\x00' * (i.offset - idx) 1907 buff += i.buff 1908 idx += (i.offset - idx) 1909 # raise( "oops" ) 1910 1911 idx += i.size 1912 1913 return buff
1914
1915 - def get_method(self, name) :
1916 """Return into a list all methods which corresponds to the regexp 1917 1918 @param name : the name of the method (a regexp) 1919 """ 1920 prog = re.compile(name) 1921 l = [] 1922 for i in self.classes.class_def : 1923 for j in i.get_methods() : 1924 if prog.match( j.get_name() ) : 1925 l.append( j ) 1926 return l
1927
1928 - def get_field(self, name) :
1929 """Return into a list all fields which corresponds to the regexp 1930 1931 @param name : the name of the field (a regexp) 1932 """ 1933 prog = re.compile(name) 1934 l = [] 1935 for i in self.classes.class_def : 1936 for j in i.get_fields() : 1937 if prog.match( j.get_name() ) : 1938 l.append( j ) 1939 return l
1940
1941 - def get_fields(self) :
1942 """Return all objects fields""" 1943 l = [] 1944 for i in self.classes.class_def : 1945 for j in i.get_fields() : 1946 l.append( j ) 1947 return l
1948
1949 - def get_methods(self) :
1950 """Return all objects methods""" 1951 l = [] 1952 for i in self.classes.class_def : 1953 for j in i.get_methods() : 1954 l.append( j ) 1955 return l
1956
1957 - def save(self) :
1958 """Return the class (with the modifications) into raw format""" 1959 return self._get_raw()
1960