port new code from other projects, minor fixes, bump ver

This commit is contained in:
zeffy
2017-08-17 15:49:44 -07:00
parent 370fe4b242
commit 5d99c1481f
19 changed files with 475 additions and 445 deletions

View File

@@ -1,4 +1,4 @@
version: 0.7.1.{build} version: 0.7.2.{build}
skip_commits: skip_commits:
files: files:
- README.md - README.md

View File

@@ -1,16 +0,0 @@
#pragma once
DWORD WINAPI NewThreadProc(LPVOID lpParam);
BOOL PatchWU(HMODULE hModule);
HMODULE WINAPI _LoadLibraryExA(
_In_ LPCSTR lpFileName,
_Reserved_ HANDLE hFile,
_In_ DWORD dwFlags
);
HMODULE WINAPI _LoadLibraryExW(
_In_ LPCWSTR lpFileName,
_Reserved_ HANDLE hFile,
_In_ DWORD dwFlags
);

View File

@@ -1,20 +1,23 @@
#include <Windows.h> #include <Windows.h>
#include "core.h"
#include "util.h" #include "helpers.h"
#include "logging.h"
#include "hooks.h"
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) { switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
{ {
if (!IsOperatingSystemSupported() || IsWow64()) { if (!IsOperatingSystemSupported() || IsWow64())
return FALSE; return FALSE;
}
DisableThreadLibraryCalls(hModule); DisableThreadLibraryCalls(hModule);
HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL); HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL);
CloseHandle(hThread); CloseHandle(hThread);
break; break;
} }
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
logging_free();
break; break;
default: default:
break; break;

120
wufuc/helpers.c Normal file
View File

@@ -0,0 +1,120 @@
#include <Windows.h>
#include <stdint.h>
#include <tchar.h>
#include <TlHelp32.h>
#include <Psapi.h>
#include "logging.h"
#include "helpers.h"
static BOOL m_checkedIsWindows7 = FALSE;
static BOOL m_isWindows7 = FALSE;
static BOOL m_checkedIsWindows8Point1 = FALSE;
static BOOL m_isWindows8Point1 = FALSE;
static ISWOW64PROCESS fpIsWow64Process = NULL;
static BOOL m_checkedIsWow64 = FALSE;
static BOOL m_isWow64 = FALSE;
static TCHAR m_emod_basename[MAX_PATH];
BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask) {
OSVERSIONINFOEX osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
osvi.dwMajorVersion = dwMajorVersion;
osvi.dwMinorVersion = dwMinorVersion;
osvi.wServicePackMajor = wServicePackMajor;
osvi.wServicePackMinor = wServicePackMinor;
DWORDLONG dwlConditionMask = 0;
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, Operator);
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, Operator);
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, Operator);
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMINOR, Operator);
return VerifyVersionInfo(&osvi, dwTypeMask, dwlConditionMask);
}
BOOL IsWindows7(void) {
if (!m_checkedIsWindows7) {
m_isWindows7 = CompareWindowsVersion(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION);
m_checkedIsWindows7 = TRUE;
}
return m_isWindows7;
}
BOOL IsWindows8Point1(void) {
if (!m_checkedIsWindows8Point1) {
m_isWindows8Point1 = CompareWindowsVersion(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION);
m_checkedIsWindows8Point1 = TRUE;
}
return m_isWindows8Point1;
}
BOOL IsOperatingSystemSupported(void) {
#if !defined(_AMD64_) && !defined(_X86_)
return FALSE;
#else
return IsWindows7() || IsWindows8Point1();
#endif
}
BOOL IsWow64(void) {
if (!m_checkedIsWow64) {
if (!fpIsWow64Process)
fpIsWow64Process = (ISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "IsWow64Process");
if (fpIsWow64Process && fpIsWow64Process(GetCurrentProcess(), &m_isWow64))
m_checkedIsWow64 = TRUE;
}
return m_isWow64;
}
VOID suspend_other_threads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb) {
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
THREADENTRY32 te;
ZeroMemory(&te, sizeof(THREADENTRY32));
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;
trace(L"Suspended %d other threads", count);
}
VOID resume_and_close_threads(LPHANDLE lphThreads, SIZE_T cb) {
for (SIZE_T i = 0; i < cb; i++) {
ResumeThread(lphThreads[i]);
CloseHandle(lphThreads[i]);
}
trace(L"Resumed %d threads", cb);
}
void get_cpuid_brand(char *brand) {
int info[4];
__cpuidex(info, 0x80000000, 0);
if (info[0] < 0x80000004) {
brand[0] = '\0';
return;
}
uint32_t *char_as_int = (uint32_t *)brand;
for (int op = 0x80000002; op <= 0x80000004; op++) {
__cpuidex(info, op, 0);
*(char_as_int++) = info[0];
*(char_as_int++) = info[1];
*(char_as_int++) = info[2];
*(char_as_int++) = info[3];
}
}

19
wufuc/helpers.h Normal file
View File

@@ -0,0 +1,19 @@
#pragma once
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
typedef BOOL(WINAPI *ISWOW64PROCESS)(HANDLE, PBOOL);
BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask);
BOOL IsWindows7(void);
BOOL IsWindows8Point1(void);
BOOL IsOperatingSystemSupported(void);
BOOL IsWow64(void);
VOID suspend_other_threads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb);
VOID resume_and_close_threads(LPHANDLE lphThreads, SIZE_T dwSize);
void get_cpuid_brand(char *brand);
#define STRINGIZE_(x) #x
#define STRINGIZE(x) STRINGIZE_(x)

View File

