0% found this document useful (0 votes)
30 views3 pages

Breaking Into The DllMain

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views3 pages

Breaking Into The DllMain

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3

https://stmxcsr.com/break-into-dllmain.

html

Breaking into the DllMain


This post is a walkthrough to seting up a breakpoint into DllMain using the Windows Debugger.

The Code
Continuing the research on DLL files, we used as ground the same skeleton code we used to generate a
DLL that exports a function by its actual name (without compiler decorations). We added a small
enhancement in the code: an empty function that takes the ordinal number 1 so it can be called and facilitate
the demonstration purposes.

#include <windows.h>
#include <debugapi.h>

#define DllExport1 comment(linker, "/EXPORT:CallMe=?CallMe@@YGXXZ,@1,NONAME")


#define DllExport comment(linker, "/EXPORT:DoSomeMagic=?DoSomeMagic@@YGXXZ")

void WINAPI CallMe(void)


{
#pragma DllExport1
}

void WINAPI DoSomeMagic(void)


{
#pragma DllExport
OutputDebugStringA("DoSomeMagic was executed");
}

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


{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
OutputDebugStringA("DllMain was executed");
DoSomeMagic();
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}

return TRUE;
}

Execute the generated DLL


In order to execute the generated DLL, we use the Windows native utility rundll32.exe:
rundll32.exe test.dll, #1

As you can see in the code above, upon execution, debug strings are printed. We can see this strings using
SysInternal’s DebugView:
Following the path to DllMain
In order to debug the DLL and reach to DllMain, we have to load the DLL in memory. We can do this by
opening rundll32.exe on Windbg and setting it to execute our DLL. We follow this path: File -> Open
Executable. We the set the appropriate arguments as shown in the following image:

The first break point we hit is on ntdll!LdrInitShimEngineDynamic. Before we continue, we set up a


breakpoint to hit when our module gets loaded. This is done with sxe ld test. We carry on with debuggging
and we hit the breakpoint as soon as our module is loaded:

As the DLL is now mapped in memory, we can use lm m test to identify where it was mapped in memory:

Next step is to locate the entry point of our DLL by static analysis so we know where to break. For this, we
can use a tool like dumpbin, CFF Explorer, Ghidra or IDA.
To get the entry point using dumpbin:

dumpbin.exe test.dll findstr entry

The entry point as shown on Ghidra:

In order to find the actual bytes of the DllMain we’ll have to add the number dumpbin reports, to the start
address that lm m test shows.
?0x00000000`5a930000 + 0x1368

So, the DllMain should start at: 00000000`5a931368


We can confirm that by unassembling the byte that exist on and after this memory address:

In theory, if we set a breakpoint at 00000000`5a931368 and continue debugging, we should hit the
breakpoint and land into DllMain. However that’s what we get instead:

Tools
For this article, we used the following tools:

 Ghidra
 dumpbin
 Windbg

https://stmxcsr.com/categories/reversing

You might also like