Debugging a DLL is not quite as straight forward as an executable, since you have to use rundll32 to load it and invoke DllMain. This is a brief posting discussing how to load a 64-bit DLL and break on DllMain, the sample I am using is Dridex and can be found on VirusTotal.
To begin, I needed to find the entry point of the DLL. In this case, I let IDA Pro do the work – IDA will identify the entry point in the exports tab.
Since I won’t be debugging with symbols, I took note of the address 0x140001570, this is where I ultimately set my breakpoint. The next step is to use WinDbg and rundll32 to load the DLL in memory. This can be done via command line or through the GUI. I’m using the 64-bit version of rundll32, which is located in C:\Windows\System32 (the 32-bit version is located in C:\Windows\SysWOW64\).
Take note of the arguments, you need to provide the path to the DLL you want to load, along with the name of entry point. Once WinDbg loads rundll32 into memory, it will break. This will allow you to set breakpoints, in this case I want to break when the malicious DLL is loaded into memory – I can’t set a breakpoint on the address of it’s entry point yet, as it’s not in memory (you could set a deferred break point, but if it’s using ASLR you won’t know it’s image base until it’s loaded). You can do this with the sxe ld command (MSDN), which allows the debugger to catch the load module exception. This will then give you the opportunity to set your break point before DllMain is called. From the command window, where dridex is the name of the DLL you want to break on load:
> sxe ld dridex
Resume your debugger and it should break when this module is loaded:
All this is left is to confirm your module’s base address and set your break point.
Resume execution, and you should see indication that your break point was encountered.
Now you’re ready to debug this DLL!