spaces > tabs
This commit is contained in:
221
wufuc/core.c
221
wufuc/core.c
@@ -10,152 +10,151 @@
|
||||
#include "util.h"
|
||||
|
||||
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];
|
||||
get_svcpath(hSCManager, _T("wuauserv"), lpBinaryPathName, _countof(lpBinaryPathName));
|
||||
TCHAR lpBinaryPathName[0x8000];
|
||||
get_svcpath(hSCManager, _T("wuauserv"), lpBinaryPathName, _countof(lpBinaryPathName));
|
||||
|
||||
BOOL result = _tcsicmp(GetCommandLine(), lpBinaryPathName);
|
||||
CloseServiceHandle(hSCManager);
|
||||
BOOL result = _tcsicmp(GetCommandLine(), lpBinaryPathName);
|
||||
CloseServiceHandle(hSCManager);
|
||||
|
||||
if (result) {
|
||||
return 0;
|
||||
}
|
||||
if (result) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(sa);
|
||||
ConvertStringSecurityDescriptorToSecurityDescriptor(_T("D:PAI(A;;FA;;;BA)"), SDDL_REVISION_1, &(sa.lpSecurityDescriptor), NULL);
|
||||
sa.bInheritHandle = FALSE;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(sa);
|
||||
ConvertStringSecurityDescriptorToSecurityDescriptor(_T("D:PAI(A;;FA;;;BA)"), SDDL_REVISION_1, &(sa.lpSecurityDescriptor), NULL);
|
||||
sa.bInheritHandle = FALSE;
|
||||
|
||||
HANDLE hEvent = CreateEvent(&sa, TRUE, FALSE, _T("Global\\wufuc_UnloadEvent"));
|
||||
HANDLE hEvent = CreateEvent(&sa, TRUE, FALSE, _T("Global\\wufuc_UnloadEvent"));
|
||||
|
||||
if (!hEvent) {
|
||||
return 0;
|
||||
}
|
||||
if (!hEvent) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD dwProcessId = GetCurrentProcessId();
|
||||
DWORD dwThreadId = GetCurrentThreadId();
|
||||
HANDLE lphThreads[0x1000];
|
||||
SIZE_T cb;
|
||||
DWORD dwProcessId = GetCurrentProcessId();
|
||||
DWORD dwThreadId = GetCurrentThreadId();
|
||||
HANDLE lphThreads[0x1000];
|
||||
SIZE_T cb;
|
||||
|
||||
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
|
||||
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
|
||||
|
||||
HMODULE hm = GetModuleHandle(NULL);
|
||||
DETOUR_IAT(hm, LoadLibraryExA);
|
||||
DETOUR_IAT(hm, LoadLibraryExW);
|
||||
HMODULE hm = GetModuleHandle(NULL);
|
||||
DETOUR_IAT(hm, LoadLibraryExA);
|
||||
DETOUR_IAT(hm, LoadLibraryExW);
|
||||
|
||||
HMODULE hwu = GetModuleHandle(_T("wuaueng.dll"));
|
||||
if (hwu) {
|
||||
PatchWUModule(hwu);
|
||||
}
|
||||
ResumeAndCloseThreads(lphThreads, cb);
|
||||
HMODULE hwu = GetModuleHandle(_T("wuaueng.dll"));
|
||||
if (hwu) {
|
||||
PatchWUModule(hwu);
|
||||
}
|
||||
ResumeAndCloseThreads(lphThreads, cb);
|
||||
|
||||
WaitForSingleObject(hEvent, INFINITE);
|
||||
WaitForSingleObject(hEvent, INFINITE);
|
||||
|
||||
_tdbgprintf(_T("Received wufuc_UnloadEvent, removing hooks."));
|
||||
_tdbgprintf(_T("Received wufuc_UnloadEvent, removing hooks."));
|
||||
|
||||
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
|
||||
RESTORE_IAT(hm, LoadLibraryExA);
|
||||
RESTORE_IAT(hm, LoadLibraryExW);
|
||||
ResumeAndCloseThreads(lphThreads, cb);
|
||||
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
|
||||
RESTORE_IAT(hm, LoadLibraryExA);
|
||||
RESTORE_IAT(hm, LoadLibraryExW);
|
||||
ResumeAndCloseThreads(lphThreads, cb);
|
||||
|
||||
_tdbgprintf(_T("Unloading library. Cya!"));
|
||||
CloseHandle(hEvent);
|
||||
FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0);
|
||||
return 0;
|
||||
_tdbgprintf(_T("Unloading library. Cya!"));
|
||||
CloseHandle(hEvent);
|
||||
FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL IsWUModule(HMODULE hModule) {
|
||||
TCHAR lpBaseName[MAX_PATH + 1];
|
||||
GetModuleBaseName(GetCurrentProcess(), hModule, lpBaseName, _countof(lpBaseName));
|
||||
return !_tcsicmp(lpBaseName, _T("wuaueng.dll"));
|
||||
TCHAR lpBaseName[MAX_PATH + 1];
|
||||
GetModuleBaseName(GetCurrentProcess(), hModule, lpBaseName, _countof(lpBaseName));
|
||||
return !_tcsicmp(lpBaseName, _T("wuaueng.dll"));
|
||||
}
|
||||
|
||||
BOOL PatchWUModule(HMODULE hModule) {
|
||||
if (!IsWindows7Or8Point1()) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!IsWindows7Or8Point1()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LPSTR lpszPattern;
|
||||
SIZE_T n1, n2;
|
||||
LPSTR lpszPattern;
|
||||
SIZE_T n1, n2;
|
||||
#ifdef _WIN64
|
||||
lpszPattern =
|
||||
"FFF3" // push rbx
|
||||
"4883EC??" // sub rsp,??
|
||||
"33DB" // xor ebx,ebx
|
||||
"391D????????" // cmp dword ptr ds:[???????????],ebx
|
||||
"7508" // jnz $+8
|
||||
"8B05????????"; // mov eax,dword ptr ds:[???????????]
|
||||
n1 = 10;
|
||||
n2 = 18;
|
||||
lpszPattern =
|
||||
"FFF3" // push rbx
|
||||
"4883EC??" // sub rsp,??
|
||||
"33DB" // xor ebx,ebx
|
||||
"391D????????" // cmp dword ptr ds:[???????????],ebx
|
||||
"7508" // jnz $+8
|
||||
"8B05????????"; // mov eax,dword ptr ds:[???????????]
|
||||
n1 = 10;
|
||||
n2 = 18;
|
||||
#elif defined(_WIN32)
|
||||
if (IsWindows8Point1()) {
|
||||
lpszPattern =
|
||||
"8BFF" // mov edi,edi
|
||||
"51" // push ecx
|
||||
"833D????????00" // cmp dword ptr ds:[????????],0
|
||||
"7507" // jnz $+7
|
||||
"A1????????"; // mov eax,dword ptr ds:[????????]
|
||||
n1 = 5;
|
||||
n2 = 13;
|
||||
}
|
||||
else if (IsWindows7()) {
|
||||
lpszPattern =
|
||||
"833D????????00" // cmp dword ptr ds:[????????],0
|
||||
"743E" // je $+3E
|
||||
"E8????????" // call <wuaueng.IsCPUSupported>
|
||||
"A3????????"; // mov dword ptr ds:[????????],eax
|
||||
n1 = 2;
|
||||
n2 = 15;
|
||||
}
|
||||
if (IsWindows8Point1()) {
|
||||
lpszPattern =
|
||||
"8BFF" // mov edi,edi
|
||||
"51" // push ecx
|
||||
"833D????????00" // cmp dword ptr ds:[????????],0
|
||||
"7507" // jnz $+7
|
||||
"A1????????"; // mov eax,dword ptr ds:[????????]
|
||||
n1 = 5;
|
||||
n2 = 13;
|
||||
} else if (IsWindows7()) {
|
||||
lpszPattern =
|
||||
"833D????????00" // cmp dword ptr ds:[????????],0
|
||||
"743E" // je $+3E
|
||||
"E8????????" // call <wuaueng.IsCPUSupported>
|
||||
"A3????????"; // mov dword ptr ds:[????????],eax
|
||||
n1 = 2;
|
||||
n2 = 15;
|
||||
}
|
||||
#else
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
MODULEINFO modinfo;
|
||||
GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO));
|
||||
MODULEINFO modinfo;
|
||||
GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO));
|
||||
|
||||
SIZE_T offset;
|
||||
if (!FindPattern(modinfo.lpBaseOfDll, modinfo.SizeOfImage, lpszPattern, 0, &offset)) {
|
||||
return FALSE;
|
||||
}
|
||||
SIZE_T rva = (SIZE_T)modinfo.lpBaseOfDll + offset;
|
||||
_tdbgprintf(_T("IsDeviceServiceable(void) matched at %IX"), rva);
|
||||
SIZE_T offset;
|
||||
if (!FindPattern(modinfo.lpBaseOfDll, modinfo.SizeOfImage, lpszPattern, 0, &offset)) {
|
||||
return FALSE;
|
||||
}
|
||||
SIZE_T rva = (SIZE_T)modinfo.lpBaseOfDll + offset;
|
||||
_tdbgprintf(_T("IsDeviceServiceable(void) matched at %IX"), rva);
|
||||
|
||||
BOOL *lpbNotRunOnce = (BOOL *)(rva + n1 + sizeof(DWORD) + *(DWORD *)(rva + n1));
|
||||
if (*lpbNotRunOnce) {
|
||||
*lpbNotRunOnce = FALSE;
|
||||
_tdbgprintf(_T("Patched %p=%d"), lpbNotRunOnce, *lpbNotRunOnce);
|
||||
}
|
||||
BOOL *lpbNotRunOnce = (BOOL *)(rva + n1 + sizeof(DWORD) + *(DWORD *)(rva + n1));
|
||||
if (*lpbNotRunOnce) {
|
||||
*lpbNotRunOnce = FALSE;
|
||||
_tdbgprintf(_T("Patched %p=%d"), lpbNotRunOnce, *lpbNotRunOnce);
|
||||
}
|
||||
|
||||
BOOL *lpbCachedResult = (BOOL *)(rva + n2 + sizeof(DWORD) + *(DWORD *)(rva + n2));
|
||||
if (!*lpbCachedResult) {
|
||||
*lpbCachedResult = TRUE;
|
||||
_tdbgprintf(_T("Patched %p=%d"), lpbCachedResult, *lpbCachedResult);
|
||||
}
|
||||
return TRUE;
|
||||
BOOL *lpbCachedResult = (BOOL *)(rva + n2 + sizeof(DWORD) + *(DWORD *)(rva + n2));
|
||||
if (!*lpbCachedResult) {
|
||||
*lpbCachedResult = TRUE;
|
||||
_tdbgprintf(_T("Patched %p=%d"), lpbCachedResult, *lpbCachedResult);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HMODULE WINAPI _LoadLibraryExA(
|
||||
_In_ LPCSTR lpFileName,
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags
|
||||
_In_ LPCSTR lpFileName,
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags
|
||||
) {
|
||||
HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags);
|
||||
if (IsWUModule(result)) {
|
||||
PatchWUModule(result);
|
||||
}
|
||||
return result;
|
||||
HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags);
|
||||
if (IsWUModule(result)) {
|
||||
PatchWUModule(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HMODULE WINAPI _LoadLibraryExW(
|
||||
_In_ LPCWSTR lpFileName,
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags
|
||||
_In_ LPCWSTR lpFileName,
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags
|
||||
) {
|
||||
HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags);
|
||||
if (IsWUModule(result)) {
|
||||
PatchWUModule(result);
|
||||
}
|
||||
return result;
|
||||
HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags);
|
||||
if (IsWUModule(result)) {
|
||||
PatchWUModule(result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
12
wufuc/core.h
12
wufuc/core.h
@@ -5,13 +5,13 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam);
|
||||
BOOL PatchWUModule(HMODULE hModule);
|
||||
|
||||
HMODULE WINAPI _LoadLibraryExA(
|
||||
_In_ LPCSTR lpFileName,
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags
|
||||
_In_ LPCSTR lpFileName,
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags
|
||||
);
|
||||
|
||||
HMODULE WINAPI _LoadLibraryExW(
|
||||
_In_ LPCWSTR lpFileName,
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags
|
||||
_In_ LPCWSTR lpFileName,
|
||||
_Reserved_ HANDLE hFile,
|
||||
_In_ DWORD dwFlags
|
||||
);
|
||||
|
@@ -2,18 +2,18 @@
|
||||
#include "core.h"
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL);
|
||||
CloseHandle(hThread);
|
||||
break;
|
||||
}
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL);
|
||||
CloseHandle(hThread);
|
||||
break;
|
||||
}
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -6,36 +6,36 @@
|
||||
#include "util.h"
|
||||
|
||||
void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
|
||||
HANDLE hEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("Global\\wufuc_UnloadEvent"));
|
||||
if (hEvent) {
|
||||
CloseHandle(hEvent);
|
||||
return;
|
||||
}
|
||||
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
|
||||
TCHAR lpGroupName[256];
|
||||
DWORD dwProcessId;
|
||||
BOOL result = get_svcpid(hSCManager, _T("wuauserv"), &dwProcessId);
|
||||
if (!result && get_svcgname(hSCManager, _T("wuauserv"), lpGroupName, _countof(lpGroupName))) {
|
||||
result = get_svcgpid(hSCManager, lpGroupName, &dwProcessId);
|
||||
}
|
||||
CloseServiceHandle(hSCManager);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
TCHAR lpLibFileName[MAX_PATH + 1];
|
||||
GetModuleFileName(HINST_THISCOMPONENT, lpLibFileName, _countof(lpLibFileName));
|
||||
HANDLE hEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("Global\\wufuc_UnloadEvent"));
|
||||
if (hEvent) {
|
||||
CloseHandle(hEvent);
|
||||
return;
|
||||
}
|
||||
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
|
||||
TCHAR lpGroupName[256];
|
||||
DWORD dwProcessId;
|
||||
BOOL result = get_svcpid(hSCManager, _T("wuauserv"), &dwProcessId);
|
||||
if (!result && get_svcgname(hSCManager, _T("wuauserv"), lpGroupName, _countof(lpGroupName))) {
|
||||
result = get_svcgpid(hSCManager, lpGroupName, &dwProcessId);
|
||||
}
|
||||
CloseServiceHandle(hSCManager);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
TCHAR lpLibFileName[MAX_PATH + 1];
|
||||
GetModuleFileName(HINST_THISCOMPONENT, lpLibFileName, _countof(lpLibFileName));
|
||||
|
||||
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
|
||||
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
|
||||
|
||||
InjectLibrary(hProcess, lpLibFileName, _countof(lpLibFileName));
|
||||
CloseHandle(hProcess);
|
||||
InjectLibrary(hProcess, lpLibFileName, _countof(lpLibFileName));
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
|
||||
void CALLBACK Rundll32Unload(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
|
||||
HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, _T("Global\\wufuc_UnloadEvent"));
|
||||
if (hEvent) {
|
||||
_tdbgprintf(_T("Setting wufuc_UnloadEvent..."));
|
||||
SetEvent(hEvent);
|
||||
CloseHandle(hEvent);
|
||||
}
|
||||
HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, _T("Global\\wufuc_UnloadEvent"));
|
||||
if (hEvent) {
|
||||
_tdbgprintf(_T("Setting wufuc_UnloadEvent..."));
|
||||
SetEvent(hEvent);
|
||||
CloseHandle(hEvent);
|
||||
}
|
||||
}
|
||||
|
136
wufuc/service.c
136
wufuc/service.c
@@ -5,87 +5,87 @@
|
||||
#include "shellapihelper.h"
|
||||
|
||||
BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize) {
|
||||
HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_CONFIG);
|
||||
if (!hService) {
|
||||
return FALSE;
|
||||
}
|
||||
HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_CONFIG);
|
||||
if (!hService) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD cbBytesNeeded;
|
||||
QueryServiceConfig(hService, NULL, 0, &cbBytesNeeded);
|
||||
LPQUERY_SERVICE_CONFIG sc = malloc(cbBytesNeeded);
|
||||
BOOL result = QueryServiceConfig(hService, sc, cbBytesNeeded, &cbBytesNeeded);
|
||||
CloseServiceHandle(hService);
|
||||
if (result) {
|
||||
_tcscpy_s(lpBinaryPathName, dwSize, sc->lpBinaryPathName);
|
||||
}
|
||||
free(sc);
|
||||
return result;
|
||||
DWORD cbBytesNeeded;
|
||||
QueryServiceConfig(hService, NULL, 0, &cbBytesNeeded);
|
||||
LPQUERY_SERVICE_CONFIG sc = malloc(cbBytesNeeded);
|
||||
BOOL result = QueryServiceConfig(hService, sc, cbBytesNeeded, &cbBytesNeeded);
|
||||
CloseServiceHandle(hService);
|
||||
if (result) {
|
||||
_tcscpy_s(lpBinaryPathName, dwSize, sc->lpBinaryPathName);
|
||||
}
|
||||
free(sc);
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessId) {
|
||||
SC_HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_STATUS);
|
||||
if (!hService) {
|
||||
return FALSE;
|
||||
}
|
||||
SC_HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_STATUS);
|
||||
if (!hService) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SERVICE_STATUS_PROCESS lpBuffer;
|
||||
DWORD cbBytesNeeded;
|
||||
BOOL result = FALSE;
|
||||
if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&lpBuffer, sizeof(lpBuffer), &cbBytesNeeded) && lpBuffer.dwProcessId) {
|
||||
*lpdwProcessId = lpBuffer.dwProcessId;
|
||||
result = TRUE;
|
||||
}
|
||||
CloseServiceHandle(hService);
|
||||
return result;
|
||||
SERVICE_STATUS_PROCESS lpBuffer;
|
||||
DWORD cbBytesNeeded;
|
||||
BOOL result = FALSE;
|
||||
if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&lpBuffer, sizeof(lpBuffer), &cbBytesNeeded) && lpBuffer.dwProcessId) {
|
||||
*lpdwProcessId = lpBuffer.dwProcessId;
|
||||
result = TRUE;
|
||||
}
|
||||
CloseServiceHandle(hService);
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupName, SIZE_T dwSize) {
|
||||
TCHAR lpBinaryPathName[0x8000];
|
||||
if (!get_svcpath(hSCManager, lpServiceName, lpBinaryPathName, _countof(lpBinaryPathName))) {
|
||||
return FALSE;
|
||||
}
|
||||
int numArgs;
|
||||
LPWSTR *argv = CommandLineToArgv(lpBinaryPathName, &numArgs);
|
||||
if (numArgs < 3) {
|
||||
return FALSE;
|
||||
}
|
||||
TCHAR lpBinaryPathName[0x8000];
|
||||
if (!get_svcpath(hSCManager, lpServiceName, lpBinaryPathName, _countof(lpBinaryPathName))) {
|
||||
return FALSE;
|
||||
}
|
||||
int numArgs;
|
||||
LPWSTR *argv = CommandLineToArgv(lpBinaryPathName, &numArgs);
|
||||
if (numArgs < 3) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TCHAR fname[_MAX_FNAME];
|
||||
_tsplitpath_s(argv[0], NULL, 0, NULL, 0, fname, _countof(fname), NULL, 0);
|
||||
TCHAR fname[_MAX_FNAME];
|
||||
_tsplitpath_s(argv[0], NULL, 0, NULL, 0, fname, _countof(fname), NULL, 0);
|
||||
|
||||
BOOL result = FALSE;
|
||||
if (!_tcsicmp(fname, _T("svchost"))) {
|
||||
LPWSTR *p = argv;
|
||||
for (int i = 1; i < numArgs; i++) {
|
||||
if (!_tcsicmp(*(p++), _T("-k"))) {
|
||||
_tcscpy_s(lpGroupName, dwSize, *p);
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
BOOL result = FALSE;
|
||||
if (!_tcsicmp(fname, _T("svchost"))) {
|
||||
LPWSTR *p = argv;
|
||||
for (int i = 1; i < numArgs; i++) {
|
||||
if (!_tcsicmp(*(p++), _T("-k"))) {
|
||||
_tcscpy_s(lpGroupName, dwSize, *p);
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwProcessId) {
|
||||
DWORD uBytes = 0x100000;
|
||||
LPBYTE pvData = malloc(uBytes);
|
||||
DWORD uBytes = 0x100000;
|
||||
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);
|
||||
|
||||
BOOL result = FALSE;
|
||||
for (LPTSTR p = (LPTSTR)pvData; *p; p += _tcslen(p) + 1) {
|
||||
DWORD dwProcessId;
|
||||
TCHAR group[256];
|
||||
if (get_svcpid(hSCManager, p, &dwProcessId)) {
|
||||
get_svcgname(hSCManager, p, group, _countof(group));
|
||||
result = !_tcsicmp(group, lpServiceGroupName);
|
||||
}
|
||||
if (result) {
|
||||
*lpdwProcessId = dwProcessId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(pvData);
|
||||
return result;
|
||||
BOOL result = FALSE;
|
||||
for (LPTSTR p = (LPTSTR)pvData; *p; p += _tcslen(p) + 1) {
|
||||
DWORD dwProcessId;
|
||||
TCHAR group[256];
|
||||
if (get_svcpid(hSCManager, p, &dwProcessId)) {
|
||||
get_svcgname(hSCManager, p, group, _countof(group));
|
||||
result = !_tcsicmp(group, lpServiceGroupName);
|
||||
}
|
||||
if (result) {
|
||||
*lpdwProcessId = dwProcessId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(pvData);
|
||||
return result;
|
||||
}
|
||||
|
236
wufuc/util.c
236
wufuc/util.c
@@ -6,161 +6,161 @@
|
||||
#include "util.h"
|
||||
|
||||
BOOL IsWindows7Or8Point1(void) {
|
||||
return IsWindows7() || IsWindows8Point1();
|
||||
return IsWindows7() || IsWindows8Point1();
|
||||
}
|
||||
|
||||
BOOL IsWindows7(void) {
|
||||
return IsWindows7OrGreater() && !IsWindows8OrGreater();
|
||||
return IsWindows7OrGreater() && !IsWindows8OrGreater();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
_dbgprintf("%s %p => %p", lpFuncName, *lpAddress, lpNewAddress);
|
||||
*lpAddress = lpNewAddress;
|
||||
VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect);
|
||||
DWORD flOldProtect;
|
||||
DWORD flNewProtect = PAGE_READWRITE;
|
||||
VirtualProtect(lpAddress, sizeof(LPVOID), flNewProtect, &flOldProtect);
|
||||
if (lpOldAddress) {
|
||||
*lpOldAddress = *lpAddress;
|
||||
}
|
||||
_dbgprintf("%s %p => %p", lpFuncName, *lpAddress, lpNewAddress);
|
||||
*lpAddress = lpNewAddress;
|
||||
VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect);
|
||||
}
|
||||
|
||||
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFunctionName) {
|
||||
SIZE_T hm = (SIZE_T)hModule;
|
||||
SIZE_T hm = (SIZE_T)hModule;
|
||||
|
||||
for (PIMAGE_IMPORT_DESCRIPTOR iid = (PIMAGE_IMPORT_DESCRIPTOR)(hm +
|
||||
((PIMAGE_NT_HEADERS)(hm + ((PIMAGE_DOS_HEADER)hm)->e_lfanew))->OptionalHeader
|
||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
|
||||
.VirtualAddress); iid->Name; iid++) {
|
||||
for (PIMAGE_IMPORT_DESCRIPTOR iid = (PIMAGE_IMPORT_DESCRIPTOR)(hm +
|
||||
((PIMAGE_NT_HEADERS)(hm + ((PIMAGE_DOS_HEADER)hm)->e_lfanew))->OptionalHeader
|
||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
|
||||
.VirtualAddress); iid->Name; iid++) {
|
||||
|
||||
LPVOID *p;
|
||||
for (SIZE_T i = 0; *(p = i + (LPVOID *)(hm + iid->FirstThunk)); i++) {
|
||||
LPSTR fn = (LPSTR)(hm + *(i + (SIZE_T *)(hm + iid->OriginalFirstThunk)) + 2);
|
||||
if (!((uintptr_t)fn & IMAGE_ORDINAL_FLAG) && !_stricmp(lpFunctionName, fn)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
LPVOID *p;
|
||||
for (SIZE_T i = 0; *(p = i + (LPVOID *)(hm + iid->FirstThunk)); i++) {
|
||||
LPSTR fn = (LPSTR)(hm + *(i + (SIZE_T *)(hm + iid->OriginalFirstThunk)) + 2);
|
||||
if (!((uintptr_t)fn & IMAGE_ORDINAL_FLAG) && !_stricmp(lpFunctionName, fn)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL FindPattern(LPCBYTE pvData, SIZE_T nNumberOfBytes, LPSTR lpszPattern, SIZE_T nStart, SIZE_T *lpOffset) {
|
||||
SIZE_T length = strlen(lpszPattern);
|
||||
SIZE_T nBytes;
|
||||
if (length % 2 || (nBytes = length / 2) > nNumberOfBytes) {
|
||||
return FALSE;
|
||||
}
|
||||
SIZE_T length = strlen(lpszPattern);
|
||||
SIZE_T nBytes;
|
||||
if (length % 2 || (nBytes = length / 2) > nNumberOfBytes) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LPBYTE lpBytes = malloc(nBytes * sizeof(BYTE));
|
||||
BOOL *lpbwc = malloc(nBytes * sizeof(BOOL));
|
||||
LPBYTE lpBytes = malloc(nBytes * sizeof(BYTE));
|
||||
BOOL *lpbwc = malloc(nBytes * sizeof(BOOL));
|
||||
|
||||
LPSTR p = lpszPattern;
|
||||
BOOL valid = TRUE;
|
||||
for (SIZE_T i = 0; i < nBytes; i++) {
|
||||
if ((lpbwc[i] = strncmp(p, "??", 2)) && sscanf_s(p, "%2hhx", &lpBytes[i]) != 1) {
|
||||
valid = FALSE;
|
||||
break;
|
||||
}
|
||||
p += 2;
|
||||
}
|
||||
BOOL result = FALSE;
|
||||
if (valid) {
|
||||
for (SIZE_T i = nStart; i < nNumberOfBytes - nStart - (nBytes - 1); i++) {
|
||||
BOOL found = TRUE;
|
||||
for (SIZE_T j = 0; j < nBytes; j++) {
|
||||
if (lpbwc[j] && pvData[i + j] != lpBytes[j]) {
|
||||
found = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
*lpOffset = i;
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(lpBytes);
|
||||
free(lpbwc);
|
||||
return result;
|
||||
LPSTR p = lpszPattern;
|
||||
BOOL valid = TRUE;
|
||||
for (SIZE_T i = 0; i < nBytes; i++) {
|
||||
if ((lpbwc[i] = strncmp(p, "??", 2)) && sscanf_s(p, "%2hhx", &lpBytes[i]) != 1) {
|
||||
valid = FALSE;
|
||||
break;
|
||||
}
|
||||
p += 2;
|
||||
}
|
||||
BOOL result = FALSE;
|
||||
if (valid) {
|
||||
for (SIZE_T i = nStart; i < nNumberOfBytes - nStart - (nBytes - 1); i++) {
|
||||
BOOL found = TRUE;
|
||||
for (SIZE_T j = 0; j < nBytes; j++) {
|
||||
if (lpbwc[j] && pvData[i + j] != lpBytes[j]) {
|
||||
found = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
*lpOffset = i;
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(lpBytes);
|
||||
free(lpbwc);
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||||
THREADENTRY32 te;
|
||||
te.dwSize = sizeof(te);
|
||||
Thread32First(hSnap, &te);
|
||||
|
||||
SIZE_T count = 0;
|
||||
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);
|
||||
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."));
|
||||
*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."));
|
||||
for (SIZE_T i = 0; i < cb; i++) {
|
||||
ResumeThread(lphThreads[i]);
|
||||
CloseHandle(lphThreads[i]);
|
||||
}
|
||||
_tdbgprintf(_T("Resumed threads."));
|
||||
}
|
||||
|
||||
VOID _wdbgprintf(LPCWSTR format, ...) {
|
||||
WCHAR buffer[0x1000];
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
vswprintf_s(buffer, _countof(buffer), format, argptr);
|
||||
va_end(argptr);
|
||||
OutputDebugStringW(buffer);
|
||||
WCHAR buffer[0x1000];
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
vswprintf_s(buffer, _countof(buffer), format, argptr);
|
||||
va_end(argptr);
|
||||
OutputDebugStringW(buffer);
|
||||
}
|
||||
|
||||
VOID _dbgprintf(LPCSTR format, ...) {
|
||||
CHAR buffer[0x1000];
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
vsprintf_s(buffer, _countof(buffer), format, argptr);
|
||||
va_end(argptr);
|
||||
OutputDebugStringA(buffer);
|
||||
CHAR buffer[0x1000];
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
vsprintf_s(buffer, _countof(buffer), format, argptr);
|
||||
va_end(argptr);
|
||||
OutputDebugStringA(buffer);
|
||||
}
|
||||
|
@@ -39,4 +39,3 @@ VOID _dbgprintf(LPCSTR format, ...);
|
||||
//#else
|
||||
//#define _tdbgprintf(format, ...)
|
||||
//#endif // !_DEBUG
|
||||
|
||||
|
Reference in New Issue
Block a user