Today we are picking up where we left off in part three. The goal here is to extract the PE file that's injected into
iexplorer.exe's address space. Unlike the prior article, this post will be light on static analysis as its main goal is to help us transition to reversing the injected binary.
Follow along note: We'll be using the sample dumped after step 8 (part one) for IDA. When running the sample in x64dbg, the dumped sample is taken just prior to step 8.
Exercise caution (i.e. run in an isolated VM) as this is a live malware sample.
I'm not responsible for any damage.
Here is what we have covered so far:
- Extracted executable from web page
- Using the upx executable, unpacked the first packer
- Using a debugger, unpacked the sample a second time
- The final running instance of the dumped executable looked to have been wrapped with another packer that, when removed, caused the unpacked executable to throw an error during execution.
- Had to leave the final packer in place for the debugger but removed for IDA.
- Inspected API hooking of
- Call to
CreateProcessAto trigger it
- Removal of the API hook
- Reviewed the code the API hook jumps to
- Discovered that the code is writing another PE file into the address space of
Here we will use two debuggers to control execution. The first one will pause execution of
svchost.exe so that the second debugger can be attached to
iexplorer.exe (before the injected code in
Debugger 1 will control
svchost.exe by setting a break point inside the function the API hook jumps to. To set the break point, highlight the instruction after final call to
402AFD and hit
F2. Or, assuming your base address is the same, run this script in x64Dbg.
run bpc bp 411513 run step bp 402B02 run
Code Snippet 1 - x64Dbg script to break execution for
The script also covers unpacking the packer at the beginning of the executable's process. This will leave the program paused at the correct location for the next phase.
Screenshot 1 - Debugger running
svchost.exe paused after hooking
iexplorer.exe's entry point
Calling Debugger Two
Open up another instance of x64Dbg and attach it to the running instance of
Screenshot 2 - Attaching to
iexplorer.exe's entry point by hitting
Ctrl+g and entering this formula.
iexplorer.exe's base address go to the
Memory Maptab in x64Dbg and look for
AddressBase + [AddressBase + [AddressBase + 3c] + 28]
Code Snippet 2 - Entry Point Formula
The current running instance of
iexplorer.exe is loaded into
1380000 so our formula looks like this.
Screenshot 3 - Find
iexplorer.exe entry point
Which takes us to this location in the disassembler.
Screenshot 4 -
iexplorer.exe entry point
Next, set a break point at the
call edi instruction (@ RVA
1CA4) and now we are ready to let
svchost.exe run its course. Go back to
svchost.exe's x64Dbg instance and hit
F9. The program will exit; however, in
iexplorer.exe's x64Dbg instance the program will pause at the break point. Might need to hit
F9 a single time in
iexplorer.exe's debugger to let execution to get to the entry point and out of
So close! Now we need to extract the PE file at the opportune moment.
When to Extract
Before we can extract the binary we need to do a little bit of analysis. Remember the value pushed onto the stack just prior to the call to
EDI (see part three)? This is an allocated memory region which holds variables the function called probably needs. Right click on the
push instruction and select
Follow in Dump and choose the address value.
Screenshot 5 - Follow in Dump
Dump window it should look something like this. Might need to set the view to
Screenshot 6 - Memory Addresses
The ones in red resolve to
ntdll functions. Notice when looking at the top 5 in x64Dbg's
Memory Map tab, 4 correspond to places in memory with
ERW permissions (also included the two memory segments which hold the variables and the function @
Screenshot 7 - Allocated Memory (1)
Screenshot 8 - Allocated Memory (2)
Let's take this analysis a little bit further. Open up each of these memory segments in the
Screenshot 9 - Start of address space 20010000
Screenshot 10 - Hex values @ 20017C79
Screenshot 11 - Start of address space 50000
Screenshot 12 - Start of address space 60000
Aha! Notice the
MZ at the start of 20010000! This should be the injected binary file! Looking at the address of the second address entry in screenshot 6, the value points to an address inside the address space for 20010000. This is probably the entry point into the binary.
Let's search for a call to this entry point. Upon looking at the assembly code, we notice that call instructions are made using the base address in
EDI probably holds the the value of the function's argument. We can confirm by looking near the beginning of the function where the argument passed into this function is loaded into
EDI. Let's mimic the format for these calls in the find dialog box. Press
Ctrl+f in x64Dbg and search for
call dword ptr ds:[edi+4].
Screenshot 13 - Find call
Following the only result returned, we see the call instruction at
Screenshot 14 - Find Result
Notice the value of
Screenshot 15 - Value of
We could go all crazy and further confirm using the entry point formula we used earlier to see if the entry point address matches this value.
Screenshot 16 - Resolve Entry Point of injected binary
This corresponds directly with screenshot 6's second entry!
We probably could extract it now, but let's get
EIP to point to the entry point first just to be safe.
Set a break point at
call dword ptr ds:[edi+4] and run to that point.
Screenshot 17 - Execution paused at jump to entry point
Single step using
F7 and the
EIP should now point to the injected binary's entry point.
Screenshot 18 - Execution at binary's entry point
Now time to dump the binary from memory. Open Scylla and click on
Dump Memory under
Screenshot 19 - Scylla
Dump Memory option
Select the used memory ranges inside of
20010000 and click
Dump PE. Give the file a name (choose extension .dll as this turns out to be a dll according to Puppy[^n]) and save the file.
Screenshot 20 - Memory selection in Scylla
Before we can declare victory, let's perform two quick checks to help ensure the dumped file runs.
Check 1: Open the dumped PE file in your favorite PE viewer to see if it can be parsed.
Check 2: Launch the DLL in the debugger to see it if works
- Change the
010Eto signal that it is an exe versus a dll.[^n]
- Screenshot 21 - Change the DLL's characteristics
Save Asto save the change in-order to not overwrite the original dumped file.
- Start the exe in x64Dbg and confirm the RVA of the starting address is
And, hopefully, Victory!
Overall nothing deep here as we successfully dump the injected DLL to disk for further inspection. In the next post of the series we will start to pick apart the DLL's functionality.