Home > Back-end >  difficulty in understanding c function that resolves function names by ordinals
difficulty in understanding c function that resolves function names by ordinals

Time:03-24

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.

  • Related