Example #1
0
    def optimize(self):
        """
        smali 通用优化代码
        一般情况下,可以使用这个,插件也可以实现自己的优化方式。
        """
        if not self.json_list or not self.target_contexts:
            return

        jsons = JSONEncoder().encode(self.json_list)
        if get_value('DEBUG_MODE'):
            print("\nJSON内容(解密类、方法、参数):")
            print(jsons)

        outputs = {}
        with tempfile.NamedTemporaryFile(mode='w+', delete=False) as tfile:
            tfile.write(jsons)
        outputs = self.driver.decode(tfile.name)
        os.unlink(tfile.name)

        if get_value('DEBUG_MODE'):
            print("解密结果:")
            print(outputs)

        if not outputs:
            return

        if isinstance(outputs, str):
            return

        for key, value in outputs.items():
            if key not in self.target_contexts:
                continue

            if not value[0] or value[0] == 'null':
                continue

            if not value[0].isprintable():
                print("解密结果不可读:", key, value)
                continue

            # json_item, mtd, old_content, rtn_name
            for item in self.target_contexts[key]:
                old_body = item[0].get_body()
                old_content = item[1]
                if get_value('DEBUG_MODE'):
                    print(item[2], value[0])
                new_content = item[2].format(value[0])

                item[0].set_body(old_body.replace(old_content, new_content))
                item[0].set_modified(True)
                self.make_changes = True

        self.smali_files_update()
        self.clear()
Example #2
0
def main(args):
    if args.debug:
        set_value("DEBUG_MODE", args.debug)
    if args.pname:
        set_value("PLUGIN_NAME", args.pname)

    includes = args.includes

    output_dex = None
    if args.o:
        output_dex = args.o

    if args.s:
        if os.path.isdir(args.s):
            dexsim_apk(args.f, args.s, includes, output_dex)
        return

    smali_dir = None
    if get_value('DEBUG_MODE'):
        smali_dir = os.path.join(os.path.abspath(os.curdir), 'zzz')
    else:
        smali_dir = tempfile.mkdtemp()

    dex_file = None
    if Magic(args.f).get_type() == 'apk':
        apk_path = args.f

        if get_value('DEBUG_MODE'):
            tempdir = os.path.join(os.path.abspath(os.curdir), 'tmp_dir')
            if not os.path.exists(tempdir):
                os.mkdir(tempdir)
        else:
            tempdir = tempfile.mkdtemp()

        ptn = re.compile(r'classes\d*.dex')

        zipFile = zipfile.ZipFile(apk_path)
        for item in zipFile.namelist():
            if ptn.match(item):
                output_path = zipFile.extract(item, tempdir)
                baksmali(output_path, smali_dir)
        zipFile.close()

        dex_file = os.path.join(tempdir, 'new.dex')

        smali(smali_dir, dex_file)
        dexsim_apk(args.f, smali_dir, includes, output_dex)
        if not get_value('DEBUG_MODE'):
            shutil.rmtree(tempdir)

    else:
        print("Please give A apk.")
Example #3
0
    def _process_mtd(self, mtd, ptn):
        if get_value('DEBUG_MODE'):
            print('\n', '+' * 100)
            print('Starting to decode ...')
            print(Color.green(mtd))

        body = mtd.get_body()

        for item in ptn.finditer(body):
            old_content = item.group()  # 匹配到的内容,用来替换
            arg_pos, cname, mname, rtn_name = item.groups()
            cname = cname[1:].replace('/', '.')
            # 通过参数位置获取参数值
            rex = arg_pos + '\s*.array-data 1([\w\W\s]+?).end array-data'
            ptn_arr = re.compile(rex, re.MULTILINE)
            bjson = []
            for it in ptn_arr.finditer(body):
                arr = it.groups()
                for i in arr[0].split("\n"):
                    i = i.strip()
                    if i == "":
                        continue
                    bjson.append(int(i.replace('t', ''), 16))
            arguments = ['[B:' + str(bjson)]
            json_item = self.get_json_item(cname, mname, arguments)
            self.append_json_item(json_item, mtd, old_content, rtn_name)
Example #4
0
    def __init__(self, driver, smalidir):
        self.driver = driver
        self.smalidir = smalidir

        self.plugin_filenames = self.__get_plugin_filenames()
        self.__plugins = []
        pname = get_value("PLUGIN_NAME")
        if pname:
            self.__init_plugin(pname)
        else:
            self.__init__plugins()