@@ -3,10 +3,16 @@
#include <tchar.h> #include <tchar.h>
#include <Psapi.h> #include <Psapi.h>
#include <sddl.h> #include <sddl.h>
#include "helpers.h"
#include "logging.h"
#include "service.h" #include "service.h"
#include "iathook.h"
#include "patternfind.h" #include "patternfind.h"
#include "util.h" #include "hooks.h"
#include "core.h"
LOADLIBRARYEXW fpLoadLibraryExW = NULL;
LOADLIBRARYEXA fpLoadLibraryExA = NULL;
DWORD WINAPI NewThreadProc(LPVOID lpParam) { 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);
@@ -15,63 +21,85 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) {
get_svcpath(hSCManager, _T("wuauserv"), lpBinaryPathName, _countof(lpBinaryPathName)); get_svcpath(hSCManager, _T("wuauserv"), lpBinaryPathName, _countof(lpBinaryPathName));
CloseServiceHandle(hSCManager); CloseServiceHandle(hSCManager);
BOOL result = _tcsicmp(GetCommandLine(), lpBinaryPathName); if (_tcsicmp(GetCommandLine(), lpBinaryPathName))
if (result) {
return 0; return 0;
}
SECURITY_ATTRIBUTES sa; SECURITY_ATTRIBUTES sa = { 0 };
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.nLength = sizeof(SECURITY_ATTRIBUTES);
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, TRUE, 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 dwProcessId = GetCurrentProcessId();
DWORD dwThreadId = GetCurrentThreadId(); DWORD dwThreadId = GetCurrentThreadId();
HANDLE lphThreads[0x1000]; HANDLE lphThreads[0x1000];
SIZE_T cb; SIZE_T count;
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb); suspend_other_threads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &count);
HMODULE hm = GetModuleHandle(NULL); HMODULE hm = GetModuleHandle(NULL);
DETOUR_IAT(hm, LoadLibraryExA); iat_hook(hm, "LoadLibraryExA", (LPVOID)&fpLoadLibraryExA, LoadLibraryExA_hook);
DETOUR_IAT(hm, LoadLibraryExW); iat_hook(hm, "LoadLibraryExW", (LPVOID)&fpLoadLibraryExW, LoadLibraryExW_hook);
HMODULE hwu = GetModuleHandle(get_wuauservdll()); HMODULE hwu = GetModuleHandle(get_wuauservdll());
if (hwu && PatchWU(hwu)) { if (hwu && PatchWUA(hwu))
dwprintf(L"Patched previously loaded Windows Update module!"); trace(L"Successfully patched previously loaded WUA module!");
}
ResumeAndCloseThreads(lphThreads, cb); resume_and_close_threads(lphThreads, count);
WaitForSingleObject(hEvent, INFINITE); WaitForSingleObject(hEvent, INFINITE);
trace(L"Unloading...");
dwprintf(L"Unloading..."); suspend_other_threads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &count);
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb); iat_hook(hm, "LoadLibraryExA", NULL, fpLoadLibraryExA);
RESTORE_IAT(hm, LoadLibraryExA); iat_hook(hm, "LoadLibraryExW", NULL, fpLoadLibraryExW);
RESTORE_IAT(hm, LoadLibraryExW);
ResumeAndCloseThreads(lphThreads, cb);
resume_and_close_threads(lphThreads, count);
trace(L"Bye bye!");
CloseHandle(hEvent); CloseHandle(hEvent);
dwprintf(L"Bye bye!");
close_log();
FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0); FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0);
} }
BOOL PatchWU(HMODULE hModule) { HMODULE WINAPI LoadLibraryExA_hook(
_In_ LPCSTR lpFileName,
_Reserved_ HANDLE hFile,
_In_ DWORD dwFlags
) {
HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags);
if (result) {
trace(L"Loaded library: %S", lpFileName);
if (!_stricmp(lpFileName, get_wuauservdllA()) && PatchWUA(result))
trace(L"Successfully patched WUA module!");
}
return result;
}
HMODULE WINAPI LoadLibraryExW_hook(
_In_ LPCWSTR lpFileName,
_Reserved_ HANDLE hFile,
_In_ DWORD dwFlags
) {
HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags);
if (result) {
trace(L"Loaded library: %s", lpFileName);
if (!_wcsicmp(lpFileName, get_wuauservdllW()) && PatchWUA(result))
trace(L"Successfully patched WUA module!");
}
return result;
};
BOOL PatchWUA(HMODULE hModule) {
LPSTR pattern; LPSTR pattern;
SIZE_T offset00, offset01; SIZE_T offset00, offset01;
#ifdef _AMD64_ #ifdef _AMD64_
pattern = "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????"; pattern = "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????";
offset00 = 10; offset00 = 10;
offset01 = 18; offset01 = 18;
#elif defined(_X86_) #elif defined(_X86_)
if (IsWindows7()) { if (IsWindows7()) {
pattern = "833D????????00 743E E8???????? A3????????"; pattern = "833D????????00 743E E8???????? A3????????";
@@ -81,71 +109,37 @@ BOOL PatchWU(HMODULE hModule) {
pattern = "8BFF 51 833D????????00 7507 A1????????"; pattern = "8BFF 51 833D????????00 7507 A1????????";
offset00 = 5; offset00 = 5;
offset01 = 13; offset01 = 13;
} else {
return FALSE;
} }
#endif #endif
MODULEINFO modinfo; MODULEINFO modinfo;
GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO)); GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO));
SIZE_T rva = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage, 0, pattern); LPBYTE ptr = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage, 0, pattern);
if (rva == -1) { if (!ptr) {
dwprintf(L"No pattern match!"); trace(L"No pattern match!");
return FALSE; return FALSE;
} }
uintptr_t baseAddress = (uintptr_t)modinfo.lpBaseOfDll; trace(L"wuaueng!IsDeviceServiceable VA: %p", ptr);
uintptr_t lpfnIsDeviceServiceable = baseAddress + rva;
dwprintf(L"Address of wuaueng.dll!IsDeviceServiceable: %p", lpfnIsDeviceServiceable);
BOOL result = FALSE; BOOL result = FALSE;
LPBOOL lpbFirstRun, lpbIsCPUSupportedResult; LPBOOL lpbFirstRun, lpbIsCPUSupportedResult;
#ifdef _AMD64_ #ifdef _AMD64_
lpbFirstRun = (LPBOOL)(lpfnIsDeviceServiceable + offset00 + sizeof(uint32_t) + *(uint32_t *)(lpfnIsDeviceServiceable + offset00)); lpbFirstRun = (LPBOOL)(ptr + offset00 + sizeof(uint32_t) + *(uint32_t *)(ptr + offset00));
lpbIsCPUSupportedResult = (LPBOOL)(lpfnIsDeviceServiceable + offset01 + sizeof(uint32_t) + *(uint32_t *)(lpfnIsDeviceServiceable + offset01)); lpbIsCPUSupportedResult = (LPBOOL)(ptr + offset01 + sizeof(uint32_t) + *(uint32_t *)(ptr + offset01));
#elif defined(_X86_) #elif defined(_X86_)
lpbFirstRun = (LPBOOL)(*(uintptr_t *)(lpfnIsDeviceServiceable + offset00)); lpbFirstRun = (LPBOOL)(*(uintptr_t *)(ptr + offset00));
lpbIsCPUSupportedResult = (LPBOOL)(*(uintptr_t *)(lpfnIsDeviceServiceable + offset01)); lpbIsCPUSupportedResult = (LPBOOL)(*(uintptr_t *)(ptr + offset01));
#endif #endif
if (*lpbFirstRun) { if (*lpbFirstRun) {
*lpbFirstRun = FALSE; *lpbFirstRun = FALSE;
dwprintf(L"Patched FirstRun variable: %p = %08x", lpbFirstRun, *lpbFirstRun); trace(L"Patched boolean value #1: %p = %08x", lpbFirstRun, *lpbFirstRun);
result = TRUE; result = TRUE;
} }
if (!*lpbIsCPUSupportedResult) { if (!*lpbIsCPUSupportedResult) {
*lpbIsCPUSupportedResult = TRUE; *lpbIsCPUSupportedResult = TRUE;
dwprintf(L"Patched cached wuaueng.dll!IsCPUSupported result: %p = %08x", lpbIsCPUSupportedResult, *lpbIsCPUSupportedResult); trace(L"Patched boolean value #2: %p = %08x", lpbIsCPUSupportedResult, *lpbIsCPUSupportedResult);
result = TRUE; result = TRUE;
} }
return result; return result;
} }
HMODULE WINAPI _LoadLibraryExA(
_In_ LPCSTR lpFileName,
_Reserved_ HANDLE hFile,
_In_ DWORD dwFlags
) {
HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags);
if (result) {
dwprintf(L"Loaded library: %S", lpFileName);
if (!_stricmp(lpFileName, get_wuauservdllA()) && PatchWU(result)) {
dwprintf(L"Patched Windows Update module!");
}
}
return result;
}
HMODULE WINAPI _LoadLibraryExW(
_In_ LPCWSTR lpFileName,
_Reserved_ HANDLE hFile,
_In_ DWORD dwFlags
) {
HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags);
if (result) {
dwprintf(L"Loaded library: %s", lpFileName);
if (!_wcsicmp(lpFileName, get_wuauservdllW()) && PatchWU(result)) {
dwprintf(L"Patched Windows Update module!");
}
}
return result;
};

