6 Commits

Author SHA1 Message Date
zeffy
32753e64a2 remove cast 2017-07-01 05:19:57 -07:00
zeffy
be6ac618c2 hmm 2017-07-01 04:45:20 -07:00
zeffy
0070add1f7 simplified some code, security improvements, etc 2017-07-01 04:33:29 -07:00
zeffy
2eb61f8667 Ctrl+R,R has failed me 🤔 2017-06-30 19:20:02 -07:00
zeffy
dd40fdc30a improved logging and more
- write cpu and os info to log
- revise some log messages to be more uniform
- remove reference to .gitattributes 😠
- refactor some stuff
- refuse to load when in wow64 mode
2017-06-30 19:17:25 -07:00
zeffy
b335dffba3 Update README.md 2017-06-30 17:19:36 -07:00
8 changed files with 146 additions and 83 deletions

View File

@@ -24,7 +24,7 @@ These updates marked the implementation of a [policy change](https://blogs.windo
It was essentially a big middle finger to anyone who decides to not "upgrade" to the steaming pile of :shit: known as Windows 10, especially considering the extended support periods for Windows 7 and 8.1 won't be ending until January 4, 2020 and January 10, 2023 respectively.
This has even affected people with older Intel and AMD processors! I've received user reports of the [Intel Atom Z530](../../issues/7), [Intel Core i5-M 560](../../issues/23), [Intel Core i5-4300M](../../issues/24), [Intel Atom D525](../../issues/34), and [AMD FX-8350](../../issues/32) all being blocked from receiving updates.
This has even affected people with older Intel and AMD processors! I've received user reports of the [Intel Atom Z530](../../issues/7), [Intel Core i5-M 560](../../issues/23), [Intel Core i5-4300M](../../issues/24), [Intel Atom D525](../../issues/34), [Intel Pentium B940](../../issues/63), and [AMD FX-8350](../../issues/32) all being blocked from receiving updates.
## Bad Microsoft!

View File

@@ -7,7 +7,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wufuc", "wufuc\wufuc.vcxpro
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8C2147FF-2B83-479B-813E-5ACB86F43042}"
ProjectSection(SolutionItems) = preProject
.gitattributes = .gitattributes
.gitignore = .gitignore
appveyor.yml = appveyor.yml
CONTRIBUTING.md = CONTRIBUTING.md

View File

