PMA Lab 9-3: OllyDbg
Analyze the Malware found in the file Lab09-03.exe using OllyDbg and IDA Pro. This Malware loads three included DLLs (DLL1.dll, DLL2.dll, and DLL3.dll) that are all built to request the same memory lo
Lab 9-3
Analyze the Malware found in the file Lab09-03.exe using OllyDbg and IDA Pro. This Malware loads three included DLLs (DLL1.dll, DLL2.dll, and DLL3.dll) that are all built to request the same memory load location. Therefore, when viewing these DLLs in OllyDbg versus IDA Pro, code may appear at different memory locations. The purpose of this lab is to make you comfortable with finding the correct location of code within IDA Pro when you are looking at code in OllyDbg.
Analysis
Let’s begin by taking a look at the exe.
Looking at the strings of the 4 files, the following ones stand out:
| File | Interesting strings |
|---|---|
| Lab09-03.exe | DLL1.dll DLL2.dll DLL3.dll DLL3GetStructure DLL3Print malwareanalysisbook.com |
| DLL1.dll | |
| DLL2.dll | temp.txt |
| DLL3.dll | ping www.malwareanalysisbook.com |
In terms of Imports, we can see some possible functionalities of this Malware:
- The Malware may dynamically resolve and import external resources (GetProcAddress, LoadLibraryA, and GetModuleFilenameA)
- The Malware may write files to the system. (WriteFile)
- Also, the Malware may allocate memory and use it in some fashion. (VirtualAlloc, HeapAlloc, VirtualFree, HeapFree, etc.)
- The Malware is importing functions from DLL1 (DLL1Print), and DLL2 (DLL2ReturnJ, and DLL2Print). Since these names are similar to the String DLL3Print and DLL3GetStructure, the Malware will most likely dynamically load DLL3, and use these functions.
Looking at the DLL exports:
- DLL1 exports the function DLL1Print
- DLL2 exports DLL2ReturnJ and DLL2Print
- DLL3 exports DLL3GetStructure and DLLPrint
After executing the file the following content is presented:

Apart from this Window and a file named temp.txt that is created in the same directory of the executable nothing interesting happens. Using procmon we can confirm that DLL3.dll is dynamically loaded by the exe.
Let’s take a look at the exe file in IDA:
From the Graph view, the file isn’t complex:

The executable is actually pretty straightforward:

It starts by calling DLL1Print, DLL2Print, and DLL2ReturnJ. The file then calls WriteFile to write a buffer containing “malwareanalysisbook.com” to a file.
Then, the Malware dynamically loads DLL3.dll with LoadLibrary, it gets the address of DLL3Print with GetProcAddress and calls the function.
Let’s take a look at these “DLLXPrint” functions:
DLL1Print has the following aspect:

As we can see, an address and a string format are being pushed into the stack prior to the printf call. By using Cross References (xrefs) in dword_10008030 we can see that its value is set in DLLMain:

This address will contain the process identifier of the calling process, returned by GetCurrentProcessId.
DLL2Print is pretty similar to DLL1Print:

Using the same technique on dword_1000B078 (using xrefs) we can see that its value is set up in DLLMain as well:

dword_1000B078 will get the return value of CreateFileA which is a handle of file temp.txt.
The function DLL2ReturnJ moves dword_1000B078 to eax and returns (meaning that it will return the handle to temp.txt).
As expected, DLL3Print is similar to DLL1Print and DLL2Print:

The value at offset WideCharStr is set in DLLMain using the API Call MultiByteToWideChar:

In sum, this call converts a string into Unicode. The original string is at offset aPingWww_malwar and the function takes as the lpWideCharStr parameter a pointer to a buffer that receives the converted string. As we can see, that buffer is offset WideCharStr thus, the value that is going to be printed in DLL3Print is the address of the string in Unicode format.
Finally, we have the DLL3GetStructure function. Just like DLL3Print, this function is dynamically loaded with a call to GetProcAddress and a call to the returned Address.
This function takes only one argument. which is a Buffer.
After the call to DLL3GetStructure, NetScheduleJobAdd is called:

