Jump to content
Nytro

How to turn a DLL into a standalone EXE

Recommended Posts

How to turn a DLL into a standalone EXE

Posted on July 21, 2016 by hasherezade

During malware analysis we can often encounter payloads in form of DLLs. Analyzing them dynamically may not be very handy, because they need some external loaders to run. Different researchers have different tricks to deal with them. In this post I will describe some of my tricks for patching DLLs, so that they can run as independent executables.

Usually we can encounter 2 cases:

  1. meaningful code starts in one of the exported functions
  2. meaningful code starts in DllMain

To illustrate those cases with real-life examples I will use 2 malware samples.
First case – represented by Bunitu Trojan (b0a91e1f91078bad48252edc989e868e) and second case: represented by Petya/Mischa dropper (c8e4829dcba8b288bd0ed75717214db6).

Those DLLs have been unpacked from their loaders/crypters – but in order to keep things simple I am not gonna describe here the full process of unpacking.

In both cases we will start from editing the field Characteristics in the File Header and removing the flag indicating that the file is a DLL. I will do it using PE-bear:

edit_fhdr.png

I changed the value:

changed_fhdr.png

Case #1: When the meaningful code starts in the exported function

In this case, one more modification is required before we save the file.

We have to change the entry point in order to point the appropriate function from export table – the one where the execution of the meaningful code starts. We need to find the Function RVA:

exports.png

Then, follow it:

follow_rva

On the Disasm tab we can see the code of this function. Now, we should redirect Entry Point to it’s beginning:

redirect

And save the file as EXE:

save_as

In case of Bunitu Trojan, this function does not take any parameters, so we not need to fill anything more. Now, we can run the saved file like a normal executable (see the patched version at malwr).

Case #2 – meaningful code starts in DllMain

This time we not need to change the Entry Point – just after changing Characteristics in File Header save the file and load it under a debugger (I will use OllyDbg).

Similarly to the main function in typical executables, DLLs have their DllMain function that is executed automatically when they are loaded to the memory  (the same function is also executed on few more events – i.e. on DLL unloading).
Let’s recall it’s header:

BOOL WINAPI DllMain(
  _In_ HINSTANCE hinstDLL,
  _In_ DWORD     fdwReason,
  _In_ LPVOID    lpvReserved
);

As we can see, the function takes 3 arguments. The first one (hinstDLL) is the handle to the memory area where the DLL has been loaded. Second stores a value that indicates the reason why the DllMain has been triggered. Read more here.

To make our patched DLL run properly, we must take care that it’s arguments will be filled with proper values – especially important are the first two that I mentioned.
The first argument: hinstDLL – must contain the module handle (ImageBase). Second usually should be filled with 1 – to emulate DLL_PROCESS_ATTACH.

That’s how the Entry Point of the dumped executable looks:

setup_ep

Let’s add a code that will overwrite the arguments with valid values. I will utilize some free cave for this purpose. Fortunately, there is enough space at the end of the code section:

free_space.png

I am gonna do some patching  in order to redirect execution to this place. We need 5 bytes for the jump – so, let’s remove/rearrange some code in order to gain the space (if we are lacking in space, some instructions can be also moved to the cave, along with the added code):

place_to_patch

Patched – step 1:

place_to_patch2

Patched – step 2:

patched_step2

I redirected execution to the mentioned cave. We will copy aside the address that is just after the added jump, to go back to this place later.

Now let’s fill the cave with needed code.

To fill the first argument with the valid ImageBase I will copy the value from Process Environment Block (pointed by FS:[30]) . This is example of the code that do this job:

MOV EAX, [FS:0X30] ; copy to EAX handle to PEB
MOV EAX, [EAX+0X8] ; copy to EAX the field with ImageBase
MOV [EBP+0X8], EAX ; copy the content of EAX
 into the first argument

Now, let’s fill the second argument with a vale 1, emulating that the DLL is loaded:

MOV DWORD [EBP+0XC], 0X1

The third argument can be filled with NULL:

MOV DWORD [EBP+0X10], 0

Added code:

added_code

Now only returning jump is remaining:

returning_jump

And we can save the modified executable:

copy_mod

Now we can run/debug the saved file as a standalone executable.

Ending note

Of course the described techniques are not a silver bullet and they may not cover all the cases you encounter. My goal was just to provide some examples and inspiration for experiments. However, those simple tricks worked for me in many cases making the work much easier.

Appendix

https://en.wikipedia.org/wiki/Win32_Thread_Information_Block

https://en.wikipedia.org/wiki/Process_Environment_Block

 

Sursa: https://hshrzd.wordpress.com/2016/07/21/how-to-turn-a-dll-into-a-standalone-exe/

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...