-
-
Save DongShuaike/880b894ca3dfa14279ca987c8c1983fb to your computer and use it in GitHub Desktop.
transform dalvik format (androguard) to soot format (flowdroid)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from androguard import misc | |
""" | |
The info of methods given by androguard has a different format between that given by Soot. | |
To facilitate the FlowDroid tool, I implemented the tool to transform the format. | |
The script works on Androguard 3.0-dev. | |
The main function is getFuncNames(), we use androguard API AnalyzeAPK to traverse all functions in all classes | |
and transform them into soot formats. | |
""" | |
def classname_handler(class_name): | |
if class_name[0] == 'L': | |
class_name = class_name[1:] | |
elif class_name[0] == '[' and class_name[1] == 'L': | |
class_name = class_name[2:] | |
class_name = class_name.replace('/', '.') | |
class_name = class_name[:-1] # remove ';' | |
return class_name | |
def basictype_handler(typ): | |
res = None | |
if typ == 'Z': | |
res = 'boolean' | |
elif typ == 'B': | |
res = 'byte' | |
elif typ == 'S': | |
res = 'short' | |
elif typ == 'C': | |
res = 'char' | |
elif typ == 'I': | |
res = 'int' | |
elif typ == 'J': | |
res = 'long' | |
elif typ == 'F': | |
res = 'float' | |
elif typ == 'D': | |
res = 'double' | |
elif typ == 'V': | |
res = 'void' | |
return res | |
def type_handler(typ): | |
if len(typ) == 1: | |
return basictype_handler(typ) | |
elif len(typ) == 2: | |
return basictype_handler(typ[1:])+'[]' | |
else: | |
if typ[0] == '[': | |
return classname_handler(typ[1:])+'[]' | |
else: | |
return classname_handler(typ) | |
def descriptor_handler(descriptor): | |
#(Ljava/lang/String; Ljava/lang/String; Ljavax/naming/directory/SearchControls;)Ljavax/naming/NamingEnumeration; | |
soot_param = '(' | |
tmp = descriptor.split(')') | |
# handle parameters | |
param = tmp[0][1:] # remove '(' | |
if len(param)==0: | |
soot_param += ')' | |
else: | |
params = param.split(' ') | |
for p in params: | |
soot_param += type_handler(p)+',' | |
soot_param = soot_param[:-1] # remove ',' | |
soot_param += ')' | |
# handle return value | |
ret = tmp[1] | |
soot_ret = type_handler(ret) | |
return soot_param, soot_ret | |
def combiner(classname, funcname, descriptor): | |
""" | |
:param classname: result of clazz.get_vm_class().name | |
:param funcname: result of func.get_method().name | |
:param descriptor: result of func.get_method().get_descriptor() | |
:return: soot format | |
""" | |
""" | |
TODO: Note that we do not handle <init> and <clinit> | |
""" | |
print('classname', classname) | |
print('funcname', funcname) | |
print('descriptor', descriptor) | |
soot_param, soot_ret = descriptor_handler(descriptor) | |
soot_val = '<' + classname_handler(classname) + ': ' + soot_ret + ' ' + funcname + soot_param + '>' | |
return soot_val | |
def getFuncNames(sess, apkPath, patterns=None): | |
""" | |
:param sess: a session object | |
:param apkPath: The path to apk file | |
:return: | |
""" | |
clazzList = [] | |
funcList = [] | |
a, d, dx = misc.AnalyzeAPK(apkPath) | |
for clazz in dx.get_classes(): | |
name = clazz.get_vm_class().name | |
""" | |
Here add your filter | |
""" | |
clazzList.append(clazz) | |
print(name) | |
for clazz in clazzList: | |
funcs = clazz.get_methods() | |
class_name = clazz.get_vm_class().name | |
for func in funcs: | |
func_desp = func.get_method().get_descriptor() | |
func_name = func.get_method().name | |
soot_val = combiner(class_name, func_name, func_desp) | |
funcList.append(soot_val) | |
return funcList | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment