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  import misc 
  22  from bytecode import SV, SVs 
  23   
  24  import sys, re, types, string, zipfile, StringIO 
  25  from collections import namedtuple 
  26  from struct import pack, unpack, calcsize 
  27   
  28  from xml.dom import minidom 
  29   
  30  ######################################################## DEX FORMAT ######################################################## 
  31  DEX_FILE_MAGIC = 'dex\n035\x00' 
  32   
  33   
  34  HEADER_NAMEDTUPLE = namedtuple( "HEADER_NAMEDTUPLE", "magic checksum signature file_size header_size endian_tag link_size link_off " \ 
  35                                                                        "map_off string_ids_size string_ids_off type_ids_size type_ids_off proto_ids_size " \ 
  36                                                                        "proto_ids_off field_ids_size field_ids_off method_ids_size method_ids_off "\ 
  37                                                                        "class_defs_size class_defs_off data_size data_off" ) 
  38  HEADER = [ '=QL20sLLLLLLLLLLLLLLLLLLLL', HEADER_NAMEDTUPLE ] 
  39   
  40  MAP_ITEM_NAMEDTUPLE = namedtuple("MAP_ITEM_NAMEDTUPLE", "type unused size offset") 
  41  MAP_ITEM = [ '=HHLL', MAP_ITEM_NAMEDTUPLE ] 
  42   
  43  PROTO_ID_ITEM_NAMEDTUPLE = namedtuple("PROTO_ID_ITEM_NAMEDTUPLE", "shorty_idx return_type_idx parameters_off" ) 
  44  PROTO_ID_ITEM = [ '=LLL', PROTO_ID_ITEM_NAMEDTUPLE ] 
  45   
  46  METHOD_ID_ITEM_NAMEDTUPLE = namedtuple("METHOD_ID_ITEM_NAMEDTUPLE", "class_idx proto_idx name_idx" ) 
  47  METHOD_ID_ITEM = [ '=HHL', METHOD_ID_ITEM_NAMEDTUPLE ] 
  48   
  49  FIELD_ID_ITEM_NAMEDTUPLE = namedtuple("FIELD_ID_ITEM_NAMEDTUPLE", "class_idx type_idx name_idx") 
  50  FIELD_ID_ITEM = [ '=HHL', FIELD_ID_ITEM_NAMEDTUPLE ] 
  51   
  52  CLASS_DEF_ITEM_NAMEDTUPLE = namedtuple("CLASS_DEF_ITEM_NAMEDTUPLE", "class_idx access_flags superclass_idx interfaces_off source_file_idx annotations_off class_data_off static_values_off") 
  53  CLASS_DEF_ITEM = [ '=LLLLLLLL', CLASS_DEF_ITEM_NAMEDTUPLE ] 
  54   
  55  TRY_ITEM_NAMEDTUPLE = namedtuple("TRY_ITEM_NAMEDTUPLE", "start_addr insn_count handler_off" ) 
  56  TRY_ITEM = [ '=LHH', TRY_ITEM_NAMEDTUPLE ] 
  57   
  58  ANNOTATIONS_DIRECTORY_ITEM_NAMEDTUPLE = namedtuple("ANNOTATIONS_DIRECTORY_ITEM_NAMEDTUPLE", "class_annotations_off fields_size annotated_methods_size annotated_parameters_size") 
  59  ANNOTATIONS_DIRECTORY_ITEM = [ '=LLLL', ANNOTATIONS_DIRECTORY_ITEM_NAMEDTUPLE ] 
  60   
  61  TYPE_MAP_ITEM = { 
  62                          0x0  : "TYPE_HEADER_ITEM", 
  63                          0x1  : "TYPE_STRING_ID_ITEM", 
  64                          0x2  : "TYPE_TYPE_ID_ITEM", 
  65                          0x3  : "TYPE_PROTO_ID_ITEM", 
  66                          0x4  : "TYPE_FIELD_ID_ITEM", 
  67                          0x5  : "TYPE_METHOD_ID_ITEM", 
  68                          0x6  : "TYPE_CLASS_DEF_ITEM", 
  69                          0x1000 : "TYPE_MAP_LIST", 
  70                          0x1001 : "TYPE_TYPE_LIST", 
  71                          0x1002 : "TYPE_ANNOTATION_SET_REF_LIST", 
  72                          0x1003 : "TYPE_ANNOTATION_SET_ITEM", 
  73                          0x2000 : "TYPE_CLASS_DATA_ITEM", 
  74                          0x2001 : "TYPE_CODE_ITEM", 
  75                          0x2002 : "TYPE_STRING_DATA_ITEM", 
  76                          0x2003 : "TYPE_DEBUG_INFO_ITEM", 
  77                          0x2004 : "TYPE_ANNOTATION_ITEM", 
  78                          0x2005 : "TYPE_ENCODED_ARRAY_ITEM", 
  79                          0x2006 : "TYPE_ANNOTATIONS_DIRECTORY_ITEM", 
  80                       } 
  81   
  82  SPARSE_SWITCH_NAMEDTUPLE = namedtuple("SPARSE_SWITCH_NAMEDTUPLE", "ident size") 
  83  SPARSE_SWITCH = [ '=HH', SPARSE_SWITCH_NAMEDTUPLE ] 
  84   
  85  PACKED_SWITCH_NAMEDTUPLE = namedtuple("PACKED_SWITCH_NAMEDTUPLE", "ident size first_key") 
  86  PACKED_SWITCH = [ '=HHL', PACKED_SWITCH_NAMEDTUPLE ] 
  87   
  88  FILL_ARRAY_DATA_NAMEDTUPLE = namedtuple("FILL_ARRAY_DATA_NAMEDTUPLE", "ident element_width size") 
  89  FILL_ARRAY_DATA = [ '=HHL', FILL_ARRAY_DATA_NAMEDTUPLE ] 
  90   
  91  NORMAL_DVM_INS = 0 
  92  SPECIFIC_DVM_INS = 1 
  93   
