'error while getting function ordinal from the IDT table - mapping PE - c++

I'm trying to map a PE file in memory but I got to this point where I get to a read access violation.

The error happens when reading the address of the function used from DLLs from IDT and adding them to the IAT table.

Here is the error that was thrown:

Exception thrown at 0x772D500B (ntdll.dll) in PELoader.exe: 0xC0000005: Access violation reading location 0x80000013.

I don't know why it's reading that location 0x80000013.

The address of the ordinal is 0x00000013, using CFF (a PE viewer).

What I found

I discovered that the error only happens when it reaches a function in the IDT that has an ordinal instead of a name.

Here is the code that gets the address from the IDT to the IAT:

for (int i = 0; import_descriptors[i].OriginalFirstThunk != 0; ++i) {

        // Get the name of the dll, and import it
        char* module_name = ImageBase + import_descriptors[i].Name;
        HMODULE import_module = LoadLibraryA(module_name);
        if (import_module == NULL) {
            return NULL;
        }

        // the lookup table points to function names or ordinals => it is the IDT
        IMAGE_THUNK_DATA* lookup_table = (IMAGE_THUNK_DATA*)(ImageBase + import_descriptors[i].OriginalFirstThunk);

        // the address table is a copy of the lookup table at first
        // but we put the addresses of the loaded function inside => that's the IAT
        IMAGE_THUNK_DATA* address_table = (IMAGE_THUNK_DATA*)(ImageBase + import_descriptors[i].FirstThunk);
    

    for (int i = 0; lookup_table[i].u1.AddressOfData != 0; ++i) {
            void* function_handle = NULL;

            // looping through the lookup table
            DWORD lookup_addr = lookup_table[i].u1.AddressOfData;

            if ((lookup_addr & IMAGE_ORDINAL_FLAG) == 0) {
                // This is where I import by name
                IMAGE_IMPORT_BY_NAME* image_import = (IMAGE_IMPORT_BY_NAME*)(ImageBase + lookup_addr);
                char* funct_name = (char*)&(image_import->Name);
                printf("[*] adding address of: %s\n", funct_name);
                function_handle = (void*)GetProcAddress(import_module, funct_name);
            }
            else {
                //the exception is thrown after this line is printed in the console
                printf("--------------- this one has an Ordinal------\n");
                // import by ordinal, directly
                function_handle = (void*)GetProcAddress(import_module, (LPSTR)lookup_addr);
            }

            //the exception is thrown when checking if the function_handle is != null
            if (function_handle == NULL) {return NULL;}

            // change the IAT, and put the function address inside.
            address_table[i].u1.Function = (DWORD)function_handle;
    }
}

I think I may have misaligned the ordinal somehow, But I don't know how.



Solution 1:[1]

I think you problem is that you need to zero out the 8 at the top of the ordinal. From msft docs

"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."

I think the high order word being zero vs not zero is how it know whether it getting a pointer to a string or an ordinal

so do this

funct_name &= 0x0000ffff

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1