23
wufuc/hooks.h Normal file
View File

@@ -0,0 +1,23 @@
#pragma once
typedef HMODULE(WINAPI *LOADLIBRARYEXA)(LPCSTR, HANDLE, DWORD);
typedef HMODULE(WINAPI *LOADLIBRARYEXW)(LPCWSTR, HANDLE, DWORD);
extern LOADLIBRARYEXW fpLoadLibraryExW;
extern LOADLIBRARYEXA fpLoadLibraryExA;
DWORD WINAPI NewThreadProc(LPVOID lpParam);
HMODULE WINAPI LoadLibraryExA_hook(
_In_ LPCSTR lpFileName,
_Reserved_ HANDLE hFile,
_In_ DWORD dwFlags
);
HMODULE WINAPI LoadLibraryExW_hook(
_In_ LPCWSTR lpFileName,
_Reserved_ HANDLE hFile,
_In_ DWORD dwFlags
);
BOOL PatchWUA(HMODULE hModule);

39
wufuc/iathook.c Normal file
View File

@@ -0,0 +1,39 @@
#include <Windows.h>
#include "logging.h"
#include "iathook.h"
VOID iat_hook(HMODULE hModule, LPCSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress) {
LPVOID *lpAddress = iat_find(hModule, lpFuncName);
if (!lpAddress || *lpAddress == lpNewAddress)
return;
if (!hModule)
hModule = GetModuleHandle(NULL);
trace(L"Modified import address: hmod=%p, import=%S, old addr=%p, new addr=%p", hModule, lpFuncName, *lpAddress, lpNewAddress);
DWORD flOldProtect;
DWORD flNewProtect = PAGE_READWRITE;
VirtualProtect(lpAddress, sizeof(LPVOID), flNewProtect, &flOldProtect);
if (lpOldAddress)
*lpOldAddress = *lpAddress;
*lpAddress = lpNewAddress;
VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect);
}
static LPVOID *iat_find(HMODULE hModule, LPCSTR lpFunctionName) {
uintptr_t hm = (uintptr_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++) {
LPVOID *pp;
for (SIZE_T i = 0; *(pp = 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 pp;
}
}
return NULL;
}

5
wufuc/iathook.h Normal file
View File

@@ -0,0 +1,5 @@
#pragma once
VOID iat_hook(HMODULE hModule, LPCSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress);
static LPVOID *iat_find(HMODULE hModule, LPCSTR lpFunctionName);

53
wufuc/logging.c Normal file
View File

@@ -0,0 +1,53 @@
#include <Windows.h>
#include <stdio.h>
#include <time.h>
#include <tchar.h>
#include <Psapi.h>
#include "helpers.h"
#include "logging.h"
static FILE *fp;
static BOOL logging_enabled = FALSE;
BOOL logging_init(void) {
if (fp)
return TRUE;
WCHAR filename[MAX_PATH];
GetModuleFileNameW(HINST_THISCOMPONENT, filename, _countof(filename));
WCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME];
_wsplitpath_s(filename, drive, _countof(drive), dir, _countof(dir), fname, _countof(fname), NULL, 0);
WCHAR basename[MAX_PATH];
GetModuleBaseNameW(GetCurrentProcess(), NULL, basename, _countof(basename));
wcscat_s(fname, _countof(fname), L".");
wcscat_s(fname, _countof(fname), basename);
_wmakepath_s(filename, _countof(filename), drive, dir, fname, L".log");
HANDLE hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
LARGE_INTEGER size;
GetFileSizeEx(hFile, &size);
CloseHandle(hFile);
fp = _wfsopen(filename, size.QuadPart < (1 << 20) ? L"at" : L"wt", _SH_DENYWR);
return (fp != NULL);
}
VOID trace_(LPCWSTR format, ...) {
if (logging_init()) {
WCHAR datebuf[9], timebuf[9];
_wstrdate_s(datebuf, _countof(datebuf));
_wstrtime_s(timebuf, _countof(timebuf));
fwprintf_s(fp, L"%s %s [%d] ", datebuf, timebuf, GetCurrentProcessId());
va_list argptr;
va_start(argptr, format);
vfwprintf_s(fp, format, argptr);
va_end(argptr);
fflush(fp);
}
}
BOOL logging_free(void) {
return fp && !fclose(fp);
}

