Emulating malware with Dumpulator

Hi Malware Analyst,

Yes finally after 4 months stop writting blog, I decided to refresh my malware analysis skill and try to write a simple tutorial related to malware analysis. I am going to share a simple tutorial on how to use Dumpulator to emulate malware.

Why emulation?

Part of the malware analysis is to gather information as much as possible about the malware for example to get the malware encryption keys, CnC server IP and Port and etc. We know that the malware creator will always evade those information from easy analysis such as by implemeting encryption, stack string, packing and so on. The question is why do we not just upload it to sandbox and get possible information? It is common that malware developer will split their executable into some stages to keep their binary small and looks legitimate to evade protection, The first executable is known to be downloader when the victim execute it then it will download the actual malicious payload. We will get full information report mixed between downloader and actual payload when we do that in sandbox.

So, If you are interested to analyze only to specific stage and specific code execution then emulation is the good choise to start with. Dumpulator allows us to write python script to emulate execution or call to specific codes that would help us to solve some complex evasion procedure. You can download dumpulator from https://github.com/mrexodia/dumpulator

I created a very simple C code just to give idea on how to simulate function call.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static char  MyData[11] = "Rio Asmara";
char MyData2[11];


char * setupString() {
    
    memcpy(MyData2, MyData, 11);
    return MyData2;
}

char* setupIP() {
    int size = 9;
    char myIP[9];
    myIP[0] = '1';
    myIP[1] = '0';
    myIP[2] = '.';
    myIP[3] = '1';
    myIP[4] = '.';
    myIP[5] = '1';
    myIP[6] = '.';
    myIP[7] = '1';
    myIP[8] = '\0';
    char * ip = (char*)malloc(size * sizeof(char));
    memcpy(ip, myIP, 9);
    return ip;
}

int main()
{
    printf("Check Me : %s\n",setupString());
    printf("Check Me : %s", setupIP());
}

We have two functions that will build strings during the execution. Lets assume those two functions execute very complex encryption code which very hard to analyze it statically that hinder the malware analyst to get malware config or IOC easily.

MiniDump

The first thing that we need to do to do the emulation is to create the memory dump of the malware. We can use x64debug to do this task.

Run the malware in x64debug and let it stop at the EntryPoint of the executable. What you need to do after you load the malware is just to click Run button once

The next thing to do is to type MiniDump followed by the filename. In this case I give the filename crack.dmp

Get the base address

The next steps is to get the PE base address from the memory dump, this is important in order to allow you rebase the image entry point in IDA so that you can have same addressing between IDA and Memory dump.

Write this python script and Run it. Point the dumpulator with the path to your memory dump file

from dumpulator import Dumpulator

if __name__ == '__main__':
    dp = Dumpulator("C:\\Apps\\xdbg\\release\\x64\\crack.dmp", quiet=False)

Find the circled information as the baseline address of the memory dump

It needs Dumpulator library to be loaded. If you use pycharm then you can install it by following this steps. Go to Settings

Press + button to add module

Search dumpulator on the search, select the module and install the package

Find the function address in IDA

The next steps is to find the memory address of the function that we are going to emulate. Open the malware binary in IDA.

Image Rebase

Once the binary is successfully opened in IDA, Then you need to rebase by following the steps below

Copy the base address from python code output into IDA and Click OK

Find the Function Address

We can see that there are two functions that we are going to call using dumpulator emulation. setupString and setupIP

We can see from the above code that both function will return value from its complex code, We want to see what is the return value of the those two functions. So lets jump into that function and get its address

We can see that the function start from the address that I circled in the picture below which indicates the start address of the function. Lets copy that address

We can do the same steps for the setupIP function.

Emulate the function call and read the return value

Once we collected the function address then next steps is to write the below python code to simulaate the call

from dumpulator import Dumpulator

if __name__ == '__main__':
    dp = Dumpulator("C:\\Apps\\xdbg\\release\\x64\\crack.dmp", quiet=False)
    result = dp.call(0x7FF6B4351790, [])
    ipAddress = dp.read_str(result)
    print(f"decrypted: '{ipAddress}'")

    result = dp.call(0x7FF6B4351910, [])
    malSignature = dp.read_str(result)
    print(f"decrypted: '{malSignature}'")

The hightlighted code above is where the call emulation will happen so that we need to put the address that we found in IDA. You can try to run the above code which will result like the below image

You can see that without having to do a heavy reverse engineering effort to read and decode the encryption algorythm (Hahahah), we can just emulate the call and get the actual strings (IOC) that we need.

3 comments

  1. Hey, great read! I particularly enjoyed your in-depth discussion of image rebasing, since it was something I hadn’t really thought of before. Being a fellow tech blogger myself, I also really appreciate how organized and well-formatted everything was – it definitely made the content much more digestible overall. Keep up the awesome work!

Leave a Reply