1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import re, random, string, cPickle
20
21 from error import error, warning
22 import jvm, dvm
23 from api_permissions import DVM_PERMISSIONS_BY_PERMISSION, DVM_PERMISSIONS_BY_ELEMENT
24
26 - def __init__(self, mode) :
27 self.mode = mode
28 self.details = []
29
30 - def set_details(self, details) :
31 for i in details :
32 self.details.append( i )
33
35 - def __init__(self) :
37
38 - def set_details(self, details) :
39 for i in details :
40 self.details.append( i )
41
43 - def __init__(self, class_name, name, descriptor) :
44 self.class_name = class_name
45 self.name = name
46 self.descriptor = descriptor
47
49 return self.class_name
50
53
55 return self.descriptor
56
59 self.__tab = tab
60 self.__re_tab = {}
61
62 for i in self.__tab :
63 self.__re_tab[i] = []
64 for j in self.__tab[i] :
65 self.__re_tab[i].append( re.compile( j ) )
66
67 self.__string = ""
68
69 - def push(self, name) :
70 for i in self.__tab :
71 for j in self.__re_tab[i] :
72 if j.match(name) != None :
73 if len(self.__string) > 0 :
74 if i == 'O' and self.__string[-1] == 'O' :
75 continue
76 self.__string += i
77
80
83 self._vm = _vm
84 self._start = idx
85 self._end = self._start
86
87 self._ins = []
88
89 self._ops = []
90
91 self._fields = {}
92 self._methods = {}
93
94
97
100
103
104 - def push(self, ins) :
105 self._ins.append(ins)
106 self._end += ins.get_length()
107
110
113
115 for i in self._ins :
116 print "\t\t",
117 i.show(0)
118
119
120
121 MATH_DVM_RE = []
122 for i in dvm.MATH_DVM_OPCODES :
123 MATH_DVM_RE.append( (re.compile( i ), dvm.MATH_DVM_OPCODES[i]) )
124
125 DVM_TOSTRING = { "O" : dvm.MATH_DVM_OPCODES.keys(),
126 "I" : dvm.INVOKE_DVM_OPCODES,
127 "G" : dvm.FIELD_READ_DVM_OPCODES,
128 "P" : dvm.FIELD_WRITE_DVM_OPCODES,
129 }
130
134
136 for i in self._ins :
137 for mre in MATH_DVM_RE :
138 if mre[0].match( i.get_name() ) :
139 self._ops.append( mre[1] )
140 break
141
142
143 FIELDS = {
144 "getfield" : "R",
145 "getstatic" : "R",
146 "putfield" : "W",
147 "putstatic" : "W",
148 }
149
150 METHODS = [ "invokestatic", "invokevirtual", "invokespecial" ]
151
152 JVM_TOSTRING = { "O" : jvm.MATH_JVM_OPCODES.keys(),
153 "I" : jvm.INVOKE_JVM_OPCODES,
154 "G" : jvm.FIELD_READ_JVM_OPCODES,
155 "P" : jvm.FIELD_WRITE_JVM_OPCODES,
156 }
157
158 BREAK_JVM_OPCODES_RE = []
159 for i in jvm.BREAK_JVM_OPCODES :
160 BREAK_JVM_OPCODES_RE.append( re.compile( i ) )
161
165
168
169 - def push(self, elem) :
170 self.__elems.append( elem )
171
173 return self.__elems[-1]
174
176 return self.__elems.pop(-1)
177
179 return len(self.__elems) == 0
180
182 if elems != self.__elems :
183 for i in elems :
184 self.__elems.insert(idx, i)
185 idx += 1
186
188 nb = 0
189
190 if len(self.__elems) == 0 :
191 print "\t--> nil"
192
193 for i in self.__elems :
194 print "\t-->", nb, ": ", i
195 nb += 1
196
200
201 - def save(self, idx, i_idx, ins, stack_pickle, msg_pickle) :
202 self.__elems.append( (idx, i_idx, ins, stack_pickle, msg_pickle) )
203
205 for i in self.__elems :
206 yield (i[0], i[1], i[2], cPickle.loads( i[3] ), cPickle.loads( i[4] ) )
207
209 for i in self.__elems :
210 print i[0], i[1], i[2].get_name()
211
212 cPickle.loads( i[3] ).show()
213 print "\t", cPickle.loads( i[4] )
214
216 value = "OBJ_REF_@_%s" % str(special)
217 stack.push( value )
218
220 stack.push( "VARIABLE_LOCAL_%d" % special )
221
224
227
231
233 value = ""
234
235 if special[0] == 1 :
236 value += special[1] + "(" + str( res.pop() ) + ") "
237 else :
238 for i in range(0, special[0]) :
239 value += str( res.pop() ) + special[1]
240
241 value = value[:-1]
242
243 stack.push( value )
244
248
250 stack.push( special )
251
253 stack.push( special )
254
255 -def putfield(_vm, ins, special, stack, res, ret_v) :
257
258 -def putstatic(_vm, ins, special, stack, res, ret_v) :
260
261 -def getfield(_vm, ins, special, stack, res, ret_v) :
264
265 -def getstatic(_vm, ins, special, stack, res, ret_v) :
266 stack.push( "FIELD_STATIC" )
267
268 -def new(_vm, ins, special, stack, res, ret_v) :
269 stack.push( "NEW_OBJ" )
270
271 -def dup(_vm, ins, special, stack, res, ret_v) :
272 l = []
273
274 for i in range(0, special+1) :
275 l.append( stack.pop() )
276 l.reverse()
277
278 l.insert( 0, l[-1] )
279 for i in l :
280 stack.push( i )
281
282 -def dup2(_vm, ins, special, stack, res, ret_v) :
283 l = []
284
285 for i in range(0, special+1) :
286 l.append( stack.pop() )
287 l.reverse()
288
289 l.insert( 0, l[-1] )
290 l.insert( 1, l[-2] )
291 for i in l :
292 stack.push( i )
293
294
295 -def ldc(_vm, ins, special, stack, res, ret_v) :
296
297 stack.push( "STRING" )
298
299 -def invoke(_vm, ins, special, stack, res, ret_v) :
300 desc = ins.get_operands()[-1]
301 param = desc[1:desc.find(")")]
302 ret = desc[desc.find(")")+1:]
303
304
305
306 for i in range(0, calc_nb( param )) :
307 stack.pop()
308
309
310 for i in range(0, special) :
311 stack.pop()
312
313 for i in range(0, calc_nb( ret )):
314 stack.push( "E" )
315
317 ret_v.add_msg( "SET VALUE %s %s @ ARRAY REF %s %s" % (special, str(stack.pop()), str(stack.pop()), str(stack.pop())) )
318
320 ret_v.add_msg( "SET OBJECT REF %d --> %s" % (special, str(stack.pop())) )
321
324
325 -def swap(_vm, ins, special, stack, res, ret_v) :
326 l = stack.pop()
327 l2 = stack.pop()
328
329 stack.push(l2)
330 stack.push(l)
331
333 if info == "" or info == "V" :
334 return 0
335
336 if ";" in info :
337 n = 0
338 for i in info.split(";") :
339 if i != "" :
340 n += 1
341 return n
342 else :
343 return len(info) - info.count('[')
344
345 INSTRUCTIONS_ACTIONS = {
346 "aaload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
347 "aastore" : [ { set_arrayref : None } ],
348 "aconst_null" : [ { push_objectref : "null" } ],
349 "aload" : [ { push_objectref_l_i : None } ],
350 "aload_0" : [ { push_objectref_l : 0 } ],
351 "aload_1" : [ { push_objectref_l : 1 } ],
352 "aload_2" : [ { push_objectref_l : 2 } ],
353 "aload_3" : [ { push_objectref_l : 3 } ],
354 "anewarray" : [ { pop_objectref : None }, { push_objectref : [ 1, "ANEWARRAY" ] } ],
355 "areturn" : [ { pop_objectref : None } ],
356 "arraylength" : [ { pop_objectref : None }, { push_objectres : [ 1, 'LENGTH' ] } ],
357 "astore" : [ { set_objectref_i : None } ],
358 "astore_0" : [ { set_objectref : 0 } ],
359 "astore_1" : [ { set_objectref : 1 } ],
360 "astore_2" : [ { set_objectref : 2 } ],
361 "astore_3" : [ { set_objectref : 3 } ],
362 "athrow" : [ { pop_objectref : None }, { push_objectres : [ 1, "throw" ] } ],
363 "baload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
364 "bastore" : [ { set_arrayref : "byte" } ],
365 "bipush" : [ { push_integer_i : None } ],
366 "caload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
367 "castore" : [ { set_arrayref : "char" } ],
368 "checkcast" : [ { pop_objectref : None }, { push_objectres : [ 1, "checkcast" ] } ],
369 "d2f" : [ { pop_objectref : None }, { push_objectres : [ 1, 'float' ] } ],
370 "d2i" : [ { pop_objectref : None }, { push_objectres : [ 1, 'integer' ] } ],
371 "d2l" : [ { pop_objectref : None }, { push_objectres : [ 1, 'long' ] } ],
372 "dadd" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '+' ] } ],
373 "daload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
374 "dastore" : [ { set_arrayref : "double" } ],
375 "dcmpg" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
376 "dcmpl" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
377 "dconst_0" : [ { push_float_d : 0.0 } ],
378 "dconst_1" : [ { push_float_d : 1.0 } ],
379 "ddiv" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '&' ] } ],
380 "dload" : [ { push_objectref_l_i : None } ],
381 "dload_0" : [ { push_objectref_l : 0 } ],
382 "dload_1" : [ { push_objectref_l : 1 } ],
383 "dload_2" : [ { push_objectref_l : 2 } ],
384 "dload_3" : [ { push_objectref_l : 3 } ],
385 "dmul" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '*' ] } ],
386 "dneg" : [ { pop_objectref : None }, { push_objectres : [ 1, '-' ] } ],
387 "drem" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, 'rem' ] } ],
388 "dreturn" : [ { pop_objectref : None } ],
389 "dstore" : [ { set_objectref_i : None } ],
390 "dstore_0" : [ { set_objectref : 0 } ],
391 "dstore_1" : [ { set_objectref : 1 } ],
392 "dstore_2" : [ { set_objectref : 2 } ],
393 "dstore_3" : [ { set_objectref : 3 } ],
394 "dsub" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '-' ] } ],
395 "dup" : [ { dup : 0 } ],
396 "dup_x1" : [ { dup : 1 } ],
397 "dup_x2" : [ { dup : 2 } ],
398 "dup2" : [ { dup2 : 0 } ],
399 "dup2_x1" : [ { dup2 : 1 } ],
400 "dup2_x2" : [ { dup2 : 2 } ],
401 "f2d" : [ { pop_objectref : None }, { push_objectres : [ 1, 'double' ] } ],
402 "f2i" : [ { pop_objectref : None }, { push_objectres : [ 1, 'integer' ] } ],
403 "f2l" : [ { pop_objectref : None }, { push_objectres : [ 1, 'long' ] } ],
404 "fadd" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '+' ] } ],
405 "faload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
406 "fastore" : [ { set_arrayref : "float" } ],
407 "fcmpg" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
408 "fcmpl" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
409 "fconst_0" : [ { push_float_d : 0.0 } ],
410 "fconst_1" : [ { push_float_d : 1.0 } ],
411 "fconst_2" : [ { push_float_d : 2.0 } ],
412 "fdiv" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '&' ] } ],
413 "fload" : [ { push_objectref_l_i : None } ],
414 "fload_0" : [ { push_objectref_l : 0 } ],
415 "fload_1" : [ { push_objectref_l : 1 } ],
416 "fload_2" : [ { push_objectref_l : 2 } ],
417 "fload_3" : [ { push_objectref_l : 3 } ],
418 "fmul" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '*' ] } ],
419 "fneg" : [ { pop_objectref : None }, { push_objectres : [ 1, '-' ] } ],
420 "freturn" : [ { pop_objectref : None } ],
421 "fstore" : [ { set_objectref_i : None } ],
422 "fstore_0" : [ { set_objectref : 0 } ],
423 "fstore_1" : [ { set_objectref : 1 } ],
424 "fstore_2" : [ { set_objectref : 2 } ],
425 "fstore_3" : [ { set_objectref : 3 } ],
426 "fsub" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '-' ] } ],
427 "getfield" : [ { getfield : None } ],
428 "getstatic" : [ { getstatic : None } ],
429 "goto" : [ {} ],
430 "goto_w" : [ {} ],
431 "i2b" : [ { pop_objectref : None }, { push_objectres : [ 1, 'byte' ] } ],
432 "i2c" : [ { pop_objectref : None }, { push_objectres : [ 1, 'char' ] } ],
433 "i2d" : [ { pop_objectref : None }, { push_objectres : [ 1, 'double' ] } ],
434 "i2f" : [ { pop_objectref : None }, { push_objectres : [ 1, 'float' ] } ],
435 "i2l" : [ { pop_objectref : None }, { push_objectres : [ 1, 'long' ] } ],
436 "i2s" : [ { pop_objectref : None }, { push_objectres : [ 1, 'string' ] } ],
437 "iadd" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '+' ] } ],
438 "iaload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
439 "iand" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '&' ] } ],
440 "iastore" : [ { set_arrayref : "int" } ],
441 "iconst_m1" : [ { push_integer_d : -1 } ],
442 "iconst_0" : [ { push_integer_d : 0 } ],
443 "iconst_1" : [ { push_integer_d : 1 } ],
444 "iconst_2" : [ { push_integer_d : 2 } ],
445 "iconst_3" : [ { push_integer_d : 3 } ],
446 "iconst_4" : [ { push_integer_d : 4 } ],
447 "iconst_5" : [ { push_integer_d : 5 } ],
448 "idiv" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '/' ] } ],
449 "if_acmpeq" : [ { pop_objectref : None }, { pop_objectref : None } ],
450 "if_acmpne" : [ { pop_objectref : None }, { pop_objectref : None } ],
451 "if_icmpeq" : [ { pop_objectref : None }, { pop_objectref : None } ],
452 "if_icmpne" : [ { pop_objectref : None }, { pop_objectref : None } ],
453 "if_icmplt" : [ { pop_objectref : None }, { pop_objectref : None } ],
454 "if_icmpge" : [ { pop_objectref : None }, { pop_objectref : None } ],
455 "if_icmpgt" : [ { pop_objectref : None }, { pop_objectref : None } ],
456 "if_icmple" : [ { pop_objectref : None }, { pop_objectref : None } ],
457 "ifeq" : [ { pop_objectref : None } ],
458 "ifne" : [ { pop_objectref : None } ],
459 "iflt" : [ { pop_objectref : None } ],
460 "ifge" : [ { pop_objectref : None } ],
461 "ifgt" : [ { pop_objectref : None } ],
462 "ifle" : [ { pop_objectref : None } ],
463 "ifnonnull" : [ { pop_objectref : None } ],
464 "ifnull" : [ { pop_objectref : None } ],
465 "iinc" : [ {} ],
466 "iload" : [ { push_objectref_l_i : None } ],
467 "iload_1" : [ { push_objectref_l : 1 } ],
468 "iload_2" : [ { push_objectref_l : 2 } ],
469 "iload_3" : [ { push_objectref_l : 3 } ],
470 "imul" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '*' ] } ],
471 "ineg" : [ { pop_objectref : None }, { push_objectres : [ 1, '-' ] } ],
472 "instanceof" : [ { pop_objectref : None }, { push_objectres : [ 1, 'instanceof' ] } ],
473 "invokeinterface" : [ { invoke : 1 } ],
474 "invokespecial" : [ { invoke : 1 } ],
475 "invokestatic" : [ { invoke : 0 } ],
476 "invokevirtual": [ { invoke : 1 } ],
477 "ior" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '|' ] } ],
478 "irem" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, 'REM' ] } ],
479 "ireturn" : [ { pop_objectref : None } ],
480 "ishl" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '<<' ] } ],
481 "ishr" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '>>' ] } ],
482 "istore" : [ { set_objectref_i : None } ],
483 "istore_0" : [ { set_objectref : 0 } ],
484 "istore_1" : [ { set_objectref : 1 } ],
485 "istore_2" : [ { set_objectref : 2 } ],
486 "istore_3" : [ { set_objectref : 3 } ],
487 "isub" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '-' ] } ],
488 "iushr" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '>>' ] } ],
489 "ixor" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '^' ] } ],
490 "jsr" : [ { push_integer_i : None } ],
491 "jsr_w" : [ { push_integer_i : None } ],
492 "l2d" : [ { pop_objectref : None }, { push_objectres : [ 1, 'double' ] } ],
493 "l2f" : [ { pop_objectref : None }, { push_objectres : [ 1, 'float' ] } ],
494 "l2i" : [ { pop_objectref : None }, { push_objectres : [ 1, 'integer' ] } ],
495 "ladd" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '+' ] } ],
496 "laload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
497 "land" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '&' ] } ],
498 "lastore" : [ { set_arrayref : "long" } ],
499 "lcmp" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
500 "lconst_0" : [ { push_float_d : 0.0 } ],
501 "lconst_1" : [ { push_float_d : 1.0 } ],
502 "ldc" : [ { ldc : None } ],
503 "ldc_w" : [ { ldc : None } ],
504 "ldc2_w" : [ { ldc : None } ],
505 "ldiv" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '/' ] } ],
506 "lload" : [ { push_objectref_l_i : None } ],
507 "lload_0" : [ { push_objectref_l : 0 } ],
508 "lload_1" : [ { push_objectref_l : 1 } ],
509 "lload_2" : [ { push_objectref_l : 2 } ],
510 "lload_3" : [ { push_objectref_l : 3 } ],
511 "lmul" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '*' ] } ],
512 "lneg" : [ { pop_objectref : None }, { push_objectres : [ 1, '-' ] } ],
513 "lookupswitch" : [ { pop_objectref : None } ],
514 "lor" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '|' ] } ],
515 "lrem" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, 'REM' ] } ],
516 "lreturn" : [ { pop_objectref : None } ],
517 "lshl" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '<<' ] } ],
518 "lshr" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '>>' ] } ],
519 "lstore" : [ { set_objectref_i : None } ],
520 "lstore_0" : [ { set_objectref : 0 } ],
521 "lstore_1" : [ { set_objectref : 1 } ],
522 "lstore_2" : [ { set_objectref : 2 } ],
523 "lstore_3" : [ { set_objectref : 3 } ],
524 "lsub" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '-' ] } ],
525 "lushr" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '>>' ] } ],
526 "lxor" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '^' ] } ],
527 "monitorenter" : [ { pop_objectref : None } ],
528 "monitorexit" : [ { pop_objectref : None } ],
529 "multianewarray" : [ { multi_pop_objectref_i : None }, { push_objectref : 0 } ],
530 "new" : [ { new : None } ],
531 "newarray" : [ { pop_objectref : None }, { push_objectref : [ 1, "NEWARRAY" ] } ],
532 "nop" : [ {} ],
533 "pop" : [ { pop_objectref : None } ],
534 "pop2" : [ { pop_objectref : None }, { pop_objectref : None } ],
535 "putfield" : [ { putfield : None }, { pop_objectref : None } ],
536 "putstatic" : [ { putstatic : None } ],
537 "ret" : [ {} ],
538 "return" : [ {} ],
539 "saload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
540 "sastore" : [ { set_arrayref : "short" } ],
541 "sipush" : [ { push_integer_i : None } ],
542 "swap" : [ { swap : None } ],
543 "tableswitch" : [ { pop_objectref : None } ],
544 "wide" : [ {} ],
545 }
546
547
550 self.__elems = []
551 self.__msgs = []
552
554 self.__msgs.append( e )
555
557 self.__elems.append( e )
558
561
564
566 - def __init__(self, class_name, name, descriptor) :
567 self.__class_name = class_name
568 self.__name = name
569 self.__descriptor = descriptor
570
572 return "M@[%s][%s]-[%s]" % (self.__class_name, self.__name, self.__descriptor)
573
576
578 - def __init__(self, start, _vm, _method, _context) :
579 self.__vm = _vm
580 self.__method = _method
581 self.__context = _context
582
583 self.__stack = Stack()
584 self.stack_traces = StackTraces()
585
586 self.ins = []
587
588 self.fathers = []
589 self.childs = []
590
591 self.start = start
592 self.end = self.start
593
594 self.break_blocks = []
595
596 self.free_blocks_offsets = []
597
598 self.name = "%s-BB@0x%x" % (self.__method.get_name(), self.start)
599
601 return self.__stack.gets()
602
605
608
611
614
617
618 - def push(self, i) :
621
623 self.fathers.append( f )
624
626
627 if values == [] :
628 next_block = self.__context.get_basic_block( self.end + 1 )
629 if next_block != None :
630 self.childs.append( ( self.end - self.ins[-1].get_length(), self.end, next_block ) )
631 else :
632 for i in values :
633
634 if i != -1 :
635 self.childs.append( ( self.end - self.ins[-1].get_length(), i, self.__context.get_basic_block( i ) ) )
636
637 for c in self.childs :
638 if c[2] != None :
639 c[2].set_fathers( ( c[1], c[0], self ) )
640
642 last = -1
643
644
645
646 if self.free_blocks_offsets == [] :
647 return -1
648
649 for i in self.free_blocks_offsets :
650 if i <= idx :
651 last = i
652 else :
653 return last
654
655 return last
656
658 return self.free_blocks_offsets[ random.randint(0, len(self.free_blocks_offsets) - 1) ]
659
661
662 for i in self.free_blocks_offsets :
663 if i > idx :
664 return i
665 return -1
666
668 return self.free_blocks_offsets[ random.randint(0, len(self.free_blocks_offsets) - 1) ]
669
671 return self.break_blocks[ random.randint(0, len(self.break_blocks) - 1) ]
672
674 for i in self.break_blocks :
675 if idx >= i.get_start() and idx <= i.get_end() :
676 return i
677 return None
678
680 idx = self.get_start()
681
682 current_break = JVMBreakBlock( self.__vm, idx )
683 self.break_blocks.append(current_break)
684 for i in self.ins :
685 name = i.get_name()
686
687
688 match = False
689 for j in BREAK_JVM_OPCODES_RE :
690 if j.match(name) != None :
691 match = True
692 break
693
694 current_break.push( i )
695 if match == True :
696 current_break.analyze()
697 current_break = JVMBreakBlock( self.__vm, current_break.get_end() )
698
699 self.break_blocks.append( current_break )
700
701
702 idx += i.get_length()
703
705 idx = 0
706 for i in self.ins :
707
708 if "load" in i.get_name() or "store" in i.get_name() :
709 action = i.get_name()
710
711 access_flag = [ "R", "load" ]
712 if "store" in action :
713 access_flag = [ "W", "store" ]
714
715 if "_" in action :
716 name = i.get_name().split(access_flag[1])
717 value = name[1][-1]
718 else :
719 value = i.get_operands()
720
721 variable_name = "%s-%s" % (i.get_name()[0], value)
722
723 self.__context.get_tainted_variables().add( variable_name, TAINTED_LOCAL_VARIABLE, self.__method )
724 self.__context.get_tainted_variables().push_info( TAINTED_LOCAL_VARIABLE, variable_name, (access_flag[0], idx, self, self.__method) )
725
726
727
728 elif i.get_name() in FIELDS :
729 o = i.get_operands()
730 desc = getattr(self.__vm, "get_field_descriptor")(o[0], o[1], o[2])
731
732
733 if desc == None :
734 desc = ExternalFM( o[0], o[1], o[2] )
735
736
737 self.__context.get_tainted_variables().push_info( TAINTED_FIELD, desc, (FIELDS[ i.get_name() ][0], idx, self, self.__method) )
738
739
740
741 elif "new" in i.get_name() or "invoke" in i.get_name() or "getstatic" in i.get_name() :
742 if "new" in i.get_name() :
743 self.__context.get_tainted_packages()._push_info( i.get_operands(), (TAINTED_PACKAGE_CREATE, idx, self, self.__method) )
744 else :
745 self.__context.get_tainted_packages()._push_info( i.get_operands()[0], (TAINTED_PACKAGE_CALL, idx, self, self.__method, i.get_operands()[1], i.get_operands()[2]) )
746
747
748
749 if "ldc" == i.get_name() :
750 o = i.get_operands()
751
752 if o[0] == "CONSTANT_Integer" :
753 self.__context.get_tainted_integers().push_info( i, (o[1], idx, self, self.__method) )
754
755 elif "sipush" in i.get_name() :
756 self.__context.get_tainted_integers().push_info( i, (i.get_operands(), idx, self, self.__method) )
757
758 elif "bipush" in i.get_name() :
759 self.__context.get_tainted_integers().push_info( i, (i.get_operands(), idx, self, self.__method) )
760
761
762
763 idx += i.get_length()
764
765
767 self.analyze_break_blocks()
768
769
770 d = {}
771 for i in self.fathers :
772
773 d[ i[0] ] = i[2]
774
775 self.free_blocks_offsets.append( self.get_start() )
776
777 idx = 0
778 for i in self.ins :
779
780
781
782 if self.start + idx in d :
783 self.__stack.insert_stack( 0, d[ self.start + idx ].get_stack() )
784
785 ret_v = ReturnValues()
786
787 res = []
788 try :
789
790
791 if INSTRUCTIONS_ACTIONS[ i.get_name() ] == [] :
792 print "[[[[ %s is not yet implemented ]]]]" % i.get_name()
793 raise("ooops")
794
795 i_idx = 0
796 for actions in INSTRUCTIONS_ACTIONS[ i.get_name() ] :
797 for action in actions :
798 action( self.__vm, i, actions[action], self.__stack, res, ret_v )
799 for val in ret_v.get_return() :
800 res.append( val )
801
802
803 self.stack_traces.save( idx, i_idx, i, cPickle.dumps( self.__stack ), cPickle.dumps( ret_v.get_msg() ) )
804 i_idx += 1
805
806 except KeyError :
807 print "[[[[ %s is not in INSTRUCTIONS_ACTIONS ]]]]" % i.get_name()
808 except IndexError :
809 print "[[[[ Analysis failed in %s-%s-%s ]]]]" % (self.__method.get_class_name(), self.__method.get_name(), self.__method.get_descriptor())
810
811 idx += i.get_length()
812
813 if self.__stack.nil() == True and i != self.ins[-1] :
814 self.free_blocks_offsets.append( idx + self.get_start() )
815
817 print "\t@", self.name
818
819 idx = 0
820 nb = 0
821 for i in self.ins :
822 print "\t\t", nb, idx,
823 i.show(nb)
824 nb += 1
825 idx += i.get_length()
826
827 print ""
828 print "\t\tFree blocks offsets --->", self.free_blocks_offsets
829 print "\t\tBreakBlocks --->", len(self.break_blocks)
830
831 print "\t\tF --->", ', '.join( i[2].get_name() for i in self.fathers )
832 print "\t\tC --->", ', '.join( i[2].get_name() for i in self.childs )
833
834 self.stack_traces.show()
835
838
847
848
850 if self._ins == [] :
851 return False
852
853 if "store" in self._ins[-1].get_name() :
854 return True
855 elif "putfield" in self._ins[-1].get_name() :
856 return True
857
858 return False
859
861 ctt = []
862
863 stack = Stack()
864 for i in self._ins :
865 v = self.trans(i)
866 if v != None :
867 ctt.append( v )
868
869 t = ""
870
871 for mre in jvm.MATH_JVM_RE :
872 if mre[0].match( i.get_name() ) :
873 self._ops.append( mre[1] )
874 break
875
876
877 if i.get_name() in FIELDS :
878 t = "F"
879 elif i.get_name() in METHODS :
880 t = "M"
881
882 if t != "" :
883 o = i.get_operands()
884 desc = getattr(self._vm, self.__info[t][0])(o[0], o[1], o[2])
885
886
887 if desc == None :
888 desc = ExternalFM( o[0], o[1], o[2] )
889
890 if desc not in self.__info[t][1] :
891 self.__info[t][1][desc] = []
892
893 if t == "F" :
894 self.__info[t][1][desc].append( self.__info[t][2]( FIELDS[ i.get_name() ][0] ) )
895
896
897
898 elif t == "M" :
899 self.__info[t][1][desc].append( self.__info[t][2]() )
900
901 for i in self._fields :
902 for k in self._fields[i] :
903 k.set_details( ctt )
904
905 for i in self._methods :
906 for k in self._methods[i] :
907 k.set_details( ctt )
908
910 v = i.get_name()[0:2]
911 if v == "il" or v == "ic" or v == "ia" or v == "si" or v == "bi" :
912 return "I"
913
914 if v == "ba" :
915 return "B"
916
917 if v == "if" :
918 return "IF"
919
920 if v == "ir" :
921 return "RET"
922
923 if "and" in i.get_name() :
924 return "&"
925
926 if "add" in i.get_name() :
927 return "+"
928
929 if "sub" in i.get_name() :
930 return "-"
931
932 if "xor" in i.get_name() :
933 return "^"
934
935 if "ldc" in i.get_name() :
936 return "I"
937
938 if "invokevirtual" in i.get_name() :
939 return "M" + i.get_operands()[2]
940
941 if "getfield" in i.get_name() :
942 return "F" + i.get_operands()[2]
943
944
945 DVM_FIELDS_ACCESS = {
946 "iget" : "R",
947 "iget-wide" : "R",
948 "iget-object" : "R",
949 "iget-boolean" : "R",
950 "iget-byte" : "R",
951 "iget-char" : "R",
952 "iget-short" : "R",
953
954 "iput" : "W",
955 "iput-wide" : "W",
956 "iput-object" : "W",
957 "iput-boolean" : "W",
958 "iput-byte" : "W",
959 "iput-char" : "W",
960 "iput-short" : "W",
961
962 "sget" : "R",
963 "sget-wide" : "R",
964 "sget-object" : "R",
965 "sget-boolean" : "R",
966 "sget-byte" : "R",
967 "sget-char" : "R",
968 "sget-short" : "R",
969
970 "sput" : "W",
971 "sput-wide" : "W",
972 "sput-object" : "W",
973 "sput-boolean" : "W",
974 "sput-byte" : "W",
975 "sput-char" : "W",
976 "sput-short" : "W",
977 }
978
980 - def __init__(self, start, _vm, _method, _context) :
981 self.__vm = _vm
982 self.__method = _method
983 self.__context = _context
984
985 self.ins = []
986
987 self.fathers = []
988 self.childs = []
989
990 self.start = start
991 self.end = self.start
992
993 self.break_blocks = []
994
995 self.free_blocks_offsets = []
996
997 self.name = "%s-BB@0x%x" % (self.__method.get_name(), self.start)
998
1000 return self.__method
1001
1004
1007
1010
1013
1014 - def push(self, i) :
1017
1019 self.fathers.append( f )
1020
1022
1023 if values == [] :
1024 next_block = self.__context.get_basic_block( self.end + 1 )
1025 if next_block != None :
1026 self.childs.append( ( self.end - self.ins[-1].get_length(), self.end, next_block ) )
1027 else :
1028 for i in values :
1029 if i != -1 :
1030 next_block = self.__context.get_basic_block( i )
1031
1032
1033
1034 if next_block != None :
1035 self.childs.append( ( self.end - self.ins[-1].get_length(), i, next_block) )
1036
1037 for c in self.childs :
1038 if c[2] != None :
1039 c[2].set_fathers( ( c[1], c[0], self ) )
1040
1042 idx = 0
1043 for i in self.ins :
1044 if i.get_name() in DVM_FIELDS_ACCESS :
1045 o = i.get_operands()
1046 desc = self.__vm.get_class_manager().get_field(o[-1][1], True)
1047 if desc == None :
1048 raise("oo")
1049
1050 self.__context.get_tainted_variables().push_info( TAINTED_FIELD, desc, (DVM_FIELDS_ACCESS[ i.get_name() ][0], idx, self, self.__method) )
1051 elif "invoke" in i.get_name() :
1052 idx_meth = 0
1053 for op in i.get_operands() :
1054 if op[0] == "meth@" :
1055 idx_meth = op[1]
1056 break
1057
1058 method_info = self.__vm.get_class_manager().get_method( idx_meth )
1059 self.__context.get_tainted_packages()._push_info( method_info[0], (TAINTED_PACKAGE_CALL, idx, self, self.__method, method_info[2], method_info[1][0] + method_info[1][1]) )
1060 elif "new-instance" in i.get_name() :
1061 type_info = self.__vm.get_class_manager().get_type( i.get_operands()[-1][1] )
1062 self.__context.get_tainted_packages()._push_info( type_info, (TAINTED_PACKAGE_CREATE, idx, self, self.__method) )
1063 elif "const-string" in i.get_name() :
1064 string_name = self.__vm.get_class_manager().get_string( i.get_operands()[-1][1] )
1065 self.__context.get_tainted_variables().add( string_name, TAINTED_STRING )
1066 self.__context.get_tainted_variables().push_info( TAINTED_STRING, string_name, ("R", idx, self, self.__method) )
1067
1068 idx += i.get_length()
1069
1072
1075
1076 TAINTED_LOCAL_VARIABLE = 0
1077 TAINTED_FIELD = 1
1078 TAINTED_STRING = 2
1081 self.access_flag = info[0]
1082 self.idx = info[1]
1083 self.bb = info[2]
1084 self.method = info[3]
1085
1087 return self.access_flag
1088
1091
1094
1097
1100 self.var = var
1101 self.type = _type
1102
1103 self.paths = []
1104
1107
1112
1113 - def push(self, info) :
1114 p = Path( info )
1115 self.paths.append( p )
1116 return p
1117
1122
1124 for i in self.paths :
1125 yield i
1126
1128 return len(self.paths)
1129
1133
1147
1148
1149
1151 try :
1152 return self.__vars[ TAINTED_STRING ][ s ]
1153 except KeyError :
1154 return None
1155
1156 - def get_field(self, class_name, name, descriptor) :
1161
1162
1168
1169
1170
1174
1178
1179
1180
1182 try :
1183 return self.__methods[ TAINTED_STRING ][ method ]
1184 except KeyError :
1185 return {}
1186
1188 try :
1189 return self.__methods[ TAINTED_FIELD ][ method ]
1190 except KeyError :
1191 return {}
1192
1194 try :
1195 return self.__vars[ TAINTED_LOCAL_VARIABLE ][ _method ]
1196 except KeyError :
1197 return None
1198
1206
1207 - def add(self, var, _type, _method=None) :
1222
1224 if _type == TAINTED_FIELD or _type == TAINTED_STRING :
1225 self.add( var, _type )
1226 p = self.__vars[ _type ][ var ].push( info )
1227
1228 try :
1229 self.__methods[ _type ][ p.get_method() ][ var ].append( p )
1230 except KeyError :
1231 try :
1232 self.__methods[ _type ][ p.get_method() ][ var ] = []
1233 except KeyError :
1234 self.__methods[ _type ][ p.get_method() ] = {}
1235 self.__methods[ _type ][ p.get_method() ][ var ] = []
1236
1237 self.__methods[ _type ][ p.get_method() ][ var ].append( p )
1238
1239 elif _type == TAINTED_LOCAL_VARIABLE :
1240 self.add( var, _type, info[-1] )
1241 self.__vars[ TAINTED_LOCAL_VARIABLE ][ info[-1] ][ var ].push( info )
1242 else :
1243 raise("ooop")
1244
1252
1255 self.info = PathI( info )
1256
1259
1262 self.__vm = _vm
1263 self.__integers = []
1264 self.__hash = {}
1265
1267 try :
1268 return self.__hash[ method ]
1269 except KeyError :
1270 return []
1271
1273
1274
1275 ti = TaintedInteger( info )
1276 self.__integers.append( ti )
1277
1278 try :
1279 self.__hash[ info[-1] ].append( ti )
1280 except KeyError :
1281 self.__hash[ info[-1] ] = []
1282 self.__hash[ info[-1] ].append( ti )
1283
1285 for i in self.__integers :
1286 yield i
1287
1288 TAINTED_PACKAGE_CREATE = 0
1289 TAINTED_PACKAGE_CALL = 1
1290
1291 TAINTED_PACKAGE = {
1292 TAINTED_PACKAGE_CREATE : "C",
1293 TAINTED_PACKAGE_CALL : "M"
1294 }
1295
1301
1303 - def __init__(self, info, class_name) :
1304 Path.__init__( self, info )
1305 self.class_name = class_name
1306 if info[0] == TAINTED_PACKAGE_CALL :
1307 self.name = info[-2]
1308 self.descriptor = info[-1]
1309
1311 return self.class_name
1312
1315
1317 return self.descriptor
1318
1323
1326
1327
1330
1333
1334 - def push(self, info) :
1335 p = PathP( info, self.get_name() )
1336 self.paths[ info[0] ].append( p )
1337 return p
1338
1340 """
1341 @param name : a regexp for the name of the method
1342 @param descriptor : a regexp for the descriptor of the method
1343
1344 @rtype : a list of called paths
1345 """
1346 ex = re.compile( class_name )
1347 l = []
1348 m_name = re.compile(name)
1349 m_descriptor = re.compile(descriptor)
1350
1351 for path in self.paths[ TAINTED_PACKAGE_CALL ] :
1352 if m_name.match( path.get_name() ) != None and m_descriptor.match( path.get_descriptor() ) != None :
1353 l.append( path )
1354 return l
1355
1362
1364 for i in self.paths :
1365 for j in self.paths[ i ] :
1366 yield j
1367
1369 x = 0
1370 for i in self.paths :
1371 x += len(self.paths[ i ])
1372 return x
1373
1376
1377 - def show(self, format) :
1387
1390 self.__vm = _vm
1391 self.__packages = {}
1392 self.__methods = {}
1393
1395 if name not in self.__packages :
1396 self.__packages[ name ] = TaintedPackage( name )
1397
1399 self._add_pkg( class_name )
1400 p = self.__packages[ class_name ].push( info )
1401
1402 try :
1403 self.__methods[ p.get_method() ][ class_name ].append( p )
1404 except :
1405 try :
1406 self.__methods[ p.get_method() ][ class_name ] = []
1407 except :
1408 self.__methods[ p.get_method() ] = {}
1409 self.__methods[ p.get_method() ][ class_name ] = []
1410
1411 self.__methods[ p.get_method() ][ class_name ].append( p )
1412
1414 try :
1415 return self.__methods[ method ]
1416 except KeyError :
1417 return {}
1418
1420 """
1421 @rtype : return a list of packaged used in a basic block
1422 """
1423 l = []
1424 for i in self.__packages :
1425 paths = self.__packages[i].gets()
1426 for j in paths :
1427 for k in paths[j] :
1428 if k.get_bb() == bb :
1429 l.append( (i, k.get_access_flag(), k.get_idx(), k.get_method()) )
1430
1431 return l
1432
1434 for i in self.__packages :
1435 yield self.__packages[ i ], i
1436
1450
1464
1466 """
1467 @param package_name : a regexp for the name of the package
1468
1469 @rtype : a list of called packages' paths
1470 """
1471 ex = re.compile( package_name )
1472
1473 l = []
1474 for m, _ in self.get_packages() :
1475 if ex.match( m.get_info() ) != None :
1476 l.extend( m.get_methods() )
1477 return l
1478
1480 """
1481 @param class_name : a regexp for the class name of the method (the package)
1482 @param name : a regexp for the name of the method
1483 @param descriptor : a regexp for the descriptor of the method
1484
1485 @rtype : a list of called methods' paths
1486 """
1487 ex = re.compile( class_name )
1488 l = []
1489
1490 for m, _ in self.get_packages() :
1491 if ex.match( m.get_info() ) != None :
1492 l.extend( m.search_method( name, descriptor ) )
1493 return l
1494
1496 """
1497 @rtype : a list of called crypto packages
1498 """
1499 return self.search_packages( "Ljavax/crypto/" )
1500
1502 """
1503 @rtype : a list of called telephony packages
1504 """
1505 return self.search_packages( "Landroid/telephony/" )
1506
1508 """
1509 @rtype : a list of called net packages
1510 """
1511 return self.search_packages( "Landroid/net/" )
1512
1513 - def get_method(self, class_name, name, descriptor) :
1514 try :
1515 return self.__packages[ class_name ].get_method( name, descriptor )
1516 except KeyError :
1517 return []
1518
1548
1551 self.__vm = _vm
1552 self.__tainted = _tv
1553
1554 self.bb = []
1555
1556 - def push(self, bb):
1557 self.bb.append( bb )
1558
1559 - def pop(self, idx) :
1560 return self.bb.pop( idx )
1561
1563 for i in self.bb :
1564 if idx >= i.get_start() and idx < i.get_end() :
1565 return i
1566 return None
1567
1569 return self.__tainted["integers"]
1570
1572 return self.__tainted["packages"]
1573
1575 return self.__tainted["variables"]
1576
1578 """
1579 @rtype : return a random basic block
1580 """
1581 return self.bb[ random.randint(0, len(self.bb) - 1) ]
1582
1584 """
1585 @rtype : return each basic block
1586 """
1587 for i in self.bb :
1588 yield i
1589
1591 """
1592 @rtype : a list of basic blocks
1593 """
1594 return self.bb
1595
1597 """
1598 This class analyses in details a method of a class/dex file
1599 """
1600 - def __init__(self, _vm, _method, _tv, code_analysis=False) :
1601 """
1602 @param _vm : a L{JVMFormat} or L{DalvikVMFormat} object
1603 @param _method : a method object
1604 @param tv : a dictionnary of tainted information
1605 """
1606 self.__vm = _vm
1607 self.__method = _method
1608
1609 self.__tainted = _tv
1610
1611 BO = { "BasicOPCODES" : jvm.BRANCH2_JVM_OPCODES, "BasicClass" : JVMBasicBlock, "Dnext" : jvm.determineNext,
1612 "TS" : JVM_TOSTRING }
1613 if self.__vm.get_type() == "DVM" :
1614 BO = { "BasicOPCODES" : dvm.BRANCH_DVM_OPCODES, "BasicClass" : DVMBasicBlock, "Dnext" : dvm.determineNext,
1615 "TS" : DVM_TOSTRING }
1616
1617 self.__TS = ToString( BO[ "TS" ] )
1618
1619 BO["BasicOPCODES_H"] = []
1620 for i in BO["BasicOPCODES"] :
1621 BO["BasicOPCODES_H"].append( re.compile( i ) )
1622
1623 self.basic_blocks = BasicBlocks( self.__vm, self.__tainted )
1624
1625 code = self.__method.get_code()
1626 if code == None :
1627 return
1628
1629 current_basic = BO["BasicClass"]( 0, self.__vm, self.__method, self.basic_blocks )
1630 self.basic_blocks.push( current_basic )
1631
1632
1633
1634 bc = code.get_bc()
1635 l = []
1636 h = {}
1637 idx = 0
1638 for i in bc.get() :
1639 for j in BO["BasicOPCODES_H"] :
1640 if j.match(i.get_name()) != None :
1641 v = BO["Dnext"]( i, idx, self.__method )
1642 h[ idx ] = v
1643 l.extend( v )
1644 break
1645
1646 idx += i.get_length()
1647
1648
1649 idx = 0
1650 for i in bc.get() :
1651 name = i.get_name()
1652
1653 self.__TS.push( name )
1654
1655 here = False
1656
1657 if idx in l :
1658 if current_basic.ins != [] :
1659 current_basic = BO["BasicClass"]( current_basic.get_end(), self.__vm, self.__method, self.basic_blocks )
1660 self.basic_blocks.push( current_basic )
1661 here = True
1662
1663 current_basic.push( i )
1664
1665
1666 if idx in h :
1667 current_basic = BO["BasicClass"]( current_basic.get_end(), self.__vm, self.__method, self.basic_blocks )
1668 self.basic_blocks.push( current_basic )
1669
1670 idx += i.get_length()
1671
1672
1673 if current_basic.ins == [] :
1674 self.basic_blocks.pop( -1 )
1675
1676 for i in self.basic_blocks.get() :
1677 try :
1678 i.set_childs( h[ i.end - i.ins[-1].get_length() ] )
1679 except KeyError :
1680 i.set_childs( [] )
1681
1682
1683 for i in self.basic_blocks.get() :
1684 i.analyze()
1685
1686 if code_analysis == True :
1687 for i in self.basic_blocks.get() :
1688 i.analyze_code()
1689
1691 """
1692 @rtype : an integer which is the length of the code
1693 """
1694 return self.get_code().get_length()
1695
1697 l = []
1698 for i in self.basic_blocks.get() :
1699 if i.get_start() <= idx :
1700 l.append( i )
1701
1702 l.reverse()
1703 for i in l :
1704 x = i.prev_free_block_offset( idx )
1705 if x != -1 :
1706 return x
1707 return -1
1708
1713
1720
1726
1729
1732
1734 return self.__method
1735
1738
1741
1743 l = []
1744 for i in self.__bb :
1745 for j in i.get_ops() :
1746 l.append( j )
1747 return l
1748
1757
1759 print "\t #METHODS :"
1760 l = []
1761 for i in self.__bb :
1762 methods = i.get_methods()
1763 for method in methods :
1764 print "\t\t-->", method.get_class_name(), method.get_name(), method.get_descriptor()
1765 for context in methods[method] :
1766 print "\t\t\t |---|", context.details
1767
1768 SIGNATURE_L0_0 = "L0_0"
1769 SIGNATURE_L0_1 = "L0_1"
1770 SIGNATURE_L0_2 = "L0_2"
1771 SIGNATURE_L0_3 = "L0_3"
1772 SIGNATURE_L0_4 = "L0_4"
1773 SIGNATURE_L0_5 = "L0_5"
1774 SIGNATURE_L0_6 = "L0_6"
1775 SIGNATURE_L0_0_L1 = "L0_0:L1"
1776 SIGNATURE_L0_1_L1 = "L0_1:L1"
1777 SIGNATURE_L0_2_L1 = "L0_2:L1"
1778 SIGNATURE_L0_3_L1 = "L0_3:L1"
1779 SIGNATURE_L0_4_L1 = "L0_4:L1"
1780 SIGNATURE_L0_5_L1 = "L0_5:L1"
1781 SIGNATURE_L0_0_L2 = "L0_0:L2"
1782 SIGNATURE_L0_0_L3 = "L0_0:L3"
1783
1784 SIGNATURES = {
1785 SIGNATURE_L0_0 : { "type" : 0 },
1786 SIGNATURE_L0_1 : { "type" : 1 },
1787 SIGNATURE_L0_2 : { "type" : 2, "arguments" : ["Landroid"] },
1788 SIGNATURE_L0_3 : { "type" : 2, "arguments" : ["Ljava"] },
1789 SIGNATURE_L0_4 : { "type" : 2, "arguments" : ["Landroid", "Ljava"] },
1790 SIGNATURE_L0_5 : { "type" : 3, "arguments" : ["Landroid"] },
1791 SIGNATURE_L0_6 : { "type" : 3, "arguments" : ["Ljava"] },
1792 }
1793
1794 from sign import Signature
1795
1797 """
1798 This class analyses a class file or a dex file
1799
1800 @param _vm : a virtual machine object
1801 """
1802 - def __init__(self, _vm, code_analysis=False) :
1803 """
1804 @param _vm : a L{JVMFormat} or L{DalvikFormatVM}
1805 @param code_analysis : True if you would like to do an advanced analyse of the code (e.g : to search free offset to insert codes
1806 """
1807
1808 self.__vm = _vm
1809
1810 self.tainted_variables = TaintedVariables( self.__vm )
1811 self.tainted_packages = TaintedPackages( self.__vm )
1812 self.tainted_integers = TaintedIntegers( self.__vm )
1813
1814 self.tainted = { "variables" : self.tainted_variables,
1815 "packages" : self.tainted_packages,
1816 "integers" : self.tainted_integers,
1817 }
1818
1819 self.signature = Signature( self.tainted )
1820
1821 for i in self.__vm.get_all_fields() :
1822 self.tainted_variables.add( i, TAINTED_FIELD )
1823
1824 self.methods = []
1825 self.hmethods = {}
1826 self.__nmethods = {}
1827 for i in self.__vm.get_methods() :
1828 x = MethodAnalysis( self.__vm, i, self.tainted, code_analysis )
1829 self.methods.append( x )
1830 self.hmethods[ i ] = x
1831 self.__nmethods[ i.get_name() ] = x
1832
1834 """
1835 Return an analysis method
1836
1837 @param method : a classical method object
1838 @rtype : L{MethodAnalysis}
1839 """
1840 return self.hmethods[ method ]
1841
1842
1844 return [ random.choice( string.letters ) + ''.join([ random.choice(string.letters + string.digits) for i in range(10 - 1) ]),
1845 "ACC_PUBLIC",
1846 "I"
1847 ]
1848
1849
1851 m = self.__vm.get_method("<init>")
1852 return m[0]
1853
1854
1857
1859 """
1860 Find the previous offset where you can insert a block
1861
1862 @param method : a reference of a method object where you would like the offset
1863 @param idx : the index to start the research
1864
1865 @rtype : return -1 if an error occured, otherwise the offset
1866 """
1867
1868 try :
1869 return self.hmethods[ method ].prev_free_block_offset( idx )
1870 except KeyError :
1871
1872 return -1
1873
1875 """
1876 Find a random offset where you can insert a block
1877
1878 @param method : a reference of method object or a string which represents a regexp
1879
1880 @rtype : return -1 if an error occured, otherwise the offset
1881 """
1882 if isinstance(method, str) :
1883 p = re.compile(method)
1884 for i in self.hmethods :
1885 if random.randint(0, 1) == 1 :
1886 if p.match( i.get_name() ) == None :
1887 return i, self.hmethods[i].random_free_block_offset()
1888
1889 for i in self.hmethods :
1890 if p.match( i.get_name() ) == None :
1891 return i, self.hmethods[i].random_free_block_offset()
1892
1893
1894 try :
1895 return self.hmethods[ method ].random_free_block_offset()
1896 except KeyError :
1897
1898 return -1
1899
1901 """
1902 Find the next offset where you can insert a block
1903
1904 @param method : a reference of a method object where you would like the offset
1905 @param idx : the index to start the research
1906
1907 @rtype : return -1 if an error occured, otherwise the offset
1908 """
1909
1910 try :
1911 return self.hmethods[ method ].next_free_block_offset( idx )
1912 except KeyError :
1913
1914 return -1
1915
1917 """
1918 Return the tainted variables
1919
1920 @rtype : L{TaintedVariables}
1921 """
1922 return self.tainted_variables
1923
1925 """
1926 Return the tainted packages
1927
1928 @rtype : L{TaintedPackages}
1929 """
1930 return self.tainted_packages
1931
1933 """
1934 Return a specific tainted field
1935
1936 @param class_name : the name of the class
1937 @param name : the name of the field
1938 @param descriptor : the descriptor of the field
1939
1940 @rtype : L{TaintedVariable}
1941 """
1942 return self.tainted_variables.get_field( class_name, name, descriptor )
1943
1945 """
1946 Return each analysis method
1947
1948 @rtype : L{MethodAnalysis}
1949 """
1950 for i in self.hmethods :
1951 yield self.hmethods[i]
1952
1954 """
1955 Return a specific signature for a specific method
1956
1957 @param method : a reference to method from a vm class
1958 @param grammar_type : the type of the signature
1959 @param options : the options of the signature
1960 @param predef_sign : used a predefined signature
1961
1962 @rtype : L{Sign}
1963 """
1964 if predef_sign != "" :
1965 g = ""
1966 o = {}
1967
1968 for i in predef_sign.split(":") :
1969 if "_" in i :
1970 g += "L0:"
1971 o[ "L0" ] = SIGNATURES[ i ]
1972 else :
1973 g += i
1974 g += ":"
1975
1976 return self.signature.get_method( self.get_method( method ), g[:-1], o )
1977 else :
1978 return self.signature.get_method( self.get_method( method ), grammar_type, options )
1979
1980
1981
1984
1985
1988