@@ -43,7 +43,7 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) {
DETOUR_IAT(hm, LoadLibraryExA);
DETOUR_IAT(hm, LoadLibraryExW);
TCHAR lpServiceDll[MAX_PATH + 1];
TCHAR lpServiceDll[MAX_PATH];
get_svcdll(_T("wuauserv"), lpServiceDll, _countof(lpServiceDll));
HMODULE hwu = GetModuleHandle(lpServiceDll);
@@ -54,7 +54,7 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) {
WaitForSingleObject(hEvent, INFINITE);
dwprintf(L"Unload event was set.");
dwprintf(L"Unloading...");
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
RESTORE_IAT(hm, LoadLibraryExA);
@@ -62,7 +62,7 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) {
ResumeAndCloseThreads(lphThreads, cb);
CloseHandle(hEvent);
dwprintf(L"See ya!");
dwprintf(L"Bye bye!");
close_log();
FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0);
}
@@ -75,11 +75,11 @@ BOOL PatchWUAgentHMODULE(HMODULE hModule) {
offset00 = 10;
offset01 = 18;
#elif defined(_X86_)
if (g_IsWindows7) {
if (IsWindows7()) {
pattern = "833D????????00 743E E8???????? A3????????";
offset00 = 2;
offset01 = 15;
} else if (g_IsWindows8Point1) {
} else if (IsWindows8Point1()) {
pattern = "8BFF 51 833D????????00 7507 A1????????";
offset00 = 5;
offset01 = 13;
@@ -97,26 +97,26 @@ BOOL PatchWUAgentHMODULE(HMODULE hModule) {
return FALSE;
}
uintptr_t baseAddress = (uintptr_t)modinfo.lpBaseOfDll;
uintptr_t fpIsDeviceServiceable = baseAddress + rva;
dwprintf(L"Found address of IsDeviceServiceable. (%p)", fpIsDeviceServiceable);
uintptr_t lpfnIsDeviceServiceable = baseAddress + rva;
dwprintf(L"Address of wuaueng.dll!IsDeviceServiceable: %p", lpfnIsDeviceServiceable);
BOOL result = FALSE;
LPBOOL lpbFirstRun, lpbIsCPUSupportedResult;
#ifdef _AMD64_
lpbFirstRun = (LPBOOL)(fpIsDeviceServiceable + offset00 + sizeof(uint32_t) + *(uint32_t *)(fpIsDeviceServiceable + offset00));
lpbIsCPUSupportedResult = (LPBOOL)(fpIsDeviceServiceable + offset01 + sizeof(uint32_t) + *(uint32_t *)(fpIsDeviceServiceable + offset01));
lpbFirstRun = (LPBOOL)(lpfnIsDeviceServiceable + offset00 + sizeof(uint32_t) + *(uint32_t *)(lpfnIsDeviceServiceable + offset00));
lpbIsCPUSupportedResult = (LPBOOL)(lpfnIsDeviceServiceable + offset01 + sizeof(uint32_t) + *(uint32_t *)(lpfnIsDeviceServiceable + offset01));
#elif defined(_X86_)
lpbFirstRun = (LPBOOL)(*(uintptr_t *)(fpIsDeviceServiceable + offset00));
lpbIsCPUSupportedResult = (LPBOOL)(*(uintptr_t *)(fpIsDeviceServiceable + offset01));
lpbFirstRun = (LPBOOL)(*(uintptr_t *)(lpfnIsDeviceServiceable + offset00));
lpbIsCPUSupportedResult = (LPBOOL)(*(uintptr_t *)(lpfnIsDeviceServiceable + offset01));
#endif
if (*lpbFirstRun) {
*lpbFirstRun = FALSE;
dwprintf(L"Unset first run var. (%p=%08x)", lpbFirstRun, *lpbFirstRun);
dwprintf(L"Patched FirstRun variable: %p = %08x", lpbFirstRun, *lpbFirstRun);
result = TRUE;
}
if (!*lpbIsCPUSupportedResult) {
*lpbIsCPUSupportedResult = TRUE;
dwprintf(L"Set cached result. (%p=%08x)", lpbIsCPUSupportedResult, *lpbIsCPUSupportedResult);
dwprintf(L"Patched cached wuaueng.dll!IsCPUSupported result: %p = %08x", lpbIsCPUSupportedResult, *lpbIsCPUSupportedResult);
result = TRUE;
}
return result;
@@ -129,12 +129,11 @@ HMODULE WINAPI _LoadLibraryExA(
) {
HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags);
if (result) {
dwprintf(L"Loaded %S.", lpFileName);
CHAR path[MAX_PATH + 1];
dwprintf(L"Loaded library: %S", lpFileName);
CHAR path[MAX_PATH];
if (!get_svcdllA("wuauserv", path, _countof(path))) {
return result;
}
if (!_stricmp(lpFileName, path) && PatchWUAgentHMODULE(result)) {
dwprintf(L"Patched Windows Update module!");
}
@@ -149,12 +148,11 @@ HMODULE WINAPI _LoadLibraryExW(
) {
HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags);
if (result) {
dwprintf(L"Loaded library: %s.", lpFileName);
WCHAR path[MAX_PATH + 1];
dwprintf(L"Loaded library: %s", lpFileName);
WCHAR path[MAX_PATH];
if (!get_svcdllW(L"wuauserv", path, _countof(path))) {
return result;
}
if (!_wcsicmp(lpFileName, path) && PatchWUAgentHMODULE(result)) {
dwprintf(L"Patched Windows Update module!");
}

View File

@@ -6,10 +6,9 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
{
if (!IsOperatingSystemSupported(&g_IsWindows7, &g_IsWindows8Point1)) {
if (!IsOperatingSystemSupported() || IsWow64()) {
return FALSE;
}
DisableThreadLibraryCalls(hModule);
HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL);
CloseHandle(hThread);

View File

@@ -1,19 +1,41 @@
#include <Windows.h>
#include <TlHelp32.h>
#include <tchar.h>
#include <VersionHelpers.h>
#include "service.h"
#include "util.h"
void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
if (!g_IsWindows7 && !g_IsWindows8Point1) {
return;
}
HANDLE hEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("Global\\wufuc_UnloadEvent"));
if (hEvent) {
CloseHandle(hEvent);
return;
}
LPWSTR osname;
if (IsWindows7()) {
if (IsWindowsServer()) {
osname = L"Windows Server 2008 R2";
} else {
osname = L"Windows 7";
}
} else if (IsWindows8Point1()) {
if (IsWindowsServer()) {
osname = L"Windows Server 2012 R2";
} else {
osname = L"Windows 8.1";
}
}
dwprintf(L"Operating System: %s %d-bit", osname, sizeof(uintptr_t) * 8);
char brand[0x31];
get_cpuid_brand(brand);
SIZE_T i = 0;
while (i < _countof(brand) && isspace(*(brand + i))) {
i++;
}
dwprintf(L"Processor: %S", brand + i);
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
if (!hSCManager) {
return;
@@ -28,34 +50,26 @@ void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int n
if (!result) {
return;
}
TCHAR lpLibFileName[MAX_PATH + 1];
TCHAR lpLibFileName[MAX_PATH];
GetModuleFileName(HINST_THISCOMPONENT, lpLibFileName, _countof(lpLibFileName));
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (!hProcess) {
return;
}
LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, _countof(lpLibFileName) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (lpBaseAddress && WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, _countof(lpLibFileName), NULL)) {
LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, sizeof(lpLibFileName), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (lpBaseAddress && WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, sizeof(lpLibFileName), NULL)) {
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
if (hSnap) {
MODULEENTRY32 me;
me.dwSize = sizeof(me);
if (Module32First(hSnap, &me)) {
do {
if (!_tcsicmp(me.szModule, _T("kernel32.dll"))) {
break;
}
} while (Module32Next(hSnap, &me));
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(me.hModule, STRINGIZE(LoadLibrary)), lpBaseAddress, 0, NULL);
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32.dll"),
STRINGIZE(LoadLibrary)),
lpBaseAddress, 0, NULL
);
WaitForSingleObject(hThread, INFINITE);
dwprintf(L"Injected into process: %d", dwProcessId);
CloseHandle(hThread);
}
CloseHandle(hSnap);
}
}
VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE);
CloseHandle(hProcess);
close_log();
}

