Skip to content

Commit ad9605e

Browse files
committed
update .net hooks
1 parent 429d549 commit ad9605e

5 files changed

Lines changed: 161 additions & 45 deletions

File tree

MemoryModule/MmpDotNet.cpp

Lines changed: 143 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,29 @@ typedef struct _MMP_FAKE_HANDLE_LIST_ENTRY {
1212
LIST_ENTRY InMmpFakeHandleList;
1313
HANDLE hObject;
1414
PVOID value;
15+
BOOL bImageMapping;
1516
}MMP_FAKE_HANDLE_LIST_ENTRY, * PMMP_FAKE_HANDLE_LIST_ENTRY;
1617

1718
static decltype(&CreateFileW) OriginCreateFileW = CreateFileW;
1819
static decltype(&GetFileInformationByHandle) OriginGetFileInformationByHandle = GetFileInformationByHandle;
1920
static decltype(&GetFileAttributesExW) OriginGetFileAttributesExW = GetFileAttributesExW;
21+
static decltype(&GetFileSize) OriginGetFileSize = GetFileSize;
22+
static decltype(&GetFileSizeEx) OriginGetFileSizeEx = GetFileSizeEx;
2023
static decltype(&CreateFileMappingW) OriginCreateFileMappingW = CreateFileMappingW;
2124
static decltype(&MapViewOfFileEx) OriginMapViewOfFileEx = MapViewOfFileEx;
25+
static decltype(&MapViewOfFile) OriginMapViewOfFile = MapViewOfFile;
2226
static decltype(&UnmapViewOfFile)OriginUnmapViewOfFile = UnmapViewOfFile;
2327
static decltype(&CloseHandle)OriginCloseHandle = CloseHandle;
24-
static GetFileVersion_T OriginGetFileVersion = nullptr;
28+
static GetFileVersion_T OriginGetFileVersion1 = nullptr;
29+
static GetFileVersion_T OriginGetFileVersion2 = nullptr;
2530

2631
FILETIME AssemblyTimes;
2732

2833
CRITICAL_SECTION MmpFakeHandleListLock;
2934
LIST_ENTRY MmpFakeHandleListHead;
3035

31-
static BOOL Initialized = FALSE;
36+
static BOOLEAN PreHooked = FALSE;
37+
static BOOLEAN Initialized = FALSE;
3238

3339
BOOL MmpIsMemoryModuleFileName(
3440
_In_ LPCWSTR lpFileName,
@@ -74,10 +80,12 @@ BOOL MmpIsMemoryModuleFileName(
7480

7581
VOID MmpInsertHandleEntry(
7682
_In_ HANDLE hObject,
77-
_In_ PVOID value) {
83+
_In_ PVOID value,
84+
_In_ BOOL bImageMapping = FALSE) {
7885
auto entry = (PMMP_FAKE_HANDLE_LIST_ENTRY)RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_FAKE_HANDLE_LIST_ENTRY));
7986
entry->hObject = hObject;
8087
entry->value = value;
88+
entry->bImageMapping = bImageMapping;
8189

8290
EnterCriticalSection(&MmpFakeHandleListLock);
8391
InsertTailList(&MmpFakeHandleListHead, &entry->InMmpFakeHandleList);
@@ -193,6 +201,49 @@ BOOL WINAPI HookGetFileAttributesExW(
193201
);
194202
}
195203