94 -class FillArrayData :
95 - def __init__(self, buff) :
96 self.format = SVs( FILL_ARRAY_DATA[0], FILL_ARRAY_DATA[1], buff[ 0 : calcsize(FILL_ARRAY_DATA[0]) ] ) 97 98 general_format = self.format.get_value() 99 self.data = buff[ calcsize(FILL_ARRAY_DATA[0]) : calcsize(FILL_ARRAY_DATA[0]) + (general_format.size * general_format.element_width ) ]
100
101 - def get_raw(self) :
102 return self.format.get_raw() + self.data
103
104 - def get_data(self) :
105 return self.data
106
107 - def get_operands(self) :
108 return self.data
109
110 - def get_name(self) :
111 return "FILL-ARRAY-DATA"
112
113 - def show_buff(self, pos) :
114 buff = self.get_name() + " " 115 116 for i in range(0, len(self.data)) : 117 buff += "\\x%02x" % ord( self.data[i] ) 118 return buff
119
120 - def show(self, pos) :
121 print self.show_buff(pos),
122
123 - def get_length(self) :
124 general_format = self.format.get_value() 125 return calcsize(FILL_ARRAY_DATA[0]) + ( general_format.size * general_format.element_width )
126
127 -class SparseSwitch :
128 - def __init__(self, buff) :
129 self.format = SVs( SPARSE_SWITCH[0], SPARSE_SWITCH[1], buff[ 0 : calcsize(SPARSE_SWITCH[0]) ] ) 130 self.keys = [] 131 self.targets = [] 132 133 idx = calcsize(SPARSE_SWITCH[0]) 134 for i in range(0, self.format.get_value().size) : 135 self.keys.append( unpack('=L', buff[idx:idx+4])[0] ) 136 idx += 4 137 138 for i in range(0, self.format.get_value().size) : 139 self.targets.append( unpack('=L', buff[idx:idx+4])[0] ) 140 idx += 4
141 142 # FIXME : return correct raw
143 - def get_raw(self) :
144 return self.format.get_raw()
145
146 - def get_keys(self) :
147 return self.keys
148
149 - def get_targets(self) :
150 return self.targets
151
152 - def get_operands(self) :
153 return [ self.keys, self.targets ]
154
155 - def get_name(self) :
156 return "SPARSE-SWITCH"
157
158 - def show_buff(self, pos) :
159 buff = self.get_name() + " " 160 for i in range(0, len(self.keys)) : 161 buff += "%x:%x " % (self.keys[i], self.targets[i]) 162 163 return buff
164
165 - def show(self, pos) :
166 print self.show_buff( pos ),
167
168 - def get_length(self) :
169 return calcsize(SPARSE_SWITCH[0]) + (self.format.get_value().size * calcsize('<L')) * 2
170
171 -class PackedSwitch :
172 - def __init__(self, buff) :
173 self.format = SVs( PACKED_SWITCH[0], PACKED_SWITCH[1], buff[ 0 : calcsize(PACKED_SWITCH[0]) ] ) 174 self.targets = [] 175 176 idx = calcsize(PACKED_SWITCH[0]) 177 for i in range(0, self.format.get_value().size) : 178 self.targets.append( unpack('=L', buff[idx:idx+4])[0] ) 179 idx += 4
180 181 # FIXME : return correct raw
182 - def get_raw(self) :
183 return self.format.get_raw()
184
185 - def get_operands(self) :
186 return [ self.format.get_value().first_key, self.targets ]
187
188 - def get_targets(self) :
189 return self.targets
190
191 - def get_name(self) :
192 return "PACKED-SWITCH"
193
194 - def show_buff(self, pos) :
195 buff = self.get_name() + " " 196 buff += "%x:" % self.format.get_value().first_key 197 198 for i in self.targets : 199 buff += " %x" % i 200 201 return buff
202
203 - def show(self, pos) :
204 print self.show_buff( pos ),
205
206 - def get_length(self) :
207 return calcsize(PACKED_SWITCH[0]) + (self.format.get_value().size * calcsize('<L'))
208 209 OPCODE_OP = 0x01 210 OPCODE_BB = 0x01 211 212 OPCODE_AA_OP = 0x02 213 OPCODE_CC_BB = 0x02 214 215 OPCODE_00 = 0x03 216 OPCODE_B_A_OP = 0x04 217 218 OPCODE_CCCC = 0x05 219 OPCODE_BBBB = 0x05 220 OPCODE_AAAA = 0x05 221 222 OPCODE_SBBBB = 0x06 223 OPCODE_SAAAA = 0x06 224 OPCODE_SCCCC = 0x06 225 226 OPCODE_G_F_E_D = 0x07 227 OPCODE_SB_A_OP = 0x08 228 OPCODE_SCC_BB = 0x0b 229 230 OPCODE_SCC = 0x0d 231 OPCODE_SAA = 0x0d 232 233 OPCODE_SBBBB0000 = 0x0f 234 235 OPCODE_SBBBBBBBB = 0x10 236 OPCODE_SAAAAAAAA = 0x10 237 238 OPCODE_00_OP = 0x11 239 OPCODE_BBBBBBBB = 0x12 240 241 DALVIK_OPCODES = { 242 0x00 : [ "10x", "nop", "op", [ OPCODE_OP, OPCODE_00 ], {} ], 243 0x01 : [ "12x", "move", "vA, vB", [ OPCODE_B_A_OP ], {} ] , 244 0x02 : [ "22x", "move/from16", "vAA, vBBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], {} ], 245 0x03 : [ "32x", "move/16", "vAAAA, vBBBB", [ OPCODE_00_OP, OPCODE_AAAA, OPCODE_BBBB ], {} ], 246 0x04 : [ "12x", "move-wide", "vA, vB", [ OPCODE_B_A_OP ], {} ], 247 0x05 : [ "22x", "move-wide/from16", "vAA, vBBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], {} ], 248 0x06 : [ "32x", "move-wide/16", "vAAAA, vBBBB", [ OPCODE_00_OP, OPCODE_AAAA, OPCODE_BBBB ], {} ], 249 0x07 : [ "12x", "move-object", "vA, vB", [ OPCODE_B_A_OP ], {} ], 250 0x08 : [ "22x", "move-object/from16", "vAA, vBBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], {} ], 251 0x09 : [ "32x", "move-object/16", "vAAAA, vBBBB", [ OPCODE_00_OP, OPCODE_AAAA, OPCODE_BBBB ], {} ], 252 0x0a : [ "11x", "move-result", "vAA", [ OPCODE_AA_OP ], {} ], 253 0x0b : [ "11x", "move-result-wide", "vAA", [ OPCODE_AA_OP ], {} ], 254 0x0c : [ "11x", "move-result-object", "vAA", [ OPCODE_AA_OP ], {} ], 255 0x0d : [ "11x", "move-exception", "vAA", [ OPCODE_AA_OP ], {} ], 256 0x0e : [ "10x", "return-void", "op", [ OPCODE_OP, OPCODE_00 ], {} ], 257 0x0f : [ "11x", "return", "vAA", [ OPCODE_AA_OP ], {} ], 258 0x10 : [ "11x", "return-wide", "vAA", [ OPCODE_AA_OP ], {} ], 259 0x11 : [ "11x", "return-object", "vAA", [ OPCODE_AA_OP ], {} ], 260 0x12 : [ "11n", "const/4", "vA, #+B", [ OPCODE_SB_A_OP ], { 2 : "#+" } ], 261 0x13 : [ "21s", "const/16", "vAA, #+BBBB", [ OPCODE_AA_OP, OPCODE_SBBBB ], { 2 : "#+" } ], 262 0x14 : [ "31i", "const", "vAA, #+BBBBBBBB", [ OPCODE_AA_OP, OPCODE_SBBBB, OPCODE_SBBBB ], { 2 : "#+", 3 : "#+" } ], 263 0x15 : [ "21h", "const/high16", "vAA, #+BBBB0000", [ OPCODE_AA_OP, OPCODE_SBBBB ], { 2 : "#+" } ], 264 0x16 : [ "21s", "const-wide/16", "vAA, #+BBBB", [ OPCODE_AA_OP, OPCODE_SBBBB ], { 2 : "#+" } ], 265 0x17 : [ "31i", "const-wide/32", "vAA, #+BBBBBBBB", [ OPCODE_AA_OP, OPCODE_SBBBB, OPCODE_SBBBB ], { 2 : "#+", 3 : "#+" } ], 266 0x18 : [ "51l", "const-wide", "vAA, #+BBBBBBBBBBBBBBBB", [ OPCODE_AA_OP, OPCODE_SBBBB, OPCODE_SBBBB, OPCODE_SBBBB, OPCODE_SBBBB ], { 2 : "#+", 3 : "#+", 4 : "#+", 5 : "#+" } ], 267 0x19 : [ "21h", "const-wide/high16", "vAA, #+BBBB000000000000", [ OPCODE_AA_OP, OPCODE_SBBBB ], { 2 : "#+" } ], 268 0x1a : [ "21c", "const-string", "vAA, string@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "string@" } ], 269 0x1b : [ "31c", "const-string/jumbo", "vAA, string@BBBBBBBB", [ OPCODE_AA_OP, OPCODE_BBBBBBBB ], { 2 : "#+" } ], 270 0x1c : [ "21c", "const-class", "vAA, type@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "type@" } ], 271 0x1d : [ "11x", "monitor-enter", "vAA", [ OPCODE_AA_OP ], {} ], 272 0x1e : [ "11x", "monitor-exit", "vAA", [ OPCODE_AA_OP ], {} ], 273 0x1f : [ "21c", "check-cast", "vAA, type@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "type@" } ], 274 0x20 : [ "22c", "instance-of", "vA, vB, type@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "type@" } ], 275 0x21 : [ "12x", "array-length", "vA, vB", [ OPCODE_B_A_OP ], {} ], 276 0x22 : [ "21c", "new-instance", "vAA, type@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "type@" } ], 277 0x23 : [ "22c", "new-array", "vA, vB, type@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "type@"} ], 278 0x24 : [ "35c", "filled-new-array", "vD, vE, vF, vG, vA, type@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC, OPCODE_G_F_E_D ], { 3 : "type@" } ], 279 0x25 : [ "3rc", "filled-new-array/range", "vB{vCCCC .. vNNNN}, type@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB, OPCODE_CCCC ], { 2 : "type@" } ], 280 0x26 : [ "31t", "fill-array-data", "vAA, +BBBBBBBB ", [ OPCODE_AA_OP, OPCODE_SBBBBBBBB ], { 2 : "#+" }, FillArrayData ], 281 0x27 : [ "11x", "throw", "vAA", [ OPCODE_B_A_OP ], {} ], 282 0x28 : [ "10t", "goto", "+AA", [ OPCODE_OP, OPCODE_SAA ], { 1 : "#+" } ], 283 0x29 : [ "20t", "goto/16", "+AAAA", [ OPCODE_00_OP, OPCODE_SAAAA ], { 1 : "#+" } ], 284 0x2a : [ "30t", "goto/32", "+AAAAAAAA", [ OPCODE_00_OP, OPCODE_SAAAAAAAA ], { 1 : "#+" } ], 285 0x2b : [ "31t", "packed-switch", "vAA, +BBBBBBBB ", [ OPCODE_AA_OP, OPCODE_SBBBBBBBB ], { 2 : "#+"}, PackedSwitch ], 286 0x2c : [ "31t", "sparse-switch", "vAA +BBBBBBBB", [ OPCODE_AA_OP, OPCODE_SBBBBBBBB ], { 2 : "#+"}, SparseSwitch ], 287 0x2d : [ "23x", "cmpl-float", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 288 0x2e : [ "23x", "cmpg-float", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 289 0x2f : [ "23x", "cmpl-double", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 290 0x30 : [ "23x", "cmpg-double", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 291 0x31 : [ "23x", "cmp-long", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 292 0x32 : [ "22t", "if-eq", "vA, vB, +CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 293 0x33 : [ "22t", "if-ne", "vA, vB, +CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 294 0x34 : [ "22t", "if-lt", "vA, vB, +CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 295 0x35 : [ "22t", "if-ge", "vA, vB, +CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 296 0x36 : [ "22t", "if-gt", "vA, vB, +CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 297 0x37 : [ "22t", "if-le", "vA, vB, +CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 298 0x38 : [ "21t", "if-eqz", "vAA, +BBBB", [ OPCODE_AA_OP, OPCODE_SBBBB ], { 2 : "#+" } ], 299 0x39 : [ "21t", "if-nez", "vAA, +BBBB", [ OPCODE_AA_OP, OPCODE_SBBBB ], { 2 : "#+" } ], 300 0x3a : [ "21t", "if-ltz", "vAA, +BBBB", [ OPCODE_AA_OP, OPCODE_SBBBB ], { 2 : "#+" } ], 301 0x3b : [ "21t", "if-gez", "vAA, +BBBB", [ OPCODE_AA_OP, OPCODE_SBBBB ], { 2 : "#+" } ], 302 0x3c : [ "21t", "if-gtz", "vAA, +BBBB", [ OPCODE_AA_OP, OPCODE_SBBBB ], { 2 : "#+" } ], 303 0x3d : [ "21t", "if-lez", "vAA, +BBBB", [ OPCODE_AA_OP, OPCODE_SBBBB ], { 2 : "#+" } ], 304 305 # UNUSED OPCODES 306 0x3e : [ "10x", "nop", "op", [ OPCODE_OP, OPCODE_00 ], {} ], 307 0x3f : [ "10x", "nop", "op", [ OPCODE_OP, OPCODE_00 ], {} ], 308 0x40 : [ "10x", "nop", "op", [ OPCODE_OP, OPCODE_00 ], {} ], 309 0x41 : [ "10x", "nop", "op", [ OPCODE_OP, OPCODE_00 ], {} ], 310 0x42 : [ "10x", "nop", "op", [ OPCODE_OP, OPCODE_00 ], {} ], 311 0x43 : [ "10x", "nop", "op", [ OPCODE_OP, OPCODE_00 ], {} ], 312 ################### 313 314 0x44 : [ "23x", "aget", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 315 0x45 : [ "23x", "aget-wide", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 316 0x46 : [ "23x", "aget-object", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 317 0x47 : [ "23x", "aget-boolean", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 318 0x48 : [ "23x", "aget-byte", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 319 0x49 : [ "23x", "aget-char", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 320 0x4a : [ "23x", "aget-short", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 321 0x4b : [ "23x", "aput", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 322 0x4c : [ "23x", "aput-wide", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 323 0x4d : [ "23x", "aput-object", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 324 0x4e : [ "23x", "aput-boolean", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 325 0x4f : [ "23x", "aput-byte", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 326 0x50 : [ "23x", "aput-char", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 327 0x51 : [ "23x", "aput-short", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 328 0x52 : [ "22c", "iget", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 329 0x53 : [ "22c", "iget-wide", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 330 0x54 : [ "22c", "iget-object", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 331 0x55 : [ "22c", "iget-boolean", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 332 0x56 : [ "22c", "iget-byte", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 333 0x57 : [ "22c", "iget-char", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 334 0x58 : [ "22c", "iget-short", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 335 0x59 : [ "22c", "iput", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 336 0x5a : [ "22c", "iput-wide", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 337 0x5b : [ "22c", "iput-object", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 338 0x5c : [ "22c", "iput-boolean", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 339 0x5d : [ "22c", "iput-byte", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 340 0x5e : [ "22c", "iput-char", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 341 0x5f : [ "22c", "iput-short", "vA, vB, field@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC ], { 3 : "field@" } ], 342 0x60 : [ "21c", "sget", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 343 0x61 : [ "21c", "sget-wide", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 344 0x62 : [ "21c", "sget-object", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 345 0x63 : [ "21c", "sget-boolean", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 346 0x64 : [ "21c", "sget-byte", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 347 0x65 : [ "21c", "sget-char", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 348 0x66 : [ "21c", "sget-short", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 349 0x67 : [ "21c", "sput", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 350 0x68 : [ "21c", "sput-wide", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 351 0x69 : [ "21c", "sput-object", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "#+" } ], 352 0x6a : [ "21c", "sput-boolean", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 353 0x6b : [ "21c", "sput-byte", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 354 0x6c : [ "21c", "sput-char", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 355 0x6d : [ "21c", "sput-short", "vAA, field@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB ], { 2 : "field@" } ], 356 0x6e : [ "35c", "invoke-virtual", "vB{vD, vE, vF, vG, vA}, meth@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC, OPCODE_G_F_E_D ], { 3 : "meth@" } ], 357 0x6f : [ "35c", "invoke-super", "vB{vD, vE, vF, vG, vA}, meth@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC, OPCODE_G_F_E_D ], { 3 : "meth@" } ], 358 0x70 : [ "35c", "invoke-direct", "vB{vD, vE, vF, vG, vA}, meth@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC, OPCODE_G_F_E_D ], { 3 : "meth@" } ], 359 0x71 : [ "35c", "invoke-static", "vB{vD, vE, vF, vG, vA}, meth@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC, OPCODE_G_F_E_D ], { 3 : "meth@" } ], 360 0x72 : [ "35c", "invoke-interface", "vB{vD, vE, vF, vG, vA}, meth@CCCC", [ OPCODE_B_A_OP, OPCODE_CCCC, OPCODE_G_F_E_D ], { 3 : "meth@" } ], 361 0x74 : [ "3rc", "invoke-virtual/range", "vB{vCCCC .. vNNNN}, meth@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB, OPCODE_CCCC ], { 2 : "meth@"} ], 362 0x75 : [ "3rc", "invoke-super/range", "vB{vCCCC .. vNNNN}, meth@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB, OPCODE_CCCC ], { 2 : "meth@"} ], 363 0x76 : [ "3rc", "invoke-direct/range", "vB{vCCCC .. vNNNN}, meth@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB, OPCODE_CCCC ], { 2 : "meth@"} ], 364 0x77 : [ "3rc", "invoke-static/range", "vB{vCCCC .. vNNNN}, meth@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB, OPCODE_CCCC ], { 2 : "meth@"} ], 365 0x78 : [ "3rc", "invoke-interface/range", "vB{vCCCC .. vNNNN}, meth@BBBB", [ OPCODE_AA_OP, OPCODE_BBBB, OPCODE_CCCC ], { 2 : "meth@"} ], 366 0x7b : [ "12x", "neg-int", "vA, vB", [ OPCODE_B_A_OP ], {} ], 367 0x7c : [ "12x", "not-int", "vA, vB", [ OPCODE_B_A_OP ], {} ], 368 0x7d : [ "12x", "neg-long", "vA, vB", [ OPCODE_B_A_OP ], {} ], 369 0x7e : [ "12x", "not-long", "vA, vB", [ OPCODE_B_A_OP ], {} ], 370 0x7f : [ "12x", "neg-float", "vA, vB", [ OPCODE_B_A_OP ], {} ], 371 0x80 : [ "12x", "neg-double", "vA, vB", [ OPCODE_B_A_OP ], {} ], 372 0x81 : [ "12x", "int-to-long", "vA, vB", [ OPCODE_B_A_OP ], {} ], 373 0x82 : [ "12x", "int-to-float", "vA, vB", [ OPCODE_B_A_OP ], {} ], 374 0x83 : [ "12x", "int-to-double", "vA, vB", [ OPCODE_B_A_OP ], {} ], 375 0x84 : [ "12x", "long-to-int", "vA, vB", [ OPCODE_B_A_OP ], {} ], 376 0x85 : [ "12x", "long-to-float", "vA, vB", [ OPCODE_B_A_OP ], {} ], 377 0x86 : [ "12x", "long-to-double", "vA, vB", [ OPCODE_B_A_OP ], {} ], 378 0x87 : [ "12x", "float-to-int", "vA, vB", [ OPCODE_B_A_OP ], {} ], 379 0x88 : [ "12x", "float-to-long", "vA, vB", [ OPCODE_B_A_OP ], {} ], 380 0x89 : [ "12x", "float-to-double", "vA, vB", [ OPCODE_B_A_OP ], {} ], 381 0x8a : [ "12x", "double-to-int", "vA, vB", [ OPCODE_B_A_OP ], {} ], 382 0x8b : [ "12x", "double-to-long", "vA, vB", [ OPCODE_B_A_OP ], {} ], 383 0x8c : [ "12x", "double-to-float", "vA, vB", [ OPCODE_B_A_OP ], {} ], 384 0x8d : [ "12x", "int-to-byte", "vA, vB", [ OPCODE_B_A_OP ], {} ], 385 0x8e : [ "12x", "int-to-char", "vA, vB", [ OPCODE_B_A_OP ], {} ], 386 0x8f : [ "12x", "int-to-short", "vA, vB", [ OPCODE_B_A_OP ], {} ], 387 0x90 : [ "23x", "add-int", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 388 0x91 : [ "23x", "sub-int", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 389 0x92 : [ "23x", "mul-int", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 390 0x93 : [ "23x", "div-int", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 391 0x94 : [ "23x", "rem-int", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 392 0x95 : [ "23x", "and-int", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 393 0x96 : [ "23x", "or-int", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 394 0x97 : [ "23x", "xor-int", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 395 0x98 : [ "23x", "shl-int", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 396 0x99 : [ "23x", "shr-int", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 397 0x9a : [ "23x", "ushr-int", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 398 0x9b : [ "23x", "add-long", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 399 0x9c : [ "23x", "sub-long", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 400 0x9d : [ "23x", "mul-long", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 401 0x9e : [ "23x", "div-long", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 402 0x9f : [ "23x", "rem-long", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 403 0xa0 : [ "23x", "and-long", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 404 0xa1 : [ "23x", "or-long", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 405 0xa2 : [ "23x", "xor-long", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 406 0xa3 : [ "23x", "shl-long", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 407 0xa4 : [ "23x", "shr-long", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 408 0xa5 : [ "23x", "ushr-long", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 409 0xa6 : [ "23x", "add-float", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 410 0xa7 : [ "23x", "sub-float", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 411 0xa8 : [ "23x", "mul-float", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 412 0xa9 : [ "23x", "div-float", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 413 0xaa : [ "23x", "rem-float", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 414 0xab : [ "23x", "add-double", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 415 0xac : [ "23x", "sub-double", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 416 0xad : [ "23x", "mul-double", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 417 0xae : [ "23x", "div-double", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 418 0xaf : [ "23x", "rem-double", "vAA, vBB, vCC", [ OPCODE_AA_OP, OPCODE_CC_BB ], {} ], 419 0xb0 : [ "12x", "add-int/2addr", "vA, vB", [ OPCODE_B_A_OP], {} ], 420 0xb1 : [ "12x", "sub-int/2addr", "vA, vB", [ OPCODE_B_A_OP], {} ], 421 0xb2 : [ "12x", "mul-int/2addr", "vA, vB", [ OPCODE_B_A_OP], {} ], 422 0xb3 : [ "12x", "div-int/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 423 0xb4 : [ "12x", "rem-int/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 424 0xb5 : [ "12x", "and-int/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 425 0xb6 : [ "12x", "or-int/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 426 0xb7 : [ "12x", "xor-int/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 427 0xb8 : [ "12x", "shl-int/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 428 0xb9 : [ "12x", "shr-int/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 429 0xba : [ "12x", "ushr-int/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 430 0xbb : [ "12x", "add-long/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 431 0xbc : [ "12x", "sub-long/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 432 0xbd : [ "12x", "mul-long/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 433 0xbe : [ "12x", "div-long/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 434 0xbf : [ "12x", "rem-long/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 435 0xc0 : [ "12x", "and-long/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 436 0xc1 : [ "12x", "or-long/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 437 0xc2 : [ "12x", "xor-long/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 438 0xc3 : [ "12x", "shl-long/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 439 0xc4 : [ "12x", "shr-long/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 440 0xc5 : [ "12x", "ushr-long/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 441 0xc6 : [ "12x", "add-float/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 442 0xc7 : [ "12x", "sub-float/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 443 0xc8 : [ "12x", "mul-float/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 444 0xc9 : [ "12x", "div-float/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 445 0xca : [ "12x", "rem-float/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 446 0xcb : [ "12x", "add-double/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 447 0xcc : [ "12x", "sub-double/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 448 0xcd : [ "12x", "mul-double/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 449 0xce : [ "12x", "div-double/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 450 0xcf : [ "12x", "rem-double/2addr", "vA, vB", [ OPCODE_B_A_OP ], {} ], 451 0xd0 : [ "22s", "add-int/lit16", "vA, vB, #+CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 452 0xd1 : [ "22s", "rsub-int", "vA, vB, #+CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 453 0xd2 : [ "22s", "mul-int/lit16", "vA, vB, #+CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 454 0xd3 : [ "22s", "div-int/lit16", "vA, vB, #+CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 455 0xd4 : [ "22s", "rem-int/lit16", "vA, vB, #+CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 456 0xd5 : [ "22s", "and-int/lit16", "vA, vB, #+CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 457 0xd6 : [ "22s", "or-int/lit16", "vA, vB, #+CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 458 0xd7 : [ "22s", "xor-int/lit16", "vA, vB, #+CCCC", [ OPCODE_B_A_OP, OPCODE_SCCCC ], { 3 : "#+" } ], 459 0xd8 : [ "22b", "add-int/lit8", "vAA, vBB, #+CC", [ OPCODE_AA_OP, OPCODE_BB, OPCODE_SCC ], { 3 : "#+" } ], 460 0xd9 : [ "22s", "rsub-int/lit8", "vAA, vBB, #+CC", [ OPCODE_AA_OP, OPCODE_BB, OPCODE_SCC ], { 3 : "#+" } ], 461 0xda : [ "22s", "mul-int/lit8", "vAA, vBB, #+CC", [ OPCODE_AA_OP, OPCODE_BB, OPCODE_SCC ], { 3 : "#+" } ], 462 0xdb : [ "22s", "div-int/lit8", "vAA, vBB, #+CC", [ OPCODE_AA_OP, OPCODE_BB, OPCODE_SCC ], { 3 : "#+" } ], 463 0xdc : [ "22s", "rem-int/lit8", "vAA, vBB, #+CC", [ OPCODE_AA_OP, OPCODE_BB, OPCODE_SCC ], { 3 : "#+" } ], 464 0xdd : [ "22s", "and-int/lit8", "vAA, vBB, #+CC", [ OPCODE_AA_OP, OPCODE_BB, OPCODE_SCC ], { 3 : "#+" } ], 465 0xde : [ "22s", "or-int/lit8", "vAA, vBB, #+CC", [ OPCODE_AA_OP, OPCODE_BB, OPCODE_SCC ], { 3 : "#+" } ], 466 0xdf : [ "22s", "xor-int/lit8", "vAA, vBB, #+CC", [ OPCODE_AA_OP, OPCODE_BB, OPCODE_SCC ], { 3 : "#+" } ], 467 0xe0 : [ "22s", "shl-int/lit8", "vAA, vBB, #+CC", [ OPCODE_AA_OP, OPCODE_BB, OPCODE_SCC ], { 3 : "#+" } ], 468 0xe1 : [ "22s", "shr-int/lit8", "vAA, vBB, #+CC", [ OPCODE_AA_OP, OPCODE_BB, OPCODE_SCC ], { 3 : "#+" } ], 469 0xe2 : [ "22s", "ushr-int/lit8", "vAA, vBB, #+CC", [ OPCODE_AA_OP, OPCODE_BB, OPCODE_SCC ], { 3 : "#+" } ], 470 } 471 472 MATH_DVM_OPCODES = { "add." : '+', 473 "div." : '/', 474 "mul." : '*', 475 "or." : '|', 476 "sub." : '-', 477 "and." : '&', 478 "xor." : '^', 479 "shl." : "<<", 480 "shr." : ">>", 481 } 482 483 INVOKE_DVM_OPCODES = [ "invoke." ] 484 485 FIELD_READ_DVM_OPCODES = [ ".get" ] 486 FIELD_WRITE_DVM_OPCODES = [ ".put" ] 487 488 BREAK_DVM_OPCODES = [ "invoke.", "move.", ".put", "if." ] 489 490 BRANCH_DVM_OPCODES = [ "if.", "goto", "goto.", "return", "return.", "packed.", "sparse." ] 491
492 -def readuleb128(buff) :
493 result = ord( buff.read(1) ) 494 if result > 0x7f : 495 cur = ord( buff.read(1) ) 496 result = (result & 0x7f) | ((cur & 0x7f) << 7) 497 if cur > 0x7f : 498 cur = ord( buff.read(1) ) 499 result |= (cur & 0x7f) << 14 500 if cur > 0x7f : 501 cur = ord( buff.read(1) ) 502 result |= (cur & 0x7f) << 21 503 if cur > 0x7f : 504 cur = ord( buff.read(1) ) 505 result |= cur << 28 506 507 return result
508
509 -def readsleb128(buff) :
510 result = unpack( '=b', buff.read(1) )[0] 511 512 if result <= 0x7f : 513 result = (result << 25) 514 if result > 0x7fffffff : 515 result = (0x7fffffff & result) - 0x80000000 516 result = result >> 25 517 else : 518 cur = unpack( '=b', buff.read(1) )[0] 519 result = (result & 0x7f) | ((cur & 0x7f) << 7) 520 if cur <= 0x7f : 521 result = (result << 18) >> 18 522 else : 523 cur = unpack( '=b', buff.read(1) )[0] 524 result |= (cur & 0x7f) << 14 525 if cur <= 0x7f : 526 result = (result << 11) >> 11 527 else : 528 cur = unpack( '=b', buff.read(1) )[0] 529 result |= (cur & 0x7f) << 21 530 if cur <= 0x7f : 531 result = (result << 4) >> 4 532 else : 533 cur = unpack( '=b', buff.read(1) )[0] 534 result |= cur << 28 535 536 return result
537
538 -def writeuleb128(value) :
539 remaining = value >> 7 540 541 buff = "" 542 while remaining > 0 : 543 buff += pack( "=B", ((value & 0x7f) | 0x80) ) 544 545 value = remaining 546 remaining >>= 7 547 548 buff += pack( "=B", value & 0x7f ) 549 return buff
550
551 -def writesleb128(value) :
552 remaining = value >> 7 553 hasMore = True 554 end = 0 555 buff = "" 556 557 if (value & (-sys.maxint - 1)) == 0 : 558 end = 0 559 else : 560 end = -1 561 562 while hasMore : 563 hasMore = (remaining != end) or ((remaining & 1) != ((value >> 6) & 1)) 564 tmp = 0 565 if hasMore : 566 tmp = 0x80 567 568 buff += pack( "=B", (value & 0x7f) | (tmp) ) 569 value = remaining 570 remaining >>= 7 571 572 return buff
573
574 -def determineNext(i, end, m) :
575 if "return" in i.get_name() : 576 return [ -1 ] 577 elif "goto" in i.get_name() : 578 off = i.get_operands()[-1][1] * 2 579 return [ off + end ] 580 elif "if" in i.get_name() : 581 off = i.get_operands()[-1][1] * 2 582 583 return [ end + i.get_length(), off + (end) ] 584 elif "packed" in i.get_name() or "sparse" in i.get_name() : 585 x = [] 586 587 x.append( end + i.get_length() ) 588 589 code = m.get_code().get_bc() 590 off = i.get_operands()[-1][1] * 2 591 data = code.get_ins_off( off + end ) 592 593 for target in data.get_targets() : 594 x.append( target*2 + end ) 595 596 return x 597 return []
598
599 -class HeaderItem :
600 - def __init__(self, size, buff, cm) :
601 self.__CM = cm 602 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 603 self.format = SVs( HEADER[0], HEADER[1], buff.read( calcsize(HEADER[0]) ) )
604
605 - def reload(self) :
606 pass
607
608 - def get_obj(self) :
609 return []
610
611 - def get_raw(self) :
612 return [ bytecode.Buff( self.__offset.off, self.format.get_value_buff() ) ]
613
614 - def get_value(self) :
615 return self.format.get_value()
616
617 - def show(self) :
618 bytecode._Print("HEADER", self.format)
619
620 - def get_off(self) :
621 return self.__offset.off
622
623 -class AnnotationOffItem :
624 - def __init__(self, buff, cm) :
625 self.__CM = cm 626 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 627 self.annotation_off = SV( '=L', buff.read( 4 ) )
628
629 - def show(self) :
630 print "ANNOTATION_OFF_ITEM annotation_off=0x%x" % self.annotation_off.get_value()
631
632 - def get_obj(self) :
633 return []
634
635 - def get_raw(self) :
636 return bytecode.Buff( self.__offset.off, self.annotation_off.get_value_buff() )
637
638 -class AnnotationSetItem :
639 - def __init__(self, buff, cm) :
640 self.__CM = cm 641 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 642 self.annotation_off_item = [] 643 644 self.size = SV( '=L', buff.read( 4 ) ) 645 for i in range(0, self.size) : 646 self.annotation_off_item.append( AnnotationOffItem(buff, cm) )
647
648 - def reload(self) :
649 pass
650
651 - def get_annotation_off_item(self) :
652 return self.annotation_off_item
653
654 - def show(self) :
655 print "ANNOTATION_SET_ITEM" 656 nb = 0 657 for i in self.annotation_off_item : 658 print nb, 659 i.show() 660 nb = nb + 1
661
662 - def get_obj(self) :
663 return [ i for i in self.annotation_off_item ]
664
665 - def get_raw(self) :
666 return [ bytecode.Buff(self.__offset.off, self.size.get_value_buff()) ] + [ i.get_raw() for i in self.annotation_off_item ]
667
668 - def get_off(self) :
669 return self.__offset.off
670
671 -class AnnotationSetRefItem :
672 - def __init__(self, buff, cm) :
673 self.__CM = cm 674 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 675 self.annotations_off = SV( '=L', buff.read( 4 ) )
676
677 - def show(self) :
678 print "ANNOTATION_SET_REF_ITEM annotations_off=0x%x" % self.annotation_offs.get_value()
679
680 - def get_obj(self) :
681 return []
682
683 - def get_raw(self) :
684 return bytecode.Buff( self.__offset.off, self.annotations_off.get_value_buff() )
685
686 -class AnnotationSetRefList :
687 - def __init__(self, buff, cm) :
688 self.__CM = cm 689 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 690 self.list = [] 691 692 self.size = SV( '=L', buff.read( 4 ) ) 693 for i in range(0, self.size) : 694 self.list.append( AnnotationSetRefItem(buff, cm) )
695
696 - def reload(self) :
697 pass
698
699 - def show(self) :
700 print "ANNOTATION_SET_REF_LIST" 701 nb = 0 702 for i in self.list : 703 print nb, 704 i.show() 705 nb = nb + 1
706
707 - def get_obj(self) :
708 return [ i for i in self.list ]
709
710 - def get_raw(self) :
711 return [ bytecode.Buff(self.__offset.off, self.size.get_value_buff()) ] + [ i.get_raw() for i in self.list ]
712
713 - def get_off(self) :
714 return self.__offset.off
715
716 -class FieldAnnotation :
717 - def __init__(self, buff, cm) :
718 self.__CM = cm 719 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 720 self.field_idx = SV('=L', buff.read( 4 ) ) 721 self.annotations_off = SV('=L', buff.read( 4 ) )
722
723 - def show(self) :
724 print "FIELD_ANNOTATION field_idx=0x%x annotations_off=0x%x" % (self.field_idx.get_value(), self.annotations_off.get_value())
725
726 - def get_obj(self) :
727 return []
728
729 - def get_raw(self) :
730 return bytecode.Buff(self.__offset.off, self.field_idx.get_value_buff() + self.annotations_off.get_value_buff())
731
732 -class MethodAnnotation :
733 - def __init__(self, buff, cm) :
734 self.__CM = cm 735 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 736 self.method_idx = SV('=L', buff.read( 4 ) ) 737 self.annotations_off = SV('=L', buff.read( 4 ) )
738
739 - def show(self) :
740 print "METHOD_ANNOTATION method_idx=0x%x annotations_off=0x%x" % ( self.method_idx.get_value(), self.annotations_off.get_value())
741
742 - def get_obj(self) :
743 return []
744
745 - def get_raw(self) :
746 return bytecode.Buff(self.__offset.off, self.method_idx.get_value_buff() + self.annotations_off.get_value_buff())
747
748 -class ParameterAnnotation :
749 - def __init__(self, buff, cm) :
750 self.__CM = cm 751 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 752 self.method_idx = SV('=L', buff.read( 4 ) ) 753 self.annotations_off = SV('=L', buff.read( 4 ) )
754
755 - def show(self) :
756 print "PARAMETER_ANNOTATION method_idx=0x%x annotations_off=0x%x" % (self.method_idx.get_value(), self.annotations_off.get_value())
757
758 - def get_obj(self) :
759 return []
760
761 - def get_raw(self) :
762 return bytecode.Buff(self.__offset.off, self.method_idx.get_value_buff() + self.annotations_off.get_value_buff())
763
764 -class AnnotationsDirectoryItem :
765 - def __init__(self, buff, cm) :
766 self.__CM = cm 767 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 768 self.format = SVs( ANNOTATIONS_DIRECTORY_ITEM[0], ANNOTATIONS_DIRECTORY_ITEM[1], buff.read( calcsize(ANNOTATIONS_DIRECTORY_ITEM[0]) ) ) 769 770 self.field_annotations = [] 771 for i in range(0, self.format.get_value().fields_size) : 772 self.field_annotations.append( FieldAnnotation( buff, cm ) ) 773 774 self.method_annotations = [] 775 for i in range(0, self.format.get_value().annotated_methods_size) : 776 self.method_annotations.append( MethodAnnotation( buff, cm ) ) 777 778 self.parameter_annotations = [] 779 for i in range(0, self.format.get_value().annotated_parameters_size) : 780 self.parameter_annotations.append( ParameterAnnotation( buff, cm ) )
781
782 - def reload(self) :
783 pass
784
785 - def show(self) :
786 print "ANNOTATIONS_DIRECTORY_ITEM", self.format.get_value() 787 for i in self.field_annotations : 788 i.show() 789 790 for i in self.method_annotations : 791 i.show() 792 793 for i in self.parameter_annotations : 794 i.show()
795
796 - def get_obj(self) :
797 return [ i for i in self.field_annotations ] + \ 798 [ i for i in self.method_annotations ] + \ 799 [ i for i in self.parameter_annotations ]
800
801 - def get_raw(self) :
802 return [ bytecode.Buff( self.__offset.off, self.format.get_value_buff() ) ] + \ 803 [ i.get_raw() for i in self.field_annotations ] + \ 804 [ i.get_raw() for i in self.method_annotations ] + \ 805 [ i.get_raw() for i in self.parameter_annotations ]
806
807 - def get_off(self) :
808 return self.__offset.off
809
810 -class TypeLItem :
811 - def __init__(self, buff, cm) :
812 self.__CM = cm 813 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 814 self.type_idx = SV( '=H', buff.read( 2 ) )
815
816 - def show(self) :
817 print "TYPE_LITEM", self.type_idx.get_value()
818
819 - def get_string(self) :
820 return self.__CM.get_type( self.type_idx.get_value() )
821
822 - def get_obj(self) :
823 return []
824
825 - def get_raw(self) :
826 return bytecode.Buff(self.__offset.off, self.type_idx.get_value_buff())
827
828 -class TypeList :
829 - def __init__(self, buff, cm) :
830 self.__CM = cm 831 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 832 offset = buff.get_idx() 833 834 self.pad = "" 835 if offset % 4 != 0 : 836 self.pad = buff.read( offset % 4 ) 837 838 self.len_pad = len(self.pad) 839 840 self.size = SV( '=L', buff.read( 4 ) ) 841 842 self.list = [] 843 for i in range(0, self.size) : 844 self.list.append( TypeLItem( buff, cm ) )
845
846 - def reload(self) :
847 pass
848
849 - def get_type_list_off(self) :
850 return self.__offset.off + self.len_pad
851
852 - def get_string(self) :
853 return ' '.join(i.get_string() for i in self.list)
854
855 - def show(self) :
856 print "TYPE_LIST" 857 nb = 0 858 for i in self.list : 859 print nb, self.__offset.off + self.lend_pad, 860 i.show() 861 nb = nb + 1
862
863 - def get_obj(self) :
864 return [ i for i in self.list ]
865
866 - def get_raw(self) :
867 return [ bytecode.Buff( self.__offset.off, self.pad + self.size.get_value_buff() ) ] + [ i.get_raw() for i in self.list ]
868
869 - def get_off(self) :
870 return self.__offset.off
871 872 DBG_END_SEQUENCE = 0x00 # (none) terminates a debug info sequence for a code_item 873 DBG_ADVANCE_PC = 0x01 # uleb128 addr_diff addr_diff: amount to add to address register advances the address register without emitting a positions entry 874 DBG_ADVANCE_LINE = 0x02 # sleb128 line_diff line_diff: amount to change line register by advances the line register without emitting a positions entry 875 DBG_START_LOCAL = 0x03 # uleb128 register_num 876 # uleb128p1 name_idx 877 # uleb128p1 type_idx 878 # register_num: register that will contain local name_idx: string index of the name 879 # 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. 880 DBG_START_LOCAL_EXTENDED = 0x04 # uleb128 register_num uleb128p1 name_idx uleb128p1 type_idx uleb128p1 sig_idx 881 # register_num: register that will contain local 882 # name_idx: string index of the name 883 # type_idx: type index of the type 884 # sig_idx: string index of the type signature 885 # 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. ( 886 # If sig_idx is -1, though, the same data could be represented more efficiently using the opcode DBG_START_LOCAL.) 887 # Note: See the discussion under "dalvik.annotation.Signature" below for caveats about handling signatures. 888 DBG_END_LOCAL = 0x05 # uleb128 register_num 889 # register_num: register that contained local 890 # marks a currently-live local variable as out of scope at the current address 891 DBG_RESTART_LOCAL = 0x06 # uleb128 register_num 892 # register_num: register to restart re-introduces a local variable at the current address. 893 # The name and type are the same as the last local that was live in the specified register. 894 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 895 # method prologue (an appropriate place for a method breakpoint). The prologue_end register is cleared by any special (>= 0x0a) opcode. 896 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 897 # of a method epilogue (an appropriate place to suspend execution before method exit). The epilogue_begin register is cleared by any special (>= 0x0a) opcode. 898 DBG_SET_FILE = 0x09 # uleb128p1 name_idx 899 # 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, 900 # instead of the default name specified in code_item 901 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. 902 DBG_Special_Opcodes_END = 0xff 903
904 -class DBGBytecode :
905 - def __init__(self, op_value) :
906 self.__op_value = op_value 907 self.__format = []
908
909 - def get_op_value(self) :
910 return self.__op_value
911
912 - def add(self, value, ttype) :
913 self.__format.append( (value, ttype) )
914
915 - def show(self) :
916 return [ i[0] for i in self.__format ]
917
918 - def get_obj(self) :
919 return []
920
921 - def get_raw(self) :
922 buff = self.__op_value.get_value_buff() 923 for i in self.__format : 924 if i[1] == "u" : 925 buff += writeuleb128( i[0] ) 926 elif i[1] == "s" : 927 buff += writesleb128( i[0] ) 928 return buff
929
930 -class DebugInfoItem2 :
931 - def __init__(self, buff, cm) :
932 self.__CM = cm 933 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 934 935 self.__buff = buff 936 self.__raw = ""
937
938 - def reload(self) :
939 offset = self.__offset.off 940 941 n = self.__CM.get_next_offset_item( offset ) 942 943 s_idx = self.__buff.get_idx() 944 self.__buff.set_idx( offset ) 945 self.__raw = self.__buff.read( n - offset ) 946 self.__buff.set_idx( s_idx )
947
948 - def show(self) :
949 pass
950
951 - def get_obj(self) :
952 return []
953
954 - def get_raw(self) :
955 return [ bytecode.Buff(self.__offset.off, self.__raw) ]
956
957 - def get_off(self) :
958 return self.__offset.off
959
960 -class DebugInfoItem :
961 - def __init__(self, buff, cm) :
962 self.__offset = buff.get_idx() 963 self.__line_start = readuleb128( buff ) 964 self.__parameters_size = readuleb128( buff ) 965 966 self.__parameter_names = [] 967 for i in range(0, self.__parameters_size) : 968 self.__parameter_names.append( readuleb128( buff ) ) 969 970 self.__bytecodes = [] 971 bcode = DBGBytecode( SV( '=B', buff.read(1) ) ) 972 self.__bytecodes.append( bcode ) 973 974 while bcode.get_op_value().get_value() != DBG_END_SEQUENCE : 975 bcode_value = bcode.get_op_value().get_value() 976 # print "0x%x" % bcode_value 977 978 if bcode_value == DBG_SET_PROLOGUE_END : 979 pass 980 elif bcode_value >= DBG_Special_Opcodes_BEGIN and bcode_value <= DBG_Special_Opcodes_END : 981 pass 982 elif bcode_value == DBG_ADVANCE_PC : 983 bcode.add( readuleb128( buff ), "u" ) 984 elif bcode_value == DBG_ADVANCE_LINE : 985 bcode.add( readsleb128( buff ), "s" ) 986 elif bcode_value == DBG_START_LOCAL : 987 bcode.add( readuleb128( buff ), "u" ) 988 bcode.add( readuleb128( buff ), "u" ) 989 bcode.add( readuleb128( buff ), "u" ) 990 elif bcode_value == DBG_START_LOCAL_EXTENDED : 991 bcode.add( readuleb128( buff ), "u" ) 992 bcode.add( readuleb128( buff ), "u" ) 993 bcode.add( readuleb128( buff ), "u" ) 994 bcode.add( readuleb128( buff ), "u" ) 995 elif bcode_value == DBG_END_LOCAL : 996 bcode.add( readuleb128( buff ), "u" ) 997 elif bcode_value == DBG_RESTART_LOCAL : 998 bcode.add( readuleb128( buff ), "u" ) 999 else : 1000 bytecode.Exit( "unknown or not yet supported DBG bytecode 0x%x" % bcode_value ) 1001 1002 bcode = DBGBytecode( SV( '=B', buff.read(1) ) ) 1003 self.__bytecodes.append( bcode )
1004
1005 - def reload(self) :
1006 pass
1007
1008 - def show(self) :
1009 print self.__line_start 1010 print self.__parameters_size 1011 print self.__parameter_names
1012
1013 - def get_raw(self) :
1014 return [ bytecode.Buff( self.__offset, writeuleb128( self.__line_start ) + \ 1015 writeuleb128( self.__parameters_size ) + \ 1016 ''.join(writeuleb128(i) for i in self.__parameter_names) + \ 1017 ''.join(i.get_raw() for i in self.__bytecodes) ) ]
1018 1019 1020 VALUE_BYTE = 0x00 # (none; must be 0) ubyte[1] signed one-byte integer value 1021 VALUE_SHORT = 0x02 # size - 1 (0..1) ubyte[size] signed two-byte integer value, sign-extended 1022 VALUE_CHAR = 0x03 # size - 1 (0..1) ubyte[size] unsigned two-byte integer value, zero-extended 1023 VALUE_INT = 0x04 # size - 1 (0..3) ubyte[size] signed four-byte integer value, sign-extended 1024 VALUE_LONG = 0x06 # size - 1 (0..7) ubyte[size] signed eight-byte integer value, sign-extended 1025 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 1026 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 1027 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 1028 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 1029 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 1030 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 1031 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 1032 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. 1033 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. 1034 VALUE_NULL = 0x1e # (none; must be 0) (none) null reference value 1035 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. 1036 1037
1038 -class EncodedArray :
1039 - def __init__(self, buff, cm) :
1040 self.__CM = cm 1041 self.size = readuleb128( buff ) 1042 1043 self.values = [] 1044 for i in range(0, self.size) : 1045 self.values.append( EncodedValue(buff, cm) )
1046
1047 - def show(self) :
1048 print "ENCODED_ARRAY" 1049 for i in self.values : 1050 i.show()
1051
1052 - def get_values(self) :
1053 return self.values
1054
1055 - def get_obj(self) :
1056 return [ i for i in self.values ]
1057
1058 - def get_raw(self) :
1059 return writeuleb128( self.size ) + ''.join(i.get_raw() for i in self.values)
1060
1061 -class EncodedValue :
1062 - def __init__(self, buff, cm) :
1063 self.__CM = cm 1064 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1065 1066 self.val = SV('=B', buff.read( 1 ) ) 1067 self.__value_arg = self.val.get_value() >> 5 1068 self.__value_type = self.val.get_value() & 0x1f 1069 1070 1071 self.value = "" 1072 1073 # TODO: parse floats/doubles correctly 1074 if self.__value_type >= VALUE_SHORT and self.__value_type < VALUE_STRING : 1075 self.value = self._getintvalue(buff.read( self.__value_arg + 1 )) 1076 elif self.__value_type == VALUE_STRING : 1077 id = self._getintvalue(buff.read( self.__value_arg + 1 )) 1078 self.value = cm.get_string(id) 1079 elif self.__value_type == VALUE_TYPE : 1080 id = self._getintvalue(buff.read( self.__value_arg + 1 )) 1081 self.value = cm.get_type(id) 1082 elif self.__value_type == VALUE_FIELD : 1083 id = self._getintvalue(buff.read( self.__value_arg + 1 )) 1084 self.value = cm.get_field(id) 1085 elif self.__value_type == VALUE_METHOD : 1086 id = self._getintvalue(buff.read( self.__value_arg + 1 )) 1087 self.value = cm.get_method(id) 1088 elif self.__value_type == VALUE_ENUM : 1089 id = self._getintvalue(buff.read( self.__value_arg + 1 )) 1090 self.value = cm.get_field(id) 1091 elif self.__value_type == VALUE_ARRAY : 1092 self.value = EncodedArray( buff, cm ) 1093 elif self.__value_type == VALUE_ANNOTATION : 1094 self.value = EncodedAnnotation( buff, cm ) 1095 elif self.__value_type == VALUE_BYTE : 1096 self.value = buff.read( 1 ) 1097 elif self.__value_type == VALUE_NULL : 1098 self.value = None 1099 elif self.__value_type == VALUE_BOOLEAN : 1100 if self.__value_arg: 1101 self.value = True 1102 else: 1103 self.value = False 1104 pass 1105 else : 1106 bytecode.Exit( "Unknown value 0x%x" % self.__value_type )
1107
1108 - def _getintvalue(self, buf):
1109 ret = 0 1110 shift = 0 1111 for b in buf: 1112 ret |= ord(b) << shift 1113 shift += 8 1114 1115 return ret
1116
1117 - def show(self) :
1118 print "ENCODED_VALUE", self.val, self.__value_arg, self.__value_type, repr(self.value)
1119
1120 - def get_obj(self) :
1121 if isinstance(self.value, str) == False : 1122 return [ self.value ] 1123 return []
1124
1125 - def get_raw(self) :
1126 if isinstance(self.value, str) : 1127 return self.val.get_value_buff() + self.value 1128 else : 1129 return self.val.get_value_buff() + self.value.get_raw()
1130
1131 -class AnnotationElement :
1132 - def __init__(self, buff, cm) :
1133 self.__CM = cm 1134 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1135 1136 self.name_idx = readuleb128( buff ) 1137 self.value = EncodedValue( buff, cm )
1138
1139 - def show(self) :
1140 print "ANNOTATION_ELEMENT", self.name_idx 1141 self.value.show()
1142
1143 - def get_obj(self) :
1144 return [ self.value ]
1145
1146 - def get_raw(self) :
1147 return [ bytecode.Buff(self.__offset.off, writeuleb128(self.name_idx) + self.value.get_raw()) ]
1148 1149
1150 -class EncodedAnnotation :
1151 - def __init__(self, buff, cm) :
1152 self.__CM = cm 1153 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1154 1155 self.type_idx = readuleb128( buff ) 1156 self.size = readuleb128( buff ) 1157 1158 self.elements = [] 1159 for i in range(0, self.size) : 1160 self.elements.append( AnnotationElement( buff, cm ) )
1161
1162 - def show(self) :
1163 print "ENCODED_ANNOTATION", self.type_idx, self.size 1164 for i in self.elements : 1165 i.show()
1166
1167 - def get_obj(self) :
1168 return [ i for i in self.elements ]
1169
1170 - def get_raw(self) :
1171 return [ bytecode.Buff( self.__offset.off, writeuleb128(self.type_idx) + writeuleb128(self.size) ) ] + \ 1172 [ i.get_raw() for i in self.elements ]
1173
1174 -class AnnotationItem :
1175 - def __init__(self, buff, cm) :
1176 self.__CM = cm 1177 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1178 1179 self.visibility = SV( '=B', buff.read( 1 ) ) 1180 self.annotation = EncodedAnnotation(buff, cm)
1181
1182 - def reload(self) :
1183 pass
1184
1185 - def show(self) :
1186 print "ANNOATATION_ITEM", self.visibility.get_value() 1187 self.annotation.show()
1188
1189 - def get_obj(self) :
1190 return [ self.annotation ]
1191
1192 - def get_raw(self) :
1193 return [ bytecode.Buff(self.__offset.off, self.visibility.get_value_buff()) ] + self.annotation.get_raw()
1194
1195 - def get_off(self) :
1196 return self.__offset.off
1197
1198 -class EncodedArrayItem :
1199 - def __init__(self, buff, cm) :
1200 self.__CM = cm 1201 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1202 1203 self.value = EncodedArray( buff, cm )
1204
1205 - def reload(self) :
1206 pass
1207
1208 - def show(self) :
1209 print "ENCODED_ARRAY_ITEM" 1210 self.value.show()
1211
1212 - def get_obj(self) :
1213 return [ self.value ]
1214
1215 - def get_raw(self) :
1216 return bytecode.Buff( self.__offset.off, self.value.get_raw() )
1217
1218 - def get_off(self) :
1219 return self.__offset.off
1220
1221 -class StringDataItem :
1222 - def __init__(self, buff, cm) :
1223 self.__CM = cm 1224 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1225 1226 self.utf16_size = readuleb128( buff ) 1227 self.data = buff.read( self.utf16_size + 1 ) 1228 1229 if self.data[-1] != '\x00' : 1230 i = buff.read( 1 ) 1231 self.utf16_size += 1 1232 self.data += i 1233 while i != '\x00' : 1234 i = buff.read( 1 ) 1235 self.utf16_size += 1 1236 self.data += i
1237
1238 - def reload(self) :
1239 pass
1240
1241 - def get(self) :
1242 return self.data[:-1]
1243
1244 - def show(self) :
1245 print "STRING_DATA_ITEM", "%d %s" % ( self.utf16_size, repr( self.data ) )
1246
1247 - def get_obj(self) :
1248 return []
1249
1250 - def get_raw(self) :
1251 return [ bytecode.Buff( self.__offset.off, writeuleb128( self.utf16_size ) + self.data ) ]
1252
1253 - def get_off(self) :
1254 return self.__offset.off
1255
1256 -class StringIdItem :
1257 - def __init__(self, buff, cm) :
1258 self.__CM = cm 1259 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1260 1261 self.string_data_off = SV( '=L', buff.read( 4 ) )
1262
1263 - def reload(self) :
1264 pass
1265
1266 - def get_data_off(self) :
1267 return self.string_data_off.get_value()
1268
1269 - def get_obj(self) :
1270 return []
1271
1272 - def get_raw(self) :
1273 return [ bytecode.Buff( self.__offset.off, self.string_data_off.get_value_buff() ) ]
1274
1275 - def show(self) :
1276 print "STRING_ID_ITEM", self.string_data_off.get_value()
1277
1278 - def get_off(self) :
1279 return self.__offset.off
1280
1281 -class IdItem(object) :
1282 - def __init__(self, size, buff, cm, TClass) :
1283 self.elem = [] 1284 for i in range(0, size) : 1285 self.elem.append( TClass(buff, cm) )
1286
1287 - def gets(self) :
1288 return self.elem
1289
1290 - def get(self, idx) :
1291 return self.elem[ idx ]
1292
1293 - def reload(self) :
1294 for i in self.elem : 1295 i.reload()
1296
1297 - def show(self) :
1298 nb = 0 1299 for i in self.elem : 1300 print nb, 1301 i.show() 1302 nb = nb + 1
1303
1304 - def get_obj(self) :
1305 return [ i for i in self.elem ]
1306
1307 - def get_raw(self) :
1308 return [ i.get_raw() for i in self.elem ]
1309
1310 -class TypeItem :
1311 - def __init__(self, buff, cm) :
1312 self.__CM = cm 1313 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1314 1315 self.format = SV( '=L', buff.read( 4 ) ) 1316 self._name = None
1317
1318 - def reload(self) :
1319 self._name = self.__CM.get_string( self.format.get_value() )
1320
1321 - def show(self) :
1322 print "TYPE_ITEM", self.format.get_value(), self._name
1323
1324 - def get_value(self) :
1325 return self.format.get_value()
1326
1327 - def get_obj(self) :
1328 return []
1329
1330 - def get_raw(self) :
1331 return bytecode.Buff( self.__offset.off, self.format.get_value_buff() )
1332
1333 -class TypeIdItem :
1334 - def __init__(self, size, buff, cm) :
1335 self.__CM = cm 1336 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1337 1338 self.type = [] 1339 1340 for i in range(0, size) : 1341 self.type.append( TypeItem( buff, cm ) )
1342
1343 - def reload(self) :
1344 for i in self.type : 1345 i.reload()
1346
1347 - def get(self, idx) :
1348 return self.type[ idx ].get_value()
1349
1350 - def show(self) :
1351 print "TYPE_ID_ITEM" 1352 nb = 0 1353 for i in self.type : 1354 print nb, 1355 i.show() 1356 nb = nb + 1
1357
1358 - def get_obj(self) :
1359 return [ i for i in self.type ]
1360
1361 - def get_raw(self) :
1362 return [ i.get_raw() for i in self.type ]
1363
1364 - def get_off(self) :
1365 return self.__offset.off
1366
1367 -class ProtoItem :
1368 - def __init__(self, buff, cm) :
1369 self.__CM = cm 1370 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1371 1372 self.format = SVs( PROTO_ID_ITEM[0], PROTO_ID_ITEM[1], buff.read( calcsize(PROTO_ID_ITEM[0]) ) ) 1373 self._shorty = None 1374 self._return = None 1375 self._params = None
1376
1377 - def reload(self) :
1378 self._shorty = self.__CM.get_string( self.format.get_value().shorty_idx ) 1379 self._return = self.__CM.get_type( self.format.get_value().return_type_idx ) 1380 self._params = self.__CM.get_type_list( self.format.get_value().parameters_off )
1381
1382 - def get_params(self) :
1383 return self._params
1384
1385 - def get_shorty(self) :
1386 return self._shorty
1387
1388 - def get_return_type(self) :
1389 return self._return
1390
1391 - def show(self) :
1392 print "PROTO_ITEM", self._shorty, self._return, self.format.get_value()
1393
1394 - def get_obj(self) :
1395 return []
1396
1397 - def get_raw(self) :
1398 return bytecode.Buff( self.__offset.off, self.format.get_value_buff() )
1399
1400 -class ProtoIdItem :
1401 - def __init__(self, size, buff, cm) :
1402 self.__CM = cm 1403 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1404 1405 self.proto = [] 1406 1407 for i in range(0, size) : 1408 self.proto.append( ProtoItem(buff, cm) )
1409
1410 - def get(self, idx) :
1411 return self.proto[ idx ]
1412
1413 - def reload(self) :
1414 for i in self.proto : 1415 i.reload()
1416
1417 - def show(self) :
1418 print "PROTO_ID_ITEM" 1419 nb = 0 1420 for i in self.proto : 1421 print nb, 1422 i.show() 1423 nb = nb + 1
1424
1425 - def get_obj(self) :
1426 return [ i for i in self.proto ]
1427
1428 - def get_raw(self) :
1429 return [ i.get_raw() for i in self.proto ]
1430
1431 - def get_off(self) :
1432 return self.__offset.off
1433
1434 -class FieldItem :
1435 - def __init__(self, buff, cm) :
1436 self.__CM = cm 1437 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1438 1439 self.format = SVs( FIELD_ID_ITEM[0], FIELD_ID_ITEM[1], buff.read( calcsize(FIELD_ID_ITEM[0]) ) ) 1440 self._class = None 1441 self._type = None 1442 self._name = None
1443
1444 - def reload(self) :
1445 general_format = self.format.get_value() 1446 self._class = self.__CM.get_type( general_format.class_idx ) 1447 self._type = self.__CM.get_type( general_format.type_idx ) 1448 self._name = self.__CM.get_string( general_format.name_idx )
1449
1450 - def get_class_name(self) :
1451 return self._class
1452
1453 - def get_class(self) :
1454 return self._class
1455
1456 - def get_type(self) :
1457 return self._type
1458
1459 - def get_descriptor(self) :
1460 return self._type
1461
1462 - def get_name(self) :
1463 return self._name
1464
1465 - def show(self) :
1466 print "FIELD_ITEM", self._class, self._type, self._name, self.format.get_value()
1467
1468 - def get_obj(self) :
1469 return []
1470
1471 - def get_raw(self) :
1472 return bytecode.Buff( self.__offset.off, self.format.get_value_buff() )
1473
1474 - def get_off(self) :
1475 return self.__offset.off
1476
1477 -class FieldIdItem(IdItem) :
1478 - def __init__(self, size, buff, cm) :
1479 self.__CM = cm 1480 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1481 1482 super(FieldIdItem, self).__init__(size, buff, cm, FieldItem)
1483
1484 - def get_off(self) :
1485 return self.__offset.off
1486
1487 -class MethodItem :
1488 - def __init__(self, buff, cm) :
1489 self.__CM = cm 1490 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1491 1492 self.format = SVs( METHOD_ID_ITEM[0], METHOD_ID_ITEM[1], buff.read( calcsize(METHOD_ID_ITEM[0]) ) ) 1493 self._class = None 1494 self._proto = None 1495 self._name = None
1496
1497 - def reload(self) :
1498 general_format = self.format.get_value() 1499 self._class = self.__CM.get_type( general_format.class_idx ) 1500 self._proto = self.__CM.get_proto( general_format.proto_idx ) 1501 self._name = self.__CM.get_string( general_format.name_idx )
1502
1503 - def get_type(self) :
1504 return self.format.get_value().proto_idx
1505
1506 - def show(self) :
1507 print "METHOD_ITEM", self._name, self._proto, self._class, self.format.get_value()
1508
1509 - def get_class(self) :
1510 return self._class
1511
1512 - def get_proto(self) :
1513 return self._proto
1514
1515 - def get_name(self) :
1516 return self._name
1517
1518 - def get_obj(self) :
1519 return []
1520
1521 - def get_raw(self) :
1522 return bytecode.Buff( self.__offset.off, self.format.get_value_buff() )
1523
1524 -class MethodIdItem :
1525 - def __init__(self, size, buff, cm) :
1526 self.__CM = cm 1527 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1528 1529 self.methods = [] 1530 for i in range(0, size) : 1531 self.methods.append( MethodItem(buff, cm) )
1532
1533 - def get(self, idx) :
1534 return self.methods[ idx ]
1535
1536 - def reload(self) :
1537 for i in self.methods : 1538 i.reload()
1539
1540 - def show(self) :
1541 print "METHOD_ID_ITEM" 1542 nb = 0 1543 for i in self.methods : 1544 print nb, 1545 i.show() 1546 nb = nb + 1
1547
1548 - def get_obj(self) :
1549 return [ i for i in self.methods ]
1550
1551 - def get_raw(self) :
1552 return [ i.get_raw() for i in self.methods ]
1553
1554 - def get_off(self) :
1555 return self.__offset.off
1556
1557 -class EncodedField :
1558 - def __init__(self, buff, cm) :
1559 self.__CM = cm 1560 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1561 1562 self.field_idx_diff = readuleb128( buff ) 1563 self.access_flags = readuleb128( buff ) 1564 1565 self.__field_idx = 0 1566 1567 self._name = None 1568 self._proto = None 1569 self._class_name = None
1570
1571 - def reload(self) :
1572 name = self.__CM.get_field( self.__field_idx ) 1573 self._class_name = name[0] 1574 self._name = name[2] 1575 self._proto = ''.join(i for i in name[1])
1576
1577 - def get_access(self) :
1578 return self.access_flags
1579
1580 - def get_class_name(self) :
1581 return self._class_name
1582
1583 - def get_descriptor(self) :
1584 return self._proto
1585
1586 - def get_name(self) :
1587 return self._name
1588
1589 - def adjust_idx(self, val) :
1590 self.__field_idx = self.field_idx_diff + val
1591
1592 - def get_idx(self) :
1593 return self.__field_idx
1594
1595 - def get_obj(self) :
1596 return []
1597
1598 - def get_raw(self) :
1599 return writeuleb128( self.field_idx_diff ) + writeuleb128( self.access_flags )
1600
1601 - def show(self) :
1602 print "\tENCODED_FIELD field_idx_diff=%d access_flags=%d (%s,%s,%s)" % (self.field_idx_diff, self.access_flags, self._class_name, self._proto, self._name)
1603
1604 -class EncodedMethod :
1605 - def __init__(self, buff, cm) :
1606 self.__CM = cm 1607 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1608 1609 self.method_idx_diff = readuleb128( buff ) 1610 self.access_flags = readuleb128( buff ) 1611 self.code_off = readuleb128( buff ) 1612 1613 self.__method_idx = 0 1614 1615 self._name = None 1616 self._proto = None 1617 self._class_name = None 1618 1619 self._code = None
1620
1621 - def reload(self) :
1622 v = self.__CM.get_method( self.__method_idx ) 1623 self._class_name = v[0] 1624 self._proto = ''.join(i for i in v[1]) 1625 self._name = v[2] 1626 1627 self._code = self.__CM.get_code( self.code_off )
1628
1629 - def show(self) :
1630 print "\tENCODED_METHOD method_idx_diff=%d access_flags=%d code_off=0x%x (%s %s,%s)" % (self.method_idx_diff, self.access_flags, self.code_off, self._class_name, self._proto, self._name) 1631 if self._code != None : 1632 self._code.show()
1633
1634 - def pretty_show(self, vm_a) :
1635 print "\tENCODED_METHOD method_idx_diff=%d access_flags=%d code_off=0x%x (%s %s,%s)" % (self.method_idx_diff, self.access_flags, self.code_off, self._class_name, self._proto, self._name) 1636 if self._code != None : 1637 self._code.pretty_show( vm_a.hmethods[ self ] )
1638
1639 - def get_access(self) :
1640 return self.access_flags
1641
1642 - def get_length(self) :
1643 if self._code != None : 1644 return self._code.get_length() 1645 return 0
1646
1647 - def get_code(self) :
1648 return self._code
1649
1650 - def get_descriptor(self) :
1651 return self._proto
1652
1653 - def get_class_name(self) :
1654 return self._class_name
1655
1656 - def get_name(self) :
1657 return self._name
1658
1659 - def adjust_idx(self, val) :
1660 self.__method_idx = self.method_idx_diff + val
1661
1662 - def get_idx(self) :
1663 return self.__method_idx
1664
1665 - def get_obj(self) :
1666 return []
1667
1668 - def get_raw(self) :
1669 return writeuleb128( self.method_idx_diff ) + writeuleb128( self.access_flags ) + writeuleb128( self.code_off )
1670 1671
1672 -class ClassDataItem :
1673 - def __init__(self, buff, cm) :
1674 self.__CM = cm 1675 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1676 1677 self.static_fields_size = readuleb128( buff ) 1678 self.instance_fields_size = readuleb128( buff ) 1679 self.direct_methods_size = readuleb128( buff ) 1680 self.virtual_methods_size = readuleb128( buff ) 1681 1682 self.static_fields = [] 1683 self.instance_fields = [] 1684 self.direct_methods = [] 1685 self.virtual_methods = [] 1686 1687 self.load_field( self.static_fields_size, self.static_fields, EncodedField, buff, cm ) 1688 self.load_field( self.instance_fields_size, self.instance_fields, EncodedField, buff, cm ) 1689 self.load_field( self.direct_methods_size, self.direct_methods, EncodedMethod, buff, cm ) 1690 self.load_field( self.virtual_methods_size, self.virtual_methods, EncodedMethod, buff, cm )
1691
1692 - def load_field(self, size, l, Type, buff, cm) :
1693 prev = 0 1694 for i in range(0, size) : 1695 el = Type(buff, cm) 1696 el.adjust_idx( prev ) 1697 prev = el.get_idx() 1698 1699 l.append( el )
1700
1701 - def reload(self) :
1702 for i in self.static_fields : 1703 i.reload() 1704 1705 for i in self.instance_fields : 1706 i.reload() 1707 1708 for i in self.direct_methods : 1709 i.reload() 1710 1711 for i in self.virtual_methods : 1712 i.reload()
1713
1714 - def show(self) :
1715 print "CLASS_DATA_ITEM static_fields_size=%d instance_fields_size=%d direct_methods_size=%d virtual_methods_size=%d" % \ 1716 (self.static_fields_size, self.instance_fields_size, self.direct_methods_size, self.virtual_methods_size) 1717 1718 print "SF" 1719 for i in self.static_fields : 1720 i.show() 1721 1722 print "IF" 1723 for i in self.instance_fields : 1724 i.show() 1725 1726 print "DM" 1727 for i in self.direct_methods : 1728 i.show() 1729 1730 print "VM" 1731 for i in self.virtual_methods : 1732 i.show()
1733
1734 - def pretty_show(self, vm_a) :
1735 print "CLASS_DATA_ITEM static_fields_size=%d instance_fields_size=%d direct_methods_size=%d virtual_methods_size=%d" % \ 1736 (self.static_fields_size, self.instance_fields_size, self.direct_methods_size, self.virtual_methods_size) 1737 1738 print "SF" 1739 for i in self.static_fields : 1740 i.show() 1741 1742 print "IF" 1743 for i in self.instance_fields : 1744 i.show() 1745 1746 print "DM" 1747 for i in self.direct_methods : 1748 i.pretty_show( vm_a ) 1749 1750 print "VM" 1751 for i in self.virtual_methods : 1752 i.pretty_show( vm_a )
1753
1754 - def get_methods(self) :
1755 return [ x for x in self.direct_methods ] + [ x for x in self.virtual_methods ]
1756
1757 - def get_fields(self) :
1758 return [ x for x in self.static_fields ] + [ x for x in self.instance_fields ]
1759
1760 - def get_off(self) :
1761 return self.__offset.off
1762
1763 - def get_obj(self) :
1764 return [ i for i in self.static_fields ] + \ 1765 [ i for i in self.instance_fields ] + \ 1766 [ i for i in self.direct_methods ] + \ 1767 [ i for i in self.virtual_methods ]
1768
1769 - def get_raw(self) :
1770 buff = writeuleb128( self.static_fields_size ) + \ 1771 writeuleb128( self.instance_fields_size ) + \ 1772 writeuleb128( self.direct_methods_size ) + \ 1773 writeuleb128( self.virtual_methods_size ) + \ 1774 ''.join(i.get_raw() for i in self.static_fields) + \ 1775 ''.join(i.get_raw() for i in self.instance_fields) + \ 1776 ''.join(i.get_raw() for i in self.direct_methods) + \ 1777 ''.join(i.get_raw() for i in self.virtual_methods) 1778 1779 return [ bytecode.Buff(self.__offset.off, buff) ]
1780
1781 -class ClassItem :
1782 - def __init__(self, buff, cm) :
1783 self.__CM = cm 1784 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1785 1786 self.format = SVs( CLASS_DEF_ITEM[0], CLASS_DEF_ITEM[1], buff.read( calcsize(CLASS_DEF_ITEM[0]) ) ) 1787 self._interfaces = None 1788 self._class_data_item = None 1789 self._static_values = None 1790 1791 self._name = None 1792 self._sname = None
1793
1794 - def reload(self) :
1795 general_format = self.format.get_value() 1796 self._name = self.__CM.get_type( general_format.class_idx ) 1797 self._sname = self.__CM.get_type( general_format.superclass_idx ) 1798 1799 if general_format.interfaces_off != 0 : 1800 self._interfaces = self.__CM.get_type_list( general_format.interfaces_off ) 1801 1802 if general_format.class_data_off != 0 : 1803 self._class_data_item = self.__CM.get_class_data_item( general_format.class_data_off ) 1804 self._class_data_item.reload() 1805 1806 if general_format.static_values_off != 0 : 1807 self._static_values = self.__CM.get_encoded_array_item ( general_format.static_values_off )
1808
1809 - def show(self) :
1810 print "CLASS_ITEM", self._name, self._sname, self._interfaces, self.format.get_value()
1811
1812 - def get_name(self) :
1813 return self._name
1814
1815 - def get_info(self) :
1816 return "%s:%s" % (self._name, self._sname)
1817
1818 - def get_methods(self) :
1819 if self._class_data_item != None : 1820 return self._class_data_item.get_methods() 1821 return []
1822
1823 - def get_fields(self) :
1824 if self._class_data_item != None : 1825 return self._class_data_item.get_fields() 1826 return []
1827
1828 - def get_obj(self) :
1829 return []
1830
1831 - def get_raw(self) :
1832 return [ bytecode.Buff( self.__offset.off, self.format.get_value_buff() ) ]
1833
1834 -class ClassDefItem :
1835 - def __init__(self, size, buff, cm) :
1836 self.__CM = cm 1837 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 1838 1839 self.class_def = [] 1840 1841 for i in range(0, size) : 1842 idx = buff.get_idx() 1843 1844 class_def = ClassItem( buff, cm ) 1845 self.class_def.append( class_def ) 1846 1847 buff.set_idx( idx + calcsize(CLASS_DEF_ITEM[0]) )
1848
1849 - def get_method(self, name_class, name_method) :
1850 l = [] 1851 1852 for i in self.class_def : 1853 if i.get_name() == name_class : 1854 for j in i.get_methods() : 1855 if j.get_name() == name_method : 1856 l.append(j) 1857 1858 return l
1859
1860 - def get_names(self) :
1861 return [ x.get_name() for x in self.class_def ]
1862
1863 - def reload(self) :
1864 for i in self.class_def : 1865 i.reload()
1866
1867 - def show(self) :
1868 print "CLASS_DEF_ITEM" 1869 nb = 0 1870 for i in self.class_def : 1871 print nb, 1872 i.show() 1873 nb = nb + 1
1874
1875 - def get_obj(self) :
1876 return [ i for i in self.class_def ]
1877
1878 - def get_raw(self) :
1879 return [ i.get_raw() for i in self.class_def ]
1880
1881 - def get_off(self) :
1882 return self.__offset.off
1883
1884 -class EncodedTypeAddrPair :
1885 - def __init__(self, buff) :
1886 self.type_idx = readuleb128( buff ) 1887 self.addr = readuleb128( buff )
1888
1889 - def get_obj(self) :
1890 return []
1891
1892 - def show(self) :
1893 print "ENCODED_TYPE_ADDR_PAIR", self.type_idx, self.addr
1894
1895 - def get_raw(self) :
1896 return writeuleb128( self.type_idx ) + writeuleb128( self.addr )
1897
1898 -class EncodedCatchHandler :
1899 - def __init__(self, buff) :
1900 self.size = readsleb128( buff ) 1901 1902 self.handlers = [] 1903 1904 for i in range(0, abs(self.size)) : 1905 self.handlers.append( EncodedTypeAddrPair(buff) ) 1906 1907 if self.size <= 0 : 1908 self.catch_all_addr = readuleb128( buff )
1909
1910 - def show(self) :
1911 print "ENCODED_CATCH_HANDLER size=0x%x" % self.size 1912 for i in self.handlers : 1913 i.show()
1914
1915 - def get_obj(self) :
1916 return [ i for i in self.handlers ]
1917
1918 - def get_raw(self) :
1919 buff = writesleb128( self.size ) + ''.join(i.get_raw() for i in self.handlers) 1920 1921 if self.size <= 0 : 1922 buff += writeuleb128( self.catch_all_addr ) 1923 1924 return buff
1925
1926 -class EncodedCatchHandlerList :
1927 - def __init__(self, buff) :
1928 self.size = readuleb128( buff ) 1929 self.list = [] 1930 1931 for i in range(0, self.size) : 1932 self.list.append( EncodedCatchHandler(buff) )
1933
1934 - def show(self) :
1935 print "ENCODED_CATCH_HANDLER_LIST size=0x%x" % self.size 1936 for i in self.list : 1937 i.show()
1938
1939 - def get_obj(self) :
1940 return [ i for i in self.list ]
1941
1942 - def get_raw(self) :
1943 return writeuleb128( self.size ) + ''.join(i.get_raw() for i in self.list)
1944
1945 -class DBCSpe :
1946 - def __init__(self, cm, op) :
1947 self.__CM = cm 1948 self.type_ins_tag = SPECIFIC_DVM_INS 1949 self.op = op 1950 self.op_name = self.op.get_name()
1951
1952 - def _reload(self) :
1953 pass
1954
1955 - def get_data(self) :
1956 return self.op.get_data()
1957
1958 - def get_raw(self) :
1959 return self.op.get_raw()
1960
1961 - def get_name(self) :
1962 return self.op.get_name()
1963
1964 - def get_targets(self) :
1965 return self.op.get_targets()
1966
1967 - def get_formatted_operands(self) :
1968 return []
1969
1970 - def get_operands(self) :
1971 return self.op.get_operands()
1972
1973 - def get_length(self) :
1974 return self.op.get_length()
1975
1976 - def show_buff(self, pos) :
1977 return self.op.show_buff( pos )
1978
1979 - def show(self, pos) :
1980 print self.op.show_buff( pos ),
1981
1982 -class DBC :
1983 - def __init__(self, class_manager, op_name, op_value, operands, raw_buff) :
1984 self.__CM = class_manager 1985 self.type_ins_tag = NORMAL_DVM_INS 1986 1987 self.op_name = op_name 1988 self.operands = operands 1989 self.formatted_operands = [] 1990 self.relative_operands = [] 1991 1992 self.raw_buff = raw_buff 1993 1994 self.op_value = op_value
1995
1996 - def _reload(self) :
1997 v = [] 1998 r = [] 1999 l = [] 2000 2001 for i in self.operands[1:] : 2002 if i[0] == "v" : 2003 v.append( i ) 2004 else : 2005 r.append( i ) 2006 2007 # 0x12 : [ "11n", "const/4", "vA, #+B", "B|A|op" ], 2008 if self.op_value == 0x12 : 2009 self.formatted_operands.append( ("#l", r[0][1]) ) 2010 2011 # 0x13 : [ "21s", "const/16", "vAA, #+BBBB", "AA|op BBBB" ], 2012 elif self.op_value == 0x13 : 2013 self.formatted_operands.append( ("#l", r[0][1]) ) 2014 2015 # 0x14 : [ "31i", "const", "vAA, #+BBBBBBBB", "AA|op BBBB BBBB" ], 2016 # const instruction, convert value into float 2017 elif self.op_value == 0x14 : 2018 x = (0xFFFF & r[0][1]) | ((0xFFFF & r[1][1] ) << 16) 2019 self.formatted_operands.append( ("#f", unpack("=f", pack("=L", x))[0] ) ) 2020 2021 # 0x15 : [ "21h", "const/high16", "vAA, #+BBBB0000", "AA|op BBBB0000" ], 2022 elif self.op_value == 0x15 : 2023 self.formatted_operands.append( ("#f", unpack( '=f', pack('=i', r[0][1]))[0] ) ) 2024 2025 # 0x16 : [ "21s", "const-wide/16", "vAA, #+BBBB", "AA|op BBBB" ], 2026 elif self.op_value == 0x16 : 2027 self.formatted_operands.append( ("#l", r[0][1]) ) 2028 2029 # 0x17 : [ "31i", "const-wide/32", "vAA, #+BBBBBBBB", "AA|op BBBB BBBB" ], 2030 elif self.op_value == 0x17 : 2031 x = ((0xFFFF & r[1][1]) << 16) | (0xFFFF & r[0][1]) 2032 self.formatted_operands.append( ("#l", unpack( '=d', pack('=d', x))[0] ) ) 2033 2034 # 0x18 : [ "51l", "const-wide", "vAA, #+BBBBBBBBBBBBBBBB", "AA|op BBBB BBBB BBBB BBBB" ], 2035 # convert value to double 2036 elif self.op_value == 0x18 : 2037 x = (0xFFFF & r[0][1]) | ((0xFFFF & r[1][1]) << 16) | ((0xFFFF & r[2][1]) << 32) | ((0xFFFF & r[3][1]) << 48) 2038 self.formatted_operands.append( ("#d", unpack( '=d', pack('=Q', x ) )[0]) ) 2039 2040 # 0x19 : [ "21h", "const-wide/high16", "vAA, #+BBBB000000000000", "AA|op BBBB000000000000" ], 2041 # convert value to double 2042 elif self.op_value == 0x19 : 2043 self.formatted_operands.append( ("#d", unpack( '=d', pack('=q', r[0][1]))[0]) ) 2044 2045 # 0x26 fill-array-data 2046 elif self.op_value == 0x26 : 2047 self.relative_operands.append( r[0][1] * 2 ) 2048 2049 elif self.op_value == 0x2b or self.op_value == 0x2c : 2050 self.relative_operands.append( r[0][1] * 2 ) 2051 2052 l.extend( [ self._more_info(n[0], n[1]) for n in v ] ) 2053 l.extend( [ self._more_info(n[0], n[1]) for n in r ] ) 2054 2055 self.operands = l
2056
2057 - def get_length(self) :
2058 """Return the length of the instruction""" 2059 return len(self.raw_buff)
2060
2061 - def get_name(self) :
2062 """Return the name of the bytecode""" 2063 return self.op_name
2064
2065 - def get_formatted_operands(self) :
2066 """Return the formatted operands""" 2067 return self.formatted_operands
2068
2069 - def get_operands(self) :
2070 """Return the operands""" 2071 return self.operands
2072
2073 - def get_raw(self) :
2074 """Return the raw buffer""" 2075 return self.raw_buff
2076
2077 - def show(self, pos) :
2078 """Display the instruction""" 2079 print self.show_buff(pos),
2080
2081 - def show_buff(self, pos) :
2082 """Return the instruction in a buffer""" 2083 buff = self.op_name + " " 2084 2085 l = [] 2086 for i in self.operands : 2087 if i[0] != "v" : 2088 l.append( "[" + ' '.join( str(j) for j in i ) + "]" ) 2089 else : 2090 l.append( ''.join( str(j) for j in i ) ) 2091 l.append( "," ) 2092 2093 if self.formatted_operands != [] : 2094 for i in self.formatted_operands : 2095 l.append( "{" + str(i[1]) + "}" ) 2096 l.append(",") 2097 2098 if self.relative_operands != [] : 2099 for i in self.relative_operands : 2100 l.append("{" + "0x%x" % (i + pos) + "}") 2101 l.append(",") 2102 2103 if l != [] : 2104 l.pop(-1) 2105 buff += ' '.join( i for i in l ) 2106 2107 return buff
2108
2109 - def _more_info(self, c, v) :
2110 if "string@" == c : 2111 return [ c, v, self.__CM.get_string(v) ] 2112 elif "meth@" == c : 2113 m = self.__CM.get_method(v) 2114 return [ c, v, m[0], m[1][0], m[1][1], m[2] ] 2115 elif "field@" == c : 2116 f = self.__CM.get_field(v) 2117 return [ c, v, f[0], f[1], f[2] ] 2118 elif "type@" == c : 2119 return [ c, v, self.__CM.get_type(v) ] 2120 return [ c, v ]
2121
2122 -class DCode :
2123 - def __init__(self, class_manager, size, buff) :
2124 self.__CM = class_manager 2125 self.__insn = buff 2126 2127 self.__h_special_bytecodes = {} 2128 self.__bytecodes = [] 2129 2130 self.__map_extract_values = { 2131 OPCODE_B_A_OP : self.op_B_A_OP, 2132 OPCODE_AA_OP : self.op_AA_OP, 2133 OPCODE_00_OP : self.op_00_OP, 2134 OPCODE_CCCC : self.op_CCCC, 2135 OPCODE_SAAAA : self.op_SAAAA, 2136 OPCODE_SB_A_OP : self.op_SB_A_OP, 2137 OPCODE_SCC_BB : self.op_SCC_BB, 2138 OPCODE_G_F_E_D : self.op_G_F_E_D, 2139 OPCODE_OP : self.op_OP, 2140 OPCODE_SCC : self.op_SCC, 2141 OPCODE_SAAAAAAAA : self.op_SAAAAAAAA, 2142 OPCODE_BBBBBBBB : self.op_BBBBBBBB, 2143 OPCODE_00 : self.op_00, 2144 } 2145 2146 self.__current_pos = 0 2147 2148 ushort = calcsize( '<H' ) 2149 2150 #print "HERE", len(self.__insn), repr(self.__insn), size * ushort 2151 2152 real_j = 0 2153 j = 0 2154 while j < (size * ushort) : 2155 #print "BYTES", self.__all_bytes 2156 # handle special instructions 2157 if real_j in self.__h_special_bytecodes : 2158 # print "REAL_J === ", real_j 2159 special_e = self.__h_special_bytecodes[ real_j ]( self.__insn[j : ] ) 2160 2161 self.__bytecodes.append( DBCSpe( self.__CM, special_e ) ) 2162 2163 del self.__h_special_bytecodes[ real_j ] 2164 2165 self.__current_pos += special_e.get_length() 2166 j = self.__current_pos 2167 else : 2168 2169 op_value = unpack( '=B', self.__insn[j] )[0] 2170 2171 if op_value in DALVIK_OPCODES : 2172 operands, special = self._analyze_mnemonic( op_value, DALVIK_OPCODES[ op_value ]) 2173 2174 if special != None : 2175 self.__h_special_bytecodes[ special[0] + real_j ] = special[1] 2176 2177 self.__bytecodes.append( DBC( self.__CM, DALVIK_OPCODES[ op_value ][1], op_value, operands, self.__insn[ j : self.__current_pos ] ) ) 2178 2179 #print "J === ", j, self.__current_pos 2180 j = self.__current_pos 2181 else : 2182 bytecode.Exit( "invalid opcode [ 0x%x ]" % op_value ) 2183 real_j = j / 2
2184
2185 - def _extract_values(self, i) :
2186 return self.__map_extract_values[ i ]()
2187
2188 - def op_B_A_OP(self) :
2189 i16 = unpack("=H", self.__insn[self.__current_pos:self.__current_pos+2])[0] 2190 return [2, map(int, [i16 & 0xff, (i16 >> 8) & 0xf, (i16 >> 12) & 0xf])]
2191
2192 - def op_AA_OP(self) :
2193 i16 = unpack("=H", self.__insn[self.__current_pos:self.__current_pos+2])[0] 2194 return [2, map(int, [i16 & 0xff, (i16 >> 8) & 0xff])]
2195
2196 - def op_00_OP(self) :
2197 i16 = unpack("=H", self.__insn[self.__current_pos:self.__current_pos+2])[0] 2198 return [2, map(int, [i16 & 0xff])]
2199
2200 - def op_CCCC(self) :
2201 i16 = unpack("=H", self.__insn[self.__current_pos:self.__current_pos+2])[0] 2202 return [2, [i16]]
2203
2204 - def op_SAAAA(self) :
2205 i16 = unpack("=h", self.__insn[self.__current_pos:self.__current_pos+2])[0] 2206 return [2, [i16]]
2207
2208 - def op_SB_A_OP(self) :
2209 i16 = unpack("=h", self.__insn[self.__current_pos:self.__current_pos+2])[0] 2210 return [2, map(int, [i16 & 0xff, (i16 >> 8) & 0xf, (i16 >> 12) & 0xf])]
2211
2212 - def op_SCC_BB(self) :
2213 i16 = unpack("=h", self.__insn[self.__current_pos:self.__current_pos+2])[0] 2214 return [2, map(int, [i16 & 0xff, (i16 >> 8) & 0xff])]
2215
2216 - def op_G_F_E_D(self) :
2217 i16 = unpack("=H", self.__insn[self.__current_pos:self.__current_pos+2])[0] 2218 return [2, map(int, [i16 & 0xf, (i16 >> 4) & 0xf, (i16 >> 8) & 0xf, (i16 >> 12) & 0xf])]
2219
2220 - def op_OP(self) :
2221 i8 = unpack("=B", self.__insn[self.__current_pos:self.__current_pos+1])[0] 2222 return [1, [i8]]
2223
2224 - def op_SCC(self) :
2225 i8 = unpack("=b", self.__insn[self.__current_pos:self.__current_pos+1])[0] 2226 return [1, [i8]]
2227
2228 - def op_SAAAAAAAA(self) :
2229 i32 = unpack("=i", self.__insn[self.__current_pos:self.__current_pos+4])[0] 2230 return [4, [i32]]
2231
2232 - def op_BBBBBBBB(self) :
2233 i32 = unpack("=I", self.__insn[self.__current_pos:self.__current_pos+4])[0] 2234 return [4, [i32]]
2235
2236 - def op_00(self) :
2237 return [1, []]
2238
2239 - def _analyze_mnemonic(self, op_value, mnemonic) :
2240 # print op_value, mnemonic, self.__current_pos 2241 special = False 2242 if len(mnemonic) == 6 : 2243 special = True 2244 2245 operands = [] 2246 for i in mnemonic[3] : 2247 r = self._extract_values(i) 2248 # print "R", r 2249 2250 self.__current_pos += r[0] 2251 operands.extend( r[1] ) 2252 # print operands 2253 2254 operands[0] = [ "OP", operands[0] ] 2255 for i in range(1, len(operands)) : 2256 if i in mnemonic[4] : 2257 operands[i] = [ mnemonic[4][i], operands[i] ] 2258 else : 2259 operands[i] = [ 'v', operands[i] ] 2260 2261 # SPECIFIC OPCODES 2262 if op_value >= 0x6e and op_value <= 0x72 : 2263 if operands[2][1] == 5 : 2264 operands = [operands[ 0 ]] + operands[ 4 : 4 + operands[ 2 ][1] ] + [operands[ 1 ]] + [operands[ 3 ]] 2265 else : 2266 operands = [operands[ 0 ]] + operands[ 4 : 4 + operands[ 2 ][1] ] + [operands[ 3 ]] 2267 2268 elif (op_value >= 0x74 and op_value <= 0x78) or op_value == 0x25 : 2269 NNNN = operands[3][1] + operands[1][1] + 1 2270 2271 for i in range(operands[3][1] + 1, NNNN - 1) : 2272 operands.append( ["v", i ] ) 2273 2274 operands.append( operands.pop(2) ) 2275 operands.pop(1) 2276 2277 if special : 2278 return operands, (operands[2][1], mnemonic[-1]) 2279 return operands, None
2280
2281 - def get(self) :
2282 return self.__bytecodes
2283
2284 - def get_raw(self) :
2285 return self.__insn
2286
2287 - def get_ins_off(self, off) :
2288 idx = 0 2289 2290 for i in self.__bytecodes : 2291 if idx == off : 2292 return i 2293 idx += i.get_length() 2294 2295 return None
2296
2297 - def reload(self) :
2298 for i in self.__bytecodes : 2299 i._reload()
2300
2301 - def show(self) :
2302 nb = 0 2303 idx = 0 2304 for i in self.__bytecodes : 2305 print nb, "0x%x" % idx, 2306 i.show(nb) 2307 print 2308 2309 idx += i.get_length() 2310 nb += 1
2311
2312 - def pretty_show(self, m_a) :
2313 bytecode.PrettyShow( m_a.basic_blocks.gets() )
2314
2315 -class DalvikCode :
2316 - def __init__(self, buff, cm) :
2317 self.__CM = cm 2318 2319 off = buff.get_idx() 2320 while off % 4 != 0 : 2321 off += 1 2322 2323 buff.set_idx( off ) 2324 2325 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 2326 2327 self.__off = buff.get_idx() 2328 2329 self.registers_size = SV( '=H', buff.read( 2 ) ) 2330 self.ins_size = SV( '=H', buff.read( 2 ) ) 2331 self.outs_size = SV( '=H', buff.read( 2 ) ) 2332 self.tries_size = SV( '=H', buff.read( 2 ) ) 2333 self.debug_info_off = SV( '=L', buff.read( 4 ) ) 2334 self.insns_size = SV( '=L', buff.read( 4 ) ) 2335 2336 ushort = calcsize( '=H' ) 2337 2338 self._code = DCode( self.__CM, self.insns_size.get_value(), buff.read( self.insns_size.get_value() * ushort ) ) 2339 2340 if (self.insns_size.get_value() % 2 == 1) : 2341 self.__padding = SV( '=H', buff.read( 2 ) ) 2342 2343 self.tries = [] 2344 self.handlers = [] 2345 if self.tries_size.get_value() > 0 : 2346 for i in range(0, self.tries_size.get_value()) : 2347 try_item = SVs( TRY_ITEM[0], TRY_ITEM[1], buff.read( calcsize(TRY_ITEM[0]) ) ) 2348 self.tries.append( try_item ) 2349 2350 self.handlers.append( EncodedCatchHandlerList( buff ) )
2351
2352 - def reload(self) :
2353 self._code.reload()
2354
2355 - def get_length(self) :
2356 return self.insns_size.get_value()
2357
2358 - def get_bc(self) :
2359 return self._code
2360
2361 - def get_off(self) :
2362 return self.__off
2363
2364 - def _begin_show(self) :
2365 print "*" * 80 2366 print "DALVIK_CODE :" 2367 bytecode._Print("\tREGISTERS_SIZE", self.registers_size) 2368 bytecode._Print("\tINS_SIZE", self.ins_size) 2369 bytecode._Print("\tOUTS_SIZE", self.outs_size) 2370 bytecode._Print("\tTRIES_SIZE", self.tries_size) 2371 bytecode._Print("\tDEBUG_INFO_OFF", self.debug_info_off) 2372 bytecode._Print("\tINSNS_SIZE", self.insns_size) 2373 2374 for i in self.handlers : 2375 i.show() 2376 2377 print ""
2378
2379 - def show(self) :
2380 self._begin_show() 2381 self._code.show() 2382 self._end_show()
2383
2384 - def _end_show(self) :
2385 print "*" * 80
2386
2387 - def pretty_show(self, vm_a) :
2388 self._begin_show() 2389 self._code.pretty_show(vm_a) 2390 self._end_show()
2391
2392 - def get_obj(self) :
2393 return [ i for i in self.__handlers ]
2394
2395 - def get_raw(self) :
2396 buff = self.registers_size.get_value_buff() + \ 2397 self.ins_size.get_value_buff() + \ 2398 self.outs_size.get_value_buff() + \ 2399 self.tries_size.get_value_buff() + \ 2400 self.debug_info_off.get_value_buff() + \ 2401 self.insns_size.get_value_buff() + \ 2402 self._code.get_raw() 2403 2404 if (self.insns_size.get_value() % 2 == 1) : 2405 buff += self.__padding.get_value_buff() 2406 2407 if self.tries_size.get_value() > 0 : 2408 buff += ''.join(i.get_value_buff() for i in self.tries) 2409 for i in self.handlers : 2410 buff += i.get_raw() 2411 2412 return bytecode.Buff( self.__offset.off, 2413 buff )
2414
2415 -class CodeItem :
2416 - def __init__(self, size, buff, cm) :
2417 self.__CM = cm 2418 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 2419 2420 self.code = [] 2421 self.__code_off = {} 2422 2423 for i in range(0, size) : 2424 x = DalvikCode( buff, cm ) 2425 self.code.append( x ) 2426 self.__code_off[ x.get_off() ] = x
2427
2428 - def get_code(self, off) :
2429 try : 2430 return self.__code_off[off] 2431 except KeyError : 2432 return None
2433
2434 - def reload(self) :
2435 for i in self.code : 2436 i.reload()
2437
2438 - def show(self) :
2439 print "CODE_ITEM" 2440 for i in self.code : 2441 i.show()
2442
2443 - def get_obj(self) :
2444 return [ i for i in self.code ]
2445
2446 - def get_raw(self) :
2447 return [ i.get_raw() for i in self.code ]
2448
2449 - def get_off(self) :
2450 return self.__offset.off
2451
2452 -class MapItem :
2453 - def __init__(self, buff, cm) :
2454 self.__CM = cm 2455 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 2456 2457 self.format = SVs( MAP_ITEM[0], MAP_ITEM[1], buff.read( calcsize( MAP_ITEM[0] ) ) ) 2458 2459 self.item = None 2460 2461 general_format = self.format.get_value() 2462 buff.set_idx( general_format.offset ) 2463 2464 # print TYPE_MAP_ITEM[ general_format.type ], "@ 0x%x(%d) %d" % (buff.get_idx(), buff.get_idx(), general_format.size) 2465 2466 if TYPE_MAP_ITEM[ general_format.type ] == "TYPE_STRING_ID_ITEM" : 2467 self.item = [ StringIdItem( buff, cm ) for i in range(0, general_format.size) ] 2468 2469 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_CODE_ITEM" : 2470 self.item = CodeItem( general_format.size, buff, cm ) 2471 2472 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_TYPE_ID_ITEM" : 2473 self.item = TypeIdItem( general_format.size, buff, cm ) 2474 2475 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_PROTO_ID_ITEM" : 2476 self.item = ProtoIdItem( general_format.size, buff, cm ) 2477 2478 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_FIELD_ID_ITEM" : 2479 self.item = FieldIdItem( general_format.size, buff, cm ) 2480 2481 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_METHOD_ID_ITEM" : 2482 self.item = MethodIdItem( general_format.size, buff, cm ) 2483 2484 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_CLASS_DEF_ITEM" : 2485 self.item = ClassDefItem( general_format.size, buff, cm ) 2486 2487 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_HEADER_ITEM" : 2488 self.item = HeaderItem( general_format.size, buff, cm ) 2489 2490 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_ANNOTATION_ITEM" : 2491 self.item = [ AnnotationItem( buff, cm ) for i in range(0, general_format.size) ] 2492 2493 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_ANNOTATION_SET_ITEM" : 2494 self.item = [ AnnotationSetItem( buff, cm ) for i in range(0, general_format.size) ] 2495 2496 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_ANNOTATIONS_DIRECTORY_ITEM" : 2497 self.item = [ AnnotationsDirectoryItem( buff, cm ) for i in range(0, general_format.size) ] 2498 2499 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_ANNOTATION_SET_REF_LIST" : 2500 self.item = [ AnnotationSetRefList( buff, cm ) for i in range(0, general_format.size) ] 2501 2502 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_TYPE_LIST" : 2503 self.item = [ TypeList( buff, cm ) for i in range(0, general_format.size) ] 2504 2505 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_STRING_DATA_ITEM" : 2506 self.item = [ StringDataItem( buff, cm ) for i in range(0, general_format.size) ] 2507 2508 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_DEBUG_INFO_ITEM" : 2509 # FIXME : strange bug with sleb128 .... 2510 # self.item = [ DebugInfoItem( buff, cm ) for i in range(0, general_format.size) ] 2511 self.item = DebugInfoItem2( buff, cm ) 2512 2513 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_ENCODED_ARRAY_ITEM" : 2514 self.item = [ EncodedArrayItem( buff, cm ) for i in range(0, general_format.size) ] 2515 2516 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_CLASS_DATA_ITEM" : 2517 self.item = [ ClassDataItem(buff, cm) for i in range(0, general_format.size) ] 2518 2519 elif TYPE_MAP_ITEM[ general_format.type ] == "TYPE_MAP_LIST" : 2520 pass # It's me I think !!! 2521 2522 else : 2523 bytecode.Exit( "Map item %d @ 0x%x(%d) is unknown" % (general_format.type, buff.get_idx(), buff.get_idx()) )
2524
2525 - def reload(self) :
2526 if self.item != None : 2527 if isinstance( self.item, list ): 2528 for i in self.item : 2529 i.reload() 2530 else : 2531 self.item.reload()
2532
2533 - def show(self) :
2534 bytecode._Print( "MAP_ITEM", self.format ) 2535 bytecode._Print( "\tTYPE_ITEM", TYPE_MAP_ITEM[ self.format.get_value().type ]) 2536 2537 if self.item != None : 2538 if isinstance( self.item, list ): 2539 for i in self.item : 2540 i.show() 2541 else : 2542 if isinstance(self.item, CodeItem) == False : 2543 self.item.show()
2544
2545 - def pretty_show(self, vm_a) :
2546 bytecode._Print( "MAP_ITEM", self.format ) 2547 bytecode._Print( "\tTYPE_ITEM", TYPE_MAP_ITEM[ self.format.get_value().type ]) 2548 2549 if self.item != None : 2550 if isinstance( self.item, list ): 2551 for i in self.item : 2552 if isinstance(i, ClassDataItem) : 2553 i.pretty_show(vm_a) 2554 elif isinstance(self.item, CodeItem) == False : 2555 i.show() 2556 else : 2557 if isinstance(self.item, ClassDataItem) : 2558 self.item.pretty_show(vm_a) 2559 elif isinstance(self.item, CodeItem) == False : 2560 self.item.show()
2561
2562 - def get_obj(self) :
2563 if self.item == None : 2564 return [] 2565 2566 if isinstance( self.item, list ) : 2567 return [ i for i in self.item ] 2568 2569 return [ self.item ]
2570
2571 - def get_raw(self) :
2572 if self.item == None : 2573 return [ bytecode.Buff( self.__offset.off, self.format.get_value_buff() ) ] 2574 else : 2575 if isinstance( self.item, list ) : 2576 return [ bytecode.Buff( self.__offset.off, self.format.get_value_buff() ) ] + [ i.get_raw() for i in self.item ] 2577 else : 2578 return [ bytecode.Buff( self.__offset.off, self.format.get_value_buff() ) ] + self.item.get_raw()
2579
2580 - def get_length(self) :
2581 return calcsize( MAP_ITEM[0] )
2582
2583 - def get_type(self) :
2584 return self.format.get_value().type
2585
2586 - def get_item(self) :
2587 return self.item
2588
2589 -class OffObj :
2590 - def __init__(self, o) :
2591 self.off = o
2592
2593 -class ClassManager :
2594 - def __init__(self) :
2595 self.__manage_item = {} 2596 self.__manage_item_off = [] 2597 self.__offsets = {} 2598 2599 self.__strings_off = {} 2600 2601 self.__cached_type_list = {} 2602 self.__cached_proto = {}
2603
2604 - def add_offset(self, off, obj) :
2605 x = OffObj( off ) 2606 self.__offsets[ obj ] = x 2607 return x
2608
2609 - def add_type_item(self, type_item, item) :
2610 self.__manage_item[ type_item ] = item 2611 2612 sdi = False 2613 if type_item == "TYPE_STRING_DATA_ITEM" : 2614 sdi = True 2615 2616 if item != None : 2617 if isinstance(item, list) : 2618 for i in item : 2619 goff = i.get_off() 2620 self.__manage_item_off.append( goff ) 2621 if sdi == True : 2622 self.__strings_off[ goff ] = i 2623 else : 2624 self.__manage_item_off.append( item.get_off() )
2625
2626 - def get_code(self, idx) :
2627 return self.__manage_item[ "TYPE_CODE_ITEM" ].get_code( idx )
2628
2629 - def get_class_data_item(self, off) :
2630 for i in self.__manage_item[ "TYPE_CLASS_DATA_ITEM" ] : 2631 if i.get_off() == off : 2632 return i 2633 2634 bytecode.Exit( "unknown class data item @ 0x%x" % off )
2635
2636 - def get_encoded_array_item(self, off) :
2637 for i in self.__manage_item["TYPE_ENCODED_ARRAY_ITEM" ] : 2638 if i.get_off() == off : 2639 return i
2640
2641 - def get_string(self, idx) :
2642 off = self.__manage_item[ "TYPE_STRING_ID_ITEM" ][idx].get_data_off() 2643 try : 2644 return self.__strings_off[off].get() 2645 except KeyError : 2646 bytecode.Exit( "unknown string item @ 0x%x(%d)" % (off,idx) )
2647
2648 - def get_type_list(self, off) :
2649 if off == 0 : 2650 return "()" 2651 2652 if off in self.__cached_type_list : 2653 return self.__cached_type_list[ off ] 2654 2655 for i in self.__manage_item[ "TYPE_TYPE_LIST" ] : 2656 if i.get_type_list_off() == off : 2657 ret = "(" + i.get_string() + ")" 2658 self.__cached_type_list[ off ] = ret 2659 return ret 2660 2661 return None
2662
2663 - def get_type(self, idx) :
2664 type = self.__manage_item[ "TYPE_TYPE_ID_ITEM" ].get( idx ) 2665 return self.get_string( type )
2666
2667 - def get_proto(self, idx) :
2668 #proto = self.__manage_item[ "TYPE_PROTO_ID_ITEM" ].get( idx ) 2669 #return [ proto.get_params(), proto.get_return_type() ] 2670 2671 try : 2672 proto = self.__cached_proto[ idx ] 2673 except KeyError : 2674 proto = self.__manage_item[ "TYPE_PROTO_ID_ITEM" ].get( idx ) 2675 self.__cached_proto[ idx ] = proto 2676 2677 return [ proto.get_params(), proto.get_return_type() ]
2678
2679 - def get_field(self, idx, ref=False) :
2680 field = self.__manage_item[ "TYPE_FIELD_ID_ITEM"].get( idx ) 2681 2682 if ref == True : 2683 return field 2684 2685 return [ field.get_class(), field.get_type(), field.get_name() ]
2686
2687 - def get_method(self, idx) :
2688 method = self.__manage_item[ "TYPE_METHOD_ID_ITEM" ].get( idx ) 2689 return [ method.get_class(), method.get_proto(), method.get_name() ]
2690
2691 - def get_next_offset_item(self, idx) :
2692 for i in self.__manage_item_off : 2693 if i > idx : 2694 return i 2695 return idx
2696
2697 -class MapList :
2698 - def __init__(self, off, buff) :
2699 self.__CM = ClassManager() 2700 buff.set_idx( off ) 2701 2702 self.__offset = self.__CM.add_offset( buff.get_idx(), self ) 2703 2704 self.size = SV( '=L', buff.read( 4 ) ) 2705 2706 self.map_item = [] 2707 for i in range(0, self.size) : 2708 idx = buff.get_idx() 2709 2710 mi = MapItem( buff, self.__CM ) 2711 self.map_item.append( mi ) 2712 2713 buff.set_idx( idx + mi.get_length() ) 2714 2715 self.__CM.add_type_item( TYPE_MAP_ITEM[ mi.get_type() ], mi.get_item() ) 2716 2717 for i in self.map_item : 2718 i.reload()
2719
2720 - def get_item_type(self, ttype) :
2721 for i in self.map_item : 2722 if TYPE_MAP_ITEM[ i.get_type() ] == ttype : 2723 return i.get_item()
2724
2725 - def show(self) :
2726 bytecode._Print("MAP_LIST SIZE", self.size.get_value()) 2727 for i in self.map_item : 2728 i.show()
2729
2730 - def pretty_show(self, vm_a) :
2731 bytecode._Print("MAP_LIST SIZE", self.size.get_value()) 2732 for i in self.map_item : 2733 i.pretty_show(vm_a)
2734
2735 - def get_obj(self) :
2736 return [ x for x in self.map_item ]
2737
2738 - def get_raw(self) :
2739 return [ bytecode.Buff( self.__offset.off, self.size.get_value_buff()) ] + \ 2740 [ x.get_raw() for x in self.map_item ]
2741
2742 - def get_class_manager(self) :
2743 return self.__CM
2744
2745 -class Data :
2746 - def __init__(self, buff) :
2747 pass
2748
2749 -class DalvikVMFormat(bytecode._Bytecode) :
2750 - def __init__(self, buff) :
2751 super(DalvikVMFormat, self).__init__( buff ) 2752 2753 self.load_class()
2754
2755 - def load_class(self) :
2756 self.__header = HeaderItem( 0, self, ClassManager() ) 2757 2758 self.map_list = MapList( self.__header.get_value().map_off, self ) 2759 2760 self.classes = self.map_list.get_item_type( "TYPE_CLASS_DEF_ITEM" ) 2761 self.methods = self.map_list.get_item_type( "TYPE_METHOD_ID_ITEM" ) 2762 self.fields = self.map_list.get_item_type( "TYPE_FIELD_ID_ITEM" ) 2763 self.codes = self.map_list.get_item_type( "TYPE_CODE_ITEM" ) 2764 self.strings = self.map_list.get_item_type( "TYPE_STRING_DATA_ITEM" )
2765
2766 - def show(self) :
2767 """Show the .class format into a human readable format""" 2768 self.map_list.show()
2769
2770 - def save(self) :
2771 """ 2772 Return the dex (with the modifications) into raw format 2773 2774 @rtype: string 2775 """ 2776 return self._get_raw()
2777
2778 - def pretty_show(self, vm_a) :
2779 self.map_list.pretty_show(vm_a)
2780
2781 - def _iterFlatten(self, root):
2782 if isinstance(root, (list, tuple)): 2783 for element in root : 2784 for e in self._iterFlatten(element) : 2785 yield e 2786 else: 2787 yield root
2788
2789 - def _Exp(self, x) :
2790 l = [] 2791 for i in x : 2792 l.append(i) 2793 l.append( self._Exp( i.get_obj() ) ) 2794 return l
2795
2796 - def _get_raw(self) :
2797 # print len( list(self._iterFlatten( self._Exp( self.map_list.get_obj() ) ) ) ) 2798 # Due to the specific format of dalvik virtual machine, 2799 # we will get a list of raw object described by a buffer, a size and an offset 2800 # where to insert the specific buffer into the file 2801 l = self.map_list.get_raw() 2802 2803 result = list(self._iterFlatten( l )) 2804 result = sorted(result, key=lambda x: x.offset) 2805 2806 idx = 0 2807 buff = "" 2808 for i in result : 2809 # print idx, i.offset, "--->", i.offset + i.size 2810 if idx == i.offset : 2811 buff += i.buff 2812 else : 2813 # print "PATCH @ 0x%x" % idx 2814 self.set_idx( idx ) 2815 buff += '\x00' * (i.offset - idx) 2816 buff += i.buff 2817 idx += (i.offset - idx) 2818 2819 idx += i.size 2820 2821 return buff
2822
2823 - def get_classes_names(self) :
2824 """ 2825 Return the names of classes 2826 """ 2827 return [ i.get_name() for i in self.classes.class_def ]
2828
2829 - def get_classes(self) :
2830 return self.classes.class_def
2831
2832 - def get_method(self, name) :
2833 """Return into a list all methods which corresponds to the regexp 2834 2835 @param name : the name of the method (a regexp) 2836 """ 2837 prog = re.compile(name) 2838 l = [] 2839 for i in self.classes.class_def : 2840 for j in i.get_methods() : 2841 if prog.match( j.get_name() ) : 2842 l.append( j ) 2843 return l
2844
2845 - def get_field(self, name) :
2846 """Return into a list all fields which corresponds to the regexp 2847 2848 @param name : the name of the field (a regexp) 2849 """ 2850 prog = re.compile(name) 2851 l = [] 2852 for i in self.classes.class_def : 2853 for j in i.get_fields() : 2854 if prog.match( j.get_name() ) : 2855 l.append( j ) 2856 return l
2857
2858 - def get_all_fields(self) :
2859 return self.fields.gets()
2860
2861 - def get_fields(self) :
2862 """Return all objects fields""" 2863 l = [] 2864 for i in self.classes.class_def : 2865 for j in i.get_fields() : 2866 l.append( j ) 2867 return l
2868 2869
2870 - def get_methods(self) :
2871 """Return all objects methods""" 2872 l = [] 2873 for i in self.classes.class_def : 2874 for j in i.get_methods() : 2875 l.append( j ) 2876 return l
2877
2878 - def get_len_methods(self) :
2879 return len( self.get_methods() )
2880
2881 - def get_method_descriptor(self, class_name, method_name, descriptor) :
2882 """ 2883 Return the specific method 2884 2885 @param class_name : the class name of the method 2886 @param method_name : the name of the method 2887 @param descriptor : the descriptor of the method 2888 2889 """ 2890 for i in self.classes.class_def : 2891 for j in i.get_methods() : 2892 if class_name == j.get_class_name() and method_name == j.get_name() and descriptor == j.get_descriptor() : 2893 return j 2894 return None
2895
2896 - def get_methods_class(self, class_name) :
2897 """ 2898 Return methods of a class 2899 2900 @param class_name : the class name 2901 """ 2902 l = [] 2903 for i in self.classes.class_def : 2904 for j in i.get_methods() : 2905 if class_name == j.get_class_name() : 2906 l.append( j ) 2907 2908 return l
2909
2910 - def get_fields_class(self, class_name) :
2911 """ 2912 Return fields of a class 2913 2914 @param class_name : the class name 2915 """ 2916 l = [] 2917 for i in self.classes.class_def : 2918 for j in i.get_fields() : 2919 if class_name == j.get_class_name() : 2920 l.append( j ) 2921 2922 return l
2923
2924 - def get_field_descriptor(self, class_name, field_name, descriptor) :
2925 """ 2926 Return the specific field 2927 2928 @param class_name : the class name of the field 2929 @param field_name : the name of the field 2930 @param descriptor : the descriptor of the field 2931 2932 """ 2933 for i in self.classes.class_def : 2934 if class_name == i.get_name() : 2935 for j in i.get_fields() : 2936 if field_name == j.get_name() and descriptor == j.get_descriptor() : 2937 return j 2938 return None
2939
2940 - def get_class_manager(self) :
2941 """ 2942 Return directly the class manager 2943 2944 @rtype : L{ClassManager} 2945 """ 2946 return self.map_list.get_class_manager()
2947
2948 - def get_strings(self) :
2949 """ 2950 Return all strings 2951 """ 2952 return [i.get() for i in self.strings]
2953
2954 - def get_type(self) :
2955 return "DVM"
2956