diff --git a/app.py b/app.py index 09bb8a8..7bbc873 100644 --- a/app.py +++ b/app.py @@ -13,19 +13,28 @@ from libs.task.base_task import BaseTask def cli(): pass + # 创建Android任务 @cli.command(help="Get the key information of Android system.") -@click.option("-i", "--inputs", required=True, type=str, help="Please enter the APK file or DEX file to be scanned or the corresponding APK download address.") -@click.option("-r", "--rules", required=False, type=str, default="", help="Please enter a rule for temporary scanning of file contents.") -@click.option("-s", "--sniffer", is_flag=True, default=False, help="Enable the network sniffer function. It is on by default.") -@click.option("-n", '--no-resource', is_flag=True, default=False, help="Ignore all resource files, including network sniffing. It is not enabled by default.") -@click.option("-a", '--all', is_flag=True, default=False, help="Output the string content that conforms to the scan rules.It is on by default.") -@click.option("-t", '--threads', required=False, type=int, default=10, help="Set the number of concurrency. The larger the concurrency, the faster the speed. The default value is 10.") +@click.option("-i", "--inputs", required=True, type=str, + help="Please enter the APK file or DEX file to be scanned or the corresponding APK download address.") +@click.option("-r", "--rules", required=False, type=str, default="", + help="Please enter a rule for temporary scanning of file contents.") +@click.option("-s", "--sniffer", is_flag=True, default=False, + help="Enable the network sniffer function. It is on by default.") +@click.option("-n", '--no-resource', is_flag=True, default=False, + help="Ignore all resource files, including network sniffing. It is not enabled by default.") +@click.option("-a", '--all', is_flag=True, default=False, + help="Output the string content that conforms to the scan rules.It is on by default.") +@click.option("-t", '--threads', required=False, type=int, default=10, + help="Set the number of concurrency. The larger the concurrency, the faster the speed. The default value is 10.") @click.option("-o", '--output', required=False, type=str, default=None, help="Specify the result set output directory.") -@click.option("-p", '--package', required=False, type=str, default="", help="Specifies the package name information that needs to be scanned.") -def android(inputs: str, rules: str, sniffer: bool, no_resource: bool, all: bool, threads: int, output, package: str) -> None: +@click.option("-p", '--package', required=False, type=str, default="", + help="Specifies the package name information that needs to be scanned.") +def android(inputs: str, rules: str, sniffer: bool, no_resource: bool, all: bool, threads: int, output, + package: str) -> None: try: bootstrapper = Bootstrapper(__file__, output, all, no_resource) bootstrapper.init() @@ -36,12 +45,18 @@ def android(inputs: str, rules: str, sniffer: bool, no_resource: bool, all: bool @cli.command(help="Get the key information of iOS system.") -@click.option("-i", "--inputs", required=True, type=str, help="Please enter IPA file or ELF file to scan or corresponding IPA download address. App store is not supported at present.") -@click.option("-r", "--rules", required=False, type=str, default="", help="Please enter a rule for temporary scanning of file contents.") -@click.option("-s", "--sniffer", is_flag=True, default=False, help="Enable the network sniffer function. It is on by default.") -@click.option("-n", '--no-resource', is_flag=True, default=False, help="Ignore all resource files, including network sniffing. It is not enabled by default.") -@click.option("-a", '--all', is_flag=True, default=False, help="Output the string content that conforms to the scan rules.It is on by default.") -@click.option("-t", '--threads', required=False, type=int, default=10, help="Set the number of concurrency. The larger the concurrency, the faster the speed. The default value is 10.") +@click.option("-i", "--inputs", required=True, type=str, + help="Please enter IPA file or ELF file to scan or corresponding IPA download address. App store is not supported at present.") +@click.option("-r", "--rules", required=False, type=str, default="", + help="Please enter a rule for temporary scanning of file contents.") +@click.option("-s", "--sniffer", is_flag=True, default=False, + help="Enable the network sniffer function. It is on by default.") +@click.option("-n", '--no-resource', is_flag=True, default=False, + help="Ignore all resource files, including network sniffing. It is not enabled by default.") +@click.option("-a", '--all', is_flag=True, default=False, + help="Output the string content that conforms to the scan rules.It is on by default.") +@click.option("-t", '--threads', required=False, type=int, default=10, + help="Set the number of concurrency. The larger the concurrency, the faster the speed. The default value is 10.") @click.option("-o", '--output', required=False, type=str, default=None, help="Specify the result set output directory.") def ios(inputs: str, rules: str, sniffer: bool, no_resource: bool, all: bool, threads: int, output: str) -> None: try: @@ -54,12 +69,18 @@ def ios(inputs: str, rules: str, sniffer: bool, no_resource: bool, all: bool, th @cli.command(help="Get the key information of Web system.") -@click.option("-i", "--inputs", required=True, type=str, help="Please enter the site directory or site file to scan or the corresponding site download address.") -@click.option("-r", "--rules", required=False, type=str, default="", help="Please enter a rule for temporary scanning of file contents.") -@click.option("-s", "--sniffer", is_flag=True, default=False, help="Enable the network sniffer function. It is on by default.") -@click.option("-n", '--no-resource', is_flag=True, default=False, help="Ignore all resource files, including network sniffing. It is not enabled by default.") -@click.option("-a", '--all', is_flag=True, default=False, help="Output the string content that conforms to the scan rules.It is on by default.") -@click.option("-t", '--threads', required=False, type=int, default=10, help="Set the number of concurrency. The larger the concurrency, the faster the speed. The default value is 10.") +@click.option("-i", "--inputs", required=True, type=str, + help="Please enter the site directory or site file to scan or the corresponding site download address.") +@click.option("-r", "--rules", required=False, type=str, default="", + help="Please enter a rule for temporary scanning of file contents.") +@click.option("-s", "--sniffer", is_flag=True, default=False, + help="Enable the network sniffer function. It is on by default.") +@click.option("-n", '--no-resource', is_flag=True, default=False, + help="Ignore all resource files, including network sniffing. It is not enabled by default.") +@click.option("-a", '--all', is_flag=True, default=False, + help="Output the string content that conforms to the scan rules.It is on by default.") +@click.option("-t", '--threads', required=False, type=int, default=10, + help="Set the number of concurrency. The larger the concurrency, the faster the speed. The default value is 10.") @click.option("-o", '--output', required=False, type=str, default=None, help="Specify the result set output directory.") def web(inputs: str, rules: str, sniffer: bool, no_resource: bool, all: bool, threads: int, output: str) -> None: try: diff --git a/libs/core/__init__.py b/libs/core/__init__.py index febe6b3..693fe7c 100644 --- a/libs/core/__init__.py +++ b/libs/core/__init__.py @@ -16,6 +16,16 @@ backsmali_path = "" # apktool 所在路径 apktool_path = "" +# adb 所在路径 +adb_path = "" + +# frida server 所在路径 +frida32_path = "" +frida64_path = "" + +# aapt 所在路径 +aapt_apth = "" + # 系统类型 os_type = "" @@ -28,12 +38,17 @@ download_flag = False # excel 起始行号 excel_row = 1 + class Bootstrapper(object): - def __init__(self, path, out_path, all=False, no_resource= False): + def __init__(self, path, out_path, all=False, no_resource=False): global smali_path global backsmali_path global apktool_path + global adb_path + global frida32_path + global frida64_path + global aapt_apth global os_type global output_path global script_root_dir @@ -43,44 +58,48 @@ class Bootstrapper(object): global history_path global app_history_path global domain_history_path - global excel_row + global excel_row global download_path global download_flag global out_dir global all_flag - global resource_flag + global resource_flag all_flag = not all resource_flag = no_resource create_time = time.strftime("%Y%m%d%H%M%S", time.localtime()) - script_root_dir = os.path.dirname(os.path.abspath(path)) + script_root_dir = os.path.dirname(os.path.abspath(path)) if out_path: out_dir = out_path else: out_dir = script_root_dir - tools_dir = os.path.join(script_root_dir,"tools") - output_path = os.path.join(out_dir,"out") - history_path = os.path.join(script_root_dir,"history") - + tools_dir = os.path.join(script_root_dir, "tools") + output_path = os.path.join(out_dir, "out") + history_path = os.path.join(script_root_dir, "history") + if platform.system() == "Windows": - machine2bits = {'AMD64':64, 'x86_64': 64, 'i386': 32, 'x86': 32} + machine2bits = {'AMD64': 64, 'x86_64': 64, 'i386': 32, 'x86': 32} machine2bits.get(platform.machine()) if platform.machine() == 'i386' or platform.machine() == 'x86': - strings_path = os.path.join(tools_dir,"strings.exe") + strings_path = os.path.join(tools_dir, "strings.exe") else: - strings_path = os.path.join(tools_dir,"strings64.exe") + strings_path = os.path.join(tools_dir, "strings64.exe") else: - strings_path ="strings" - - backsmali_path = os.path.join(tools_dir,"baksmali.jar") + strings_path = "strings" + + backsmali_path = os.path.join(tools_dir, "baksmali.jar") apktool_path = os.path.join(tools_dir, "apktool.jar") - download_path = os.path.join(out_dir,"download") - txt_result_path = os.path.join(out_dir,"result_"+str(create_time)+".txt") - xls_result_path = os.path.join(out_dir,"result_"+str(create_time)+".xlsx") - app_history_path = os.path.join(history_path,"app_history.txt") - domain_history_path = os.path.join(history_path,"domain_history.txt") + adb_path = os.path.join(tools_dir + '\\unpacker', "adb.exe") + frida32_path = os.path.join(tools_dir + '\\unpacker', "hexl-server-arm32") + frida64_path = os.path.join(tools_dir + '\\unpacker', "hexl-server-arm64") + aapt_apth = os.path.join(tools_dir + '\\unpacker', "aapt.exe") + download_path = os.path.join(out_dir, "download") + txt_result_path = os.path.join(out_dir, "result_" + str(create_time) + ".txt") + xls_result_path = os.path.join(out_dir, "result_" + str(create_time) + ".xlsx") + app_history_path = os.path.join(history_path, "app_history.txt") + domain_history_path = os.path.join(history_path, "domain_history.txt") def init(self): if not os.path.exists(out_dir): @@ -95,7 +114,7 @@ class Bootstrapper(object): if not (platform.system() == "Windows"): raise e self.__removed_dirs_cmd__(output_path) - + os.makedirs(output_path) print("[*] Create directory {}".format(output_path)) @@ -106,22 +125,22 @@ class Bootstrapper(object): if not os.path.exists(history_path): os.makedirs(history_path) print("[*] Create directory {}".format(history_path)) - + if os.path.exists(txt_result_path): os.remove(txt_result_path) if os.path.exists(xls_result_path): os.remove(xls_result_path) - - def __removed_dirs_cmd__(self,output_path): + + def __removed_dirs_cmd__(self, output_path): files = os.listdir(output_path) for file in files: - new_dir = os.path.join(output_path,"newdir") - old_dir = os.path.join(output_path,file) + new_dir = os.path.join(output_path, "newdir") + old_dir = os.path.join(output_path, file) if not os.path.exists(new_dir): os.makedirs(new_dir) os.chdir(output_path) cmd = ("robocopy %s %s /purge") % (new_dir, old_dir) os.system(cmd) os.removedirs(new_dir) - os.removedirs(old_dir) \ No newline at end of file + os.removedirs(old_dir) diff --git a/libs/task/android_task.py b/libs/task/android_task.py index 8a03a0e..0583c2c 100644 --- a/libs/task/android_task.py +++ b/libs/task/android_task.py @@ -2,10 +2,16 @@ # -*- coding: utf-8 -*- # Author: kelvinBen # Github: https://github.com/kelvinBen/AppInfoScanner +import json import os import re +import shutil +import subprocess + import config import hashlib +import zipfile +import platform from queue import Queue import libs.core as cores @@ -21,14 +27,279 @@ class AndroidTask(object): self.comp_list = [] self.file_identifier = [] self.permissions = [] + self.files = [] + self.protect_flag = """{ + "360加固": [ + "assets/.appkey", + "assets/libjiagu.so", + "libjiagu.so", + "libjiagu_art.so", + "libjiagu_x86.so", + "libprotectClass.so", + ".appkey", + "1ibjgdtc.so", + "libjgdtc.so", + "libjgdtc_a64.so", + "libjgdtc_art.so", + "libjgdtc_x64.so", + "libjgdtc_x86.so", + "libjiagu_a64.so", + "libjiagu_ls.so", + "libjiagu_x64.so" + ], + "APKProtect": [ + "libAPKProtect.so" + ], + "UU安全": [ + "libuusafe.jar.so", + "libuusafe.so", + "libuusafeempty.so", + "assets/libuusafe.jar.so", + "assets/libuusafe.so", + "lib/armeabi/libuusafeempty.so" + ], + "apktoolplus": [ + "assets/jiagu_data.bin", + "assets/sign.bin", + "jiagu_data.bin", + "lib/armeabi/libapktoolplus_jiagu.so", + "libapktoolplus_jiagu.so", + "sign.bin" + ], + "中国移动加固": [ + "assets/mogosec_classes", + "assets/mogosec_data", + "assets/mogosec_dexinfo", + "assets/mogosec_march", + "ibmogosecurity.so", + "lib/armeabi/libcmvmp.so", + "lib/armeabi/libmogosec_dex.so", + "lib/armeabi/libmogosec_sodecrypt.so", + "lib/armeabi/libmogosecurity.so", + "libcmvmp.so", + "libmogosec_dex.so", + "libmogosec_sodecrypt.so", + "mogosec_classes", + "mogosec_data", + "mogosec_dexinfo", + "mogosec_march" + ], + "几维安全": [ + "assets/dex.dat", + "lib/armeabi/kdpdata.so", + "lib/armeabi/libkdp.so", + "lib/armeabi/libkwscmm.so", + "libkwscmm.so", + "libkwscr.so", + "libkwslinker.so" + ], + "启明星辰": [ + "libvenSec.so", + "libvenustech.so" + ], + "网秦加固": [ + "libnqshield.so" + ], + "娜迦加固": [ + "libchaosvmp.so", + "libddog.so", + "libfdog.so" + ], + "娜迦加固(新版2022)": [ + "assets/maindata/fake_classes.dex", + "lib/armeabi/libxloader.so", + "lib/armeabi-v7a/libxloader.so", + "lib/arm64-v8a/libxloader.so", + "libxloader.so" + ], + "娜迦加固(企业版)": [ + "libedog.so" + ], + "梆梆安全(企业版)": [ + "libDexHelper-x86.so", + "libDexHelper.so", + "1ibDexHelper.so" + ], + "梆梆安全": [ + "libSecShell.so", + "libsecexe.so", + "libsecmain.so", + "libSecShel1.so" + ], + "梆梆安全(定制版)": [ + "assets/classes.jar", + "lib/armeabi/DexHelper.so" + ], + "梆梆安全(免费版)": [ + "assets/secData0.jar", + "lib/armeabi/libSecShell-x86.so", + "lib/armeabi/libSecShell.so" + ], + "海云安加固": [ + "assets/itse", + "lib/armeabi/libitsec.so", + "libitsec.so" + ], + "爱加密": [ + "assets/af.bin", + "assets/ijiami.ajm", + "assets/ijm_lib/X86/libexec.so", + "assets/ijm_lib/armeabi/libexec.so", + "assets/signed.bin", + "ijiami.dat", + "lib/armeabi/libexecmain.so", + "libexecmain.so" + ], + "爱加密企业版": [ + "ijiami.ajm" + ], + "珊瑚灵御": [ + "assets/libreincp.so", + "assets/libreincp_x86.so", + "libreincp.so", + "libreincp_x86.so" + ], + "瑞星加固": [ + "librsprotect.so" + ], + "百度加固": [ + "libbaiduprotect.so", + "assets/baiduprotect.jar", + "assets/baiduprotect1.jar", + "baiduprotect1.jar", + "lib/armeabi/libbaiduprotect.so", + "libbaiduprotect_art.so", + "libbaiduprotect_x86.so" + ], + "盛大加固": [ + "libapssec.so" + ], + "网易易盾": [ + "libnesec.so" + ], + "腾讯": [ + "libexec.so", + "libshell.so" + ], + "腾讯加固": [ + "lib/armeabi/mix.dex", + "lib/armeabi/mixz.dex", + "lib/armeabi/libshella-xxxx.so", + "lib/armeabi/libshellx-xxxx.so", + "tencent_stub" + ], + "腾讯乐固(旧版)": [ + "libtup.so", + "mix.dex", + "liblegudb.so", + "libshella", + "mixz.dex", + "libshel1x" + ], + "腾讯乐固": [ + "libshellx" + ], + "腾讯乐固(VMP)": [ + "lib/arm64-v8a/libxgVipSecurity.so", + "lib/armeabi-v7a/libxgVipSecurity.so", + "libxgVipSecurity.so" + ], + "腾讯云": [ + "assets/libshellx-super.2021.so", + "lib/armeabi/libshell-super.2019.so", + "lib/armeabi/libshell-super.2020.so", + "lib/armeabi/libshell-super.2021.so", + "lib/armeabi/libshell-super.2022.so", + "lib/armeabi/libshell-super.2023.so", + "tencent_sub" + ], + "腾讯云移动应用安全": [ + "0000000lllll.dex", + "00000olllll.dex", + "000O00ll111l.dex", + "00O000ll111l.dex", + "0OO00l111l1l", + "o0oooOO0ooOo.dat" + ], + "腾讯云移动应用安全(腾讯御安全)": [ + "libBugly-yaq.so", + "libshell-super.2019.so", + "libshellx-super.2019.so", + "libzBugly-yaq.so", + "t86", + "tosprotection", + "tosversion", + "000000011111.dex", + "000000111111.dex", + "000001111111", + "00000o11111.dex", + "o0ooo000oo0o.dat" + ], + "腾讯御安全": [ + "libtosprotection.armeabi-v7a.so", + "libtosprotection.armeabi.so", + "libtosprotection.x86.so", + "assets/libtosprotection.armeabi-v7a.so", + "assets/libtosprotection.armeabi.so", + "assets/libtosprotection.x86.so", + "assets/tosversion", + "lib/armeabi/libTmsdk-xxx-mfr.so", + "lib/armeabi/libtest.so" + ], + "腾讯Bugly": [ + "lib/arm64-v8a/libBugly.so", + "libBugly.so" + ], + "蛮犀": [ + "assets/mxsafe.config", + "assets/mxsafe.data", + "assets/mxsafe.jar", + "assets/mxsafe/arm64-v8a/libdSafeShell.so", + "assets/mxsafe/x86_64/libdSafeShell.so", + "libdSafeShell.so" + ], + "通付盾": [ + "libNSaferOnly.so", + "libegis.so" + ], + "阿里加固": [ + "assets/armeabi/libfakejni.so", + "assets/armeabi/libzuma.so", + "assets/classes.dex.dat", + "assets/dp.arm-v7.so.dat", + "assets/dp.arm.so.dat", + "assets/libpreverify1.so", + "assets/libzuma.so", + "assets/libzumadata.so", + "dexprotect" + ], + "阿里聚安全": [ + "aliprotect.dat", + "libdemolish.so", + "libfakejni.so", + "libmobisec.so", + "libsgmain.so", + "libzuma.so", + "libzumadata.so", + "libdemolishdata.so", + "libpreverify1.so", + "libsgsecuritybody.so" + ], + "顶像科技": [ + "libx3g.so", + "lib/armeabi/libx3g.so" + ] + }""" def start(self): # 检查java环境是否存在 if os.system("java -version") != 0: raise Exception("Please install the Java environment!") + # 检查Frida环境是否存在 + if os.system("frida --version") != 0: + raise Exception("Please install the Frida environment!") input_file_path = self.path - if os.path.isdir(input_file_path): self.__decode_dir__(input_file_path) else: @@ -36,7 +307,68 @@ class AndroidTask(object): raise Exception( "Retrieval of this file type is not supported. Select APK file or DEX file.") - return {"comp_list": self.comp_list, "shell_flag": self.shell_flag, "file_queue": self.file_queue, "packagename": self.packagename, "file_identifier": self.file_identifier, "permissions": self.permissions} + return {"comp_list": self.comp_list, "shell_flag": self.shell_flag, "file_queue": self.file_queue, + "packagename": self.packagename, "file_identifier": self.file_identifier, + "permissions": self.permissions} + + def __detect_protect__(self, file_path): + markNameMap = json.loads(self.protect_flag) + markNameMap = dict(markNameMap) + zip_stream = zipfile.ZipFile(file_path) # 默认模式r,读 + flag = '' + for zippath in zip_stream.namelist(): + if 'lib' in zippath: + for key, value in markNameMap.items(): + for mark in value: + if mark in zippath: + print("detect 【{}】 protector\nspecific code:{}->{}\n".format(key, zippath, mark)) + flag += ("detect 【{}】 protector\nspecific code:{}->{}\n".format(key, zippath, mark)) + if len(flag) > 0: + self.__android_unpack__() + # so库文件模式找不到就全量匹配 + for zippath in zip_stream.namelist(): + for key, value in markNameMap.items(): + for mark in value: + if mark in zippath: + print("detect 【{}】 protector\nspecific code:{}->{}\n".format(key, zippath, mark)) + flag += ("detect 【{}】 protector\nspecific code:{}->{}\n".format(key, zippath, mark)) + if len(flag) > 0: + self.__android_unpack__() + print("We can't detect protect") + + def __android_unpack__(self): + print('[*] unpacking') + cmd_str = ('%s install %s') % (str(cores.adb_path), str(self.path)) + print('[*] Install the APK') + if os.system(cmd_str) == 0: + print("Push Frida Server") + cmd_str = ('%s push %s /data/local/tmp') % (str(cores.adb_path), str(cores.frida32_path)) + cmd_str1 = ('%s push %s /data/local/tmp') % (str(cores.adb_path), str(cores.frida64_path)) + cmd_str2 = ('%s shell su -c "chmod 777 /data/local/tmp/hexl-server-arm64"') % (str(cores.adb_path)) + cmd_str3 = ('%s shell su -c "setenforce 0"') % (str(cores.adb_path)) + cmd_str4 = ('%s shell su -c "./data/local/tmp/hexl-server-arm64 &"') % (str(cores.adb_path)) + print("[*] Running Frida Server") + if os.system(cmd_str) == 0 and os.system(cmd_str1) == 0 and os.system(cmd_str2) == 0 \ + and os.system(cmd_str3) == 0 and os.system(cmd_str4) == 0: + print("[*] Frida Server started") + else: + print("[-] Running failed, please check the error in terminal") + exit() + else: + print("[-] We can't install the APP") + exit() + get_info_command = "%s dump badging %s" % (cores.aapt_apth, self.path) + pip = os.popen(get_info_command) + output = pip.buffer.read().decode('utf-8', 'ignore') + if output == "": + raise Exception("can't get the app info") + match = re.compile("package: name='(\S+)'").match( + output) # 通过正则匹配,获取包名 + print(match.group(1)) + cmd_str = ('frida-dexdump -U -f %s') % (str(match.group(1))) + if os.system(cmd_str) != 0: + print("An error occurred in the unpack") + exit() def __decode_file__(self, file_path): apktool_path = str(cores.apktool_path) @@ -45,6 +377,9 @@ class AndroidTask(object): filename = os.path.basename(file_path) suffix_name = filename.split(".")[-1] + if suffix_name == "apk": + self.__detect_protect__(file_path) + if suffix_name == "apk" or suffix_name == "hpk": name = filename.split(".")[0] output_path = os.path.join(base_out_path, name) @@ -84,7 +419,8 @@ class AndroidTask(object): self.__shell_test__(output_path) self.__scanner_file_by_apktool__(output_path) else: - print("[-] Decompilation failed, please submit error information at https://github.com/kelvinBen/AppInfoScanner/issues") + print( + "[-] Decompilation failed, please submit error information at https://github.com/kelvinBen/AppInfoScanner/issues") raise Exception(file_path + ", Decompilation failed.") # 分解dex @@ -94,7 +430,8 @@ class AndroidTask(object): if os.system(cmd_str) == 0: self.__get_scanner_file__(output_path) else: - print("[-] Decompilation failed, please submit error information at https://github.com/kelvinBen/AppInfoScanner/issues") + print( + "[-] Decompilation failed, please submit error information at https://github.com/kelvinBen/AppInfoScanner/issues") raise Exception(file_path + ", Decompilation failed.") # 初始化检测文件信息 @@ -119,13 +456,14 @@ class AndroidTask(object): if os.path.isdir(dir_file_path): self.__get_scanner_file__(dir_file_path, scanner_file_suffixs) else: - if ("." not in dir_or_file) or (len(dir_or_file.split(".")) < 1) or (dir_or_file.split(".")[-1] not in scanner_file_suffixs): + if ("." not in dir_or_file) or (len(dir_or_file.split(".")) < 1) or ( + dir_or_file.split(".")[-1] not in scanner_file_suffixs): continue self.file_queue.put(dir_file_path) for component in config.filter_components: comp = component.replace(".", "/") - if(comp in dir_file_path): - if(component not in self.comp_list): + if (comp in dir_file_path): + if (component not in self.comp_list): self.comp_list.append(component) def __shell_test__(self, output): diff --git a/requirements.txt b/requirements.txt index 6431b45..e8bb5f4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ requests click -openpyxl \ No newline at end of file +openpyxl +frida-tools==11.0.0 +frida-dexdump \ No newline at end of file diff --git a/tools/unpacker/aapt.exe b/tools/unpacker/aapt.exe new file mode 100644 index 0000000..e5d63b7 Binary files /dev/null and b/tools/unpacker/aapt.exe differ diff --git a/tools/unpacker/adb.exe b/tools/unpacker/adb.exe new file mode 100644 index 0000000..dd233d8 Binary files /dev/null and b/tools/unpacker/adb.exe differ diff --git a/tools/unpacker/hexl-server-arm32 b/tools/unpacker/hexl-server-arm32 new file mode 100644 index 0000000..9886ad7 Binary files /dev/null and b/tools/unpacker/hexl-server-arm32 differ diff --git a/tools/unpacker/hexl-server-arm64 b/tools/unpacker/hexl-server-arm64 new file mode 100644 index 0000000..17d7447 Binary files /dev/null and b/tools/unpacker/hexl-server-arm64 differ