Skip to content

Instantly share code, notes, and snippets.

@DongShuaike
Last active October 8, 2019 01:55
Show Gist options
  • Save DongShuaike/880b894ca3dfa14279ca987c8c1983fb to your computer and use it in GitHub Desktop.
Save DongShuaike/880b894ca3dfa14279ca987c8c1983fb to your computer and use it in GitHub Desktop.
transform dalvik format (androguard) to soot format (flowdroid)
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