通过修改PEB进程环境块的方式实现隐藏DLL,此类隐藏属于断链隐藏。
PEB 中有一个成员 Ldr:
typedef struct _PEB { UCHAR InheritedAddressSpace; UCHAR ReadImageFileExecOptions; UCHAR BeingDebugged; UCHAR BitField; ULONG ImageUsesLargePages: 1; ULONG IsProtectedProcess: 1; ULONG IsLegacyProcess: 1; ULONG IsImageDynamicallyRelocated: 1; ULONG SpareBits: 4; PVOID Mutant; PVOID ImageBaseAddress; PPEB_LDR_DATA Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; PVOID SubSystemData; PVOID ProcessHeap; PRTL_CRITICAL_SECTION FastPebLock; PVOID AtlThunkSListPtr; PVOID IFEOKey; ULONG CrossProcessFlags; ULONG ProcessInJob: 1; ULONG ProcessInitializing: 1; ULONG ReservedBits0: 30; union { PVOID KernelCallbackTable; PVOID UserSharedInfoPtr; }; ULONG SystemReserved[1]; ULONG SpareUlong; PPEB_FREE_BLOCK FreeList; ULONG TlsExpansionCounter; PVOID TlsBitmap; ULONG TlsBitmapBits[2]; PVOID ReadOnlySharedMemoryBase; PVOID HotpatchInformation; VOID * * ReadOnlyStaticServerData; PVOID AnsiCodePageData; PVOID OemCodePageData; PVOID UnicodeCaseTableData; ULONG NumberOfProcessors; ULONG NtGlobalFlag; LARGE_INTEGER CriticalSectionTimeout; ULONG HeapSegmentReserve; ULONG HeapSegmentCommit; ULONG HeapDeCommitTotalFreeThreshold; ULONG HeapDeCommitFreeBlockThreshold; ULONG NumberOfHeaps; ULONG MaximumNumberOfHeaps; VOID * * ProcessHeaps; PVOID GdiSharedHandleTable; PVOID ProcessStarterHelper; ULONG GdiDCAttributeList; PRTL_CRITICAL_SECTION LoaderLock; ULONG OSMajorVersion; ULONG OSMinorVersion; WORD OSBuildNumber; WORD OSCSDVersion; ULONG OSPlatformId; ULONG ImageSubsystem; ULONG ImageSubsystemMajorVersion; ULONG ImageSubsystemMinorVersion; ULONG ImageProcessAffinityMask; ULONG GdiHandleBuffer[34]; PVOID PostProcessInitRoutine; PVOID TlsExpansionBitmap; ULONG TlsExpansionBitmapBits[32]; ULONG SessionId; ULARGE_INTEGER AppCompatFlags; ULARGE_INTEGER AppCompatFlagsUser; PVOID pShimData; PVOID AppCompatInfo; UNICODE_STRING CSDVersion; _ACTIVATION_CONTEXT_DATA * ActivationContextData; _ASSEMBLY_STORAGE_MAP * ProcessAssemblyStorageMap; _ACTIVATION_CONTEXT_DATA * SystemDefaultActivationContextData; _ASSEMBLY_STORAGE_MAP * SystemAssemblyStorageMap; ULONG MinimumStackCommit; _FLS_CALLBACK_INFO * FlsCallback; LIST_ENTRY FlsListHead; PVOID FlsBitmap; ULONG FlsBitmapBits[4]; ULONG FlsHighIndex; PVOID WerRegistrationData; PVOID WerShipAssertPtr; } PEB, *PPEB;
|
这个 Ldr 的数据类型是 _PEB_LDR_DATA:
typedef struct _PEB_LDR_DATA { ULONG Length; BOOLEAN Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; } PEB_LDR_DATA,*PPEB_LDR_DATA;
|
InLoadOrderModuleList 成员保存了模块信息,而模块信息的结构为 _LDR_DATA_TABLE_ENTRY。
typedef struct _LDR_DATA_TABLE_ENTRY { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderLinks; LIST_ENTRY InInitializationOrderLinks; PVOID DllBase; PVOID EntryPoint; ULONG32 SizeOfImage; UINT8 Unknow0[0x4]; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; }LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
|
所以 ,我们获取到了这个结构.因为是链表.可以遍历链表. 根据DllBase判断 你的模块基址跟这个模块基址是否一样.如果一样那么我们就断开链表,从而实现 dll 的隐藏。
代码参考来自:https://cloud.tencent.com/developer/article/1432475
#include <stdio.h> #include <Windows.h> #include <stdlib.h>
DWORD g_isHide = 0; typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING;
typedef struct _PEB_LDR_DATA { ULONG Length; BOOLEAN Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; } PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _LDR_MODULE { LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; void* BaseAddress; void* EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; SHORT LoadCount; SHORT TlsIndex; HANDLE SectionHandle; ULONG CheckSum; ULONG TimeDateStamp; } LDR_MODULE, *PLDR_MODULE; void HideDll() { HMODULE hMod = ::GetModuleHandle("ntdll.dll"); PLIST_ENTRY Head, Cur; PPEB_LDR_DATA ldr; PLDR_MODULE ldm; __asm { mov eax, fs:[0x30] mov ecx, [eax + 0x0c] mov ldr, ecx } Head = &(ldr->InLoadOrderModuleList); Cur = Head->Flink; do { ldm = CONTAINING_RECORD(Cur, LDR_MODULE, InLoadOrderModuleList); if (hMod == ldm->BaseAddress) { g_isHide = 1; ldm->InLoadOrderModuleList.Blink->Flink = ldm->InLoadOrderModuleList.Flink; ldm->InLoadOrderModuleList.Flink->Blink = ldm->InLoadOrderModuleList.Blink; ldm->InInitializationOrderModuleList.Blink->Flink = ldm->InInitializationOrderModuleList.Flink; ldm->InInitializationOrderModuleList.Flink->Blink = ldm->InInitializationOrderModuleList.Blink; ldm->InMemoryOrderModuleList.Blink->Flink = ldm->InMemoryOrderModuleList.Flink; ldm->InMemoryOrderModuleList.Flink->Blink = ldm->InMemoryOrderModuleList.Blink; break; } Cur = Cur->Flink; } while (Head != Cur); }
int main() {
printf("按键开始隐藏\r\n"); getchar(); HideDll();
if (g_isHide == 0) { printf("没有成功隐藏\r\n"); system("pause"); return 0; }
printf("成功隐藏\r\n"); system("pause"); return 0; }
|