spaces > tabs

This commit is contained in:
zeffy
2017-06-05 15:50:18 -07:00
parent b02ad7a9d6
commit 7f0784424f
7 changed files with 343 additions and 345 deletions

View File

@@ -10,152 +10,151 @@
#include "util.h" #include "util.h"
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);
TCHAR lpBinaryPathName[0x8000]; TCHAR lpBinaryPathName[0x8000];
get_svcpath(hSCManager, _T("wuauserv"), lpBinaryPathName, _countof(lpBinaryPathName)); get_svcpath(hSCManager, _T("wuauserv"), lpBinaryPathName, _countof(lpBinaryPathName));
BOOL result = _tcsicmp(GetCommandLine(), lpBinaryPathName); BOOL result = _tcsicmp(GetCommandLine(), lpBinaryPathName);
CloseServiceHandle(hSCManager); CloseServiceHandle(hSCManager);
if (result) { if (result) {
return 0; return 0;
} }
SECURITY_ATTRIBUTES sa; SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa); sa.nLength = sizeof(sa);
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 cb;
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb); SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
HMODULE hm = GetModuleHandle(NULL); HMODULE hm = GetModuleHandle(NULL);
DETOUR_IAT(hm, LoadLibraryExA); DETOUR_IAT(hm, LoadLibraryExA);
DETOUR_IAT(hm, LoadLibraryExW); DETOUR_IAT(hm, LoadLibraryExW);
HMODULE hwu = GetModuleHandle(_T("wuaueng.dll")); HMODULE hwu = GetModuleHandle(_T("wuaueng.dll"));
if (hwu) { if (hwu) {
PatchWUModule(hwu); PatchWUModule(hwu);
} }
ResumeAndCloseThreads(lphThreads, cb); ResumeAndCloseThreads(lphThreads, cb);
WaitForSingleObject(hEvent, INFINITE); WaitForSingleObject(hEvent, INFINITE);
_tdbgprintf(_T("Received wufuc_UnloadEvent, removing hooks.")); _tdbgprintf(_T("Received wufuc_UnloadEvent, removing hooks."));
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb); SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
RESTORE_IAT(hm, LoadLibraryExA); RESTORE_IAT(hm, LoadLibraryExA);
RESTORE_IAT(hm, LoadLibraryExW); RESTORE_IAT(hm, LoadLibraryExW);
ResumeAndCloseThreads(lphThreads, cb); ResumeAndCloseThreads(lphThreads, cb);
_tdbgprintf(_T("Unloading library. Cya!")); _tdbgprintf(_T("Unloading library. Cya!"));
CloseHandle(hEvent); CloseHandle(hEvent);
FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0); FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0);
return 0; return 0;
} }
BOOL IsWUModule(HMODULE hModule) { BOOL IsWUModule(HMODULE hModule) {
TCHAR lpBaseName[MAX_PATH + 1]; TCHAR lpBaseName[MAX_PATH + 1];
GetModuleBaseName(GetCurrentProcess(), hModule, lpBaseName, _countof(lpBaseName)); GetModuleBaseName(GetCurrentProcess(), hModule, lpBaseName, _countof(lpBaseName));
return !_tcsicmp(lpBaseName, _T("wuaueng.dll")); return !_tcsicmp(lpBaseName, _T("wuaueng.dll"));
} }
BOOL PatchWUModule(HMODULE hModule) { BOOL PatchWUModule(HMODULE hModule) {
if (!IsWindows7Or8Point1()) { if (!IsWindows7Or8Point1()) {
return FALSE; return FALSE;
} }
LPSTR lpszPattern; LPSTR lpszPattern;
SIZE_T n1, n2; SIZE_T n1, n2;
#ifdef _WIN64 #ifdef _WIN64
lpszPattern = lpszPattern =
"FFF3" // push rbx "FFF3" // push rbx
"4883EC??" // sub rsp,?? "4883EC??" // sub rsp,??
"33DB" // xor ebx,ebx "33DB" // xor ebx,ebx
"391D????????" // cmp dword ptr ds:[???????????],ebx "391D????????" // cmp dword ptr ds:[???????????],ebx
"7508" // jnz $+8 "7508" // jnz $+8
"8B05????????"; // mov eax,dword ptr ds:[???????????] "8B05????????"; // mov eax,dword ptr ds:[???????????]
n1 = 10; n1 = 10;
n2 = 18; n2 = 18;
#elif defined(_WIN32) #elif defined(_WIN32)
if (IsWindows8Point1()) { if (IsWindows8Point1()) {
lpszPattern = lpszPattern =
"8BFF" // mov edi,edi "8BFF" // mov edi,edi
"51" // push ecx "51" // push ecx
"833D????????00" // cmp dword ptr ds:[????????],0 "833D????????00" // cmp dword ptr ds:[????????],0
"7507" // jnz $+7 "7507" // jnz $+7
"A1????????"; // mov eax,dword ptr ds:[????????] "A1????????"; // mov eax,dword ptr ds:[????????]
n1 = 5; n1 = 5;
n2 = 13; n2 = 13;
} } else if (IsWindows7()) {
else if (IsWindows7()) { lpszPattern =
lpszPattern = "833D????????00" // cmp dword ptr ds:[????????],0
"833D????????00" // cmp dword ptr ds:[????????],0 "743E" // je $+3E
"743E" // je $+3E "E8????????" // call <wuaueng.IsCPUSupported>
"E8????????" // call <wuaueng.IsCPUSupported> "A3????????"; // mov dword ptr ds:[????????],eax
"A3????????"; // mov dword ptr ds:[????????],eax n1 = 2;
n1 = 2; n2 = 15;
n2 = 15; }
}
#else #else
return FALSE; return FALSE;
#endif #endif
MODULEINFO modinfo; MODULEINFO modinfo;
GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO)); GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO));
SIZE_T offset; SIZE_T offset;
if (!FindPattern(modinfo.lpBaseOfDll, modinfo.SizeOfImage, lpszPattern, 0, &offset)) { if (!FindPattern(modinfo.lpBaseOfDll, modinfo.SizeOfImage, lpszPattern, 0, &offset)) {
return FALSE; return FALSE;
} }
SIZE_T rva = (SIZE_T)modinfo.lpBaseOfDll + offset; SIZE_T rva = (SIZE_T)modinfo.lpBaseOfDll + offset;
_tdbgprintf(_T("IsDeviceServiceable(void) matched at %IX"), rva); _tdbgprintf(_T("IsDeviceServiceable(void) matched at %IX"), rva);
BOOL *lpbNotRunOnce = (BOOL *)(rva + n1 + sizeof(DWORD) + *(DWORD *)(rva + n1)); BOOL *lpbNotRunOnce = (BOOL *)(rva + n1 + sizeof(DWORD) + *(DWORD *)(rva + n1));
if (*lpbNotRunOnce) { if (*lpbNotRunOnce) {
*lpbNotRunOnce = FALSE; *lpbNotRunOnce = FALSE;
_tdbgprintf(_T("Patched %p=%d"), lpbNotRunOnce, *lpbNotRunOnce); _tdbgprintf(_T("Patched %p=%d"), lpbNotRunOnce, *lpbNotRunOnce);
} }
BOOL *lpbCachedResult = (BOOL *)(rva + n2 + sizeof(DWORD) + *(DWORD *)(rva + n2)); BOOL *lpbCachedResult = (BOOL *)(rva + n2 + sizeof(DWORD) + *(DWORD *)(rva + n2));
if (!*lpbCachedResult) { if (!*lpbCachedResult) {
*lpbCachedResult = TRUE; *lpbCachedResult = TRUE;
_tdbgprintf(_T("Patched %p=%d"), lpbCachedResult, *lpbCachedResult); _tdbgprintf(_T("Patched %p=%d"), lpbCachedResult, *lpbCachedResult);
} }
return TRUE; return TRUE;
} }
HMODULE WINAPI _LoadLibraryExA( HMODULE WINAPI _LoadLibraryExA(
_In_ LPCSTR lpFileName, _In_ LPCSTR lpFileName,
_Reserved_ HANDLE hFile, _Reserved_ HANDLE hFile,
_In_ DWORD dwFlags _In_ DWORD dwFlags
) { ) {
HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags); HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags);
if (IsWUModule(result)) { if (IsWUModule(result)) {
PatchWUModule(result); PatchWUModule(result);
} }
return result; return result;
} }
HMODULE WINAPI _LoadLibraryExW( HMODULE WINAPI _LoadLibraryExW(
_In_ LPCWSTR lpFileName, _In_ LPCWSTR lpFileName,
_Reserved_ HANDLE hFile, _Reserved_ HANDLE hFile,
_In_ DWORD dwFlags _In_ DWORD dwFlags
) { ) {
HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags); HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags);
if (IsWUModule(result)) { if (IsWUModule(result)) {
PatchWUModule(result); PatchWUModule(result);
} }
return result; return result;
}; };

