Fill in DLL import table manually: IMAGE_IMPORT_DESCRIPTOR's Name field stores 0x0000FFFF
Asked Answered
D

1

0

My goal is to fill in Dll's import table manually in order to hook internal LoadLibrary calls (when you load library it may load another library inside its DllMain).

Here is my code which fill in Import table recursively for each dll in dependecies hierarchy and it works fine except some dlls (api-ms-win-crt-locale-l1-1-0.dll in this case).

void PEUtility::fillImportTable(HMODULE loadedModule, FillImportFlag flag, std::function<void(HMODULE&)> callback)
{
    std::stack<HMODULE> modules;
    modules.push(loadedModule);

    while (modules.size())
    {
        auto module = modules.top();
        modules.pop();

        auto imageBase = (DWORD_PTR)module;

        auto header = ImageNtHeader(module);
        auto importTable = (PIMAGE_IMPORT_DESCRIPTOR)(DWORD_PTR)(header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + imageBase);

        while (importTable->OriginalFirstThunk)
        {
// !!!
// HERE I've got an error: importTable->Name stores 0x0000FFFF instead dll name
// !!!
            auto importedModuleName = (char*)(DWORD_PTR)(importTable->Name + imageBase);
            auto importedModule = GetModuleHandleA(importedModuleName);
            if (!importedModule)
            {
                importedModule = LoadLibraryExA(importedModuleName, 0, DONT_RESOLVE_DLL_REFERENCES);
                if (flag == FillImportFlag::Recursive)
                    modules.push(importedModule);
            }

            auto nameAddressPtr = (PIMAGE_THUNK_DATA)(DWORD_PTR)(importTable->OriginalFirstThunk + imageBase); //Import Lookup Table address (functions names)
            auto functionAddressPtr = (PIMAGE_THUNK_DATA)(DWORD_PTR)(importTable->FirstThunk + imageBase); //Import Address Table (IAT) address (functions addresses)

            while (nameAddressPtr->u1.Function)
            {
                FARPROC importedFunctionPtr = NULL;
                if (nameAddressPtr->u1.Ordinal & IMAGE_ORDINAL_FLAG)
                {
                    importedFunctionPtr = GetProcAddress(importedModule, MAKEINTRESOURCEA(nameAddressPtr->u1.Ordinal));
                }
                else
                {
                    auto impotByNameImage = (PIMAGE_IMPORT_BY_NAME)(DWORD_PTR)(nameAddressPtr->u1.AddressOfData + imageBase);
                    importedFunctionPtr = GetProcAddress(importedModule, (char*)impotByNameImage->Name);
                }

                if (importedFunctionPtr)
                {
                    auto oldProt = 0ul;
                    VirtualProtect(functionAddressPtr, sizeof(IMAGE_THUNK_DATA), PAGE_EXECUTE_READWRITE, &oldProt);
                    functionAddressPtr->u1.Function = (DWORD_PTR)importedFunctionPtr;
                }

                nameAddressPtr++;
                functionAddressPtr++;
            }

            importTable++;
        }

// HERE in callback I hook LoadLibrary & RegQueryVAlue calls if 'module' has such dependencies
        callback(module);
    }
}

The problem is that the Name field of IMAGE_IMPORT_DESCRIPTOR structure stores 0x0000FFFF instead of Dll name.

So my question is how can I fix that? What does 0x0000FFFF mean? Maybe this is some "special" module (see api-ms-win-crt-locale-l1-1-0.dll below on screenshot)?

Here is screenshot from my debug session. enter image description here

UPDATE:

Maybe 0x0000FFFF means that dll doesn't have dependencies?

I've looked api-ms-win-crt-locale-l1-1-0.dll dependencies in Dependency Walker and seems this dll has nothing to import.

Dystopia answered 15/11, 2016 at 9:41 Comment(0)
B
3

from your screenshot clear view that importTable point to imageBase (i.e. IMAGE_DOS_HEADER). this happens when header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0 - you not check for this condition, as result and error

api-ms-win-crt-locale-l1-1-0.dll simply have no import - DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] is zero. need check - are import exist before process it

Blomquist answered 15/11, 2016 at 13:19 Comment(2)
does this mean that DLL does not have imports if and only if DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] is zero? How best to check that module have no import?Dystopia
@DmitryKatkevich - yes, you exactly need check DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] - VirtualAddress must be !=0 and Size == sizeof(IMAGE_IMPORT_DESCRIPTOR)*n; where n > 0Blomquist

© 2022 - 2024 — McMap. All rights reserved.