Reputation: 33
I am following a malware analysis course. And I came across this code which I found confusing. The first two sections make sense but the part where the if statement starts is very difficult for me to understand. This "if" statement is supposed to resolve function names by ordinals. I have put my questions in the comments.
FARPROC WINAPI myGetProcAddress(HMODULE hMod, char * sProcName) {
char * pBaseAddress = (char *) hMod;
// get pointers to main headers/structures
IMAGE_DOS_HEADER * pDosHdr = (IMAGE_DOS_HEADER *) pBaseAddress;
IMAGE_NT_HEADERS * pNTHdr = (IMAGE_NT_HEADERS *) (pBaseAddress + pDosHdr->e_lfanew);
IMAGE_OPTIONAL_HEADER * pOptionalHdr = &pNTHdr->OptionalHeader;
IMAGE_DATA_DIRECTORY * pDataDir = (IMAGE_DATA_DIRECTORY *) (&pOptionalHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
IMAGE_EXPORT_DIRECTORY * pExportDirAddr = (IMAGE_EXPORT_DIRECTORY *) (pBaseAddress + pDataDir->VirtualAddress);
// resolve addresses to Export Address Table, table of function names and "table of ordinals"
DWORD * pEAT = (DWORD *) (pBaseAddress + pExportDirAddr->AddressOfFunctions);
DWORD * pFuncNameTbl = (DWORD *) (pBaseAddress + pExportDirAddr->AddressOfNames);
WORD * pHintsTbl = (WORD *) (pBaseAddress + pExportDirAddr->AddressOfNameOrdinals);
// function address we're looking for
void *pProcAddr = NULL;
// resolve function by ordinal
if (((DWORD_PTR)sProcName >> 16) == 0) { // why shift by 16
WORD ordinal = (WORD) sProcName & 0xFFFF; // why & 0xFFFF
DWORD Base = pExportDirAddr->Base;
if (ordinal < Base || ordinal >= Base + pExportDirAddr->NumberOfFunctions)
return NULL;
// not sure what this part does
pProcAddr = (FARPROC) (pBaseAddress + (DWORD_PTR) pEAT[ordinal - Base]);
}
...
...
...
}
I would very much appreciate some explanation.
Upvotes: 1
Views: 112
Reputation: 138896
This allows you to split a number (here dword or double word) in two parts using bit operations, e.g:
0x12345678 >> 16 = 0x1234 (hi order word)
0x12345678 & 0xFFFF = 0x5678 (lo order word)
Why is the code doing that? It's documented with GetProcAddress's lpProcName parameter:
The function or variable name, or the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero.
Upvotes: 2