View File

@@ -5,13 +5,13 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam);
BOOL PatchWUModule(HMODULE hModule); BOOL PatchWUModule(HMODULE hModule);
HMODULE WINAPI _LoadLibraryExA( HMODULE WINAPI _LoadLibraryExA(
_In_ LPCSTR lpFileName, _In_ LPCSTR lpFileName,
_Reserved_ HANDLE hFile, _Reserved_ HANDLE hFile,
_In_ DWORD dwFlags _In_ DWORD dwFlags
); );
HMODULE WINAPI _LoadLibraryExW( HMODULE WINAPI _LoadLibraryExW(
_In_ LPCWSTR lpFileName, _In_ LPCWSTR lpFileName,
_Reserved_ HANDLE hFile, _Reserved_ HANDLE hFile,
_In_ DWORD dwFlags _In_ DWORD dwFlags
); );

View File

@@ -2,18 +2,18 @@
#include "core.h" #include "core.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:
{ {
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:
break; break;
default: default:
break; break;
} }
return TRUE; return TRUE;
} }

View File

@@ -6,36 +6,36 @@
#include "util.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"));
if (hEvent) { if (hEvent) {
CloseHandle(hEvent); CloseHandle(hEvent);
return; return;
} }
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
TCHAR lpGroupName[256]; TCHAR lpGroupName[256];
DWORD dwProcessId; DWORD dwProcessId;
BOOL result = 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;
} }
TCHAR lpLibFileName[MAX_PATH + 1]; TCHAR lpLibFileName[MAX_PATH + 1];
GetModuleFileName(HINST_THISCOMPONENT, lpLibFileName, _countof(lpLibFileName)); GetModuleFileName(HINST_THISCOMPONENT, lpLibFileName, _countof(lpLibFileName));
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
InjectLibrary(hProcess, lpLibFileName, _countof(lpLibFileName)); InjectLibrary(hProcess, lpLibFileName, _countof(lpLibFileName));
CloseHandle(hProcess); CloseHandle(hProcess);
} }
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) {
_tdbgprintf(_T("Setting wufuc_UnloadEvent...")); _tdbgprintf(_T("Setting wufuc_UnloadEvent..."));
SetEvent(hEvent); SetEvent(hEvent);
CloseHandle(hEvent); CloseHandle(hEvent);
} }
} }