View File

@@ -6,27 +6,24 @@
#include "service.h"
BOOL get_svcdllA(LPCSTR lpServiceName, LPSTR lpServiceDll, DWORD dwSize) {
CHAR lpSubKey[MAX_PATH + 1];
CHAR lpSubKey[257];
sprintf_s(lpSubKey, _countof(lpSubKey), "SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", lpServiceName);
DWORD uBytes = _MAX_PATH + 1;
LPBYTE pvData = malloc(uBytes);
RegGetValueA(HKEY_LOCAL_MACHINE, lpSubKey, "ServiceDll", RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND, NULL, pvData, &uBytes);
ExpandEnvironmentStringsA((LPSTR)pvData, lpServiceDll, dwSize);
DWORD cb = dwSize;
if (RegGetValueA(HKEY_LOCAL_MACHINE, lpSubKey, "ServiceDll", RRF_RT_REG_SZ, NULL, lpServiceDll, &cb)) {
return FALSE;
}
dwprintf(L"Service \"%S\" DLL path: %S", lpServiceName, lpServiceDll);
return TRUE;
}
BOOL get_svcdllW(LPCWSTR lpServiceName, LPWSTR lpServiceDll, DWORD dwSize) {
WCHAR lpSubKey[MAX_PATH + 1];
WCHAR lpSubKey[257];
swprintf_s(lpSubKey, _countof(lpSubKey), L"SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", lpServiceName);
DWORD uBytes = _MAX_PATH + 1;
LPBYTE pvData = malloc(uBytes);
RegGetValueW(HKEY_LOCAL_MACHINE, lpSubKey, L"ServiceDll", RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND, NULL, pvData, &uBytes);
ExpandEnvironmentStringsW((LPWSTR)pvData, lpServiceDll, dwSize);
DWORD cb = dwSize;
if (RegGetValueW(HKEY_LOCAL_MACHINE, lpSubKey, L"ServiceDll", RRF_RT_REG_SZ, NULL, lpServiceDll, &cb)) {
return FALSE;
}
dwprintf(L"Service \"%s\" DLL path: %s", lpServiceName, lpServiceDll);
return TRUE;
}
@@ -44,9 +41,9 @@ BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessI
*lpdwProcessId = lpBuffer.dwProcessId;
#ifdef _UNICODE
dwprintf(L"Got pid for service %s: %d.", lpServiceName, *lpdwProcessId);
dwprintf(L"Service \"%s\" process ID: %d", lpServiceName, *lpdwProcessId);
#else
dwprintf(L"Got pid for service %S: %d.", lpServiceName, *lpdwProcessId);
dwprintf(L"Service \"%S\" process ID: %d", lpServiceName, *lpdwProcessId);
#endif
result = TRUE;
}
@@ -59,6 +56,7 @@ BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupNam
if (!get_svcpath(hSCManager, lpServiceName, lpBinaryPathName, _countof(lpBinaryPathName))) {
return FALSE;
}
int numArgs;
LPWSTR *argv = CommandLineToArgv(lpBinaryPathName, &numArgs);
if (numArgs < 3) {
@@ -75,9 +73,9 @@ BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupNam
if (!_tcsicmp(*(p++), _T("-k")) && !_tcscpy_s(lpGroupName, dwSize, *p)) {
result = TRUE;
#ifdef _UNICODE
dwprintf(L"Got group name of service %s: %s.", lpServiceName, lpGroupName);
dwprintf(L"Service \"%s\" group name: %s", lpServiceName, lpGroupName);
#else
dwprintf(L"Got group name of service %S: %S.", lpServiceName, lpGroupName);
dwprintf(L"Service \"%S\" group name: %S", lpServiceName, lpGroupName);
#endif
break;
}
@@ -105,7 +103,7 @@ BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPat
}
BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwProcessId) {
DWORD uBytes = 0x100000;
DWORD uBytes = 1 << 20;
LPBYTE pvData = malloc(uBytes);
RegGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"),
lpServiceGroupName, RRF_RT_REG_MULTI_SZ, NULL, pvData, &uBytes);
@@ -120,9 +118,9 @@ BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwPro
*lpdwProcessId = dwProcessId;
result = TRUE;
#ifdef _UNICODE
dwprintf(L"Got pid for service group %s: %d.", lpServiceGroupName, *lpdwProcessId);
dwprintf(L"Service group \"%s\" process ID: %d", lpServiceGroupName, *lpdwProcessId);
#else
dwprintf(L"Got pid for service group %S: %d.", lpServiceGroupName, *lpdwProcessId);
dwprintf(L"Service group \"%S\" process ID: %d", lpServiceGroupName, *lpdwProcessId);
#endif
break;
}

