PMA - Lab 09-03
Questions
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.
1
2
3
4
5
6
7
8
9
Questions:
1. What DLLs are imported by Lab09-03.exe?
2. What is the base address requested by DLL1.dll, DLL2.dll, and DLL3.dll?
3. When you use OllyDbg to debug Lab09-03.exe, what is the assigned based address for: DLL1.dll, DLL2.dll, and DLL3.dll?
4. When Lab09-03.exe calls an import function from DLL1.dll, what does this import function do?
5. When Lab09-03.exe calls WriteFile, what is the filename it writes to?
6. When Lab09-03.exe creates a job using NetScheduleJobAdd, where does it get the data for the second parameter?
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?
8. How can you load DLL2.dll into IDA Pro so that it matches the load address used by OllyDbg?
Answers
1. What DLLs are imported by Lab09-03.exe?
If we open the exe using CFFExplorer, we can see that it imports the following:
- Kernel32.dll
- Netapi32.dll
- DLL1.dll
- DLL2.dll
Now we can see that in Kernel32.dll the function LoadLibraryA is also imported:
Let’s open the exe in IDA and xref LoadLibraryA in order to check for other DLLs that are possibly loaded, so let’s go to imports and double click the function:
Now let’s press “x” to xref it:
And we can see 2 calls, let’s check them:
So the DLLs imported are:
- Kernel32.dll
- Netapi32.dll
- DLL1.dll
- DLL2.dll
- DLL3.dll - Could be loaded dynamically.
- user32.dll - Could be loaded dynamically.
2. What is the base address requested by DLL1.dll, DLL2.dll, and DLL3.dll?
To check the base address requested by those DLLs, we open them in CFFExplorer and go to: Optional Header -> ImageBase
And we do the same with the other DLLs:
- DLL1.dll - ImageBase=10000000
- DLL2.dll - ImageBase=10000000
- DLL3.dll - ImageBase=10000000 They all request the same base address 10000000.
3. When you use OllyDbg to debug Lab09-03.exe, what is the assigned based address for: DLL1.dll, DLL2.dll, and DLL3.dll?
We first need to find out where DLL3.dll is being loaded at because its the only one not in the Import Table, so we need to make sure it is executed and loaded by LoadLibraryA:
We can see it is loaded in sub_401000, let’s find what it is.
By xrefing sub_401000 we can see it is being called from the start, and right after GetCommandLineA with 3 parameters passed to it, so it looks like this is main:
So we have found main at 0x401000, let’s put a breakpoint on it in x32dbg
Go there, and put another breakpoint right after LoadLibraryA, to make sure all 3 DLLs were loaded:
Now after we run untill the breakpoint, we can open the “Memory Map” tab and search there for our DLLs, to see their base address:
So we can see that the base addresses they were loaded at were:
- DLL1.dll at 0x10000000
- DLL2.dll at 0x330000 - Didn’t manage to get “0x10000000” because DLL1.dll was already there.
- DLL3.dll at 0x390000 - Didn’t manage to get “0x10000000” because DLL1.dll was already there.
4. When Lab09-03.exe calls an import function from DLL1.dll, what does this import function do?
We can check what functions are imported from DLL1.dll:
And we can see it is being called at the start of the main:
We can then disassemble it with IDA by opening the DLL, we then go to the “Exports” and double click “DLL1Print”:
We can see that we pass 2 parameters to sub_10001038, one of them is a string format:
And from labs before, we know this looks like the “printf” function:
So we know the function will print “DLL 1 mystery data” followed by the data in dword_10008030.
If we check for xrefs to dword_10008030, we can see it is being written to in DLLMain:
If we go there, we can see that the return value from “GetCurrentProcessId” is being moved into that address:
Meaning it will print “DLL 1 mystery data” followed by the Process ID.
5. When Lab09-03.exe calls WriteFile, what is the filename it writes to?
We can go to main and take a look at the call for WriteFile:
We can see that the handle for the file comes from the return value of the function DLL2ReturnJ, and we can see it is imported from DLL2.dll:
So let’s check that function by double clicking it in the exports of DLL2.dll in IDA:
We can see that all it did is pass dword_1000B078 to eax. Let’s xref it to see where does it write to it:
Let’s take a look in DLLMain for this:
And we can see that it opens a file named “temp.txt” or creates it if it doesn’t exist.
So we know it writes to the file “temp.txt”.
6. When Lab09-03.exe creates a job using NetScheduleJobAdd, where does it get the data for the second parameter?
To answer that we need to walk back from the call to NetScheduleJobAdd:
We can see that the second parameter comes from the local variable “Buffer”.
Now we can see that has no xref to being written to, but we do send it as a parameter to a call to “ebp+var_10”. If we take a look at where is “var_10” being written to, we can see it is set as the return value from the call to GetProcAddress for the function “DLL3GetStructure” (that we dynamically resolve) and we know this function comes from DLL3.dll based on “hModule” value.
So to understand what the second parameter is set to, we need to understand what the function “DLL3GetStructure” in “DLL3.dll” does.
When we open DLL3.dll in IDA and go to the exports and double click “DLL3GetStructure”, we can see this:
So it moves the address of the memory location dword_1000B0A0 into the memory location pointed to by eax (which is the argument passed), let’s xref this dword to see where it is being written to:
Only in DLLMain, let’s go there:
So we can see it is being set to “36EE80”, if we want to understand more about this value, we need to read more about the second parameter of the function NetScheduleJobAdd:
We can see that we expect a pointer to the struct “AT_INFO”.
So let’s add that structure to IDA to help us understand what those values are set to.
We start by opening the structure window by pressing (shift + F9) or by going selecting View -> Open subviews -> Structures:
Now we want to add a new structure, so we press INSERT to add it, then select “Add standard structure”:
In it we search for the structure and double click it:
After that we go to the address of dword_1000B0A0 and press (alt + Q) or selecting Edit -> Struct var…:
In here we select our struct and press ok:
Now we can see that dword changed it representation to the struct:
And if we take a look at the disassembly now, we can see that it is a lot more clear:
We can see that the address 0x1000B0A0 (dword_1000B0A0) was JobTime because it was the first member of the struct AT_INFO. Let’s understand now what will run and when:
- JobTime:
To calculate it, we convert it to dec: 0x36EE80=3600000(milisecons) -> 3600000 / 1000 / 60 = 60(minutes) -> this means at 1am. - DaysOfWeek:
To calculate it, we convert it to binary: 0x7F=01111111(bin) so it is every day of the week. - Command:
We can see that the command is “ping www[.]malwareanalysisbook[.]com”. - Flags:
Now on the page I didn’t manage to find what those values stands for, so we can take a look at the SDK and search for those to understand their values. We can see that the struct is defined at “Imat.h”:
So we can take a look at the file, I searched for it and found it here:
Now we can open it and take a look at the values:
Nice! So we can see that based on our flags (0x11), it has set:- JOB_RUN_PERIODICALLY
- JOB_NONINTERACTIVE
So now we know it runs “ping www[.]malwareanalysisbook[.]com” every day at 1AM non interactively.
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?
- DLL 1 mystery data 1
As we already showed, this prints the process Id:
- DLL 2 mystery data 2
As we can see it prints the value CreateFileA returns, which is the handle to the open file.
- DLL 3 mystery data 3
As we can see it prints the address of the string “ping www[.]malwareanalysisbook[.]com”
8. How can you load DLL2.dll into IDA Pro so that it matches the load address used by OllyDbg?
In x32dbg we saw that DLL2.dll was loaded at 0x330000:
To load it in IDA at the same base address we can do the following:
Example First Option
Start by ticking the “Manual load” option, when we load the file to IDA:
Then we specify the new Image base we want:
And IDA will relocate the rest of the sections.
Example Second Option
Another option that we have, is to click Edit -> Segments -> Rebase program…:
And we then enter the new base we want:
And the program is rebased!