move source files to src folder, some code updates..
This commit is contained in:
165
src/wufuc/callbacks.c
Normal file
165
src/wufuc/callbacks.c
Normal file
@@ -0,0 +1,165 @@
|
||||
#include "stdafx.h"
|
||||
#include "callbacks.h"
|
||||
#include "hooks.h"
|
||||
#include "hlpmisc.h"
|
||||
#include "hlpmem.h"
|
||||
#include "hlpsvc.h"
|
||||
|
||||
bool DuplicateContextHandles(HANDLE hSrcProcess, ContextHandles *pSrcContext, HANDLE hAuxiliaryMutex, HANDLE hTargetProcess, ContextHandles *pTargetContext)
|
||||
{
|
||||
return
|
||||
DuplicateHandle(hSrcProcess, pSrcContext->hMainMutex,
|
||||
hTargetProcess, &pTargetContext->hMainMutex, SYNCHRONIZE, FALSE, 0)
|
||||
&& DuplicateHandle(hSrcProcess, pSrcContext->hUnloadEvent,
|
||||
hTargetProcess, &pTargetContext->hUnloadEvent, SYNCHRONIZE, FALSE, 0)
|
||||
&& DuplicateHandle(hSrcProcess, hAuxiliaryMutex,
|
||||
hTargetProcess, &pTargetContext->hAuxiliaryMutex, 0, FALSE, DUPLICATE_SAME_ACCESS);
|
||||
}
|
||||
|
||||
VOID CALLBACK ServiceNotifyCallback(PSERVICE_NOTIFYW pNotifyBuffer)
|
||||
{
|
||||
HANDLE hProcess;
|
||||
wchar_t MutexName[44];
|
||||
HANDLE hAuxiliaryMutex;
|
||||
ContextHandles TargetContext;
|
||||
|
||||
switch ( pNotifyBuffer->dwNotificationStatus ) {
|
||||
case ERROR_SUCCESS:
|
||||
if ( !pNotifyBuffer->ServiceStatus.dwProcessId
|
||||
|| swprintf_s(MutexName, _countof(MutexName),
|
||||
L"Global\\%08x-7132-44a8-be15-56698979d2f3",
|
||||
pNotifyBuffer->ServiceStatus.dwProcessId) == -1
|
||||
|| !InitializeMutex(false, MutexName, &hAuxiliaryMutex) )
|
||||
break;
|
||||
|
||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS,
|
||||
FALSE,
|
||||
pNotifyBuffer->ServiceStatus.dwProcessId);
|
||||
if ( !hProcess ) {
|
||||
trace(L"Failed to open target process! (GetLastError=%lu)", GetLastError());
|
||||
break;
|
||||
};
|
||||
|
||||
if ( !DuplicateContextHandles(GetCurrentProcess(), pNotifyBuffer->pContext, hAuxiliaryMutex, hProcess, &TargetContext) ) {
|
||||
trace(L"Failed to duplicate handles into target process."
|
||||
L"%p %p %p (GetLastError=%lu)",
|
||||
TargetContext.hMainMutex,
|
||||
TargetContext.hUnloadEvent,
|
||||
TargetContext.hAuxiliaryMutex,
|
||||
GetLastError());
|
||||
break;
|
||||
};
|
||||
InjectLibraryAndCreateRemoteThread(
|
||||
hProcess,
|
||||
PIMAGEBASE,
|
||||
StartAddress,
|
||||
&TargetContext,
|
||||
sizeof TargetContext);
|
||||
break;
|
||||
case ERROR_SERVICE_MARKED_FOR_DELETE:
|
||||
SetEvent((HANDLE)pNotifyBuffer->pContext);
|
||||
break;
|
||||
}
|
||||
if ( pNotifyBuffer->pszServiceNames )
|
||||
LocalFree((HLOCAL)pNotifyBuffer->pszServiceNames);
|
||||
}
|
||||
|
||||
DWORD WINAPI StartAddress(LPVOID pParam)
|
||||
{
|
||||
ContextHandles ctx;
|
||||
SC_HANDLE hSCM;
|
||||
DWORD dwProcessId;
|
||||
DWORD cbData;
|
||||
HMODULE hModule;
|
||||
DWORD result;
|
||||
|
||||
// get mutex and unload event handles from virtual memory
|
||||
if ( !pParam ) {
|
||||
trace(L"Context parameter is null!");
|
||||
goto unload;
|
||||
}
|
||||
ctx = *(ContextHandles *)pParam;
|
||||
if ( !VirtualFree(pParam, 0, MEM_RELEASE) )
|
||||
trace(L"Failed to free context parameter. pParam=%p GetLastError=%lu",
|
||||
pParam, GetLastError());
|
||||
|
||||
// acquire child mutex, should be immediate.
|
||||
if ( WaitForSingleObject(ctx.hAuxiliaryMutex, 5000) != WAIT_OBJECT_0 ) {
|
||||
trace(L"Failed to acquire aux mutex within five seconds. hAuxiliaryMutex=%p", ctx.hAuxiliaryMutex);
|
||||
goto close_handles;
|
||||
}
|
||||
|
||||
hSCM = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
|
||||
if ( !hSCM ) {
|
||||
trace(L"Failed to open SCM. (GetLastError=%ul)", GetLastError());
|
||||
goto release;
|
||||
}
|
||||
|
||||
dwProcessId = QueryServiceProcessId(hSCM, L"wuauserv");
|
||||
CloseServiceHandle(hSCM);
|
||||
if ( dwProcessId != GetCurrentProcessId() ) {
|
||||
trace(L"Injected into wrong process! CurrentProcessId=%lu wuauserv ProcessId=%lu",
|
||||
GetCurrentProcessId, dwProcessId);
|
||||
goto release;
|
||||
}
|
||||
|
||||
// hook IsDeviceServiceable
|
||||
g_pszWUServiceDll = RegGetValueAlloc(HKEY_LOCAL_MACHINE,
|
||||
L"SYSTEM\\CurrentControlSet\\services\\wuauserv\\Parameters",
|
||||
L"ServiceDll",
|
||||
RRF_RT_REG_SZ,
|
||||
NULL,
|
||||
&cbData);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
// hook LoadLibraryExW
|
||||
g_pfnLoadLibraryExW = DetourFindFunction("kernel32.dll", "LoadLibraryExW");
|
||||
if ( g_pfnLoadLibraryExW )
|
||||
DetourAttach(&(PVOID)g_pfnLoadLibraryExW, LoadLibraryExW_hook);
|
||||
|
||||
if ( g_pszWUServiceDll ) {
|
||||
hModule = GetModuleHandleW(g_pszWUServiceDll);
|
||||
if ( hModule && FindIsDeviceServiceablePtr(hModule,
|
||||
&(PVOID)g_pfnIsDeviceServiceable) ) {
|
||||
|
||||
DetourAttach(&(PVOID)g_pfnIsDeviceServiceable, IsDeviceServiceable_hook);
|
||||
}
|
||||
}
|
||||
DetourTransactionCommit();
|
||||
|
||||
|
||||
// wait for unload event or parent mutex to be abandoned.
|
||||
// for example if the user killed rundll32.exe with task manager.
|
||||
// intentionally leave parent mutex open until this thread ends, at
|
||||
// which point it becomes abandoned again.
|
||||
result = WaitForMultipleObjects(_countof(ctx.handles), ctx.handles, FALSE, INFINITE);
|
||||
|
||||
trace(L"Unloading!");
|
||||
|
||||
// unhook
|
||||
if ( g_pfnLoadLibraryExW || g_pfnIsDeviceServiceable ) {
|
||||
trace(L"Removing hooks...");
|
||||
trace(L"DetourTransactionBegin %lu", DetourTransactionBegin());
|
||||
trace(L"DetourUpdateThread %lu", DetourUpdateThread(GetCurrentThread()));
|
||||
|
||||
if ( g_pfnLoadLibraryExW )
|
||||
trace(L"DetourDetach LoadLibraryExW %lu", DetourDetach(&(PVOID)g_pfnLoadLibraryExW, LoadLibraryExW_hook));
|
||||
|
||||
if ( g_pfnIsDeviceServiceable )
|
||||
trace(L"DetourDetach IsDeviceServiceable %lu", DetourDetach(&(PVOID)g_pfnIsDeviceServiceable, IsDeviceServiceable_hook));
|
||||
|
||||
trace(L"DetourTransactionCommit %lu", DetourTransactionCommit());
|
||||
}
|
||||
free(g_pszWUServiceDll);
|
||||
|
||||
release:
|
||||
ReleaseMutex(ctx.hAuxiliaryMutex);
|
||||
close_handles:
|
||||
CloseHandle(ctx.hAuxiliaryMutex);
|
||||
CloseHandle(ctx.hMainMutex);
|
||||
CloseHandle(ctx.hUnloadEvent);
|
||||
unload:
|
||||
FreeLibraryAndExitThread(PIMAGEBASE, 0);
|
||||
}
|
25
src/wufuc/callbacks.h
Normal file
25
src/wufuc/callbacks.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
HANDLE hAuxiliaryMutex;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
HANDLE hMainMutex;
|
||||
HANDLE hUnloadEvent;
|
||||
} DUMMYSTRUCTNAME;
|
||||
struct
|
||||
{
|
||||
HANDLE hMainMutex;
|
||||
HANDLE hUnloadEvent;
|
||||
} u;
|
||||
HANDLE handles[2];
|
||||
};
|
||||
} ContextHandles;
|
||||
#pragma pack(pop)
|
||||
|
||||
VOID CALLBACK ServiceNotifyCallback(PSERVICE_NOTIFYW pNotifyBuffer);
|
||||
DWORD WINAPI StartAddress(LPVOID pParam);
|
16
src/wufuc/dllmain.c
Normal file
16
src/wufuc/dllmain.c
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved)
|
||||
{
|
||||
switch ( ul_reason_for_call ) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
5
src/wufuc/exports.def
Normal file
5
src/wufuc/exports.def
Normal file
@@ -0,0 +1,5 @@
|
||||
LIBRARY
|
||||
EXPORTS
|
||||
RUNDLL32_StartW @1
|
||||
RUNDLL32_UnloadW @2
|
||||
RUNDLL32_DeleteFileW @3
|
265
src/wufuc/hlpmem.c
Normal file
265
src/wufuc/hlpmem.c
Normal file
@@ -0,0 +1,265 @@
|
||||
#include "stdafx.h"
|
||||
#include "hlpmem.h"
|
||||
#include "hlpver.h"
|
||||
#include "hooks.h"
|
||||
#include <sddl.h>
|
||||
|
||||
bool FindIsDeviceServiceablePtr(HMODULE hModule, PVOID *ppfnIsDeviceServiceable)
|
||||
{
|
||||
bool result = false;
|
||||
bool is_win7 = false;
|
||||
bool is_win81 = false;
|
||||
PLANGANDCODEPAGE ptl;
|
||||
HANDLE hProcess;
|
||||
int tmp;
|
||||
UINT cbtl;
|
||||
wchar_t SubBlock[38];
|
||||
UINT cbInternalName;
|
||||
wchar_t *pInternalName;
|
||||
UINT cbffi;
|
||||
VS_FIXEDFILEINFO *pffi;
|
||||
MODULEINFO modinfo;
|
||||
size_t offset;
|
||||
|
||||
is_win7 = IsWindowsVersion(6, 1, 1);
|
||||
if ( !is_win7 ) {
|
||||
is_win81 = IsWindowsVersion(6, 3, 0);
|
||||
if ( !is_win81 ) {
|
||||
trace(L"Unsupported operating system.");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
ptl = GetVersionInfoFromHModuleAlloc(hModule, L"\\VarFileInfo\\Translation", &cbtl);
|
||||
if ( !ptl ) {
|
||||
trace(L"Failed to allocate version translation information from hmodule.");
|
||||
return result;
|
||||
}
|
||||
hProcess = GetCurrentProcess();
|
||||
|
||||
for ( size_t i = 0, count = (cbtl / sizeof *ptl); i < count; i++ ) {
|
||||
if ( swprintf_s(SubBlock,
|
||||
_countof(SubBlock),
|
||||
L"\\StringFileInfo\\%04x%04x\\InternalName",
|
||||
ptl[i].wLanguage,
|
||||
ptl[i].wCodePage) == -1 )
|
||||
continue;
|
||||
|
||||
pInternalName = GetVersionInfoFromHModuleAlloc(hModule, SubBlock, &cbInternalName);
|
||||
if ( !pInternalName ) {
|
||||
trace(L"Failed to allocate version internal name from hmodule.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// identify wuaueng.dll by its resource data
|
||||
tmp = _wcsicmp(pInternalName, L"wuaueng.dll");
|
||||
if ( tmp )
|
||||
trace(L"Module internal name does not match. pInternalName=%ls cbInternalName=%lu", pInternalName, cbInternalName);
|
||||
free(pInternalName);
|
||||
if ( tmp )
|
||||
continue;
|
||||
|
||||
pffi = GetVersionInfoFromHModuleAlloc(hModule, L"\\", &cbffi);
|
||||
if ( !pffi ) {
|
||||
trace(L"Failed to allocate version information from hmodule.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// assure wuaueng.dll is at least the minimum supported version
|
||||
tmp = ((is_win7 && FileInfoVerCompare(pffi, 7, 6, 7601, 23714) != -1)
|
||||
|| (is_win81 && FileInfoVerCompare(pffi, 7, 9, 9600, 18621) != -1));
|
||||
free(pffi);
|
||||
if ( !tmp ) {
|
||||
trace(L"Module does not meet the minimum supported version.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !GetModuleInformation(hProcess, hModule, &modinfo, sizeof modinfo) )
|
||||
break;
|
||||
|
||||
offset = patternfind(modinfo.lpBaseOfDll,
|
||||
modinfo.SizeOfImage,
|
||||
#ifdef _WIN64
|
||||
"FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????"
|
||||
#else
|
||||
is_win7
|
||||
? "833D????????00 743E E8???????? A3????????"
|
||||
: "8BFF 51 833D????????00 7507 A1????????"
|
||||
#endif
|
||||
);
|
||||
if ( offset != -1 ) {
|
||||
*ppfnIsDeviceServiceable = (PVOID)((uint8_t *)modinfo.lpBaseOfDll + offset);
|
||||
trace(L"Found IsDeviceServiceable address: %p", *ppfnIsDeviceServiceable);
|
||||
result = true;
|
||||
} else {
|
||||
trace(L"IsDeviceServiceable function pattern not found.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
free(ptl);
|
||||
return result;
|
||||
}
|
||||
|
||||
HANDLE GetRemoteHModuleFromTh32ModuleSnapshot(HANDLE hSnapshot, const wchar_t *pLibFileName)
|
||||
{
|
||||
MODULEENTRY32W me = { sizeof me };
|
||||
if ( !Module32FirstW(hSnapshot, &me) )
|
||||
return NULL;
|
||||
do {
|
||||
if ( !_wcsicmp(me.szExePath, pLibFileName) )
|
||||
return me.hModule;
|
||||
} while ( Module32NextW(hSnapshot, &me) );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool InjectLibraryAndCreateRemoteThread(
|
||||
HANDLE hProcess,
|
||||
HMODULE hModule,
|
||||
LPTHREAD_START_ROUTINE pStartAddress,
|
||||
const void *pParam,
|
||||
size_t cbParam)
|
||||
{
|
||||
bool result = false;
|
||||
NTSTATUS Status;
|
||||
LPVOID pBaseAddress = NULL;
|
||||
SIZE_T cb;
|
||||
HMODULE hRemoteModule = NULL;
|
||||
HANDLE hThread;
|
||||
|
||||
Status = NtSuspendProcess(hProcess);
|
||||
if ( !NT_SUCCESS(Status) ) return result;
|
||||
trace(L"Suspended process. hProcess=%p", hProcess);
|
||||
|
||||
if ( pParam ) {
|
||||
// this gets freed by pStartAddress
|
||||
pBaseAddress = VirtualAllocEx(hProcess,
|
||||
NULL,
|
||||
cbParam,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if ( !pBaseAddress ) goto resume;
|
||||
|
||||
if ( !WriteProcessMemory(hProcess, pBaseAddress, pParam, cbParam, &cb) )
|
||||
goto vfree;
|
||||
}
|
||||
if ( InjectLibrary(hProcess, hModule, &hRemoteModule) ) {
|
||||
trace(L"Injected library. hRemoteModule=%p", hRemoteModule);
|
||||
|
||||
hThread = CreateRemoteThread(hProcess,
|
||||
NULL,
|
||||
0,
|
||||
(LPTHREAD_START_ROUTINE)((uint8_t *)hRemoteModule + ((uint8_t *)pStartAddress - (uint8_t *)hModule)),
|
||||
pBaseAddress,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if ( hThread ) {
|
||||
trace(L"Created remote thread. hThread=%p", hThread);
|
||||
CloseHandle(hThread);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
vfree:
|
||||
if ( !result && pBaseAddress )
|
||||
VirtualFreeEx(hProcess, pBaseAddress, 0, MEM_RELEASE);
|
||||
resume: NtResumeProcess(hProcess);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool InjectLibrary(HANDLE hProcess, HMODULE hModule, HMODULE *phRemoteModule)
|
||||
{
|
||||
WCHAR Filename[MAX_PATH];
|
||||
DWORD nLength;
|
||||
|
||||
nLength = GetModuleFileNameW(hModule, Filename, _countof(Filename));
|
||||
if ( nLength ) {
|
||||
trace(L"Got module filename for local module. "
|
||||
L"hModule=%p Filename=%ls nLength=%lu",
|
||||
hModule, Filename, nLength);
|
||||
return InjectLibraryByFilename(hProcess,
|
||||
Filename,
|
||||
nLength,
|
||||
phRemoteModule);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InjectLibraryByFilename(
|
||||
HANDLE hProcess,
|
||||
const wchar_t *pLibFilename,
|
||||
size_t cchLibFilename,
|
||||
HMODULE *phRemoteModule)
|
||||
{
|
||||
bool result = false;
|
||||
DWORD dwProcessId;
|
||||
NTSTATUS Status;
|
||||
HANDLE hSnapshot;
|
||||
SIZE_T nSize;
|
||||
LPVOID pBaseAddress;
|
||||
HANDLE hThread;
|
||||
|
||||
Status = NtSuspendProcess(hProcess);
|
||||
if ( !NT_SUCCESS(Status) ) return result;
|
||||
trace(L"Suspended process. hProcess=%p", hProcess);
|
||||
|
||||
dwProcessId = GetProcessId(hProcess);
|
||||
|
||||
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
|
||||
if ( !hSnapshot ) goto resume;
|
||||
trace(L"Created TH32 module snapshot. dwProcessId=%lu", dwProcessId);
|
||||
|
||||
*phRemoteModule = GetRemoteHModuleFromTh32ModuleSnapshot(hSnapshot,
|
||||
pLibFilename);
|
||||
|
||||
CloseHandle(hSnapshot);
|
||||
|
||||
// already injected... still sets *phRemoteModule
|
||||
if ( *phRemoteModule ) goto resume;
|
||||
|
||||
nSize = (cchLibFilename + 1) * sizeof *pLibFilename;
|
||||
pBaseAddress = VirtualAllocEx(hProcess,
|
||||
NULL,
|
||||
nSize,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
|
||||
if ( !pBaseAddress ) goto resume;
|
||||
trace(L"Allocated virtual memory in process. hProcess=%p pBaseAddress=%p nSize=%Iu",
|
||||
hProcess, pBaseAddress, nSize);
|
||||
|
||||
if ( !WriteProcessMemory(hProcess, pBaseAddress, pLibFilename, nSize, NULL) )
|
||||
goto vfree;
|
||||
trace(L"Wrote to process memory. hProcess=%p pBaseAddress=%p pLibFileName=%.*ls nSize=%Iu",
|
||||
hProcess, pBaseAddress, cchLibFilename, pLibFilename, nSize);
|
||||
|
||||
hThread = CreateRemoteThread(hProcess,
|
||||
NULL,
|
||||
0,
|
||||
(LPTHREAD_START_ROUTINE)LoadLibraryW,
|
||||
pBaseAddress,
|
||||
0,
|
||||
NULL);
|
||||
if ( !hThread ) goto vfree;
|
||||
trace(L"Created remote thread. hThread=%p", hThread);
|
||||
|
||||
WaitForSingleObject(hThread, INFINITE);
|
||||
trace(L"Created thread finished running. hThread=%p", hThread);
|
||||
|
||||
if ( sizeof *phRemoteModule > sizeof(DWORD) ) {
|
||||
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
|
||||
if ( hSnapshot ) {
|
||||
*phRemoteModule = GetRemoteHModuleFromTh32ModuleSnapshot(
|
||||
hSnapshot,
|
||||
pLibFilename);
|
||||
|
||||
CloseHandle(hSnapshot);
|
||||
result = !!*phRemoteModule;
|
||||
}
|
||||
} else {
|
||||
result = !!GetExitCodeThread(hThread, (LPDWORD)phRemoteModule);
|
||||
}
|
||||
CloseHandle(hThread);
|
||||
vfree: VirtualFreeEx(hProcess, pBaseAddress, 0, MEM_RELEASE);
|
||||
resume: NtResumeProcess(hProcess);
|
||||
return result;
|
||||
}
|
22
src/wufuc/hlpmem.h
Normal file
22
src/wufuc/hlpmem.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD wLanguage;
|
||||
WORD wCodePage;
|
||||
} LANGANDCODEPAGE, *PLANGANDCODEPAGE;
|
||||
|
||||
bool FindIsDeviceServiceablePtr(HMODULE hModule, PVOID *ppfnIsDeviceServiceable);
|
||||
HANDLE GetRemoteHModuleFromTh32ModuleSnapshot(HANDLE hSnapshot, const wchar_t *pLibFileName);
|
||||
bool InjectLibraryAndCreateRemoteThread(
|
||||
HANDLE hProcess,
|
||||
HMODULE hModule,
|
||||
LPTHREAD_START_ROUTINE pStartAddress,
|
||||
const void *pParam,
|
||||
size_t cbParam);
|
||||
bool InjectLibrary(HANDLE hProcess, HMODULE hModule, HMODULE *phRemoteModule);
|
||||
bool InjectLibraryByFilename(
|
||||
HANDLE hProcess,
|
||||
const wchar_t *pLibFilename,
|
||||
size_t cchLibFilename,
|
||||
HMODULE *phRemoteModule);
|
70
src/wufuc/hlpmisc.c
Normal file
70
src/wufuc/hlpmisc.c
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "stdafx.h"
|
||||
#include "hlpmisc.h"
|
||||
#include <sddl.h>
|
||||
|
||||
bool InitializeMutex(bool InitialOwner, const wchar_t *pMutexName, HANDLE *phMutex)
|
||||
{
|
||||
HANDLE hMutex;
|
||||
|
||||
hMutex = CreateMutexW(NULL, InitialOwner, pMutexName);
|
||||
if ( hMutex ) {
|
||||
if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
|
||||
CloseHandle(hMutex);
|
||||
return false;
|
||||
}
|
||||
*phMutex = hMutex;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CreateEventWithStringSecurityDescriptor(
|
||||
const wchar_t *pStringSecurityDescriptor,
|
||||
bool ManualReset,
|
||||
bool InitialState,
|
||||
const wchar_t *pName,
|
||||
HANDLE *phEvent)
|
||||
{
|
||||
SECURITY_ATTRIBUTES sa = { sizeof sa };
|
||||
HANDLE event;
|
||||
|
||||
if ( ConvertStringSecurityDescriptorToSecurityDescriptorW(
|
||||
pStringSecurityDescriptor,
|
||||
SDDL_REVISION_1,
|
||||
&sa.lpSecurityDescriptor,
|
||||
NULL) ) {
|
||||
|
||||
event = CreateEventW(&sa, ManualReset, InitialState, pName);
|
||||
if ( event ) {
|
||||
*phEvent = event;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PVOID RegGetValueAlloc(
|
||||
HKEY hkey,
|
||||
const wchar_t *pSubKey,
|
||||
const wchar_t *pValue,
|
||||
DWORD dwFlags,
|
||||
LPDWORD pdwType,
|
||||
LPDWORD pcbData)
|
||||
{
|
||||
DWORD cbData = 0;
|
||||
PVOID result = NULL;
|
||||
|
||||
if ( RegGetValueW(hkey, pSubKey, pValue, dwFlags, pdwType, NULL, &cbData) != ERROR_SUCCESS )
|
||||
return result;
|
||||
|
||||
result = malloc(cbData);
|
||||
if ( !result ) return result;
|
||||
|
||||
if ( RegGetValueW(hkey, pSubKey, pValue, dwFlags, pdwType, result, &cbData) == ERROR_SUCCESS ) {
|
||||
*pcbData = cbData;
|
||||
} else {
|
||||
free(result);
|
||||
result = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
16
src/wufuc/hlpmisc.h
Normal file
16
src/wufuc/hlpmisc.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
bool InitializeMutex(bool InitialOwner, const wchar_t *pMutexName, HANDLE *phMutex);
|
||||
bool CreateEventWithStringSecurityDescriptor(
|
||||
const wchar_t *pStringSecurityDescriptor,
|
||||
bool ManualReset,
|
||||
bool InitialState,
|
||||
const wchar_t *pName,
|
||||
HANDLE *phEvent);
|
||||
PVOID RegGetValueAlloc(
|
||||
HKEY hkey,
|
||||
const wchar_t *pSubKey,
|
||||
const wchar_t *pValue,
|
||||
DWORD dwFlags,
|
||||
LPDWORD pdwType,
|
||||
LPDWORD pcbData);
|
118
src/wufuc/hlpsvc.c
Normal file
118
src/wufuc/hlpsvc.c
Normal file
@@ -0,0 +1,118 @@
|
||||
#include "stdafx.h"
|
||||
#include "hlpmisc.h"
|
||||
#include "hlpsvc.h"
|
||||
|
||||
LPQUERY_SERVICE_CONFIGW QueryServiceConfigByNameAlloc(
|
||||
SC_HANDLE hSCM,
|
||||
const wchar_t *pServiceName,
|
||||
LPDWORD pcbBufSize)
|
||||
{
|
||||
SC_HANDLE hService;
|
||||
DWORD cbBytesNeeded;
|
||||
LPQUERY_SERVICE_CONFIGW result = NULL;
|
||||
|
||||
hService = OpenServiceW(hSCM, pServiceName, SERVICE_QUERY_CONFIG);
|
||||
if ( !hService ) return result;
|
||||
|
||||
if ( !QueryServiceConfigW(hService, NULL, 0, &cbBytesNeeded)
|
||||
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
|
||||
|
||||
result = malloc(cbBytesNeeded);
|
||||
if ( result ) {
|
||||
if ( QueryServiceConfigW(hService, result, cbBytesNeeded, &cbBytesNeeded) ) {
|
||||
*pcbBufSize = cbBytesNeeded;
|
||||
} else {
|
||||
free(result);
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseServiceHandle(hService);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QueryServiceStatusProcessInfoByName(
|
||||
SC_HANDLE hSCM,
|
||||
const wchar_t *pServiceName,
|
||||
LPSERVICE_STATUS_PROCESS pServiceStatus)
|
||||
{
|
||||
bool result = false;
|
||||
SC_HANDLE hService;
|
||||
DWORD cbBytesNeeded;
|
||||
|
||||
hService = OpenServiceW(hSCM, pServiceName, SERVICE_QUERY_STATUS);
|
||||
if ( !hService ) {
|
||||
trace(L"Failed to open service %ls! (GetLastError=%ul)", pServiceName, GetLastError());
|
||||
return result;
|
||||
}
|
||||
|
||||
result = !!QueryServiceStatusEx(hService,
|
||||
SC_STATUS_PROCESS_INFO,
|
||||
(LPBYTE)pServiceStatus,
|
||||
sizeof *pServiceStatus,
|
||||
&cbBytesNeeded);
|
||||
CloseServiceHandle(hService);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QueryServiceGroupName(const LPQUERY_SERVICE_CONFIGW pServiceConfig, wchar_t *pGroupName, size_t nSize)
|
||||
{
|
||||
bool result = false;
|
||||
int NumArgs;
|
||||
LPWSTR *argv;
|
||||
|
||||
argv = CommandLineToArgvW(pServiceConfig->lpBinaryPathName, &NumArgs);
|
||||
if ( argv ) {
|
||||
if ( !_wcsicmp(PathFindFileNameW(argv[0]), L"svchost.exe") ) {
|
||||
|
||||
for ( int i = 1; (i + 1) < NumArgs; i++ ) {
|
||||
if ( !_wcsicmp(argv[i], L"-k") )
|
||||
return !wcscpy_s(pGroupName, nSize, argv[++i]);
|
||||
}
|
||||
}
|
||||
LocalFree((HLOCAL)argv);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DWORD QueryServiceProcessId(SC_HANDLE hSCM, const wchar_t *pServiceName)
|
||||
{
|
||||
SERVICE_STATUS_PROCESS ServiceStatusProcess;
|
||||
|
||||
if ( QueryServiceStatusProcessInfoByName(hSCM, pServiceName, &ServiceStatusProcess) )
|
||||
return ServiceStatusProcess.dwProcessId;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD InferSvchostGroupProcessId(SC_HANDLE hSCM, const wchar_t *pGroupName)
|
||||
{
|
||||
DWORD result = 0;
|
||||
DWORD cbData;
|
||||
wchar_t *pData;
|
||||
DWORD dwProcessId;
|
||||
DWORD cbBufSize;
|
||||
LPQUERY_SERVICE_CONFIGW pServiceConfig;
|
||||
bool success;
|
||||
WCHAR GroupName[256];
|
||||
|
||||
pData = RegGetValueAlloc(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost", pGroupName, RRF_RT_REG_MULTI_SZ, NULL, &cbData);
|
||||
if ( !pData ) return result;
|
||||
|
||||
for ( wchar_t *pName = pData; *pName; pName += wcslen(pName) + 1 ) {
|
||||
dwProcessId = QueryServiceProcessId(hSCM, pName);
|
||||
trace(L"pName=%ls dwProcessId=%lu", pName, dwProcessId);
|
||||
if ( !dwProcessId ) continue;
|
||||
|
||||
pServiceConfig = QueryServiceConfigByNameAlloc(hSCM, pName, &cbBufSize);
|
||||
if ( !pServiceConfig ) continue;
|
||||
success = QueryServiceGroupName(pServiceConfig, GroupName, _countof(GroupName));
|
||||
free(pServiceConfig);
|
||||
if ( success && !_wcsicmp(pGroupName, GroupName) ) {
|
||||
trace(L"found PID for group %ls: %lu", pGroupName, dwProcessId);
|
||||
result = dwProcessId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(pData);
|
||||
return result;
|
||||
}
|
13
src/wufuc/hlpsvc.h
Normal file
13
src/wufuc/hlpsvc.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
LPQUERY_SERVICE_CONFIGW QueryServiceConfigByNameAlloc(
|
||||
SC_HANDLE hSCM,
|
||||
const wchar_t *pServiceName,
|
||||
LPDWORD pcbBufSize);
|
||||
bool QueryServiceStatusProcessInfoByName(
|
||||
SC_HANDLE hSCM,
|
||||
const wchar_t *pServiceName,
|
||||
LPSERVICE_STATUS_PROCESS pServiceStatus);
|
||||
bool QueryServiceGroupName(const LPQUERY_SERVICE_CONFIGW pServiceConfig, wchar_t *pGroupName, size_t nSize);
|
||||
DWORD QueryServiceProcessId(SC_HANDLE hSCM, const wchar_t *pServiceName);
|
||||
DWORD InferSvchostGroupProcessId(SC_HANDLE hSCM, const wchar_t *pGroupName);
|
107
src/wufuc/hlpver.c
Normal file
107
src/wufuc/hlpver.c
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "stdafx.h"
|
||||
#include "hlpver.h"
|
||||
|
||||
int FileInfoVerCompare(VS_FIXEDFILEINFO *pffi, WORD wMajor, WORD wMinor, WORD wBuild, WORD wRev)
|
||||
{
|
||||
if ( HIWORD(pffi->dwProductVersionMS) < wMajor ) return -1;
|
||||
if ( HIWORD(pffi->dwProductVersionMS) > wMajor ) return 1;
|
||||
if ( LOWORD(pffi->dwProductVersionMS) < wMinor ) return -1;
|
||||
if ( LOWORD(pffi->dwProductVersionMS) > wMinor ) return 1;
|
||||
if ( HIWORD(pffi->dwProductVersionLS) < wBuild ) return -1;
|
||||
if ( HIWORD(pffi->dwProductVersionLS) > wBuild ) return 1;
|
||||
if ( LOWORD(pffi->dwProductVersionLS) < wRev ) return -1;
|
||||
if ( LOWORD(pffi->dwProductVersionLS) > wRev ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool GetVersionInfoFromHModule(HMODULE hModule, LPCWSTR pszSubBlock, LPVOID pData, PUINT pcbData)
|
||||
{
|
||||
bool result = false;
|
||||
UINT cbData;
|
||||
HRSRC hResInfo;
|
||||
DWORD dwSize;
|
||||
HGLOBAL hResData;
|
||||
LPVOID pRes;
|
||||
LPVOID pCopy;
|
||||
LPVOID pBuffer;
|
||||
UINT uLen;
|
||||
|
||||
if ( !pcbData ) return result;
|
||||
cbData = *pcbData;
|
||||
|
||||
hResInfo = FindResourceW(hModule,
|
||||
MAKEINTRESOURCEW(VS_VERSION_INFO),
|
||||
RT_VERSION);
|
||||
if ( !hResInfo ) return result;
|
||||
|
||||
dwSize = SizeofResource(hModule, hResInfo);
|
||||
if ( !dwSize ) return result;
|
||||
|
||||
hResData = LoadResource(hModule, hResInfo);
|
||||
if ( !hResData ) return result;
|
||||
|
||||
pRes = LockResource(hResData);
|
||||
if ( !pRes ) return result;
|
||||
|
||||
pCopy = malloc(dwSize);
|
||||
if ( !pCopy
|
||||
|| memcpy_s(pCopy, dwSize, pRes, dwSize)
|
||||
|| !VerQueryValueW(pCopy, pszSubBlock, &pBuffer, &uLen) )
|
||||
goto cleanup;
|
||||
|
||||
if ( !_wcsnicmp(pszSubBlock, L"\\StringFileInfo\\", 16) )
|
||||
*pcbData = uLen * sizeof(wchar_t);
|
||||
else
|
||||
*pcbData = uLen;
|
||||
|
||||
if ( !pData ) {
|
||||
result = true;
|
||||
goto cleanup;
|
||||
}
|
||||
if ( cbData < *pcbData
|
||||
|| memcpy_s(pData, cbData, pBuffer, *pcbData) )
|
||||
goto cleanup;
|
||||
|
||||
result = true;
|
||||
cleanup:
|
||||
free(pCopy);
|
||||
return result;
|
||||
}
|
||||
|
||||
LPVOID GetVersionInfoFromHModuleAlloc(HMODULE hModule, LPCWSTR pszSubBlock, PUINT pcbData)
|
||||
{
|
||||
UINT cbData = 0;
|
||||
LPVOID result = NULL;
|
||||
|
||||
if ( !GetVersionInfoFromHModule(hModule, pszSubBlock, NULL, &cbData) )
|
||||
return result;
|
||||
|
||||
result = malloc(cbData);
|
||||
if ( !result ) return result;
|
||||
|
||||
if ( GetVersionInfoFromHModule(hModule, pszSubBlock, result, &cbData) ) {
|
||||
*pcbData = cbData;
|
||||
} else {
|
||||
free(result);
|
||||
result = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IsWindowsVersion(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
|
||||
{
|
||||
OSVERSIONINFOEXW osvi = { sizeof osvi };
|
||||
|
||||
DWORDLONG dwlConditionMask = 0;
|
||||
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL);
|
||||
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_EQUAL);
|
||||
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
|
||||
osvi.dwMajorVersion = wMajorVersion;
|
||||
osvi.dwMinorVersion = wMinorVersion;
|
||||
osvi.wServicePackMajor = wServicePackMajor;
|
||||
|
||||
return VerifyVersionInfoW(&osvi,
|
||||
VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR,
|
||||
dwlConditionMask) != FALSE;
|
||||
}
|
6
src/wufuc/hlpver.h
Normal file
6
src/wufuc/hlpver.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
int FileInfoVerCompare(VS_FIXEDFILEINFO *pffi, WORD wMajor, WORD wMinor, WORD wBuild, WORD wRev);
|
||||
bool GetVersionInfoFromHModule(HMODULE hModule, LPCWSTR pszSubBlock, LPVOID pData, PUINT pcbData);
|
||||
LPVOID GetVersionInfoFromHModuleAlloc(HMODULE hModule, LPCWSTR pszSubBlock, PUINT pcbData);
|
||||
bool IsWindowsVersion(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor);
|
35
src/wufuc/hooks.c
Normal file
35
src/wufuc/hooks.c
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "stdafx.h"
|
||||
#include "hooks.h"
|
||||
#include "hlpmem.h"
|
||||
#include "hlpmisc.h"
|
||||
#include "hlpsvc.h"
|
||||
|
||||
LPWSTR g_pszWUServiceDll;
|
||||
|
||||
LPFN_ISDEVICESERVICEABLE g_pfnIsDeviceServiceable;
|
||||
LPFN_LOADLIBRARYEXW g_pfnLoadLibraryExW;
|
||||
|
||||
HMODULE WINAPI LoadLibraryExW_hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags)
|
||||
{
|
||||
HMODULE result;
|
||||
|
||||
result = g_pfnLoadLibraryExW(lpFileName, hFile, dwFlags);
|
||||
if ( !result ) return result;
|
||||
trace(L"Loaded library. lpFileName=%ls result=%p", lpFileName, result);
|
||||
|
||||
if ( g_pszWUServiceDll
|
||||
&& !_wcsicmp(lpFileName, g_pszWUServiceDll)
|
||||
&& FindIsDeviceServiceablePtr(result, &(PVOID)g_pfnIsDeviceServiceable) ) {
|
||||
|
||||
trace(L"DetourTransactionBegin=%lu", DetourTransactionBegin());
|
||||
trace(L"DetourUpdateThread=%lu", DetourUpdateThread(GetCurrentThread()));
|
||||
trace(L"DetourAttach=%lu", DetourAttach(&(PVOID)g_pfnIsDeviceServiceable, IsDeviceServiceable_hook));
|
||||
trace(L"DetourTransactionCommit=%lu", DetourTransactionCommit());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL WINAPI IsDeviceServiceable_hook(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
13
src/wufuc/hooks.h
Normal file
13
src/wufuc/hooks.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
typedef HMODULE(WINAPI *LPFN_LOADLIBRARYEXW)(LPCWSTR, HANDLE, DWORD);
|
||||
typedef BOOL(WINAPI *LPFN_ISDEVICESERVICEABLE)(void);
|
||||
|
||||
extern LPWSTR g_pszWUServiceDll;
|
||||
|
||||
extern LPFN_LOADLIBRARYEXW g_pfnLoadLibraryExW;
|
||||
extern LPFN_ISDEVICESERVICEABLE g_pfnIsDeviceServiceable;
|
||||
|
||||
HMODULE WINAPI LoadLibraryExW_hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags);
|
||||
BOOL WINAPI IsDeviceServiceable_hook(void);
|
11
src/wufuc/patternfind.CHANGES.txt
Normal file
11
src/wufuc/patternfind.CHANGES.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
Based on mrexodia's patternfind code originally written in C++
|
||||
Licensed under Lesser GNU Public License 3.0
|
||||
|
||||
https://bitbucket.org/mrexodia/patternfind
|
||||
|
||||
Changes made:
|
||||
|
||||
- Ported to C, removed dependency on C++ type vector<T>
|
||||
- Uses stdint.h type uint8_t instead of unsigned char (for readability)
|
||||
- Renamed patternfind overloads to patternfind, patternfind_bytes, patternfind_pbyte
|
||||
- Added VirtualProtect calls to patternwrite function to prevent access violation exceptions
|
165
src/wufuc/patternfind.LICENSE
Normal file
165
src/wufuc/patternfind.LICENSE
Normal file
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
181
src/wufuc/patternfind.c
Normal file
181
src/wufuc/patternfind.c
Normal file
@@ -0,0 +1,181 @@
|
||||
#include "stdafx.h"
|
||||
#include "patternfind.h"
|
||||
|
||||
static inline bool isHex(char ch)
|
||||
{
|
||||
return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f');
|
||||
}
|
||||
|
||||
static inline int hexchtoint(char ch)
|
||||
{
|
||||
if ( ch >= '0' && ch <= '9' )
|
||||
return ch - '0';
|
||||
else if ( ch >= 'A' && ch <= 'F' )
|
||||
return ch - 'A' + 10;
|
||||
else if ( ch >= 'a' && ch <= 'f' )
|
||||
return ch - 'a' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline size_t formathexpattern(const char *patterntext, char *formattext, size_t formattextsize)
|
||||
{
|
||||
size_t len = strlen(patterntext);
|
||||
size_t result = 0;
|
||||
for ( size_t i = 0; i < len; i++ ) {
|
||||
if ( patterntext[i] == '?' || hexchtoint(patterntext[i]) != -1 ) {
|
||||
if ( formattext && result + 1 < formattextsize )
|
||||
formattext[result] = patterntext[i];
|
||||
|
||||
result++;
|
||||
}
|
||||
}
|
||||
if ( result % 2 ) { //not a multiple of 2
|
||||
if ( formattext && result + 1 < formattextsize )
|
||||
formattext[result] = '?';
|
||||
|
||||
result++;
|
||||
}
|
||||
if ( formattext ) {
|
||||
if ( result <= formattextsize )
|
||||
formattext[result] = '\0';
|
||||
else
|
||||
formattext[0] = '\0';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool patterntransform(const char *patterntext, PatternByte *pattern, size_t patternsize)
|
||||
{
|
||||
memset(pattern, 0, patternsize * (sizeof *pattern));
|
||||
size_t len = formathexpattern(patterntext, NULL, 0);
|
||||
|
||||
if ( !len || len / 2 > patternsize )
|
||||
return false;
|
||||
|
||||
size_t size = len + 1;
|
||||
char *formattext = malloc(size);
|
||||
formathexpattern(patterntext, formattext, size);
|
||||
PatternByte newByte;
|
||||
|
||||
for ( size_t i = 0, j = 0, k = 0; i < len && k <= patternsize; i++ ) {
|
||||
if ( formattext[i] == '?' ) { //wildcard
|
||||
newByte.nibble[j].wildcard = true; //match anything
|
||||
} else { //hex
|
||||
newByte.nibble[j].wildcard = false;
|
||||
newByte.nibble[j].data = hexchtoint(formattext[i]) & 0xF;
|
||||
}
|
||||
|
||||
j++;
|
||||
if ( j == 2 ) { //two nibbles = one byte
|
||||
j = 0;
|
||||
pattern[k++] = newByte;
|
||||
}
|
||||
}
|
||||
free(formattext);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool patternmatchbyte(uint8_t byte, const PatternByte pbyte)
|
||||
{
|
||||
int matched = 0;
|
||||
|
||||
uint8_t n1 = (byte >> 4) & 0xF;
|
||||
if ( pbyte.nibble[0].wildcard )
|
||||
matched++;
|
||||
else if ( pbyte.nibble[0].data == n1 )
|
||||
matched++;
|
||||
|
||||
uint8_t n2 = byte & 0xF;
|
||||
if ( pbyte.nibble[1].wildcard )
|
||||
matched++;
|
||||
else if ( pbyte.nibble[1].data == n2 )
|
||||
matched++;
|
||||
|
||||
return (matched == 2);
|
||||
}
|
||||
|
||||
size_t patternfind(uint8_t *data, size_t datasize, const char *pattern)
|
||||
{
|
||||
size_t searchpatternsize = formathexpattern(pattern, NULL, 0) / 2;
|
||||
PatternByte *searchpattern = calloc(searchpatternsize, sizeof(PatternByte));
|
||||
|
||||
size_t result = -1;
|
||||
if ( patterntransform(pattern, searchpattern, searchpatternsize) )
|
||||
result = patternfind_pbyte(data, datasize, searchpattern, searchpatternsize);
|
||||
|
||||
free(searchpattern);
|
||||
return result;
|
||||
}
|
||||
|
||||
__declspec(noinline)
|
||||
size_t patternfind_bytes(uint8_t *data, size_t datasize, const uint8_t *pattern, size_t patternsize)
|
||||
{
|
||||
if ( patternsize > datasize )
|
||||
patternsize = datasize;
|
||||
for ( size_t i = 0, pos = 0; i < datasize; i++ ) {
|
||||
if ( data[i] == pattern[pos] ) {
|
||||
pos++;
|
||||
if ( pos == patternsize )
|
||||
return i - patternsize + 1;
|
||||
} else if ( pos > 0 ) {
|
||||
i -= pos;
|
||||
pos = 0; //reset current pattern position
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void patternwritebyte(uint8_t *byte, const PatternByte pbyte)
|
||||
{
|
||||
uint8_t n1 = (*byte >> 4) & 0xF;
|
||||
uint8_t n2 = *byte & 0xF;
|
||||
|
||||
if ( !pbyte.nibble[0].wildcard )
|
||||
n1 = pbyte.nibble[0].data;
|
||||
if ( !pbyte.nibble[1].wildcard )
|
||||
n2 = pbyte.nibble[1].data;
|
||||
*byte = ((n1 << 4) & 0xF0) | (n2 & 0xF);
|
||||
}
|
||||
|
||||
void patternwrite(uint8_t *data, size_t datasize, const char *pattern)
|
||||
{
|
||||
size_t writepatternsize = formathexpattern(pattern, NULL, 0) / 2;
|
||||
PatternByte *writepattern = calloc(writepatternsize, sizeof(PatternByte));
|
||||
|
||||
if ( patterntransform(pattern, writepattern, writepatternsize) ) {
|
||||
DWORD OldProtect;
|
||||
BOOL result = VirtualProtect(data, writepatternsize, PAGE_READWRITE, &OldProtect);
|
||||
if ( writepatternsize > datasize )
|
||||
writepatternsize = datasize;
|
||||
for ( size_t i = 0; i < writepatternsize; i++ )
|
||||
patternwritebyte(&data[i], writepattern[i]);
|
||||
result = VirtualProtect(data, writepatternsize, OldProtect, &OldProtect);
|
||||
}
|
||||
|
||||
free(writepattern);
|
||||
}
|
||||
|
||||
bool patternsnr(uint8_t *data, size_t datasize, const char *searchpattern, const char *replacepattern)
|
||||
{
|
||||
size_t found = patternfind(data, datasize, searchpattern);
|
||||
if ( found == -1 )
|
||||
return false;
|
||||
patternwrite(data + found, found - datasize, replacepattern);
|
||||
return true;
|
||||
}
|
||||
|
||||
__declspec(noinline)
|
||||
size_t patternfind_pbyte(uint8_t *data, size_t datasize, const PatternByte *pattern, size_t searchpatternsize)
|
||||
{
|
||||
for ( size_t i = 0, pos = 0; i < datasize; i++ ) { //search for the pattern
|
||||
if ( patternmatchbyte(data[i], pattern[pos]) ) { //check if our pattern matches the current byte
|
||||
pos++;
|
||||
if ( pos == searchpatternsize ) //everything matched
|
||||
return i - searchpatternsize + 1;
|
||||
} else if ( pos > 0 ) { //fix by Computer_Angel
|
||||
i -= pos;
|
||||
pos = 0; //reset current pattern position
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
55
src/wufuc/patternfind.h
Normal file
55
src/wufuc/patternfind.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t data;
|
||||
bool wildcard;
|
||||
} nibble[2];
|
||||
} PatternByte;
|
||||
|
||||
//returns: offset to data when found, -1 when not found
|
||||
size_t patternfind(
|
||||
uint8_t *data, //data
|
||||
size_t datasize, //size of data
|
||||
const char *pattern //pattern to search
|
||||
);
|
||||
|
||||
//returns: offset to data when found, -1 when not found
|
||||
size_t patternfind_bytes(
|
||||
uint8_t *data, //data
|
||||
size_t datasize, //size of data
|
||||
const uint8_t *pattern, //bytes to search
|
||||
size_t patternsize //size of bytes to search
|
||||
);
|
||||
|
||||
//returns: nothing
|
||||
void patternwrite(
|
||||
uint8_t *data, //data
|
||||
size_t datasize, //size of data
|
||||
const char *pattern //pattern to write
|
||||
);
|
||||
|
||||
//returns: true on success, false on failure
|
||||
bool patternsnr(
|
||||
uint8_t *data, //data
|
||||
size_t datasize, //size of data
|
||||
const char *searchpattern, //pattern to search
|
||||
const char *replacepattern //pattern to write
|
||||
);
|
||||
|
||||
//returns: true on success, false on failure
|
||||
bool patterntransform(
|
||||
const char *patterntext, //pattern string
|
||||
PatternByte *pattern, //pattern to feed to patternfind
|
||||
size_t patternsize //size of pattern
|
||||
);
|
||||
|
||||
//returns: offset to data when found, -1 when not found
|
||||
size_t patternfind_pbyte(
|
||||
uint8_t *data, //data
|
||||
size_t datasize, //size of data
|
||||
const PatternByte *pattern, //pattern to search
|
||||
size_t searchpatternsize //size of pattern to search
|
||||
);
|
102
src/wufuc/rundll32.c
Normal file
102
src/wufuc/rundll32.c
Normal file
@@ -0,0 +1,102 @@
|
||||
#include "stdafx.h"
|
||||
#include "callbacks.h"
|
||||
#include "hlpmisc.h"
|
||||
|
||||
|
||||
void CALLBACK RUNDLL32_StartW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
ContextHandles ctx;
|
||||
bool Unloading = false;
|
||||
bool Lagging;
|
||||
SC_HANDLE hSCM;
|
||||
SC_HANDLE hService;
|
||||
SERVICE_NOTIFYW NotifyBuffer;
|
||||
|
||||
if ( !InitializeMutex(true,
|
||||
L"Global\\25020063-b5a7-4227-9fdf-25cb75e8c645",
|
||||
&ctx.hMainMutex) ) {
|
||||
|
||||
trace(L"Failed to initialize main mutex. (GetLastError=%ul)", GetLastError());
|
||||
return;
|
||||
};
|
||||
if ( !CreateEventWithStringSecurityDescriptor(L"D:(A;;0x001F0003;;;BA)",
|
||||
true,
|
||||
false,
|
||||
L"Global\\wufuc_UnloadEvent",
|
||||
&ctx.hUnloadEvent) ) {
|
||||
|
||||
trace(L"Failed to create unload event. (GetLastError=%ul)", GetLastError());
|
||||
goto close_mutex;
|
||||
}
|
||||
do {
|
||||
Lagging = false;
|
||||
hSCM = OpenSCManagerW(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
|
||||
if ( !hSCM ) {
|
||||
trace(L"Failed to open SCM. (GetLastError=%ul)", GetLastError());
|
||||
goto close_event;
|
||||
}
|
||||
|
||||
hService = OpenServiceW(hSCM, L"wuauserv", SERVICE_QUERY_STATUS);
|
||||
if ( !hService ) {
|
||||
trace(L"Failed to open service. (GetLastError=%ul)", GetLastError());
|
||||
goto close_scm;
|
||||
}
|
||||
|
||||
ZeroMemory(&NotifyBuffer, sizeof NotifyBuffer);
|
||||
NotifyBuffer.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE;
|
||||
NotifyBuffer.pfnNotifyCallback = ServiceNotifyCallback;
|
||||
NotifyBuffer.pContext = (PVOID)&ctx;
|
||||
while ( !Unloading && !Lagging ) {
|
||||
switch ( NotifyServiceStatusChangeW(hService,
|
||||
SERVICE_NOTIFY_START_PENDING | SERVICE_NOTIFY_RUNNING,
|
||||
&NotifyBuffer) ) {
|
||||
case ERROR_SUCCESS:
|
||||
Unloading = WaitForSingleObjectEx(ctx.hUnloadEvent, INFINITE, TRUE) == WAIT_OBJECT_0;
|
||||
break;
|
||||
case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING:
|
||||
trace(L"Client lagging!");
|
||||
Lagging = true;
|
||||
break;
|
||||
default:
|
||||
Unloading = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CloseServiceHandle(hService);
|
||||
close_scm: CloseServiceHandle(hSCM);
|
||||
} while ( Lagging );
|
||||
close_event:
|
||||
CloseHandle(ctx.hUnloadEvent);
|
||||
close_mutex:
|
||||
ReleaseMutex(ctx.hMainMutex);
|
||||
CloseHandle(ctx.hMainMutex);
|
||||
}
|
||||
|
||||
void CALLBACK RUNDLL32_UnloadW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
HANDLE hEvent;
|
||||
|
||||
hEvent = OpenEventW(EVENT_MODIFY_STATE, FALSE, L"Global\\wufuc_UnloadEvent");
|
||||
if ( hEvent ) {
|
||||
SetEvent(hEvent);
|
||||
CloseHandle(hEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void CALLBACK RUNDLL32_DeleteFileW(
|
||||
HWND hwnd,
|
||||
HINSTANCE hinst,
|
||||
LPWSTR lpszCmdLine,
|
||||
int nCmdShow)
|
||||
{
|
||||
int argc;
|
||||
LPWSTR *argv;
|
||||
|
||||
argv = CommandLineToArgvW(lpszCmdLine, &argc);
|
||||
if ( argv ) {
|
||||
if ( !DeleteFileW(argv[0]) && GetLastError() == ERROR_ACCESS_DENIED )
|
||||
MoveFileExW(argv[0], NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
|
||||
|
||||
LocalFree((HLOCAL)argv);
|
||||
}
|
||||
}
|
11
src/wufuc/rundll32.h
Normal file
11
src/wufuc/rundll32.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef UNICODE
|
||||
#define RUNDLL32_Start RUNDLL32_StartW
|
||||
#define RUNDLL32_Unload RUNDLL32_UnloadW
|
||||
#define RUNDLL32_DeleteFile RUNDLL32_DeleteFileW
|
||||
#else
|
||||
#define RUNDLL32_Start RUNDLL32_StartA
|
||||
#define RUNDLL32_Unload RUNDLL32_UnloadA
|
||||
#define RUNDLL32_DeleteFile RUNDLL32_DeleteFileA
|
||||
#endif // !UNICODE
|
7
src/wufuc/stdafx.c
Normal file
7
src/wufuc/stdafx.c
Normal file
@@ -0,0 +1,7 @@
|
||||
// stdafx.c : source file that includes just the standard includes
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
34
src/wufuc/stdafx.h
Normal file
34
src/wufuc/stdafx.h
Normal file
@@ -0,0 +1,34 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
// Windows Header Files:
|
||||
#include <phnt_windows.h>
|
||||
#include <phnt.h>
|
||||
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <strsafe.h>
|
||||
#include <shellapi.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <Psapi.h>
|
||||
#include <TlHelp32.h>
|
||||
|
||||
#include <detours.h>
|
||||
#include "patternfind.h"
|
||||
#include "tracing.h"
|
||||
|
||||
extern IMAGE_DOS_HEADER __ImageBase;
|
||||
#define PIMAGEBASE ((HMODULE)&__ImageBase)
|
||||
|
9
src/wufuc/targetver.h
Normal file
9
src/wufuc/targetver.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
// Including SDKDDKVer.h defines the highest available Windows platform.
|
||||
|
||||
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
||||
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
||||
|
||||
#define _WIN32_WINNT _WIN32_WINNT_WIN7
|
||||
#include <SDKDDKVer.h>
|
19
src/wufuc/tracing.c
Normal file
19
src/wufuc/tracing.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "stdafx.h"
|
||||
#include "tracing.h"
|
||||
|
||||
void trace_(const wchar_t *const format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
int count;
|
||||
wchar_t *buffer;
|
||||
|
||||
va_start(argptr, format);
|
||||
|
||||
count = _vscwprintf(format, argptr) + 1;
|
||||
buffer = calloc(count, sizeof *buffer);
|
||||
vswprintf_s(buffer, count, format, argptr);
|
||||
|
||||
va_end(argptr);
|
||||
OutputDebugStringW(buffer);
|
||||
free(buffer);
|
||||
}
|
14
src/wufuc/tracing.h
Normal file
14
src/wufuc/tracing.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <phnt_windows.h>
|
||||
|
||||
extern IMAGE_DOS_HEADER __ImageBase;
|
||||
#define HMODULE_THISCOMPONENT ((HMODULE)&__ImageBase);
|
||||
|
||||
void trace_(const wchar_t *const format, ...);
|
||||
|
||||
#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__)
|
BIN
src/wufuc/wufuc.rc
Normal file
BIN
src/wufuc/wufuc.rc
Normal file
Binary file not shown.
17
src/wufuc/wufuc.rch
Normal file
17
src/wufuc/wufuc.rch
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef WUFUC_RCH_INCLUDED
|
||||
#define WUFUC_RCH_INCLUDED
|
||||
#pragma once
|
||||
#ifndef BUILD_COMMIT_VERSION
|
||||
#define BUILD_COMMIT_VERSION 0.9.999.0
|
||||
#endif
|
||||
#ifndef BUILD_VERSION_COMMA
|
||||
#define BUILD_VERSION_COMMA 0,9,999,0
|
||||
#endif
|
||||
#define STRINGIZE_(x) #x
|
||||
#define STRINGIZE(x) STRINGIZE_(x)
|
||||
#ifdef X64
|
||||
#define WUFUC_DLL "wufuc64.dll"
|
||||
#elif defined(X86)
|
||||
#define WUFUC_DLL "wufuc32.dll"
|
||||
#endif
|
||||
#endif
|
273
src/wufuc/wufuc.vcxproj
Normal file
273
src/wufuc/wufuc.vcxproj
Normal file
@@ -0,0 +1,273 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="callbacks.h" />
|
||||
<ClInclude Include="hlpmem.h" />
|
||||
<ClInclude Include="hlpmisc.h" />
|
||||
<ClInclude Include="hlpsvc.h" />
|
||||
<ClInclude Include="hlpver.h" />
|
||||
<ClInclude Include="hooks.h" />
|
||||
<ClInclude Include="patternfind.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="tracing.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="callbacks.c" />
|
||||
<ClCompile Include="dllmain.c" />
|
||||
<ClCompile Include="hlpmem.c" />
|
||||
<ClCompile Include="hlpmisc.c" />
|
||||
<ClCompile Include="hlpsvc.c" />
|
||||
<ClCompile Include="hlpver.c" />
|
||||
<ClCompile Include="hooks.c" />
|
||||
<ClCompile Include="patternfind.c" />
|
||||
<ClCompile Include="stdafx.c">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rundll32.c" />
|
||||
<ClCompile Include="tracing.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="exports.def" />
|
||||
<None Include="wufuc.rch">
|
||||
<FileType>Document</FileType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="wufuc.rc" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{00F96695-CE41-4C2F-A344-6219DFB4F887}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>wufuc</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(ProjectDir)bin\$(Configuration)\$(PlatformShortName)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<IncludePath>$(SolutionDir)..\inc\phnt;$(SolutionDir)..\inc\detours;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)..\lib\detours;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(ProjectDir)bin\$(Configuration)\$(PlatformShortName)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<IncludePath>$(SolutionDir)..\inc\phnt;$(SolutionDir)..\inc\detours;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)..\lib\detours;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(ProjectDir)bin\$(Configuration)\$(PlatformShortName)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<IncludePath>$(SolutionDir)..\inc\phnt;$(SolutionDir)..\inc\detours;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)..\lib\detours;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(ProjectDir)bin\$(Configuration)\$(PlatformShortName)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<IncludePath>$(SolutionDir)..\inc\phnt;$(SolutionDir)..\inc\detours;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)..\lib\detours;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;WUFUC_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
||||
<EntryPointSymbol>
|
||||
</EntryPointSymbol>
|
||||
<AdditionalDependencies>version.lib;Shlwapi.lib;detours.X86.MTd.lib;%(AdditionalDependencies);ntdll.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;WUFUC_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
||||
<EntryPointSymbol>
|
||||
</EntryPointSymbol>
|
||||
<AdditionalDependencies>version.lib;Shlwapi.lib;detours.X64.MTd.lib;%(AdditionalDependencies);ntdll.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>X64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;WUFUC_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<ResourceCompile Condition="'$(APPVEYOR)'=='True'">
|
||||
<PreprocessorDefinitions>BUILD_COMMIT_VERSION=$(BUILD_COMMIT_VERSION);BUILD_VERSION_COMMA=$(BUILD_VERSION_COMMA);$(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
||||
<EntryPointSymbol>
|
||||
</EntryPointSymbol>
|
||||
<AdditionalDependencies>version.lib;Shlwapi.lib;detours.X86.MT.lib;%(AdditionalDependencies);ntdll.lib</AdditionalDependencies>
|
||||
<SetChecksum>true</SetChecksum>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(TargetPath)" "$(SolutionDir)wufuc_setup_bat\"
|
||||
copy /Y "$(TargetPath)" "$(SolutionDir)wufuc_setup\"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Copy release binaries to the setup staging directories</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;WUFUC_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<ResourceCompile Condition="'$(APPVEYOR)'=='True'">
|
||||
<PreprocessorDefinitions>BUILD_COMMIT_VERSION=$(BUILD_COMMIT_VERSION);BUILD_VERSION_COMMA=$(BUILD_VERSION_COMMA);$(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>version.lib;Shlwapi.lib;detours.X64.MT.lib;%(AdditionalDependencies);ntdll.lib</AdditionalDependencies>
|
||||
<SetChecksum>true</SetChecksum>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>X64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(TargetPath)" "$(SolutionDir)wufuc_setup_bat\"
|
||||
copy /Y "$(TargetPath)" "$(SolutionDir)wufuc_setup\"</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>Copy release binaries to the setup staging directories</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
97
src/wufuc/wufuc.vcxproj.filters
Normal file
97
src/wufuc/wufuc.vcxproj.filters
Normal file
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{629a1242-73f5-4282-a218-7b8d7d761cc6}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{e54f7242-67a6-4c85-bf48-0f7a6095b613}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{acf0da3d-e3e4-4fc8-aaf8-8d0558e6414c}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="callbacks.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hooks.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="tracing.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="patternfind.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hlpmem.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hlpmisc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hlpsvc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hlpver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="callbacks.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dllmain.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hooks.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tracing.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rundll32.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stdafx.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="patternfind.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hlpsvc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hlpmem.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hlpver.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hlpmisc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="wufuc.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="wufuc.rch">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="exports.def">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
Reference in New Issue
Block a user