def do_work(params): gradle_bin = params['compiler'] out_file = params['log_file'] work_dir = params['work_dir'] fp_keystore = params['keystore'] signed_apk_path = params['signed_apk_path'] ec, pub_key_str = get_pub_key(work_dir, signed_apk_path) if ec != 0: return ec tmp_so_prj_path = os.path.join(work_dir, 'CryptPrj') if not exe_cmd('cp -r {} {}'.format(so_seed_prj_path, tmp_so_prj_path)): return dfs.err_cp_encrpt_prj while 1: ec = build_so_prj(tmp_so_prj_path, gradle_bin, pub_key_str, out_file) if ec != 0: break ec, apk_file = replace_so_file(work_dir, tmp_so_prj_path, signed_apk_path, fp_keystore) if ec != 0: break # finally apk path. params['signed_apk_path'] = apk_file break # remove tmp project. exe_cmd("rm -rf {}".format(tmp_so_prj_path)) return ec
def handle_command(debugger, command, exe_ctx, result, internal_dict): command_args = shlex.split(command, posix=False) parser = generate_option_parser() try: (options, _) = parser.parse_args(command_args) except: result.SetError(parser.usage) return _ = exe_ctx.target _ = exe_ctx.thread if options.superX: utils.ILOG("set breakpoint at CFBundleGetMainBundle") utils.exe_cmd(debugger, "b CFBundleGetMainBundle") time.sleep(1) utils.ILOG("will continue process and dump") utils.exe_cmd(debugger, "c") time.sleep(1) utils.ILOG("start execute dumpdecrypted") ret = dumpdecrypted(debugger) else: if options.modulePath and options.moduleIdx: module_path = options.modulePath module_idx = options.moduleIdx utils.ILOG("you manual set dump module idx:{} and path:{}".format( module_idx, module_path)) ret = dumpdecrypted(debugger, module_path, module_idx) else: ret = dumpdecrypted(debugger) result.AppendMessage(str(ret)) return
def log_malloc_stack(debugger, command, exe_ctx, result, internal_dict): command_args = shlex.split(command, posix=False) _ = exe_ctx.target _ = exe_ctx.thread utils.exe_cmd(debugger, "po turn_on_stack_logging(1)") # result.AppendMessage(str('usage: croc [-m moduleName, -a address, -u UserDefaults]')) return
def impt_heap(debugger, command, exe_ctx, result, internal_dict): command_args = shlex.split(command, posix=False) _ = exe_ctx.target _ = exe_ctx.thread utils.exe_cmd(debugger, "command script import lldb.macosx.heap") # result.AppendMessage(str('usage: croc [-m moduleName, -a address, -u UserDefaults]')) return
def load_python_scripts_dir(dir_name, debugger): this_files_basename = os.path.basename(__file__) cmd = '' for file in os.listdir(dir_name): if file.endswith('.py'): cmd = 'command script import ' elif file.endswith('.txt'): cmd = 'command source -e0 -s1 ' else: continue if file != this_files_basename: fullpath = dir_name + '/' + file utils.exe_cmd(debugger, cmd + fullpath)
def mem_dump(debugger, command, exe_ctx, result, internal_dict): command_args = shlex.split(command, posix=False) _ = exe_ctx.target _ = exe_ctx.thread if len(command_args) != 3: utils.ELOG("[usage] mem_dump outFile addr size") return outfile = command_args[0] start_addr = utils.convertToInt(command_args[1]) size = eval(command_args[2]) if not start_addr: utils.ELOG("params format error") return utils.ILOG("default address will plus main image slide") slide = utils.get_image_slide(debugger, 0) start_addr = start_addr + slide cmd = "memory read --binary --outfile {} --count {} {}".format( outfile, size, start_addr) utils.ILOG("mem dump:{}".format(cmd)) ret = utils.exe_cmd(debugger, cmd) result.AppendMessage(str(ret)) return
def mr(debugger, command, exe_ctx, result, internal_dict): command_args = shlex.split(command, posix=False) _ = exe_ctx.target _ = exe_ctx.thread if len(command_args) != 2: utils.ELOG("[usage] mr addr count") return start_addr = utils.convertToInt(command_args[0]) size = eval(command_args[1]) if not start_addr: utils.ELOG("params format error") return # utils.ILOG("default address will plus main image slide") # slide = utils.get_image_slide(debugger, 0) # start_addr = start_addr + slide cmd = "memory read {} --count {}".format(start_addr, size) utils.ILOG("mem read:{}".format(cmd)) ret = utils.exe_cmd(debugger, cmd) result.AppendMessage(str(ret)) return
def dumpdecrypted(debugger, modulePath=None, moduleIdx=None): # must delete all breakpoints. utils.ILOG("delete all breakpoints") utils.exe_cmd(debugger, "br de -f") main_image = utils.get_app_exe_path() images = utils.get_all_image_of_app() utils.ILOG("start to dump...\n") if modulePath and moduleIdx: print(dump_macho_to_file(debugger, moduleIdx, modulePath)) else: for image in images: if main_image == image["name"]: entryAddrStr = get_macho_entry_offset(debugger) entryAddr_int = int(entryAddrStr.strip()[1:-1], 16) utils.SLOG("fix main addr:" + hex(entryAddr_int)) print( dump_macho_to_file(debugger, image["idx"], image["name"], entryAddr_int)) continue print(dump_macho_to_file(debugger, image["idx"], image["name"])) return '[*] Developed By xia0@2019'
def gen_key_store(work_dir): pwd = "".join(random.sample(ch_list, 16)) with open("/tmp/keytool.in", "w") as f: f.write(keytool_in.format(pwd)) alias = "".join(random.sample(ch_list, 6)) key_file = "{}-{}.keystore".format(alias, pwd) cmd = 'cd {} && keytool -genkey -v -keystore {} -alias {} -keyalg RSA -keysize {} -validity 365' \ '< /tmp/keytool.in'.format(work_dir, key_file, alias, 1024) if not exe_cmd(cmd): return dfs.err_gen_keystore with open(os.path.join(work_dir, 'password'), 'w') as f: f.write('{}\n'.format(pwd)) return 0
def get_pub_key(work_dir, signed_apk_path): raw_apk_dir = os.path.join(work_dir, 'raw_apk') # move signed apk to work_dir/raw_apk if not exe_cmd('mkdir {1} && cp {0} {1}'.format(signed_apk_path, raw_apk_dir)): return dfs.err_make_dir, None # unzip apk signed_apk_name = os.path.basename(signed_apk_path) if not exe_cmd('cd {} && unzip {}'.format(raw_apk_dir, signed_apk_name)): return dfs.err_unzip_apk, None # get pub key csr_path = None for item in os.listdir(os.path.join(raw_apk_dir, 'META-INF')): if item.endswith('RSA'): csr_path = os.path.join(raw_apk_dir, 'META-INF', item) if not csr_path: return dfs.err_csr_file_not_exist, None cmd = "cd /tmp && openssl pkcs7 -in {} -inform DER -print_certs -out cert.pem " \ "&& openssl x509 -in cert.pem -noout -text".format(csr_path) s, o = commands.getstatusoutput(cmd) logging.info('>>>{}\n>>>{}'.format(cmd, o)) if s != 0: logging.fatal('exe [{}] failed.reason:[{}]'.format(cmd, o)) return dfs.err_get_pub_key, None ptn = re.compile(r'Modulus:([\s\S]*?)Exponent') out = ptn.findall(o) if not out: logging.fatal('cannot find pub key in output:[{}]'.format(o)) return dfs.err_get_pub_raw_str, None pub_key_list = re.compile(r'([a-f0-9]+)').findall(out[0]) if not pub_key_list: logging.fatal('cannot find pub key detail in pub key:[{}]'.format( out[0])) return dfs.err_get_pub_str, None pub_key = ''.join(pub_key_list) for i, ch in enumerate(pub_key): if ch != '0': return 0, pub_key[i:] return 0, '0'
def dumpdecrypted(debugger, modulePath=None, moduleIdx=None): # must delete all breakpoints. utils.ILOG("delete all breakpoints") utils.exe_cmd(debugger, "br de -f") #dump_macho_to_file(debugger,) if modulePath and moduleIdx: print(dump_macho_to_file(debugger, moduleIdx, modulePath)) else: mainImagePath = get_main_image_path(debugger) appDir = os.path.dirname(mainImagePath) appImagesStr = get_all_image_of_app(debugger, appDir) appImagesArr = appImagesStr.split("#") for imageInfo in appImagesArr: if not imageInfo or not "," in imageInfo: utils.ELOG("image info is null, skip image # " + imageInfo) continue utils.ILOG("now is image: " + imageInfo) info = imageInfo.split(",") if len(info) == 2: utils.ILOG("start dump [" + info[0] + "] image:" + info[1]) # print "idx:" + info[0] # print "path:" + info[1] if info[1] == mainImagePath: entryAddrStr = get_macho_entry_offset(debugger) entryAddr_int = int(entryAddrStr.strip()[1:-1], 16) utils.SLOG("fix main addr:" + hex(entryAddr_int)) print( dump_macho_to_file(debugger, info[0], info[1], entryAddr_int)) continue print(dump_macho_to_file(debugger, info[0], info[1])) return '\n\n[*] Developed By xia0@2019'
def do_work(params): logging.info('prepare project.') tmp_dir = params['tmp_dir'] repo_addr = params['git_address'] branch = params['git_branch'] update_code = params['update_code'] work_dir = params['work_dir'] if not repo_addr.endswith('.git') or repo_addr[:3] not in ('git', 'ssh'): logging.fatal( 'invalid repo address[{}]. expect ssh address.'.format(repo_addr)) return dfs.err_invalid_repo repo_name = os.path.basename(repo_addr)[:-4] repo_dir_name = '{}-{}'.format(repo_name, branch) repo_dir_abs_path = os.path.join(tmp_dir, repo_dir_name) if os.path.exists(repo_dir_abs_path): cmd = 'cd {} && git checkout {} && git pull'.format( repo_dir_abs_path, branch) if update_code else None elif update_code: cmd = 'cd {0} && git clone {1} {2} && cd {2} && git checkout {3}'.format( tmp_dir, repo_addr, repo_dir_name, branch) else: return dfs.err_pull_code if cmd and not exe_cmd(cmd): logging.fatal('pull code from git failed.\ncmd:[{}]'.format(cmd)) return dfs.err_pull_code prj_dir = os.path.join(work_dir, 'prj') cmd = 'cp -r {} {}'.format(repo_dir_abs_path, prj_dir) if not exe_cmd(cmd): logging.fatal('copy project [{}]->[{}]'.format(repo_dir_abs_path, work_dir)) return dfs.err_cp_prj params['prj_dir'] = prj_dir params['work_dir'] = work_dir return 0
def replace_icon(self, icon_path): logging.info('replace icon to :%s', icon_path) if not icon_path: return True icon_dirs = \ [os.path.join(self.dir_res, f) for f in os.listdir(self.dir_res) if f.startswith(self.icon_dir_prefix)] logging.info('icon may in dir: %s', icon_dirs) replaced_count = 0 for icon_dir in icon_dirs: f_icon = os.path.join(icon_dir, self.icon_file_name) if os.path.exists(f_icon): logging.info('replace app icon in dir {}.'.format(icon_dir)) if not exe_cmd('cp {} {}'.format(icon_path, f_icon)): return False replaced_count += 1 return bool(replaced_count)
def handle_command(debugger, command, exe_ctx, result, internal_dict): command_args = shlex.split(command, posix=False) parser = generate_option_parser() try: (options, _) = parser.parse_args(command_args) except: result.SetError(parser.usage) return _ = exe_ctx.target _ = exe_ctx.thread if options.patchInstrument: if options.patchAddress: patch_addr = int(options.patchAddress, 16) else: ret = utils.exe_cmd(debugger, "p/x $pc") ret = ret.strip() pattern = '0x[0-9a-f]+' match = re.search(pattern, ret) if match: found = match.group(0) else: utils.ELOG("not get address:" + ret) return utils.ILOG( "you not set patch address, default is current pc address:{}". format(found)) patch_addr = int(found, 16) patch_ins = options.patchInstrument # default instrument size is 1 patch_size = 0x1 patch_ins = patch_ins.replace("\"", "") patch_ins = patch_ins.replace("'", "") if options.patchSize: patch_size = int(options.patchSize) ret = patcher(debugger, patch_ins, patch_addr, patch_size) result.AppendMessage(str(ret)) else: result.AppendMessage("[-] args error, check it !") return
def replace_so_file(work_dir, so_prj_dir, unprotected_apk, keystore_file, from_apk=True): so_apk_unzip_dir = os.path.join(work_dir, 'app4so') fp_ori_so_apk = os.path.join(so_prj_dir, built_so_apk_dir, built_so_apk_name) if from_apk: # mkdir work_dir/app4so && cd work_dir/app4so && cp so.apk . && unzip so.apk cmd = 'mkdir {0} && cd {0} && cp {1} . && unzip {2}'.format( so_apk_unzip_dir, fp_ori_so_apk, built_so_apk_name) if not exe_cmd(cmd): return dfs.err_unzip_apk, None else: return dfs.err_for_future, None so_name = os.path.basename(so_path_in_apk) cmd = 'cd {0} && chmod +x {1} && {2} -9 -v -o {3} {1}'.format( so_apk_unzip_dir, so_path_in_apk, upx, so_name) if not exe_cmd(cmd): return dfs.err_add_shell_to_so, None # 解包目标APK name = os.path.basename(unprotected_apk) if not exe_cmd('cd {0} && cp {1} . ; apktool d {2}'.format( work_dir, unprotected_apk, name)): return dfs.err_unzip_target_apk, None path = os.path.join(work_dir, os.path.splitext(name)[0]) arm_so_dir = os.path.join(path, 'lib/armeabi') # 直接替换lib下的文件 cmd = "cd {} && cp {} .".format(arm_so_dir, os.path.join(so_apk_unzip_dir, '*.so')) if not exe_cmd(cmd): return dfs.err_mv_so_to_apk, None # 打包 apk_file = 'safe-{}'.format(name) cmd = "cd {} && apktool b {} -o {}".format(work_dir, os.path.splitext(name)[0], apk_file) if not exe_cmd(cmd): return dfs.err_zip_apk, None # 签名, alias-password.keystore alias, pwd = os.path.splitext( os.path.basename(keystore_file))[0].split('-') pwd_file = os.path.join(work_dir, 'password') with open(pwd_file, 'w') as f: f.write(pwd + '\n') cmd = "cd {} && jarsigner -verbose -keystore {} {} {} < {}".format( work_dir, keystore_file, apk_file, alias, pwd_file) if not exe_cmd(cmd): return dfs.err_resign_apk, None return 0, os.path.join(work_dir, apk_file)
def gen_key_settings(work_dir): logging.info('generate signature key under %s', work_dir) ch_list = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z') pwd = "".join(random.sample(ch_list, 16)) keytool_in = '\n'.join((pwd, pwd, 'Spider', 'TMSLYLY', 'Cor.td', 'HonKong', 'ThreeSeason', '86', 'y', '')) with open(os.path.join(work_dir, 'genkey.in'), "w") as f: f.write(keytool_in.encode('utf-8')) alias = "".join(random.sample(ch_list, 8)) key_name = "{}-{}.keystore".format(alias, pwd) cmd = 'cd {} && keytool -genkey -v -keystore {} -alias {} ' \ '-keyalg RSA -keysize 1024 -validity 90 < genkey.in'.format(work_dir, key_name, alias) if not exe_cmd(cmd): logging.fatal('make key file failed.') return None return os.path.join(work_dir, key_name), alias, pwd
def do_work(params): output_apk_name = params['output'] do_upload = params['upload'] domain = params['cdn_domain'] public_key = params['cdn_pub_key'] private_key = params['cdn_prv_key'] apk_bucket = params['cdn_bucket'] signed_apk_path = params['signed_apk_path'] if not signed_apk_path: logging.fatal("can not find signed apk.") return dfs.err_find_built_apk logging.info("singed apk:{}".format(signed_apk_path)) out_file_name = '{}-{}.apk'.format( output_apk_name, datetime.datetime.now().strftime('%H%M%S')) local_file_name = output_apk_name + '.apk' cmd = 'cp {} {}'.format( signed_apk_path, os.path.join(os.getcwd(), 'apk_files/', local_file_name)) if not exe_cmd(cmd): logging.fatal('copy apk failed.') return dfs.err_cp_apk if do_upload: try: handler = putufile.PutUFile(safestr(public_key), safestr(private_key)) key = "auto/{}".format(out_file_name) logging.info('start upload file %s to public bucket %s', key, apk_bucket) ret, resp = handler.putfile(safestr(apk_bucket), safestr(key), safestr(signed_apk_path)) except: logging.exception('upload apk failed.') return dfs.err_upload_apk logging.info('ucloud response:[%s], detail: %s', resp.content, resp) if resp.ok() == 200: url = 'http://{}/{}'.format(domain, key) logging.info("upload success: url[%s]", url) sys.stdout.write(safestr(url)) return 0 logging.fatal("upload failed with code: %s.", resp.status_code) return dfs.err_upload_apk return 0
def croc(debugger, command, exe_ctx, result, internal_dict): command_args = shlex.split(command, posix=False) _ = exe_ctx.target _ = exe_ctx.thread utils.ILOG("going to env that can run oc script") utils.exe_cmd(debugger, "b CFBundleGetMainBundle") utils.exe_cmd(debugger, "c") utils.exe_cmd(debugger, "br del -f") utils.SLOG("now you can exe oc") # result.AppendMessage(str('usage: croc [-m moduleName, -a address, -u UserDefaults]')) return
def get_module_info_by_name(debugger, moduleName): command_script = '@import Foundation;NSString* moduleName = @"' + moduleName + '";' command_script += r''' NSMutableString* retStr = [NSMutableString string]; uint32_t count = (uint32_t)_dyld_image_count(); for(uint32_t i = 0; i < count; i++){ char* curModuleName_cstr = (char*)_dyld_get_image_name(i); long slide = (long)_dyld_get_image_vmaddr_slide(i); uintptr_t baseAddr = (uintptr_t)_dyld_get_image_header(i); NSString* curModuleName = @(curModuleName_cstr); if([curModuleName containsString:moduleName]) { [retStr appendString:@"\n=======\nModule Path : "]; [retStr appendString:@(curModuleName_cstr)]; [retStr appendString:@"\nModule Silde: "]; [retStr appendString:(id)[@(slide) stringValue]]; [retStr appendString:@"\nModule base : "]; [retStr appendString:(id)[@(baseAddr) stringValue]]; } } retStr ''' retStr = utils.exe_script(debugger, command_script) if "error" in retStr: utils.ELOG("something error in OC script # " + retStr.strip()) utils.ILOG("so use command to get info") ret = utils.exe_cmd(debugger, "im li -o -f") pattern = ".*" + moduleName.replace("\"", "") match = re.search(pattern, ret) # TODO: more strict if match: found = match.group(0) else: utils.ELOG("not found image:" + moduleName) return return found return utils.hex_int_in_str(retStr)
def update_build_gradle(self, app_id): logging.info('update build.gradle with app id(package name) to %s', app_id) ptn = re.compile( r'(.*?defaultConfig\s*\{\s*applicationId\s+")(.*?)("\s+.*)') bptn = re.compile(r'(defaultConfig)') xptn = re.compile( r'(defaultConfig\s*\{[\s\S]*?release\s*\{[\s\S]*?)(\})') old_app_id = None with open(self.f_built_gradle) as f: ctnt = f.read() if ctnt.find('signingConfigs') >= 0: logging.fatal('signingConfigs already in %s, abort.', self.f_built_gradle) return dfs.err_replace_strings if self.b_replace_appid: res = ptn.findall(ctnt) if not res or len(res) > 1: return dfs.err_bad_build_gradle_file old_app_id = res[0][1] # add sign apk conf. ctnt = ptn.sub( lambda m: '{}{}{}'.format(m.group(1), app_id, m.group(3)), ctnt) ctnt = bptn.sub(lambda m: '{}{}'.format(sign_conf_str, m.group(1)), ctnt) ctnt = xptn.sub( lambda m: '{}{}{}'.format(m.group(1), release_sign_conf_str, m.group(2)), ctnt) with open(self.f_built_gradle, 'w') as f: f.write(ctnt.encode("utf-8")) if self.b_replace_appid and self.f_manifest: logging.info('replace app id in %s', self.f_manifest) cmd = 'sed -i "s/{}/{}/g" {}'.format( old_app_id.replace('.', '\\.'), app_id, self.f_manifest) if not exe_cmd(cmd): logging.fatal('repace appid in %s failed.', self.f_manifest) return dfs.err_replace_strings return 0
def build_so_prj(so_prj_path, gradle_bin, pub_key, out_file): counter = 0 res = ['', '', ''] for idx, ch in enumerate(pub_key): if counter < 8: pos = idx % len(res) res[pos] += ch counter += (1 if pos == len(res) - 1 else 0) else: res[2] += ch cpp_dir = os.path.join(so_prj_path, cpp_path) cmd = 'cd {} && sed -i \'s/%part1%/{}/g\' *.cpp && sed -i \'s/%part2%/{}/g\' *.cpp ' \ '&& sed -i \'s/%part3%/{}/g\' *.cpp '.format(cpp_dir, *res) if not exe_cmd(cmd): return dfs.err_replace_so_signature args = [gradle_bin, 'build'] out_file.write("-----build so-----\n") exit_code = subprocess.call(args=args, cwd=so_prj_path, stderr=out_file, stdout=out_file) if exit_code != 0: return dfs.err_build_so return 0
if options.build_ver == '3rd': params['channel'] = options.channel_id params['dataeye'] = options.dataeye_id elif options.build_ver == 'sms': params['chn_name'] = options.chn_name_list params['chn_val'] = options.chn_val_list else: exit(dfs.err_invalid_param) params = { k: v.decode('utf-8') if isinstance(v, str) else v for k, v in params.items() } from build_executor import BuildExecutor be = BuildExecutor(apk_conf['build_processors'], params) exit_code = be.execute() except Exception as e: import traceback exit_code = 99 traceback.print_exc() finally: if fp_log_file: fp_log_file.close() if 'prj_dir' in params: if not exe_cmd('rm -rf {}'.format(params['prj_dir'])): logging.warning('delete prj [{}] failed'.format( params['prj_dir'])) exit(exit_code)
def xbr(debugger, command, result, dict): raw_args = create_command_arguments(command) command_args = shlex.split(command, posix=False) parser = generate_option_parser() try: (options, args) = parser.parse_args(command_args) except: result.SetError(parser.usage) return # check is options? if options.address: targetAddr = options.address if targetAddr.startswith("0x"): targetAddr_int = int(targetAddr, 16) else: targetAddr_int = int(targetAddr, 10) utils.ILOG("breakpoint at address:{}".format(hex(targetAddr_int))) lldb.debugger.HandleCommand ('breakpoint set --address %d' % targetAddr_int) return if options.entryAddress: if options.entryAddress == "main": entryAddrStr = get_macho_entry_offset(debugger) entryAddr_int = int(entryAddrStr.strip()[1:-1], 16) utils.ILOG("breakpoint at main function:{}".format(hex(entryAddr_int))) lldb.debugger.HandleCommand ('breakpoint set --address %d' % entryAddr_int) elif options.entryAddress == "init": initFunAddrStr = get_macho_mod_init_first_func(debugger) initFunAddr_int = int(initFunAddrStr.strip()[1:-1], 16) utils.ILOG("breakpoint at mod int first function:{}".format(hex(initFunAddr_int))) lldb.debugger.HandleCommand ('breakpoint set --address %d' % initFunAddr_int) elif options.entryAddress == "load": ret = get_all_class_plus_load_methods(debugger) if "<object returned empty description>" in ret: utils.ILOG("not found +[* load] method") return all_load_addrs_str_arr = ret.strip().split(",") all_load_addrs = [] for addr in all_load_addrs_str_arr: if addr != "": all_load_addrs.append(int(addr, 10)) utils.ILOG("will set breakpoint at all +[* load] methold, count:{}".format(len(all_load_addrs))) for addr in all_load_addrs: lldb.debugger.HandleCommand ('breakpoint set --address %d' % addr) utils.SLOG("set br at:{}".format(hex(addr))) # utils.ILOG("load:\n{}\n".format([hex(addr) for addr in all_load_addrs])) else: utils.ELOG("you should special the -E options:[main/init/load]") return # check is arg is address ? mean auto add slide if is_just_address_cmd(args): if options.modulePath: modulePath = options.modulePath utils.ILOG("you special the module:" + modulePath) else: utils.ILOG("you not special the module, default is main module") modulePath = None targetAddr = args[0] if targetAddr.startswith("0x"): targetAddr_int = int(targetAddr, 16) else: targetAddr_int = int(targetAddr, 10) moduleSlide = get_process_module_slide(debugger, modulePath) if "error" in moduleSlide: utils.ELOG("error in oc script # " + moduleSlide.strip()) if modulePath: targetImagePath = modulePath else: mainImagePath = get_main_image_path(debugger) if "no value available" in mainImagePath or "error" in mainImagePath: ret = utils.exe_cmd(debugger, "target list") # pylint: disable=anomalous-backslash-in-string pattern = '/.*\(' match = re.search(pattern, ret) # TODO: more strict if match: found = match.group(0) found = found.split("(")[0] found = found.strip() else: utils.ELOG("failed to auto get main module, use -m option") return mainImagePath = found print("[+] use \"target list\" to get main module:" + mainImagePath) else: mainImagePath = mainImagePath.strip()[1:-1] targetImagePath = mainImagePath ret = utils.exe_cmd(debugger, "image list -o -f") pattern = '0x.*?' + targetImagePath.replace("\"", "") match = re.search(pattern, ret) # TODO: more strict if match: found = match.group(0) else: utils.ELOG("not found image:"+targetImagePath) return moduleSlide = found.split()[0] utils.ILOG("use \"image list -o -f\" cmd to get image slide:"+moduleSlide) moduleSlide = int(moduleSlide, 16) else: moduleSlide = int(moduleSlide, 10) brAddr = moduleSlide + targetAddr_int utils.ILOG("ida's address:{} module slide:{} target breakpoint address:{}".format(hex(targetAddr_int), hex(moduleSlide), hex(brAddr))) lldb.debugger.HandleCommand ('breakpoint set --address %d' % brAddr) return # check is breakpoint at all methods address(IMP) for given classname if is_br_all_cmd_x(args): classname = args[0] begin = classname.find('$') end = classname.rfind('$') classname = classname[begin+1 : end] utils.ILOG("classname:{}".format(classname)) ret = get_all_method_address_of_class(debugger, classname) addrArr = ret.split('-')[:-1] for addr in addrArr: address = int(addr) if address: lldb.debugger.HandleCommand ('breakpoint set --address %x' % address) result.AppendMessage("Set %ld breakpoints of %s" % (len(addrArr),classname)) return if is_br_all_cmd(args): classname = args[0] ret = get_all_method_address_of_class(debugger, classname) addrArr = ret.split('-')[:-1] for addr in addrArr: address = int(addr) if address: lldb.debugger.HandleCommand ('breakpoint set --address %x' % address) result.AppendMessage("Set %ld breakpoints of %s" % (len(addrArr),classname)) return if not is_command_valid(raw_args): print('please specify the param, for example: "-[UIView initWithFrame:]"') return arg_ = raw_args[0] class_name = get_class_name(arg_) method_name = get_method_name(arg_) # xlog = 'className:'+ str(class_name) + '\tmethodName:' + str(method_name) utils.ILOG("className:{} methodName:{}".format(class_name, method_name)) # print class_name, method_name address = 0 if is_class_method(arg_): address = get_class_method_address(class_name, method_name) else: address = get_instance_method_address(class_name, method_name) utils.SLOG('found method address:0x%x' % address) if address: lldb.debugger.HandleCommand ('breakpoint set --address %x' % address) else: utils.ELOG("fail, please check the arguments")
def _restore_namespace(self): cmd = 'sed -i s/xmlns:ns0/xmlns:android/g {0} && sed -i s/ns0:/android:/g {0}'.format( self.f_manifest) return 0 if exe_cmd(cmd) else dfs.err_replace_strings
def replace_icon_v2(self, icon_path): if not icon_path: return True return exe_cmd( 'cp %s %s' % (icon_path, os.path.join(self.dir_prj_root, self.icon_file_name)))