Script Template¶
Use the following as a template to write your custom script.
The basics steps for writing a custom scripts are:
- rename the script class (has to be the same name as the module!)
- change the
AndroScript._analyze()
method to reflect your custom analysis - define the script requirements needed (by default everything is disabled allowing only to access the basic
Apk
class)
Optional:
- use a custom logging object (e.g. to store the data to a file)
- save the results in MongoDBs gridFS if they may exceed 16MB
Note
There is a utility class for disassembling, decompiling, accessing the abstract syntrax tree etc.
Have a look at AnaUtil
This is the template:
# encoding: utf-8
__author__ = "Nils Tobias Schmidt"
__email__ = "schmidt89 at informatik.uni-marburg.de"
from androlyze.model.script.AndroScript import AndroScript
# TODO: RENAME THE SCRIPT AND MODULE NAME!!
from androlyze.model.script.dblyze.DBLyze import DBLyze
from pprint import pprint
class ScriptTemplate(AndroScript):
''' Template for writing a custom `AndroScript` '''
VERSION = "0.1"
def _analyze(self, apk, dalvik_vm_format, vm_analysis, gvm_analysis, *args, **kwargs):
'''
Overwrite this function in apk subclass to build your own script!
Use the `ResultObject` for logging.
Parameters
----------
apk: EAndroApk
dalvik_vm_format: DalvikVMFormat
Parsed .dex file.
Only available if `needs_dalvik_vm_format` returns True.
vm_analysis: VMAnalysis
Dex analyzer.
Only available if `needs_vmanalysis` returns True.
gvm_analysis : GVMAnalysis
'''
# TODO: CUSTOMIZE
#categories
CAT_FILES = "files"
res = self.res
res.register_keys([CAT_FILES])
# files
res.log(CAT_FILES, apk.get_files())
def custom_result_object(self):
'''
Overwrite this method, if you want to use your own result logging framework/object,
You can supply it here and access it via `self.cres`.
E.g. you could return ("", "txt") for simply logging with a string to a .txt file.
The str representation of it will be stored!
The `ResultObject` in `self.res` is still existing and internally used to log some meta information.
Returns
-------
tuple<object, str>
First argument is the result object you want to use,
the second is the file name extension used for storage (without a leading point)
'''
raise NotImplementedError
def reset(self):
'''
Reset the `AndroScript` so that it can be used for a new analysis.
If you do a custom initialization in your script,
you probably want do put the init code inside this method.
Don't forget to call the super `reset` !
'''
super(ScriptTemplate, self).reset()
############################################################
#---Script requirements
############################################################
def needs_dalvik_vm_format(self):
''' Gives access to the `DalvikVMFormat` object which is a parser for the classes.dex file '''
return False
def needs_vmanalysis(self):
''' Gives access to the `VMAnalysis` object which is a analyzer for the `DalvikVMFormat` object '''
return False
def needs_gvmanalysis(self):
''' Gives access to the `GVMAnalysis` object.
Creates a graph which you can use for export (gexf etc) or do your custom stuff
'''
return False
def needs_xref(self):
''' Create cross references '''
return False
def needs_dref(self):
''' Create data references '''
return False
############################################################
#---Options
############################################################
def create_script_stats(self):
''' If true, create some script statistics and
write them into the `ResultObject` '''
return False
def is_big_res(self):
''' Return true, if your result may exceed 16mb.
This will store your data (str() of `self.cres`) in mongodb's gridfs.
You don't need to return true, if you're using a different result object! (see :py:meth:`.custom_result_object`)
This will be done automatically.
'''
return False
class Eval(DBLyze):
# Evaluate ScripTemplate
ON_SCRIPT = ScriptTemplate
def _evaluate(self, storage):
'''
Evaluate the script results.
Parameters
----------
storage : RedundantStorage
'''
# Use either the AndroLyze query API:
# iterate over the results (one result per APK = iteration)
for ordered_dict in self.action_query_result_db():
# do something else than just printing the dictionary
#pprint(dict(ordered_dict))
pass
# Or perform a direct query on the mongodb API:
# get the mongodb singleton
mongodb = storage.result_db_storage
for ordered_dict in mongodb.get_res_coll().find({"script meta.name" : "ScriptTemplate"}, {"apk meta" : 1}):
pprint(dict(ordered_dict))
# testing code
if __name__ == '__main__':
for res in AndroScript.test(ScriptTemplate, ["../../../../testenv/apks/a2dp.Vol.apk"]):
print res
print res.write_to_json()