refactoring
This commit is contained in:
15
wufuc/core.c
15
wufuc/core.c
@@ -13,7 +13,7 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) {
|
|||||||
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
|
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
|
||||||
|
|
||||||
TCHAR lpBinaryPathName[0x8000];
|
TCHAR lpBinaryPathName[0x8000];
|
||||||
QueryServiceBinaryPathName(hSCManager, _T("wuauserv"), lpBinaryPathName, _countof(lpBinaryPathName));
|
get_svcpath(hSCManager, _T("wuauserv"), lpBinaryPathName, _countof(lpBinaryPathName));
|
||||||
|
|
||||||
BOOL result = _tcsicmp(GetCommandLine(), lpBinaryPathName);
|
BOOL result = _tcsicmp(GetCommandLine(), lpBinaryPathName);
|
||||||
CloseServiceHandle(hSCManager);
|
CloseServiceHandle(hSCManager);
|
||||||
@@ -27,22 +27,23 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) {
|
|||||||
ConvertStringSecurityDescriptorToSecurityDescriptor(_T("D:PAI(A;;FA;;;BA)"), SDDL_REVISION_1, &(sa.lpSecurityDescriptor), NULL);
|
ConvertStringSecurityDescriptorToSecurityDescriptor(_T("D:PAI(A;;FA;;;BA)"), SDDL_REVISION_1, &(sa.lpSecurityDescriptor), NULL);
|
||||||
sa.bInheritHandle = FALSE;
|
sa.bInheritHandle = FALSE;
|
||||||
|
|
||||||
HANDLE hEvent = CreateEvent(&sa, FALSE, FALSE, _T("Global\\wufuc_UnloadEvent"));
|
HANDLE hEvent = CreateEvent(&sa, TRUE, FALSE, _T("Global\\wufuc_UnloadEvent"));
|
||||||
|
|
||||||
if (!hEvent) {
|
if (!hEvent) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD dwProcessId = GetCurrentProcessId();
|
||||||
|
DWORD dwThreadId = GetCurrentThreadId();
|
||||||
HANDLE lphThreads[0x1000];
|
HANDLE lphThreads[0x1000];
|
||||||
SIZE_T cb;
|
SIZE_T cb;
|
||||||
SuspendProcess(lphThreads, _countof(lphThreads), &cb);
|
|
||||||
|
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
|
||||||
|
|
||||||
HMODULE hm = GetModuleHandle(NULL);
|
HMODULE hm = GetModuleHandle(NULL);
|
||||||
DETOUR_IAT(hm, LoadLibraryExA);
|
DETOUR_IAT(hm, LoadLibraryExA);
|
||||||
DETOUR_IAT(hm, LoadLibraryExW);
|
DETOUR_IAT(hm, LoadLibraryExW);
|
||||||
|
|
||||||
_tdbgprintf(_T("Applied LoadLibraryEx hooks."));
|
|
||||||
|
|
||||||
HMODULE hwu = GetModuleHandle(_T("wuaueng.dll"));
|
HMODULE hwu = GetModuleHandle(_T("wuaueng.dll"));
|
||||||
if (hwu) {
|
if (hwu) {
|
||||||
PatchWUModule(hwu);
|
PatchWUModule(hwu);
|
||||||
@@ -50,16 +51,16 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) {
|
|||||||
ResumeAndCloseThreads(lphThreads, cb);
|
ResumeAndCloseThreads(lphThreads, cb);
|
||||||
|
|
||||||
WaitForSingleObject(hEvent, INFINITE);
|
WaitForSingleObject(hEvent, INFINITE);
|
||||||
CloseHandle(hEvent);
|
|
||||||
|
|
||||||
_tdbgprintf(_T("Received wufuc_UnloadEvent, removing hooks."));
|
_tdbgprintf(_T("Received wufuc_UnloadEvent, removing hooks."));
|
||||||
|
|
||||||
SuspendProcess(lphThreads, _countof(lphThreads), &cb);
|
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
|
||||||
RESTORE_IAT(hm, LoadLibraryExA);
|
RESTORE_IAT(hm, LoadLibraryExA);
|
||||||
RESTORE_IAT(hm, LoadLibraryExW);
|
RESTORE_IAT(hm, LoadLibraryExW);
|
||||||
ResumeAndCloseThreads(lphThreads, cb);
|
ResumeAndCloseThreads(lphThreads, cb);
|
||||||
|
|
||||||
_tdbgprintf(_T("Unloading library. Cya!"));
|
_tdbgprintf(_T("Unloading library. Cya!"));
|
||||||
|
CloseHandle(hEvent);
|
||||||
FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0);
|
FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -14,9 +14,9 @@ void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int n
|
|||||||
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
|
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
|
||||||
TCHAR lpGroupName[256];
|
TCHAR lpGroupName[256];
|
||||||
DWORD dwProcessId;
|
DWORD dwProcessId;
|
||||||
BOOL result = QueryServiceProcessId(hSCManager, _T("wuauserv"), &dwProcessId);
|
BOOL result = get_svcpid(hSCManager, _T("wuauserv"), &dwProcessId);
|
||||||
if (!result && GetServiceGroupName(hSCManager, _T("wuauserv"), lpGroupName, _countof(lpGroupName))) {
|
if (!result && get_svcgname(hSCManager, _T("wuauserv"), lpGroupName, _countof(lpGroupName))) {
|
||||||
result = FindServiceGroupProcessId(hSCManager, lpGroupName, &dwProcessId);
|
result = get_svcgpid(hSCManager, lpGroupName, &dwProcessId);
|
||||||
}
|
}
|
||||||
CloseServiceHandle(hSCManager);
|
CloseServiceHandle(hSCManager);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
139
wufuc/process.c
139
wufuc/process.c
@@ -1,139 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <TlHelp32.h>
|
|
||||||
#include <tchar.h>
|
|
||||||
#include "util.h"
|
|
||||||
#include "process.h"
|
|
||||||
|
|
||||||
VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress) {
|
|
||||||
LPVOID *lpAddress = FindIAT(hModule, lpFuncName);
|
|
||||||
if (!lpAddress || *lpAddress == lpNewAddress) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD flOldProtect;
|
|
||||||
DWORD flNewProtect = PAGE_READWRITE;
|
|
||||||
VirtualProtect(lpAddress, sizeof(LPVOID), flNewProtect, &flOldProtect);
|
|
||||||
if (lpOldAddress) {
|
|
||||||
*lpOldAddress = *lpAddress;
|
|
||||||
}
|
|
||||||
_tdbgprintf(_T("%S %p => %p"), lpFuncName, *lpAddress, lpNewAddress);
|
|
||||||
*lpAddress = lpNewAddress;
|
|
||||||
VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect);
|
|
||||||
}
|
|
||||||
|
|
||||||
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFuncName) {
|
|
||||||
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)hModule;
|
|
||||||
PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)((LPBYTE)dos + dos->e_lfanew);
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR desc = (PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)dos + nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
|
||||||
|
|
||||||
for (PIMAGE_IMPORT_DESCRIPTOR iid = desc; iid->Name != 0; iid++) {
|
|
||||||
for (int i = 0; *(i + (LPVOID*)(iid->FirstThunk + (SIZE_T)hModule)) != NULL; i++) {
|
|
||||||
LPSTR name = (LPSTR)(*(i + (SIZE_T*)(iid->OriginalFirstThunk + (SIZE_T)hModule)) + (SIZE_T)hModule + 2);
|
|
||||||
const uintptr_t n = (uintptr_t)name;
|
|
||||||
if (!(n & (sizeof(n) == 4 ? 0x80000000 : 0x8000000000000000)) && !_stricmp(lpFuncName, name)) {
|
|
||||||
return i + (LPVOID*)(iid->FirstThunk + (SIZE_T)hModule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL FindPattern(LPCBYTE lpBytes, SIZE_T nNumberOfBytes, LPSTR lpszPattern, SIZE_T nStart, SIZE_T *lpOffset) {
|
|
||||||
SIZE_T nPatternLength = strlen(lpszPattern);
|
|
||||||
SIZE_T nMaskLength = nPatternLength / 2;
|
|
||||||
if (nMaskLength > nNumberOfBytes || nPatternLength % 2) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPBYTE lpPattern = malloc(nMaskLength * sizeof(BYTE));
|
|
||||||
BOOL *lpbMask = malloc(nMaskLength * sizeof(BOOL));
|
|
||||||
|
|
||||||
LPSTR p = lpszPattern;
|
|
||||||
BOOL valid = TRUE;
|
|
||||||
for (SIZE_T i = 0; i < nMaskLength; i++) {
|
|
||||||
if (lpbMask[i] = strncmp(p, "??", 2)) {
|
|
||||||
if (sscanf_s(p, "%2hhx", &lpPattern[i]) != 1) {
|
|
||||||
valid = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p += 2;
|
|
||||||
}
|
|
||||||
BOOL result = FALSE;
|
|
||||||
if (valid) {
|
|
||||||
for (SIZE_T i = nStart; i < nNumberOfBytes - nStart - (nMaskLength - 1); i++) {
|
|
||||||
BOOL found = TRUE;
|
|
||||||
for (SIZE_T j = 0; j < nMaskLength; j++) {
|
|
||||||
if (lpbMask[j] && lpBytes[i + j] != lpPattern[j]) {
|
|
||||||
found = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found) {
|
|
||||||
*lpOffset = i;
|
|
||||||
result = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(lpPattern);
|
|
||||||
free(lpbMask);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL InjectLibrary(HANDLE hProcess, LPCTSTR lpLibFileName, DWORD cb) {
|
|
||||||
LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, cb, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
|
||||||
if (!WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, cb, NULL)) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
DWORD dwProcessId = GetProcessId(hProcess);
|
|
||||||
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
|
|
||||||
MODULEENTRY32 me;
|
|
||||||
me.dwSize = sizeof(me);
|
|
||||||
|
|
||||||
Module32First(hSnap, &me);
|
|
||||||
do {
|
|
||||||
if (!_tcsicmp(me.szModule, _T("kernel32.dll"))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (Module32Next(hSnap, &me));
|
|
||||||
CloseHandle(hSnap);
|
|
||||||
_tdbgprintf(_T("Injecting %s into process %d"), lpLibFileName, dwProcessId);
|
|
||||||
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(me.hModule, _CRT_STRINGIZE(LoadLibrary)), lpBaseAddress, 0, NULL);
|
|
||||||
CloseHandle(hThread);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID SuspendProcess(HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb) {
|
|
||||||
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
|
||||||
THREADENTRY32 te;
|
|
||||||
te.dwSize = sizeof(te);
|
|
||||||
Thread32First(hSnap, &te);
|
|
||||||
|
|
||||||
DWORD dwProcessId = GetCurrentProcessId();
|
|
||||||
DWORD dwThreadId = GetCurrentThreadId();
|
|
||||||
|
|
||||||
SIZE_T count = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (te.th32OwnerProcessID != dwProcessId || te.th32ThreadID == dwThreadId) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
lphThreads[count] = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID);
|
|
||||||
SuspendThread(lphThreads[count]);
|
|
||||||
count++;
|
|
||||||
} while (count < dwSize && Thread32Next(hSnap, &te));
|
|
||||||
CloseHandle(hSnap);
|
|
||||||
|
|
||||||
*lpcb = count;
|
|
||||||
_tdbgprintf(_T("Suspended other threads."));
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) {
|
|
||||||
for (SIZE_T i = 0; i < cb; i++) {
|
|
||||||
ResumeThread(lphThreads[i]);
|
|
||||||
CloseHandle(lphThreads[i]);
|
|
||||||
}
|
|
||||||
_tdbgprintf(_T("Resumed threads."));
|
|
||||||
}
|
|
@@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress);
|
|
||||||
|
|
||||||
#define DETOUR_IAT(x, y) \
|
|
||||||
LPVOID __LPORIGINAL##y; \
|
|
||||||
DetourIAT(x, #y, &__LPORIGINAL##y, &_##y)
|
|
||||||
|
|
||||||
#define RESTORE_IAT(x, y) \
|
|
||||||
DetourIAT(x, #y, NULL, __LPORIGINAL##y)
|
|
||||||
|
|
||||||
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFuncName);
|
|
||||||
|
|
||||||
BOOL FindPattern(LPCBYTE lpBytes, SIZE_T nNumberOfBytes, LPSTR lpszPattern, SIZE_T nStart, SIZE_T *lpOffset);
|
|
||||||
|
|
||||||
BOOL InjectLibrary(HANDLE hProcess, LPCTSTR lpLibFileName, DWORD cb);
|
|
||||||
|
|
||||||
VOID SuspendProcess(HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb);
|
|
||||||
|
|
||||||
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T dwSize);
|
|
@@ -2,8 +2,9 @@
|
|||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
|
#include "shellapihelper.h"
|
||||||
|
|
||||||
BOOL QueryServiceBinaryPathName(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize) {
|
BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize) {
|
||||||
HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_CONFIG);
|
HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_CONFIG);
|
||||||
if (!hService) {
|
if (!hService) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -22,7 +23,7 @@ BOOL QueryServiceBinaryPathName(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPT
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL QueryServiceProcessId(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessId) {
|
BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessId) {
|
||||||
SC_HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_STATUS);
|
SC_HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_STATUS);
|
||||||
if (!hService) {
|
if (!hService) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -34,15 +35,15 @@ BOOL QueryServiceProcessId(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *l
|
|||||||
if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&lpBuffer, sizeof(lpBuffer), &cbBytesNeeded) && lpBuffer.dwProcessId) {
|
if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&lpBuffer, sizeof(lpBuffer), &cbBytesNeeded) && lpBuffer.dwProcessId) {
|
||||||
*lpdwProcessId = lpBuffer.dwProcessId;
|
*lpdwProcessId = lpBuffer.dwProcessId;
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
_tdbgprintf(_T("Found %s pid %d"), lpServiceName, *lpdwProcessId);
|
_tdbgprintf(_T("QueryServiceProcessId: Found %s pid %d"), lpServiceName, *lpdwProcessId);
|
||||||
}
|
}
|
||||||
CloseServiceHandle(hService);
|
CloseServiceHandle(hService);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL GetServiceGroupName(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupName, SIZE_T dwSize) {
|
BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupName, SIZE_T dwSize) {
|
||||||
TCHAR lpBinaryPathName[0x8000];
|
TCHAR lpBinaryPathName[0x8000];
|
||||||
if (!QueryServiceBinaryPathName(hSCManager, lpServiceName, lpBinaryPathName, _countof(lpBinaryPathName))) {
|
if (!get_svcpath(hSCManager, lpServiceName, lpBinaryPathName, _countof(lpBinaryPathName))) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
int numArgs;
|
int numArgs;
|
||||||
@@ -57,7 +58,7 @@ BOOL GetServiceGroupName(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpG
|
|||||||
BOOL result = FALSE;
|
BOOL result = FALSE;
|
||||||
if (!_tcsicmp(fname, _T("svchost"))) {
|
if (!_tcsicmp(fname, _T("svchost"))) {
|
||||||
LPWSTR *p = argv;
|
LPWSTR *p = argv;
|
||||||
for (int i = 0; i + 1 < numArgs; i++) {
|
for (int i = 1; i < numArgs; i++) {
|
||||||
if (!_tcsicmp(*(p++), _T("-k"))) {
|
if (!_tcsicmp(*(p++), _T("-k"))) {
|
||||||
_tcscpy_s(lpGroupName, dwSize, *p);
|
_tcscpy_s(lpGroupName, dwSize, *p);
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
@@ -69,28 +70,29 @@ BOOL GetServiceGroupName(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpG
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL FindServiceGroupProcessId(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwProcessId) {
|
BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwProcessId) {
|
||||||
DWORD uBytes = 0x100000;
|
DWORD uBytes = 0x100000;
|
||||||
LPBYTE pvData = malloc(uBytes);
|
LPBYTE pvData = malloc(uBytes);
|
||||||
|
|
||||||
RegGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"), lpServiceGroupName, RRF_RT_REG_MULTI_SZ, NULL, pvData, &uBytes);
|
RegGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"), lpServiceGroupName, RRF_RT_REG_MULTI_SZ, NULL, pvData, &uBytes);
|
||||||
|
|
||||||
LPTSTR ptr = (LPTSTR)pvData;
|
LPTSTR lpSvc = (LPTSTR)pvData;
|
||||||
|
|
||||||
BOOL result = FALSE;
|
BOOL result = FALSE;
|
||||||
while (*ptr) {
|
while (*lpSvc) {
|
||||||
DWORD dwProcessId;
|
DWORD dwProcessId;
|
||||||
if (QueryServiceProcessId(hSCManager, ptr, &dwProcessId)) {
|
TCHAR group[256];
|
||||||
TCHAR group[256];
|
if (get_svcpid(hSCManager, lpSvc, &dwProcessId)) {
|
||||||
GetServiceGroupName(hSCManager, ptr, group, _countof(group));
|
get_svcgname(hSCManager, lpSvc, group, _countof(group));
|
||||||
result = !_tcsicmp(group, lpServiceGroupName);
|
result = !_tcsicmp(group, lpServiceGroupName);
|
||||||
|
if (result) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
_tdbgprintf(_T("Found %s pid %d"), lpServiceGroupName, dwProcessId);
|
|
||||||
*lpdwProcessId = dwProcessId;
|
*lpdwProcessId = dwProcessId;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ptr += _tcslen(ptr) + 1;
|
lpSvc += _tcslen(lpSvc) + 1;
|
||||||
}
|
}
|
||||||
LocalFree(pvData);
|
LocalFree(pvData);
|
||||||
return result;
|
return result;
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
BOOL QueryServiceBinaryPathName(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize);
|
BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize);
|
||||||
|
|
||||||
BOOL QueryServiceProcessId(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessId);
|
BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessId);
|
||||||
|
|
||||||
BOOL GetServiceGroupName(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupName, SIZE_T dwSize);
|
BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupName, SIZE_T dwSize);
|
||||||
|
|
||||||
BOOL FindServiceGroupProcessId(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwProcessId);
|
BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwProcessId);
|
||||||
|
7
wufuc/shellapihelper.h
Normal file
7
wufuc/shellapihelper.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define CommandLineToArgv CommandLineToArgvW
|
||||||
|
#else
|
||||||
|
#define CommandLineToArgv CommandLineToArgvA
|
||||||
|
#endif // !UNICODE
|
131
wufuc/util.c
131
wufuc/util.c
@@ -1,6 +1,7 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <VersionHelpers.h>
|
#include <VersionHelpers.h>
|
||||||
|
#include <TlHelp32.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
@@ -16,6 +17,136 @@ BOOL IsWindows8Point1(void) {
|
|||||||
return IsWindows8Point1OrGreater() && !IsWindows10OrGreater();
|
return IsWindows8Point1OrGreater() && !IsWindows10OrGreater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress) {
|
||||||
|
LPVOID *lpAddress = FindIAT(hModule, lpFuncName);
|
||||||
|
if (!lpAddress || *lpAddress == lpNewAddress) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD flOldProtect;
|
||||||
|
DWORD flNewProtect = PAGE_READWRITE;
|
||||||
|
VirtualProtect(lpAddress, sizeof(LPVOID), flNewProtect, &flOldProtect);
|
||||||
|
if (lpOldAddress) {
|
||||||
|
*lpOldAddress = *lpAddress;
|
||||||
|
}
|
||||||
|
_tdbgprintf(_T("%S %p => %p"), lpFuncName, *lpAddress, lpNewAddress);
|
||||||
|
*lpAddress = lpNewAddress;
|
||||||
|
VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect);
|
||||||
|
}
|
||||||
|
|
||||||
|
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFuncName) {
|
||||||
|
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)hModule;
|
||||||
|
PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)((LPBYTE)dos + dos->e_lfanew);
|
||||||
|
PIMAGE_IMPORT_DESCRIPTOR desc = (PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)dos + nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
||||||
|
|
||||||
|
for (PIMAGE_IMPORT_DESCRIPTOR iid = desc; iid->Name != 0; iid++) {
|
||||||
|
for (int i = 0; *(i + (LPVOID*)(iid->FirstThunk + (SIZE_T)hModule)) != NULL; i++) {
|
||||||
|
LPSTR name = (LPSTR)(*(i + (SIZE_T*)(iid->OriginalFirstThunk + (SIZE_T)hModule)) + (SIZE_T)hModule + 2);
|
||||||
|
const uintptr_t n = (uintptr_t)name;
|
||||||
|
if (!(n & (sizeof(n) == 4 ? 0x80000000 : 0x8000000000000000)) && !_stricmp(lpFuncName, name)) {
|
||||||
|
return i + (LPVOID*)(iid->FirstThunk + (SIZE_T)hModule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL FindPattern(LPCBYTE lpBytes, SIZE_T nNumberOfBytes, LPSTR lpszPattern, SIZE_T nStart, SIZE_T *lpOffset) {
|
||||||
|
SIZE_T nPatternLength = strlen(lpszPattern);
|
||||||
|
SIZE_T nMaskLength = nPatternLength / 2;
|
||||||
|
if (nMaskLength > nNumberOfBytes || nPatternLength % 2) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPBYTE lpPattern = malloc(nMaskLength * sizeof(BYTE));
|
||||||
|
BOOL *lpbMask = malloc(nMaskLength * sizeof(BOOL));
|
||||||
|
|
||||||
|
LPSTR p = lpszPattern;
|
||||||
|
BOOL valid = TRUE;
|
||||||
|
for (SIZE_T i = 0; i < nMaskLength; i++) {
|
||||||
|
if (lpbMask[i] = strncmp(p, "??", 2)) {
|
||||||
|
if (sscanf_s(p, "%2hhx", &lpPattern[i]) != 1) {
|
||||||
|
valid = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
BOOL result = FALSE;
|
||||||
|
if (valid) {
|
||||||
|
for (SIZE_T i = nStart; i < nNumberOfBytes - nStart - (nMaskLength - 1); i++) {
|
||||||
|
BOOL found = TRUE;
|
||||||
|
for (SIZE_T j = 0; j < nMaskLength; j++) {
|
||||||
|
if (lpbMask[j] && lpBytes[i + j] != lpPattern[j]) {
|
||||||
|
found = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
*lpOffset = i;
|
||||||
|
result = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(lpPattern);
|
||||||
|
free(lpbMask);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL InjectLibrary(HANDLE hProcess, LPCTSTR lpLibFileName, DWORD cb) {
|
||||||
|
LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, cb, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||||
|
if (!WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, cb, NULL)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
DWORD dwProcessId = GetProcessId(hProcess);
|
||||||
|
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
|
||||||
|
MODULEENTRY32 me;
|
||||||
|
me.dwSize = sizeof(me);
|
||||||
|
|
||||||
|
Module32First(hSnap, &me);
|
||||||
|
do {
|
||||||
|
if (!_tcsicmp(me.szModule, _T("kernel32.dll"))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (Module32Next(hSnap, &me));
|
||||||
|
CloseHandle(hSnap);
|
||||||
|
_tdbgprintf(_T("Injecting %s into process %d"), lpLibFileName, dwProcessId);
|
||||||
|
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(me.hModule, _CRT_STRINGIZE(LoadLibrary)), lpBaseAddress, 0, NULL);
|
||||||
|
CloseHandle(hThread);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb) {
|
||||||
|
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||||||
|
THREADENTRY32 te;
|
||||||
|
te.dwSize = sizeof(te);
|
||||||
|
Thread32First(hSnap, &te);
|
||||||
|
|
||||||
|
SIZE_T count = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (te.th32OwnerProcessID != dwProcessId || te.th32ThreadID == dwThreadId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lphThreads[count] = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID);
|
||||||
|
SuspendThread(lphThreads[count]);
|
||||||
|
count++;
|
||||||
|
} while (count < dwSize && Thread32Next(hSnap, &te));
|
||||||
|
CloseHandle(hSnap);
|
||||||
|
|
||||||
|
*lpcb = count;
|
||||||
|
_tdbgprintf(_T("Suspended other threads."));
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) {
|
||||||
|
for (SIZE_T i = 0; i < cb; i++) {
|
||||||
|
ResumeThread(lphThreads[i]);
|
||||||
|
CloseHandle(lphThreads[i]);
|
||||||
|
}
|
||||||
|
_tdbgprintf(_T("Resumed threads."));
|
||||||
|
}
|
||||||
|
|
||||||
VOID _wdbgprintf(LPCWSTR format, ...) {
|
VOID _wdbgprintf(LPCWSTR format, ...) {
|
||||||
WCHAR buffer[0x1000];
|
WCHAR buffer[0x1000];
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
|
24
wufuc/util.h
24
wufuc/util.h
@@ -9,6 +9,25 @@ BOOL IsWindows7(void);
|
|||||||
|
|
||||||
BOOL IsWindows8Point1(void);
|
BOOL IsWindows8Point1(void);
|
||||||
|
|
||||||
|
VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress);
|
||||||
|
|
||||||
|
#define DETOUR_IAT(x, y) \
|
||||||
|
LPVOID __LPORIGINAL##y; \
|
||||||
|
DetourIAT(x, #y, &__LPORIGINAL##y, &_##y)
|
||||||
|
|
||||||
|
#define RESTORE_IAT(x, y) \
|
||||||
|
DetourIAT(x, #y, NULL, __LPORIGINAL##y)
|
||||||
|
|
||||||
|
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFuncName);
|
||||||
|
|
||||||
|
BOOL FindPattern(LPCBYTE lpBytes, SIZE_T nNumberOfBytes, LPSTR lpszPattern, SIZE_T nStart, SIZE_T *lpOffset);
|
||||||
|
|
||||||
|
BOOL InjectLibrary(HANDLE hProcess, LPCTSTR lpLibFileName, DWORD cb);
|
||||||
|
|
||||||
|
VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb);
|
||||||
|
|
||||||
|
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T dwSize);
|
||||||
|
|
||||||
VOID _wdbgprintf(LPCWSTR format, ...);
|
VOID _wdbgprintf(LPCWSTR format, ...);
|
||||||
VOID _dbgprintf(LPCSTR format, ...);
|
VOID _dbgprintf(LPCSTR format, ...);
|
||||||
//#ifdef _DEBUG
|
//#ifdef _DEBUG
|
||||||
@@ -21,8 +40,3 @@ VOID _dbgprintf(LPCSTR format, ...);
|
|||||||
//#define _tdbgprintf(format, ...)
|
//#define _tdbgprintf(format, ...)
|
||||||
//#endif // !_DEBUG
|
//#endif // !_DEBUG
|
||||||
|
|
||||||
#ifdef UNICODE
|
|
||||||
#define CommandLineToArgv CommandLineToArgvW
|
|
||||||
#else
|
|
||||||
#define CommandLineToArgv CommandLineToArgvA
|
|
||||||
#endif // !UNICODE
|
|
||||||
|
@@ -168,7 +168,6 @@
|
|||||||
<ClCompile Include="core.c" />
|
<ClCompile Include="core.c" />
|
||||||
<ClCompile Include="dllmain.c" />
|
<ClCompile Include="dllmain.c" />
|
||||||
<ClCompile Include="entrypoint.c" />
|
<ClCompile Include="entrypoint.c" />
|
||||||
<ClCompile Include="process.c" />
|
|
||||||
<ClCompile Include="service.c" />
|
<ClCompile Include="service.c" />
|
||||||
<ClCompile Include="util.c" />
|
<ClCompile Include="util.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -177,8 +176,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="core.h" />
|
<ClInclude Include="core.h" />
|
||||||
<ClInclude Include="process.h" />
|
|
||||||
<ClInclude Include="service.h" />
|
<ClInclude Include="service.h" />
|
||||||
|
<ClInclude Include="shellapihelper.h" />
|
||||||
<ClInclude Include="util.h" />
|
<ClInclude Include="util.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
Reference in New Issue
Block a user