13
wufuc/logging.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
BOOL logging_init(void);
VOID trace_(LPCWSTR format, ...);
BOOL logging_free(void);
#define STRINGIZE_(x) #x
#define STRINGIZE(x) STRINGIZE_(x)
#define STRINGIZEW_(x) L#x
#define STRINGIZEW(x) STRINGIZEW_(x)
#define __LINEWSTR__ STRINGIZEW(__LINE__)
#define trace(format, ...) trace_(__FILEW__ L":" __LINEWSTR__ L"(" __FUNCTIONW__ L"): " format L"\n", ##__VA_ARGS__)

View File

@@ -1,32 +1,32 @@
#include <Windows.h> #include <Windows.h>
#include "patternfind.h" #include "patternfind.h"
/* Ported to C from x64dbg's patternfind.cpp: /* Ported to C from x64dbg's patternfind.cpp:
<https://github.com/x64dbg/x64dbg/blob/development/src/dbg/patternfind.cpp> * https://github.com/x64dbg/x64dbg/blob/development/src/dbg/patternfind.cpp
* x64dbg license (GPL-3.0):
* https://github.com/x64dbg/x64dbg/blob/development/LICENSE>
*/
x64dbg license (GPL-3.0): int hexchtoint(CHAR c) {
<https://github.com/x64dbg/x64dbg/blob/development/LICENSE> */
static int hexchtoint(CHAR c) {
int result = -1; int result = -1;
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9')
result = c - '0'; result = c - '0';
} else if (c >= 'A' && c <= 'F') { else if (c >= 'A' && c <= 'F')
result = c - 'A' + 10; result = c - 'A' + 10;
} else if (c >= 'a' && c <= 'f') { else if (c >= 'a' && c <= 'f')
result = c - 'a' + 10; result = c - 'a' + 10;
}
return result; return result;
} }
static SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T formattextsize) { SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T formattextsize) {
SIZE_T len = strlen(patterntext); SIZE_T len = strlen(patterntext);
SIZE_T result = 0; SIZE_T result = 0;
for (SIZE_T i = 0; i < len && (!formattext || result < formattextsize); i++) { for (SIZE_T i = 0; i < len && (!formattext || result < formattextsize); i++) {
if (patterntext[i] == '?' || hexchtoint(patterntext[i]) != -1) { if (patterntext[i] == '?' || hexchtoint(patterntext[i]) != -1) {
if (formattext) { if (formattext)
formattext[result] = patterntext[i]; formattext[result] = patterntext[i];
}
result++; result++;
} }
} }
@@ -35,21 +35,21 @@ static SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T form
BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *patternsize) { BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *patternsize) {
SIZE_T cb = formathexpattern(patterntext, NULL, 0); SIZE_T cb = formathexpattern(patterntext, NULL, 0);
if (!cb || cb > *patternsize) { if (!cb || cb > *patternsize)
return FALSE; return FALSE;
}
LPSTR formattext = calloc(cb, sizeof(CHAR)); LPSTR formattext = calloc(cb, sizeof(CHAR));
cb = formathexpattern(patterntext, formattext, cb); cb = formathexpattern(patterntext, formattext, cb);
if (cb % 2) { if (cb % 2)
formattext[cb++] = '?'; formattext[cb++] = '?';
}
formattext[cb] = '\0'; formattext[cb] = '\0';
for (SIZE_T i = 0, j = 0, k = 0; i < cb; i++, j ^= 1, k = (i - j) >> 1) { for (SIZE_T i = 0, j = 0, k = 0; i < cb; i++, j ^= 1, k = (i - j) >> 1) {
if (formattext[i] == '?') { if (formattext[i] == '?')
pattern[k].nibble[j].wildcard = TRUE; pattern[k].nibble[j].wildcard = TRUE;
} else { else {
pattern[k].nibble[j].wildcard = FALSE; pattern[k].nibble[j].wildcard = FALSE;
pattern[k].nibble[j].data = hexchtoint(formattext[i]) & 0xf; pattern[k].nibble[j].data = hexchtoint(formattext[i]) & 0xf;
} }
@@ -59,19 +59,18 @@ BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *pattern
return TRUE; return TRUE;
} }
SIZE_T patternfind(LPCBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR pattern) { LPBYTE patternfind(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR pattern) {
SIZE_T result = -1; LPBYTE result = NULL;
SIZE_T searchpatternsize = strlen(pattern); SIZE_T searchpatternsize = strlen(pattern);
LPPATTERNBYTE searchpattern = calloc(searchpatternsize, sizeof(PATTERNBYTE)); LPPATTERNBYTE searchpattern = calloc(searchpatternsize, sizeof(PATTERNBYTE));
if (patterntransform(pattern, searchpattern, &searchpatternsize)) { if (patterntransform(pattern, searchpattern, &searchpatternsize)) {
for (SIZE_T i = startindex, j = 0; i < datasize; i++) //search for the pattern for (SIZE_T i = startindex, j = 0; i < datasize; i++) { //search for the pattern
{
if ((searchpattern[j].nibble[0].wildcard || searchpattern[j].nibble[0].data == ((data[i] >> 4) & 0xf)) if ((searchpattern[j].nibble[0].wildcard || searchpattern[j].nibble[0].data == ((data[i] >> 4) & 0xf))
&& (searchpattern[j].nibble[1].wildcard || searchpattern[j].nibble[1].data == (data[i] & 0xf))) { //check if our pattern matches the current byte && (searchpattern[j].nibble[1].wildcard || searchpattern[j].nibble[1].data == (data[i] & 0xf))) { //check if our pattern matches the current byte
if (++j == searchpatternsize) { //everything matched if (++j == searchpatternsize) { //everything matched
result = i - searchpatternsize + 1; result = data + (i - searchpatternsize + 1);
break; break;
} }
} else if (j > 0) { //fix by Computer_Angel } else if (j > 0) { //fix by Computer_Angel
@@ -87,33 +86,50 @@ SIZE_T patternfind(LPCBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR patt
VOID patternwritebyte(LPBYTE byte, LPPATTERNBYTE pbyte) { VOID patternwritebyte(LPBYTE byte, LPPATTERNBYTE pbyte) {
BYTE n1 = (*byte >> 4) & 0xf; BYTE n1 = (*byte >> 4) & 0xf;
BYTE n2 = *byte & 0xf; BYTE n2 = *byte & 0xf;
if (!pbyte->nibble[0].wildcard) { if (!pbyte->nibble[0].wildcard)
n1 = pbyte->nibble[0].data; n1 = pbyte->nibble[0].data;
}
if (!pbyte->nibble[1].wildcard) { if (!pbyte->nibble[1].wildcard)
n2 = pbyte->nibble[1].data; n2 = pbyte->nibble[1].data;
}
*byte = ((n1 << 4) & 0xf0) | (n2 & 0xf); *byte = ((n1 << 4) & 0xf0) | (n2 & 0xf);
} }
VOID patternwrite(LPBYTE data, SIZE_T datasize, LPCSTR pattern) { BOOL patternwrite(LPBYTE data, SIZE_T datasize, LPCSTR pattern) {
SIZE_T writepatternsize = strlen(pattern); SIZE_T writepatternsize = strlen(pattern);
if (writepatternsize > datasize) { if (writepatternsize > datasize)
writepatternsize = datasize; writepatternsize = datasize;
}
BOOL result = FALSE;
LPPATTERNBYTE writepattern = calloc(writepatternsize, sizeof(PATTERNBYTE)); LPPATTERNBYTE writepattern = calloc(writepatternsize, sizeof(PATTERNBYTE));
if (patterntransform(pattern, writepattern, &writepatternsize)) { if (patterntransform(pattern, writepattern, &writepatternsize)) {
for (size_t i = 0; i < writepatternsize; i++) { DWORD flNewProtect = PAGE_READWRITE;
patternwritebyte(&data[i], &writepattern[i]); DWORD flOldProtect;
if (VirtualProtect(data, writepatternsize, flNewProtect, &flOldProtect)) {
for (size_t i = 0; i < writepatternsize; i++) {
BYTE n1 = (data[i] >> 4) & 0xf;
BYTE n2 = data[i] & 0xf;
if (!writepattern[i].nibble[0].wildcard)
n1 = writepattern[i].nibble[0].data;
if (!writepattern[i].nibble[1].wildcard)
n2 = writepattern[i].nibble[1].data;
data[i] = ((n1 << 4) & 0xf0) | (n2 & 0xf);
}
result = VirtualProtect(data, writepatternsize, flOldProtect, &flNewProtect);
} }
} }
free(writepattern); free(writepattern);
} return result;
}
SIZE_T patternsnr(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR searchpattern, LPCSTR replacepattern) {
SIZE_T result = patternfind(data, datasize, startindex, searchpattern); LPBYTE patternsnr(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR searchpattern, LPCSTR replacepattern) {
if (result == -1) LPBYTE result = patternfind(data, datasize, startindex, searchpattern);
return result; if (result == NULL)
patternwrite(data + result, datasize - result, replacepattern); return result;
patternwrite(result, datasize, replacepattern);
return result; return result;
} }

View File

@@ -10,7 +10,7 @@ typedef struct _PATTERNBYTE {
int hexchtoint(CHAR ch); int hexchtoint(CHAR ch);
SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T formattextsize); SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T formattextsize);
BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *patternsize); BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *patternsize);
SIZE_T patternfind(LPCBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR pattern); LPBYTE patternfind(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR pattern);
VOID patternwritebyte(LPBYTE byte, LPPATTERNBYTE pbyte); VOID patternwritebyte(LPBYTE byte, LPPATTERNBYTE pbyte);
VOID patternwrite(LPBYTE data, SIZE_T datasize, LPCSTR pattern); BOOL patternwrite(LPBYTE data, SIZE_T datasize, LPCSTR pattern);
SIZE_T patternsnr(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR searchpattern, LPCSTR replacepattern); LPBYTE patternsnr(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR searchpattern, LPCSTR replacepattern);

View File

@@ -2,8 +2,10 @@
#include <TlHelp32.h> #include <TlHelp32.h>
#include <tchar.h> #include <tchar.h>
#include <VersionHelpers.h> #include <VersionHelpers.h>
#include "helpers.h"
#include "logging.h"
#include "service.h" #include "service.h"
#include "util.h"
void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
HANDLE hEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("Global\\wufuc_UnloadEvent")); HANDLE hEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("Global\\wufuc_UnloadEvent"));
@@ -14,74 +16,72 @@ void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int n
LPWSTR osname; LPWSTR osname;
if (IsWindows7()) { if (IsWindows7()) {
if (IsWindowsServer()) { if (IsWindowsServer())
osname = L"Windows Server 2008 R2"; osname = L"Windows Server 2008 R2";
} else { else
osname = L"Windows 7"; osname = L"Windows 7";
}
} else if (IsWindows8Point1()) { } else if (IsWindows8Point1()) {
if (IsWindowsServer()) { if (IsWindowsServer())
osname = L"Windows Server 2012 R2"; osname = L"Windows Server 2012 R2";
} else { else
osname = L"Windows 8.1"; osname = L"Windows 8.1";
}
} }
dwprintf(L"Operating System: %s %d-bit", osname, sizeof(uintptr_t) * 8); trace(L"Operating System: %s %d-bit", osname, sizeof(uintptr_t) * 8);
char brand[0x31]; char brand[0x31];
get_cpuid_brand(brand); get_cpuid_brand(brand);
SIZE_T i = 0; SIZE_T i = 0;
while (i < _countof(brand) && isspace(*(brand + i))) { while (i < _countof(brand) && isspace(*(brand + i)))
i++; i++;
}
dwprintf(L"Processor: %S", brand + i); trace(L"Processor: %S", brand + i);
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
if (!hSCManager) { if (!hSCManager)
return; return;
}
TCHAR lpGroupName[256]; TCHAR lpGroupName[256];
DWORD dwProcessId; DWORD dwProcessId;
BOOL result = get_svcpid(hSCManager, _T("wuauserv"), &dwProcessId); BOOL result = get_svcpid(hSCManager, _T("wuauserv"), &dwProcessId);
if (!result && get_svcgname(hSCManager, _T("wuauserv"), lpGroupName, _countof(lpGroupName))) { if (!result && get_svcgname(hSCManager, _T("wuauserv"), lpGroupName, _countof(lpGroupName)))
result = get_svcgpid(hSCManager, lpGroupName, &dwProcessId); result = get_svcgpid(hSCManager, lpGroupName, &dwProcessId);
}
CloseServiceHandle(hSCManager); CloseServiceHandle(hSCManager);
if (!result) { if (!result)
return; return;
}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (!hProcess) { if (!hProcess)
return; return;
}
TCHAR lpLibFileName[MAX_PATH]; TCHAR lpLibFileName[MAX_PATH];
GetModuleFileName(HINST_THISCOMPONENT, lpLibFileName, _countof(lpLibFileName)); GetModuleFileName(HINST_THISCOMPONENT, lpLibFileName, _countof(lpLibFileName));
SIZE_T size = (_tcslen(lpLibFileName) + 1) * sizeof(TCHAR); SIZE_T size = (_tcslen(lpLibFileName) + 1) * sizeof(TCHAR);
LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (lpBaseAddress && WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, size, NULL)) { if (lpBaseAddress && WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, size, NULL)) {
HANDLE hThread = CreateRemoteThread(
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, hProcess,
(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32.dll"), NULL,
STRINGIZE(LoadLibrary)), 0,
lpBaseAddress, 0, NULL (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("kernel32.dll")),
STRINGIZE(LoadLibrary)),
lpBaseAddress,
0,
NULL
); );
WaitForSingleObject(hThread, INFINITE); WaitForSingleObject(hThread, INFINITE);
dwprintf(L"Injected into process: %d", dwProcessId); trace(L"Injected into process: %d", dwProcessId);
CloseHandle(hThread); CloseHandle(hThread);
} }
VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE); VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE);
CloseHandle(hProcess); CloseHandle(hProcess);
close_log();
} }
void CALLBACK Rundll32Unload(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { void CALLBACK Rundll32Unload(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, _T("Global\\wufuc_UnloadEvent")); HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, _T("Global\\wufuc_UnloadEvent"));
if (hEvent) { if (hEvent) {
dwprintf(L"Setting unload event..."); trace(L"Setting unload event...");
SetEvent(hEvent); SetEvent(hEvent);
CloseHandle(hEvent); CloseHandle(hEvent);
} }

View File

@@ -1,8 +1,10 @@
#include <windows.h> #include <windows.h>
#include <stdio.h> #include <stdio.h>
#include <tchar.h> #include <tchar.h>
#include "util.h"
#include "helpers.h"
#include "shellapihelper.h" #include "shellapihelper.h"
#include "logging.h"
#include "service.h" #include "service.h"
static CHAR wuauservdllA[MAX_PATH]; static CHAR wuauservdllA[MAX_PATH];
@@ -12,10 +14,10 @@ BOOL get_svcdllA(LPCSTR lpServiceName, LPSTR lpServiceDll, DWORD dwSize) {
CHAR lpSubKey[257]; CHAR lpSubKey[257];
sprintf_s(lpSubKey, _countof(lpSubKey), "SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", lpServiceName); sprintf_s(lpSubKey, _countof(lpSubKey), "SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", lpServiceName);
DWORD cb = dwSize; DWORD cb = dwSize;
if (RegGetValueA(HKEY_LOCAL_MACHINE, lpSubKey, "ServiceDll", RRF_RT_REG_SZ, NULL, lpServiceDll, &cb)) { if (RegGetValueA(HKEY_LOCAL_MACHINE, lpSubKey, "ServiceDll", RRF_RT_REG_SZ, NULL, lpServiceDll, &cb))
return FALSE; return FALSE;
}
dwprintf(L"Service \"%S\" DLL path: %S", lpServiceName, lpServiceDll); trace(L"Service \"%S\" DLL path: %S", lpServiceName, lpServiceDll);
return TRUE; return TRUE;
} }
@@ -23,32 +25,31 @@ BOOL get_svcdllW(LPCWSTR lpServiceName, LPWSTR lpServiceDll, DWORD dwSize) {
WCHAR lpSubKey[257]; WCHAR lpSubKey[257];
swprintf_s(lpSubKey, _countof(lpSubKey), L"SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", lpServiceName); swprintf_s(lpSubKey, _countof(lpSubKey), L"SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", lpServiceName);
DWORD cb = dwSize; DWORD cb = dwSize;
if (RegGetValueW(HKEY_LOCAL_MACHINE, lpSubKey, L"ServiceDll", RRF_RT_REG_SZ, NULL, lpServiceDll, &cb)) { if (RegGetValueW(HKEY_LOCAL_MACHINE, lpSubKey, L"ServiceDll", RRF_RT_REG_SZ, NULL, lpServiceDll, &cb))
return FALSE; return FALSE;
}
dwprintf(L"Service \"%s\" DLL path: %s", lpServiceName, lpServiceDll); trace(L"Service \"%s\" DLL path: %s", lpServiceName, lpServiceDll);
return TRUE; return TRUE;
} }
LPSTR get_wuauservdllA(void) { LPSTR get_wuauservdllA(void) {
if (wuauservdllA[0] == '\0') { if (!wuauservdllA[0])
get_svcdllA("wuauserv", wuauservdllA, _countof(wuauservdllA)); get_svcdllA("wuauserv", wuauservdllA, _countof(wuauservdllA));
}
return wuauservdllA; return wuauservdllA;
} }
LPWSTR get_wuauservdllW(void) { LPWSTR get_wuauservdllW(void) {
if (wuauservdllW[0] == L'\0') { if (!wuauservdllW[0])
get_svcdllW(L"wuauserv", wuauservdllW, _countof(wuauservdllW)); get_svcdllW(L"wuauserv", wuauservdllW, _countof(wuauservdllW));
}
return wuauservdllW; return wuauservdllW;
} }
BOOL get_svcpid(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;
}
SERVICE_STATUS_PROCESS lpBuffer; SERVICE_STATUS_PROCESS lpBuffer;
DWORD cbBytesNeeded; DWORD cbBytesNeeded;
@@ -58,9 +59,9 @@ BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessI
*lpdwProcessId = lpBuffer.dwProcessId; *lpdwProcessId = lpBuffer.dwProcessId;
#ifdef _UNICODE #ifdef _UNICODE
dwprintf(L"Service \"%s\" process ID: %d", lpServiceName, *lpdwProcessId); trace(L"Service \"%s\" process ID: %d", lpServiceName, *lpdwProcessId);
#else #else
dwprintf(L"Service \"%S\" process ID: %d", lpServiceName, *lpdwProcessId); trace(L"Service \"%S\" process ID: %d", lpServiceName, *lpdwProcessId);
#endif #endif
result = TRUE; result = TRUE;
} }
@@ -70,15 +71,13 @@ BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessI
BOOL get_svcgname(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 (!get_svcpath(hSCManager, lpServiceName, lpBinaryPathName, _countof(lpBinaryPathName))) { if (!get_svcpath(hSCManager, lpServiceName, lpBinaryPathName, _countof(lpBinaryPathName)))
return FALSE; return FALSE;
}
int numArgs; int numArgs;
LPWSTR *argv = CommandLineToArgv(lpBinaryPathName, &numArgs); LPWSTR *argv = CommandLineToArgv(lpBinaryPathName, &numArgs);
if (numArgs < 3) { if (numArgs < 3)
return FALSE; return FALSE;
}
TCHAR fname[_MAX_FNAME]; TCHAR fname[_MAX_FNAME];
_tsplitpath_s(argv[0], NULL, 0, NULL, 0, fname, _countof(fname), NULL, 0); _tsplitpath_s(argv[0], NULL, 0, NULL, 0, fname, _countof(fname), NULL, 0);
@@ -90,9 +89,9 @@ BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupNam
if (!_tcsicmp(*(p++), _T("-k")) && !_tcscpy_s(lpGroupName, dwSize, *p)) { if (!_tcsicmp(*(p++), _T("-k")) && !_tcscpy_s(lpGroupName, dwSize, *p)) {
result = TRUE; result = TRUE;
#ifdef _UNICODE #ifdef _UNICODE
dwprintf(L"Service \"%s\" group name: %s", lpServiceName, lpGroupName); trace(L"Service \"%s\" group name: %s", lpServiceName, lpGroupName);
#else #else
dwprintf(L"Service \"%S\" group name: %S", lpServiceName, lpGroupName); trace(L"Service \"%S\" group name: %S", lpServiceName, lpGroupName);
#endif #endif
break; break;
} }
@@ -103,16 +102,15 @@ BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupNam
BOOL get_svcpath(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;
}
DWORD cbBytesNeeded; DWORD cbBytesNeeded;
BOOL result = FALSE; BOOL result = FALSE;
if (!QueryServiceConfig(hService, NULL, 0, &cbBytesNeeded) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if (!QueryServiceConfig(hService, NULL, 0, &cbBytesNeeded) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
LPQUERY_SERVICE_CONFIG sc = malloc(cbBytesNeeded); LPQUERY_SERVICE_CONFIG sc = malloc(cbBytesNeeded);
if (QueryServiceConfig(hService, sc, cbBytesNeeded, &cbBytesNeeded) && !_tcscpy_s(lpBinaryPathName, dwSize, sc->lpBinaryPathName)) { if (QueryServiceConfig(hService, sc, cbBytesNeeded, &cbBytesNeeded) && !_tcscpy_s(lpBinaryPathName, dwSize, sc->lpBinaryPathName))
result = TRUE; result = TRUE;
}
free(sc); free(sc);
} }
CloseServiceHandle(hService); CloseServiceHandle(hService);
@@ -135,9 +133,9 @@ BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwPro
*lpdwProcessId = dwProcessId; *lpdwProcessId = dwProcessId;
result = TRUE; result = TRUE;
#ifdef _UNICODE #ifdef _UNICODE
dwprintf(L"Service group \"%s\" process ID: %d", lpServiceGroupName, *lpdwProcessId); trace(L"Service group \"%s\" process ID: %d", lpServiceGroupName, *lpdwProcessId);
#else #else
dwprintf(L"Service group \"%S\" process ID: %d", lpServiceGroupName, *lpdwProcessId); trace(L"Service group \"%S\" process ID: %d", lpServiceGroupName, *lpdwProcessId);
#endif #endif
break; break;
} }