Example #5
0
    def decode(self, targets):
        '''
        推送解密配置到手机/模拟器,让DSS读取解密配置。
        '''
        self.adb.run_cmd(['push', targets, DSS_TARGETS_PATH])
        self.adb.run_shell_cmd(self.cmd_set_finish)
        self.adb.run_shell_cmd(self.cmd_dss)

        self.start_dss()

        import time
        counter = 0
        while 1:
            time.sleep(3)
            counter += 3
            self.adb.run_shell_cmd(self.cmd_get_finish)
            output = self.adb.get_output().decode('utf-8', errors='ignore')
            if 'Yes' in output:
                break

            if counter > 1200:
                print("Time out")
                self.stop_dss()
                return

        tempdir = tempfile.gettempdir()
        output_path = os.path.join(tempdir, 'output.json')
        self.adb.run_cmd(
            ['pull', DSS_OUTPUT_PATH, output_path])

        if not os.path.exists(output_path):
            print('Could not pull the file {}'.format(output_path))
            self.stop_dss()
            return

        with open(output_path, mode='r+', encoding='utf-8') as ofile:
            size = len(ofile.read())
            if not size:
                self.adb.run_cmd(['pull', DSS_EXCEPTION_PATH, 'exception.txt'])
                self.adb.run_shell_cmd(['rm', DSS_EXCEPTION_PATH])
            else:
                ofile.seek(0)
                result = json.load(ofile)

        if not get_value('DEBUG_MODE'):
            self.adb.run_shell_cmd(['rm', DSS_OUTPUT_PATH])
            self.adb.run_shell_cmd(['rm', DSS_TARGETS_PATH])
        else:
            self.adb.run_shell_cmd(['pull', DSS_TARGETS_PATH])
        # os.unlink(output_path)
        print(output_path)
        self.stop_dss()

        return result
Example #6
0
    def _process_mtd(self, mtd, ptn):
        if get_value('DEBUG_MODE'):
            print('\n', '+' * 100)
            print('Starting to decode ...')
            print(Color.green(mtd))

        body = mtd.get_body()

        for item in ptn.finditer(body):
            old_content = item.group()  # 匹配到的内容,用来替换
            arg, cname, mname, rtn_name = item.groups()
            arguments = ['java.lang.String:' + arg]
            json_item = self.get_json_item(cname, mname, arguments)
            self.append_json_item(json_item, mtd, old_content, rtn_name)
Example #7
0
    def _process_mtd(self, mtd, ptn):
        if get_value('DEBUG_MODE'):
            print('\n', '+' * 100)
            print('Starting to decode ...')
            print(Color.green(mtd))

        body = mtd.get_body()

        for item in ptn.finditer(body):
            old_content = item.group()  # 匹配到的内容,用来替换
            # base解密的字符串,base64解密
            # 得到结果再次解密,
            # rtn_name:最后返回的字符串寄存器,new String的寄存器名字
            arg, cname, mname, rtn_name = item.groups()
            # base64解密
            arguments = [self.convert_args('Ljava/lang/String;', arg), 'I:2']
            json_item = self.get_json_item('android.util.Base64', 'decode',
                                           arguments)

            mid = json_item['id']
            self.append_json_item(json_item, mtd, old_content, rtn_name)

            arg0 = None
            if mid not in self.results:  # 如果同样的ID存在,那么无需解密
                self.decode(mid)

            arg0 = self.results[mid]
            old_mid = mid
            # arg1 = 'fmsd1234'  # 这个是一个固定值
            # 解密得到的结果
            # 进行第二次解密
            import smafile
            cname = smafile.smali2java(cname)
            arguments = ['[B:' + arg0, 'java.lang.String:fmsd1234']
            # print(cname, mname, arguments)
            json_item = self.get_json_item(cname, mname, arguments)
            mid = json_item['id']
            self.append_json_item(json_item, mtd, old_content, rtn_name)
            if mid in self.results:
                self.json_list.clear()
                continue
            self.decode(mid)
            x = self.results[mid]
            try:
                result = bytes(eval(x)).decode('utf-8')
                self.results[old_mid] = result
                print(result)
            except Exception as e:
                print(result, e)
Example #8
0
def dexsim_apk(apk_file, smali_dir, includes, output_dex):
    """解密apk

    Args:
        apk_file (str): apk文件
        smali_dir (str): smali 目录
        includes (list): 过滤字符串
        output_dex (str): 反编译后的文件
    """
    dexsim(apk_file, smali_dir, includes)
    if output_dex:
        smali(smali_dir, output_dex)
    else:
        smali(smali_dir,
              os.path.splitext(os.path.basename(apk_file))[0] + '.sim.dex')

    if not get_value('DEBUG_MODE'):
        shutil.rmtree(smali_dir)
Example #9
0
    def run(self):
        print('Run ' + __name__, end=' ', flush=True)
        for templet in self.templets:
            for item in templet:
                for key, value in item.items():
                    dtype = value['type']
                    if dtype != 1:
                        continue

                    self.tname = key
                    if not value['enabled']:
                        continue

                    if get_value('DEBUG_MODE'):
                        print('Load ' + self.tname)
                    if value['protos']:
                        protos = [i.replace('\\', '') for i in value['protos']]
                    else:
                        protos = []

                    ptn = ''.join(value['pattern'])

                    self.__process(protos, ptn)