204+
DWORD WINAPI HookGetFileSize(
205+
_In_ HANDLE hFile,
206+
_Out_opt_ LPDWORD lpFileSizeHigh) {
207+
208+
auto iter = MmpFindHandleEntry(hFile);
209+
if (iter) {
210+
if (lpFileSizeHigh)*lpFileSizeHigh = 0;
211+
212+
auto entry = (PLDR_DATA_TABLE_ENTRY)iter->value;
213+
auto module = MapMemoryModuleHandle((HMEMORYMODULE)entry->DllBase);
214+
215+
return module->dwImageFileSize;
216+
}
217+
else {
218+
return OriginGetFileSize(
219+
hFile,
220+
lpFileSizeHigh
221+
);
222+
}
223+
224+
}
225+
226+
BOOL WINAPI HookGetFileSizeEx(
227+
_In_ HANDLE hFile,
228+
_Out_ PLARGE_INTEGER lpFileSize) {
229+
230+
auto iter = MmpFindHandleEntry(hFile);
231+
if (iter) {
232+
auto entry = (PLDR_DATA_TABLE_ENTRY)iter->value;
233+
auto module = MapMemoryModuleHandle((HMEMORYMODULE)entry->DllBase);
234+
235+
lpFileSize->QuadPart = module->dwImageFileSize;
236+
return TRUE;
237+
}
238+
else {
239+
return OriginGetFileSizeEx(
240+
hFile,
241+
lpFileSize
242+
);
243+
}
244+
245+
}
246+
196247
HANDLE WINAPI HookCreateFileMappingW(
197248
_In_ HANDLE hFile,
198249
_In_opt_ LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
@@ -205,7 +256,7 @@ HANDLE WINAPI HookCreateFileMappingW(
205256
if (iter) {
206257
HANDLE hEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr);
207258

208-
MmpInsertHandleEntry(hEvent, iter->value);
259+
MmpInsertHandleEntry(hEvent, iter->value, !!(flProtect & SEC_IMAGE));
209260
return hEvent;
210261
}
211262

@@ -233,9 +284,13 @@ LPVOID WINAPI HookMapViewOfFileEx(
233284
auto entry = (PLDR_DATA_TABLE_ENTRY)iter->value;
234285
auto pModule = MapMemoryModuleHandle((HMEMORYMODULE)entry->DllBase);
235286
if (pModule) {
236-
MemoryLoadLibrary(&hModule, pModule->lpReserved, pModule->dwImageFileSize);
237-
238-
if (hModule) MmpInsertHandleEntry(hModule, hModule);
287+
if (iter->bImageMapping) {
288+
MemoryLoadLibrary(&hModule, pModule->lpReserved, pModule->dwImageFileSize);
289+
if (hModule) MmpInsertHandleEntry(hModule, hModule);
290+
}
291+
else {
292+
return pModule->lpReserved;
293+
}
239294
}
240295

241296
return hModule;
@@ -251,6 +306,24 @@ LPVOID WINAPI HookMapViewOfFileEx(
251306
);
252307
}
253308

309+
LPVOID WINAPI HookMapViewOfFile(
310+
_In_ HANDLE hFileMappingObject,
311+
_In_ DWORD dwDesiredAccess,
312+
_In_ DWORD dwFileOffsetHigh,
313+
_In_ DWORD dwFileOffsetLow,
314+
_In_ SIZE_T dwNumberOfBytesToMap) {
315+
316+
return HookMapViewOfFileEx(
317+
hFileMappingObject,
318+
dwDesiredAccess,
319+
dwFileOffsetHigh,
320+
dwFileOffsetLow,
321+
dwNumberOfBytesToMap,
322+
nullptr
323+
);
324+
325+
}
326+
254327
BOOL WINAPI HookUnmapViewOfFile(_In_ LPCVOID lpBaseAddress) {
255328
auto iter = MmpFindHandleEntry((HANDLE)lpBaseAddress);
256329
if (iter) {
@@ -309,49 +382,81 @@ HRESULT WINAPI HookGetFileVersion(
309382

310383
}
311384

312-
return OriginGetFileVersion(
385+
return OriginGetFileVersion1(
313386
szFilename,
314387
szBuffer,
315388
cchBuffer,
316389
dwLength
317390
);
318391
}
319392

393+
BOOL WINAPI MmpPreInitializeHooksForDotNet() {
394+
395+
EnterCriticalSection(NtCurrentPeb()->FastPebLock);
396+
397+
if (!PreHooked) {
398+
HMODULE hModule = LoadLibraryW(L"mscoree.dll");
399+
if (hModule) {
400+
OriginGetFileVersion2 = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion");
401+
if (OriginGetFileVersion2) {
402+
403+
GetSystemTimeAsFileTime(&AssemblyTimes);
404+
405+
InitializeCriticalSection(&MmpFakeHandleListLock);
406+
InitializeListHead(&MmpFakeHandleListHead);
407+
408+
DetourTransactionBegin();
409+
DetourUpdateThread(NtCurrentThread());
410+
411+
DetourAttach((PVOID*)&OriginCreateFileW, HookCreateFileW);
412+
DetourAttach((PVOID*)&OriginGetFileInformationByHandle, HookGetFileInformationByHandle);
413+
DetourAttach((PVOID*)&OriginGetFileAttributesExW, HookGetFileAttributesExW);
414+
DetourAttach((PVOID*)&OriginGetFileSize, HookGetFileSize);
415+
DetourAttach((PVOID*)&OriginGetFileSizeEx, HookGetFileSizeEx);
416+
DetourAttach((PVOID*)&OriginCreateFileMappingW, HookCreateFileMappingW);
417+
DetourAttach((PVOID*)&OriginMapViewOfFileEx, HookMapViewOfFileEx);
418+
DetourAttach((PVOID*)&OriginMapViewOfFile, HookMapViewOfFile);
419+
DetourAttach((PVOID*)&OriginUnmapViewOfFile, HookUnmapViewOfFile);
420+
DetourAttach((PVOID*)&OriginCloseHandle, HookCloseHandle);
421+
DetourAttach((PVOID*)&OriginGetFileVersion2, HookGetFileVersion);
422+
423+
DetourTransactionCommit();
424+
425+
PreHooked = TRUE;
426+
}
427+
}
428+
}
429+
430+
LeaveCriticalSection(NtCurrentPeb()->FastPebLock);
431+
432+
return PreHooked;
433+
}
434+
320435
BOOL WINAPI MmpInitializeHooksForDotNet() {
321436
HMODULE hModule = GetModuleHandleW(L"mscoreei.dll");
322-
if (!hModule) {
323-
RtlRaiseStatus(STATUS_NOT_SUPPORTED);
324-
return FALSE;
325-
}
437+
if (hModule) {
438+
OriginGetFileVersion1 = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion");
439+
if (OriginGetFileVersion1) {
326440

327-
OriginGetFileVersion = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion");
328-
if (!OriginGetFileVersion) {
329-
RtlRaiseStatus(STATUS_NOT_SUPPORTED);
330-
return FALSE;
331-
}
441+
EnterCriticalSection(NtCurrentPeb()->FastPebLock);
332442

333-
GetSystemTimeAsFileTime(&AssemblyTimes);
443+
if (!PreHooked) {
444+
LeaveCriticalSection(NtCurrentPeb()->FastPebLock);
445+
return FALSE;
446+
}
334447

335-
EnterCriticalSection(NtCurrentPeb()->FastPebLock);
336-
if (!Initialized) {
337-
338-
InitializeCriticalSection(&MmpFakeHandleListLock);
339-
InitializeListHead(&MmpFakeHandleListHead);
340-
341-
DetourTransactionBegin();
342-
DetourUpdateThread(NtCurrentThread());
343-
DetourAttach((PVOID*)&OriginCreateFileW, HookCreateFileW);
344-
DetourAttach((PVOID*)&OriginGetFileInformationByHandle, HookGetFileInformationByHandle);
345-
DetourAttach((PVOID*)&OriginGetFileAttributesExW, HookGetFileAttributesExW);
346-
DetourAttach((PVOID*)&OriginCreateFileMappingW, HookCreateFileMappingW);
347-
DetourAttach((PVOID*)&OriginMapViewOfFileEx, HookMapViewOfFileEx);
348-
DetourAttach((PVOID*)&OriginUnmapViewOfFile, HookUnmapViewOfFile);
349-
DetourAttach((PVOID*)&OriginCloseHandle, HookCloseHandle);
350-
DetourAttach((PVOID*)&OriginGetFileVersion, HookGetFileVersion);
351-
DetourTransactionCommit();
352-
Initialized = TRUE;
448+
if (!Initialized) {
449+
DetourTransactionBegin();
450+
DetourUpdateThread(NtCurrentThread());
451+
DetourAttach((PVOID*)&OriginGetFileVersion1, HookGetFileVersion);
452+
DetourTransactionCommit();
453+
Initialized = TRUE;
454+
}
455+
456+
LeaveCriticalSection(NtCurrentPeb()->FastPebLock);
457+
return TRUE;
458+
}
353459
}
354-
LeaveCriticalSection(NtCurrentPeb()->FastPebLock);
355460

356-
return TRUE;
461+
return FALSE;
357462
}

MemoryModule/MmpDotNet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
#pragma once
2+
BOOL WINAPI MmpPreInitializeHooksForDotNet();
23
BOOL WINAPI MmpInitializeHooksForDotNet();

MemoryModule/MmpTls.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
172172

173173
THREAD_CONTEXT Context;
174174
bool success = false;
175+
PMMP_TLSP_RECORD record = nullptr;
175176

176177
__try {
177178
RtlCopyMemory(
@@ -186,13 +187,16 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
186187
return GetExceptionCode();
187188
}
188189

190+
if (!NtCurrentTeb()->ThreadLocalStoragePointer) {
191+
goto __skip_tls;
192+
}
189193

190194
//
191195
// Allocate and replace ThreadLocalStoragePointer for new thread
192196
//
193197
EnterCriticalSection(&MmpTlspLock);
194198

195-
auto record = PMMP_TLSP_RECORD(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_TLSP_RECORD)));
199+
record = PMMP_TLSP_RECORD(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_TLSP_RECORD)));
196200
if (record) {
197201
record->TlspLdrBlock = (PVOID*)NtCurrentTeb()->ThreadLocalStoragePointer;
198202
record->TlspMmpBlock = (PVOID*)MmpAllocateTlsp();
@@ -259,6 +263,7 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
259263
++MmpActiveThreadCount;
260264
LeaveCriticalSection(&MmpTlspLock);
261265

266+
__skip_tls:
262267
return Context.ThreadStartRoutine(Context.ThreadParameter);
263268
}
264269

@@ -272,7 +277,7 @@ NTSTATUS NTAPI HookNtCreateThread(
272277
_In_ PVOID InitialTeb,
273278
_In_ BOOLEAN CreateSuspended) {
274279
CONTEXT Context = *ThreadContext;
275-
PTHREAD_CONTEXT _Context = PTHREAD_CONTEXT(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(_Context)));
280+
PTHREAD_CONTEXT _Context = PTHREAD_CONTEXT(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(*_Context)));
276281
NTSTATUS status;
277282

