From 14740195e0f01262442f5bc8869a3ffa185254d4 Mon Sep 17 00:00:00 2001 From: loland <73586395+loland@users.noreply.github.com> Date: Thu, 4 Dec 2025 22:19:14 +0800 Subject: [PATCH] Update SubscriberBitPatch.c --- Code Snippets/SubscriberBitPatch.c | 65 ++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/Code Snippets/SubscriberBitPatch.c b/Code Snippets/SubscriberBitPatch.c index 3d08a89..12d8b2b 100644 --- a/Code Snippets/SubscriberBitPatch.c +++ b/Code Snippets/SubscriberBitPatch.c @@ -7,9 +7,61 @@ int getImageSize(void* imageBase) { return sizeOfImage; } +int isEtwFunc(unsigned char* funcAddr, void* etwEventWrite) { + int i = 0; + while (1) { + unsigned char* currAddr = funcAddr + i; + unsigned char currByte = *currAddr; + + if (currByte == 0xc3) { + return 0; + } + + unsigned char nextByte = *(currAddr + 1); + + if (currByte != 0xff || nextByte != 0x15) { + i += 1; + continue; + } + + int iatOffset = *(int*)(currAddr + 2); + unsigned char* rip = (currAddr + 6); + int* iatAddr = *(int**)(rip + iatOffset); + + if (iatAddr == etwEventWrite) { + break; + } + + i += 1; + } + return 1; +} + +int hasCoTemplateEventDescriptorCall(unsigned char* addr, void* etwEventWrite) { + // test cs:Microsoft_Windows_DotNETRuntimeEnableBits, 40000000h (10 bytes) + // jz short loc_* (2 bytes) + // lea rdx, DebugIPCEventEnd (7 bytes) + // call CoTemplateEventDescriptor (5 bytes) + + unsigned char* callInstrAddr = addr + 10 + 2 + 7; + unsigned char* rip = addr + 10 + 2 + 7 + 5; + + if (*callInstrAddr != 0xe8) { + return 0; // not a call + } + + int offset = *(DWORD*)(callInstrAddr + 1); + unsigned char* funcAddr = rip + offset; + + return isEtwFunc(funcAddr, etwEventWrite); +} + int* findDotNETRuntimeEnableBits(HMODULE clrBase) { int clrSize = getImageSize(clrBase); + HMODULE ntdllBase = LoadLibraryA("ntdll.dll"); + void* etwEventWrite = GetProcAddress(ntdllBase, "EtwEventWrite"); + // assuming a max of 20 global variables that match the pattern int MAX = 20; int* globalVars[20] = { 0 }; @@ -18,12 +70,16 @@ int* findDotNETRuntimeEnableBits(HMODULE clrBase) { for (int i = 0; i < clrSize; i++) { unsigned char* addr = (unsigned char*)clrBase + i; - // matching "test cs:Microsoft_Windows_DotNETRuntimeEnableBits, 80000000h" + // matches "test cs:Microsoft_Windows_DotNETRuntimeEnableBits, 80000000h" if (addr[0] != 0xf7 || addr[1] != 0x5) { continue; } - if (*(DWORD*)(addr + 6) != 0x80000000) { + if (*(DWORD*)(addr + 6) != 0x80000000 && *(DWORD*)(addr + 6) != 0x40000000) { + continue; + } + + if (!hasCoTemplateEventDescriptorCall(addr, etwEventWrite)) { continue; } @@ -67,9 +123,12 @@ void turnOnEtw(int* DotNETRuntimeEnableBits_addr, int DotNETRuntimeEnableBits_va } int main() { - HMODULE clrBase = LoadLibraryA("C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\clr.dll"); + HMODULE clrBase = LoadLibraryA("C:\\Users\\root\\Desktop\\clrs\\clr_4.8.4220.0.dll"); int* DotNETRuntimeEnableBits_addr = findDotNETRuntimeEnableBits(clrBase); + printf("clrBase: %p\n", clrBase); + printf("DotNETRuntimeEnableBits_addr: %p\n", DotNETRuntimeEnableBits_addr); + // because the CLR isn't initialized, there will be no DotNETRuntimeEnableBits value. int DotNETRuntimeEnableBits_val = 0; turnOffEtw(DotNETRuntimeEnableBits_addr, &DotNETRuntimeEnableBits_val);