Remove unused bitrotted code

This commit is contained in:
Robert Grosse 2014-11-05 14:56:23 -08:00
parent 78bafe6ace
commit e51ec266dc
13 changed files with 3 additions and 4862 deletions

View File

@ -1,146 +0,0 @@
#!/usr/bin/env python
# This file is part of Androguard.
#
# Copyright (C) 2012, Anthony Desnos <desnos at t0t0.fr>
# All rights reserved.
#
# Androguard is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Androguard is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Androguard. If not, see <http://www.gnu.org/licenses/>.
import sys, os, cmd, threading, re, atexit
from optparse import OptionParser
import androguard, androconf, jvm
# External Libraries
# python-ptrace : http://bitbucket.org/haypo/python-ptrace/
from ptrace import PtraceError
from ptrace.tools import locateProgram
from ptrace.debugger import ProcessExit, DebuggerError, PtraceDebugger, ProcessExit, ProcessSignal, NewProcessEvent, ProcessExecution
from ptrace.debugger.memory_mapping import readProcessMappings
####################
option_0 = { 'name' : ('-i', '--input'), 'help' : 'pid', 'nargs' : 1 }
option_1 = { 'name' : ('-v', '--version'), 'help' : 'version of the API', 'action' : 'count' }
options = [option_0, option_1]
MAGIC_PATTERN = "\xca\xfe\xba\xbe"
class AndroPreDump(object):
def __init__(self, input):
self.data = []
self.pid = int(input)
self.debugger = PtraceDebugger()
self.process = self.debugger.addProcess(self.pid, is_attached=False)
atexit.register(self.debugger.quit)
Header = False
Code = False
self.procmaps = readProcessMappings(self.process)
for pm in self.procmaps:
if pm.permissions.find("w") != -1 and pm.pathname == None:
# if Code == False and Header == True:
# data = self.process.readBytes(pm.start, pm.end-pm.start)
# idx = data.find("SourceFile")
# if idx != -1:
# print "CODE", pm
# self.data.append( (pm, data, idx) )
# Code = True
if Header == False:
data = self.process.readBytes(pm.start, pm.end-pm.start)
idx = data.find(MAGIC_PATTERN)
if idx != -1:
print "HEADER", pm
self.data.append( (pm, data) )
Header = True
self.dumpMemory( "java_dump_memory" )
# self.dumpFiles( "java_files" )
def write(self, idx, buff):
self.process.writeBytes( idx, buff )
def getFilesBuffer(self):
for i in self.data:
d = i[1]
x = d.find(MAGIC_PATTERN)
idx = x
while x != -1:
yield i[0].start + idx, d[x:]
d = d[x+len(MAGIC_PATTERN):]
idx += len(MAGIC_PATTERN)
x = d.find(MAGIC_PATTERN)
idx += x
def dumpMemory(self, base_filename):
for i in self.data:
with open(base_filename + "-" + "0x%x-0x%x" % (i[0].start, i[0].end), "w") as fd:
fd.write( i[1] )
def dumpFiles(self, base_filename):
for i in self.data:
with fd = open(base_filename + "-" + "0x%x-0x%x" % (i[0].start + i[2], i[0].end), "w") as fd:
fd.write( i[1][i[2]:] )
class AndroDump(object):
def __init__(self, adp):
self.__adp = adp
for i in self.__adp.getFilesBuffer():
try:
print "0x%x :" % (i[0])
j = jvm.JVMFormat( i[1] )
for method in j.get_methods():
print "\t -->", method.get_class_name(), method.get_name(), method.get_descriptor()
# if (method.get_class_name() == "Test2" and method.get_name() == "main"):
# print "patch"
# code = method.get_code()
#code.remplace_at( 51, [ "bipush", 20 ] )
# code.show()
# print "\t\t-> %x" % (len(j.save()))
# self.__adp.write( i[0], j.save() )
except Exception, e:
print e
def main(options, arguments):
if options.input != None:
apd = AndroPreDump( options.input )
AndroDump( apd )
elif options.version != None:
print "Androdump version %s" % androconf.ANDROGUARD_VERSION
if __name__ == "__main__":
parser = OptionParser()
for option in options:
param = option['name']
del option['name']
parser.add_option(*param, **option)
options, arguments = parser.parse_args()
sys.argv[:] = arguments
main(options, arguments)

View File