278283
if (!_Context)return STATUS_NO_MEMORY;
@@ -325,7 +330,7 @@ NTSTATUS NTAPI HookNtCreateThreadEx(
325330
_In_ SIZE_T StackSize,
326331
_In_ SIZE_T MaximumStackSize,
327332
_In_opt_ PVOID AttributeList) {
328-
PTHREAD_CONTEXT Context = PTHREAD_CONTEXT(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(Context)));
333+
PTHREAD_CONTEXT Context = PTHREAD_CONTEXT(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(*Context)));
329334
if (!Context) {
330335
return STATUS_NO_MEMORY;
331336
}

MemoryModule/NativeFunctionsInternal.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,9 +704,14 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW(
704704
}
705705
}
706706

707+
if (dwFlags & LOAD_FLAGS_HOOK_DOT_NET) {
708+
MmpPreInitializeHooksForDotNet();
709+
}
710+
707711
if (!LdrpExecuteTLS(module) || !LdrpCallInitializers(module, DLL_PROCESS_ATTACH)) {
708712
status = STATUS_DLL_INIT_FAILED;
709713
LdrUnloadDllMemory(*BaseAddress);
714+
return status;
710715
}
711716

712717
if (dwFlags & LOAD_FLAGS_HOOK_DOT_NET) {

test/test.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ static PVOID ReadDllFile(LPCSTR FileName) {
2121
int main() {
2222
HMEMORYMODULE hModule;
2323
NTSTATUS status;
24-
PVOID buffer = ReadDllFile("lib.dll");
24+
PVOID buffer = ReadDllFile("ManagedLib_x64.dll");
2525

2626
if (!buffer) {
2727
return 0;
@@ -38,10 +38,10 @@ int main() {
3838
);
3939
if (NT_SUCCESS(status) && status != STATUS_IMAGE_MACHINE_TYPE_MISMATCH) {
4040
int result = 0;
41-
typedef int(WINAPI* func)(int, int);
41+
typedef VOID(WINAPI* func)(LPCSTR);
4242

43-
func f = (func)GetProcAddress(hModule, "Add");
44-
if (f)result = f(128, 256);
43+
func f = (func)GetProcAddress(hModule, "ManagedExportFunc");
44+
if (f)f("Hello World!");
4545

4646
LdrUnloadDllMemory(hModule);
4747
}

0 commit comments

Comments
 (0)