View File

@@ -1,202 +0,0 @@
#include <Windows.h>
#include <stdio.h>
#include <stdint.h>
#include <intrin.h>
#include <tchar.h>
#include <TlHelp32.h>
#include <Psapi.h>
#include "util.h"
static BOOL checkedIsWindows7 = FALSE;
static BOOL isWindows7 = FALSE;
static BOOL checkedIsWindows8Point1 = FALSE;
static BOOL isWindows8Point1 = FALSE;
static LPFN_ISWOW64PROCESS fnIsWow64Process = NULL;
static BOOL checkedIsWow64 = FALSE;
static BOOL isWow64 = FALSE;
static FILE *log_fp = NULL;
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFunctionName) {
uintptr_t hm = (uintptr_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++) {
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;
}
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;
}
dwprintf(L"Modified %S import address: %p => %p", lpFuncName, *lpAddress, lpNewAddress);
*lpAddress = lpNewAddress;
VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect);
}
VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb) {
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
THREADENTRY32 te;
ZeroMemory(&te, sizeof(THREADENTRY32));
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;
dwprintf(L"Suspended %d other threads", count);
}
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) {
for (SIZE_T i = 0; i < cb; i++) {
ResumeThread(lphThreads[i]);
CloseHandle(lphThreads[i]);
}
dwprintf(L"Resumed %d other threads", cb);
}
BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask) {
OSVERSIONINFOEX osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
osvi.dwMajorVersion = dwMajorVersion;
osvi.dwMinorVersion = dwMinorVersion;
osvi.wServicePackMajor = wServicePackMajor;
osvi.wServicePackMinor = wServicePackMinor;
DWORDLONG dwlConditionMask = 0;
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, Operator);
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, Operator);
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, Operator);
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMINOR, Operator);
return VerifyVersionInfo(&osvi, dwTypeMask, dwlConditionMask);
}
BOOL IsWindows7(void) {
if (!checkedIsWindows7) {
isWindows7 = CompareWindowsVersion(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION);
checkedIsWindows7 = TRUE;
}
return isWindows7;
}
BOOL IsWindows8Point1(void) {
if (!checkedIsWindows8Point1) {
isWindows8Point1 = CompareWindowsVersion(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION);
checkedIsWindows8Point1 = TRUE;
}
return isWindows8Point1;
}
BOOL IsOperatingSystemSupported(void) {
#if !defined(_AMD64_) && !defined(_X86_)
return FALSE;
#else
return IsWindows7() || IsWindows8Point1();
#endif
}
BOOL IsWow64(void) {
if (!checkedIsWow64) {
if (!fnIsWow64Process) {
fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "IsWow64Process");
}
if (fnIsWow64Process && fnIsWow64Process(GetCurrentProcess(), &isWow64)) {
checkedIsWow64 = TRUE;
}
}
return isWow64;
}
void get_cpuid_brand(char* brand) {
int info[4];
__cpuidex(info, 0x80000000, 0);
if (info[0] < 0x80000004) {
brand[0] = '\0';
return;
}
uint32_t *char_as_int = (uint32_t *)brand;
for (int op = 0x80000002; op <= 0x80000004; op++) {
__cpuidex(info, op, 0);
*(char_as_int++) = info[0];
*(char_as_int++) = info[1];
*(char_as_int++) = info[2];
*(char_as_int++) = info[3];
}
}
BOOL init_log(void) {
if (log_fp) {
return TRUE;
}
WCHAR filename[MAX_PATH];
GetModuleFileNameW(HINST_THISCOMPONENT, filename, _countof(filename));
WCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME];
_wsplitpath_s(filename, drive, _countof(drive), dir, _countof(dir), fname, _countof(fname), NULL, 0);
WCHAR basename[MAX_PATH];
GetModuleBaseNameW(GetCurrentProcess(), NULL, basename, _countof(basename));
wcscat_s(fname, _countof(fname), L".");
wcscat_s(fname, _countof(fname), basename);
_wmakepath_s(filename, _countof(filename), drive, dir, fname, L".log");
HANDLE hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
LARGE_INTEGER size;
GetFileSizeEx(hFile, &size);
CloseHandle(hFile);
log_fp = _wfsopen(filename, size.QuadPart < (1 << 20) ? L"at" : L"wt", _SH_DENYWR);
if (!log_fp) {
return FALSE;
}
return TRUE;
}
VOID close_log(void) {
if (log_fp) {
fclose(log_fp);
}
}
VOID dwprintf_(LPCWSTR format, ...) {
if (init_log()) {
WCHAR datebuf[9], timebuf[9];
_wstrdate_s(datebuf, _countof(datebuf));
_wstrtime_s(timebuf, _countof(timebuf));
fwprintf_s(log_fp, L"%s %s [%d] ", datebuf, timebuf, GetCurrentProcessId());
va_list argptr;
va_start(argptr, format);
vfwprintf_s(log_fp, format, argptr);
va_end(argptr);
fflush(log_fp);
}
}

