Информация об изменениях

Сообщение Re[2]: Может ли GetModuleHandle(Ex) привести к вызову LoadLi от 12.07.2018 11:08

Изменено 12.07.2018 11:22 EreTIk

Re[2]: Может ли GetModuleHandle(Ex) привести к вызову LoadLibra
M>Если исполняемый файл скомпанован с библиотеками в режиме deferred DLL load и до этого ни разу библиотека не использовалась, то LoadLibrary для библиотеки будет вызван, но...

Пример:
void __cdecl _tmain(int argc, TCHAR *argv[])
{
    HMODULE hModule{nullptr};
    ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, L"user32.dll", &hModule);

    keybd_event(0,0,0,0);
}


Сборка:
>cl /Zi /MTd /EHsc test.cpp /link /RELEASE /OPT:REF /DELAYLOAD:user32.dll dloadhelper.lib


Отладчик:
test!wmain+0x16:
00007ff7`8a121036 4c8d442420      lea     r8,[rsp+20h]
0:000> lsa @$ip
    56: 
    57: void __cdecl _tmain(int argc, TCHAR *argv[])
    58: {
    59:     HMODULE hModule{nullptr};
>   60:     ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, L"user32.dll", &hModule);
    61: 
    62:     keybd_event(0,0,0,0);
    63: }



Исполняем GetModuleHandleEx:
0:000> p
test!wmain+0x2d:
00007ff7`8a12104d 4533c9          xor     r9d,r9d
0:000> lsa @$ip
    58: {
    59:     HMODULE hModule{nullptr};
    60:     ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, L"user32.dll", &hModule);
    61: 
>   62:     keybd_event(0,0,0,0);
    63: }


User32 не появился:
0:000> ?? hModule
struct HINSTANCE__ * 0x00000000`00000000
0:000> lm
start             end                 module name
00007ff7`8a120000 00007ff7`8a172000   test       (private pdb symbols)  D:\Projects\!Trash\test.pdb
00007ff8`00090000 00007ff8`00303000   KERNELBASE   (deferred)             
00007ff8`031b0000 00007ff8`03262000   KERNEL32   (deferred)             
00007ff8`032c0000 00007ff8`034a1000   ntdll      (pdb symbols)          \\192.168.0.10\public\symbols\ntdll.pdb\E7A53714619369B2356D6363BA34ACA31\ntdll.pdb


Трассируем первое использрвание:
0:000> p
ModLoad: 00007ff8`01990000 00007ff8`01b20000   C:\WINDOWS\System32\USER32.dll
ModLoad: 00007fff`ff720000 00007fff`ff740000   C:\WINDOWS\System32\win32u.dll
ModLoad: 00007ff8`00d10000 00007ff8`00d38000   C:\WINDOWS\System32\GDI32.dll
ModLoad: 00007fff`ff740000 00007fff`ff8d2000   C:\WINDOWS\System32\gdi32full.dll
ModLoad: 00007ff8`006b0000 00007ff8`0074f000   C:\WINDOWS\System32\msvcp_win.dll
ModLoad: 00007ff8`005b0000 00007ff8`006aa000   C:\WINDOWS\System32\ucrtbase.dll
ModLoad: 00007ff8`016b0000 00007ff8`016dd000   C:\WINDOWS\System32\IMM32.DLL
test!wmain+0x3d:
00007ff7`8a12105d 33c0            xor     eax,eax
0:000> lm
start             end                 module name
00007ff7`8a120000 00007ff7`8a172000   test       (private pdb symbols)  D:\Projects\!Trash\test.pdb
00007ff8`00090000 00007ff8`00303000   KERNELBASE   (deferred)             
00007ff8`005b0000 00007ff8`006aa000   ucrtbase   (deferred)             
00007ff8`006b0000 00007ff8`0074f000   msvcp_win   (deferred)             
00007ff8`00d10000 00007ff8`00d38000   GDI32      (deferred)             
00007ff8`016b0000 00007ff8`016dd000   IMM32      (deferred)             
00007ff8`01990000 00007ff8`01b20000   USER32     (deferred)             
00007ff8`031b0000 00007ff8`03262000   KERNEL32   (deferred)             
00007ff8`032c0000 00007ff8`034a1000   ntdll      (pdb symbols)          \\192.168.0.10\public\symbols\ntdll.pdb\E7A53714619369B2356D6363BA34ACA31\ntdll.pdb
00007fff`ff720000 00007fff`ff740000   win32u     (deferred)             
00007fff`ff740000 00007fff`ff8d2000   gdi32full   (deferred)             
0:000> lsa @$ip
    59:     HMODULE hModule{nullptr};
    60:     ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, L"user32.dll", &hModule);
    61: 
    62:     keybd_event(0,0,0,0);
>   63: }


