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

Source Code for Module jvm

   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  from bytecode import SV, SVs 
  22   
  23  from struct import pack, unpack, calcsize 
  24  from collections import namedtuple 
  25  import re 
  26   
  27  # Special functions to manage more easily special arguments of bytecode  
28 -def special_F0(x) :
29 return [ i for i in x ]
30
31 -def special_F0R(x) :
32 return [ x ]
33
34 -def special_F1(x) :
35 return (x[0] << 8) | x[1]
36
37 -def special_F1R(x) :
38 return [ (x & 0xFF00) >> 8, x & 0x00FF ]
39
40 -def special_F2(x) :
41 v = ((x[0] << 8) | x[1]) 42 if v > 0x7FFF : 43 v = (0x7FFF & v) - 0x8000 44 45 return v
46
47 -def special_F2R(x) :
48 val = x & 0xFFFF 49 return [ (val & 0xFF00) >> 8, val & 0x00FF ]
50
51 -def special_F3(x) :
52 val = (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3] 53 if val > 0x7fffffff : 54 val = (0x7fffffff & val) - 0x80000000 55 return val
56
57 -def special_F3R(x) :
58 val = x & 0xFFFFFFFF 59 return [ (val & 0xFF000000) >> 24, (val & 0x00FF0000) >> 16, (val & 0x0000FF00) >> 8, val & 0x000000FF ]
60 61 # The list of java bytecodes, with their value, name, and special functions ! 62 JAVA_OPCODES = { 63 0x32 : [ "aaload" ], 64 0x53 : [ "aastore" ], 65 0x1 : [ "aconst_null" ], 66 0x19 : [ "aload", "index:B", special_F0, special_F0, None ], 67 0x2a : [ "aload_0" ], 68 0x2b : [ "aload_1" ], 69 0x2c : [ "aload_2" ], 70 0x2d : [ "aload_3" ], 71 0xbd : [ "anewarray", "indexbyte1:B indexbyte2:B", special_F1, special_F1R, "get_class" ], 72 0xb0 : [ "areturn" ], 73 0xbe : [ "arraylength" ], 74 0x3a : [ "astore", "index:B", special_F0, special_F0, None ], 75 0x4b : [ "astore_0" ], 76 0x4c : [ "astore_1" ], 77 0x4d : [ "astore_2" ], 78 0x4e : [ "astore_3" ], 79 0xbf : [ "athrow" ], 80 0x33 : [ "baload" ], 81 0x54 : [ "bastore" ], 82 0x10 : [ "bipush", "byte:B", special_F0, special_F0R, None ], 83 0x34 : [ "caload" ], 84 0x55 : [ "castore" ], 85 0xc0 : [ "checkcast", "indexbyte1:B indexbyte2:B" ], 86 0x90 : [ "d2f" ], 87 0x8e : [ "d2i" ], 88 0x8f : [ "d2l" ], 89 0x63 : [ "dadd" ], 90 0x31 : [ "daload" ], 91 0x52 : [ "dastore" ], 92 0x98 : [ "dcmpg" ], 93 0x97 : [ "dcmpl" ], 94 0xe : [ "dconst_0" ], 95 0xf : [ "dconst_1" ], 96 0x6f : [ "ddiv" ], 97 0x18 : [ "dload", "index:1" ], 98 0x26 : [ "dload_0" ], 99 0x27 : [ "dload_1" ], 100 0x28 : [ "dload_2" ], 101 0x29 : [ "dload_3" ], 102 0x6b : [ "dmul" ], 103 0x77 : [ "dneg" ], 104 0x73 : [ "drem" ], 105 0xaf : [ "dreturn" ], 106 0x39 : [ "dstore", "index:B", special_F0, special_F0, None ], 107 0x47 : [ "dstore_0" ], 108 0x48 : [ "dstore_1" ], 109 0x49 : [ "dstore_2" ], 110 0x4a : [ "dstore_3" ], 111 0x67 : [ "dsub" ], 112 0x59 : [ "dup" ], 113 0x5a : [ "dup_x1" ], 114 0x5b : [ "dup_x2" ], 115 0x5c : [ "dup2" ], 116 0x5d : [ "dup2_x1" ], 117 0x5e : [ "dup2_x2" ], 118 0x8d : [ "f2d" ], 119 0x8b : [ "f2i" ], 120 0x8c : [ "f2l" ], 121 0x62 : [ "fadd" ], 122 0x30 : [ "faload" ], 123 0x51 : [ "fastore" ], 124 0x96 : [ "fcmpg" ], 125 0x95 : [ "fcmpl" ], 126 0xb : [ "fconst_0" ], 127 0xc : [ "fconst_1" ], 128 0xd : [ "fconst_2" ], 129 0x6e : [ "fdiv" ], 130 0x17 : [ "fload", "index:B", special_F0, special_F0, None ], 131 0x22 : [ "fload_0" ], 132 0x23 : [ "fload_1" ], 133 0x24 : [ "fload_2" ], 134 0x25 : [ "fload_3" ], 135 0x6a : [ "fmul" ], 136 0x76 : [ "fneg" ], 137 0x72 : [ "frem" ], 138 0xae : [ "freturn" ], 139 0x38 : [ "fstore", "index:B", special_F0, special_F0, None ], 140 0x43 : [ "fstore_0" ], 141 0x44 : [ "fstore_1" ], 142 0x45 : [ "fstore_2" ], 143 0x46 : [ "fstore_3" ], 144 0x66 : [ "fsub" ], 145 0xb4 : [ "getfield", "indexbyte1:B indexbyte2:B", special_F1, special_F1R, "get_field" ], 146 0xb2 : [ "getstatic", "indexbyte1:B indexbyte2:B", special_F1, special_F1R, "get_field", "get_field_index" ], 147 0xa7 : [ "goto", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 148 0xc8 : [ "goto_w", "branchbyte1:B branchbyte2:B branchbyte3:B branchbyte4:B" ], 149 0x91 : [ "i2b" ], 150 0x92 : [ "i2c" ], 151 0x87 : [ "i2d" ], 152 0x86 : [ "i2f" ], 153 0x85 : [ "i2l" ], 154 0x93 : [ "i2s" ], 155 0x60 : [ "iadd" ], 156 0x2e : [ "iaload" ], 157 0x7e : [ "iand" ], 158 0x4f : [ "iastore" ], 159 0x2 : [ "iconst_m1" ], 160 0x3 : [ "iconst_0" ], 161 0x4 : [ "iconst_1" ], 162 0x5 : [ "iconst_2" ], 163 0x6 : [ "iconst_3" ], 164 0x7 : [ "iconst_4" ], 165 0x8 : [ "iconst_5" ], 166 0x6c : [ "idiv" ], 167 0xa5 : [ "if_acmpeq", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 168 0xa6 : [ "if_acmpne", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 169 0x9f : [ "if_icmpeq", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 170 0xa0 : [ "if_icmpne", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 171 0xa1 : [ "if_icmplt", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 172 0xa2 : [ "if_icmpge", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 173 0xa3 : [ "if_icmpgt", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 174 0xa4 : [ "if_icmple", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 175 0x99 : [ "ifeq", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 176 0x9a : [ "ifne", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 177 0x9b : [ "iflt", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 178 0x9c : [ "ifge", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 179 0x9d : [ "ifgt", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 180 0x9e : [ "ifle", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 181 0xc7 : [ "ifnonnull", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 182 0xc6 : [ "ifnull", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 183 0x84 : [ "iinc", "index:B const:B", special_F0, special_F0, None ], 184 0x15 : [ "iload", "index:B", special_F0, special_F0, None ], 185 0x1a : [ "iload_0" ], 186 0x1b : [ "iload_1" ], 187 0x1c : [ "iload_2" ], 188 0x1d : [ "iload_3" ], 189 0x68 : [ "imul" ], 190 0x74 : [ "ineg" ], 191 0xc1 : [ "instanceof", "indexbyte1:B indexbyte2:B" ], 192 0xb9 : [ "invokeinterface", "indexbyte1:B indexbyte2:B count:B null:B" ], 193 0xb7 : [ "invokespecial", "indexbyte1:B indexbyte2:B", special_F1, special_F1R, "get_method", "get_method_index" ], 194 0xb8 : [ "invokestatic", "indexbyte1:B indexbyte2:B", special_F1, special_F1R, "get_method", "get_method_index" ], 195 0xb6 : [ "invokevirtual", "indexbyte1:B indexbyte2:B", special_F1, special_F1R, "get_method", "get_method_index" ], 196 0x80 : [ "ior" ], 197 0x70 : [ "irem" ], 198 0xac : [ "ireturn" ], 199 0x78 : [ "ishl" ], 200 0x7a : [ "ishr" ], 201 0x36 : [ "istore", "index:B", special_F0, special_F0, None ], 202 0x3b : [ "istore_0" ], 203 0x3c : [ "istore_1" ], 204 0x3d : [ "istore_2" ], 205 0x3e : [ "istore_3" ], 206 0x64 : [ "isub" ], 207 0x7c : [ "iushr" ], 208 0x82 : [ "ixor" ], 209 0xa8 : [ "jsr", "branchbyte1:B branchbyte2:B", special_F2, special_F2R, None ], 210 0xc9 : [ "jsr_w", "branchbyte1:B branchbyte2:B branchbyte3:B branchbyte4:B", special_F3, special_F3R, None ], 211 0x8a : [ "l2d" ], 212 0x89 : [ "l2f" ], 213 0x88 : [ "l2i" ], 214 0x61 : [ "ladd" ], 215 0x2f : [ "laload" ], 216 0x7f : [ "land" ], 217 0x50 : [ "lastore" ], 218 0x94 : [ "lcmp" ], 219 0x9 : [ "lconst_0" ], 220 0xa : [ "lconst_1" ], 221 0x12 : [ "ldc", "index:B", special_F0, special_F0R, "get_value" ], 222 0x13 : [ "ldc_w", "indexbyte1:B indexbyte2:B", special_F2, special_F2R, None ], 223 0x14 : [ "ldc2_w", "indexbyte1:B indexbyte2:B", special_F2, special_F2R, None ], 224 0x6d : [ "ldiv" ], 225 0x16 : [ "lload", "index:B", special_F0, special_F0, None ], 226 0x1e : [ "lload_0" ], 227 0x1f : [ "lload_1" ], 228 0x20 : [ "lload_2" ], 229 0x21 : [ "lload_3" ], 230 0x69 : [ "lmul" ], 231 0x75 : [ "lneg" ], 232 0xab : [ "lookupswitch", "bytepad1:B bytepad2:B bytepad3:B defaultbyte1:B defaultbyte2:B defaultbyte2:B defaultbyte3:B defaultbyte4:B npairs1:B npairs2:B npairs3:B npairs4:B" ], # TODO 233 0x81 : [ "lor" ], 234 0x71 : [ "lrem" ], 235 0xad : [ "lreturn" ], 236 0x79 : [ "lshl" ], 237 0x7b : [ "lshr" ], 238 0x37 : [ "lstore", "index:B", special_F0, special_F0, None ], 239 0x3f : [ "lstore_0" ], 240 0x40 : [ "lstore_1" ], 241 0x41 : [ "lstore_2" ], 242 0x42 : [ "lstore_3" ], 243 0x65 : [ "lsub" ], 244 0x7d : [ "lushr" ], 245 0x83 : [ "lxor" ], 246 0xc2 : [ "monitorenter" ], 247 0xc3 : [ "monitorexit" ], 248 0xc5 : [ "multianewarray", "indexbyte1:B indexbyte2:B dimensions:B" ], 249 0xbb : [ "new", "indexbyte1:B indexbyte2:B", special_F1, special_F1R, "get_class" ], 250 0xbc : [ "newarray", "atype:B", special_F0, special_F0, "get_array_type" ], 251 0x0 : [ "nop" ], 252 0x57 : [ "pop" ], 253 0x58 : [ "pop2" ], 254 0xb5 : [ "putfield", "indexbyte1:B indexbyte2:B", special_F1, special_F1R, "get_field" ], 255 0xb3 : [ "putstatic", "indexbyte1:B indexbyte2:B" ], 256 0xa9 : [ "ret", "index:B", special_F0, special_F0, None ], 257 0xb1 : [ "return" ], 258 0x35 : [ "saload" ], 259 0x56 : [ "sastore" ], 260 0x11 : [ "sipush", "byte1:B byte2:B", special_F1, special_F1R, None ], 261 0x5f : [ "swap" ], 262 0xaa : [ "tableswitch" ], # TODO 263 0xc4 : [ "wide" ], # TODO 264 } 265 266 # Invert the value and the name of the bytecode 267 INVERT_JAVA_OPCODES = dict([( JAVA_OPCODES[k][0], k ) for k in JAVA_OPCODES]) 268 269 # List of java bytecodes which can modify the control flow 270 BRANCH_JAVA_OPCODES = [ "goto", "goto_w", "if_acmpeq", "if_icmpeq", "if_icmpne", "if_icmplt", "if_icmpge", "if_icmpgt", "if_icmple", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle", "ifnonnull", "ifnull", "jsr", "jsr_w" ] 271
272 -def EXTRACT_INFORMATION(op_value) :
273 """Extract information (special functions) about a bytecode""" 274 r_function = JAVA_OPCODES[ op_value ][2] 275 v_function = JAVA_OPCODES[ op_value ][3] 276 f_function = JAVA_OPCODES[ op_value ][4] 277 278 r_format = ">" 279 r_buff = [] 280 281 format = JAVA_OPCODES[ op_value ][1] 282 l = format.split(" ") 283 for j in l : 284 operands = j.split(":") 285 286 name = operands[0] + " " 287 val = operands[1] 288 289 r_buff.append( name.replace(' ', '') ) 290 r_format += val 291 292 return ( r_function, v_function, r_buff, r_format, f_function )
293 294 295 METHOD_INFO = [ '>HHHH', namedtuple("MethodInfo", "access_flags name_index descriptor_index attributes_count") ] 296 ATTRIBUTE_INFO = [ '>HL', namedtuple("AttributeInfo", "attribute_name_index attribute_length") ] 297 FIELD_INFO = [ '>HHHH', namedtuple("FieldInfo", "access_flags name_index descriptor_index attributes_count") ] 298 LINE_NUMBER_TABLE = [ '>HH', namedtuple("LineNumberTable", "start_pc line_number") ] 299 EXCEPTION_TABLE = [ '>HHHH', namedtuple("ExceptionTable", "start_pc end_pc handler_pc catch_type") ] 300 LOCAL_VARIABLE_TABLE = [ '>HHHHH', namedtuple("LocalVariableTable", "start_pc length name_index descriptor_index index") ] 301 302 CODE_LOW_STRUCT = [ '>HHL', namedtuple( "LOW", "max_stack max_locals code_length" ) ] 303 304 ARRAY_TYPE = { 305 4 : "T_BOOLEAN", 306 5 : "T_CHAR", 307 6 : "T_FLOAT", 308 7 : "T_DOUBLE", 309 8 : "T_BYTE", 310 9 : "T_SHORT", 311 10 : "T_INT", 312 11 : "T_LONG", 313 } 314 INVERT_ARRAY_TYPE = dict([( ARRAY_TYPE[k][0], k ) for k in ARRAY_TYPE]) 315 316 317 ACC_CLASS_FLAGS = { 318 0x0001 : [ "ACC_PUBLIC", "Declared public; may be accessed from outside its package." ], 319 0x0010 : [ "ACC_FINAL", "Declared final; no subclasses allowed." ], 320 0x0020 : [ "ACC_SUPER", "Treat superclass methods specially when invoked by the invokespecial instruction." ], 321 0x0200 : [ "ACC_INTERFACE", "Is an interface, not a class." ], 322 0x0400 : [ "ACC_ABSTRACT", "Declared abstract; may not be instantiated." ], 323 } 324 INVERT_ACC_CLASS_FLAGS = dict([( ACC_CLASS_FLAGS[k][0], k ) for k in ACC_CLASS_FLAGS]) 325 326 327 ACC_FIELD_FLAGS = { 328 0x0001 : [ "ACC_PUBLIC", "Declared public; may be accessed from outside its package." ], 329 0x0002 : [ "ACC_PRIVATE", "Declared private; usable only within the defining class." ], 330 0x0004 : [ "ACC_PROTECTED", "Declared protected; may be accessed within subclasses." ], 331 0x0008 : [ "ACC_STATIC", "Declared static." ], 332 0x0010 : [ "ACC_FINAL", "Declared final; no further assignment after initialization." ], 333 0x0040 : [ "ACC_VOLATILE", "Declared volatile; cannot be cached." ], 334 0x0080 : [ "ACC_TRANSIENT", "Declared transient; not written or read by a persistent object manager." ], 335 } 336 INVERT_ACC_FIELD_FLAGS = dict([( ACC_FIELD_FLAGS[k][0], k ) for k in ACC_FIELD_FLAGS]) 337 338 339 ACC_METHOD_FLAGS = { 340 0x0001 : [ "ACC_PUBLIC", "Declared public; may be accessed from outside its package." ], 341 0x0002 : [ "ACC_PRIVATE", "Declared private; accessible only within the defining class." ], 342 0x0004 : [ "ACC_PROTECTED", "Declared protected; may be accessed within subclasses." ], 343 0x0008 : [ "ACC_STATIC", "Declared static." ], 344 0x0010 : [ "ACC_FINAL", "Declared final; may not be overridden." ], 345 0x0020 : [ "ACC_SYNCHRONIZED", "Declared synchronized; invocation is wrapped in a monitor lock." ], 346 0x0100 : [ "ACC_NATIVE", "Declared native; implemented in a language other than Java." ], 347 0x0400 : [ "ACC_ABSTRACT", "Declared abstract; no implementation is provided." ], 348 0x0800 : [ "ACC_STRICT", "Declared strictfp; floating-point mode is FP-strict" ] 349 } 350 INVERT_ACC_METHOD_FLAGS = dict([( ACC_METHOD_FLAGS[k][0], k ) for k in ACC_METHOD_FLAGS]) 351
352 -class CpInfo(object) :
353 """Generic class to manage constant info object"""
354 - def __init__(self, buff) :
355 self.__tag = SV( '>B', buff.read_b(1) ) 356 357 self.__bytes = None 358 self.__extra = 0 359 360 tag_value = self.__tag.get_value() 361 format = CONSTANT_INFO[ tag_value ][1] 362 363 self.__name = CONSTANT_INFO[ tag_value ][0] 364 365 self.format = SVs( format, CONSTANT_INFO[ tag_value ][2], buff.read( calcsize( format ) ) ) 366 367 # Utf8 value ? 368 if tag_value == 1 : 369 self.__extra = self.format.get_value().length 370 self.__bytes = SVs( ">%ss" % self.format.get_value().length, namedtuple( CONSTANT_INFO[ tag_value ][0] + "_next", "bytes" ), buff.read( self.format.get_value().length ) )
371
372 - def get_format(self) :
373 return self.format
374
375 - def get_name(self) :
376 return self.__name
377
378 - def get_bytes(self) :
379 return self.__bytes.get_value().bytes
380
381 - def set_bytes(self, name) :
382 self.format.set_value( { "length" : len(name) } ) 383 self.__extra = self.format.get_value().length 384 self.__bytes = SVs( ">%ss" % self.format.get_value().length, namedtuple( CONSTANT_INFO[ self.__tag.get_value() ][0] + "_next", "bytes" ), name )
385
386 - def get_length(self) :
387 return self.__extra + calcsize( CONSTANT_INFO[ self.__tag.get_value() ][1] )
388
389 - def get_raw(self) :
390 if self.__bytes != None : 391 return self.format.get_value_buff() + self.__bytes.get_value_buff() 392 return self.format.get_value_buff()
393
394 - def show(self) :
395 if self.__bytes != None : 396 print self.format.get_value(), self.__bytes.get_value() 397 else : 398 print self.format.get_value()
399
400 -class MethodRef(CpInfo) :
401 - def __init__(self, class_manager, buff) :
402 super(MethodRef, self).__init__( buff )
403
404 - def get_class_index(self) :
405 return self.format.get_value().class_index
406
407 - def get_name_and_type_index(self) :
408 return self.format.get_value().name_and_type_index
409
410 -class InterfaceMethodRef(CpInfo) :
411 - def __init__(self, class_manager, buff) :
412 super(InterfaceMethodRef, self).__init__( buff )
413
414 -class FieldRef(CpInfo) :
415 - def __init__(self, class_manager, buff) :
416 super(FieldRef, self).__init__( buff )
417
418 - def get_class_index(self) :
419 return self.format.get_value().class_index
420
421 - def get_name_and_type_index(self) :
422 return self.format.get_value().name_and_type_index
423
424 -class Class(CpInfo) :
425 - def __init__(self, class_manager, buff) :
426 super(Class, self).__init__( buff )
427
428 - def get_name_index(self) :
429 return self.format.get_value().name_index
430
431 -class Utf8(CpInfo) :
432 - def __init__(self, class_manager, buff) :
433 super(Utf8, self).__init__( buff )
434
435 -class String(CpInfo) :
436 - def __init__(self, class_manager, buff) :
437 super(String, self).__init__( buff )
438
439 -class Integer(CpInfo) :
440 - def __init__(self, class_manager, buff) :
441 super(Integer, self).__init__( buff )
442
443 -class Float(CpInfo) :
444 - def __init__(self, class_manager, buff) :
445 super(Float, self).__init__( buff )
446
447 -class Long(CpInfo) :
448 - def __init__(self, class_manager, buff) :
449 super(Long, self).__init__( buff )
450
451 -class Double(CpInfo) :
452 - def __init__(self, class_manager, buff) :
453 super(Double, self).__init__( buff )
454
455 -class NameAndType(CpInfo) :
456 - def __init__(self, class_manager, buff) :
457 super(NameAndType, self).__init__( buff )
458
459 - def get_get_name_index(self) :
460 return self.format.get_value().get_name_index
461
462 - def get_name_index(self) :
463 return self.format.get_value().name_index
464
465 - def get_descriptor_index(self) :
466 return self.format.get_value().descriptor_index
467 468 CONSTANT_INFO = { 469 7 : [ "CONSTANT_Class", '>BH', namedtuple( "CONSTANT_Class_info", "tag name_index" ), Class ], 470 9 : [ "CONSTANT_Fieldref", '>BHH', namedtuple( "CONSTANT_Fieldref_info", "tag class_index name_and_type_index" ), FieldRef ], 471 10 : [ "CONSTANT_Methodref", '>BHH', namedtuple( "CONSTANT_Methodref_info", "tag class_index name_and_type_index" ), MethodRef ], 472 11 : [ "CONSTANT_InterfaceMethodref", '>BHH', namedtuple( "CONSTANT_InterfaceMethodref_info", "tag class_index name_and_type_index" ), InterfaceMethodRef ], 473 8 : [ "CONSTANT_String", '>BH', namedtuple( "CONSTANT_String_info", "tag string_index" ), String ], 474 3 : [ "CONSTANT_Integer", '>BL', namedtuple( "CONSTANT_Integer_info", "tag bytes" ), Integer ], 475 4 : [ "CONSTANT_Float", '>BL', namedtuple( "CONSTANT_Float_info", "tag bytes" ), Float ], 476 5 : [ "CONSTANT_Long", '>BLL', namedtuple( "CONSTANT_Long_info", "tag high_bytes low_bytes" ), Long ], 477 6 : [ "CONSTANT_Double", '>BLL', namedtuple( "CONSTANT_Long_info", "tag high_bytes low_bytes" ), Double ], 478 12 : [ "CONSTANT_NameAndType", '>BHH', namedtuple( "CONSTANT_NameAndType_info", "tag name_index descriptor_index" ), NameAndType ], 479 1 : [ "CONSTANT_Utf8", '>BH', namedtuple( "CONSTANT_Utf8_info", "tag length" ), Utf8 ] 480 } 481 INVERT_CONSTANT_INFO = dict([( CONSTANT_INFO[k][0], k ) for k in CONSTANT_INFO]) 482 ITEM_Top = 0 483 ITEM_Integer = 1 484 ITEM_Float = 2 485 ITEM_Long = 4 486 ITEM_Double = 3 487 ITEM_Null = 5 488 ITEM_UninitializedThis = 6 489 ITEM_Object = 7 490 ITEM_Uninitialized = 8 491 492 VERIFICATION_TYPE_INFO = { 493 ITEM_Top : [ "Top_variable_info", '>B', namedtuple( "Top_variable_info", "tag" ) ], 494 ITEM_Integer : [ "Integer_variable_info", '>B', namedtuple( "Integer_variable_info", "tag" ) ], 495 ITEM_Float : [ "Float_variable_info", '>B', namedtuple( "Float_variable_info", "tag" ) ], 496 ITEM_Long : [ "Long_variable_info", '>B', namedtuple( "Long_variable_info", "tag" ) ], 497 ITEM_Double : [ "Double_variable_info", '>B', namedtuple( "Double_variable_info", "tag" ) ], 498 ITEM_Null : [ "Null_variable_info", '>B', namedtuple( "Null_variable_info", "tag" ) ], 499 ITEM_UninitializedThis : [ "UninitializedThis_variable_info", '>B', namedtuple( "UninitializedThis_variable_info", "tag" ) ], 500 ITEM_Object : [ "Object_variable_info", '>BH', namedtuple( "Object_variable_info", "tag cpool_index" ), [ ("cpool_index", "get_class") ] ], 501 ITEM_Uninitialized : [ "Uninitialized_variable_info", '>BH', namedtuple( "Uninitialized_variable_info", "tag offset" ) ], 502 } 503
504 -class FieldInfo :
505 """An object which represents a Field"""
506 - def __init__(self, class_manager, buff) :
507 self.__raw_buff = buff.read( calcsize( FIELD_INFO[0] ) ) 508 self.format = SVs( FIELD_INFO[0], FIELD_INFO[1], self.__raw_buff ) 509 510 self.__CM = class_manager 511 self.__attributes = [] 512 513 for i in range(0, self.format.get_value().attributes_count) : 514 ai = AttributeInfo( self.__CM, buff ) 515 self.__attributes.append( ai )
516
517 - def get_raw(self) :
518 return self.__raw_buff + ''.join(x.get_raw() for x in self.__attributes)
519
520 - def get_length(self) :
521 val = 0 522 for i in self.__attributes : 523 val += i.length 524 return val + calcsize( FIELD_INFO[0] )
525
526 - def get_access(self) :
527 return ACC_FIELD_FLAGS[ self.format.get_value().access_flags ][0]
528
529 - def set_access(self, value) :
530 self.format.set_value( { "access_flags" : value } )
531
532 - def get_name(self) :
533 return self.__CM.get_string( self.format.get_value().name_index )
534
535 - def set_name(self, name) :
536 return self.__CM.set_string( self.format.get_value().name_index, name )
537
538 - def get_descriptor(self) :
539 return self.__CM.get_string( self.format.get_value().descriptor_index )
540
541 - def set_descriptor(self, name) :
542 return self.__CM.set_string( self.format.get_value().descriptor_index, name )
543
544 - def get_attributes(self) :
545 return self.__attributes
546
547 - def show(self) :
548 print self.format.get_value(), self.__CM.get_string( self.format.get_value().name_index ) 549 for i in self.__attributes : 550 i.show()
551
552 -class MethodInfo :
553 """An object which represents a Method"""
554 - def __init__(self, class_manager, buff) :
555 self.format = SVs( METHOD_INFO[0], METHOD_INFO[1], buff.read( calcsize( METHOD_INFO[0] ) ) ) 556 557 self.__CM = class_manager 558 self.__code = None 559 self.__attributes = [] 560 561 for i in range(0, self.format.get_value().attributes_count) : 562 ai = AttributeInfo( self.__CM, buff ) 563 self.__attributes.append( ai ) 564 565 if ai.get_name() == "Code" : 566 self.__code = ai
567
568 - def get_raw(self) :
569 return self.format.get_value_buff() + ''.join(x.get_raw() for x in self.__attributes)
570
571 - def get_length(self) :
572 val = 0 573 for i in self.__attributes : 574 val += i.length 575 576 return val + calcsize( METHOD_INFO[0] )
577
578 - def get_attributes(self) :
579 return self.__attributes
580
581 - def get_access(self) :
582 return ACC_METHOD_FLAGS[ self.format.get_value().access_flags ][0]
583
584 - def set_access(self, value) :
585 self.format.set_value( { "access_flags" : value } )
586
587 - def get_name(self) :
588 return self.__CM.get_string( self.format.get_value().name_index )
589
590 - def set_name(self, name) :
591 return self.__CM.set_string( self.format.get_value().name_index, name )
592
593 - def get_descriptor(self) :
594 return self.__CM.get_string( self.format.get_value().descriptor_index )
595
596 - def set_descriptor(self, name) :
597 return self.__CM.set_string( self.format.get_value().name_descriptor, name )
598
599 - def get_name_index(self) :
600 return self.format.get_value().name_index
601
602 - def get_descriptor_index(self) :
603 return self.format.get_value().descriptor_index
604
605 - def get_local_variables(self) :
606 return self.get_code().get_local_variables()
607
608 - def get_code(self) :
609 return self.__code.get_item()
610
611 - def set_name_index(self, name_index) :
612 self.format.set_value( { "name_index" : name_index } )
613
614 - def set_descriptor_index(self, descriptor_index) :
615 self.format.set_value( { "descriptor_index" : descriptor_index } )
616
617 - def set_cm(self, cm) :
618 self.__CM = cm 619 for i in self.__attributes : 620 i.set_cm( cm )
621
622 - def with_descriptor(self, descriptor) :
623 return descriptor == self.__CM.get_string( self.format.get_value().descriptor_index )
624
625 - def _patch_bytecodes(self) :
626 return self.get_code()._patch_bytecodes()
627
628 - def show(self) :
629 print "*" * 80 630 print self.format.get_value(), self.__CM.get_string( self.format.get_value().name_index ), self.__CM.get_string( self.format.get_value().descriptor_index ) 631 for i in self.__attributes : 632 i.show() 633 print "*" * 80
634
635 -class CreateString :
636 """Create a specific String constant by given the name index"""
637 - def __init__(self, class_manager, bytes) :
638 self.__string_index = class_manager.add_string( bytes )
639
640 - def get_raw(self) :
641 tag_value = INVERT_CONSTANT_INFO[ "CONSTANT_String" ] 642 buff = pack( CONSTANT_INFO[ tag_value ][1], tag_value, self.__string_index ) 643 644 return buff
645
646 -class CreateInteger :
647 """Create a specific Integer constant by given the name index"""
648 - def __init__(self, byte) :
649 self.__byte = byte
650
651 - def get_raw(self) :
652 tag_value = INVERT_CONSTANT_INFO[ "CONSTANT_Integer" ] 653 buff = pack( CONSTANT_INFO[ tag_value ][1], tag_value, self.__byte ) 654 655 return buff
656
657 -class CreateClass :
658 """Create a specific Class constant by given the name index"""
659 - def __init__(self, class_manager, name_index) :
660 self.__CM = class_manager 661 662 self.__name_index = name_index
663
664 - def get_raw(self) :
665 tag_value = INVERT_CONSTANT_INFO[ "CONSTANT_Class" ] 666 buff = pack( CONSTANT_INFO[ tag_value ][1], tag_value, self.__name_index ) 667 668 return buff
669
670 -class CreateNameAndType :
671 """Create a specific NameAndType constant by given the name and the descriptor index"""
672 - def __init__(self, class_manager, name_index, descriptor_index) :
673 self.__CM = class_manager 674 675 self.__name_index = name_index 676 self.__descriptor_index = descriptor_index
677
678 - def get_raw(self) :
679 tag_value = INVERT_CONSTANT_INFO[ "CONSTANT_NameAndType" ] 680 buff = pack( CONSTANT_INFO[ tag_value ][1], tag_value, self.__name_index, self.__descriptor_index ) 681 682 return buff
683
684 -class CreateFieldRef :
685 """Create a specific FieldRef constant by given the class and the NameAndType index"""
686 - def __init__(self, class_manager, class_index, name_and_type_index) :
687 self.__CM = class_manager 688 689 self.__class_index = class_index 690 self.__name_and_type_index = name_and_type_index
691
692 - def get_raw(self) :
693 tag_value = INVERT_CONSTANT_INFO[ "CONSTANT_Fieldref" ] 694 buff = pack( CONSTANT_INFO[ tag_value ][1], tag_value, self.__class_index, self.__name_and_type_index ) 695 696 return buff
697
698 -class CreateMethodRef :
699 """Create a specific MethodRef constant by given the class and the NameAndType index"""
700 - def __init__(self, class_manager, class_index, name_and_type_index) :
701 self.__CM = class_manager 702 703 self.__class_index = class_index 704 self.__name_and_type_index = name_and_type_index
705
706 - def get_raw(self) :
707 tag_value = INVERT_CONSTANT_INFO[ "CONSTANT_Methodref" ] 708 buff = pack( CONSTANT_INFO[ tag_value ][1], tag_value, self.__class_index, self.__name_and_type_index ) 709 710 return buff
711
712 -class CreateCodeAttributeInfo :
713 """Create a specific CodeAttributeInfo by given bytecodes (into an human readable format)"""
714 - def __init__(self, class_manager, codes) :
715 self.__CM = class_manager 716 717 #ATTRIBUTE_INFO = [ '>HL', namedtuple("AttributeInfo", "attribute_name_index attribute_length") ] 718 self.__attribute_name_index = self.__CM.get_string_index( "Code" ) 719 self.__attribute_length = 0 720 ######## 721 722 # CODE_LOW_STRUCT = [ '>HHL', namedtuple( "LOW", "max_stack max_locals code_length" ) ] 723 self.__max_stack = 1 724 self.__max_locals = 2 725 self.__code_length = 0 726 ######## 727 728 # CODE 729 raw_buff = "" 730 731 for i in codes : 732 op_name = i[0] 733 op_value = INVERT_JAVA_OPCODES[ op_name ] 734 raw_buff += pack( '>B', op_value ) 735 736 if len( JAVA_OPCODES[ op_value ] ) > 1 : 737 r_function, v_function, r_buff, r_format, f_function = EXTRACT_INFORMATION( op_value ) 738 raw_buff += pack(r_format, *v_function( *i[1:] ) ) 739 740 self.__code = JavaCode( self.__CM, raw_buff ) 741 self.__code_length = len( raw_buff ) 742 ######## 743 744 # EXCEPTION 745 # u2 exception_table_length; 746 self.__exception_table_length = 0 747 748 # { u2 start_pc; 749 # u2 end_pc; 750 # u2 handler_pc; 751 # u2 catch_type; 752 # } exception_table[exception_table_length]; 753 self.__exception_table = [] 754 ######## 755 756 # ATTRIBUTES 757 # u2 attributes_count; 758 self.__attributes_count = 0 759 760 # attribute_info attributes[attributes_count]; 761 self.__attributes = [] 762 ######## 763 764 # FIXME : remove calcsize 765 self.__attribute_length = calcsize( ATTRIBUTE_INFO[0] ) + \ 766 calcsize( CODE_LOW_STRUCT[0] ) + \ 767 self.__code_length + \ 768 calcsize('>H') + \ 769 calcsize('>H')
770
771 - def get_raw(self) :
772 return pack( ATTRIBUTE_INFO[0], self.__attribute_name_index, self.__attribute_length ) + \ 773 pack( CODE_LOW_STRUCT[0], self.__max_stack, self.__max_locals, self.__code_length ) + \ 774 self.__code.get_raw() + \ 775 pack( '>H', self.__exception_table_length ) + \ 776 ''.join( i.get_raw() for i in self.__exception_table ) + \ 777 pack( '>H', self.__attributes_count ) + \ 778 ''.join( i.get_raw() for i in self.__attributes )
779 780 781 # METHOD_INFO = [ '>HHHH', namedtuple("MethodInfo", "access_flags name_index descriptor_index attributes_count") ]
782 -class CreateMethodInfo :
783 """Create a specific MethodInfo by given the name, the prototype and the code (into an human readable format) of the "new" method"""
784 - def __init__(self, class_manager, name, proto, codes) :
785 self.__CM = class_manager 786 787 access_flags_value = proto[0] 788 return_value = proto[1] 789 arguments_value = proto[2] 790 791 self.__access_flags = INVERT_ACC_METHOD_FLAGS[ access_flags_value ] 792 793 self.__name_index = self.__CM.get_string_index( name ) 794 if self.__name_index == -1 : 795 self.__name_index = self.__CM.add_string( name ) 796 797 proto_final = "(" + arguments_value + ")" + return_value 798 self.__descriptor_index = self.__CM.get_string_index( proto_final ) 799 if self.__descriptor_index == -1 : 800 self.__descriptor_index = self.__CM.add_string( proto_final ) 801 802 self.__attributes = [] 803 804 self.__attributes.append( CreateCodeAttributeInfo( self.__CM, codes ) )
805
806 - def get_raw(self) :
807 buff = pack( METHOD_INFO[0], self.__access_flags, self.__name_index, self.__descriptor_index, len(self.__attributes) ) 808 809 for i in self.__attributes : 810 buff += i.get_raw() 811 812 return buff
813
814 -class JBC :
815 """JBC manages each bytecode with the value, name, raw buffer and special functions""" 816 # special --> ( r_function, v_function, r_buff, r_format, f_function )
817 - def __init__(self, class_manager, op_name, raw_buff, special=None) :
818 self.__CM = class_manager 819 self.__op_name = op_name 820 self.__raw_buff = raw_buff 821 822 self.__special = special 823 self.__special_value = None 824 825 self._load()
826
827 - def _load(self) :
828 if self.__special != None : 829 ntuple = namedtuple( self.__op_name, self.__special[2] ) 830 x = ntuple._make( unpack( self.__special[3], self.__raw_buff[1:] ) ) 831 832 if self.__special[4] == None : 833 self.__special_value = self.__special[0]( x ) 834 else : 835 self.__special_value = getattr(self.__CM, self.__special[4])( self.__special[0]( x ) )
836
837 - def reload(self, raw_buff) :
838 """Reload the bytecode with a new raw buffer""" 839 self.__raw_buff = raw_buff 840 self._load()
841
842 - def set_cm(self, cm) :
843 self.__CM = cm
844
845 - def get_length(self) :
846 """Return the length of the bytecode""" 847 return len( self.__raw_buff )
848
849 - def get_raw(self) :
850 """Return the current raw buffer of the bytecode""" 851 return self.__raw_buff
852
853 - def get_name(self) :
854 """Return the name of the bytecode""" 855 return self.__op_name
856
857 - def get_operands(self) :
858 """Return the operands of the bytecode""" 859 return self.__special_value
860
861 - def adjust_r(self, pos, pos_modif, len_modif) :
862 """Adjust the bytecode (if necessary (in this cas the bytecode is a branch bytecode)) when a bytecode has been removed""" 863 # print self.__op_name, pos, pos_modif, len_modif, self.__special_value, type(pos), type(pos_modif), type(len_modif), type(self.__special_value) 864 865 if pos > pos_modif : 866 if (self.__special_value + pos) < (pos_modif) : 867 # print "MODIF +", self.__special_value, len_modif, 868 self.__special_value += len_modif 869 # print self.__special_value 870 self.__raw_buff = pack( '>B', INVERT_JAVA_OPCODES[ self.__op_name ] ) + pack(self.__special[3], *self.__special[1]( self.__special_value ) ) 871 872 elif pos < pos_modif : 873 if (self.__special_value + pos) > (pos_modif) : 874 # print "MODIF -", self.__special_value, len_modif, 875 self.__special_value -= len_modif 876 # print self.__special_value 877 self.__raw_buff = pack( '>B', INVERT_JAVA_OPCODES[ self.__op_name ] ) + pack(self.__special[3], *self.__special[1]( self.__special_value ) )
878
879 - def adjust_i(self, pos, pos_modif, len_modif) :
880 """Adjust the bytecode (if necessary (in this cas the bytecode is a branch bytecode)) when a bytecode has been inserted""" 881 #print self.__op_name, pos, pos_modif, len_modif, self.__special_value, type(pos), type(pos_modif), type(len_modif), type(self.__special_value) 882 883 if pos > pos_modif : 884 if (self.__special_value + pos) < (pos_modif) : 885 # print "MODIF +", self.__special_value, len_modif, 886 self.__special_value -= len_modif 887 # print self.__special_value 888 self.__raw_buff = pack( '>B', INVERT_JAVA_OPCODES[ self.__op_name ] ) + pack(self.__special[3], *self.__special[1]( self.__special_value ) ) 889 890 elif pos < pos_modif : 891 if (self.__special_value + pos) > (pos_modif) : 892 # print "MODIF -", self.__special_value, len_modif, 893 self.__special_value += len_modif 894 # print self.__special_value 895 self.__raw_buff = pack( '>B', INVERT_JAVA_OPCODES[ self.__op_name ] ) + pack(self.__special[3], *self.__special[1]( self.__special_value ) )
896
897 - def show(self, pos) :
898 """Show the bytecode at a specific position 899 900 pos - the position into the bytecodes (integer) 901 """ 902 if self.__special_value == None : 903 print self.__op_name 904 else : 905 if self.__op_name in BRANCH_JAVA_OPCODES : 906 print self.__op_name, self.__special_value, self.__special_value + pos 907 else : 908 print self.__op_name, self.__special_value
909
910 -class JavaCode :
911 """JavaCode manages a list of bytecode to a specific method, by decoding a raw buffer and transform each bytecode into a JBC object"""
912 - def __init__(self, class_manager, buff) :
913 self.__CM = class_manager 914 915 self.__raw_buff = buff 916 self.__bytecodes = [] 917 self.__maps = [] 918 self.__branches = [] 919 920 i = 0 921 while i < len(self.__raw_buff) : 922 op_value = unpack( '>B', self.__raw_buff[i])[0] 923 if op_value in JAVA_OPCODES : 924 if len( JAVA_OPCODES[ op_value ] ) > 2 : 925 r_function, v_function, r_buff, r_format, f_function = EXTRACT_INFORMATION( op_value ) 926 len_format = calcsize(r_format) 927 928 raw_buff = self.__raw_buff[ i : i + 1 + len_format ] 929 930 jbc = JBC( class_manager, JAVA_OPCODES[ op_value ][0], raw_buff, ( r_function, v_function, r_buff, r_format, f_function ) ) 931 self.__bytecodes.append( jbc ) 932 933 i += len_format 934 else : 935 self.__bytecodes.append( JBC( class_manager, JAVA_OPCODES[ op_value ][0], self.__raw_buff[ i ] ) ) 936 else : 937 bytecode.Exit( "op_value 0x%x is unknown" % op_value ) 938 939 i += 1 940 941 # Create branch bytecodes list 942 idx = 0 943 nb = 0 944 for i in self.__bytecodes : 945 self.__maps.append( idx ) 946 947 if i.get_name() in BRANCH_JAVA_OPCODES : 948 self.__branches.append( nb ) 949 950 idx += i.get_length() 951 nb += 1
952
953 - def _patch_bytecodes(self) :
954 methods = [] 955 for i in self.__bytecodes : 956 if "invoke" in i.get_name() : 957 operands = i.get_operands() 958 methods.append( operands ) 959 op_value = INVERT_JAVA_OPCODES[ i.get_name() ] 960 raw_buff = pack( '>B', op_value ) 961 962 r_function, v_function, r_buff, r_format, f_function = EXTRACT_INFORMATION( op_value ) 963 964 new_class_index = self.__CM.create_class( operands[0] ) 965 new_name_and_type_index = self.__CM.create_name_and_type( operands[1], operands[2] ) 966 967 self.__CM.create_method_ref( new_class_index, new_name_and_type_index ) 968 969 value = getattr( self.__CM, JAVA_OPCODES[ op_value ][5] )( *operands[0:] ) 970 if value == -1 : 971 bytecode.Exit( "Unable to found method " + str(operands) ) 972 973 raw_buff += pack(r_format, *v_function( value ) ) 974 975 i.reload( raw_buff ) 976 elif "anewarray" in i.get_name() : 977 operands = i.get_operands() 978 op_value = INVERT_JAVA_OPCODES[ i.get_name() ] 979 raw_buff = pack( '>B', op_value ) 980 981 r_function, v_function, r_buff, r_format, f_function = EXTRACT_INFORMATION( op_value ) 982 983 new_class_index = self.__CM.create_class( operands[0] ) 984 985 raw_buff += pack(r_format, *v_function( new_class_index ) ) 986 987 i.reload( raw_buff ) 988 989 elif "getstatic" == i.get_name() : 990 operands = i.get_operands() 991 op_value = INVERT_JAVA_OPCODES[ i.get_name() ] 992 raw_buff = pack( '>B', op_value ) 993 994 r_function, v_function, r_buff, r_format, f_function = EXTRACT_INFORMATION( op_value ) 995 996 new_class_index = self.__CM.create_class( operands[0] ) 997 new_name_and_type_index = self.__CM.create_name_and_type( operands[1], operands[2] ) 998 999 self.__CM.create_field_ref( new_class_index, new_name_and_type_index ) 1000 1001 1002 value = getattr( self.__CM, JAVA_OPCODES[ op_value ][5] )( *operands[1:] ) 1003 if value == -1 : 1004 bytecode.Exit( "Unable to found method " + str(operands) ) 1005 1006 raw_buff += pack(r_format, *v_function( value ) ) 1007 1008 i.reload( raw_buff ) 1009 1010 elif "ldc" == i.get_name() : 1011 operands = i.get_operands() 1012 op_value = INVERT_JAVA_OPCODES[ i.get_name() ] 1013 raw_buff = pack( '>B', op_value ) 1014 1015 r_function, v_function, r_buff, r_format, f_function = EXTRACT_INFORMATION( op_value ) 1016 1017 if operands[0] != "CONSTANT_Integer" and operands[0] != "CONSTANT_String" : 1018 bytecode.Exit( "...." ) 1019 1020 if operands[0] == "CONSTANT_Integer" : 1021 new_int_index = self.__CM.create_integer( operands[1] ) 1022 raw_buff += pack(r_format, *v_function( new_int_index ) ) 1023 1024 elif operands[0] == "CONSTANT_String" : 1025 new_string_index = self.__CM.create_string( operands[1] ) 1026 1027 raw_buff += pack(r_format, *v_function( new_string_index ) ) 1028 1029 i.reload( raw_buff ) 1030 1031 elif "new" == i.get_name() : 1032 operands = i.get_operands() 1033 op_value = INVERT_JAVA_OPCODES[ i.get_name() ] 1034 raw_buff = pack( '>B', op_value ) 1035 1036 r_function, v_function, r_buff, r_format, f_function = EXTRACT_INFORMATION( op_value ) 1037 1038 new_class_index = self.__CM.create_class( operands[0] ) 1039 1040 raw_buff += pack(r_format, *v_function( new_class_index ) ) 1041 1042 i.reload( raw_buff ) 1043 1044 return methods
1045
1046 - def get(self) :
1047 return self.__bytecodes
1048
1049 - def get_raw(self) :
1050 return ''.join(x.get_raw() for x in self.__bytecodes)
1051
1052 - def show(self) :
1053 nb = 0 1054 print repr( self.__raw_buff ) 1055 for i in self.__bytecodes : 1056 print nb, self.__maps[nb], "\t", 1057 i.show( self.__maps[nb] ) 1058 nb += 1
1059
1060 - def get_at(self, idx) :
1061 return self.__bytecodes[ idx ]
1062
1063 - def remove_at(self, idx) :
1064 """Remove bytecode at a specific index""" 1065 val = self.__bytecodes[idx] 1066 val_m = self.__maps[idx] 1067 1068 # Remove the index if it's in our branch list 1069 if idx in self.__branches : 1070 self.__branches.remove( idx ) 1071 1072 # Adjust each branch 1073 for i in self.__branches : 1074 self.__bytecodes[i].adjust_r( self.__maps[i], val_m, val.get_length() ) 1075 1076 # Remove it ! 1077 self.__maps.pop(idx) 1078 self.__bytecodes.pop(idx) 1079 1080 # Adjust branch and map list 1081 self._adjust_maps( val_m, val.get_length() * -1 ) 1082 self._adjust_branches( idx, -1 ) 1083 1084 return val.get_length()
1085
1086 - def _adjust_maps(self, val, size) :
1087 nb = 0 1088 for i in self.__maps : 1089 if i > val : 1090 self.__maps[ nb ] = i + size 1091 nb = nb + 1
1092
1093 - def _adjust_maps_i(self, val, size) :
1094 nb = 0 1095 x = 0 1096 for i in self.__maps : 1097 if i == val : 1098 x+=1 1099 1100 if x == 2 : 1101 self.__maps[ nb ] = i + size 1102 1103 if i > val : 1104 self.__maps[ nb ] = i + size 1105 nb = nb + 1
1106
1107 - def _adjust_branches(self, val, size) :
1108 nb = 0 1109 for i in self.__branches : 1110 if i > val : 1111 self.__branches[ nb ] = i + size 1112 nb += 1
1113
1114 - def insert_at(self, idx, bytecode) :
1115 """Insert bytecode at a specific index""" 1116 1117 # Get the op_value and add it to the raw_buff 1118 op_name = bytecode[0] 1119 op_value = INVERT_JAVA_OPCODES[ op_name ] 1120 raw_buff = pack( '>B', op_value ) 1121 1122 new_jbc = None 1123 1124 # If it's an op_value with args, we must handle that ! 1125 if len( JAVA_OPCODES[ op_value ] ) > 1 : 1126 1127 # Find information about the op_value 1128 r_function, v_function, r_buff, r_format, f_function = EXTRACT_INFORMATION( op_value ) 1129 1130 # Special values for this op_value (advanced bytecode) 1131 if len( JAVA_OPCODES[ op_value ] ) == 6 : 1132 1133 1134 value = getattr( self.__CM, JAVA_OPCODES[ op_value ][5] )( *bytecode[1:] ) 1135 if value == -1 : 1136 bytecode.Exit( "Unable to found method ", str(bytecode[1:]) ) 1137 1138 raw_buff += pack(r_format, *v_function( value ) ) 1139 else : 1140 raw_buff += pack(r_format, *v_function( *bytecode[1:] ) ) 1141 1142 new_jbc = JBC(self.__CM, op_name, raw_buff, ( r_function, v_function, r_buff, r_format, f_function ) ) 1143 else : 1144 new_jbc = JBC(self.__CM, op_name, raw_buff) 1145 1146 # Adjust each branch with the new insertion 1147 val_m = self.__maps[ idx ] 1148 for i in self.__branches : 1149 self.__bytecodes[i].adjust_i( self.__maps[i], val_m, new_jbc.get_length() ) 1150 1151 # Insert the new bytecode at the correct index 1152 # Adjust maps + branches 1153 self.__bytecodes.insert( idx, new_jbc ) 1154 self.__maps.insert( idx, val_m ) 1155 self._adjust_maps_i( val_m, new_jbc.get_length() ) 1156 1157 self._adjust_branches( idx, 1 ) 1158 1159 # Add it to the branches if it's a correct op_value 1160 if new_jbc.get_name() in BRANCH_JAVA_OPCODES : 1161 self.__branches.append( idx ) 1162 1163 # return the length of the raw_buff 1164 return len(raw_buff)
1165
1166 - def remplace_at(self, idx, bytecode) :
1167 """Remplace bytecode at a specific index by another bytecode (remplace = remove + insert)""" 1168 size = self.remove_at(idx) * (-1) 1169 size += self.insert_at(idx, bytecode) 1170 1171 return size
1172
1173 - def set_cm(self, cm) :
1174 self.__CM = cm 1175 for i in self.__bytecodes : 1176 i.set_cm( cm )
1177
1178 -class BasicAttribute(object) :
1179 - def __init__(self) :
1180 self.__attributes = []
1181
1182 - def get_attributes(self) :
1183 return self.__attributes
1184
1185 - def set_cm(self, cm) :
1186 self.__CM = cm
1187
1188 -class CodeAttribute(BasicAttribute) :
1189 - def __init__(self, class_manager, buff) :
1190 self.__CM = class_manager 1191 1192 super(CodeAttribute, self).__init__() 1193 # u2 attribute_name_index; 1194 # u4 attribute_length; 1195 1196 # u2 max_stack; 1197 # u2 max_locals; 1198 # u4 code_length; 1199 # u1 code[code_length]; 1200 self.low_struct = SVs( CODE_LOW_STRUCT[0], CODE_LOW_STRUCT[1], buff.read( calcsize(CODE_LOW_STRUCT[0]) ) ) 1201 1202 self.__code = JavaCode( class_manager, buff.read( self.low_struct.get_value().code_length ) ) 1203 1204 # u2 exception_table_length; 1205 self.exception_table_length = SV( '>H', buff.read(2) ) 1206 1207 # { u2 start_pc; 1208 # u2 end_pc; 1209 # u2 handler_pc; 1210 # u2 catch_type; 1211 # } exception_table[exception_table_length]; 1212 self.__exception_table = [] 1213 for i in range(0, self.exception_table_length.get_value()) : 1214 et = SVs( EXCEPTION_TABLE[0], EXCEPTION_TABLE[1], buff.read( calcsize(EXCEPTION_TABLE[0]) ) ) 1215 self.__exception_table.append( et ) 1216 1217 # u2 attributes_count; 1218 self.attributes_count = SV( '>H', buff.read(2) ) 1219 1220 # attribute_info attributes[attributes_count]; 1221 self.__attributes = [] 1222 for i in range(0, self.attributes_count.get_value()) : 1223 ai = AttributeInfo( self.__CM, buff ) 1224 self.__attributes.append( ai )
1225
1226 - def get_attributes(self) :
1227 return self.__attributes
1228
1229 - def get_exceptions(self) :
1230 return self.__exception_table
1231
1232 - def get_raw(self) :
1233 return self.low_struct.get_value_buff() + \ 1234 self.__code.get_raw() + \ 1235 self.exception_table_length.get_value_buff() + \ 1236 ''.join(x.get_value_buff() for x in self.__exception_table) + \ 1237 self.attributes_count.get_value_buff() + \ 1238 ''.join(x.get_raw() for x in self.__attributes)
1239
1240 - def get_max_stack(self) :
1241 return self.low_struct.get_value().max_stack
1242
1243 - def get_max_locals(self) :
1244 return self.low_struct.get_value().max_locals
1245
1246 - def get_local_variables(self) :
1247 for i in self.__attributes : 1248 if i.get_name() == "StackMapTable" : 1249 return i.get_item().get_local_variables() 1250 return []
1251
1252 - def get_bc(self) :
1253 return self.__code
1254 1255 # FIXME : show* --> add exceptions
1256 - def show_info(self) :
1257 print "!" * 70 1258 print self.low_struct.get_value() 1259 bytecode._Print( "ATTRIBUTES_COUNT", self.attributes_count.get_value() ) 1260 for i in self.__attributes : 1261 i.show() 1262 print "!" * 70
1263
1264 - def show(self) :
1265 print "!" * 70 1266 print self.low_struct.get_value() 1267 self.__code.show() 1268 bytecode._Print( "ATTRIBUTES_COUNT", self.attributes_count.get_value() ) 1269 for i in self.__attributes : 1270 i.show() 1271 print "!" * 70
1272
1273 - def _patch_bytecodes(self) :
1274 return self.__code._patch_bytecodes()
1275
1276 - def remplace_at(self, idx, bytecode) :
1277 size = self.__code.remplace_at(idx, bytecode) 1278 1279 # Adjust the length of our bytecode 1280 self.low_struct.set_value( { "code_length" : self.low_struct.get_value().code_length + size } )
1281
1282 - def remove_at(self, idx) :
1283 size = self.__code.remove_at(idx) 1284 # Adjust the length of our bytecode 1285 self.low_struct.set_value( { "code_length" : self.low_struct.get_value().code_length - size } )
1286
1287 - def removes_at(self, l_idx) :
1288 i = 0 1289 while i < len(l_idx) : 1290 self.remove_at( l_idx[i] ) 1291 1292 j = i + 1 1293 while j < len(l_idx) : 1294 if l_idx[j] > l_idx[i] : 1295 l_idx[j] -= 1 1296 1297 j += 1 1298 1299 i += 1
1300
1301 - def insert_at(self, idx, bytecode) :
1302 size = self.__code.insert_at(idx, bytecode) 1303 # Adjust the length of our bytecode 1304 self.low_struct.set_value( { "code_length" : self.low_struct.get_value().code_length + size } )
1305
1306 - def get_at(self, idx) :
1307 return self.__code.get_at(idx)
1308
1309 - def gets_at(self, l_idx) :
1310 return [ self.__code.get_at(i) for i in l_idx ]
1311
1312 - def set_cm(self, cm) :
1313 self.__CM = cm 1314 for i in self.__attributes : 1315 i.set_cm( cm ) 1316 self.__code.set_cm( cm )
1317
1318 - def _fix_attributes(self, new_cm) :
1319 for i in self.__attributes : 1320 i._fix_attributes( new_cm )
1321
1322 -class SourceFileAttribute(BasicAttribute) :
1323 - def __init__(self, buff) :
1324 super(SourceFileAttribute, self).__init__() 1325 # u2 attribute_name_index; 1326 # u4 attribute_length; 1327 1328 # u2 sourcefile_index; 1329 self.sourcefile_index = SV( '>H', buff.read(2) )
1330
1331 - def get_raw(self) :
1332 return self.sourcefile_index.get_value_buff()
1333
1334 - def show(self) :
1335 print self.sourcefile_index
1336
1337 -class LineNumberTableAttribute(BasicAttribute) :
1338 - def __init__(self, buff) :
1339 super(LineNumberTableAttribute, self).__init__() 1340 # u2 attribute_name_index; 1341 # u4 attribute_length; 1342 1343 # u2 line_number_table_length; 1344 # { u2 start_pc; 1345 # u2 line_number; 1346 # } line_number_table[line_number_table_length]; 1347 1348 self.line_number_table_length = SV( '>H', buff.read( 2 ) ) 1349 1350 self.__line_number_table = [] 1351 for i in range(0, self.line_number_table_length.get_value()) : 1352 lnt = SVs( LINE_NUMBER_TABLE[0], LINE_NUMBER_TABLE[1], buff.read( 4 ) ) 1353 self.__line_number_table.append( lnt )
1354
1355 - def get_raw(self) :
1356 return self.line_number_table_length.get_value_buff() + \ 1357 ''.join(x.get_value_buff() for x in self.__line_number_table)
1358
1359 - def get_line_number_table(self) :
1360 return self.__line_number_table
1361
1362 - def show(self) :
1363 bytecode._Print("LINE_NUMBER_TABLE_LENGTH", self.line_number_table_length.get_value()) 1364 for x in self.__line_number_table : 1365 print "\t", x.get_value()
1366
1367 - def _fix_attributes(self, new_cm) :
1368 pass
1369
1370 -class LocalVariableTableAttribute(BasicAttribute) :
1371 - def __init__(self, buff) :
1372 super(LocalVariableTableAttribute, self).__init__() 1373 # u2 attribute_name_index; 1374 # u4 attribute_length; 1375 1376 # u2 local_variable_table_length; 1377 # { u2 start_pc; 1378 # u2 length; 1379 # u2 name_index; 1380 # u2 descriptor_index; 1381 # u2 index; 1382 # } local_variable_table[local_variable_table_length]; 1383 self.local_variable_table_length = SV( '>H', buff.read(2) ) 1384 1385 self.__local_variable_table = [] 1386 for i in range(0, self.local_variable_table_length.get_value()) : 1387 lvt = SVs( LOCAL_VARIABLE_TABLE[0], LOCAL_VARIABLE_TABLE[1], buff.read( 10 ) ) 1388 1389 self.__local_variable_table.append( lvt )
1390
1391 - def get_raw(self) :
1392 return self.local_variable_table_length.get_value_buff() + \ 1393 ''.join(x.get_value_buff() for x in self.__local_variable_table)
1394
1395 - def show(self) :
1396 print self.local_variable_table_length 1397 for x in self.__local_variable_table : 1398 print x.get_value()
1399
1400 -class ExceptionsAttribute(BasicAttribute) :
1401 - def __init__(self, buff) :
1402 super(ExceptionsAttribute, self).__init__() 1403 # u2 attribute_name_index; 1404 # u4 attribute_length; 1405 1406 # u2 number_of_exceptions; 1407 # u2 exception_index_table[number_of_exceptions]; 1408 self.number_of_exceptions = SV( '>H', buff.read(2) ) 1409 1410 self.__exception_index_table = [] 1411 for i in range(0, self.number_of_exceptions.get_value()) : 1412 self.__exception_index_table.append( SV( '>H', buff.read(2) ) )
1413
1414 - def get_raw(self) :
1415 return self.number_of_exceptions.get_value_buff() + ''.join(x.get_value_buff() for x in self.__exception_index_table)
1416
1417 - def get_exception_index_table(self) :
1418 return self.__exception_index_table
1419
1420 - def show(self) :
1421 print self.number_of_exceptions 1422 for i in self.__exception_index_table : 1423 print "\t", i
1424
1425 -class VerificationTypeInfo :
1426 - def __init__(self, class_manager, buff) :
1427 self.__CM = class_manager 1428 tag = SV( '>B', buff.read_b(1) ).get_value() 1429 1430 if tag not in VERIFICATION_TYPE_INFO : 1431 bytecode.Exit( "tag not in VERIFICATION_TYPE_INFO" ) 1432 1433 format = VERIFICATION_TYPE_INFO[ tag ][1] 1434 self.format = SVs( format, VERIFICATION_TYPE_INFO[ tag ][2], buff.read( calcsize( format ) ) )
1435
1436 - def get_raw(self) :
1437 return self.format.get_value_buff()
1438
1439 - def show(self) :
1440 general_format = self.format.get_value() 1441 if len( VERIFICATION_TYPE_INFO[ general_format.tag ] ) > 3 : 1442 print general_format, 1443 for (i,j) in VERIFICATION_TYPE_INFO[ general_format.tag ][3] : 1444 print getattr(self.__CM, j)( getattr(general_format, i) ) 1445 else : 1446 print general_format
1447
1448 - def _fix_attributes(self, new_cm) :
1449 general_format = self.format.get_value() 1450 1451 if len( VERIFICATION_TYPE_INFO[ general_format.tag ] ) > 3 : 1452 for (i,j) in VERIFICATION_TYPE_INFO[ general_format.tag ][3] : 1453 # Fix the first object which is the current class 1454 if getattr(self.__CM, j)( getattr(general_format, i) )[0] == self.__CM.get_this_class_name() : 1455 self.format.set_value( { "cpool_index" : new_cm.get_this_class() } ) 1456 # Fix other objects 1457 else : 1458 new_class_index = new_cm.create_class( getattr(self.__CM, j)( getattr(general_format, i) )[0] ) 1459 self.format.set_value( { "cpool_index" : new_class_index } )
1460
1461 - def set_cm(self, cm) :
1462 self.__CM = cm
1463
1464 -class FullFrame :
1465 - def __init__(self, class_manager, buff) :
1466 self.__CM = class_manager 1467 # u1 frame_type = FULL_FRAME; /* 255 */ 1468 # u2 offset_delta; 1469 # u2 number_of_locals; 1470 self.frame_type = SV( '>B', buff.read(1) ) 1471 self.offset_delta = SV( '>H', buff.read(2) ) 1472 self.number_of_locals = SV( '>H', buff.read(2) ) 1473 1474 # verification_type_info locals[number_of_locals]; 1475 self.__locals = [] 1476 for i in range(0, self.number_of_locals.get_value()) : 1477 self.__locals.append( VerificationTypeInfo( self.__CM, buff ) ) 1478 1479 # u2 number_of_stack_items; 1480 self.number_of_stack_items = SV( '>H', buff.read(2) ) 1481 # verification_type_info stack[number_of_stack_items]; 1482 self.__stack = [] 1483 for i in range(0, self.number_of_stack_items.get_value()) : 1484 self.__stack.append( VerificationTypeInfo( self.__CM, buff ) )
1485
1486 - def get_locals(self) :
1487 return self.__locals
1488
1489 - def get_raw(self) :
1490 return self.frame_type.get_value_buff() + \ 1491 self.offset_delta.get_value_buff() + \ 1492 self.number_of_locals.get_value_buff() + \ 1493 ''.join(x.get_raw() for x in self.__locals) + \ 1494 self.number_of_stack_items.get_value_buff() + \ 1495 ''.join(x.get_raw() for x in self.__stack)
1496
1497 - def show(self) :
1498 print "#" * 60 1499 bytecode._Print("\tFULL_FRAME", self.frame_type.get_value()) 1500 bytecode._Print("\tOFFSET_DELTA", self.offset_delta.get_value()) 1501 1502 bytecode._Print("\tNUMBER_OF_LOCALS", self.number_of_locals.get_value()) 1503 for i in self.__locals : 1504 i.show() 1505 1506 bytecode._Print("\tNUMBER_OF_STACK_ITEMS", self.number_of_stack_items.get_value()) 1507 for i in self.__stack : 1508 i.show() 1509 1510 print "#" * 60
1511
1512 - def _fix_attributes(self, new_cm) :
1513 for i in self.__locals : 1514 i._fix_attributes( new_cm )
1515
1516 - def set_cm(self, cm) :
1517 self.__CM = cm 1518 for i in self.__locals : 1519 i.set_cm( cm )
1520
1521 -class ChopFrame :
1522 - def __init__(self, buff) :
1523 # u1 frame_type=CHOP; /* 248-250 */ 1524 # u2 offset_delta; 1525 self.frame_type = SV( '>B', buff.read(1) ) 1526 self.offset_delta = SV( '>H', buff.read(2) )
1527
1528 - def get_raw(self) :
1529 return self.frame_type.get_value_buff() + self.offset_delta.get_value_buff()
1530
1531 - def show(self) :
1532 print "#" * 60 1533 bytecode._Print("\tCHOP_FRAME", self.frame_type.get_value()) 1534 bytecode._Print("\tOFFSET_DELTA", self.offset_delta.get_value()) 1535 print "#" * 60
1536
1537 - def _fix_attributes(self, cm) :
1538 pass
1539
1540 - def set_cm(self, cm) :
1541 pass
1542
1543 -class SameFrame :
1544 - def __init__(self, buff) :
1545 # u1 frame_type = SAME;/* 0-63 */ 1546 self.frame_type = SV( '>B', buff.read(1) )
1547
1548 - def get_raw(self) :
1549 return self.frame_type.get_value_buff()
1550
1551 - def show(self) :
1552 print "#" * 60 1553 bytecode._Print("\tSAME_FRAME", self.frame_type.get_value()) 1554 print "#" * 60
1555
1556 - def _fix_attributes(self, new_cm) :
1557 pass
1558
1559 - def set_cm(self, cm) :
1560 pass
1561
1562 - def show(self) :
1563 print "#" * 60 1564 bytecode._Print("\tSAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED", self.frame_type.get_value()) 1565 print "#" * 60
1566
1567 -class SameLocals1StackItemFrame :
1568 - def __init__(self, class_manager, buff) :
1569 self.__CM = class_manager 1570 # u1 frame_type = SAME_LOCALS_1_STACK_ITEM;/* 64-127 */ 1571 # verification_type_info stack[1]; 1572 self.frame_type = SV( '>B', buff.read(1) ) 1573 self.stack = VerificationTypeInfo( self.__CM, buff )
1574
1575 - def show(self) :
1576 print "#" * 60 1577 bytecode._Print("\tSAME_LOCALS_1_STACK_ITEM_FRAME", self.frame_type.get_value()) 1578 self.stack.show() 1579 print "#" * 60
1580
1581 - def get_raw(self) :
1582 return self.frame_type.get_value_buff() + self.stack.get_value_buff()
1583
1584 - def _fix_attributes(self, new_cm) :
1585 pass
1586
1587 - def set_cm(self, cm) :
1588 self.__CM = cm
1589
1590 -class SameLocals1StackItemFrameExtended :
1591 - def __init__(self, class_manager, buff) :
1592 self.__CM = class_manager 1593 # u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED; /* 247 */ 1594 # u2 offset_delta; 1595 # verification_type_info stack[1]; 1596 self.frame_type = SV( '>B', buff.read(1) ) 1597 self.offset_delta = SV( '>H', buff.read(2) ) 1598 self.stack = VerificationTypeInfo( self.__CM, buff )
1599
1600 - def get_raw(self) :
1601 return self.frame_type.get_value_buff() + self.offset_delta.get_value_buff() + self.stack.get_value_buff()
1602
1603 - def _fix_attributes(self, new_cm) :
1604 pass
1605
1606 - def set_cm(self, cm) :
1607 self.__CM = cm
1608
1609 - def show(self) :
1610 print "#" * 60 1611 bytecode._Print("\tSAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED", self.frame_type.get_value()) 1612 bytecode._Print("\tOFFSET_DELTA", self.offset_delta.get_value()) 1613 self.stack.show() 1614 print "#" * 60
1615
1616 -class SameFrameExtended :
1617 - def __init__(self, buff) :
1618 # u1 frame_type = SAME_FRAME_EXTENDED;/* 251*/ 1619 # u2 offset_delta; 1620 self.frame_type = SV( '>B', buff.read(1) ) 1621 self.offset_delta = SV( '>H', buff.read(2) )
1622
1623 - def get_raw(self) :
1624 return self.frame_type.get_value_buff() + self.offset_delta.get_value_buff()
1625
1626 - def _fix_attributes(self, cm) :
1627 pass
1628
1629 - def set_cm(self, cm) :
1630 pass
1631
1632 - def show(self) :
1633 print "#" * 60 1634 bytecode._Print("\tSAME_FRAME_EXTENDED", self.frame_type.get_value()) 1635 bytecode._Print("\tOFFSET_DELTA", self.offset_delta.get_value()) 1636 print "#" * 60
1637
1638 -class AppendFrame :
1639 - def __init__(self, class_manager, buff) :
1640 self.__CM = class_manager 1641 # u1 frame_type = APPEND; /* 252-254 */ 1642 # u2 offset_delta; 1643 self.frame_type = SV( '>B', buff.read(1) ) 1644 self.offset_delta = SV( '>H', buff.read(2) ) 1645 1646 # verification_type_info locals[frame_type -251]; 1647 self.__locals = [] 1648 k = self.frame_type.get_value() - 251 1649 for i in range(0, k) : 1650 self.__locals.append( VerificationTypeInfo( self.__CM, buff ) )
1651
1652 - def get_locals(self) :
1653 return self.__locals
1654
1655 - def show(self) :
1656 print "#" * 60 1657 bytecode._Print("\tAPPEND_FRAME", self.frame_type.get_value()) 1658 bytecode._Print("\tOFFSET_DELTA", self.offset_delta.get_value()) 1659 1660 for i in self.__locals : 1661 i.show() 1662 1663 print "#" * 60
1664
1665 - def get_raw(self) :
1666 return self.frame_type.get_value_buff() + \ 1667 self.offset_delta.get_value_buff() + \ 1668 ''.join(x.get_raw() for x in self.__locals)
1669
1670 - def _fix_attributes(self, new_cm) :
1671 for i in self.__locals : 1672 i._fix_attributes( new_cm )
1673
1674 - def set_cm(self, cm) :
1675 self.__CM = cm 1676 for i in self.__locals : 1677 i.set_cm( cm )
1678
1679 -class StackMapTableAttribute(BasicAttribute) :
1680 - def __init__(self, class_manager, buff) :
1681 self.__CM = class_manager 1682 1683 super(StackMapTableAttribute, self).__init__() 1684 # u2 attribute_name_index; 1685 # u4 attribute_length 1686 1687 # u2 number_of_entries; 1688 self.number_of_entries = SV( '>H', buff.read(2) ) 1689 1690 # stack_map_frame entries[number_of_entries]; 1691 self.__entries = [] 1692 for i in range(0, self.number_of_entries.get_value()) : 1693 frame_type = SV( '>B', buff.read_b(1) ).get_value() 1694 1695 if frame_type >= 0 and frame_type <= 63 : 1696 self.__entries.append( SameFrame( buff ) ) 1697 elif frame_type >= 64 and frame_type <= 127 : 1698 self.__entries.append( SameLocals1StackItemFrame( self.__CM, buff ) ) 1699 elif frame_type == 247 : 1700 self.__entries.append( SameLocals1StackItemFrameExtended( self.__CM, buff ) ) 1701 elif frame_type >= 248 and frame_type <= 250 : 1702 self.__entries.append( ChopFrame( buff ) ) 1703 elif frame_type == 251 : 1704 self.__entries.append( SameFrameExtended( buff ) ) 1705 elif frame_type >= 252 and frame_type <= 254 : 1706 self.__entries.append( AppendFrame( self.__CM, buff ) ) 1707 elif frame_type == 255 : 1708 self.__entries.append( FullFrame( self.__CM, buff ) ) 1709 else : 1710 bytecode.Exit( "Frame type %d is unknown" % frame_type )
1711
1712 - def get_entries(self) :
1713 return self.__entries
1714
1715 - def get_local_variables(self) :
1716 for i in self.__entries : 1717 if isinstance(i, FullFrame) : 1718 return i.get_local_variables() 1719 1720 return []
1721
1722 - def get_raw(self) :
1723 return self.number_of_entries.get_value_buff() + \ 1724 ''.join(x.get_raw() for x in self.__entries )
1725
1726 - def show(self) :
1727 bytecode._Print("NUMBER_OF_ENTRIES", self.number_of_entries.get_value()) 1728 for i in self.__entries : 1729 i.show()
1730
1731 - def _fix_attributes(self, new_cm) :
1732 for i in self.__entries : 1733 i._fix_attributes( new_cm )
1734
1735 - def set_cm(self, cm) :
1736 self.__CM = cm 1737 for i in self.__entries : 1738 i.set_cm( cm )
1739
1740 -class InnerClassesDesc :
1741 - def __init__(self, class_manager, buff) :
1742 INNER_CLASSES_FORMAT = [ ">BBBB", "inner_class_info_index outer_class_info_index inner_name_index inner_class_access_flags" ] 1743 1744 self.__CM = class_manager 1745 1746 self.__raw_buff = buff.read( calcsize( INNER_CLASSES_FORMAT[0] ) ) 1747 1748 self.format = SVs( INNER_CLASSES_FORMAT[0], namedtuple( "InnerClassesFormat", INNER_CLASSES_FORMAT[1] ), self.__raw_buff )
1749
1750 - def show(self) :
1751 print self.format
1752
1753 - def get_raw(self) :
1754 return self.format.get_value_buff()
1755
1756 - def set_cm(self, cm) :
1757 self.__CM = cm
1758
1759 -class InnerClassesAttribute(BasicAttribute) :
1760 - def __init__(self, class_manager, buff) :
1761 self.__CM = class_manager 1762 1763 super(InnerClassesAttribute, self).__init__() 1764 # u2 attribute_name_index; 1765 # u4 attribute_length 1766 1767 # u2 number_of_classes; 1768 self.number_of_classes = SV( '>H', buff.read(2) ) 1769 1770 # { u2 inner_class_info_index; 1771 # u2 outer_class_info_index; 1772 # u2 inner_name_index; 1773 # u2 inner_class_access_flags; 1774 # } classes[number_of_classes]; 1775 self.__classes = [] 1776 1777 for i in range(0, self.number_of_classes.get_value()) : 1778 self.__classes.append( InnerClassesDesc( self.__CM, buff ) )
1779
1780 - def get_classes(self) :
1781 return self.__classes
1782
1783 - def show(self) :
1784 print self.number_of_classes 1785 for i in self.__classes : 1786 i.show()
1787
1788 - def set_cm(self, cm) :
1789 self.__CM = cm 1790 for i in self.__classes : 1791 i.set_cm( cm )
1792
1793 - def get_raw(self) :
1794 return self.number_of_classes.get_value_buff + \ 1795 ''.join(x.get_raw() for x in self.__classes)
1796
1797 -class AttributeInfo :
1798 """AttributeInfo manages each attribute info (Code, SourceFile ....)"""
1799 - def __init__(self, class_manager, buff) :
1800 self.__CM = class_manager 1801 self.__raw_buff = buff.read( calcsize( ATTRIBUTE_INFO[0] ) ) 1802 1803 self.format = SVs( ATTRIBUTE_INFO[0], ATTRIBUTE_INFO[1], self.__raw_buff ) 1804 self.__name = self.__CM.get_string( self.format.get_value().attribute_name_index ) 1805 1806 if self.__name == "Code" : 1807 self.__info = CodeAttribute( self.__CM, buff ) 1808 elif self.__name == "SourceFile" : 1809 self.__info = SourceFileAttribute( buff ) 1810 elif self.__name == "Exceptions" : 1811 self.__info = ExceptionsAttribute( buff ) 1812 elif self.__name == "LineNumberTable" : 1813 self.__info = LineNumberTableAttribute( buff ) 1814 elif self.__name == "LocalVariableTable" : 1815 self.__info = LocalVariableTableAttribute( buff ) 1816 elif self.__name == "StackMapTable" : 1817 self.__info = StackMapTableAttribute( self.__CM, buff ) 1818 elif self.__name == "InnerClasses" : 1819 self.__info = InnerClassesAttribute( self.__CM, buff ) 1820 else : 1821 bytecode.Exit( "AttributeInfo %s doesn't exit" % self.__name )
1822
1823 - def get_item(self) :
1824 """Return the specific attribute info""" 1825 return self.__info
1826
1827 - def get_name(self) :
1828 """Return the name of the attribute""" 1829 return self.__name
1830
1831 - def get_raw(self) :
1832 v1 = self.format.get_value().attribute_length 1833 v2 = len(self.__info.get_raw()) 1834 if v1 != v2 : 1835 self.set_attribute_length( v2 ) 1836 1837 return self.format.get_value_buff() + self.__info.get_raw()
1838
1839 - def get_attribute_name_index(self) :
1840 return self.format.get_value().attribute_name_index
1841
1842 - def set_attribute_name_index(self, value) :
1843 self.format.set_value( { "attribute_name_index" : value } )
1844
1845 - def set_attribute_length(self, value) :
1846 self.format.set_value( { "attribute_length" : value } )
1847
1848 - def get_attributes(self) :
1849 return self.format
1850
1851 - def _fix_attributes(self, new_cm) :
1852 self.__info._fix_attributes( new_cm )
1853
1854 - def set_cm(self, cm) :
1855 self.__CM = cm 1856 self.__info.set_cm( cm )
1857
1858 - def show(self) :
1859 print self.format, self.__name 1860 if self.__info != None : 1861 self.__info.show()
1862
1863 -class ClassManager :
1864 """ClassManager can be used by all classes to get more information"""
1865 - def __init__(self, constant_pool, constant_pool_count) :
1866 self.__constant_pool = constant_pool 1867 self.__constant_pool_count = constant_pool_count 1868 1869 self.__this_class = None
1870
1871 - def get_value(self, idx) :
1872 name = self.get_item(idx[0]).get_name() 1873 if name == "CONSTANT_Integer" : 1874 return [ name, self.get_item(idx[0]).get_format().get_value().bytes ] 1875 elif name == "CONSTANT_String" : 1876 return [ name, self.get_string( self.get_item(idx[0]).get_format().get_value().string_index ) ] 1877 1878 bytecode.Exit( "get_value not yet implemented for %s" % name )
1879
1880 - def get_item(self, idx) :
1881 return self.__constant_pool[ idx - 1]
1882
1883 - def get_method(self, idx) :
1884 if self.get_item(idx).get_name() != "CONSTANT_Methodref" : 1885 return [] 1886 1887 class_idx = self.get_item(idx).get_class_index() 1888 name_and_type_idx = self.get_item(idx).get_name_and_type_index() 1889 1890 return [ self.get_string( self.get_item(class_idx).get_name_index() ), 1891 self.get_string( self.get_item(name_and_type_idx).get_name_index() ), 1892 self.get_string( self.get_item(name_and_type_idx).get_descriptor_index() ) 1893 ]
1894
1895 - def get_method_index(self, class_name, name, descriptor) :
1896 idx = 1 1897 for i in self.__constant_pool : 1898 res = self.get_method( idx ) 1899 if res != [] : 1900 m_class_name, m_name, m_descriptor = res 1901 if m_class_name == class_name and m_name == name and m_descriptor == descriptor : 1902 return idx 1903 idx += 1 1904 1905 return -1
1906
1907 - def get_field(self, idx) :
1908 if self.get_item(idx).get_name() != "CONSTANT_Fieldref" : 1909 return [] 1910 1911 class_idx = self.get_item(idx).get_class_index() 1912 name_and_type_idx = self.get_item(idx).get_name_and_type_index() 1913 1914 return [ self.get_string( self.get_item(class_idx).get_name_index() ), 1915 self.get_string( self.get_item(name_and_type_idx).get_name_index() ), 1916 self.get_string( self.get_item(name_and_type_idx).get_descriptor_index() ) 1917 ]
1918
1919 - def get_field_index(self, name, descriptor) :
1920 idx = 1 1921 for i in self.__constant_pool : 1922 res = self.get_field( idx ) 1923 if res != [] : 1924 _, m_name, m_descriptor = res 1925 if m_name == name and m_descriptor == descriptor : 1926 return idx 1927 idx += 1
1928
1929 - def get_class(self, idx):
1930 return [ self.get_string( self.get_item(idx).get_name_index() ) ]
1931
1932 - def get_array_type(self, idx) :
1933 return ARRAY_TYPE[ idx[0] ]
1934
1935 - def get_string_index(self, name) :
1936 idx = 1 1937 for i in self.__constant_pool : 1938 if i.get_name() == "CONSTANT_Utf8" : 1939 if i.get_bytes() == name : 1940 return idx 1941 idx += 1 1942 return -1
1943
1944 - def get_integer_index(self, value) :
1945 idx = 1 1946 for i in self.__constant_pool : 1947 if i.get_name() == "CONSTANT_Integer" : 1948 if i.get_format().get_value().bytes == value : 1949 return idx 1950 idx += 1 1951 return -1
1952
1953 - def get_cstring_index(self, value) :
1954 idx = 1 1955 for i in self.__constant_pool : 1956 if i.get_name() == "CONSTANT_String" : 1957 if self.get_string( i.get_format().get_value().string_index ) == value : 1958 return idx 1959 idx += 1 1960 return -1
1961
1962 - def get_name_and_type_index(self, name_method_index, descriptor_method_index) :
1963 idx = 1 1964 for i in self.__constant_pool : 1965 if i.get_name() == "CONSTANT_NameAndType" : 1966 value = i.get_format().get_value() 1967 if value.name_index == name_method_index and value.descriptor_index == descriptor_method_index : 1968 return idx 1969 idx += 1 1970 return -1
1971
1972 - def get_class_by_index(self, name_index) :
1973 idx = 1 1974 for i in self.__constant_pool : 1975 if i.get_name() == "CONSTANT_Class" : 1976 value = i.get_format().get_value() 1977 if value.name_index == name_index : 1978 return idx 1979 idx += 1 1980 return -1
1981
1982 - def get_method_ref_index(self, new_class_index, new_name_and_type_index) :
1983 idx = 1 1984 for i in self.__constant_pool : 1985 if i.get_name() == "CONSTANT_Methodref" : 1986 value = i.get_format().get_value() 1987 if value.class_index == new_class_index and value.name_and_type_index == new_name_and_type_index : 1988 return idx 1989 idx += 1 1990 return -1
1991
1992 - def get_field_ref_index(self, new_class_index, new_name_and_type_index) :
1993 idx = 1 1994 for i in self.__constant_pool : 1995 if i.get_name() == "CONSTANT_Fieldref" : 1996 value = i.get_format().get_value() 1997 if value.class_index == new_class_index and value.name_and_type_index == new_name_and_type_index : 1998 return idx 1999 idx += 1 2000 return -1
2001
2002 - def get_class_index(self, method_name) :
2003 idx = 1 2004 for i in self.__constant_pool : 2005 res = self.get_method( idx ) 2006 if res != [] : 2007 _, name, _ = res 2008 if name == method_name : 2009 return i.get_class_index() 2010 idx += 1 2011 return -1
2012
2013 - def get_string(self, idx) :
2014 if self.__constant_pool[idx - 1].get_name() == "CONSTANT_Utf8" : 2015 return self.__constant_pool[idx - 1].get_bytes() 2016 return None
2017
2018 - def set_string(self, idx, name) :
2019 if self.__constant_pool[idx - 1].get_name() == "CONSTANT_Utf8" : 2020 self.__constant_pool[idx - 1].set_bytes( name ) 2021 else : 2022 bytecode.Exit( "invalid index %d to set string %s" % (idx, name) )
2023
2024 - def add_string(self, name) :
2025 name_index = self.get_string_index(name) 2026 if name_index != -1 : 2027 return name_index 2028 2029 tag_value = INVERT_CONSTANT_INFO[ "CONSTANT_Utf8" ] 2030 buff = pack( CONSTANT_INFO[ tag_value ][1], tag_value, len(name) ) + pack( ">%ss" % len(name), name ) 2031 ci = CONSTANT_INFO[ tag_value ][-1]( self, bytecode.BuffHandle( buff ) ) 2032 2033 self.__constant_pool.append( ci ) 2034 self.__constant_pool_count.set_value( self.__constant_pool_count.get_value() + 1 ) 2035 2036 return self.__constant_pool_count.get_value() - 1
2037
2038 - def set_this_class(self, this_class) :
2039 self.__this_class = this_class
2040
2041 - def get_this_class(self) :
2042 return self.__this_class.get_value()
2043
2044 - def get_this_class_name(self) :
2045 return self.get_class( self.__this_class.get_value() )[0]
2046
2047 - def add_constant_pool(self, elem) :
2048 self.__constant_pool.append( elem ) 2049 self.__constant_pool_count.set_value( self.__constant_pool_count.get_value() + 1 )
2050
2051 - def get_constant_pool_count(self) :
2052 return self.__constant_pool_count.get_value()
2053
2054 - def create_class(self, name) :
2055 class_name_index = self.add_string( name ) 2056 return self._create_class( class_name_index )
2057
2058 - def _create_class(self, class_name_index) :
2059 class_index = self.get_class_by_index( class_name_index ) 2060 if class_index == -1 : 2061 new_class = CreateClass( self, class_name_index ) 2062 self.add_constant_pool( Class( self, bytecode.BuffHandle( new_class.get_raw() ) ) ) 2063 class_index = self.get_constant_pool_count() - 1 2064 return class_index
2065
2066 - def create_name_and_type(self, name, desc) :
2067 name_method_index = self.add_string( name ) 2068 descriptor_method_index = self.add_string( desc ) 2069 2070 return self._create_name_and_type( name_method_index, descriptor_method_index )
2071
2072 - def create_name_and_type_by_index(self, name_method_index, descriptor_method_index) :
2073 return self._create_name_and_type( name_method_index, descriptor_method_index )
2074
2075 - def _create_name_and_type(self, name_method_index, descriptor_method_index) :
2076 name_and_type_index = self.get_name_and_type_index( name_method_index, descriptor_method_index ) 2077 if name_and_type_index == -1 : 2078 new_nat = CreateNameAndType( self, name_method_index, descriptor_method_index ) 2079 self.add_constant_pool( NameAndType( self, bytecode.BuffHandle( new_nat.get_raw() ) ) ) 2080 name_and_type_index = self.get_constant_pool_count() - 1 2081 return name_and_type_index
2082
2083 - def create_method_ref(self, new_class_index, new_name_and_type_index) :
2084 new_mr_index = self.get_method_ref_index( new_class_index, new_name_and_type_index ) 2085 if new_mr_index == -1 : 2086 new_mr = CreateMethodRef( self, new_class_index, new_name_and_type_index ) 2087 self.add_constant_pool( MethodRef( self, bytecode.BuffHandle( new_mr.get_raw() ) ) ) 2088 new_mr_index = self.get_constant_pool_count() - 1 2089 return new_mr_index
2090
2091 - def create_field_ref(self, new_class_index, new_name_and_type_index) :
2092 new_fr_index = self.get_field_ref_index( new_class_index, new_name_and_type_index ) 2093 if new_fr_index == -1 : 2094 new_fr = CreateFieldRef( self, new_class_index, new_name_and_type_index ) 2095 self.add_constant_pool( FieldRef( self, bytecode.BuffHandle( new_mr.get_raw() ) ) ) 2096 new_fr_index = self.get_constant_pool_count() - 1 2097 return new_fr_index
2098
2099 - def create_integer(self, value) :
2100 new_int_index = self.get_integer_index( value ) 2101 if new_int_index == -1 : 2102 new_int = CreateInteger( value ) 2103 self.add_constant_pool( Integer( self, bytecode.BuffHandle( new_int.get_raw() ) ) ) 2104 new_int_index = self.get_constant_pool_count() - 1 2105 2106 return new_int_index
2107
2108 - def create_string(self, value) :
2109 new_string_index = self.get_cstring_index( value ) 2110 if new_string_index == -1 : 2111 new_string = CreateString( self, value ) 2112 self.add_constant_pool( String( self, bytecode.BuffHandle( new_string.get_raw() ) ) ) 2113 new_string_index = self.get_constant_pool_count() - 1 2114 return new_string_index
2115 2116
2117 -class JVMFormat(bytecode._Bytecode) :
2118 """An object which is the main class to handle properly a class file. 2119 Exported fields : magic, minor_version, major_version, constant_pool_count, access_flags, this_class, super_class, interfaces_count, fields_count, methods_count, attributes_count 2120 2121 @param buff : the buffer which represents the open file 2122 """
2123 - def __init__(self, buff) :
2124 super(JVMFormat, self).__init__( buff ) 2125 super(JVMFormat, self).register( bytecode.SHOW, self.show ) 2126 2127 self._load_class()
2128
2129 - def _load_class(self) :
2130 # u4 magic; 2131 # u2 minor_version; 2132 # u2 major_version; 2133 self.magic = SV( '>L', self.read( 4 ) ) 2134 self.minor_version = SV( '>H', self.read( 2 ) ) 2135 self.major_version = SV( '>H', self.read( 2 ) ) 2136 2137 # u2 constant_pool_count; 2138 self.constant_pool_count = SV( '>H', self.read( 2 ) ) 2139 2140 # cp_info constant_pool[constant_pool_count-1]; 2141 self.__constant_pool = [] 2142 self.__CM = ClassManager( self.__constant_pool, self.constant_pool_count ) 2143 for i in range(1, self.constant_pool_count.get_value()) : 2144 tag = SV( '>B', self.read_b( 1 ) ) 2145 2146 if tag.get_value() not in CONSTANT_INFO : 2147 bytecode.Exit( "tag not in CONSTANT_INFO" ) 2148 2149 ci = CONSTANT_INFO[ tag.get_value() ][-1]( self.__CM, self ) 2150 2151 self.__constant_pool.append( ci ) 2152 2153 2154 # u2 access_flags; 2155 # u2 this_class; 2156 # u2 super_class; 2157 self.access_flags = SV( '>H', self.read( 2 ) ) 2158 self.this_class = SV( '>H', self.read( 2 ) ) 2159 self.super_class = SV( '>H', self.read( 2 ) ) 2160 2161 2162 self.__CM.set_this_class( self.this_class ) 2163 2164 # u2 interfaces_count; 2165 self.interfaces_count = SV( '>H', self.read( 2 ) ) 2166 2167 #FIXME 2168 # u2 interfaces[interfaces_count]; 2169 self.__interfaces = [] 2170 for i in range(0, self.interfaces_count.get_value()) : 2171 tag = SV( '>H', self.read( 2 ) ) 2172 self.__interfaces.append( tag ) 2173 2174 2175 # u2 fields_count; 2176 self.fields_count = SV( '>H', self.read( 2 ) ) 2177 2178 # field_info fields[fields_count]; 2179 self.__fields = [] 2180 for i in range(0, self.fields_count.get_value()) : 2181 fi = FieldInfo( self.__CM, self ) 2182 2183 self.__fields.append( fi ) 2184 2185 # u2 methods_count; 2186 self.methods_count = SV( '>H', self.read( 2 ) ) 2187 2188 # method_info methods[methods_count]; 2189 self.__methods = [] 2190 for i in range(0, self.methods_count.get_value()) : 2191 mi = MethodInfo( self.__CM, self ) 2192 2193 self.__methods.append( mi ) 2194 2195 # u2 attributes_count; 2196 self.attributes_count = SV( '>H', self.read( 2 ) ) 2197 2198 # attribute_info attributes[attributes_count]; 2199 self.__attributes = [] 2200 for i in range(0, self.attributes_count.get_value()) : 2201 ai = AttributeInfo( self.__CM, self ) 2202 self.__attributes.append( ai )
2203
2204 - def get_field(self, name) :
2205 """Return into a list all fields which corresponds to the regexp 2206 2207 @param name : the name of the field (a regexp) 2208 """ 2209 prog = re.compile( name ) 2210 fields = [] 2211 for i in self.__fields : 2212 if prog.match( i.get_name() ) : 2213 fields.append( i ) 2214 return fields
2215
2216 - def get_method(self, name) :
2217 """Return into a list all methods which corresponds to the regexp 2218 2219 @param name : the name of the method (a regexp) 2220 """ 2221 prog = re.compile( name ) 2222 methods = [] 2223 for i in self.__methods : 2224 if prog.match( i.get_name() ) : 2225 methods.append( i ) 2226 return methods
2227
2228 - def get_fields(self) :
2229 """Return all objects fields""" 2230 return self.__fields
2231
2232 - def get_methods(self) :
2233 """Return all objects methods""" 2234 return self.__methods
2235
2236 - def get_constant_pool(self) :
2237 """Return the constant pool list""" 2238 return self.__constant_pool
2239
2240 - def get_strings(self) :
2241 """Return all strings into the class""" 2242 l = [] 2243 for i in self.__constant_pool : 2244 if i.get_name() == "CONSTANT_Utf8" : 2245 l.append( i.get_bytes() ) 2246 return l
2247
2248 - def get_class_manager(self) :
2249 """Return directly the class manager""" 2250 return self.__CM
2251
2252 - def show(self) :
2253 """Show the .class format into a human readable format""" 2254 bytecode._Print( "MAGIC", self.magic.get_value() ) 2255 bytecode._Print( "MINOR VERSION", self.minor_version.get_value() ) 2256 bytecode._Print( "MAJOR VERSION", self.major_version.get_value() ) 2257 bytecode._Print( "CONSTANT POOL COUNT", self.constant_pool_count.get_value() ) 2258 2259 nb = 0 2260 for i in self.__constant_pool : 2261 print nb, 2262 i.show() 2263 nb += 1 2264 2265 2266 bytecode._Print( "ACCESS FLAGS", self.access_flags.get_value() ) 2267 bytecode._Print( "THIS CLASS", self.this_class.get_value() ) 2268 bytecode._Print( "SUPER CLASS", self.super_class.get_value() ) 2269 2270 bytecode._Print( "INTERFACE COUNT", self.interfaces_count.get_value() ) 2271 nb = 0 2272 for i in self.__interfaces : 2273 print nb, 2274 i.show() 2275 2276 bytecode._Print( "FIELDS COUNT", self.fields_count.get_value() ) 2277 nb = 0 2278 for i in self.__fields : 2279 print nb, 2280 i.show() 2281 nb += 1 2282 2283 2284 bytecode._Print( "METHODS COUNT", self.methods_count.get_value() ) 2285 nb = 0 2286 for i in self.__methods : 2287 print nb, 2288 i.show() 2289 nb += 1 2290 2291 2292 bytecode._Print( "ATTRIBUTES COUNT", self.attributes_count.get_value() ) 2293 nb = 0 2294 for i in self.__attributes : 2295 print nb, 2296 i.show() 2297 nb += 1
2298
2299 - def insert_string(self, value) :
2300 """Insert a string into the constant pool list (Constant_Utf8) 2301 2302 @param value : the new string 2303 """ 2304 self.__CM.add_string( value )
2305
2306 - def insert_craft_method(self, name, proto, codes) :
2307 """Insert a craft method into the class 2308 2309 @param name : the name of the new method 2310 @param proto : a list which describe the method ( [ ACCESS_FLAGS, RETURN_TYPE, ARGUMENTS ], ie : [ "ACC_PUBLIC", "[B", "[B" ] ) 2311 @param codes : a list which represents the code into a human readable format ( [ "aconst_null" ], [ "areturn" ] ] ) 2312 """ 2313 # Create new method 2314 new_method = CreateMethodInfo(self.__CM, name, proto, codes) 2315 2316 # Insert the method by casting it directly into a MethodInfo with the raw buffer 2317 self._insert_basic_method( MethodInfo( self.__CM, bytecode.BuffHandle( new_method.get_raw() ) ) )
2318
2319 - def insert_direct_method(self, name, ref_method) :
2320 """Insert a direct method (MethodInfo Object) into the class 2321 2322 @param name : the name of the new method 2323 @param ref_method : the MethodInfo Object 2324 """ 2325 if ref_method == None : 2326 return 2327 2328 # Change the name_index 2329 name_index = self.__CM.get_string_index( name ) 2330 if name_index != -1 : 2331 bytecode.Exit( "method %s already exits" % name ) 2332 2333 name_index = self.__CM.add_string( name ) 2334 ref_method.set_name_index( name_index ) 2335 2336 # Change the descriptor_index 2337 descriptor_index = self.__CM.get_string_index( ref_method.get_descriptor() ) 2338 if descriptor_index == -1 : 2339 descriptor_index = self.__CM.add_string( ref_method.get_descriptor() ) 2340 ref_method.set_descriptor_index( descriptor_index ) 2341 2342 # Change attributes name index 2343 self._fix_attributes_external( ref_method ) 2344 2345 # Change internal index 2346 self._fix_attributes_internal( ref_method ) 2347 2348 # Insert the method 2349 self._insert_basic_method( ref_method )
2350
2351 - def _fix_attributes_external(self, ref_method) :
2352 for i in ref_method.get_attributes() : 2353 attribute_name_index = self.__CM.get_string_index( i.get_name() ) 2354 if attribute_name_index == -1 : 2355 bytecode.Exit( "attribute_name_index %s not present into the new constant pool" % i.get_name() ) 2356 2357 i.set_attribute_name_index( attribute_name_index ) 2358 2359 self._fix_attributes_external( i.get_item() )
2360
2361 - def _fix_attributes_internal(self, ref_method) :
2362 for i in ref_method.get_attributes() : 2363 attribute_name_index = self.__CM.get_string_index( i.get_name() ) 2364 if attribute_name_index == -1 : 2365 bytecode.Exit( "attribute_name_index %s not present into the new constant pool" % i.get_name() ) 2366 2367 i._fix_attributes( self.__CM ) 2368 2369 i.set_attribute_name_index( attribute_name_index )
2370
2371 - def _insert_basic_method(self, ref_method) :
2372 # Add a MethodRef and a NameAndType 2373 name_and_type_index = self.__CM.create_name_and_type_by_index( ref_method.get_name_index(), ref_method.get_descriptor_index() ) 2374 2375 self.__CM.create_method_ref( self.__CM.get_this_class(), name_and_type_index ) 2376 2377 # Change the class manager 2378 ref_method.set_cm( self.__CM ) 2379 2380 # Insert libraries/constants dependances 2381 methods = ref_method._patch_bytecodes() 2382 2383 # FIXME : insert needed fields + methods 2384 prog = re.compile( "^java*" ) 2385 for i in methods : 2386 if prog.match( i[0] ) == None : 2387 bytecode.Exit( "ooooops" ) 2388 2389 2390 #ref_method.show() 2391 2392 # Insert the method 2393 self.__methods.append( ref_method ) 2394 self.methods_count.set_value( self.methods_count.get_value() + 1 )
2395
2396 - def _get_raw(self) :
2397 # u4 magic; 2398 # u2 minor_version; 2399 # u2 major_version; 2400 buff = self.magic.get_value_buff() 2401 buff += self.minor_version.get_value_buff() 2402 buff += self.major_version.get_value_buff() 2403 2404 # u2 constant_pool_count; 2405 buff += self.constant_pool_count.get_value_buff() 2406 2407 # cp_info constant_pool[constant_pool_count-1]; 2408 for i in self.__constant_pool : 2409 buff += i.get_raw() 2410 2411 # u2 access_flags; 2412 # u2 this_class; 2413 # u2 super_class; 2414 buff += self.access_flags.get_value_buff() 2415 buff += self.this_class.get_value_buff() 2416 buff += self.super_class.get_value_buff() 2417 2418 # u2 interfaces_count; 2419 buff += self.interfaces_count.get_value_buff() 2420 2421 # u2 interfaces[interfaces_count]; 2422 for i in self.__interfaces : 2423 buff += i.get_value_buff() 2424 2425 # u2 fields_count; 2426 buff += self.fields_count.get_value_buff() 2427 2428 # field_info fields[fields_count]; 2429 for i in self.__fields : 2430 buff += i.get_raw() 2431 2432 # u2 methods_count; 2433 buff += self.methods_count.get_value_buff() 2434 2435 # method_info methods[methods_count]; 2436 for i in self.__methods : 2437 buff += i.get_raw() 2438 2439 # u2 attributes_count; 2440 buff += self.attributes_count.get_value_buff() 2441 2442 # attribute_info attributes[attributes_count]; 2443 for i in self.__attributes : 2444 buff += i.get_raw() 2445 2446 return buff
2447
2448 - def save(self) :
2449 """Return the class (with the modifications) into raw format 2450 2451 @rtype: string 2452 """ 2453 return self._get_raw()
2454