def main(): parser = ArgumentParser(description="Create a call graph based on the data" "of Analysis and export it into a graph format.") parser.add_argument("APK", nargs=1, help="The APK to analyze") parser.add_argument("--output", "-o", default="callgraph.gml", help="Filename of the output file, the extension is used to decide which format to use (default callgraph.gml)") parser.add_argument("--show", "-s", action="store_true", default=False, help="instead of saving the graph, print it with mathplotlib (you might not see anything!") parser.add_argument("--verbose", "-v", action="store_true", default=False, help="Print more output") parser.add_argument("--classname", default=".*", help="Regex to filter by classname") parser.add_argument("--methodname", default=".*", help="Regex to filter by methodname") parser.add_argument("--descriptor", default=".*", help="Regex to filter by descriptor") parser.add_argument("--accessflag", default=".*", help="Regex to filter by accessflags") parser.add_argument("--no-isolated", default=False, action="store_true", help="Do not store methods which has no xrefs") args = parser.parse_args() if args.verbose: show_logging(logging.INFO) a, d, dx = AnalyzeAPK(args.APK[0]) entry_points = map(FormatClassToJava, a.get_activities() + a.get_providers() + a.get_services() + a.get_receivers()) entry_points = list(entry_points) log.info("Found The following entry points by search AndroidManifest.xml: {}".format(entry_points)) CG = generate_graph(dx, args.classname, args.methodname, args.descriptor, args.accessflag, args.no_isolated, entry_points, ) write_methods = dict(gml=_write_gml, gexf=nx.write_gexf, gpickle=nx.write_gpickle, graphml=nx.write_graphml, yaml=nx.write_yaml, net=nx.write_pajek, ) if args.show: plot(CG) else: writer = args.output.rsplit(".", 1)[1] if writer in ["bz2", "gz"]: writer = args.output.rsplit(".", 2)[1] if writer not in write_methods: print("Could not find a method to export files to {}!".format(writer)) sys.exit(1) write_methods[writer](CG, args.output)
def main(): parser = ArgumentParser(description="Create a call graph based on the data" "of Analysis and export it into a graph format.") parser.add_argument("APK", nargs=1, help="The APK to analyze") parser.add_argument("--output", "-o", default="callgraph.gml", help="Filename of the output file, the extension is used to decide which format to use (default callgraph.gml)") parser.add_argument("--show", "-s", action="store_true", default=False, help="instead of saving the graph, print it with mathplotlib (you might not see anything!") parser.add_argument("--verbose", "-v", action="store_true", default=False, help="Print more output") parser.add_argument("--classname", default=".*", help="Regex to filter by classname") parser.add_argument("--methodname", default=".*", help="Regex to filter by methodname") parser.add_argument("--descriptor", default=".*", help="Regex to filter by descriptor") parser.add_argument("--accessflag", default=".*", help="Regex to filter by accessflags") parser.add_argument("--no-isolated", default=False, action="store_true", help="Do not store methods which has no xrefs") args = parser.parse_args() if args.verbose: show_logging(logging.INFO) a, d, dx = AnalyzeAPK(args.APK[0]) entry_points = map(FormatClassToJava, a.get_activities() + a.get_providers() + a.get_services() + a.get_receivers()) entry_points = list(entry_points) log.info("Found The following entry points by search AndroidManifest.xml: {}".format(entry_points)) CG = dx.get_call_graph(args.classname, args.methodname, args.descriptor, args.accessflag, args.no_isolated, entry_points, ) write_methods = dict(gml=_write_gml, gexf=nx.write_gexf, gpickle=nx.write_gpickle, graphml=nx.write_graphml, yaml=nx.write_yaml, net=nx.write_pajek, ) if args.show: plot(CG) else: writer = args.output.rsplit(".", 1)[1] if writer in ["bz2", "gz"]: writer = args.output.rsplit(".", 2)[1] if writer not in write_methods: print("Could not find a method to export files to {}!".format(writer)) sys.exit(1) write_methods[writer](CG, args.output)
def androcg_main(verbose, APK, classname, methodname, descriptor, accessflag, no_isolated, show, output): from androguard.core.androconf import show_logging from androguard.core.bytecode import FormatClassToJava from androguard.misc import AnalyzeAPK import networkx as nx import logging log = logging.getLogger("androcfg") if verbose: show_logging(logging.INFO) a, d, dx = AnalyzeAPK(APK) entry_points = map(FormatClassToJava, a.get_activities() + a.get_providers() + a.get_services() + a.get_receivers()) entry_points = list(entry_points) log.info("Found The following entry points by search AndroidManifest.xml: " "{}".format(entry_points)) CG = dx.get_call_graph(classname, methodname, descriptor, accessflag, no_isolated, entry_points, ) write_methods = dict(gml=_write_gml, gexf=nx.write_gexf, gpickle=nx.write_gpickle, graphml=nx.write_graphml, yaml=nx.write_yaml, net=nx.write_pajek, ) if show: plot(CG) else: writer = output.rsplit(".", 1)[1] if writer in ["bz2", "gz"]: writer = output.rsplit(".", 2)[1] if writer not in write_methods: print("Could not find a method to export files to {}!" .format(writer)) sys.exit(1) write_methods[writer](CG, output)
def entry_point(verbosity): level = logging.INFO if verbosity == 'verbose': level = logging.DEBUG if verbosity == 'quiet': level = logging.WARNING # If something out of this module is imported, activate console logging if verbosity != 'silent': show_logging(level=level)
def androlyze_main(debug, ddebug, no_session, args_apk): # Import commonly used classes import logging from androguard.core.bytecodes.apk import APK from androguard.core.bytecodes.dvm import DalvikVMFormat from androguard.core.analysis.analysis import Analysis if debug: androconf.show_logging(logging.INFO) if ddebug: androconf.show_logging(logging.DEBUG) # Go interactive! interact(session=not no_session, apk=args_apk)
def compression(apk): """ Test idempotency on actual APK files and return a ranking of compression algorithms This might be very slow and take up to some hours per APK given! """ show_logging() overall_results = collections.defaultdict(list) overall_results_strings = collections.defaultdict(list) if apk == (): # Run a test on random data for _ in tqdm(range(1000)): # Go way beyond the block size b = bytearray([random.randrange(0, 256) for _ in range(100000)]) for k, v in test_idempotency_quant(b): overall_results[k].append(v) print("----> RESULTS FOR BINARY COMPRESSION") print_res(overall_results) return for f in apk: print("-->", f) _, _, dx = AnalyzeAPK(f) sdx = Signature(dx) for s in tqdm(list(dx.strings.keys())): if s == b'': continue for k, v in test_idempotency_quant(s): overall_results_strings[k].append(v) for m in tqdm(list(dx.find_methods(no_external=True))): realmethod = m.get_method() sig = sdx.get_method_signature(realmethod, predef_sign="L0_4").get_string() if sig == b'': continue for k, v in test_idempotency_quant(sig): overall_results[k].append(v) print("----> RESULTS FOR STRING COMPRESSION") print_res(overall_results_strings) print("----> RESULTS FOR METHOD COMPRESSION") print_res(overall_results)
def __init__(self, app_path, output_dir=None): from androguard.core.bytecodes.apk import APK from androguard.core.androconf import show_logging show_logging(level=logging.CRITICAL) self.app_path = app_path self.apk = APK(app_path) self.package_name = self.apk.get_package() self.domain = appdomainmapping.get_domain(self.package_name) self.permissions = self.apk.get_permissions() self.version_name = self.apk.get_androidversion_name() self.receivers = self.apk.get_receivers() self.activities = self.apk.get_activities() self.app_size = self.compute_app_size() # self.possible_broadcasts = self.get_possible_broadcasts() self.exploration_model: Optional[ExplorationModel] = None self.ad_tracking_libraries = set() self.short_name: str = self.get_short_name()
def __init__(self, report_folder, apk=None, txt=None, package_name=None): self.report_folder = report_folder self.apk_file = apk self.text_file = txt self.n_nearest_apps = 15 self.n_top_terms = 25 self.load_from_preprocessed = True # only checks package name, not version, hash, etc. self.app_name = "Unknown App | " + datetime.today().strftime( '%Y-%m-%d %H:%M') self.text = None self.package_name = package_name self.result_file_name = None self.report_saver = ReportSaver(report_folder=report_folder) os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' show_logging(logging.ERROR) # androguard warnings.simplefilter(action='ignore', category=FutureWarning)
def __init__(self, report_folder, apk=None, txt=None, package_name=None): self.report_folder = report_folder self.apk_file = apk self.text_file = txt self.n_nearest_apps = 15 self.n_top_terms = 25 self.load_from_preprocessed = True # only checks package name, not version, hash, etc. self.app_name = "Unknown App | " + datetime.today().strftime( '%Y-%m-%d %H:%M') self.text = None self.package_name = package_name self.result_file_name = None self._preloaded_input_tfidf_model = {} self._preloaded_descriptions_tfidf_model = None self.report_saver = ReportSaver(report_folder=report_folder) os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' show_logging(logging.ERROR) # androguard
def compile_dex(apkfile, filtercfg): show_logging(level=logging.INFO) d = auto_vm(apkfile) dx = analysis.Analysis(d) method_filter = MethodFilter(filtercfg, d) compiler = Dex2C(d, dx) compiled_method_code = {} errors = [] for m in d.get_methods(): method_triple = get_method_triple(m) jni_longname = JniLongName(*method_triple) full_name = ''.join(method_triple) if len(jni_longname) > 220: logger.debug("name to long %s(> 220) %s" % (jni_longname, full_name)) continue if method_filter.should_compile(m): logger.debug("compiling %s" % (full_name)) try: code = compiler.get_source_method(m) except Exception as e: logger.warning("compile method failed:%s (%s)" % (full_name, str(e)), exc_info=True) errors.append('%s:%s' % (full_name, str(e))) continue if code: compiled_method_code[method_triple] = code return compiled_method_code, errors
from collections import defaultdict from pprint import pprint from typing import Union from androguard import misc from androguard.core.analysis.analysis import (ClassAnalysis, ExternalMethod, MethodAnalysis, MethodClassAnalysis) from androguard.core.androconf import show_logging from androguard.core.bytecodes.dvm import EncodedMethod from androguard.decompiler.dad.decompile import DvClass, DvMachine from networkx import shortest_simple_paths from callback_list import callback_list as android_callback_list show_logging(logging.FATAL) apk_file = sys.argv[1].strip() print("Decompiling APK...") start_time = time.time() apk_obj, dalv_format, dx = misc.AnalyzeAPK(apk_file) cg = dx.get_call_graph() print("Getting syntax tree...") machine = DvMachine(apk_file) def format_activity_name(name):
from .stringanalysis import FileAnalysis from androguard.core.analysis.analysis import Analysis from androguard.core.androconf import show_logging from androguard.core.bytecodes.apk import APK from androguard.core.bytecodes.dvm import DalvikVMFormat from androguard.core.analysis.analysis import MethodClassAnalysis from androguard.decompiler.decompiler import DecompilerJADX from androguard.misc import AnalyzeAPK from androguard.core.analysis.analysis import StringAnalysis from .bcolors import bcolors import threading import xml.etree.ElementTree as ET import hashlib from . import smaliparser show_logging(level=logging.CRITICAL) # androguard class MyAPK: def __init__(self, name_file, conf, file_log, tag, string_to_find, logger, api_monitor_dict=None, network_dict=None, dynamic_time=0, use_smaliparser=True):
from tqdm import tqdm import numpy as np import optparse parser = optparse.OptionParser() parser.add_option('-s', '--source-dataset', action="store", dest="dataset_dir", help="Directory of the dataset to process", default="../dataset/") options, args = parser.parse_args() show_logging(level=logging.ERROR) logging.basicConfig(level=logging.ERROR) root_dir = options.dataset_dir dataset_name = "dataset_entropy" def parse_apk(path): """ Parse an apk file to my custom bytecode output :param path: the path to the :rtype: string """ # Load our example APK a = APK(path) # Create DalvikVMFormat Object
#!/usr/bin/python from androguard.misc import * import sys from Crypto.Cipher import ARC4 from androguard.core.androconf import show_logging import logging from base64 import b64decode show_logging(level=logging.FATAL) def dropDex(apkname): try: a, d, dx = AnalyzeAPK(apkname) except Exception as e: print(e) return for c in dx.get_classes(): for m in c.get_methods(): try: source = m.get_method().get_source() if "length" in source: y = m.get_xref_from() dexobj = list(y)[0][1].get_source() v = re.findall(" (.{2,5}) = .{2,5}length", source) v2 = re.findall(" % (.{2,5})\)\]", source) ss = re.findall("= {(.{100,300})};", dexobj) if len(v) > 0: if len(ss) > 0 and v[0] == v2[0]: key = re.findall("(-?[0-9]+),?", ss[0])
from androguard.core.bytecodes.apk import APK from androguard.core.bytecodes.dvm import DalvikVMFormat from androguard.core.analysis.analysis import Analysis from androguard.decompiler.decompiler import DecompilerJADX from androguard.core.androconf import show_logging import logging # Enable log output show_logging(level=logging.DEBUG) # Load our example APK a = APK("examples/android/TestsAndroguard/bin/TestActivity.apk") # Create DalvikVMFormat Object d = DalvikVMFormat(a) # Create Analysis Object dx = Analysis(d) # Load the decompiler # Set the path to the jadx executable! decompiler = DecompilerJADX(d, dx, jadx="/home/vagrant/jadx/build/jadx/bin/jadx") # propagate decompiler and analysis back to DalvikVMFormat d.set_decompiler(decompiler) d.set_vmanalysis(dx) # Now you can do stuff like: for m in d.get_methods()[:10]: print(m) print(decompiler.get_source_method(m))