Приветствую вас, уважаемые. Имеется ситуация - в процесс загружается DLL, внутри DllMain происходит удаление записи об ее имени из списков InLoadOrderModuleList и InMemoryOrderModuleList. вот код: Code (Text): hModule - хэндл DLL HideDllFromPEB proc uses esi edi ebx hModule : DWORD LOCAL lpBuffer : DWORD LOCAL lpName : DWORD invoke LocalAlloc, LPTR, 256 mov lpBuffer, eax invoke LocalAlloc, LPTR, 64 mov lpName, eax invoke GetModuleFileNameA, hModule, lpBuffer, 256 test eax, eax jz _return mov esi, lpBuffer mov ecx, eax dec eax @@: cmp byte ptr [esi + eax], '\' jz @F dec eax jmp @B @@: inc eax add esi, eax sub ecx, eax xor eax, eax mov edi, lpName @@: lodsb stosw loop @B assume fs : nothing mov eax, fs :[30h] mov eax, [eax + 0Ch] mov eax, [eax + 0Ch] mov ebx, eax @@: mov ecx, [eax + 30h] push eax invoke lstrcmpiW, ecx, lpName test eax, eax pop eax jz _found mov eax, [eax] test eax, ebx jnz @B jmp _return _found: call _del_peb_entry add eax, 8 call _del_peb_entry _return: invoke LocalFree, lpName invoke LocalFree, lpBuffer ret _del_peb_entry: push eax mov eax, [eax + 4] mov ebx, [eax] mov ebx, [ebx] mov dword ptr [eax], ebx mov ebx, [eax + 4] mov ebx, [ebx + 4] mov dword ptr [eax + 4], ebx pop eax retn HideDllFromPEB endp после того как DLL отработала мне необходимо удалить ее, но выгрузить само собой не получается. Подскажите пожалуйста каким образом реализовать данную задачу. Понимаю что нужно вернуть запись в PEB. Буду рад любым примерам. Благодарю за внимание
На случай, если потребуется когда-нибудь работа со списками загрузчика. Code (Text): #include <ntdll.h> #include <stdio.h> ////////////////////////////////////////////////////////////////////////// // Some loader stuff #define LDRP_HASH_TABLE_SIZE 32 #define LDRP_HASH_MASK (LDRP_HASH_TABLE_SIZE-1) #define LDRP_COMPUTE_HASH_INDEX(wch) ( (RtlUpcaseUnicodeChar((wch)) - (WCHAR)'A') & LDRP_HASH_MASK ) // Loader hash table. // This table contains 32 list heads to double-linked lists for each hash index (0..31). // Indexes are computed from uppercased first character of base dll name (see LDRP_COMPUTE_HASH_INDEX) // Real prototype in ntdll: LIST_ENTRY LdrpHashTable[LDRP_HASH_TABLE_SIZE]; PLIST_ENTRY LdrpHashTable; // Global loader heap HANDLE LdrHeap; // Find loader heap BOOL FindLoaderHeap () { PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr; MEMORY_BASIC_INFORMATION mbi; PLDR_DATA_TABLE_ENTRY NtdllEntry; // Get any pointer within this heap. NtdllEntry = CONTAINING_RECORD (Ldr->InInitializationOrderModuleList.Flink, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks); // Query VM information (base address) if (VirtualQuery (NtdllEntry, &mbi, sizeof(mbi))) { LdrHeap = (HANDLE) mbi.AllocationBase; return TRUE; } return FALSE; } // Find LdrpHashTable[] table with list heads BOOL FindLdrpHashTable () { PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr; // get ntdll entry PLDR_DATA_TABLE_ENTRY Ntdll = CONTAINING_RECORD (Ldr->InInitializationOrderModuleList.Flink, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks); UCHAR NtdllHashIndex = LDRP_COMPUTE_HASH_INDEX (Ntdll->BaseDllName.Buffer[0]); // get ntdll.dll module bounds ULONG_PTR NtdllBase = (ULONG_PTR) Ntdll->DllBase; ULONG_PTR NtdllEndAddress = NtdllBase + Ntdll->SizeOfImage - 1; // scan hash list to the head (head is located within ntdll) BOOL bHeadFound = FALSE; PLIST_ENTRY pNtdllHashHead = NULL; for (PLIST_ENTRY e = Ntdll->HashLinks.Flink; e != &Ntdll->HashLinks; e = e->Flink) { if ((ULONG_PTR)e >= NtdllBase && (ULONG_PTR)e < NtdllEndAddress) { bHeadFound = TRUE; pNtdllHashHead = e; break; } } if (bHeadFound) { LdrpHashTable = pNtdllHashHead - NtdllHashIndex; } return bHeadFound; } // Allocate LDR_DATA_TABLE_ENTRY from loader heap __inline PLDR_DATA_TABLE_ENTRY LdrpAllocateEntry () { return (PLDR_DATA_TABLE_ENTRY) HeapAlloc (LdrHeap, HEAP_ZERO_MEMORY, sizeof(LDR_DATA_TABLE_ENTRY)); } // Perform generic search in loader lists for the specified dll. PVOID LdrpSlowFindDllHandle (PWSTR BaseDllName) { UNICODE_STRING usBaseDllName; PLIST_ENTRY pLoadOrderHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; RtlInitUnicodeString (&usBaseDllName, BaseDllName); for (PLIST_ENTRY e = pLoadOrderHead->Flink; e != pLoadOrderHead; e = e->Flink) { PLDR_DATA_TABLE_ENTRY LoaderEntry = CONTAINING_RECORD (e, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); if (!RtlCompareUnicodeString (&LoaderEntry->BaseDllName, &usBaseDllName, TRUE)) { return LoaderEntry->DllBase; } } return NULL; } // Perform fast search for the specified dll by hash PVOID LdrpFastFindDllHandle (PWSTR BaseDllName) { UNICODE_STRING usBaseDllName; PLIST_ENTRY pHashTableHead = &LdrpHashTable[LDRP_COMPUTE_HASH_INDEX(BaseDllName[0])]; RtlInitUnicodeString (&usBaseDllName, BaseDllName); for (PLIST_ENTRY e = pHashTableHead->Flink; e != pHashTableHead; e = e->Flink) { PLDR_DATA_TABLE_ENTRY LoaderEntry = CONTAINING_RECORD (e, LDR_DATA_TABLE_ENTRY, HashLinks); if (!RtlCompareUnicodeString (&LoaderEntry->BaseDllName, &usBaseDllName, TRUE)) { return LoaderEntry->DllBase; } } //return LdrpSlowFindDllHandle (BaseDllName); return NULL; } PLDR_DATA_TABLE_ENTRY LdrpFastGetCachedEntry (PWSTR BaseDllName) { UNICODE_STRING usBaseDllName; PLIST_ENTRY pHashTableHead = &LdrpHashTable[LDRP_COMPUTE_HASH_INDEX(BaseDllName[0])]; RtlInitUnicodeString (&usBaseDllName, BaseDllName); for (PLIST_ENTRY e = pHashTableHead->Flink; e != pHashTableHead; e = e->Flink) { PLDR_DATA_TABLE_ENTRY LoaderEntry = CONTAINING_RECORD (e, LDR_DATA_TABLE_ENTRY, HashLinks); if (!RtlCompareUnicodeString (&LoaderEntry->BaseDllName, &usBaseDllName, TRUE)) { return LoaderEntry; } } return NULL; } BOOL LdrAddModuleToLdrLists (PVOID hModule, PWSTR FullDllName) { PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr; PLDR_DATA_TABLE_ENTRY e; PIMAGE_NT_HEADERS NtHeaders; if (!(e = LdrpAllocateEntry ())) return FALSE; // insufficient resources? NtHeaders = (PIMAGE_NT_HEADERS) RtlImageNtHeader (hModule); e->DllBase = hModule; e->EntryPoint = (PUCHAR)hModule + NtHeaders->OptionalHeader.AddressOfEntryPoint; e->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage; SIZE_T cchCount = wcslen(FullDllName); PWSTR wszDllNameCopy = (PWSTR) HeapAlloc (LdrHeap, HEAP_ZERO_MEMORY, cchCount*2+2); if (wszDllNameCopy == NULL) { HeapFree (LdrHeap, 0, e); return FALSE; } wcscpy (wszDllNameCopy, FullDllName); RtlInitUnicodeString (&e->FullDllName, wszDllNameCopy); PWCHAR pSlash = (PWCHAR) wcsrchr (wszDllNameCopy, L'\\'); if (pSlash) { RtlInitUnicodeString (&e->BaseDllName, pSlash+1); e->BaseDllName.MaximumLength = (USHORT)((cchCount - (pSlash - wszDllNameCopy))*2); } e->Flags = LDRP_IMAGE_DLL | // this entry describes a DLL LDRP_ENTRY_PROCESSED | // entry point has been already called LDRP_PROCESS_ATTACH_CALLED | // DLL_PROCESS_ATTACH called, don't call again LDRP_DONT_CALL_FOR_THREADS; // don't call DLL_THREAD_ATTACH/DLL_THREAD_DETACH e->LoadCount = 1; e->TlsIndex = 0; e->TimeDateStamp = NtHeaders->FileHeader.TimeDateStamp; e->EntryPointActivationContext = NULL; // no activation context (wtf is actx?!) e->PatchInformation; // no patch information, for kernel images only. // // LDR_DATA_TABLE_ENTRY allocated & initialized. // Insert in the appropriate lists. // UCHAR HashIndex = LDRP_COMPUTE_HASH_INDEX (e->BaseDllName.Buffer[0]); InsertTailList (&LdrpHashTable[HashIndex], &e->HashLinks); InsertTailList (&Ldr->InInitializationOrderModuleList, &e->InInitializationOrderLinks); InsertTailList (&Ldr->InLoadOrderModuleList, &e->InLoadOrderLinks); //bugbug InsertTailList (&Ldr->InMemoryOrderModuleList, &e->InMemoryOrderLinks); return TRUE; } VOID LdrRemoveModuleFromLdrLists (PVOID BaseAddress) { PLDR_DATA_TABLE_ENTRY Entry = NULL; PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr; BOOL bEntryFound = FALSE; for (PLIST_ENTRY e = Ldr->InLoadOrderModuleList.Flink; e != &Ldr->InLoadOrderModuleList; e = e->Flink) { Entry = CONTAINING_RECORD (e, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); if (Entry->DllBase == BaseAddress) { bEntryFound = TRUE; break; } } if (!bEntryFound) return; RemoveEntryList (&Entry->InLoadOrderLinks); RemoveEntryList (&Entry->InInitializationOrderLinks); RemoveEntryList (&Entry->InMemoryOrderLinks); RemoveEntryList (&Entry->HashLinks); HeapFree (LdrHeap, 0, Entry->FullDllName.Buffer); HeapFree (LdrHeap, 0, Entry); } void xxLdrDumpFlags (ULONG f) { #define DUMP_FLAG(VALUE) if(f & VALUE) printf(#VALUE " "); DUMP_FLAG (LDRP_STATIC_LINK); DUMP_FLAG (LDRP_IMAGE_DLL); DUMP_FLAG (LDRP_LOAD_IN_PROGRESS); DUMP_FLAG (LDRP_UNLOAD_IN_PROGRESS); DUMP_FLAG (LDRP_ENTRY_PROCESSED); DUMP_FLAG (LDRP_ENTRY_INSERTED); DUMP_FLAG (LDRP_CURRENT_LOAD); DUMP_FLAG (LDRP_FAILED_BUILTIN_LOAD); DUMP_FLAG (LDRP_DONT_CALL_FOR_THREADS); DUMP_FLAG (LDRP_PROCESS_ATTACH_CALLED); DUMP_FLAG (LDRP_DEBUG_SYMBOLS_LOADED); DUMP_FLAG (LDRP_IMAGE_NOT_AT_BASE); DUMP_FLAG (LDRP_COR_IMAGE); DUMP_FLAG (LDRP_COR_OWNS_UNMAP); DUMP_FLAG (LDRP_SYSTEM_MAPPED); DUMP_FLAG (LDRP_IMAGE_VERIFYING); DUMP_FLAG (LDRP_DRIVER_DEPENDENT_DLL); DUMP_FLAG (LDRP_ENTRY_NATIVE); DUMP_FLAG (LDRP_REDIRECTED); DUMP_FLAG (LDRP_NON_PAGED_DEBUG_INFO); DUMP_FLAG (LDRP_MM_LOADED); DUMP_FLAG (LDRP_COMPAT_DATABASE_PROCESSED); printf("\n"); } void LdrpDumpEntry (PLDR_DATA_TABLE_ENTRY e) { printf("LDR_DATA_TABLE_ENTRY at %p\n", e); printf(" load links: [%p %p]\n", e->InLoadOrderLinks.Blink, e->InLoadOrderLinks.Flink); printf(" memory links: [%p %p]\n", e->InMemoryOrderLinks.Blink, e->InMemoryOrderLinks.Flink); printf(" init links: [%p %p]\n", e->InInitializationOrderLinks.Blink, e->InInitializationOrderLinks.Flink); printf(" DllBase: %p\n", e->DllBase); printf(" EntryPoint: %p\n", e->EntryPoint); printf(" SizeOfImage: %p\n", e->SizeOfImage); printf(" FullDllName: '%wZ'\n", &e->FullDllName); printf(" BaseDllName: '%wZ'\n", &e->BaseDllName); printf(" Flags: %08x\n", e->Flags); xxLdrDumpFlags (e->Flags); printf(" LoadCount: %04x\n", e->LoadCount); printf(" TlsIndex: %04x\n", e->TlsIndex); printf(" HashLinks: [%p %p]\n", e->HashLinks.Blink, e->HashLinks.Flink); printf(" SectionPointer: %p\n", e->SectionPointer); printf(" CheckSum: %p\n", e->CheckSum); printf(" TimeDateStamp: %p\n", e->TimeDateStamp); printf(" LoadedImports: %p\n", e->LoadedImports); printf(" EntryPointActivationContext: %p\n", e->EntryPointActivationContext); printf(" PatchInformation: %p\n", e->PatchInformation); printf("\n"); } void* memdup (void* source, size_t length) { void* dst = VirtualAlloc (0, length, MEM_COMMIT, PAGE_READWRITE); if (dst) { memcpy (dst, source, length); } return dst; } void swap_dwords (DWORD* a, DWORD *b) { DWORD t = *a; *a = *b; *b = t; } int main() { if (!FindLoaderHeap ()) return printf ("Could not find loader heap\n"); printf("Loader heap handle: %p\n", LdrHeap); if (!FindLdrpHashTable ()) return printf ("Could not find LdrpHashTable[] array address\n"); printf("LdrpHashTable[] is %p\n", LdrpHashTable); // // Try to add my own fake entry to loader lists. // WCHAR path[MAX_PATH]; HMODULE hDll = LoadLibrary ("smalldll.dll"); PIMAGE_NT_HEADERS NtHeaders = (PIMAGE_NT_HEADERS) RtlImageNtHeader (hDll); SIZE_T ImageSize = NtHeaders->OptionalHeader.SizeOfImage; printf ("library loaded at %p, image size %lx\n", hDll, ImageSize); PVOID pDuplicate = memdup (hDll, ImageSize); FreeLibrary (hDll); printf ("duplicated rgn at %p\n", pDuplicate); GetCurrentDirectoryW (sizeof(path)/2, path); wcscat (path, L"\\smalldll.dll"); PVOID BaseAddress = (PVOID) hDll; SIZE_T RegionSize = ImageSize; NTSTATUS Status; #if 0 Status = ZwAllocateVirtualMemory ( NtCurrentProcess(), &BaseAddress, 0, &RegionSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); printf ("ZwAllocateVirtualMemory: %lx (allocated at %p)\n", Status, BaseAddress); #else HANDLE hTempSection = CreateFileMapping (INVALID_HANDLE_VALUE, 0, PAGE_EXECUTE_READWRITE, 0, ImageSize, 0); printf("hTempSection %lx\n", hTempSection); Status = ZwMapViewOfSection ( hTempSection, NtCurrentProcess(), &BaseAddress, 0, 0, 0, &RegionSize, ViewUnmap, MEM_DOS_LIM, PAGE_EXECUTE_READWRITE ); printf ("ZwMapViewOfSection: %lx (mapped at %p)\n", Status, BaseAddress); #endif if (NT_SUCCESS(Status)) { memcpy (BaseAddress, pDuplicate, ImageSize); VirtualFree (pDuplicate, 0, MEM_RELEASE); printf ("copied duplicated rgn %p to re-allocated memory %p\n", pDuplicate, BaseAddress); if (LdrAddModuleToLdrLists (BaseAddress, path)) { printf ("added %S (%p) to module lists\n", path, pDuplicate); PLDR_DATA_TABLE_ENTRY NtdllEntry = LdrpFastGetCachedEntry (L"ntdll.dll"); RemoveEntryList (&NtdllEntry->InLoadOrderLinks); RemoveEntryList (&NtdllEntry->InMemoryOrderLinks); RemoveEntryList (&NtdllEntry->InInitializationOrderLinks); RemoveEntryList (&NtdllEntry->HashLinks); // PLDR_DATA_TABLE_ENTRY Kernel32Entry = LdrpFastGetCachedEntry (L"kernel32.dll"); // swap_dwords ((DWORD*)&NtdllEntry->DllBase, (DWORD*)&Kernel32Entry->DllBase); // swap_dwords ((DWORD*)&NtdllEntry->SizeOfImage, (DWORD*)&Kernel32Entry->SizeOfImage); // swap_dwords ((DWORD*)&NtdllEntry->EntryPoint, (DWORD*)&Kernel32Entry->EntryPoint); // PLIST_ENTRY Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; // for (PLIST_ENTRY e = Head->Flink; e != Head; e = e->Flink) // { // PLDR_DATA_TABLE_ENTRY Ldr = (PLDR_DATA_TABLE_ENTRY) e; // Ldr->DllBase = (PVOID) 0x7c800000; // Ldr->SizeOfImage = 0x10000; // } __asm int 3; } } // GetSystemDirectoryW (path, sizeof(path)-1); // wcscat (path, L"\\csrsrv.dll"); // // HANDLE hFile = CreateFileW (path, GENERIC_READ | GENERIC_EXECUTE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); // printf("CreateFile for '%S' returned handle %lx\n", path, hFile); // // if (hFile != INVALID_HANDLE_VALUE) // { // NTSTATUS Status; // HANDLE hSection; // OBJECT_ATTRIBUTES Oa; // // InitializeObjectAttributes (&Oa, 0, 0, 0, 0); // Status = ZwCreateSection ( // &hSection, // SECTION_MAP_READ | SECTION_MAP_EXECUTE, // &Oa, // NULL, // PAGE_EXECUTE, // SEC_IMAGE, // hFile // ); // // printf("ZwCreateSection returned status %lx, handle %lx\n", Status, hSection); // // if (NT_SUCCESS (Status)) // { // PVOID BaseAddress = 0; // SIZE_T ViewSize = 0; // // Status = ZwMapViewOfSection ( // hSection, // NtCurrentProcess(), // &BaseAddress, // 0, // 0, // NULL, // &ViewSize, // ViewUnmap, // MEM_TOP_DOWN, // PAGE_EXECUTE); // // printf("ZwMapViewOfSection returned status %lx, base address %p, view size 0x%lx\n", Status, BaseAddress, ViewSize); // // if (NT_SUCCESS(Status)) // { // HMODULE hm; // // hm = GetModuleHandle ("csrsrv.dll"); // printf("GetModuleHandle(csrsrv.dll) before inserting LDR_DATA_TABLE_ENTRY returned %p\n", hm); // // if (LdrAddModuleToLdrLists (BaseAddress, path)) // { // printf("Module has been added to module lists\n"); // // hm = GetModuleHandle ("csrsrv.dll"); // printf("GetModuleHandle(csrsrv.dll) after inserting LDR_DATA_TABLE_ENTRY returned %p\n", hm); // // LdrRemoveModuleFromLdrLists (BaseAddress); // } // // UnmapViewOfFile (BaseAddress); // } // // CloseHandle (hSection); // } // // CloseHandle (hFile); // } ////////////////////////////////////////////////////////////////////////// // // // // Perform fast search in loader hash lists. // // // // PVOID hKernel32 = LdrpFastFindDllHandle (L"kernel32.dll"); // printf("LdrpFastFindDllHandle(L\"kernel32.dll\") returned %p\n", hKernel32); ////////////////////////////////////////////////////////////////////////// // // // // Try to find ntdll.dll in hash entries for 'N' (to check if LdrpHashTable[] address is valid) // // // // PLIST_ENTRY pHashTableForN = &LdrpHashTable[LDRP_COMPUTE_HASH_INDEX('n')]; // printf("hash list head for 'N'(ntdll) is: %p\n", pHashTableForN); // // printf("\nDumping dlls for 'N':\n"); // // for (PLIST_ENTRY e = pHashTableForN->Flink; e != pHashTableForN; e = e->Flink) // { // PLDR_DATA_TABLE_ENTRY Entry = CONTAINING_RECORD (e, LDR_DATA_TABLE_ENTRY, HashLinks); // LdrpDumpEntry (Entry); // } ////////////////////////////////////////////////////////////////////////// // // // // Dump entries // // // // LoadLibrary("csrsrv.dll"); // // PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr; // // for (PLIST_ENTRY e = Ldr->InLoadOrderModuleList.Flink; e != &Ldr->InLoadOrderModuleList; e = e->Flink) // { // PLDR_DATA_TABLE_ENTRY loaderEntry = (PLDR_DATA_TABLE_ENTRY) e; // LdrpDumpEntry (loaderEntry); // } ////////////////////////////////////////////////////////////////////////// return 0; } Пример хорошо откомментирован и в пояснении не нуждается. Заголовочный ntdll.h (сам составлял) со структурами everfall.com Вероятно, тебя заинтересуют LdrAddModuleToLdrLists и LdrRemoveModuleFromLdrLists. Обращаю внимание на то, что существуют кроме трех основных списков (in memory order, in init order, in load order) еще 32 списка по хешам первой буквы имени (upcase(name[0]) % 32), про которые никто не помнит, как обычно. А GetModuleHandle/LoadLibrary смотрят их в первую очередь, потому что так быстрее искать, чем полным перебором (см. LdrpSlowFindDllHandle, LdrpFastFindDllHandle, LdrpFastGetCachedEntry)
Для безопасного добавления/удаления существует ещё критическая секция. Вход в критическую секцию: NTSYSAPI NTSTATUS NTAPI LdrLockLoaderLock( IN DWORD dwFlags, OUT PULONG LockTry OPTIONAL, OUT PULONG ThreadLocks); Для dwFlags #define LOCK_GENERATE_EXEPTIONS 1 //исключение если один из параметвов не правильный #define LOCK_MUST_BE_TRY 2 //не входить если секция занята, LockTry тогда обязательный остальные биты должны быть сброшены. LockTry 0 - занято 1 - была свободной 2 - не была свободной, но вход выполнен ThreadLocks - переменная значение которой нужно сохранить для выхода из секции. NTSYSAPI NTSTATUS NTAPI LdrUnlockLoaderLock( IN DWORD dwFlags, IN ULONG ThreadLocks);
Тоже с этим сталкивался. Нужно сделать ZwUnmapViewOfSection c адресом загрузки DLL (который получен в DllMain). После загрузки DLL надо сделать DisableThreadLibraryCalls, чтобы после выгрузки не вызвалась уже не существующая DllMain.
В Win2000 этой функции нет, но в PEB есть критическая секция, которую должна использовать эта функция. Поэтому надо еще версию системы учитывать.
не спасет от DLL_PROCESS_DETACH да, и оффсет вроде фиксирован. там же есть и указатели, чтото типа FastLoaderLockRoutine, FastLoaderUnlockRoutine.
sideX Изучать свойства критических секций. Локальные вызовы допустимы без деадлоков http://ru.wikipedia.org/wiki/Критическая_секция
Очень помогли сорсы Great'a, но начиная с win7 там другая хеш функция. На радостях выкладываю сорсы Code (Text): LdrpGetHashIndex proc uses ebx esi edi pString:PUNICODE_STRING xor eax,eax cmp pString,0 je _exit mov eax,dword ptr ds:[7FFE026Ch] mov ecx,dword ptr ds:[7FFE0270h] shl eax,8 mov al,cl .if eax>=OS_WIN7 xor ebx,ebx mov esi,pString assume esi:PUNICODE_STRING mov esi,[esi].Buffer mov edi,esi mov eax,pString assume eax:PUNICODE_STRING movsx eax,[eax]._Length add esi,eax sub esi,2 @@: cmp edi,esi jg @F movsx eax,word ptr [esi] invoke RtlUpcaseUnicodeChar,eax imul eax,1003Fh add ebx,eax dec esi dec esi jmp @B @@: xchg eax,ebx .else mov eax,pString assume eax:PUNICODE_STRING mov eax,[eax].Buffer movsx eax,word ptr [eax] or eax,20h sub eax,'A' .endif and eax,31 _exit: ret LdrpGetHashIndex endp
Что-то у меня не работает добавление модуля в Windows 7 x64 (не срабатывает GetModuleHandle на загруженной из памяти dll)... В winXP все нормально. Можете помочь? (Конкретно проблема в том, что в загруженной dll не обрабатываются исключения)
Похоже, что обработка исключений не связана с присутствием dll в списке модулей. Я загрузил dll обычным способом (LoadLibrary) и удалил ее из PEB => исключения ловились правильно...