View File

@@ -5,87 +5,87 @@
#include "shellapihelper.h" #include "shellapihelper.h"
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;
QueryServiceConfig(hService, NULL, 0, &cbBytesNeeded); QueryServiceConfig(hService, NULL, 0, &cbBytesNeeded);
LPQUERY_SERVICE_CONFIG sc = malloc(cbBytesNeeded); LPQUERY_SERVICE_CONFIG sc = malloc(cbBytesNeeded);
BOOL result = QueryServiceConfig(hService, sc, cbBytesNeeded, &cbBytesNeeded); BOOL result = QueryServiceConfig(hService, sc, cbBytesNeeded, &cbBytesNeeded);
CloseServiceHandle(hService); CloseServiceHandle(hService);
if (result) { if (result) {
_tcscpy_s(lpBinaryPathName, dwSize, sc->lpBinaryPathName); _tcscpy_s(lpBinaryPathName, dwSize, sc->lpBinaryPathName);
} }
free(sc); free(sc);
return result; return result;
} }
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;
BOOL result = FALSE; BOOL result = FALSE;
if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&lpBuffer, sizeof(lpBuffer), &cbBytesNeeded) && lpBuffer.dwProcessId) { if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&lpBuffer, sizeof(lpBuffer), &cbBytesNeeded) && lpBuffer.dwProcessId) {
*lpdwProcessId = lpBuffer.dwProcessId; *lpdwProcessId = lpBuffer.dwProcessId;
result = TRUE; result = TRUE;
} }
CloseServiceHandle(hService); CloseServiceHandle(hService);
return result; return result;
} }
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);
BOOL result = FALSE; BOOL result = FALSE;
if (!_tcsicmp(fname, _T("svchost"))) { if (!_tcsicmp(fname, _T("svchost"))) {
LPWSTR *p = argv; LPWSTR *p = argv;
for (int i = 1; i < numArgs; i++) { for (int i = 1; i < numArgs; i++) {
if (!_tcsicmp(*(p++), _T("-k"))) { if (!_tcsicmp(*(p++), _T("-k"))) {
_tcscpy_s(lpGroupName, dwSize, *p); _tcscpy_s(lpGroupName, dwSize, *p);
result = TRUE; result = TRUE;
break; break;
} }
} }
} }
return result; return result;
} }
BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwProcessId) { BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwProcessId) {
DWORD uBytes = 0x100000; DWORD uBytes = 0x100000;
LPBYTE pvData = malloc(uBytes); LPBYTE pvData = malloc(uBytes);
RegGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"), lpServiceGroupName, RRF_RT_REG_MULTI_SZ, NULL, pvData, &uBytes); RegGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"), lpServiceGroupName, RRF_RT_REG_MULTI_SZ, NULL, pvData, &uBytes);
BOOL result = FALSE; BOOL result = FALSE;
for (LPTSTR p = (LPTSTR)pvData; *p; p += _tcslen(p) + 1) { for (LPTSTR p = (LPTSTR)pvData; *p; p += _tcslen(p) + 1) {
DWORD dwProcessId; DWORD dwProcessId;
TCHAR group[256]; TCHAR group[256];
if (get_svcpid(hSCManager, p, &dwProcessId)) { if (get_svcpid(hSCManager, p, &dwProcessId)) {
get_svcgname(hSCManager, p, group, _countof(group)); get_svcgname(hSCManager, p, group, _countof(group));
result = !_tcsicmp(group, lpServiceGroupName); result = !_tcsicmp(group, lpServiceGroupName);
} }
if (result) { if (result) {
*lpdwProcessId = dwProcessId; *lpdwProcessId = dwProcessId;
break; break;
} }
} }
free(pvData); free(pvData);
return result; return result;
} }

