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()
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.")
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)
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()
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
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)
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)
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)
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)