@ -18,7 +18,7 @@
import re, random, string, cPickle
from androguard.core.androconf import error, warning, debug, is_ascii_problem
from androguard.core.bytecodes import jvm, dvm
from androguard.core.bytecodes import dvm
from androguard.core.bytecodes.api_permissions import DVM_PERMISSIONS_BY_PERMISSION, DVM_PERMISSIONS_BY_ELEMENT
from androguard.util import read
@ -116,812 +116,6 @@ class BreakBlock(object):
print "\t\t",
i.show(0)
##### JVM ######
FIELDS = {
"getfield" : "R",
"getstatic" : "R",
"putfield" : "W",
"putstatic" : "W",
}
METHODS = [ "invokestatic", "invokevirtual", "invokespecial" ]
JVM_TOSTRING = { "O" : jvm.MATH_JVM_OPCODES.keys(),
"I" : jvm.INVOKE_JVM_OPCODES,
"G" : jvm.FIELD_READ_JVM_OPCODES,
"P" : jvm.FIELD_WRITE_JVM_OPCODES,
}
BREAK_JVM_OPCODES_RE = []
for i in jvm.BREAK_JVM_OPCODES:
BREAK_JVM_OPCODES_RE.append( re.compile( i ) )
class Stack(object):
def __init__(self):
self.__elems = []
def gets(self):
return self.__elems
def push(self, elem):
self.__elems.append( elem )
def get(self):
return self.__elems[-1]
def pop(self):
return self.__elems.pop(-1)
def nil(self):
return len(self.__elems) == 0
def insert_stack(self, idx, elems):
if elems != self.__elems:
for i in elems:
self.__elems.insert(idx, i)
idx += 1
def show(self):
nb = 0
if len(self.__elems) == 0:
print "\t--> nil"
for i in self.__elems:
print "\t-->", nb, ": ", i
nb += 1
class StackTraces(object):
def __init__(self):
self.__elems = []
def save(self, idx, i_idx, ins, stack_pickle, msg_pickle):
self.__elems.append( (idx, i_idx, ins, stack_pickle, msg_pickle) )
def get(self):
for i in self.__elems:
yield (i[0], i[1], i[2], cPickle.loads( i[3] ), cPickle.loads( i[4] ) )
def show(self):
for i in self.__elems:
print i[0], i[1], i[2].get_name()
cPickle.loads( i[3] ).show()
print "\t", cPickle.loads( i[4] )
def push_objectref(_vm, ins, special, stack, res, ret_v):
value = "OBJ_REF_@_%s" % str(special)
stack.push( value )
def push_objectref_l(_vm, ins, special, stack, res, ret_v):
stack.push( "VARIABLE_LOCAL_%d" % special )
def push_objectref_l_i(_vm, ins, special, stack, res, ret_v):
stack.push( "VARIABLE_LOCAL_%d" % ins.get_operands() )
def pop_objectref(_vm, ins, special, stack, res, ret_v):
ret_v.add_return( stack.pop() )
def multi_pop_objectref_i(_vm, ins, special, stack, res, ret_v):
for i in range(0, ins.get_operands()[1]):
stack.pop()
def push_objectres(_vm, ins, special, stack, res, ret_v):
value = ""
if special[0] == 1:
value += special[1] + "(" + str( res.pop() ) + ") "
else:
for i in range(0, special[0]):
value += str( res.pop() ) + special[1]
value = value[:-1]
stack.push( value )
def push_integer_i(_vm, ins, special, stack, res, ret_v):
value = ins.get_operands()
stack.push( value )
def push_integer_d(_vm, ins, special, stack, res, ret_v):
stack.push( special )
def push_float_d(_vm, ins, special, stack, res, ret_v):
stack.push( special )
def putfield(_vm, ins, special, stack, res, ret_v):
ret_v.add_return( stack.pop() )
def putstatic(_vm, ins, special, stack, res, ret_v):
stack.pop()
def getfield(_vm, ins, special, stack, res, ret_v):
ret_v.add_return( stack.pop() )
stack.push( "FIELD" )
def getstatic(_vm, ins, special, stack, res, ret_v):
stack.push( "FIELD_STATIC" )
def new(_vm, ins, special, stack, res, ret_v):
stack.push( "NEW_OBJ" )
def dup(_vm, ins, special, stack, res, ret_v):
l = []
for i in range(0, special+1):
l.append( stack.pop() )
l.reverse()
l.insert( 0, l[-1] )
for i in l:
stack.push( i )
def dup2(_vm, ins, special, stack, res, ret_v):
l = []
for i in range(0, special+1):
l.append( stack.pop() )
l.reverse()
l.insert( 0, l[-1] )
l.insert( 1, l[-2] )
for i in l:
stack.push( i )
#FIXME
def ldc(_vm, ins, special, stack, res, ret_v):
#print ins.get_name(), ins.get_operands(), special
stack.push( "STRING" )
def invoke(_vm, ins, special, stack, res, ret_v):
desc = ins.get_operands()[-1]
param = desc[1:desc.find(")")]
ret = desc[desc.find(")")+1:]
# print "DESC --->", param, calc_nb( param ), ret, calc_nb( ret )
for i in range(0, calc_nb( param )):
stack.pop()
# objectref : static or not
for i in range(0, special):
stack.pop()
for i in range(0, calc_nb( ret )):
stack.push( "E" )
def set_arrayref(_vm, ins, special, stack, res, ret_v):
ret_v.add_msg( "SET VALUE %s %s @ ARRAY REF %s %s" % (special, str(stack.pop()), str(stack.pop()), str(stack.pop())) )
def set_objectref(_vm, ins, special, stack, res, ret_v):
ret_v.add_msg( "SET OBJECT REF %d --> %s" % (special, str(stack.pop())) )
def set_objectref_i(_vm, ins, special, stack, res, ret_v):
ret_v.add_msg( "SET OBJECT REF %d --> %s" % (ins.get_operands(), str(stack.pop())) )
def swap(_vm, ins, special, stack, res, ret_v):
l = stack.pop()
l2 = stack.pop()
stack.push(l2)
stack.push(l)
def calc_nb(info):
if info == "" or info == "V":
return 0
if ";" in info:
n = 0
for i in info.split(";"):
if i != "":
n += 1
return n
else:
return len(info) - info.count('[')
INSTRUCTIONS_ACTIONS = {
"aaload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"aastore" : [ { set_arrayref : None } ],
"aconst_null" : [ { push_objectref : "null" } ],
"aload" : [ { push_objectref_l_i : None } ],
"aload_0" : [ { push_objectref_l : 0 } ],
"aload_1" : [ { push_objectref_l : 1 } ],
"aload_2" : [ { push_objectref_l : 2 } ],
"aload_3" : [ { push_objectref_l : 3 } ],
"anewarray" : [ { pop_objectref : None }, { push_objectref : [ 1, "ANEWARRAY" ] } ],
"areturn" : [ { pop_objectref : None } ],
"arraylength" : [ { pop_objectref : None }, { push_objectres : [ 1, 'LENGTH' ] } ],
"astore" : [ { set_objectref_i : None } ],
"astore_0" : [ { set_objectref : 0 } ],
"astore_1" : [ { set_objectref : 1 } ],
"astore_2" : [ { set_objectref : 2 } ],
"astore_3" : [ { set_objectref : 3 } ],
"athrow" : [ { pop_objectref : None }, { push_objectres : [ 1, "throw" ] } ],
"baload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"bastore" : [ { set_arrayref : "byte" } ],
"bipush" : [ { push_integer_i : None } ],
"caload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"castore" : [ { set_arrayref : "char" } ],
"checkcast" : [ { pop_objectref : None }, { push_objectres : [ 1, "checkcast" ] } ],
"d2f" : [ { pop_objectref : None }, { push_objectres : [ 1, 'float' ] } ],
"d2i" : [ { pop_objectref : None }, { push_objectres : [ 1, 'integer' ] } ],
"d2l" : [ { pop_objectref : None }, { push_objectres : [ 1, 'long' ] } ],
"dadd" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '+' ] } ],
"daload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"dastore" : [ { set_arrayref : "double" } ],
"dcmpg" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"dcmpl" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"dconst_0" : [ { push_float_d : 0.0 } ],
"dconst_1" : [ { push_float_d : 1.0 } ],
"ddiv" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '&' ] } ],
"dload" : [ { push_objectref_l_i : None } ],
"dload_0" : [ { push_objectref_l : 0 } ],
"dload_1" : [ { push_objectref_l : 1 } ],
"dload_2" : [ { push_objectref_l : 2 } ],
"dload_3" : [ { push_objectref_l : 3 } ],
"dmul" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '*' ] } ],
"dneg" : [ { pop_objectref : None }, { push_objectres : [ 1, '-' ] } ],
"drem" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, 'rem' ] } ],
"dreturn" : [ { pop_objectref : None } ],
"dstore" : [ { set_objectref_i : None } ],
"dstore_0" : [ { set_objectref : 0 } ],
"dstore_1" : [ { set_objectref : 1 } ],
"dstore_2" : [ { set_objectref : 2 } ],
"dstore_3" : [ { set_objectref : 3 } ],
"dsub" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '-' ] } ],
"dup" : [ { dup : 0 } ],
"dup_x1" : [ { dup : 1 } ],
"dup_x2" : [ { dup : 2 } ],
"dup2" : [ { dup2 : 0 } ],
"dup2_x1" : [ { dup2 : 1 } ],
"dup2_x2" : [ { dup2 : 2 } ],
"f2d" : [ { pop_objectref : None }, { push_objectres : [ 1, 'double' ] } ],
"f2i" : [ { pop_objectref : None }, { push_objectres : [ 1, 'integer' ] } ],
"f2l" : [ { pop_objectref : None }, { push_objectres : [ 1, 'long' ] } ],
"fadd" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '+' ] } ],
"faload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"fastore" : [ { set_arrayref : "float" } ],
"fcmpg" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"fcmpl" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"fconst_0" : [ { push_float_d : 0.0 } ],
"fconst_1" : [ { push_float_d : 1.0 } ],
"fconst_2" : [ { push_float_d : 2.0 } ],
"fdiv" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '&' ] } ],
"fload" : [ { push_objectref_l_i : None } ],
"fload_0" : [ { push_objectref_l : 0 } ],
"fload_1" : [ { push_objectref_l : 1 } ],
"fload_2" : [ { push_objectref_l : 2 } ],
"fload_3" : [ { push_objectref_l : 3 } ],
"fmul" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '*' ] } ],
"fneg" : [ { pop_objectref : None }, { push_objectres : [ 1, '-' ] } ],
"freturn" : [ { pop_objectref : None } ],
"fstore" : [ { set_objectref_i : None } ],
"fstore_0" : [ { set_objectref : 0 } ],
"fstore_1" : [ { set_objectref : 1 } ],
"fstore_2" : [ { set_objectref : 2 } ],
"fstore_3" : [ { set_objectref : 3 } ],
"fsub" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '-' ] } ],
"getfield" : [ { getfield : None } ],
"getstatic" : [ { getstatic : None } ],
"goto" : [ {} ],
"goto_w" : [ {} ],
"i2b" : [ { pop_objectref : None }, { push_objectres : [ 1, 'byte' ] } ],
"i2c" : [ { pop_objectref : None }, { push_objectres : [ 1, 'char' ] } ],
"i2d" : [ { pop_objectref : None }, { push_objectres : [ 1, 'double' ] } ],
"i2f" : [ { pop_objectref : None }, { push_objectres : [ 1, 'float' ] } ],
"i2l" : [ { pop_objectref : None }, { push_objectres : [ 1, 'long' ] } ],
"i2s" : [ { pop_objectref : None }, { push_objectres : [ 1, 'string' ] } ],
"iadd" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '+' ] } ],
"iaload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"iand" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '&' ] } ],
"iastore" : [ { set_arrayref : "int" } ],
"iconst_m1" : [ { push_integer_d : -1 } ],
"iconst_0" : [ { push_integer_d : 0 } ],
"iconst_1" : [ { push_integer_d : 1 } ],
"iconst_2" : [ { push_integer_d : 2 } ],
"iconst_3" : [ { push_integer_d : 3 } ],
"iconst_4" : [ { push_integer_d : 4 } ],
"iconst_5" : [ { push_integer_d : 5 } ],
"idiv" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '/' ] } ],
"if_acmpeq" : [ { pop_objectref : None }, { pop_objectref : None } ],
"if_acmpne" : [ { pop_objectref : None }, { pop_objectref : None } ],
"if_icmpeq" : [ { pop_objectref : None }, { pop_objectref : None } ],
"if_icmpne" : [ { pop_objectref : None }, { pop_objectref : None } ],
"if_icmplt" : [ { pop_objectref : None }, { pop_objectref : None } ],
"if_icmpge" : [ { pop_objectref : None }, { pop_objectref : None } ],
"if_icmpgt" : [ { pop_objectref : None }, { pop_objectref : None } ],
"if_icmple" : [ { pop_objectref : None }, { pop_objectref : None } ],
"ifeq" : [ { pop_objectref : None } ],
"ifne" : [ { pop_objectref : None } ],
"iflt" : [ { pop_objectref : None } ],
"ifge" : [ { pop_objectref : None } ],
"ifgt" : [ { pop_objectref : None } ],
"ifle" : [ { pop_objectref : None } ],
"ifnonnull" : [ { pop_objectref : None } ],
"ifnull" : [ { pop_objectref : None } ],
"iinc" : [ {} ],
"iload" : [ { push_objectref_l_i : None } ],
"iload_1" : [ { push_objectref_l : 1 } ],
"iload_2" : [ { push_objectref_l : 2 } ],
"iload_3" : [ { push_objectref_l : 3 } ],
"imul" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '*' ] } ],
"ineg" : [ { pop_objectref : None }, { push_objectres : [ 1, '-' ] } ],
"instanceof" : [ { pop_objectref : None }, { push_objectres : [ 1, 'instanceof' ] } ],
"invokeinterface" : [ { invoke : 1 } ],
"invokespecial" : [ { invoke : 1 } ],
"invokestatic" : [ { invoke : 0 } ],
"invokevirtual": [ { invoke : 1 } ],
"ior" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '|' ] } ],
"irem" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, 'REM' ] } ],
"ireturn" : [ { pop_objectref : None } ],
"ishl" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '<<' ] } ],
"ishr" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '>>' ] } ],
"istore" : [ { set_objectref_i : None } ],
"istore_0" : [ { set_objectref : 0 } ],
"istore_1" : [ { set_objectref : 1 } ],
"istore_2" : [ { set_objectref : 2 } ],
"istore_3" : [ { set_objectref : 3 } ],
"isub" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '-' ] } ],
"iushr" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '>>' ] } ],
"ixor" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '^' ] } ],
"jsr" : [ { push_integer_i : None } ],
"jsr_w" : [ { push_integer_i : None } ],
"l2d" : [ { pop_objectref : None }, { push_objectres : [ 1, 'double' ] } ],
"l2f" : [ { pop_objectref : None }, { push_objectres : [ 1, 'float' ] } ],
"l2i" : [ { pop_objectref : None }, { push_objectres : [ 1, 'integer' ] } ],
"ladd" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '+' ] } ],
"laload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"land" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '&' ] } ],
"lastore" : [ { set_arrayref : "long" } ],
"lcmp" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"lconst_0" : [ { push_float_d : 0.0 } ],
"lconst_1" : [ { push_float_d : 1.0 } ],
"ldc" : [ { ldc : None } ],
"ldc_w" : [ { ldc : None } ],
"ldc2_w" : [ { ldc : None } ],
"ldiv" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '/' ] } ],
"lload" : [ { push_objectref_l_i : None } ],
"lload_0" : [ { push_objectref_l : 0 } ],
"lload_1" : [ { push_objectref_l : 1 } ],
"lload_2" : [ { push_objectref_l : 2 } ],
"lload_3" : [ { push_objectref_l : 3 } ],
"lmul" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '*' ] } ],
"lneg" : [ { pop_objectref : None }, { push_objectres : [ 1, '-' ] } ],
"lookupswitch" : [ { pop_objectref : None } ],
"lor" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '|' ] } ],
"lrem" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, 'REM' ] } ],
"lreturn" : [ { pop_objectref : None } ],
"lshl" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '<<' ] } ],
"lshr" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '>>' ] } ],
"lstore" : [ { set_objectref_i : None } ],
"lstore_0" : [ { set_objectref : 0 } ],
"lstore_1" : [ { set_objectref : 1 } ],
"lstore_2" : [ { set_objectref : 2 } ],
"lstore_3" : [ { set_objectref : 3 } ],
"lsub" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '-' ] } ],
"lushr" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '>>' ] } ],
"lxor" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectres : [ 2, '^' ] } ],
"monitorenter" : [ { pop_objectref : None } ],
"monitorexit" : [ { pop_objectref : None } ],
"multianewarray" : [ { multi_pop_objectref_i : None }, { push_objectref : 0 } ],
"new" : [ { new : None } ],
"newarray" : [ { pop_objectref : None }, { push_objectref : [ 1, "NEWARRAY" ] } ],
"nop" : [ {} ],
"pop" : [ { pop_objectref : None } ],
"pop2" : [ { pop_objectref : None }, { pop_objectref : None } ],
"putfield" : [ { putfield : None }, { pop_objectref : None } ],
"putstatic" : [ { putstatic : None } ],
"ret" : [ {} ],
"return" : [ {} ],
"saload" : [ { pop_objectref : None }, { pop_objectref : None }, { push_objectref : 0 } ],
"sastore" : [ { set_arrayref : "short" } ],
"sipush" : [ { push_integer_i : None } ],
"swap" : [ { swap : None } ],
"tableswitch" : [ { pop_objectref : None } ],
"wide" : [ {} ],
}
class ReturnValues(object):
def __init__(self):
self.__elems = []
self.__msgs = []
def add_msg(self, e):
self.__msgs.append( e )
def add_return(self, e):
self.__elems.append( e )
def get_msg(self):
return self.__msgs
def get_return(self):
return self.__elems
class ExternalMethod(object):
def __init__(self, class_name, name, descriptor):
self.__class_name = class_name
self.__name = name
self.__descriptor = descriptor
def get_name(self):
return "M@[%s][%s]-[%s]" % (self.__class_name, self.__name, self.__descriptor)
def set_fathers(self, f):
pass
class JVMBasicBlock(object):
def __init__(self, start, vm, method, context):
self.__vm = vm
self.method = method
self.context = context
self.__stack = Stack()
self.stack_traces = StackTraces()
self.ins = []
self.fathers = []
self.childs = []
self.start = start
self.end = self.start
self.break_blocks = []
self.free_blocks_offsets = []
self.name = "%s-BB@0x%x" % (self.method.get_name(), self.start)
def get_stack(self):
return self.__stack.gets()
def get_method(self):
return self.method
def get_name(self):
return self.name
def get_start(self):
return self.start
def get_end(self):
return self.end
def get_last(self):
return self.ins[-1]
def push(self, i):
self.ins.append( i )
self.end += i.get_length()
def set_fathers(self, f):
self.fathers.append( f )
def set_childs(self, values):
# print self, self.start, self.end, values, self.ins[-1].get_name()
if values == []:
next_block = self.context.get_basic_block( self.end + 1 )
if next_block != None:
self.childs.append( ( self.end - self.ins[-1].get_length(), self.end, next_block ) )
else:
for i in values:
#print i, self.context.get_basic_block( i )
if i != -1:
self.childs.append( ( self.end - self.ins[-1].get_length(), i, self.context.get_basic_block( i ) ) )
for c in self.childs:
if c[2] != None:
c[2].set_fathers( ( c[1], c[0], self ) )
def prev_free_block_offset(self, idx=0):
last = -1
#print "IDX", idx, self.free_blocks_offsets
if self.free_blocks_offsets == []:
return -1
for i in self.free_blocks_offsets:
if i <= idx:
last = i
else:
return last
return last
def random_free_block_offset(self):
return self.free_blocks_offsets[ random.randint(0, len(self.free_blocks_offsets) - 1) ]
def next_free_block_offset(self, idx=0):
#print idx, self.__free_blocks_offsets
for i in self.free_blocks_offsets:
if i > idx:
return i
return -1
def get_random_free_block_offset(self):
return self.free_blocks_offsets[ random.randint(0, len(self.free_blocks_offsets) - 1) ]
def get_random_break_block(self):
return self.break_blocks[ random.randint(0, len(self.break_blocks) - 1) ]
def get_break_block(self, idx):
for i in self.break_blocks:
if idx >= i.get_start() and idx <= i.get_end():
return i
return None
def analyze_break_blocks(self):
idx = self.get_start()
current_break = JVMBreakBlock( self.__vm, idx )
self.break_blocks.append(current_break)
for i in self.ins:
name = i.get_name()
##################### Break Block ########################
match = False
for j in BREAK_JVM_OPCODES_RE:
if j.match(name) != None:
match = True
break
current_break.push( i )
if match == True:
current_break.analyze()
current_break = JVMBreakBlock( self.__vm, current_break.get_end() )
self.break_blocks.append( current_break )
#########################################################
idx += i.get_length()
def analyze(self):
idx = 0
for i in self.ins:
################### TAINTED LOCAL VARIABLES ###################
if "load" in i.get_name() or "store" in i.get_name():
action = i.get_name()
access_flag = [ "R", "load" ]
if "store" in action:
access_flag = [ "W", "store" ]
if "_" in action:
name = i.get_name().split(access_flag[1])
value = name[1][-1]
else:
value = i.get_operands()
variable_name = "%s-%s" % (i.get_name()[0], value)
self.context.get_tainted_variables().add( variable_name, TAINTED_LOCAL_VARIABLE, self.method )
self.context.get_tainted_variables().push_info( TAINTED_LOCAL_VARIABLE, variable_name, (access_flag[0], idx, self, self.method) )
#########################################################
################### TAINTED FIELDS ###################
elif i.get_name() in FIELDS:
o = i.get_operands()
desc = getattr(self.__vm, "get_field_descriptor")(o[0], o[1], o[2])
# It's an external
#if desc == None:
# desc = ExternalFM( o[0], o[1], o[2] )
# print "RES", res, "-->", desc.get_name()
self.context.get_tainted_variables().push_info( TAINTED_FIELD, [o[0], o[1], o[2]], (FIELDS[ i.get_name() ][0], idx, self, self.method) )
#########################################################
################### TAINTED PACKAGES ###################
elif "new" in i.get_name() or "invoke" in i.get_name() or "getstatic" in i.get_name():
if "new" in i.get_name():
self.context.get_tainted_packages().push_info( i.get_operands(), (TAINTED_PACKAGE_CREATE, idx, self, self.method) )
else:
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]) )
#########################################################
################### TAINTED INTEGERS ###################
if "ldc" == i.get_name():
o = i.get_operands()
if o[0] == "CONSTANT_Integer":
self.context.get_tainted_integers().push_info( i, (o[1], idx, self, self.method) )
elif "sipush" in i.get_name():
self.context.get_tainted_integers().push_info( i, (i.get_operands(), idx, self, self.method) )
elif "bipush" in i.get_name():
self.context.get_tainted_integers().push_info( i, (i.get_operands(), idx, self, self.method) )
#########################################################
idx += i.get_length()
def set_exception(self, exception_analysis):
pass
# FIXME : create a recursive function to follow the cfg, because it does not work with obfuscator
def analyze_code(self):
self.analyze_break_blocks()
#print "ANALYZE CODE -->", self.name
d = {}
for i in self.fathers:
# print "\t FATHER ->", i[2].get_name(), i[2].get_stack(), i[0], i[1]
d[ i[0] ] = i[2]
self.free_blocks_offsets.append( self.get_start() )
idx = 0
for i in self.ins:
# print i.get_name(), self.start + idx, idx
# i.show(idx)
if self.start + idx in d:
self.__stack.insert_stack( 0, d[ self.start + idx ].get_stack() )
ret_v = ReturnValues()
res = []
try:
#print i.get_name(), i.get_name() in INSTRUCTIONS_ACTIONS
if INSTRUCTIONS_ACTIONS[ i.get_name() ] == []:
print "[[[[ %s is not yet implemented ]]]]" % i.get_name()
raise("ooops")
i_idx = 0
for actions in INSTRUCTIONS_ACTIONS[ i.get_name() ]:
for action in actions:
action( self.__vm, i, actions[action], self.__stack, res, ret_v )
for val in ret_v.get_return():
res.append( val )
#self.__stack.show()
self.stack_traces.save( idx, i_idx, i, cPickle.dumps( self.__stack ), cPickle.dumps( ret_v.get_msg() ) )
i_idx += 1
except KeyError:
print "[[[[ %s is not in INSTRUCTIONS_ACTIONS ]]]]" % i.get_name()
except IndexError:
print "[[[[ Analysis failed in %s-%s-%s ]]]]" % (self.method.get_class_name(), self.method.get_name(), self.method.get_descriptor())
idx += i.get_length()
if self.__stack.nil() == True and i != self.ins[-1]:
self.free_blocks_offsets.append( idx + self.get_start() )
def show(self):
print "\t@", self.name
idx = 0
nb = 0
for i in self.ins:
print "\t\t", nb, idx,
i.show(nb)
nb += 1
idx += i.get_length()
print ""
print "\t\tFree blocks offsets --->", self.free_blocks_offsets
print "\t\tBreakBlocks --->", len(self.break_blocks)
print "\t\tF --->", ', '.join( i[2].get_name() for i in self.fathers )
print "\t\tC --->", ', '.join( i[2].get_name() for i in self.childs )
self.stack_traces.show()
def get_ins(self):
return self.ins
class JVMBreakBlock(BreakBlock):
def __init__(self, _vm, idx):
super(JVMBreakBlock, self).__init__(_vm, idx)
self.__info = {
"F" : [ "get_field_descriptor", self._fields, ContextField ],
"M" : [ "get_method_descriptor", self._methods, ContextMethod ],
}
def get_free(self):
if self._ins == []:
return False
if "store" in self._ins[-1].get_name():
return True
elif "putfield" in self._ins[-1].get_name():
return True
return False
def analyze(self):
ctt = []
stack = Stack()
for i in self._ins:
v = self.trans(i)
if v != None:
ctt.append( v )
t = ""
for mre in jvm.MATH_JVM_RE:
if mre[0].match( i.get_name() ):
self._ops.append( mre[1] )
break
# Woot it's a field !
if i.get_name() in FIELDS:
t = "F"
elif i.get_name() in METHODS:
t = "M"
if t != "":
o = i.get_operands()
desc = getattr(self._vm, self.__info[t][0])(o[0], o[1], o[2])
# It's an external
if desc == None:
desc = ExternalFM( o[0], o[1], o[2] )
if desc not in self.__info[t][1]:
self.__info[t][1][desc] = []
if t == "F":
self.__info[t][1][desc].append( self.__info[t][2]( FIELDS[ i.get_name() ][0] ) )
# print "RES", res, "-->", desc.get_name()
# self.__tf.push_info( desc, [ FIELDS[ i.get_name() ][0], res ] )
elif t == "M":
self.__info[t][1][desc].append( self.__info[t][2]() )
for i in self._fields:
for k in self._fields[i]:
k.set_details( ctt )
for i in self._methods:
for k in self._methods[i]:
k.set_details( ctt )
def trans(self, i):
v = i.get_name()[0:2]
if v == "il" or v == "ic" or v == "ia" or v == "si" or v == "bi":
return "I"
if v == "ba":
return "B"
if v == "if":
return "IF"
if v == "ir":
return "RET"
if "and" in i.get_name():
return "&"
if "add" in i.get_name():
return "+"
if "sub" in i.get_name():
return "-"
if "xor" in i.get_name():
return "^"
if "ldc" in i.get_name():
return "I"
if "invokevirtual" in i.get_name():
return "M" + i.get_operands()[2]
if "getfield" in i.get_name():
return "F" + i.get_operands()[2]
DVM_FIELDS_ACCESS = {
"iget" : "R",
"iget-wide" : "R",
@ -2156,7 +1350,6 @@ class Exceptions(object):
for i in self.exceptions:
yield i
#BO = { "BasicOPCODES" : jvm.BRANCH2_JVM_OPCODES, "BasicClass" : JVMBasicBlock, "Dnext" : jvm.determineNext, "Dexception" : jvm.determineException }
BO = { "BasicOPCODES" : dvm.BRANCH_DVM_OPCODES, "BasicClass" : DVMBasicBlock, "Dnext" : dvm.determineNext, "Dexception" : dvm.determineException }
BO["BasicOPCODES_H"] = []

View File

@ -16,7 +16,6 @@
# limitations under the License.
from androguard.core import androconf
from androguard.core.bytecodes import jvm
from androguard.core.bytecodes import dvm
from androguard.core.bytecodes import apk
from androguard.core.analysis import analysis
@ -122,11 +121,7 @@ class Androguard(object):
else:
raise( "Unknown format" )
if isinstance(bc, list):
for j in bc:
self.__bc.append( (j[0], BC( jvm.JVMFormat(j[1]) ) ) )
else:
self.__bc.append( (i, BC( bc )) )
self.__bc.append( (i, BC( bc )) )
def ianalyze(self):
for i in self.get_bc():
@ -246,7 +241,7 @@ class AndroguardS(object):
"""
This method returns the VMFormat which correspond to the file
@rtype: L{jvm.JVMFormat} or L{dvm.DalvikVMFormat}
@rtype: L{dvm.DalvikVMFormat}
"""
return self.__a.get_vm()

File diff suppressed because it is too large Load Diff

View File

@ -1,137 +0,0 @@
# This file is part of Androguard.
#
# Copyright (C) 2012 Anthony Desnos <desnos at t0t0.fr>
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import random
from androconf import error
import jvm
class Automaton(object):
def __init__(self, _analysis):
self.__analysis = _analysis
try:
from networkx import DiGraph
from networkx import draw_graphviz, write_dot
except ImportError:
error("module networkx not found")
self.__G = DiGraph()
for m in self.__analysis.get_methods():
for bb in m.basic_blocks.get():
for trace in bb.stack_traces.get():
for mre in jvm.MATH_JVM_RE:
if mre[0].match( trace[2].get_name() ):
for i in trace[3].gets():
self._add( str(i) )
def _add(self, elem):
l = []
x = ""
for i in elem:
if i not in jvm.MATH_JVM_OPCODES.values():
x += i
else:
l.append( x )
l.append( i )
x = ""
if len(l) > 1:
l.append( x )
self._add_expr( l )
def _add_expr(self, l):
if l == []:
return
i = 0
while i < (len(l)-1):
self.__G.add_edge( self._transform(l[i]), self._transform(l[i+1]) )
i += 1
def _transform(self, i):
if "VARIABLE" in i:
return "V"
return i
def new(self, loop):
expr = []
l = list( self.__G.node )
init = l[ random.randint(0, len(l) - 1) ]
while init in jvm.MATH_JVM_OPCODES.values():
init = l[ random.randint(0, len(l) - 1) ]
expr.append( init )
i = 0
while i <= loop:
l = list( self.__G.edge[ init ] )
if l == []:
break
init = l[ random.randint(0, len(l) - 1) ]
expr.append( init )
i += 1
return expr
def show(self):
print self.__G.node
print self.__G.edge
#draw_graphviz(self.__G)
#write_dot(self.__G,'file.dot')
class JVMGenerate(object):
def __init__(self, _vm, _analysis):
self.__vm = _vm
self.__analysis = _analysis
self.__automaton = Automaton( self.__analysis )
self.__automaton.show()
def create_affectation(self, method_name, desc):
l = []
if desc[0] == 0:
l.append( [ "aload_0" ] )
l.append( [ "bipush", desc[2] ] )
l.append( [ "putfield", desc[1].get_name(), desc[1].get_descriptor() ] )
return l
def write(self, method, offset, field):
print method, offset, field
expr = self.__automaton.new( 5 )
print field.get_name(), "EXPR ->", expr
self._transform( expr )
def _transform(self, expr):
if len(expr) == 1:
return
x = [ expr.pop(0), expr.pop(1), expr.pop(0) ]
# while expr != []:

View File

@ -26,7 +26,6 @@ from androguard.core import *
from androguard.core.androgen import *
from androguard.core.androconf import *
from androguard.core.bytecode import *
from androguard.core.bytecodes.jvm import *
from androguard.core.bytecodes.dvm import *
from androguard.core.bytecodes.apk import *
@ -259,23 +258,6 @@ def ExportElfToPython(e):
setattr(e, name, function)
def AnalyzeJAR(filename, raw=False):
androconf.debug("JAR ...")
a = JAR(filename, raw)
d = AnalyzeClasses(a.get_classes())
return a, d
def AnalyzeClasses(classes):
d = {}
for i in classes:
d[i[0]] = JVMFormat(i[1])
return d
def main(options, arguments):
if options.shell != None:
interact()

View File

@ -26,7 +26,6 @@ from androguard.core import *
from androguard.core.androgen import *
from androguard.core.androconf import *
from androguard.core.bytecode import *
from androguard.core.bytecodes.jvm import *
from androguard.core.bytecodes.dvm import *
from androguard.core.bytecodes.apk import *
@ -259,23 +258,6 @@ def ExportElfToPython(e):
setattr(e, name, function)
def AnalyzeJAR(filename, raw=False):
androconf.debug("JAR ...")
a = JAR(filename, raw)
d = AnalyzeClasses(a.get_classes())
return a, d
def AnalyzeClasses(classes):
d = {}
for i in classes:
d[i[0]] = JVMFormat(i[1])
return d
def main(options, arguments):
if options.shell != None:
interact()

View File

@ -1,27 +0,0 @@
#!/usr/bin/env python
import sys
PATH_INSTALL = "./"
sys.path.append(PATH_INSTALL + "/core")
sys.path.append(PATH_INSTALL + "/core/bytecodes")
from androguard.util import read
import jvm
TEST = "./examples/java/test/orig/Test1.class"
j = jvm.JVMFormat( read(TEST, binary=False) )
# SHOW CLASS (verbose)
j.show()
# SHOW FIELDS
for i in j.get_fields():
print i.get_access(), i.get_name(), i.get_descriptor()
print
# SHOW METHODS
for i in j.get_methods():
print i.get_access(), i.get_name(), i.get_descriptor()

View File

@ -1,29 +0,0 @@
#!/usr/bin/env python
import sys, random, string
PATH_INSTALL = "./"
sys.path.append(PATH_INSTALL + "/core")
sys.path.append(PATH_INSTALL + "/core/bytecodes")
from androguard.util import read
import jvm
TEST = "./examples/java/test/orig/Test1.class"
TEST_OUTPUT = "./examples/java/test/new/Test1.class"
j = jvm.JVMFormat( read(TEST, binary=False) )
# Modify the name of each field
for field in j.get_fields():
field.set_name( random.choice( string.letters ) + ''.join([ random.choice(string.letters + string.digits) for i in range(10 - 1) ] ) )
# Modify the name of each method (minus the constructor (<init>) and a extern called method (go))
for method in j.get_methods():
if method.get_name() != "go" and method.get_name() != "<init>":
method.set_name( random.choice( string.letters ) + ''.join([ random.choice(string.letters + string.digits) for i in range(10 - 1) ] ) )
# SAVE CLASS
with open( TEST_OUTPUT, "w" ) as fd:
fd.write( j.save() )

View File

@ -1,27 +0,0 @@
#!/usr/bin/env python
import sys, random, string
PATH_INSTALL = "./"
sys.path.append(PATH_INSTALL + "/core")
sys.path.append(PATH_INSTALL + "/core/bytecodes")
from androguard.util import read
import jvm
TEST = "./examples/java/test/orig/Test1.class"
TEST_REF = "./examples/java/Hello.class"
TEST_OUTPUT = "./examples/java/test/new/Test1.class"
j = jvm.JVMFormat( read(TEST, binary=False) )
j2 = jvm.JVMFormat( read(TEST_REF, binary=False) )
# Insert a craft method :)
j.insert_craft_method( "toto", [ "ACC_PUBLIC", "[B", "[B" ], [ [ "aconst_null" ], [ "areturn" ] ] )
# Insert a method with no dependances methods
j.insert_direct_method( "toto2", j2.get_method("test3")[0] )
# SAVE CLASS
with open( TEST_OUTPUT, "w" ) as fd:
fd.write( j.save() )

View File

@ -1,24 +0,0 @@
#!/usr/bin/env python
import sys, random, string
PATH_INSTALL = "./"
sys.path.append(PATH_INSTALL + "/core")
sys.path.append(PATH_INSTALL + "/core/bytecodes")
from androguard.util import read
import jvm
TEST = "./examples/java/test/orig/Test1.class"
TEST_REF = "./examples/java/Hello.class"
TEST_OUTPUT = "./examples/java/test/new/Test1.class"
j = jvm.JVMFormat( read(TEST, binary=False) )
j2 = jvm.JVMFormat( read(TEST_REF, binary=False) )
# Insert a method with java dependances methods/class
j.insert_direct_method( "toto2", j2.get_method("test5")[0] )
# SAVE CLASS
with open( TEST_OUTPUT, "w" ) as fd:
fd.write( j.save() )

View File

@ -1,24 +0,0 @@
#!/usr/bin/env python
import sys
PATH_INSTALL = "./"
sys.path.append(PATH_INSTALL + "/core")
sys.path.append(PATH_INSTALL + "/core/bytecodes")
sys.path.append(PATH_INSTALL + "/core/analysis")
from androguard.util import read
import jvm, analysis
TEST = "./examples/java/test/orig/Test1.class"
j = jvm.JVMFormat( read(TEST, binary=False) )
x = analysis.VMAnalysis( j )
# SHOW CLASS (verbose and pretty)
#j.pretty_show( x )
# SHOW METHODS
for i in j.get_methods():
print i
i.pretty_show( x )

View File

@ -1,155 +0,0 @@
#!/usr/bin/env python
import sys, re
PATH_INSTALL = "./"
sys.path.append(PATH_INSTALL)
from androguard.core.androgen import AndroguardS
from androguard.core.analysis import analysis
from androguard.core.bytecodes.jvm import BRANCH2_JVM_OPCODES, determineNext
TEST_CASE = 'examples/java/TC/orig/TCE.class'
VALUES = { "TCE <init> ()V" : [
("if_icmpge", [116]),
("if_icmpge", [19]),
("goto", [-18]),
("lookupswitch", [22, 19]),
("lookupswitch", [47, 40, 34, 37]),
("goto", [-123]),
("return", [-1]),
],
}
###############################################
MODIF = { "TCE <init> ()V" : [
("remove_at", 28),
]
}
###############################################
###############################################
MODIF2 = { "TCE <init> ()V" : [
("insert_at", 28, [ "aload_0"]),
]
}
###############################################
###############################################
MODIF3 = { "TCE <init> ()V" : [
("remove_at", 88),
]
}
VALUES3 = { "TCE <init> ()V" : [
("if_icmpge", [113]),
("if_icmpge", [16]),
("goto", [-15]),
("lookupswitch", [22, 19]),
("lookupswitch", [47, 40, 34, 37]),
("goto", [-120]),
("return", [-1]),
],
}
###############################################
###############################################
MODIF4 = { "TCE <init> ()V" : [
("insert_at", 88, [ "sipush", 400 ]),
]
}
###############################################
###############################################
MODIF4 = { "TCE <init> ()V" : [
("insert_at", 88, [ "sipush", 400 ]),
]
}
###############################################
def test(got, expected):
if got == expected:
prefix = ' OK '
else:
prefix = ' X '
print '\t%s got: %s expected: %s' % (prefix, repr(got), repr(expected))
def getVal(i):
op = i.get_operands()
if isinstance(op, int):
return [ op ]
elif i.get_name() == "lookupswitch":
x = []
x.append( i.get_operands().default )
for idx in range(0, i.get_operands().npairs):
off = getattr(i.get_operands(), "offset%d" % idx)
x.append( off )
return x
return [-1]
def check(a, values, branch):
b = []
for i in branch:
b.append( re.compile( i ) )
for method in a.get_methods():
key = method.get_class_name() + " " + method.get_name() + " " + method.get_descriptor()
if key not in values:
continue
print "CHECKING ...", method.get_class_name(), method.get_name(), method.get_descriptor()
code = method.get_code()
bc = code.get_bc()
idx = 0
v = 0
for i in bc.get():
# print "\t", "%x(%d)" % (idx, idx), i.get_name(), i.get_operands()
for j in b:
if j.match(i.get_name()) != None:
elem = values[key][v]
test("%s %s" % (elem[0], elem[1]), "%s %s" % (i.get_name(), getVal(i)))
v += 1
break
idx += i.get_length()
def modify(a, modif):
for method in a.get_methods():
key = method.get_class_name() + " " + method.get_name() + " " + method.get_descriptor()
if key not in modif:
continue
print "MODIFYING ...", method.get_class_name(), method.get_name(), method.get_descriptor()
code = method.get_code()
for i in modif[key]:
getattr( code, i[0] )( *i[1:] )
a = AndroguardS( TEST_CASE )
### INIT CHECK ###
check( a, VALUES, BRANCH2_JVM_OPCODES )
### APPLY MODIFICATION ###
modify( a, MODIF )
### CHECK IF MODIFICATION IS OK ###
check( a, VALUES, BRANCH2_JVM_OPCODES )
modify( a, MODIF2 )
check( a, VALUES, BRANCH2_JVM_OPCODES )
modify( a, MODIF3 )
check( a, VALUES3, BRANCH2_JVM_OPCODES )
modify( a, MODIF4 )
check( a, VALUES, BRANCH2_JVM_OPCODES )