原理主要就是PEB 中模塊斷鏈. 這裏整理下代碼.原理能夠看下另外一篇我寫的帖子.
http://www.javashuo.com/article/p-fadqizif-cb.htmlhtml
// dllmain.cpp : 定義 DLL 應用程序的入口點。 #include "stdafx.h" #include <Windows.h> #include <winnt.h> typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING; typedef UNICODE_STRING *PUNICODE_STRING; typedef const UNICODE_STRING *PCUNICODE_STRING; /* DLL 劫持的實現 1.首先咱們加載咱們想要劫持的DLL. 獲取其DLLModule 2.遍歷PEB中的模塊表.找到->DllBae,修改成咱們劫持DLL的hModule便可. */ #define LDRP_STATIC_LINK 0x00000002 #define LDRP_IMAGE_DLL 0x00000004 #define LDRP_LOAD_IN_PROGRESS 0x00001000 #define LDRP_UNLOAD_IN_PROGRESS 0x00002000 #define LDRP_ENTRY_PROCESSED 0x00004000 #define LDRP_ENTRY_INSERTED 0x00008000 #define LDRP_CURRENT_LOAD 0x00010000 #define LDRP_FAILED_BUILTIN_LOAD 0x00020000 #define LDRP_DONT_CALL_FOR_THREADS 0x00040000 #define LDRP_PROCESS_ATTACH_CALLED 0x00080000 #define LDRP_DEBUG_SYMBOLS_LOADED 0x00100000 #define LDRP_IMAGE_NOT_AT_BASE 0x00200000 #define LDRP_COR_IMAGE 0x00400000 #define LDR_COR_OWNS_UNMAP 0x00800000 #define LDRP_SYSTEM_MAPPED 0x01000000 #define LDRP_IMAGE_VERIFYING 0x02000000 #define LDRP_DRIVER_DEPENDENT_DLL 0x04000000 #define LDRP_ENTRY_NATIVE 0x08000000 #define LDRP_REDIRECTED 0x10000000 #define LDRP_NON_PAGED_DEBUG_INFO 0x20000000 #define LDRP_MM_LOADED 0x40000000 #define LDRP_COMPAT_DATABASE_PROCESSED 0x80000000 typedef struct _LDR_DATA_TABLE_ENTRY { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; USHORT LoadCount; USHORT TlsIndex; union { LIST_ENTRY HashLinks; PVOID SectionPointer; }; ULONG CheckSum; union { ULONG TimeDateStamp; PVOID LoadedImports; }; PVOID EntryPointActivationContext; PVOID PatchInformation; } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; typedef struct _PEB_LDR_DATA { ULONG Length; BOOLEAN Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; //按加載順序 LIST_ENTRY InMemoryOrderModuleList; //按內存順序 LIST_ENTRY InInitializationOrderModuleList;//按初始化順序 PVOID EntryInProgress; } PEB_LDR_DATA, *PPEB_LDR_DATA; typedef struct _LDR_MODULE { LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID BaseAddress; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; SHORT LoadCount; SHORT TlsIndex; LIST_ENTRY HashTableEntry; ULONG TimeDateStamp; } LDR_MODULE, *PLDR_MODULE; void PreprocessUnloadDll(HMODULE hLibModule) { PPEB_LDR_DATA pLdr = NULL; PLDR_MODULE FirstModule = NULL; PLDR_MODULE GurrentModule = NULL; __try { __asm { mov esi, fs:[0x30] mov esi, [esi + 0x0C] mov pLdr, esi } FirstModule = (PLDR_MODULE)(pLdr->InLoadOrderModuleList.Flink); GurrentModule = FirstModule; while (!(GurrentModule->BaseAddress == hLibModule)) { GurrentModule = (PLDR_MODULE)(GurrentModule->InLoadOrderModuleList.Blink); if (GurrentModule == FirstModule) { return; } } // // 設置 LDRP_PROCESS_ATTACH_CALLED // GurrentModule->Flags |= LDRP_PROCESS_ATTACH_CALLED; // // 設置 // int oldLoadCount = GurrentModule->LoadCount; GurrentModule->LoadCount = 1; return; } __except (EXCEPTION_EXECUTE_HANDLER) { return; } } VOID HideModule(HMODULE hLibModule) { PPEB_LDR_DATA pLdr = NULL; PLDR_MODULE FirstModule = NULL; PLDR_MODULE GurrentModule = NULL; __try { __asm { mov esi, fs:[0x30] mov esi, [esi + 0x0C] mov pLdr, esi } FirstModule = (PLDR_MODULE)(pLdr->InLoadOrderModuleList.Flink); GurrentModule = FirstModule; while (!(GurrentModule->BaseAddress == hLibModule)) //判斷結束位置 { GurrentModule = (PLDR_MODULE)(GurrentModule->InLoadOrderModuleList.Blink); if (GurrentModule == FirstModule) break; } if (GurrentModule->BaseAddress != hLibModule) return; // // Dll解除連接 // ((PLDR_MODULE)(GurrentModule->InLoadOrderModuleList.Flink))->InLoadOrderModuleList.Blink = GurrentModule->InLoadOrderModuleList.Blink; ((PLDR_MODULE)(GurrentModule->InLoadOrderModuleList.Blink))->InLoadOrderModuleList.Flink = GurrentModule->InLoadOrderModuleList.Flink; memset(GurrentModule->FullDllName.Buffer, 0, GurrentModule->FullDllName.Length); memset(GurrentModule, 0, sizeof(PLDR_MODULE)); PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hLibModule; PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(LPBYTE(hLibModule) + dosHeader->e_lfanew); if ((dosHeader->e_magic == IMAGE_DOS_SIGNATURE) && (ntHeaders->Signature == IMAGE_NT_SIGNATURE)) { memset(dosHeader, 0, sizeof(*dosHeader)); memset(ntHeaders, 0, sizeof(*ntHeaders)); } } __except (EXCEPTION_EXECUTE_HANDLER) { return; } } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: HideModule(hModule); return TRUE; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
檢測:app
MEMORY_BASIC_INFORMATION mbi_thunk; PVOID AllocationBase = NULL; TCHAR FilePath[MAX_PATH]; for (LPSTR Addr = (LPSTR)0x00000000; ::VirtualQueryEx(hProcess, Addr, &mbi_thunk, sizeof(mbi_thunk)); Addr = LPSTR(mbi_thunk.BaseAddress) + mbi_thunk.RegionSize) { if ((mbi_thunk.AllocationBase > AllocationBase) && (GetMappedFileName(hProcess, mbi_thunk.BaseAddress, FilePath, _countof(FilePath)) > 0)) { AllocationBase = mbi_thunk.AllocationBase; KdPrint((_T("MODULE:%x, %s\r\n"), AllocationBase, FilePath)); } }