def extract_android_manifest_info(args): input_file = args.manifest entry = args.entry acs = args.activities rs = args.receivers ss = args.services ps = args.providers both = args.both exported = args.exported pm = args.permission if not os.path.isfile(input_file): echo("error", "need apk or AndroidManifest.xml as input file!!", 'red') return elif input_file.endswith('.xml'): axml = AndroidManifestXmlParser(input_file) axml.show_manifest(acs, rs, ss, ps, entry, both, exported, pm) elif input_file.endswith('apk') or input_file.endswith('bin'): # for some reason,we can alse check sample.bin apk_parser = ApkPaser(input_file) if apk_parser.ok(): apk_parser.show_manifest(acs, rs, ss, ps, entry, both, exported, pm) # echo("info", "\n"+str(apk_parser.mainifest_info())) else: echo("error", "unknow {} filtype ".format(input_file), 'red')
def test_virus_file(self): # "/tmp/androyara/allvirusSample/MalwareSamples/TROJAN/5A51DC7F8ABB013758B8D2C9B9A29967D82C80A7C5CEC67E45E46C28A55AA84D.APK" apk_file = "/tmp/androyara/allvirusSample/virussample/virussamplevirus5.apk" if not os.path.isfile(apk_file): return apk_parser = ApkPaser(apk_file) print(json.dumps(apk_parser.apk_base_info(), indent=2))
def apk_info(args): """ 默认输出apk内的基本信息 apk的指纹信息 AndroidManifest.xml内的信息 使用-z --zipinfo 读取apk内的所有文件名信息 """ input_file = args.apk zip_info = args.zipinfo dex_num = args.dexnum info = args.info suffix = args.suffix # like .apk,.APK,.bin if suffix is None: suffix = ".apk,.APK" if input_file is None or not os.path.isfile(input_file): echo("error", "need a apk file as input.", "red") sys.exit(1) # 可以是任意文件,内部如果读取失败,则会直接异常 # found = False # for s in suffix.split(","): # if input_file.endswith(s): # #echo("error", "need a apk file", 'red') # # return # found = True # if found is False: # echo("error", "need a apk file", 'red') # return start = time.time() apk_parser = ApkPaser(input_file) if dex_num: for dexname in apk_parser.get_all_dexs(name=True): echo("dexname", dexname) print("costs: {}".format(time.time() - start)) if info: base_info = apk_parser.apk_base_info() print("") echo("AppName", base_info['app_name']) if base_info['packer_name'] != "N/A": echo("packer", "App may be packed by {}".format(base_info['packer_name']), color="red") print("") echo("apkInfo", "\n{}".format(json.dumps(base_info, indent=2)), "yellow") print("--" * 20) print("costs: {}".format(time.time() - start)) if zip_info: for f in apk_parser.get_file_names(): echo("info", "-> %s" % (f))
def test_apk(self): # app-release-v3-signed.apk : v1+v2+v3 signed app-release.apk v1+v2 signed # tencent apk aaa.apk v1+v2 signature # check signature command : /path/to/sdk/build-tools/30.0.2/apksinger verify --print-certs test.apk # signed with v3 : /path/to/sdk/build-tools/30.0.2/apksinger sign --ks my.jsk --v3-signed-enabled true test.apk for f in [sample+os.sep+"samples"+os.sep+"aaa.apk"]: apk = ApkPaser(f) print("--"*10+"apk info "+"--"*10) print(json.dumps(apk.apk_base_info(), indent=2)) print(apk.apk_base_info()) # vm = DexFileVM(apk.package,apk.get_classe_dex()) # vm.build_map() # dex = DexHeader(apk.get_classe_dex()) # dex.read_all(apk.package) pass
def __init__(self, apk, rule=None, pattern=None): self.ok = True self.rule = rule # rule file self.pattern = pattern # string pattern self.filename = apk self.rules = None try: # echo("info", " analysis : {}".format(apk)) self.apk_parser = ApkPaser(apk) except FileNotFound: self.ok = False return except Exception as e: # echo("error", " parser \"{}\" error ,exception: {}".format(apk, e), 'red') self.ok = False return self.vt = VT(self.apk_parser._app_sha256)
def match(self, f): """ f: a apk or dex file or sample ,it must be dex or apk. """ rsult = None dex = False if f.endswith(".dex"): dex = True def show_result(rsult, susp): for name in self.yara_namespace: if rsult.get(name, None) is None: continue for r in rsult[name]: tag = r['tags'][0] if r['matches']: echo( "rule", " %s/%s %s\t%s" % (tag, r['rule'], self.yara_namespace[name], susp), 'yellow') return if dex: with open(f, 'rb') as fp: result = self.yara_rule.match(data=fp.read()) show_result(result, f) # return result apk_parser = ApkPaser(f) if not apk_parser.ok(): return for _, buff in apk_parser.get_all_dexs(): rsult = self.yara_rule.match(data=buff) # print(rsult) # {'main': [{'tags': ['Android'], 'meta': {'author': 'loopher'}, 'strings': [{'data': 'http://ksjajsxccb.com/api/index/information', 'offset': 2514313, 'identifier': '$str', 'flags': 19}], 'rule': 'BYL_bank_trojan', 'matches': True}]} show_result(rsult, f)
def extract_apk_info(args): input_file = args.apk pattern = args.string method_name_arg = args.method clazz_name = args.clazz dump = args.print_ins save = args.save # save strings or methods # if save: # echo("save", "date save at "+f) executor = ThreadPoolExecutor(max_workers=4) files = [] def show_info(parser, dexname, vm): echo("dexname", "--> %s" % (dexname)) if save: f = os.getcwd() + os.sep + "%s.txt" % (dexname) files.append(f) if os.path.isfile(f): os.remove(f) if pattern is not None: # default all dex data for s in parser.all_strings([pattern], dex_vm=vm): if save: save_file(f, s) else: try: echo("string", "%s" % (s), 'yellow') except UnicodeDecodeError as e: print("--> Unicode error ,string type {}".format( type(s))) raise e if method_name_arg is not None: apk_parser.analysis_dex(clazz_name, method_name_arg, dump, dex_vm=dex_vm) if save: for f in files: echo("save", "data save at " + f) if input_file is None or not os.path.isfile(input_file): echo("error", "need a apk file : %s" % (input_file), 'red') return if pattern is None: echo("warning", "no string specificed", 'yellow') # pattern = '' apk_parser = ApkPaser(input_file) if not apk_parser.ok(): return workers = [] for dexname, dex_vm in apk_parser.all_dex_vms(): workers.append( executor.submit(fn=show_info, parser=apk_parser, dexname=dexname, vm=dex_vm)) # pass for t in as_completed(workers): t.result()
class AnalyzerApk(object): def __init__(self, apk, rule=None, pattern=None): self.ok = True self.rule = rule # rule file self.pattern = pattern # string pattern self.filename = apk self.rules = None try: # echo("info", " analysis : {}".format(apk)) self.apk_parser = ApkPaser(apk) except FileNotFound: self.ok = False return except Exception as e: # echo("error", " parser \"{}\" error ,exception: {}".format(apk, e), 'red') self.ok = False return self.vt = VT(self.apk_parser._app_sha256) def __analyzer_string(self): """ need pattern or rule file """ for rule in self.rules: ss = self.apk_parser.all_strings(rule['patters']) if len(ss) > 0: echo("info", "rule: {} {} ".format(rule['name'], self.filename)) return True return False def __analyzer_method(self): """ check method ,need rule file """ # echo("info", "to be continue...") pass def __read_rule(self): with open(self.rule, 'r') as fp: config = json.load(fp) result = [] for rule in config['rules']: item = { "name": rule['name'], "patters": [], "shell_s": [], "file_type": "" } for k, v in rule.items(): if k.startswith("string"): if v is None or v == '': continue item['patters'].append(v) elif k.startswith("shell_code"): item['shell_s'].append(v) elif k == 'file_type': item['file_type'] = v result.append(item) return result def _online_sandbox(self): result = self.vt.analysis() if result is None: return False echo("info", "VT query reult:") echo("positives", result['positives'], "magenta") echo("virusName", result['virusName'], "red") echo("link", result['link'], "green") echo("scanDate", result['scanDate'], "yellow") echo("path", self.filename, "white") return True def analyzer(self): if not self.ok: return False elif not os.path.isfile(self.rule): echo("error", "need rule file!!", 'red') return False elif not self.apk_parser.ok: echo("error", " {} is not a apk file !!!", 'red') return False self.rules = self.__read_rule() return self.__analyzer_string()\ or self.__analyzer_method()\ or self._online_sandbox()