Что я делаю не так?
Re[2]: Может ли GetModuleHandle(Ex) привести к вызову LoadLi
M>Если исполняемый файл скомпанован с библиотеками в режиме deferred DLL load и до этого ни разу библиотека не использовалась, то LoadLibrary для библиотеки будет вызван, но...

Пример:
void __cdecl _tmain(int argc, TCHAR *argv[])
{
    HMODULE hModule{nullptr};
    ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, L"user32.dll", &hModule);

    keybd_event(0,0,0,0);
}


Сборка:
>cl /Zi /MTd /EHsc test.cpp /link /RELEASE /OPT:REF /DELAYLOAD:user32.dll dloadhelper.lib


Отладчик:
test!wmain+0x16:
00007ff7`8a121036 4c8d442420      lea     r8,[rsp+20h]
0:000> lsa @$ip
    56: 
    57: void __cdecl _tmain(int argc, TCHAR *argv[])
    58: {
    59:     HMODULE hModule{nullptr};
>   60:     ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, L"user32.dll", &hModule);
    61: 
    62:     keybd_event(0,0,0,0);
    63: }



Исполняем GetModuleHandleEx:
0:000> p
test!wmain+0x2d:
00007ff7`8a12104d 4533c9          xor     r9d,r9d
0:000> lsa @$ip
    58: {
    59:     HMODULE hModule{nullptr};
    60:     ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, L"user32.dll", &hModule);
    61: 
>   62:     keybd_event(0,0,0,0);
    63: }


User32 не появился:
0:000> ?? hModule
struct HINSTANCE__ * 0x00000000`00000000
0:000> lm
start             end                 module name
00007ff7`8a120000 00007ff7`8a172000   test       (private pdb symbols)  D:\Projects\!Trash\test.pdb
00007ff8`00090000 00007ff8`00303000   KERNELBASE   (deferred)             
00007ff8`031b0000 00007ff8`03262000   KERNEL32   (deferred)             
00007ff8`032c0000 00007ff8`034a1000   ntdll      (pdb symbols)          \\192.168.0.10\public\symbols\ntdll.pdb\E7A53714619369B2356D6363BA34ACA31\ntdll.pdb


Трассируем первое использование:
0:000> p
ModLoad: 00007ff8`01990000 00007ff8`01b20000   C:\WINDOWS\System32\USER32.dll
ModLoad: 00007fff`ff720000 00007fff`ff740000   C:\WINDOWS\System32\win32u.dll
ModLoad: 00007ff8`00d10000 00007ff8`00d38000   C:\WINDOWS\System32\GDI32.dll
ModLoad: 00007fff`ff740000 00007fff`ff8d2000   C:\WINDOWS\System32\gdi32full.dll
ModLoad: 00007ff8`006b0000 00007ff8`0074f000   C:\WINDOWS\System32\msvcp_win.dll
ModLoad: 00007ff8`005b0000 00007ff8`006aa000   C:\WINDOWS\System32\ucrtbase.dll
ModLoad: 00007ff8`016b0000 00007ff8`016dd000   C:\WINDOWS\System32\IMM32.DLL
test!wmain+0x3d:
00007ff7`8a12105d 33c0            xor     eax,eax
0:000> lm
start             end                 module name
00007ff7`8a120000 00007ff7`8a172000   test       (private pdb symbols)  D:\Projects\!Trash\test.pdb
00007ff8`00090000 00007ff8`00303000   KERNELBASE   (deferred)             
00007ff8`005b0000 00007ff8`006aa000   ucrtbase   (deferred)             
00007ff8`006b0000 00007ff8`0074f000   msvcp_win   (deferred)             
00007ff8`00d10000 00007ff8`00d38000   GDI32      (deferred)             
00007ff8`016b0000 00007ff8`016dd000   IMM32      (deferred)             
00007ff8`01990000 00007ff8`01b20000   USER32     (deferred)             
00007ff8`031b0000 00007ff8`03262000   KERNEL32   (deferred)             
00007ff8`032c0000 00007ff8`034a1000   ntdll      (pdb symbols)          \\192.168.0.10\public\symbols\ntdll.pdb\E7A53714619369B2356D6363BA34ACA31\ntdll.pdb
00007fff`ff720000 00007fff`ff740000   win32u     (deferred)             
00007fff`ff740000 00007fff`ff8d2000   gdi32full   (deferred)             
0:000> lsa @$ip
    59:     HMODULE hModule{nullptr};
    60:     ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN, L"user32.dll", &hModule);
    61: 
    62:     keybd_event(0,0,0,0);
>   63: }


Что я делаю не так?

UPD:
  • Пример собран и запущен на Windows 10.0.17134.165
  • Бегло посмотрел в функцию из kernel32 в XP SP3 через IDA: никакой загрузки не нашел, все упирается в LdrGetDllHandle и LdrAddRefDll из ntdll