Proofpoint researchers uncovered a malware campaign delivering a payload named after none other than “Voldemort”—the malware that must not be named! In this post, I’ll show you how easy it is (almost dark magic) to deobfuscate strings in malware by combining the powerful Dumpulator with some simple IDA scripting. And Voldemort makes for the perfect example.

What is Dumpulator?

Dumpulator is like the magic wand of malware analysis, especially when it comes to tasks like deobfuscation. It allows you to emulate code execution, meaning you can run malware decryption routines without actually executing the malware. It’s built on top of the Unicorn engine, and as the name suggests, Dumpulator works on memory dumps to emulate code.

But enough talk—head over to the project’s GitHub and check it out yourself: Dumpulator GitHub

The Method

Here’s the overall plan:

  • First, we need to identify the string decryption function inside the malware sample.
  • If re-implementing the decryption routine looks like a major pain (which it usually is), we’ll emulate it using Dumpulator instead. This approach will almost always get the job done faster and more efficiently.
  • Once we’ve identified the decryption function, we’ll dump the process’ memory and grab all the cross-references and arguments (basically, the list of encrypted strings) using IDA scripting.
  • Then, we’ll use Dumpulator to emulate the decryption process for each string, decrypting everything in one fell swoop.
  • Finally, we can either rename the variables in IDA or just add the decrypted strings as comments—whatever works best for your analysis.

Sound good? Let’s jump into the steps.

Identifying the String Decryption Function

First, let’s channel our inner Hermione and do some detective work. We need to find where in Voldemort’s code the string decryption is happening. Usually, this involves looking for routines that deal with encrypted data—something like an XOR loop, custom cipher/hashing, AES whatever…

The number of cross references combined with the bitwise operations found inside screams string decryption already. Cross-references

Bitwise_operations

Getting the Cross-References and Arguments in IDA

Once we have the decryption function, we want to find all the places where it’s used. This means gathering cross-references to the function and checking what strings are being passed in as arguments. Lucky for us, IDA scripting (using IDAPython) makes this a breeze. You can easily automate finding all the locations where the decryption function is called, as well as the memory addresses of the encrypted strings.

In this sample we can see that the encrypted strings are passed in RCX by the instruction LEA. We go back 10 instructions before every call to the decryption function and hope there will be a LEA RCX snippet! Note, we renamed the autogenerated function name in IDA to “decrypt_string” already.

allStrings = {}

def get_xrefs_and_args(func_name):
    func_addr = idc.get_name_ea_simple(func_name)
    if func_addr == idc.BADADDR:
        return
    if not ida_funcs.get_func(func_addr):
        return
    func_name = idc.get_func_name(func_addr)
    print(f"Finding xrefs to function: {func_name} at {hex(func_addr)}")
    for xref in idautils.CodeRefsTo(func_addr, False):
        print(f"\tXref found at {hex(xref)}")
        prev_addr = xref
        found_lea = False
        for _ in range(10):
            prev_addr = idc.prev_head(prev_addr)
            if prev_addr == idc.BADADDR:
                continue
            mnemonic = idc.print_insn_mnem(prev_addr)
            if mnemonic == "lea":
                first_operand = idc.print_operand(prev_addr, 0)
                if first_operand == "rcx":
                    varname = idc.get_operand_value(prev_addr, 1)
                    allStrings[hex(varname)] = varname
                    found_lea = True
                    break
        if not found_lea:
            print(f"No LEA RCX instruction found before call at {hex(xref)}")

get_xrefs_and_args("decrypt_string")

Using Dumpulator with a Memory Dump

Now that we have the decryption function and the encrypted strings, it’s time to unleash Dumpulator. Here’s the basic idea: take a memory dump from the malware (which you can do in Process Hacker, X64dbg or numerous other ways), and feed it into Dumpulator. The tool will simulate the decryption routine, process the strings, and return the decrypted results.

Here we are using the built-in MiniDump command as suggested on the linked GitHub page. Creating_dump

Think of it as letting Voldemort’s own magic undo itself. We’re tricking the malware into decrypting its own strings for us!

dp = Dumpulator(r"YOURPATH\voldemort.dmp", quiet=True)

Dumpulator handles the heavy lifting of emulating the CPU and memory, so we can sit back and collect the decrypted strings without needing to fully reverse engineer the encryption scheme.

for s in allStrings.keys():
    dp.call(0x000000018000CE80, [allStrings[s]])
    allStrings[s] = extract_strings(dp.read(allStrings[s], 32))
    if allStrings[s]:
        success = idc.set_name(int(s,16), allStrings[s], 0x810)
        if success:
            print(f"\tSuccessfully renamed variable at {s} to {allStrings[s]}")
        else:
            print(f"Failed to rename variable at {s}")

Note the constant passed to the set_name function, those options are very useful for handling duplication and bad characters!

Use the Results in IDA

Once Dumpulator has decrypted the strings, we can pull those results back into IDA. At this point, you have a couple of options like rename the variables or add them as comments whichever you prefer.

As the previous python snippet shows I set them as names and they’re looking good! Magical_result

Wrapping Up

And that’s it—using Dumpulator with IDA Pro makes deobfuscating strings in malware so much easier. By emulating the decryption routine, we skip the tedious process of manually reversing encryption algorithms, allowing us to focus on understanding the malware’s functionality.

Next time you encounter a Voldemort-like malware sample trying to hide its strings, don’t waste hours reversing each encryption routine manually. Just fire up Dumpulator, and let the magic do the work for you!

Feel free to try this out, until next time, happy dumpulating!

Stay tuned for more malware-related tips and tricks, and as always, may your analysis be quick and your code easy to crack!