def decode(argv): if len(sys.argv) == 2: myEH = flare_emu.EmuHelper(samplePath=sys.argv[1]) else: myEH = flare_emu.EmuHelper() print("testing emulateRange feature for _xorCrypt function") myEH.emulateRange(myEH.analysisHelper.getNameAddr("_xorCrypt"), registers = {"arg1":argv[0], "arg2":argv[1], "arg3":argv[2], "arg4":argv[3]}) return myEH.getEmuString(argv[0]).decode("latin1")
def decrypt(argv): myEH = flare_emu.EmuHelper() all_mem = myEH.allocEmuMem(100) # 三个参数 myEH.emulateRange(myEH.analysisHelper.getNameAddr("sub_40103C"), stack=[0, argv[0], argv[1], argv[2]]) return myEH.getEmuString(argv[0])
def deobfuscate(argv): myEH = flare_emu.EmuHelper() allocated = myEH.allocEmuMem(1024) # we do must disable skip calls due to internal calls # stack for x86, first arg is ret addr so 0 # registers for x64 myEH.emulateRange(myEH.analysisHelper.getNameAddr("stringDecrypt"), skipCalls=False, stack=[0, argv[0], "useless", allocated]) return myEH.getEmuString(allocated).decode("latin-1")
def decode(argv): myEH = flare_emu.EmuHelper() print("testing emulateRange feature for _xorCrypt function") mu = myEH.emulateRange(idc.get_name_ea_simple("_xorCrypt"), registers={ "arg1": argv[0], "arg2": argv[1], "arg3": argv[2], "arg4": argv[3] }) return myEH.getEmuString(argv[0])
def main(): info('start') eh = flare_emu.EmuHelper() # search the decoding functions cnts = {} for fva in Functions(): #if fva != 0x1000A19F: # continue if idc.get_func_flags(fva) & (idc.FUNC_LIB | idc.FUNC_THUNK): continue size = 0 fn_bytes = idc.get_bytes(fva, get_func_attr(fva, FUNCATTR_END) - fva) for pname, pat in g_pats.items(): m = pat.search(fn_bytes) if m: try: if pname == 'sub': key = int.from_bytes(m.group(1), 'little') size = int.from_bytes(m.group(2), 'little') else: key = None size = int.from_bytes(m.group(1), 'little') except ValueError: pass else: print('\n') info('{:#x}: {}-encoded function detected (size = {:#x})'. format(fva, pname, size)) idaapi.do_name_anyway( fva, 'fn_ADVobfuscator_decode_{}_len{}'.format(pname, size)) cnt = emulate(pname, eh, fva, size, key) if cnts.get(pname): cnts[pname] += cnt else: cnts[pname] = cnt break info('number of decoded strings: {}'.format(cnts)) info('done')
def decrypt(argv, funcName): myEH = flare_emu.EmuHelper() print("decrypting...") mu = myEH.emulateRange(idc.get_name_ea_simple(funcName), stack=[0, argv[0], argv[1]], memAccessHook=mem_hook) decrypted_data = myEH.getEmuBytes(argv[0], argv[1]) print('decrypted: {}'.format(decrypted_data)) # make string in idb file if funcName == "DecryptAsciiStr": # make ascii str idc.MakeStr(argv[0], argv[0] + argv[1]) if funcName == "DecryptUnicodeStr": # make unicode str old_type = idc.GetLongPrm(INF_STRTYPE) idc.SetLongPrm(idc.INF_STRTYPE, idc.ASCSTR_UNICODE) idc.MakeStr(argv[0], argv[0] + (argv[1] * 2)) idc.SetLongPrm(idc.INF_STRTYPE, old_type) return decrypted_data
print("%s: test not found" % (testString.replace("\r\n", ""))) def wcsdupHook(eh, address, argv, funcName, userData): print("the new wcsdup hook was called") eh.hookCalled = True if eh.isValidEmuPtr(argv[0]): s = "the quick brown fox jumps over the lazy dog".encode("utf-16")[2:] memAddr = eh.allocEmuMem(len(s) + 2) eh.uc.mem_write(memAddr, s) eh.uc.reg_write(eh.regs["ret"], memAddr) return eh.uc.reg_write(eh.regs["ret"], 0) if __name__ == '__main__': eh = flare_emu.EmuHelper() print("testing iterate feature for printf function") strcpyEa = idc.get_name_ea_simple("j_strcpy") eh.iterate(idc.get_name_ea_simple("printf"), iterateHook) idc.set_name(strcpyEa, "testname", idc.SN_NOCHECK) eh.addApiHook("testname", "strcpy") eh.addApiHook("wcsdup", wcsdupHook) print( "testing with renamed and redirected strcpy hook and new hook for wcsdup" ) eh.iterate(idc.get_name_ea_simple("printf"), iterateHook) if "hookCalled" not in dir(eh): print("FAILED: addApiHook hook not called")
def main(): eh = flare_emu.EmuHelper() # dictionary that stores data used across emulation runs, function emulation specific data is set below userData = { # found stackstrings in stack memory "stackstrings": [], # found stackstrings in global memory (globalstrings) "globalstrings": [] } cnt_functions = 0 cnt_analyzed = 0 cnt_found_ss = 0 cnt_commented_ss = 0 errors = [] start = time.time() print("Started ironstrings stackstring deobfuscation") print_header() if ANALYZE_SINGLE_FUNC: fvas = [idc.get_func_attr(idc.here(), idc.FUNCATTR_START)] else: fvas = idautils.Functions() for fva in fvas: logging.debug("running on 0x%X", fva) if JUMP_TO_FUNC: idc.jumpto(fva) if fva == idaapi.BADADDR: logging.debug("skipping invalid function address") continue if idc.get_func_flags(fva) & (idc.FUNC_LIB | idc.FUNC_THUNK): logging.debug("skipping library or thunk function 0x%X", fva) continue # function start address userData["funcStart"] = fva # list of addresses of last instruction for all basic blocks in function userData["bb_ends"] = get_bb_ends(fva) # memory writes in current function userData["mem_writes"] = {} # start and end addresses of all memory writes in function userData["writelog"] = set() # memory write count in current basic block userData["mem_write_count"] = 0 # cache previous address to count instructions that are executed multiple times, e.g. rep prefixed userData["prevAddress"] = 0 # number same instruction has been executed in a row userData["repCount"] = 0 cnt_functions += 1 try: # emulate various paths through function via flare-emu, use hooks to reconstruct strings eh.iterateAllPaths(fva, noop, hookData=userData, callHook=call_hook, instructionHook=instr_hook, memAccessHook=hook_mem_write, hookApis=False, maxPaths=MAX_CODE_PATHS) except unicorn.UcError as e: errors.append("Error analyzing function 0x{:X}: {}".format( fva, str(e))) else: cnt_analyzed += 1 # print stackstrings found in this function f_ss = filter(lambda s: s.fva == fva, userData["stackstrings"]) cnt_found_ss += len(f_ss) for ss in sorted(f_ss, key=lambda s: s.written_at): print_string(ss.fva, ss.written_at, ss.offset, ss.s) # IMPROVEMENT adjust stack frame member size in IDA view # print globalstrings found in this function f_gs = filter(lambda g: g.fva == fva, userData["globalstrings"]) cnt_found_ss += len(f_gs) for gs in sorted(f_gs, key=lambda g: g.written_at): print_string(gs.fva, gs.written_at, gs.offset, gs.s) if COMMENT_STACKSTRINGS: for ss in f_ss: if not ss.written_at: errors.append( "Can't get location where '{}' was written in 0x{:X}." .format(ss.s, ss.fva)) continue ss_cmt = format_comment(ss.s) if append_comment(ss.written_at, ss_cmt): cnt_commented_ss += 1 else: errors.append( "Failed to set comment at 0x{:X}: {}".format( ss.written_at, ss_cmt)) for gs in f_gs: if COMMENT_STACKSTRING_GLOBAL_REPEATABLE: repeatable = True cmt_va = gs.offset else: repeatable = False cmt_va = gs.written_at if not cmt_va: errors.append( "Can't get location where '{}' was written in 0x{:X}." .format(gs.s, gs.fva)) continue gs_cmt = format_comment(gs.s) if append_comment(cmt_va, gs_cmt, repeatable): cnt_commented_ss += 1 else: errors.append( "Failed to set comment at 0x{:X}: {}".format( cmt_va, gs_cmt)) # update IDA view idc.refresh_idaview_anyway() # clean up memory after each function eh.resetEmulatorHeapAndStack() print_summary(cnt_functions, cnt_analyzed, cnt_found_ss, cnt_commented_ss, errors) if PRINT_PLAIN_SUMMARY: print_plain_summary(userData["stackstrings"] + userData["globalstrings"]) print( "\nFinished ironstrings stackstring deobfuscation after {:.2f} seconds" .format(time.time() - start))
print("the new wcsdup hook was called") eh.hookCalled = True if eh.isValidEmuPtr(argv[0]): s = "the quick brown fox jumps over the lazy dog".encode("utf-16")[2:] memAddr = eh.allocEmuMem(len(s) + 2) eh.uc.mem_write(memAddr, s) eh.uc.reg_write(eh.regs["ret"], memAddr) return eh.uc.reg_write(eh.regs["ret"], 0) if __name__ == '__main__': # optional argument with sample path to test radare2 support if len(sys.argv) == 2: eh = flare_emu.EmuHelper(samplePath=sys.argv[1]) else: eh = flare_emu.EmuHelper() eh.analysisHelper.setName(0x41141a, "printf") print("testing iterate feature for printf function") strcpyEa = eh.analysisHelper.getNameAddr("j_strcpy") eh.iterate(eh.analysisHelper.getNameAddr("printf"), iterateHook) eh.analysisHelper.setName(strcpyEa, "testname") eh.addApiHook("testname", "strcpy") eh.addApiHook("wcsdup", wcsdupHook) print( "testing with renamed and redirected strcpy hook and new hook for wcsdup" ) eh.iterate(eh.analysisHelper.getNameAddr("printf"), iterateHook) if "hookCalled" not in dir(eh):
def decrypt2(argv): myEH = flare_emu.EmuHelper() # 两个参数 myEH.emulateRange(myEH.analysisHelper.getNameAddr("sub_401046"), stack=[0, argv[0], argv[1]]) return myEH.getEmuString(argv[0])