예제 #1
0
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")
예제 #4
0
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])
예제 #5
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
예제 #7
0
    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")
예제 #8
0
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])