View File

@@ -1,39 +0,0 @@
#pragma once
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFuncName);
VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress);
VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb);
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T dwSize);
BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask);
BOOL IsWindows7(void);
BOOL IsWindows8Point1(void);
BOOL IsOperatingSystemSupported(void);
BOOL IsWow64(void);
void get_cpuid_brand(char *brand);
VOID dwprintf_(LPCWSTR format, ...);
#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)
BOOL init_log(void);
VOID close_log(void);
#define STRINGIZE_(x) #x
#define STRINGIZE(x) STRINGIZE_(x)
#define STRINGIZEW_(x) L#x
#define STRINGIZEW(x) STRINGIZEW_(x)
#define __LINEWSTR__ STRINGIZEW(__LINE__)
#define dwprintf(format, ...) dwprintf_(__FILEW__ L"(" __LINEWSTR__ L"): " format L"\n", ##__VA_ARGS__)

Binary file not shown.

View File

@@ -108,7 +108,7 @@
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile> <ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -121,7 +121,7 @@
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile> <ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -142,7 +142,7 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile> <ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command> <Command>
@@ -167,7 +167,7 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile> <ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command> <Command>
@@ -175,25 +175,29 @@
</PostBuildEvent> </PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="core.c" /> <ClCompile Include="hooks.c" />
<ClCompile Include="dllmain.c" /> <ClCompile Include="dllmain.c" />
<ClCompile Include="iathook.c" />
<ClCompile Include="logging.c" />
<ClCompile Include="patternfind.c" /> <ClCompile Include="patternfind.c" />
<ClCompile Include="rundll32.c" /> <ClCompile Include="rundll32.c" />
<ClCompile Include="service.c" /> <ClCompile Include="service.c" />
<ClCompile Include="util.c" /> <ClCompile Include="helpers.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="exports.def" /> <None Include="exports.def" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="core.h" /> <ClInclude Include="hooks.h" />
<ClInclude Include="iathook.h" />
<ClInclude Include="logging.h" />
<ClInclude Include="patternfind.h" /> <ClInclude Include="patternfind.h" />
<ClInclude Include="service.h" /> <ClInclude Include="service.h" />
<ClInclude Include="shellapihelper.h" /> <ClInclude Include="shellapihelper.h" />
<ClInclude Include="util.h" /> <ClInclude Include="helpers.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="version.rc" /> <ResourceCompile Include="wufuc.rc" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">