View File

@@ -1,13 +1,20 @@
#include <Windows.h>
#include <stdio.h>
#include <time.h>
#include <stdint.h>
#include <intrin.h>
#include <tchar.h>
#include <TlHelp32.h>
#include <Psapi.h>
#include "util.h"
BOOL g_IsWindows7 = FALSE;
BOOL g_IsWindows8Point1 = FALSE;
static BOOL checkedIsWindows7 = FALSE;
static BOOL isWindows7 = FALSE;
static BOOL checkedIsWindows8Point1 = FALSE;
static BOOL isWindows8Point1 = FALSE;
static LPFN_ISWOW64PROCESS fnIsWow64Process = NULL;
static BOOL checkedIsWow64 = FALSE;
static BOOL isWow64 = FALSE;
static FILE *log_fp = NULL;
@@ -40,7 +47,7 @@ VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID l
if (lpOldAddress) {
*lpOldAddress = *lpAddress;
}
dwprintf(L"Detoured %S from %p to %p.", lpFuncName, *lpAddress, lpNewAddress);
dwprintf(L"Modified %S import address: %p => %p", lpFuncName, *lpAddress, lpNewAddress);
*lpAddress = lpNewAddress;
VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect);
}
@@ -64,7 +71,7 @@ VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThrea
CloseHandle(hSnap);
*lpcb = count;
dwprintf(L"Suspended %d other threads.", count);
dwprintf(L"Suspended %d other threads", count);
}
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) {
@@ -72,7 +79,7 @@ VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) {
ResumeThread(lphThreads[i]);
CloseHandle(lphThreads[i]);
}
dwprintf(L"Resumed %d other threads.", cb);
dwprintf(L"Resumed %d other threads", cb);
}
BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask) {
@@ -93,25 +100,69 @@ BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVer
return VerifyVersionInfo(&osvi, dwTypeMask, dwlConditionMask);
}
BOOL IsOperatingSystemSupported(LPBOOL lpbIsWindows7, LPBOOL lpbIsWindows8Point1) {
BOOL IsWindows7(void) {
if (!checkedIsWindows7) {
isWindows7 = CompareWindowsVersion(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION);
checkedIsWindows7 = TRUE;
}
return isWindows7;
}
BOOL IsWindows8Point1(void) {
if (!checkedIsWindows8Point1) {
isWindows8Point1 = CompareWindowsVersion(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION);
checkedIsWindows8Point1 = TRUE;
}
return isWindows8Point1;
}
BOOL IsOperatingSystemSupported(void) {
#if !defined(_AMD64_) && !defined(_X86_)
return FALSE;
#else
return (*lpbIsWindows7 = CompareWindowsVersion(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION))
|| (*lpbIsWindows8Point1 = CompareWindowsVersion(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION));
return IsWindows7() || IsWindows8Point1();
#endif
}
BOOL IsWow64(void) {
if (!checkedIsWow64) {
if (!fnIsWow64Process) {
fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "IsWow64Process");
}
if (fnIsWow64Process && fnIsWow64Process(GetCurrentProcess(), &isWow64)) {
checkedIsWow64 = TRUE;
}
}
return isWow64;
}
void get_cpuid_brand(char* brand) {
int info[4];
__cpuidex(info, 0x80000000, 0);
if (info[0] < 0x80000004) {
brand[0] = '\0';
return;
}
uint32_t *char_as_int = (uint32_t *)brand;
for (int op = 0x80000002; op <= 0x80000004; op++) {
__cpuidex(info, op, 0);
*(char_as_int++) = info[0];
*(char_as_int++) = info[1];
*(char_as_int++) = info[2];
*(char_as_int++) = info[3];
}
}
BOOL init_log(void) {
if (log_fp) {
return TRUE;
}
WCHAR filename[MAX_PATH + 1];
WCHAR filename[MAX_PATH];
GetModuleFileNameW(HINST_THISCOMPONENT, filename, _countof(filename));
WCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME];
_wsplitpath_s(filename, drive, _countof(drive), dir, _countof(dir), fname, _countof(fname), NULL, 0);
WCHAR basename[MAX_PATH + 1];
WCHAR basename[MAX_PATH];
GetModuleBaseNameW(GetCurrentProcess(), NULL, basename, _countof(basename));
wcscat_s(fname, _countof(fname), L".");
wcscat_s(fname, _countof(fname), basename);

View File

@@ -3,8 +3,7 @@
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
extern BOOL g_IsWindows7;
extern BOOL g_IsWindows8Point1;
typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFuncName);
VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress);
@@ -13,7 +12,12 @@ VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThrea
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T dwSize);
BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask);
BOOL IsOperatingSystemSupported(LPBOOL lpbIsWindows7, LPBOOL lpbIsWindows8Point1);
BOOL IsWindows7(void);
BOOL IsWindows8Point1(void);
BOOL IsOperatingSystemSupported(void);
BOOL IsWow64(void);
void get_cpuid_brand(char *brand);
VOID dwprintf_(LPCWSTR format, ...);