Our first step will be to find the entry point of the hollowed out process, patch it with 0xCC (int9), set Ollydbg as the just in time debugger, let the malware execute till after it calls ResumeThread. At this point we the malware cause the hollowed process to be opened in Ollydbg. We can then patch the malware with the original bytes and we will be good to go.
In the recommended blog posts it was stated that the entry point will be stored in the EAX register of the CONTEXT structure. If we were to compile CodeReversing's C++ and view the code in IDA we would have the above assembly (left) and the CONTEXT structure (right). Since we know EAX will contain the address we need to find that address in the CONTEXT structure of the memory of the malware. We know that the malware will use SetThreadContext to set the register of EAX so we can set a breakpoint on it before it's called.
From MSDN
BOOL WINAPI SetThreadContext(
_In_ HANDLE hThread,
_In_ const CONTEXT *lpContext
);
If we wanted to get the contents of the EAX in the CONTEXT structure we would need to find the address of lpContext [0xB0]. In the example above the entry point is 0x40EE60. Since we know the address of the entry point we will need to patch it. The best non-complicated tool I have found for patching the memory of a running process is Process Hacker. Once we have it running we will locate the hollowed out process running under the malware. Right Click, Properties and the locate the memory section of the hollowed out process.
We will then need to patch the memory with 'cc' aka INT3 (remember the original byte) , press "Write" and now the hollowed out process has been patched. We will need to setup our just in time debugger by opening Ollydbg > Options > Just-in-time debugging. Then we will need to step through the code after the SetThreadContext until ResumeThread is called. After it's called the INT3 instruction will be executed and our Just in time debugger will open up Ollydbg. We now can patch the INT3 with the original byte and now continue stepping through the code that was written to the hollow process.
Patching with INT3 can be very useful. I have used it many times when I want to debug a service with ollydbg. Hope this was helpful to anyone who might come across this problem. Cheers.
Update 2014/08/29
If the sample uses the CreateRemoteThread and LoadLibrary* technique the following steps can be used.
- Open the sample in a debugger
- Set a breakpoint on OpenProcess and execute till the breakpoint is hit.
- Open a separate instance of the child process that is being injected into.
- Change the process-id (3rd argument for OpenProcess) to the newely created child process.
- Set a bp on LoadLibrary* in the child/dummy process in the debugger.
- Execute to LoadLibrary* is hit.
- Set a breakpoint on the DLLEntryPoint of the dll.
- Start walking through the code.
Another trick to pause at the new EntryPoint of the suspended process is to attach to it via. another debugger e.g. WinDbg and set a breakpoint at ntdll!RtlUserThreadStart (Win7) or kernel32!BaseProcessStartThunk (WinXP). Once we are at RtlUserThreadStart or BaseProcessStartThunk, inspect the value of EAX and place another breakpoint.
ReplyDeleteAs follows (In Win7):
bp ntdll!RtlUserThreadStart
bp @eax
The reason why OllyDbg v1.10 can't attach to a suspended process (initially suspended) is due to the process's PEB being incompletely initialized. This happens at point OllyDbg v1.10 tries to call "EnumProcessModules" function. Sorry if off-topic.
Not off topic at all. Thank you for the information. I was wondering how others would go about it and why I couldn't attach to the process. Keep up the great posts on your blog. Cheers.
DeleteHow exactly would i attached windbg to it. When I do it gives me an error. I am attaching before ResumeThread()
Deletethanks in advance.
Sorry, but I don't know how to mimic the steps in Windbg. I'd recommend checkout out waliedassar comments (2 above). That will probably point you in the right direction.
DeleteYou can also force the new process to initialize itself by injecting a thread using CreateRemoteThread on Sleep() for example. After that thread returns, you can attach with Olly v1.10.
ReplyDeleteCool. Thanks for the comment.
DeleteHow would that work? Sleep suspends the current thread, not the whole process.
DeleteIf the process is suspended (initially suspended), then its Process Environment Block (PEB) is not completely initialized and this is why OllyDbg v1.10 can't attach to it (due to the "EnumProcessModules" function failure).
DeleteBut once you create a dummy thread into this suspended process, the uninitialized values in its PEB will be filled i.e. PEB becomes ready and the suspended process appears in the "Select process to attach" dialog box of OllyDbg v1.10.
Hope this helps.
Nice. Excellent run-through...
ReplyDeleteHave you considered the "EB FE" technique? Right before resuming the remote thread. Patch the first two instructions with "EB FE". On resuming the thread, it'll be put into an infinite loop stuck in the same "EB FE" instruction. You can now attach with a debugger, path the "EB FE" bytes back and start debugging.
ReplyDeleteI have used the EB FE technique many times. I'm a big fan of it. The int3 technique is nice because it removes having to attach to the process manually and it's one byte shorter.
DeleteJust Look For WriteProcessMemory Call After VirtualAllocEx and You can get the Address of Executable to Written on SUSPENDED Process,You Can Easily DUMP it .
ReplyDeleteCorrect but dumping a process and continuing to debug a process are two separate things. I'd recommend re-reading the post.
DeleteUnfortunately, Ollydbg 1.1 can not attach to a suspended processes.
ReplyDeletetry https://www.openrce.org/repositories/users/anonymouse/ModifiedCommandLinePluginWithChildDbg_Date_16082008.rar
it has its own problems but it succeeds in attaching to a child process most of the time :D