View File

@@ -6,161 +6,161 @@
#include "util.h" #include "util.h"
BOOL IsWindows7Or8Point1(void) { BOOL IsWindows7Or8Point1(void) {
return IsWindows7() || IsWindows8Point1(); return IsWindows7() || IsWindows8Point1();
} }
BOOL IsWindows7(void) { BOOL IsWindows7(void) {
return IsWindows7OrGreater() && !IsWindows8OrGreater(); return IsWindows7OrGreater() && !IsWindows8OrGreater();
} }
BOOL IsWindows8Point1(void) { BOOL IsWindows8Point1(void) {
return IsWindows8Point1OrGreater() && !IsWindows10OrGreater(); return IsWindows8Point1OrGreater() && !IsWindows10OrGreater();
} }
VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress) { VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress) {
LPVOID *lpAddress = FindIAT(hModule, lpFuncName); LPVOID *lpAddress = FindIAT(hModule, lpFuncName);
if (!lpAddress || *lpAddress == lpNewAddress) { if (!lpAddress || *lpAddress == lpNewAddress) {
return; return;
} }
DWORD flOldProtect; DWORD flOldProtect;
DWORD flNewProtect = PAGE_READWRITE; DWORD flNewProtect = PAGE_READWRITE;
VirtualProtect(lpAddress, sizeof(LPVOID), flNewProtect, &flOldProtect); VirtualProtect(lpAddress, sizeof(LPVOID), flNewProtect, &flOldProtect);
if (lpOldAddress) { if (lpOldAddress) {
*lpOldAddress = *lpAddress; *lpOldAddress = *lpAddress;
} }
_dbgprintf("%s %p => %p", lpFuncName, *lpAddress, lpNewAddress); _dbgprintf("%s %p => %p", lpFuncName, *lpAddress, lpNewAddress);
*lpAddress = lpNewAddress; *lpAddress = lpNewAddress;
VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect); VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect);
} }
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFunctionName) { LPVOID *FindIAT(HMODULE hModule, LPSTR lpFunctionName) {
SIZE_T hm = (SIZE_T)hModule; SIZE_T hm = (SIZE_T)hModule;
for (PIMAGE_IMPORT_DESCRIPTOR iid = (PIMAGE_IMPORT_DESCRIPTOR)(hm + for (PIMAGE_IMPORT_DESCRIPTOR iid = (PIMAGE_IMPORT_DESCRIPTOR)(hm +
((PIMAGE_NT_HEADERS)(hm + ((PIMAGE_DOS_HEADER)hm)->e_lfanew))->OptionalHeader ((PIMAGE_NT_HEADERS)(hm + ((PIMAGE_DOS_HEADER)hm)->e_lfanew))->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
.VirtualAddress); iid->Name; iid++) { .VirtualAddress); iid->Name; iid++) {
LPVOID *p; LPVOID *p;
for (SIZE_T i = 0; *(p = i + (LPVOID *)(hm + iid->FirstThunk)); i++) { for (SIZE_T i = 0; *(p = i + (LPVOID *)(hm + iid->FirstThunk)); i++) {
LPSTR fn = (LPSTR)(hm + *(i + (SIZE_T *)(hm + iid->OriginalFirstThunk)) + 2); LPSTR fn = (LPSTR)(hm + *(i + (SIZE_T *)(hm + iid->OriginalFirstThunk)) + 2);
if (!((uintptr_t)fn & IMAGE_ORDINAL_FLAG) && !_stricmp(lpFunctionName, fn)) { if (!((uintptr_t)fn & IMAGE_ORDINAL_FLAG) && !_stricmp(lpFunctionName, fn)) {
return p; return p;
} }
} }
} }
return NULL; return NULL;
} }
BOOL FindPattern(LPCBYTE pvData, SIZE_T nNumberOfBytes, LPSTR lpszPattern, SIZE_T nStart, SIZE_T *lpOffset) { BOOL FindPattern(LPCBYTE pvData, SIZE_T nNumberOfBytes, LPSTR lpszPattern, SIZE_T nStart, SIZE_T *lpOffset) {
SIZE_T length = strlen(lpszPattern); SIZE_T length = strlen(lpszPattern);
SIZE_T nBytes; SIZE_T nBytes;
if (length % 2 || (nBytes = length / 2) > nNumberOfBytes) { if (length % 2 || (nBytes = length / 2) > nNumberOfBytes) {
return FALSE; return FALSE;
} }
LPBYTE lpBytes = malloc(nBytes * sizeof(BYTE)); LPBYTE lpBytes = malloc(nBytes * sizeof(BYTE));
BOOL *lpbwc = malloc(nBytes * sizeof(BOOL)); BOOL *lpbwc = malloc(nBytes * sizeof(BOOL));
LPSTR p = lpszPattern; LPSTR p = lpszPattern;
BOOL valid = TRUE; BOOL valid = TRUE;
for (SIZE_T i = 0; i < nBytes; i++) { for (SIZE_T i = 0; i < nBytes; i++) {
if ((lpbwc[i] = strncmp(p, "??", 2)) && sscanf_s(p, "%2hhx", &lpBytes[i]) != 1) { if ((lpbwc[i] = strncmp(p, "??", 2)) && sscanf_s(p, "%2hhx", &lpBytes[i]) != 1) {
valid = FALSE; valid = FALSE;
break; break;
} }
p += 2; p += 2;
} }
BOOL result = FALSE; BOOL result = FALSE;
if (valid) { if (valid) {
for (SIZE_T i = nStart; i < nNumberOfBytes - nStart - (nBytes - 1); i++) { for (SIZE_T i = nStart; i < nNumberOfBytes - nStart - (nBytes - 1); i++) {
BOOL found = TRUE; BOOL found = TRUE;
for (SIZE_T j = 0; j < nBytes; j++) { for (SIZE_T j = 0; j < nBytes; j++) {
if (lpbwc[j] && pvData[i + j] != lpBytes[j]) { if (lpbwc[j] && pvData[i + j] != lpBytes[j]) {
found = FALSE; found = FALSE;
break; break;
} }
} }
if (found) { if (found) {
*lpOffset = i; *lpOffset = i;
result = TRUE; result = TRUE;
break; break;
} }
} }
} }
free(lpBytes); free(lpBytes);
free(lpbwc); free(lpbwc);
return result; return result;
} }
BOOL InjectLibrary(HANDLE hProcess, LPCTSTR lpLibFileName, DWORD cb) { BOOL InjectLibrary(HANDLE hProcess, LPCTSTR lpLibFileName, DWORD cb) {
LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, cb, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, cb, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (!WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, cb, NULL)) { if (!WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, cb, NULL)) {
return FALSE; return FALSE;
} }
DWORD dwProcessId = GetProcessId(hProcess); DWORD dwProcessId = GetProcessId(hProcess);
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId); HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
MODULEENTRY32 me; MODULEENTRY32 me;
me.dwSize = sizeof(me); me.dwSize = sizeof(me);
Module32First(hSnap, &me); Module32First(hSnap, &me);
do { do {
if (!_tcsicmp(me.szModule, _T("kernel32.dll"))) { if (!_tcsicmp(me.szModule, _T("kernel32.dll"))) {
break; break;
} }
} while (Module32Next(hSnap, &me)); } while (Module32Next(hSnap, &me));
CloseHandle(hSnap); CloseHandle(hSnap);
_tdbgprintf(_T("Injecting %s into process %d"), lpLibFileName, dwProcessId); _tdbgprintf(_T("Injecting %s into process %d"), lpLibFileName, dwProcessId);
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(me.hModule, _CRT_STRINGIZE(LoadLibrary)), lpBaseAddress, 0, NULL); HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(me.hModule, _CRT_STRINGIZE(LoadLibrary)), lpBaseAddress, 0, NULL);
CloseHandle(hThread); CloseHandle(hThread);
return TRUE; return TRUE;
} }
VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb) { VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb) {
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
THREADENTRY32 te; THREADENTRY32 te;
te.dwSize = sizeof(te); te.dwSize = sizeof(te);
Thread32First(hSnap, &te); Thread32First(hSnap, &te);
SIZE_T count = 0; SIZE_T count = 0;
do { do {
if (te.th32OwnerProcessID != dwProcessId || te.th32ThreadID == dwThreadId) { if (te.th32OwnerProcessID != dwProcessId || te.th32ThreadID == dwThreadId) {
continue; continue;
} }
lphThreads[count] = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID); lphThreads[count] = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID);
SuspendThread(lphThreads[count]); SuspendThread(lphThreads[count]);
count++; count++;
} while (count < dwSize && Thread32Next(hSnap, &te)); } while (count < dwSize && Thread32Next(hSnap, &te));
CloseHandle(hSnap); CloseHandle(hSnap);
*lpcb = count; *lpcb = count;
_tdbgprintf(_T("Suspended other threads.")); _tdbgprintf(_T("Suspended other threads."));
} }
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) { VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) {
for (SIZE_T i = 0; i < cb; i++) { for (SIZE_T i = 0; i < cb; i++) {
ResumeThread(lphThreads[i]); ResumeThread(lphThreads[i]);
CloseHandle(lphThreads[i]); CloseHandle(lphThreads[i]);
} }
_tdbgprintf(_T("Resumed threads.")); _tdbgprintf(_T("Resumed threads."));
} }
VOID _wdbgprintf(LPCWSTR format, ...) { VOID _wdbgprintf(LPCWSTR format, ...) {
WCHAR buffer[0x1000]; WCHAR buffer[0x1000];
va_list argptr; va_list argptr;
va_start(argptr, format); va_start(argptr, format);
vswprintf_s(buffer, _countof(buffer), format, argptr); vswprintf_s(buffer, _countof(buffer), format, argptr);
va_end(argptr); va_end(argptr);
OutputDebugStringW(buffer); OutputDebugStringW(buffer);
} }
VOID _dbgprintf(LPCSTR format, ...) { VOID _dbgprintf(LPCSTR format, ...) {
CHAR buffer[0x1000]; CHAR buffer[0x1000];
va_list argptr; va_list argptr;
va_start(argptr, format); va_start(argptr, format);
vsprintf_s(buffer, _countof(buffer), format, argptr); vsprintf_s(buffer, _countof(buffer), format, argptr);
va_end(argptr); va_end(argptr);
OutputDebugStringA(buffer); OutputDebugStringA(buffer);
} }

View File

@@ -39,4 +39,3 @@ VOID _dbgprintf(LPCSTR format, ...);
//#else //#else
//#define _tdbgprintf(format, ...) //#define _tdbgprintf(format, ...)
//#endif // !_DEBUG //#endif // !_DEBUG