原理

利用PE结构,将模块从链表中摘除,注意该方法只适用于R3,R0还是有办法看到的。

代码

注意:代码为64位,32位道理一样,需要稍微改改?之前的代码了忘了支不支持32位了~

HideDll.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#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;
}

微软未公开结构体查询网站

Vergilius Project Home

NTAPI Undocumented Functions (ntinternals.net)