DLL means Dynamic-Link Library. It exposes functions to be used consumed by other binaries. These are called exports.
#define DLL_EXPORTextern"C" {
DECLDIR intAdd(int a, int b){
return(a + b);
}
typedefint(*addFunc)(int, int); // We define the function signature; takes 2 int, returns 1 int
addFunc _AddFunc;
HINSTANCE haModule = LoadLibrary("add.dll"); // Locate our DLL
_AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add"); // Get a pointer to the function `Add`int res = _AddFunc(23, 43);
There's not much difference between PE files and DLL. A DLL will often expose a few functions meanwhile a PE file usually only exposes one.
Both have a main function. When a DLL is load, its main function is called.
You can call a DLL using rundll32.exe myDll,MyExport arg1 arg2, or regsvr32.exe myDll and more.
rundll32.exe add.dll,Add 1 2
Strings
Can we find interesting strings?
Imports
A binary will require functions to work, these must be imported.
In Linux, it would look like #include <string.h>.
It there's an import called CreateFile or ShellExecute, you can guess what the malware might do.
A malware will often try to hide what it can do; it will do dynamic imports resolution.
Dynamic analysis
Sometimes, dynamic analysis will be faster. xdbg is a free and open source for Windows. You can load and debug a DLL.
Useful shortcuts
F7: step into (goes into the function) F8: step over (if you don't want to debug a function called) bp Add: put a breakpoint to a specific function bpc Add: remove that breakpoint
IDA
Useful shortcuts
<x>: to get the cross references of variables/functions <n>: to rename a function/variable <y>: change the type of a function/variable <g>: goto some address <esc>: go back </>: add a comment in decompilation view <;>: add a comment in disassembly view
Your turn! (~30 minutes)
Now that we've seen basic concepts, time to put it into practice
Allocates a fiber object, assigns it a stack, and sets up execution to begin at the specified start address, typically the fiber function.
A large chunk of data had been allocated previously and it is passed to this function.
We need to extract this data and analyze it.
Get our first flag
We will use xdbg.
Analyzing the function
Analyzing the function
Checks if the CnC responds with "ok"
Exits otherwise
Pushes 14ko of something on the stack
Does magic with it
Executes it
dat script
ea = 0x1000126C# start address
ea_end = 0x1001C7E5# end address
shellcode = []
instr_len = 7# mov [ebp+var_FB7], 84h = 7 bytesfor i inrange(0, (ea_end - ea), instr_len):
instr = idc.GetManyBytes(ea + i, ItemSize(ea + i)) # fetch the instruction
shellcode.append(ord(instr[6])) # get the byte moved to the buffer#print(shellcode)
time = [0x00, 0x01, 0x02, 0x03]
dec = []
for i inrange(0, len(shellcode), 4):
dec.append(shellcode[i])
dec.append(shellcode[i + 1] ^ time[1])
dec.append(shellcode[i + 2] ^ time[2])
dec.append(shellcode[i + 3] ^ time[3])
writeToFile(dec)
Basic static analysis, again
$ strings blob.data
!This program cannot be run in DOS mode.
[...]
This is a whole PE file! How come?
Position independant executable (PIE)
Position-independent code is not tied to a specific address. This independence allows the code to execute efficiently at a different address in each process that uses the code.
So, the machine code will jump on relative addresses as non-pie code would jump on absolute addresses.