2016-11-15 27 views
0

Моя цель - заполнить таблицу импорта Dll вручную, чтобы перехватить внутренние вызовы LoadLibrary (при загрузке библиотеки она может загрузить другую библиотеку внутри DllMain).Заполните таблицу импорта DLL вручную: поле имени IMAGE_IMPORT_DESCRIPTOR хранится 0x0000FFFF

Вот мой код, который заполнить таблицу импорта рекурсивно для каждой DLL в иерархии dependecies и она работает нормально, за исключением некоторых библиотек DLL (API-мс-беспроигрышная элт-локали l1-1-0.dll в этом случае).

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); 
    } 
} 

Проблема заключается в том, что Name поле IMAGE_IMPORT_DESCRIPTOR структуры магазинов 0x0000FFFF вместо имени DLL.

Так что мой вопрос в том, как я могу это исправить? Что означает 0x0000FFFF? Возможно, это какой-то «специальный» модуль (см. api-ms-win-crt-locale-l1-1-0.dll ниже на снимке экрана)?

Вот скриншот из моей сессии отладки. enter image description here

UPDATE:

Может 0x0000FFFF означает, что DLL не имеет зависимостей?

Я искал api-ms-win-crt-locale-l1-1-0.dll зависимостей в Dependency Walker и кажется, что этой DLL нечего импортировать.

ответ

2

с вашего скриншота ясный вид, что importTable указывает на imageBase (т. Е. IMAGE_DOS_HEADER). это происходит, когда header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0 - вы не проверяете это условие, как результат и погрешность

api-ms-win-crt-locale-l1-1-0.dll просто не имеют импорта - DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] is zero. нужна проверка - есть ли импорт до процесса?

+0

это означает, что DLL не имеет импорта тогда и только тогда, когда 'DataDirectory [IMAGE_DIRECTORY_ENTRY_IMPORT]' равен нулю? Как лучше проверить, нет ли у этого модуля импорта? –

+0

@DmitryKatkevich - да, вам нужна проверка 'DataDirectory [IMAGE_DIRECTORY_ENTRY_IMPORT]' - VirtualAddress должен быть! = 0 и Size == 'sizeof (IMAGE_IMPORT_DESCRIPTOR) * n;' где n> 0 – RbMm