This function submits a job to run at a specified future time and date. In terms of parameters the function has the following syntax:
NET_API_STATUS NET_API_FUNCTION NetScheduleJobAdd(
IN LPCWSTR Servername,
IN LPBYTE Buffer,
OUT LPDWORD JobId
);
Since Servername is NULL, the local computer will be used. Buffer is a pointer to an AT_INFO structure describing the job to submit and JobId is a pointer that receives a job identifier for the newly submitted job.
As we can see in the following image, the program execution is paused right before the NetScheduleJobAdd call:

The second parameter (highlighted in yellow) in the stack is a pointer to 0x0039B0A0. This value was pushed to the stack (returned) after the call to DLL3GetStructure. In the hex dump, we can see a Unicode string “ping www.malwareanalysisbook.com”. The same string that is converted to Unicode in DLLMain in DLL3.
By now we know that a Task will be scheduled, and is related to DLL3.dll. Let’s execute the Malware and inspect the Scheduled Tasks:

As we can see, this last part of the code creates a new task with the objective of pinging www.malwareanalysisbook.com every day at 1AM.
Questions:
1) What DLLs are imported by Lab09-03.exe?
In the Import Table of Lab09-03.exe we can see the following DLLs:
- kernel32.dll
- netapi32.dll
- DLL1.dll
- DLL2.dll
However, the Malware also loads DLL3.dll dynamically.
2) What is the base address requested by DLL1.dll, DLL2.dll, and DLL3.dll?
The image-base of the 3 DLLs is 0x10000000.
3) When you use OllyDbg to debug Lab09-03.exe, what is the assigned based address for: DLL1.dll, DLL2.dll, and DLL3.dll?
Inside Olly we can inspect the assigned based addresses for the DLLs with the Memory Map:

The screenshot was taken after DLL3 was Dynamically loaded. As we can see, DLL1 which was the first being loaded got its preferred address: 0x10000000. The other DLLs were rebased, DLL2 was loaded at 0x00330000 and DLL3 at 0x00360000
4) When Lab09-03.exe calls an import function from DLL1.dll, what does this import function do?
DLL1Print prints the string “DLL1 mystery data %d\n” where %d is current PID.
5) When Lab09-03.exe calls WriteFile , what is the filename it writes to?
In the following highlighted instructions prior to the WriteFile function being called, we can see that the return value of DLL2ReturnJ (handle to file temp.txt) is moved from eax to ss:[LOCAL.6] which is later moved to ecx and pushed into the stack as the first argument (hFile) to WriteFile:

Thus, the filename that the Malware writes to is temp.txt.
6) When Lab09-03.exe creates a job using NetScheduleJobAdd , where does it get the data for the second parameter?
The second parameter to NetScheduleJobAdd (Buffer) is returned by DLL3GetStructure.
7) While running or debugging the program, you will see that it prints out three pieces of mystery data. What are the following: DLL 1 mystery data 1, DLL 2 mystery data 2, and DLL 3 mystery data 3?
The Malware prints the following strings during execution:

The meaning of the numbers is:
- 2524 is the Current PID of Lab09-03.exe.
- 44 is the value of handle to temp.exe
- 3780800 is the memory address of Buffer (second argument to NetScheduleJobAdd)
8) How can you load DLL2.dll into IDA Pro so that it matches the load address used by OllyDbg?
As we’ve seen previously, DLL2 was loaded at 0x00330000:

In order to load DLL2.dll into IDA Pro with this address, we can do it in two different ways.
When opening the file, we can either select “Manual Load” :

And then selecting the Address:

Or, after loading DLL2.dll into IDA we can rebase the dll:
Edit >>> Segments >>>Rebase program…

After pressing OK, the addresses should match.