Code: GetModuleHandleA("ntdll.dll"); если не прокатит можно заюзать: Code: #include <Psapi.h> #pragma comment( lib, "Psapi.lib" ) DWORD GetModuleInfo( const char * module ) { HANDLE hProccess = GetCurrentProcess(); HMODULE Module[1024] = { 0 }; DWORD Need = 0x00; if ( EnumProcessModules( hProccess, Module, sizeof( Module ), &Need ) ) { for ( int i = 0; i < int( Need / sizeof( HMODULE ) ); i++ ) { LPSTR FileName = new CHAR[512]; ZeroMemory( FileName, 512 ); if (GetModuleFileNameExA(hProccess, Module[i], FileName, 512)) { if( strstr(FileName, module) != NULL ) { delete [] FileName; FileName = NULL; return (DWORD)Module[i]; } } delete [] FileName; FileName = NULL; } } return 0x0; } DWORD htdll = GetModuleInfo("ntdll.dll");
Ну выдири его из PEB по аналогии с kernel32/kernelbase Точно не уверен, но на 32 битных системах примерно так будет Code: void* ntdll; __asm { mov eax, fs:[0x30] // PEB mov eax, [eax + 0x0c] // PPEB_LDR_DATA mov eax, [eax + 0x1C] // Модули в порядке инита mov eax, [eax + 0x08] // ImageBase первого модуля. А первый у нас ntdll.dll mov ntdll, eax } printf("NTDLL BASE = %0.8X", ntdll); для теста можешь по оффсету 0x18 взять адрес полного пути либы и реально проверить ntdll это или нет. т.е. всё будет выглядить примерно так Code: void* ntdll; WCHAR* name; __asm { push edx mov eax, fs:[0x30] // PEB mov eax, [eax + 0x0c] // PPEB_LDR_DATA mov eax, [eax + 0x1C] // Модули в порядке инита mov edx, [eax + 0x08] // ImageBase первого модуля. А первый у нас ntdll.dll mov ntdll, edx mov edx, [eax + 0x18] // FullName первого модуля. mov name, edx pop edx } printf("BASE = %0.8X\nNAME = %ws\n", ntdll, name);
У меня так: Code: PVOID GetNtdll() { LDR_DATA_TABLE_ENTRY *pModule; PEB *pPeb; __asm { mov eax, fs:[0x30] mov pPeb, eax } pModule = (LDR_DATA_TABLE_ENTRY *)((char*)pPeb->Ldr->InInitializationOrderModuleList.Flink-0x10); return pModule->DllBase; }