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.
CodePudding user response:
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.