原理
利用PE结构,将模块从链表中摘除,注意该方法只适用于R3,R0还是有办法看到的。
代码
注意:代码为64位,32位道理一样,需要稍微改改?之前的代码了忘了支不支持32位了~
HideDll.h
#pragma once
#include <Windows.h>
#define NT_SUCCESS(x) ((x) >= 0)
#define ProcessBasicInformation (PROCESS_INFORMATION_CLASS)0
typedef NTSTATUS(NTAPI* PFN_NtQueryInformationProcess)(
IN HANDLE ProcessHandle,
IN PROCESS_INFORMATION_CLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength);
typedef NTSTATUS(NTAPI* PFN_NtReadVirtualMemory)(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesReaded OPTIONAL);
//0x10 bytes (sizeof)
struct _UNICODE_STRING {
USHORT Length; //0x0
USHORT MaximumLength; //0x2
WCHAR* Buffer; //0x8
};
//0x58 bytes (sizeof)
struct _PEB_LDR_DATA {
ULONG Length; //0x0
UCHAR Initialized; //0x4
VOID* SsHandle; //0x8
struct _LIST_ENTRY InLoadOrderModuleList; //0x10
struct _LIST_ENTRY InMemoryOrderModuleList; //0x20
struct _LIST_ENTRY InInitializationOrderModuleList; //0x30
VOID* EntryInProgress; //0x40
UCHAR ShutdownInProgress; //0x48
VOID* ShutdownThreadId; //0x50
};
//0x7c8 bytes (sizeof)
struct _PEB {
UCHAR InheritedAddressSpace; //0x0
UCHAR ReadImageFileExecOptions; //0x1
UCHAR BeingDebugged; //0x2
union {
UCHAR BitField; //0x3
struct {
UCHAR ImageUsesLargePages : 1; //0x3
UCHAR IsProtectedProcess : 1; //0x3
UCHAR IsImageDynamicallyRelocated : 1; //0x3
UCHAR SkipPatchingUser32Forwarders : 1; //0x3
UCHAR IsPackagedProcess : 1; //0x3
UCHAR IsAppContainer : 1; //0x3
UCHAR IsProtectedProcessLight : 1; //0x3
UCHAR IsLongPathAwareProcess : 1; //0x3
};
};
UCHAR Padding0[4]; //0x4
VOID* Mutant; //0x8
VOID* ImageBaseAddress; //0x10
struct _PEB_LDR_DATA* Ldr; //0x18
struct _RTL_USER_PROCESS_PARAMETERS* ProcessParameters; //0x20
VOID* SubSystemData; //0x28
VOID* ProcessHeap; //0x30
struct _RTL_CRITICAL_SECTION* FastPebLock; //0x38
union _SLIST_HEADER* volatile AtlThunkSListPtr; //0x40
VOID* IFEOKey; //0x48
union {
ULONG CrossProcessFlags; //0x50
struct {
ULONG ProcessInJob : 1; //0x50
ULONG ProcessInitializing : 1; //0x50
ULONG ProcessUsingVEH : 1; //0x50
ULONG ProcessUsingVCH : 1; //0x50
ULONG ProcessUsingFTH : 1; //0x50
ULONG ProcessPreviouslyThrottled : 1; //0x50
ULONG ProcessCurrentlyThrottled : 1; //0x50
ULONG ProcessImagesHotPatched : 1; //0x50
ULONG ReservedBits0 : 24; //0x50
};
};
UCHAR Padding1[4]; //0x54
union {
VOID* KernelCallbackTable; //0x58
VOID* UserSharedInfoPtr; //0x58
};
ULONG SystemReserved; //0x60
ULONG AtlThunkSListPtr32; //0x64
VOID* ApiSetMap; //0x68
ULONG TlsExpansionCounter; //0x70
UCHAR Padding2[4]; //0x74
VOID* TlsBitmap; //0x78
ULONG TlsBitmapBits[2]; //0x80
VOID* ReadOnlySharedMemoryBase; //0x88
VOID* SharedData; //0x90
VOID** ReadOnlyStaticServerData; //0x98
VOID* AnsiCodePageData; //0xa0
VOID* OemCodePageData; //0xa8
VOID* UnicodeCaseTableData; //0xb0
ULONG NumberOfProcessors; //0xb8
ULONG NtGlobalFlag; //0xbc
union _LARGE_INTEGER CriticalSectionTimeout; //0xc0
ULONGLONG HeapSegmentReserve; //0xc8
ULONGLONG HeapSegmentCommit; //0xd0
ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8
ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0
ULONG NumberOfHeaps; //0xe8
ULONG MaximumNumberOfHeaps; //0xec
VOID** ProcessHeaps; //0xf0
VOID* GdiSharedHandleTable; //0xf8
VOID* ProcessStarterHelper; //0x100
ULONG GdiDCAttributeList; //0x108
UCHAR Padding3[4]; //0x10c
struct _RTL_CRITICAL_SECTION* LoaderLock; //0x110
ULONG OSMajorVersion; //0x118
ULONG OSMinorVersion; //0x11c
USHORT OSBuildNumber; //0x120
USHORT OSCSDVersion; //0x122
ULONG OSPlatformId; //0x124
ULONG ImageSubsystem; //0x128
ULONG ImageSubsystemMajorVersion; //0x12c
ULONG ImageSubsystemMinorVersion; //0x130
UCHAR Padding4[4]; //0x134
ULONGLONG ActiveProcessAffinityMask; //0x138
ULONG GdiHandleBuffer[60]; //0x140
VOID(*PostProcessInitRoutine)(); //0x230
VOID* TlsExpansionBitmap; //0x238
ULONG TlsExpansionBitmapBits[32]; //0x240
ULONG SessionId; //0x2c0
UCHAR Padding5[4]; //0x2c4
union _ULARGE_INTEGER AppCompatFlags; //0x2c8
union _ULARGE_INTEGER AppCompatFlagsUser; //0x2d0
VOID* pShimData; //0x2d8
VOID* AppCompatInfo; //0x2e0
struct _UNICODE_STRING CSDVersion; //0x2e8
struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8
struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300
struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308
struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310
ULONGLONG MinimumStackCommit; //0x318
VOID* SparePointers[4]; //0x320
ULONG SpareUlongs[5]; //0x340
VOID* WerRegistrationData; //0x358
VOID* WerShipAssertPtr; //0x360
VOID* pUnused; //0x368
VOID* pImageHeaderHash; //0x370
union {
ULONG TracingFlags; //0x378
struct {
ULONG HeapTracingEnabled : 1; //0x378
ULONG CritSecTracingEnabled : 1; //0x378
ULONG LibLoaderTracingEnabled : 1; //0x378
ULONG SpareTracingBits : 29; //0x378
};
};
UCHAR Padding6[4]; //0x37c
ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380
ULONGLONG TppWorkerpListLock; //0x388
struct _LIST_ENTRY TppWorkerpList; //0x390
VOID* WaitOnAddressHashTable[128]; //0x3a0
VOID* TelemetryCoverageHeader; //0x7a0
ULONG CloudFileFlags; //0x7a8
ULONG CloudFileDiagFlags; //0x7ac
CHAR PlaceholderCompatibilityMode; //0x7b0
CHAR PlaceholderCompatibilityModeReserved[7]; //0x7b1
struct _LEAP_SECOND_DATA* LeapSecondData; //0x7b8
union {
ULONG LeapSecondFlags; //0x7c0
struct {
ULONG SixtySecondEnabled : 1; //0x7c0
ULONG Reserved : 31; //0x7c0
};
};
ULONG NtGlobalFlag2; //0x7c4
};
//0xc bytes (sizeof)
struct _RTL_BALANCED_NODE {
union {
struct _RTL_BALANCED_NODE* Children[2]; //0x0
struct {
struct _RTL_BALANCED_NODE* Left; //0x0
struct _RTL_BALANCED_NODE* Right; //0x4
};
};
union {
struct {
UCHAR Red : 1; //0x8
UCHAR Balance : 2; //0x8
};
ULONG ParentValue; //0x8
};
};
//0xa8 bytes (sizeof)
struct _LDR_DATA_TABLE_ENTRY {
struct _LIST_ENTRY InLoadOrderLinks; //0x0
struct _LIST_ENTRY InMemoryOrderLinks; //0x8
struct _LIST_ENTRY InInitializationOrderLinks; //0x10
VOID* DllBase; //0x18
VOID* EntryPoint; //0x1c
ULONG SizeOfImage; //0x20
struct _UNICODE_STRING FullDllName; //0x24
struct _UNICODE_STRING BaseDllName; //0x2c
union {
UCHAR FlagGroup[4]; //0x34
ULONG Flags; //0x34
struct {
ULONG PackagedBinary : 1; //0x34
ULONG MarkedForRemoval : 1; //0x34
ULONG ImageDll : 1; //0x34
ULONG LoadNotificationsSent : 1; //0x34
ULONG TelemetryEntryProcessed : 1; //0x34
ULONG ProcessStaticImport : 1; //0x34
ULONG InLegacyLists : 1; //0x34
ULONG InIndexes : 1; //0x34
ULONG ShimDll : 1; //0x34
ULONG InExceptionTable : 1; //0x34
ULONG ReservedFlags1 : 2; //0x34
ULONG LoadInProgress : 1; //0x34
ULONG LoadConfigProcessed : 1; //0x34
ULONG EntryProcessed : 1; //0x34
ULONG ProtectDelayLoad : 1; //0x34
ULONG ReservedFlags3 : 2; //0x34
ULONG DontCallForThreads : 1; //0x34
ULONG ProcessAttachCalled : 1; //0x34
ULONG ProcessAttachFailed : 1; //0x34
ULONG CorDeferredValidate : 1; //0x34
ULONG CorImage : 1; //0x34
ULONG DontRelocate : 1; //0x34
ULONG CorILOnly : 1; //0x34
ULONG ChpeImage : 1; //0x34
ULONG ReservedFlags5 : 2; //0x34
ULONG Redirected : 1; //0x34
ULONG ReservedFlags6 : 2; //0x34
ULONG CompatDatabaseProcessed : 1; //0x34
};
};
USHORT ObsoleteLoadCount; //0x38
USHORT TlsIndex; //0x3a
struct _LIST_ENTRY HashLinks; //0x3c
ULONG TimeDateStamp; //0x44
struct _ACTIVATION_CONTEXT* EntryPointActivationContext; //0x48
VOID* Lock; //0x4c
struct _LDR_DDAG_NODE* DdagNode; //0x50
struct _LIST_ENTRY NodeModuleLink; //0x54
struct _LDRP_LOAD_CONTEXT* LoadContext; //0x5c
VOID* ParentDllBase; //0x60
VOID* SwitchBackContext; //0x64
struct _RTL_BALANCED_NODE BaseAddressIndexNode; //0x68
struct _RTL_BALANCED_NODE MappingInfoIndexNode; //0x74
ULONG OriginalBase; //0x80
union _LARGE_INTEGER LoadTime; //0x88
ULONG BaseNameHashValue; //0x90
enum _LDR_DLL_LOAD_REASON LoadReason; //0x94
ULONG ImplicitPathOptions; //0x98
ULONG ReferenceCount; //0x9c
ULONG DependentLoadFlags; //0xa0
UCHAR SigningLevel; //0xa4
};
typedef struct _PROCESS_BASIC_INFORMATION64 {
NTSTATUS ExitStatus;
UINT32 Reserved0;
UINT64 PebBaseAddress;
UINT64 AffinityMask;
UINT32 BasePriority;
UINT32 Reserved1;
UINT64 UniqueProcessId;
UINT64 InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION64;
// 隐藏64位DLL
BOOL HideModule64(const char* szModule);
HideDll.cpp
#include "HideDll.h"
BOOL HideModule64(const char* szModule) {
BOOL isSuccess = FALSE;
DWORD* PEB = NULL;
DWORD* Ldr = NULL;
DWORD* Flink = NULL;
DWORD* p = NULL;
DWORD* BaseAddress = NULL;
DWORD* FullDllName = NULL;//定位PEB
// 获取NT句柄
HMODULE hNtdllModule = GetModuleHandle("ntdll.dll");
if (hNtdllModule == NULL) {
return isSuccess;
}
// 获取需要隐藏的DLL模块地址
HMODULE hCurrentModule = GetModuleHandle(szModule);
if (hCurrentModule == NULL) {
return isSuccess;
}
// 获取必备函数(64位)
PFN_NtQueryInformationProcess NtQueryInformationProcess = (PFN_NtQueryInformationProcess)GetProcAddress(hNtdllModule, "NtQueryInformationProcess");
if (NtQueryInformationProcess == NULL) {
return isSuccess;
}
PFN_NtReadVirtualMemory NtReadVirtualMemory = (PFN_NtReadVirtualMemory)GetProcAddress(hNtdllModule, "NtReadVirtualMemory");
if (NtReadVirtualMemory == NULL) {
return isSuccess;
}
// 读取PEB
PROCESS_BASIC_INFORMATION64 pbi = { 0 };
ULONG unReturnLength = 0;
NTSTATUS Status = NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, (UINT32)sizeof(pbi), &unReturnLength);
if (NT_SUCCESS(Status)) {
_PEB* peb = (_PEB*)pbi.PebBaseAddress;
if (peb == nullptr) {
return isSuccess;
}
PLIST_ENTRY head = &peb->Ldr->InLoadOrderModuleList;
// 获取指向的结点.
PLIST_ENTRY current = head->Flink;
do {
// 获取 _LDR_DATA_TABLE_ENTRY结构体地址
_LDR_DATA_TABLE_ENTRY* tableEntry = CONTAINING_RECORD(current, _LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
// 判断要隐藏的DLL基址跟结构中的基址是否一样
if (hCurrentModule == tableEntry->DllBase) {
isSuccess = TRUE;
// 双向链表. 断开链表
tableEntry->InLoadOrderLinks.Blink->Flink =
tableEntry->InLoadOrderLinks.Flink;
tableEntry->InLoadOrderLinks.Flink->Blink =
tableEntry->InLoadOrderLinks.Blink;
tableEntry->InInitializationOrderLinks.Blink->Flink =
tableEntry->InInitializationOrderLinks.Flink;
tableEntry->InInitializationOrderLinks.Flink->Blink =
tableEntry->InInitializationOrderLinks.Blink;
tableEntry->InMemoryOrderLinks.Blink->Flink =
tableEntry->InMemoryOrderLinks.Flink;
tableEntry->InMemoryOrderLinks.Flink->Blink =
tableEntry->InMemoryOrderLinks.Blink;
break;
}
current = current->Flink;
} while (head != current);
}
return isSuccess;
}
Comments