commit a190787f3bc221bbd30386092a2a75ef6a7a9c0f Author: Bommels05 <69975756+Bommels05@users.noreply.github.com> Date: Thu Mar 12 12:07:23 2026 +0100 Initial Commit diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..25a6ae2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 4.1) +project(BCompat) + +if (CMAKE_SIZEOF_VOID_P EQUAL 4) + set(CMAKE_C_FLAGS -m32) + set(CMAKE_CXX_FLAGS -m32) +endif () +set(CMAKE_SHARED_LINKER_FLAGS -Wl,--kill-at) + +option(ZYDIS_BUILD_TOOLS "" OFF) +option(ZYDIS_BUILD_EXAMPLES "" OFF) +add_subdirectory("deps/zydis") + +set(CMAKE_CXX_STANDARD 20) + +add_executable(patcher main.cpp dll.c) + +target_link_libraries(patcher Zydis imagehlp) + +if (CMAKE_SIZEOF_VOID_P EQUAL 4) + add_library(bcompat SHARED dll.c) + target_link_libraries(bcompat -static-libgcc) + set_target_properties(bcompat PROPERTIES PREFIX "") + #target_compile_options(bcompat PRIVATE -march=pentium) + add_library(user32 SHARED user32.c) + target_link_libraries(user32 -static-libgcc) + set_target_properties(user32 PROPERTIES PREFIX "") +endif () + +add_executable(bconfig config.c config.rc) +target_link_libraries(bconfig comctl32) diff --git a/config.c b/config.c new file mode 100644 index 0000000..103c460 --- /dev/null +++ b/config.c @@ -0,0 +1,189 @@ +#include +#include +#include + +#define MAX_FUNCTION_COUNT 8 + +struct ReportedVersion { + LPCSTR name; + DWORD major; + DWORD minor; + DWORD build; + DWORD platform; +}; +typedef struct ReportedVersion ReportedVersion; +struct FunctionVersion { + LPCSTR name; + LPCSTR functions[MAX_FUNCTION_COUNT]; +}; +typedef struct FunctionVersion FunctionVersion; + +ReportedVersion reportedVersions[] = { + { "Win32s", 4, 0, 950, VER_PLATFORM_WIN32s }, + { "Windows NT 3.1", 3, 10, 511, VER_PLATFORM_WIN32_NT }, + { "Windows NT 3.50", 3, 50, 807, VER_PLATFORM_WIN32_NT }, + { "Windows NT 3.51", 3, 51, 1057, VER_PLATFORM_WIN32_NT }, + { "Windows 95", 4, 0, 950, VER_PLATFORM_WIN32_WINDOWS }, + { "Windows NT 4.0", 4, 0, 1381, VER_PLATFORM_WIN32_NT } +}; +FunctionVersion functionVersions[] = { + { "Windows NT 4.0", "kernel32.dllGetVersionEx", "kernel32.dllGetVersion"} +}; + +BOOL reportedChanged; +BOOL functionChanged ; + +INT_PTR CALLBACK GlobalPageProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + switch (uMsg) { + case WM_INITDIALOG: + reportedChanged = FALSE; + functionChanged = FALSE; + + HWND reportedBox = GetDlgItem(hWnd, 1); + for (int i = 0; i < ARRAYSIZE(reportedVersions); i++) { + ListBox_AddString(reportedBox, reportedVersions[i].name); + } + HWND functionBox = GetDlgItem(hWnd, 2); + for (int i = 0; i < ARRAYSIZE(functionVersions); i++) { + ListBox_AddString(functionBox, functionVersions[i].name); + } + + HKEY key; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\BCompat"), 0, KEY_READ, &key) == ERROR_SUCCESS) { + DWORD size; + DWORD major = 0; + RegQueryValueEx(key, TEXT("ReportedMajor"), NULL, NULL, (LPBYTE) &major, &size); + DWORD minor = 0; + RegQueryValueEx(key, TEXT("ReportedMinor"), NULL, NULL, (LPBYTE) &minor, &size); + DWORD build = 0; + RegQueryValueEx(key, TEXT("ReportedBuild"), NULL, NULL, (LPBYTE) &build, &size); + DWORD platform = 0; + RegQueryValueEx(key, TEXT("ReportedPlatform"), NULL, NULL, (LPBYTE) &platform, &size); + RegCloseKey(key); + for (int i = 0; i < ARRAYSIZE(reportedVersions); i++) { + ReportedVersion version = reportedVersions[i]; + if (major == version.major && minor == version.minor && build == version.build && platform == version.platform) { + ListBox_SetCurSel(reportedBox, i); + } + } + } + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\BCompat\\Functions"), 0, KEY_READ, &key) == ERROR_SUCCESS) { + TCHAR functions[MAX_FUNCTION_COUNT][64]; + DWORD nameLength = 64; + int count = 0; + while (RegEnumKeyEx(key, count, functions[count], &nameLength, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { + count++; + } + for (int i = 0; i < ARRAYSIZE(functionVersions); i++) { + FunctionVersion version = functionVersions[i]; + int x; + for (x = 0; x < ARRAYSIZE(version.functions) && version.functions[x] != NULL; x++) { + BOOL found = FALSE; + for (int y = 0; y < count; ++y) { + if (strcmp(functions[y], version.functions[x]) == 0) { + found = TRUE; + break; + } + } + if (!found) { + goto outer; + } + } + if (x == count) { + ListBox_SetCurSel(functionBox, i); + } + outer: + } + RegCloseKey(key); + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case 1: + switch (HIWORD(wParam)) { + case LBN_SELCHANGE: + PropSheet_Changed(GetParent(hWnd), hWnd); + reportedChanged = TRUE; + break; + } + break; + case 2: + switch (HIWORD(wParam)) { + case LBN_SELCHANGE: + PropSheet_Changed(GetParent(hWnd), hWnd); + functionChanged = TRUE; + break; + } + break; + } + break; + case WM_NOTIFY: + switch (((NMHDR *)lParam)->code) { + case PSN_APPLY: + if (reportedChanged) { + reportedChanged = FALSE; + ReportedVersion version = reportedVersions[ListBox_GetCurSel(GetDlgItem(hWnd, 1))]; + HKEY key; + RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\BCompat"), 0, NULL, 0, KEY_WRITE, NULL, &key, NULL); + RegSetValueEx(key, "ReportedMajor", 0, REG_DWORD, (LPBYTE) &version.major, sizeof(DWORD)); + RegSetValueEx(key, "ReportedMinor", 0, REG_DWORD, (LPBYTE) &version.minor, sizeof(DWORD)); + RegSetValueEx(key, "ReportedBuild", 0, REG_DWORD, (LPBYTE) &version.build, sizeof(DWORD)); + RegSetValueEx(key, "ReportedPlatform", 0, REG_DWORD, (LPBYTE) &version.platform, sizeof(DWORD)); + RegCloseKey(key); + } + if (functionChanged) { + functionChanged = FALSE; + FunctionVersion version = functionVersions[ListBox_GetCurSel(GetDlgItem(hWnd, 2))]; + HKEY key; + RegDeleteKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\BCompat\\Functions")); + RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\BCompat\\Functions"), 0, NULL, 0, KEY_WRITE, NULL, &key, NULL); + for (int i = 0; i < ARRAYSIZE(version.functions) && version.functions[i] != NULL; i++) { + DWORD value = 0; + RegSetValueEx(key, version.functions[i], 0, REG_DWORD, (LPBYTE) &value, sizeof(DWORD)); + } + RegCloseKey(key); + } + } + } + return FALSE; +} + +int main() { + HMODULE instance = GetModuleHandle(NULL); + + PROPSHEETPAGE psp[1]; + + PROPSHEETHEADER psh; + + psp[0].dwSize = sizeof(PROPSHEETPAGE); + psp[0].dwFlags = PSP_USETITLE; + psp[0].hInstance = instance; + psp[0].pszTemplate = MAKEINTRESOURCE(1); + psp[0].pszIcon = NULL; + psp[0].pfnDlgProc = GlobalPageProc; + psp[0].pszTitle = "Global"; + psp[0].lParam = 0; + psp[0].pfnCallback = NULL; + /*psp[1].dwSize = sizeof(PROPSHEETPAGE); + psp[1].dwFlags = PSP_USETITLE; + psp[1].hInstance = instance; + psp[1].pszTemplate = MAKEINTRESOURCE(2); + psp[1].pszIcon = NULL; + psp[1].pfnDlgProc = AboutPageProc; + psp[1].pszTitle = "About"; + psp[1].lParam = 0; + psp[1].pfnCallback = NULL;*/ + + psh.dwSize = sizeof(PROPSHEETHEADER); + psh.dwFlags = PSH_PROPSHEETPAGE; + psh.hwndParent = NULL; + psh.hInstance = instance; + psh.pszIcon = NULL; + psh.pszCaption = "BCompat Settings"; + psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE); + psh.nStartPage = 0; + psh.ppsp = (LPCPROPSHEETPAGE) &psp; + psh.pfnCallback = NULL; + + PropertySheet(&psh); +} diff --git a/config.rc b/config.rc new file mode 100644 index 0000000..d1d2b3e --- /dev/null +++ b/config.rc @@ -0,0 +1,11 @@ +#include + +1 DIALOG DISCARDABLE 0, 0, 215, 125 +STYLE WS_CHILD | WS_VISIBLE | WS_BORDER +FONT 9, "SEGOE UI" +{ + CTEXT "Reported Version:", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 5, 5, 60, 10 + CONTROL "ReportedBox", 1, "ListBox", LBS_STANDARD | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 15, 85, 100 + CTEXT "Function Version:", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 95, 5, 60, 10 + CONTROL "FunctionBox", 2, "ListBox", LBS_STANDARD | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 95, 15, 85, 100 +} diff --git a/dll.c b/dll.c new file mode 100644 index 0000000..76606e3 --- /dev/null +++ b/dll.c @@ -0,0 +1,86 @@ +#define WIN32_LEAN_AND_MEAN +#define NOUSER +#include +#include +#include + +#define DLL_EXPORT __declspec(dllexport) + +typedef int (WINAPI *MessageBoxAPtr)(HWND hwnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); +typedef int (WINAPI *MessageBoxWPtr)(HWND hwnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType); + +DLL_EXPORT WINAPI int MessageBoxA(HWND hwnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { + MessageBoxAPtr proc = (MessageBoxAPtr) GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA"); + LPSTR buffer = malloc(strlen(lpText) + 1 + 26); + strcpy(buffer, "MessageBoxA gruesst Sie!\n"), + strcat(buffer, lpText); + int result = proc(hwnd, buffer, lpCaption, uType); + free(buffer); + return result; + return 0; +} + +DLL_EXPORT WINAPI int MessageBoxW(HWND hwnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) { + MessageBoxWPtr proc = (MessageBoxWPtr) GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxW"); + LPWSTR buffer = malloc(wcslen(lpText) + 1 + 26); + wcscpy(buffer, L"MessageBoxW gruesst Sie!\n"); + wcscat(buffer, lpText); + int result = proc(hwnd, buffer, lpCaption, uType); + free(buffer); + return result; +} + +DLL_EXPORT WINAPI BOOL GetVersionExW(LPOSVERSIONINFOW version) { + if (version->dwOSVersionInfoSize == sizeof(OSVERSIONINFOW)) { + version->dwMajorVersion = 4; + version->dwMinorVersion = 0; + version->dwBuildNumber = 1381; + version->dwPlatformId = VER_PLATFORM_WIN32_NT; + //wcscpy(version->szCSDVersion, L"Befator Inc gruesst Sie!"); + + /*HKEY key; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\BCompat"), 0, KEY_READ, &key) == ERROR_SUCCESS) { + DWORD size; + DWORD major = 0; + if (RegQueryValueEx(key, TEXT("ReportedMajor"), NULL, NULL, (LPBYTE) &major, &size) == ERROR_SUCCESS) { + version->dwMajorVersion = major; + } + DWORD minor = 0; + if (RegQueryValueEx(key, TEXT("ReportedMinor"), NULL, NULL, (LPBYTE) &minor, &size) == ERROR_SUCCESS) { + version->dwMinorVersion = minor; + } + DWORD build = 0; + if (RegQueryValueEx(key, TEXT("ReportedBuild"), NULL, NULL, (LPBYTE) &build, &size) == ERROR_SUCCESS) { + version->dwBuildNumber = build; + } + DWORD platform = 0; + if (RegQueryValueEx(key, TEXT("ReportedPlatform"), NULL, NULL, (LPBYTE) &platform, &size) == ERROR_SUCCESS) { + version->dwPlatformId = platform; + } + RegCloseKey(key); + }*/ + return TRUE; + } else { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } +} + +DLL_EXPORT WINAPI BOOL GetVersionExA(LPOSVERSIONINFOA version) { + if (version->dwOSVersionInfoSize == sizeof(OSVERSIONINFOA)) { + OSVERSIONINFOW versionW; + versionW.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); + if (GetVersionExW(&versionW)) { + version->dwMajorVersion = versionW.dwMajorVersion; + version->dwMinorVersion = versionW.dwMinorVersion; + version->dwBuildNumber = versionW.dwBuildNumber; + version->dwPlatformId = versionW.dwPlatformId; + //wcstombs(version->szCSDVersion, versionW.szCSDVersion, ARRAYSIZE(version->szCSDVersion)); + return TRUE; + } + return FALSE; + } else { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } +} diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..90589a0 --- /dev/null +++ b/main.cpp @@ -0,0 +1,1050 @@ +#include +#include +#include + +#include "Zydis/Zydis.h" + +#define BCOMPAT_REGISTRY_KEY L"\\Registry\\Machine\\Software\\BCompat\\Functions" +#define FUNCTION_NAME_SIZE 64 +#define PATCH_SECTION_SIZE 512 + +BYTE *buffer; + +void printLastError() { + DWORD error = GetLastError(); + if (error == ERROR_FILE_NOT_FOUND) { + printf("File not found\n"); + } else if (error == ERROR_ACCESS_DENIED) { + printf("Access to file denied\n"); + } else { + printf("Error: %lu\n", error); + } +} + +int readInt(const DWORD pos) { + return buffer[pos] | buffer[pos + 1] << 8; +} + +void writeInt(const DWORD pos, const int value) { + buffer[pos] = value & 0xff; + buffer[pos + 1] = value >> 8; +} + +void writeInt(const DWORD pos, LPDWORD offset, const int value) { + writeInt(pos + *offset, value); + *offset += 2; +} + +DWORD readDWORD(const DWORD pos) { + return buffer[pos] | buffer[pos + 1] << 8 | buffer[pos + 2] << 16 | buffer[pos + 3] << 24; +} + +void writeDWORD(const DWORD pos, const DWORD value) { + buffer[pos] = value & 0xff; + buffer[pos + 1] = value >> 8 & 0xff; + buffer[pos + 2] = value >> 16 & 0xff; + buffer[pos + 3] = value >> 24 & 0xff; +} + +void writeDWORD(const DWORD pos, LPDWORD offset, const DWORD value) { + writeDWORD(pos + *offset, value); + *offset += 4; +} + +LPSTR readString(DWORD pos) { + int size = 32; + char* string = new char[size]; + int i = 0; + while (i == 0 || string[i - 1] != '\0') { + if (i >= size) { + size += 32; + char* newString = new char[size]; + memcpy(newString, string, size - 32); + delete[] string; + string = newString; + } + string[i] = buffer[pos + i]; + i++; + } + return string; +} + +void writeString(const DWORD pos, LPDWORD offset, const char *string) { + DWORD length = strlen(string); + for (int i = 0; i <= length; i++) { + buffer[pos + *offset + i] = string[i]; + } + *offset += length + 1; +} + +void writeUnicodeString(const DWORD pos, LPDWORD offset, const wchar_t *string) { + DWORD length = wcslen(string) + 1; + for (int i = 0; i < length; i++) { + writeInt(pos, offset, string[i]); + } +} + +DWORD getRealAddress(DWORD *virtualAddresses, DWORD *realAddresses, DWORD sectionCount, DWORD address) { + int section = 0; + for (int i = 0; i < sectionCount; ++i) { + if (virtualAddresses[i] <= address) { + section = i; + } + } + return address - virtualAddresses[section] + realAddresses[section]; +} + +DWORD readAddress(DWORD *virtualAddresses, DWORD *realAddresses, DWORD sectionCount, DWORD pos) { + return getRealAddress(virtualAddresses, realAddresses, sectionCount, readDWORD(pos)); +} + +DWORD getExportedFunction(DWORD *virtualAddresses, DWORD *realAddresses, DWORD sectionCount, DWORD exportAddressTable, DWORD namePointerTable, DWORD ordinalTable, DWORD functionCount, const char *functionName) { + printf("Locating %s... ", functionName); + WORD ordinal = 0; + for (DWORD i = 0; i < functionCount; i++) { + DWORD namePtr = readAddress(virtualAddresses, realAddresses, sectionCount, namePointerTable + i * 4); + LPSTR name = readString(namePtr); + if (strcmp(name, functionName) == 0) { + ordinal = readInt(ordinalTable + i * 2); + delete[] name; + break; + } + delete[] name; + } + if (ordinal == 0) { + printf("Not found in export table"); + delete[] buffer; + exit(1); + } + DWORD function = readDWORD(exportAddressTable + ordinal * 4); + printf("0x%lx\n", function); + return function; +} + +DWORD getWrappedFunction(DWORD fileSize, DWORD wrapperFunction, const char *functionName) { + printf("Locating %s... ", functionName); + DWORD function = 0; + { + int i = 0; + ZydisDisassembledInstruction instruction; + while (ZYAN_SUCCESS(ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LEGACY_32, wrapperFunction + i, buffer + wrapperFunction + i, fileSize - wrapperFunction - i, &instruction))) { + if (instruction.info.mnemonic == ZYDIS_MNEMONIC_CALL) { + if (function != NULL) { + printf("Unexpected code structure"); + delete[] buffer; + exit(1); + } + ZyanU64 address; + ZydisCalcAbsoluteAddress(&instruction.info, &instruction.operands[0], wrapperFunction + i, &address); + function = address; + } else if (instruction.info.mnemonic == ZYDIS_MNEMONIC_RET) { + if (function == NULL) { + printf("Could not find CALL"); + delete[] buffer; + exit(1); + } + break; + } + i += instruction.info.length; + } + } + printf("0x%lx\n", function); + return function; +} + +boolean writeFile(const LPTSTR name, const BYTE *buffer, const DWORD fileSize) { + HANDLE file = CreateFile(name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) { + printLastError(); + delete[] buffer; + return false; + } + if (!WriteFile(file, buffer, fileSize, NULL, NULL)) { + printLastError(); + CloseHandle(file); + delete[] buffer; + return false; + } + CloseHandle(file); + return true; +} + +void writeJumpAddress(const DWORD pos, const DWORD virtualPos, const DWORD target) { + writeDWORD(pos, target - (virtualPos + 4)); +} + +void writeJumpAddress(const DWORD pos, const DWORD virtualPos, LPDWORD offset, const DWORD target) { + writeJumpAddress(pos + *offset, virtualPos + *offset, target); + *offset += 4; +} + +void ensureAlignment(const DWORD pos, LPDWORD offset) { + DWORD i = (pos + *offset) % 4; + if (i > 0) { + *offset += 4 - i; + } +} + +int main() { + LPTSTR cmdLine = GetCommandLine(); + LPTSTR space = strrchr(cmdLine, ' '); + if (space == NULL) { + printf("Error: No Path provided\n"); + return 0; + } + LPTSTR originalFile = space + sizeof(TCHAR); + if (strlen(originalFile) > MAX_PATH - 10 * sizeof(TCHAR)) { + printf("Error: File name is too long\n"); + return 1; + } + printf("Copying original file... "); + TCHAR patchedFile[MAX_PATH]; + sprintf(patchedFile, "%s.patched", originalFile); + if (!CopyFile(originalFile, patchedFile, FALSE)) { + printLastError(); + return 1; + } + printf("Done\n"); + + printf("Opening file for patching... "); + HANDLE file = CreateFile(patchedFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) { + printLastError(); + return 1; + } + DWORD fileSize = GetFileSize(file, NULL); + if (fileSize == INVALID_FILE_SIZE) { + printLastError(); + return 1; + } + buffer = new BYTE[fileSize + PATCH_SECTION_SIZE]; + DWORD bytesRead; + ReadFile(file, buffer, fileSize, &bytesRead, NULL); + CloseHandle(file); + if (bytesRead != fileSize) { + printLastError(); + delete[] buffer; + return 1; + } + fileSize += PATCH_SECTION_SIZE ; + printf("Done\n"); + + printf("Locating PE Header... "); + if (fileSize < 2 || buffer[0] != 'M' || buffer[1] != 'Z') { + printf("Not a valid DLL (Invalid MZ Header)"); + delete[] buffer; + return 1; + } + DWORD peHeader = readDWORD(0x3C); + if (fileSize <= peHeader + 3 || buffer[peHeader] != 'P' || buffer[peHeader + 1] != 'E' || buffer[peHeader + 2] != '\0' || buffer[peHeader + 3] != '\0') { + printf("Not a valid DLL (Invalid PE Header)"); + delete[] buffer; + return 1; + } + if (fileSize <= peHeader + 0x19 || readInt(peHeader + 0x18) != 0x10b) { + printf("Unsupported DLL (Not a normal executable)"); + delete[] buffer; + return 1; + } + printf("0x%lx\n", peHeader); + + printf("Reading Base Image location... "); + DWORD imageBase = readDWORD(peHeader + 0x18 + 28); + printf("0x%lx\n", imageBase); + + printf("Locating Sections... "); + DWORD sectionTable = peHeader + 0x18 + 224; + WORD sectionCount = readInt(peHeader + 6); + printf("%u\n", sectionCount); + DWORD virtualAddresses[sectionCount]; + DWORD realAddresses[sectionCount]; + DWORD realSectionSizes[sectionCount]; + DWORD virtualSectionSizes[sectionCount]; + for (DWORD i = 0; i < sectionCount; i++) { + LPSTR name = readString(sectionTable + i * 40); + printf("Locating %s Section... ", name); + delete[] name; + DWORD virtualAddress = readDWORD(sectionTable + i * 40 + 12); + DWORD realAddress = readDWORD(sectionTable + i * 40 + 20); + virtualAddresses[i] = virtualAddress; + realAddresses[i] = realAddress; + realSectionSizes[i] = readDWORD(sectionTable + i * 40 + 16); + virtualSectionSizes[i] = readDWORD(sectionTable + i * 40 + 8); + printf("0x%lx / %lu\n", virtualAddress, realAddress); + } + + printf("Locating Export Address Table... "); + DWORD exportTable = readAddress(virtualAddresses, realAddresses, sectionCount, peHeader + 0x18 + 96); + printf("0x%lx\n", exportTable); + + printf("Reading Export Address Table... "); + DWORD functionCount = readDWORD(exportTable + 24); + DWORD exportAddressTable = readAddress(virtualAddresses, realAddresses, sectionCount, exportTable + 28); + DWORD namePointerTable = readAddress(virtualAddresses, realAddresses, sectionCount, exportTable + 32); + DWORD ordinalTable = readAddress(virtualAddresses, realAddresses, sectionCount, exportTable + 36); + printf("Done\n"); + + DWORD ldrGetProcedureAddress = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "LdrGetProcedureAddress"); + + DWORD ldrpGetProcedureAddress = getWrappedFunction(fileSize, ldrGetProcedureAddress, "LdrpGetProcedureAddress"); + + DWORD rtlImageDirectoryEntryToData = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "RtlImageDirectoryEntryToData"); + + printf("Locating LdrpSnapThunk... "); + DWORD pSnapThunk = 0; + { + int i = 0; + int found = 0; + ZydisDisassembledInstruction instruction; + while (ZYAN_SUCCESS(ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LEGACY_32, ldrpGetProcedureAddress + i, buffer + ldrpGetProcedureAddress + i, fileSize - ldrpGetProcedureAddress - i, &instruction))) { + if (instruction.info.mnemonic == ZYDIS_MNEMONIC_CALL) { + ZyanU64 address; + ZydisCalcAbsoluteAddress(&instruction.info, &instruction.operands[0], ldrpGetProcedureAddress + i, &address); + if (address == rtlImageDirectoryEntryToData) { + if (found > 0 || pSnapThunk != NULL) { + printf("Unexpected code structure"); + delete[] buffer; + return 1; + } + found = 1; + } else if (found == 1) { //__local_unwind2 + found++; + } else { + if (found == 2) { + pSnapThunk = address; + } + found = 0; + } + } else if (instruction.info.mnemonic == ZYDIS_MNEMONIC_RET) { + if (pSnapThunk == NULL) { + printf("Could not find CALL"); + delete[] buffer; + return 1; + } + break; + } + i += instruction.info.length; + } + } + printf("0x%lx\n", pSnapThunk); + + printf("Locating patch point... "); + DWORD patchPoint = 0; + { + int i = 0; + ZydisDisassembledInstruction instruction; + while (ZYAN_SUCCESS(ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LEGACY_32, pSnapThunk + i, buffer + pSnapThunk + i, fileSize - pSnapThunk - i, &instruction))) { + if (instruction.info.mnemonic == ZYDIS_MNEMONIC_MOV) { + if (instruction.operands[0].mem.disp.value == -20) { //ImportName = ... + patchPoint = instruction.runtime_address + instruction.info.length; + break; + } + } else if (instruction.info.mnemonic == ZYDIS_MNEMONIC_RET) { + printf("Unexpected code structure"); + delete[] buffer; + return 1; + } + i += instruction.info.length; + } + } + printf("0x%lx\n", patchPoint); + + printf("Checking how many bytes to replace... "); + DWORD targetSize = 5; + DWORD patchSize = 0; + { + int i = 0; + ZydisDisassembledInstruction instruction; + while (ZYAN_SUCCESS(ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LEGACY_32, patchPoint + i, buffer + patchPoint + i, fileSize - patchPoint - i, &instruction))) { + if (instruction.info.mnemonic == ZYDIS_MNEMONIC_RET) { + printf("Unexpected end of function"); + delete[] buffer; + return 1; + } + i += instruction.info.length; + if (i >= targetSize) { + patchSize = i; + break; + } + } + } + printf("%lu\n", patchSize); + + printf("Locating LdrpSnapThunk end... "); + DWORD ldrpSnapThunkEnd = 0; + { + int i = 0; + ZydisDisassembledInstruction instruction; + while (ZYAN_SUCCESS(ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LEGACY_32, pSnapThunk + i, buffer + pSnapThunk + i, fileSize - pSnapThunk - i, &instruction))) { + if (instruction.info.mnemonic == ZYDIS_MNEMONIC_POP) { + if (instruction.operands[0].reg.value == ZYDIS_REGISTER_EDI) { //POP EDI + if (ldrpSnapThunkEnd != NULL) { + printf("Unexpected code structure"); + delete[] buffer; + return 1; + } + ldrpSnapThunkEnd = instruction.runtime_address; + } + } else if (instruction.info.mnemonic == ZYDIS_MNEMONIC_RET) { + if (ldrpSnapThunkEnd == NULL) { + printf("Unexpected end of function"); + delete[] buffer; + return 1; + } + break; + } + i += instruction.info.length; + } + } + printf("0x%lx\n", ldrpSnapThunkEnd); + + printf("Adding .patch section... "); + DWORD freeSpace = realAddresses[sectionCount - 1] + realSectionSizes[sectionCount - 1]; + DWORD virtualFreeSpace = virtualAddresses[sectionCount - 1] + virtualSectionSizes[sectionCount - 1]; + virtualFreeSpace = virtualFreeSpace + 0x1000 - virtualFreeSpace % 0x1000; + { + writeInt(peHeader + 6, sectionCount + 1); + writeDWORD(peHeader + 0x18 + 56, readDWORD(peHeader + 0x18 + 56) + PATCH_SECTION_SIZE); + DWORD patchSectionHeader = sectionTable + sectionCount * 40; + DWORD i = 0; + writeString(patchSectionHeader, &i, ".patch"); + for (int x = 0; x < 7 - strlen(".patch"); x++) { + buffer[patchSectionHeader + i++] = 0x00; + } + writeDWORD(patchSectionHeader, &i, PATCH_SECTION_SIZE); + writeDWORD(patchSectionHeader, &i, virtualFreeSpace); + writeDWORD(patchSectionHeader, &i, PATCH_SECTION_SIZE); + writeDWORD(patchSectionHeader, &i, freeSpace); + writeDWORD(patchSectionHeader, &i, 0); + writeDWORD(patchSectionHeader, &i, 0); + writeInt(patchSectionHeader, &i, 0); + writeInt(patchSectionHeader, &i, 0); + writeDWORD(patchSectionHeader, &i, IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ); + } + printf("0x%lx\n", freeSpace); + + DWORD strcmp = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "strcmp"); + + DWORD ntOpenKey = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "NtOpenKey"); + + DWORD strcpy = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "strcpy"); + + DWORD strcat = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "strcat"); + + DWORD rtlInitAnsiString = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "RtlInitAnsiString"); + + DWORD rtlAnsiStringToUnicodeString = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "RtlAnsiStringToUnicodeString"); + + DWORD ntQueryValueKey = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "NtQueryValueKey"); + + DWORD ldrLoadDll = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "LdrLoadDll"); + + DWORD ldrpLoadDll = getWrappedFunction(fileSize, ldrLoadDll, "LdrpLoadDll"); + + DWORD rtlInitUnicodeString = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "RtlInitUnicodeString"); + + printf("Locating LdrpWalkImportDescriptor... "); + DWORD ldrpWalkImportDescriptor = 0; + { + int i = 0; + int found = 0; + ZydisDisassembledInstruction instruction; + while (ZYAN_SUCCESS(ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LEGACY_32, ldrpLoadDll + i, buffer + ldrpLoadDll + i, fileSize - ldrpLoadDll - i, &instruction))) { + if (instruction.info.mnemonic == ZYDIS_MNEMONIC_CALL) { + ZyanU64 address; + ZydisCalcAbsoluteAddress(&instruction.info, &instruction.operands[0], ldrpLoadDll + i, &address); + if (address == rtlInitUnicodeString) { + if (found > 0 || ldrpWalkImportDescriptor != NULL) { + printf("Unexpected code structure"); + delete[] buffer; + return 1; + } + found = 1; + } else if (found == 1) { //LdrpCheckForLoadedDll + found++; + } else if (found == 2) { //LdrpMapDll + found++; + } else if (found == 3) { //__local_unwind2 + found++; + } else { + if (found == 4) { + ldrpWalkImportDescriptor = address; + } + found = 0; + } + } else if (instruction.info.mnemonic == ZYDIS_MNEMONIC_RET) { + if (ldrpWalkImportDescriptor == NULL) { + printf("Could not find CALL"); + delete[] buffer; + return 1; + } + break; + } + i += instruction.info.length; + } + } + printf("0x%lx\n", ldrpWalkImportDescriptor); + + /*printf("Disabling bound imports... "); + DWORD boundImportsPatch = 0; + { + int i = 0; + ZydisDisassembledInstruction instruction; + while (ZYAN_SUCCESS(ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LEGACY_32, ldrpWalkImportDescriptor + i, buffer + ldrpWalkImportDescriptor + i, fileSize - ldrpWalkImportDescriptor - i, &instruction))) { + if (instruction.info.mnemonic == ZYDIS_MNEMONIC_MOV) { + if (instruction.operands[0].mem.base == ZYDIS_REGISTER_EBP && + instruction.operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && instruction.operands[1].imm.value.u == 0) { //stale = false + if (boundImportsPatch != NULL) { + printf("Unexpected code structure"); + delete[] buffer; + return 1; + } + boundImportsPatch = ldrpWalkImportDescriptor + i; + } + } else if (instruction.info.mnemonic == ZYDIS_MNEMONIC_RET) { + if (boundImportsPatch == NULL) { + printf("Could not find patch point"); + delete[] buffer; + return 1; + } + break; + } + i += instruction.info.length; + } + } + buffer[boundImportsPatch + 3] = 0x01; + printf("0x%lx\n", boundImportsPatch);*/ + /*printf("Disabling bound imports... "); + DWORD boundImportsPatch = 0; + { + int i = 0; + ZydisDisassembledInstruction instruction; + while (ZYAN_SUCCESS(ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LEGACY_32, ldrpWalkImportDescriptor + i, buffer + ldrpWalkImportDescriptor + i, fileSize - ldrpWalkImportDescriptor - i, &instruction))) { + if (instruction.info.mnemonic == ZYDIS_MNEMONIC_CMP) { + if (instruction.operands[0].mem.base == ZYDIS_REGISTER_EBP && instruction.operands[0].mem.disp.value == -2 && + instruction.operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && instruction.operands[1].imm.value.u == 0) {//stale = false + if (boundImportsPatch != NULL) { + printf("Unexpected code structure"); + delete[] buffer; + return 1; + } + boundImportsPatch = ldrpWalkImportDescriptor + i; + } + } else if (instruction.info.mnemonic == ZYDIS_MNEMONIC_RET) { + if (boundImportsPatch == NULL) { + printf("Could not find patch point"); + delete[] buffer; + return 1; + } + break; + } + i += instruction.info.length; + } + } + buffer[boundImportsPatch + 6] = 0x90; + buffer[boundImportsPatch + 7] = 0x90; + buffer[boundImportsPatch + 8] = 0x90; + buffer[boundImportsPatch + 9] = 0x90; + buffer[boundImportsPatch + 10] = 0x90; + buffer[boundImportsPatch + 11] = 0x90; + printf("0x%lx\n", boundImportsPatch);*/ + + DWORD dbgBreakPoint = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "DbgBreakPoint"); + + printf("Locating LdrpLoadImportModule... "); + DWORD ldrpLoadImportModule = 0; + { + int i = 0; + bool found = false; + ZydisDisassembledInstruction instruction; + while (ZYAN_SUCCESS(ZydisDisassembleIntel(ZYDIS_MACHINE_MODE_LEGACY_32, ldrpWalkImportDescriptor + i, buffer + ldrpWalkImportDescriptor + i, fileSize - ldrpWalkImportDescriptor - i, &instruction))) { + if (instruction.info.mnemonic == ZYDIS_MNEMONIC_CALL) { + ZyanU64 address; + ZydisCalcAbsoluteAddress(&instruction.info, &instruction.operands[0], ldrpWalkImportDescriptor + i, &address); + if (address == dbgBreakPoint) { + if (found || ldrpLoadImportModule != NULL) { + printf("Unexpected code structure"); + delete[] buffer; + return 1; + } + found = true; + } else if (found) { + ldrpLoadImportModule = address; + found = false; + } + } else if (instruction.info.mnemonic == ZYDIS_MNEMONIC_RET) { + if (ldrpLoadImportModule == NULL) { + printf("Could not find CALL"); + delete[] buffer; + return 1; + } + break; + } + i += instruction.info.length; + } + } + printf("0x%lx\n", ldrpLoadImportModule); + + DWORD ntCurrentTeb = getExportedFunction(virtualAddresses, realAddresses, sectionCount, + exportAddressTable, namePointerTable, ordinalTable, functionCount, "NtCurrentTeb"); + + printf("Patching free space... "); + DWORD patchEntrypointAddress; + { + DWORD i = 0; + //ADD ESP, 0x4 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xc4; + buffer[freeSpace + i++] = 0x04; + //ADD ESP, 0x4 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xc4; + buffer[freeSpace + i++] = 0x04; + DWORD patchEnd = virtualFreeSpace + i; + //POP EDI + buffer[freeSpace + i++] = 0x5f; + //POP ESI + buffer[freeSpace + i++] = 0x5e; + //POP EAX + buffer[freeSpace + i++] = 0x58; + for (int x = 0; x < patchSize; x++) { + buffer[freeSpace + i++] = buffer[patchPoint + x]; + } + //JMP + buffer[freeSpace + i++] = 0xe9; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, patchPoint + patchSize); + patchEntrypointAddress = virtualFreeSpace + i; + + //PUSH EAX + buffer[freeSpace + i++] = 0x50; + //PUSH ESI + buffer[freeSpace + i++] = 0x56; + //PUSH EDI + buffer[freeSpace + i++] = 0x57; + //MOV EAX, DllName + buffer[freeSpace + i++] = 0x8b; + buffer[freeSpace + i++] = 0x45; + buffer[freeSpace + i++] = 0x24; + //TEST EAX EAX + buffer[freeSpace + i++] = 0x85; + buffer[freeSpace + i++] = 0xc0; + //JZ PatchEnd + buffer[freeSpace + i++] = 0x0f; + buffer[freeSpace + i++] = 0x84; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, patchEnd); + //JMP over "bcompat.dll" + buffer[freeSpace + i++] = 0xe9; + DWORD jumpPos = freeSpace + i; + i += 4; + DWORD dllString = virtualFreeSpace + i; + writeString(freeSpace, &i, "bcompat.dll"); + writeJumpAddress(jumpPos, jumpPos, freeSpace + i); + //PUSH "bcompat.dll" + buffer[freeSpace + i++] = 0x68; + writeDWORD(freeSpace, &i, imageBase + dllString); + //PUSH EAX + buffer[freeSpace + i++] = 0x50; + //CALL strcmp + buffer[freeSpace + i++] = 0xe8; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, strcmp); + //ADD ESP, 8 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xc4; + buffer[freeSpace + i++] = 0x08; + //TEST EAX EAX + buffer[freeSpace + i++] = 0x85; + buffer[freeSpace + i++] = 0xc0; + //JZ PatchEnd + buffer[freeSpace + i++] = 0x0f; + buffer[freeSpace + i++] = 0x84; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, patchEnd); + //JMP over + buffer[freeSpace + i++] = 0xe9; + jumpPos = freeSpace + i; + i += 4; + ensureAlignment(freeSpace, &i); + DWORD keyName = virtualFreeSpace + i; + writeUnicodeString(freeSpace, &i, BCOMPAT_REGISTRY_KEY); + //UNICODE_STRING + ensureAlignment(freeSpace, &i); + DWORD keyString = virtualFreeSpace + i; + buffer[freeSpace + i++] = wcslen(BCOMPAT_REGISTRY_KEY) * sizeof(wchar_t); //Length + buffer[freeSpace + i++] = 0x00; + buffer[freeSpace + i++] = (wcslen(BCOMPAT_REGISTRY_KEY) + 1) * sizeof(wchar_t); //MaximumLength + buffer[freeSpace + i++] = 0x00; + writeDWORD(freeSpace, &i, imageBase + keyName); //Buffer + //OBJECT_ATTRIBUTES + DWORD objectAttributes = virtualFreeSpace + i; + writeDWORD(freeSpace, &i, 0x18); //Length + writeDWORD(freeSpace, &i, 0x00); //RootDirectory + writeDWORD(freeSpace, &i, imageBase + keyString); //ObjectName + writeDWORD(freeSpace, &i, 0x40); //Attributes + writeDWORD(freeSpace, &i, 0x00); //SecurityDescriptor + writeDWORD(freeSpace, &i, 0x00); //SecurityQualityOfService + writeJumpAddress(jumpPos, jumpPos, freeSpace + i); + //SUB ESP, 4 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xec; + buffer[freeSpace + i++] = 0x04; + //LEA EAX, [ESP] + buffer[freeSpace + i++] = 0x8d; + buffer[freeSpace + i++] = 0x04; + buffer[freeSpace + i++] = 0x24; + //PUSH POBJECT_ATTRIBUTES + buffer[freeSpace + i++] = 0x68; + writeDWORD(freeSpace, &i, imageBase + objectAttributes); + //PUSH 0x20019 + buffer[freeSpace + i++] = 0x68; + writeDWORD(freeSpace, &i, 0x20019); + //PUSH EAX + buffer[freeSpace + i++] = 0x50; + //CALL NtOpenKey + buffer[freeSpace + i++] = 0xe8; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, ntOpenKey); + //TEST EAX EAX + buffer[freeSpace + i++] = 0x85; + buffer[freeSpace + i++] = 0xc0; + //JS PatchEnd + buffer[freeSpace + i++] = 0x0f; + buffer[freeSpace + i++] = 0x88; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, patchEnd - 3); + //SUB ESP, FUNCTION_NAME_SIZE + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xec; + buffer[freeSpace + i++] = FUNCTION_NAME_SIZE; + //LEA ESI, [ESP] + buffer[freeSpace + i++] = 0x8d; + buffer[freeSpace + i++] = 0x34; + buffer[freeSpace + i++] = 0x24; + //MOV EAX, [DllName] + buffer[freeSpace + i++] = 0x8b; + buffer[freeSpace + i++] = 0x45; + buffer[freeSpace + i++] = 0x24; + //PUSH EAX + buffer[freeSpace + i++] = 0x50; + //PUSH ESI + buffer[freeSpace + i++] = 0x56; + //CALL strcpy + buffer[freeSpace + i++] = 0xe8; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, strcpy); + //ADD ESP, 8 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xc4; + buffer[freeSpace + i++] = 0x08; + //MOV EAX, [ImportName] + buffer[freeSpace + i++] = 0x8b; + buffer[freeSpace + i++] = 0x45; + buffer[freeSpace + i++] = 0xec; + //PUSH EAX + buffer[freeSpace + i++] = 0x50; + //PUSH ESI + buffer[freeSpace + i++] = 0x56; + //CALL strcat + buffer[freeSpace + i++] = 0xe8; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, strcat); + //ADD ESP, 8 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xc4; + buffer[freeSpace + i++] = 0x08; + //SUB ESP, 8 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xec; + buffer[freeSpace + i++] = 0x08; + //LEA EDI, [ESP] + buffer[freeSpace + i++] = 0x8d; + buffer[freeSpace + i++] = 0x3c; + buffer[freeSpace + i++] = 0x24; + //PUSH ESI + buffer[freeSpace + i++] = 0x56; + //PUSH EDI + buffer[freeSpace + i++] = 0x57; + //CALL RtlInitAnsiString + buffer[freeSpace + i++] = 0xe8; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, rtlInitAnsiString); + //SUB ESP, 8 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xec; + buffer[freeSpace + i++] = 0x08; + //LEA EAX, [ESP] + buffer[freeSpace + i++] = 0x8d; + buffer[freeSpace + i++] = 0x04; + buffer[freeSpace + i++] = 0x24; + //PUSH 1 + buffer[freeSpace + i++] = 0x6a; + buffer[freeSpace + i++] = 0x01; + //PUSH EDI + buffer[freeSpace + i++] = 0x57; + //PUSH EAX + buffer[freeSpace + i++] = 0x50; + //CALL RtlAnsiStringToUnicodeString + buffer[freeSpace + i++] = 0xe8; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, rtlAnsiStringToUnicodeString); + //MOV EDI, [ESP+0x50] + buffer[freeSpace + i++] = 0x8b; + buffer[freeSpace + i++] = 0x7c; + buffer[freeSpace + i++] = 0x24; + buffer[freeSpace + i++] = 0x50; + //SUB ESP, 4 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xec; + buffer[freeSpace + i++] = 0x04; + //LEA EAX, [ESP] + buffer[freeSpace + i++] = 0x8d; + buffer[freeSpace + i++] = 0x04; + buffer[freeSpace + i++] = 0x24; + //PUSH EAX + buffer[freeSpace + i++] = 0x50; + //PUSH 0 + buffer[freeSpace + i++] = 0x6a; + buffer[freeSpace + i++] = 0x00; + //PUSH 0 + buffer[freeSpace + i++] = 0x6a; + buffer[freeSpace + i++] = 0x00; + //PUSH 0 + buffer[freeSpace + i++] = 0x6a; + buffer[freeSpace + i++] = 0x00; + //LEA EAX, [ESP+0x14] + buffer[freeSpace + i++] = 0x8d; + buffer[freeSpace + i++] = 0x44; + buffer[freeSpace + i++] = 0x24; + buffer[freeSpace + i++] = 0x14; + //PUSH EAX + buffer[freeSpace + i++] = 0x50; + //PUSH EDI + buffer[freeSpace + i++] = 0x57; + //CALL NtQueryValueKey + buffer[freeSpace + i++] = 0xe8; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, ntQueryValueKey); + //ADD ESP, 0x58 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xc4; + buffer[freeSpace + i++] = FUNCTION_NAME_SIZE + 0x18; + //CMP EAX, 0xc0000023 + buffer[freeSpace + i++] = 0x3d; + buffer[freeSpace + i++] = 0x23; + buffer[freeSpace + i++] = 0x00; + buffer[freeSpace + i++] = 0x00; + buffer[freeSpace + i++] = 0xc0; + //JNZ PatchEnd + buffer[freeSpace + i++] = 0x0f; + buffer[freeSpace + i++] = 0x85; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, patchEnd); + //SUB ESP, 0x8 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xec; + buffer[freeSpace + i++] = 0x08; + //LEA EDI, [ESP] + buffer[freeSpace + i++] = 0x8d; + buffer[freeSpace + i++] = 0x3c; + buffer[freeSpace + i++] = 0x24; + //LEA EAX, [ESP+0x4] + buffer[freeSpace + i++] = 0x8d; + buffer[freeSpace + i++] = 0x44; + buffer[freeSpace + i++] = 0x24; + buffer[freeSpace + i++] = 0x04; + //PUSH EAX + buffer[freeSpace + i++] = 0x50; + //PUSH EDI + buffer[freeSpace + i++] = 0x57; + //MOV EAX, ImportBase + buffer[freeSpace + i++] = 0x8b; + buffer[freeSpace + i++] = 0x45; + buffer[freeSpace + i++] = 0xc; + //PUSH EAX + buffer[freeSpace + i++] = 0x50; + //PUSH "bcompat.dll" + buffer[freeSpace + i++] = 0x68; + writeDWORD(freeSpace, &i, imageBase + dllString); + //PUSH 0 + buffer[freeSpace + i++] = 0x6a; + buffer[freeSpace + i++] = 0x00; + //CALL LdrpLoadImportModule + buffer[freeSpace + i++] = 0xe8; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, ldrpLoadImportModule); + //MOV EDI, [ESP] + buffer[freeSpace + i++] = 0x8b; + buffer[freeSpace + i++] = 0x3c; + buffer[freeSpace + i++] = 0x24; + //TEST EAX EAX + buffer[freeSpace + i++] = 0x85; + buffer[freeSpace + i++] = 0xc0; + //JS PatchEnd + buffer[freeSpace + i++] = 0x0f; + buffer[freeSpace + i++] = 0x88; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, patchEnd - 6); + //CMP byte ptr [ESP+0x4], 0 + buffer[freeSpace + i++] = 0x80; + buffer[freeSpace + i++] = 0x7c; + buffer[freeSpace + i++] = 0x24; + buffer[freeSpace + i++] = 0x04; + buffer[freeSpace + i++] = 0x00; + //ADD ESP, 0x8 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xc4; + buffer[freeSpace + i++] = 0x08; + //ADD EDI, 0x10 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xc7; + buffer[freeSpace + i++] = 0x10; + //JZ SKIP_INIT + buffer[freeSpace + i++] = 0x0f; + buffer[freeSpace + i++] = 0x84; + jumpPos = freeSpace + i; + i += 4; + //CALL NtCurrentTeb + buffer[freeSpace + i++] = 0xe8; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, ntCurrentTeb); + //MOV ESI, [EAX + 0x30] //PEB + buffer[freeSpace + i++] = 0x8b; + buffer[freeSpace + i++] = 0x70; + buffer[freeSpace + i++] = 0x30; + //MOV ESI, [ESI + 0xc] //Ldr + buffer[freeSpace + i++] = 0x8b; + buffer[freeSpace + i++] = 0x76; + buffer[freeSpace + i++] = 0x0c; + //ADD ESI, 0x1c //InInitializationOrderModuleList + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xc6; + buffer[freeSpace + i++] = 0x1c; + //MOV EAX, [ESI + 0x4] + buffer[freeSpace + i++] = 0x8b; + buffer[freeSpace + i++] = 0x46; + buffer[freeSpace + i++] = 0x04; + //MOV [EDI], ESI + buffer[freeSpace + i++] = 0x89; + buffer[freeSpace + i++] = 0x37; + //MOV [EDI + 0x4], EAX + buffer[freeSpace + i++] = 0x89; + buffer[freeSpace + i++] = 0x47; + buffer[freeSpace + i++] = 0x04; + //MOV [EAX], EDI + buffer[freeSpace + i++] = 0x89; + buffer[freeSpace + i++] = 0x38; + //MOV [ESI + 0x4], EDI + buffer[freeSpace + i++] = 0x89; + buffer[freeSpace + i++] = 0x7e; + buffer[freeSpace + i++] = 0x04; + writeJumpAddress(jumpPos, jumpPos, freeSpace + i); + //SUB ESP, 0x4 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xec; + buffer[freeSpace + i++] = 0x04; + //LEA EAX, [ESP] + buffer[freeSpace + i++] = 0x8d; + buffer[freeSpace + i++] = 0x04; + buffer[freeSpace + i++] = 0x24; + //PUSH EAX + buffer[freeSpace + i++] = 0x50; + //PUSH 0 + buffer[freeSpace + i++] = 0x6a; + buffer[freeSpace + i++] = 0x00; + //PUSH 1 + buffer[freeSpace + i++] = 0x6a; + buffer[freeSpace + i++] = 0x01; + //ADD EDI, 0x8 //DllBase + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xc7; + buffer[freeSpace + i++] = 0x08; + //mov EDI, [EDI] + buffer[freeSpace + i++] = 0x8b; + buffer[freeSpace + i++] = 0x3f; + //PUSH EDI + buffer[freeSpace + i++] = 0x57; + //CALL RtlImageDirectoryEntryToData + buffer[freeSpace + i++] = 0xe8; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, rtlImageDirectoryEntryToData); + //MOV ESI, [ESP] + buffer[freeSpace + i++] = 0x8b; + buffer[freeSpace + i++] = 0x34; + buffer[freeSpace + i++] = 0x24; + //PUSH "bcompat.dll" + buffer[freeSpace + i++] = 0x68; + writeDWORD(freeSpace, &i, imageBase + dllString); + //PUSH StaticSnap + buffer[freeSpace + i++] = 0xff; + buffer[freeSpace + i++] = 0x75; + buffer[freeSpace + i++] = 0x20; + //PUSH ESI + buffer[freeSpace + i++] = 0x56, + //PUSH EAX + buffer[freeSpace + i++] = 0x50; + //PUSH Thunk + buffer[freeSpace + i++] = 0xff; + buffer[freeSpace + i++] = 0x75; + buffer[freeSpace + i++] = 0x14; + //PUSH OriginalThunk + buffer[freeSpace + i++] = 0xff; + buffer[freeSpace + i++] = 0x75; + buffer[freeSpace + i++] = 0x10; + //PUSH ImageBase + buffer[freeSpace + i++] = 0xff; + buffer[freeSpace + i++] = 0x75; + buffer[freeSpace + i++] = 0x0c; + //PUSH EDI + buffer[freeSpace + i++] = 0x57; + //CALL LdrpSnapThunk + buffer[freeSpace + i++] = 0xe8; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, pSnapThunk); + //buffer[freeSpace + i++] = 0xcc; + //ADD ESP, 0x4 + buffer[freeSpace + i++] = 0x83; + buffer[freeSpace + i++] = 0xc4; + buffer[freeSpace + i++] = 0x04; + //POP EDI + buffer[freeSpace + i++] = 0x5f; + //POP ESI + buffer[freeSpace + i++] = 0x5e; + //POP EAX + buffer[freeSpace + i++] = 0x58; + //buffer[freeSpace + i++] = 0xcc; + //JMP LdrpSnapThunk - End + buffer[freeSpace + i++] = 0xe9; + writeJumpAddress(freeSpace, virtualFreeSpace, &i, ldrpSnapThunkEnd); + printf("Done (%lu Bytes left)\n", PATCH_SECTION_SIZE - i); + } + + printf("Patching LdrpSnapThunk... "); + buffer[patchPoint] = 0xe9; + writeJumpAddress(patchPoint + 1, patchPoint + 1, patchEntrypointAddress); + for (int i = 5; i < patchSize; i++) { + buffer[patchPoint + i] = 0x90; + } + printf("Done\n"); + + printf("Writing to patched file... "); + if (!writeFile(patchedFile, buffer, fileSize)) { + return 1; + } + printf("Done\n"); + + printf("Generating checksum... "); + DWORD originalChecksum; + DWORD checksum; + if (MapFileAndCheckSum(patchedFile, &originalChecksum, &checksum) != CHECKSUM_SUCCESS) { + printLastError(); + return 1; + } + printf("0x%lx\n", checksum); + + printf("Writing checksum to patched file... "); + writeDWORD(peHeader + 0x18 + 64, checksum); + if (!writeFile(patchedFile, buffer, fileSize)) { + return 1; + } + printf("Finished\n"); + + delete[] buffer; + return 0; +} diff --git a/user32.c b/user32.c new file mode 100644 index 0000000..227c22a --- /dev/null +++ b/user32.c @@ -0,0 +1,31 @@ +#define WIN32_LEAN_AND_MEAN +#define NOUSER +#include +#include +#include +#include "user32.h" + +#define DLL_EXPORT __declspec(dllexport) + +typedef int (WINAPI *MessageBoxAPtr)(HWND hwnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); +typedef int (WINAPI *MessageBoxWPtr)(HWND hwnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType); + +DLL_EXPORT WINAPI int MessageBoxA(HWND hwnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { + MessageBoxAPtr proc = (MessageBoxAPtr) GetProcAddress(GetModuleHandle("_user32.dll"), "MessageBoxA"); + LPSTR buffer = malloc(strlen(lpText) + 1 + 26); + strcpy(buffer, "MessageBoxA gruesst Sie!\n"), + strcat(buffer, lpText); + int result = proc(hwnd, buffer, lpCaption, uType); + free(buffer); + return result; +} + +DLL_EXPORT WINAPI int MessageBoxW(HWND hwnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) { + MessageBoxWPtr proc = (MessageBoxWPtr) GetProcAddress(GetModuleHandle("_user32.dll"), "MessageBoxW"); + LPWSTR buffer = malloc(wcslen(lpText) + 1 + 26); + wcscpy(buffer, L"MessageBoxW gruesst Sie!\n"); + wcscat(buffer, lpText); + int result = proc(hwnd, buffer, lpCaption, uType); + free(buffer); + return result; +} \ No newline at end of file diff --git a/user32.h b/user32.h new file mode 100644 index 0000000..b294a85 --- /dev/null +++ b/user32.h @@ -0,0 +1,622 @@ +#ifndef BCOMPAT_USER32_H +#define BCOMPAT_USER32_H + +#define FORWARDED_EXPORT(exp_name) asm (".section .drectve\n\t.ascii \" -export:" #exp_name "=_user32." #exp_name "\""); +FORWARDED_EXPORT(ActivateKeyboardLayout) +FORWARDED_EXPORT(AdjustWindowRect) +FORWARDED_EXPORT(AdjustWindowRectEx) +FORWARDED_EXPORT(AnyPopup) +FORWARDED_EXPORT(AppendMenuA) +FORWARDED_EXPORT(AppendMenuW) +FORWARDED_EXPORT(ArrangeIconicWindows) +FORWARDED_EXPORT(AttachThreadInput) +FORWARDED_EXPORT(BeginDeferWindowPos) +FORWARDED_EXPORT(BeginPaint) +FORWARDED_EXPORT(BringWindowToTop) +FORWARDED_EXPORT(BroadcastSystemMessage) +FORWARDED_EXPORT(BroadcastSystemMessageA) +FORWARDED_EXPORT(BroadcastSystemMessageW) +FORWARDED_EXPORT(CallMsgFilter) +FORWARDED_EXPORT(CallMsgFilterA) +FORWARDED_EXPORT(CallMsgFilterW) +FORWARDED_EXPORT(CallNextHookEx) +FORWARDED_EXPORT(CallWindowProcA) +FORWARDED_EXPORT(CallWindowProcW) +FORWARDED_EXPORT(CascadeChildWindows) +FORWARDED_EXPORT(CascadeWindows) +FORWARDED_EXPORT(ChangeClipboardChain) +FORWARDED_EXPORT(ChangeDisplaySettingsA) +FORWARDED_EXPORT(ChangeDisplaySettingsExA) +FORWARDED_EXPORT(ChangeDisplaySettingsExW) +FORWARDED_EXPORT(ChangeDisplaySettingsW) +FORWARDED_EXPORT(ChangeMenuA) +FORWARDED_EXPORT(ChangeMenuW) +FORWARDED_EXPORT(CharLowerA) +FORWARDED_EXPORT(CharLowerBuffA) +FORWARDED_EXPORT(CharLowerBuffW) +FORWARDED_EXPORT(CharLowerW) +FORWARDED_EXPORT(CharNextA) +FORWARDED_EXPORT(CharNextExA) +FORWARDED_EXPORT(CharNextW) +FORWARDED_EXPORT(CharPrevA) +FORWARDED_EXPORT(CharPrevExA) +FORWARDED_EXPORT(CharPrevW) +FORWARDED_EXPORT(CharToOemA) +FORWARDED_EXPORT(CharToOemBuffA) +FORWARDED_EXPORT(CharToOemBuffW) +FORWARDED_EXPORT(CharToOemW) +FORWARDED_EXPORT(CharUpperA) +FORWARDED_EXPORT(CharUpperBuffA) +FORWARDED_EXPORT(CharUpperBuffW) +FORWARDED_EXPORT(CharUpperW) +FORWARDED_EXPORT(CheckDlgButton) +FORWARDED_EXPORT(CheckMenuItem) +FORWARDED_EXPORT(CheckMenuRadioItem) +FORWARDED_EXPORT(CheckRadioButton) +FORWARDED_EXPORT(ChildWindowFromPoint) +FORWARDED_EXPORT(ChildWindowFromPointEx) +FORWARDED_EXPORT(ClientThreadSetup) +FORWARDED_EXPORT(ClientToScreen) +FORWARDED_EXPORT(ClipCursor) +FORWARDED_EXPORT(CloseClipboard) +FORWARDED_EXPORT(CloseDesktop) +FORWARDED_EXPORT(CloseWindow) +FORWARDED_EXPORT(CloseWindowStation) +FORWARDED_EXPORT(CopyAcceleratorTableA) +FORWARDED_EXPORT(CopyAcceleratorTableW) +FORWARDED_EXPORT(CopyIcon) +FORWARDED_EXPORT(CopyImage) +FORWARDED_EXPORT(CopyRect) +FORWARDED_EXPORT(CountClipboardFormats) +FORWARDED_EXPORT(CreateAcceleratorTableA) +FORWARDED_EXPORT(CreateAcceleratorTableW) +FORWARDED_EXPORT(CreateCaret) +FORWARDED_EXPORT(CreateCursor) +FORWARDED_EXPORT(CreateDesktopA) +FORWARDED_EXPORT(CreateDesktopW) +FORWARDED_EXPORT(CreateDialogIndirectParamA) +FORWARDED_EXPORT(CreateDialogIndirectParamAorW) +FORWARDED_EXPORT(CreateDialogIndirectParamW) +FORWARDED_EXPORT(CreateDialogParamA) +FORWARDED_EXPORT(CreateDialogParamW) +FORWARDED_EXPORT(CreateIcon) +FORWARDED_EXPORT(CreateIconFromResource) +FORWARDED_EXPORT(CreateIconFromResourceEx) +FORWARDED_EXPORT(CreateIconIndirect) +FORWARDED_EXPORT(CreateMDIWindowA) +FORWARDED_EXPORT(CreateMDIWindowW) +FORWARDED_EXPORT(CreateMenu) +FORWARDED_EXPORT(CreatePopupMenu) +FORWARDED_EXPORT(CreateWindowExA) +FORWARDED_EXPORT(CreateWindowExW) +FORWARDED_EXPORT(CreateWindowStationA) +FORWARDED_EXPORT(CreateWindowStationW) +FORWARDED_EXPORT(DdeAbandonTransaction) +FORWARDED_EXPORT(DdeAccessData) +FORWARDED_EXPORT(DdeAddData) +FORWARDED_EXPORT(DdeClientTransaction) +FORWARDED_EXPORT(DdeCmpStringHandles) +FORWARDED_EXPORT(DdeConnect) +FORWARDED_EXPORT(DdeConnectList) +FORWARDED_EXPORT(DdeCreateDataHandle) +FORWARDED_EXPORT(DdeCreateStringHandleA) +FORWARDED_EXPORT(DdeCreateStringHandleW) +FORWARDED_EXPORT(DdeDisconnect) +FORWARDED_EXPORT(DdeDisconnectList) +FORWARDED_EXPORT(DdeEnableCallback) +FORWARDED_EXPORT(DdeFreeDataHandle) +FORWARDED_EXPORT(DdeFreeStringHandle) +FORWARDED_EXPORT(DdeGetData) +FORWARDED_EXPORT(DdeGetLastError) +FORWARDED_EXPORT(DdeGetQualityOfService) +FORWARDED_EXPORT(DdeImpersonateClient) +FORWARDED_EXPORT(DdeInitializeA) +FORWARDED_EXPORT(DdeInitializeW) +FORWARDED_EXPORT(DdeKeepStringHandle) +FORWARDED_EXPORT(DdeNameService) +FORWARDED_EXPORT(DdePostAdvise) +FORWARDED_EXPORT(DdeQueryConvInfo) +FORWARDED_EXPORT(DdeQueryNextServer) +FORWARDED_EXPORT(DdeQueryStringA) +FORWARDED_EXPORT(DdeQueryStringW) +FORWARDED_EXPORT(DdeReconnect) +FORWARDED_EXPORT(DdeSetQualityOfService) +FORWARDED_EXPORT(DdeSetUserHandle) +FORWARDED_EXPORT(DdeUnaccessData) +FORWARDED_EXPORT(DdeUninitialize) +FORWARDED_EXPORT(DefDlgProcA) +FORWARDED_EXPORT(DefDlgProcW) +FORWARDED_EXPORT(DefFrameProcA) +FORWARDED_EXPORT(DefFrameProcW) +FORWARDED_EXPORT(DefMDIChildProcA) +FORWARDED_EXPORT(DefMDIChildProcW) +FORWARDED_EXPORT(DefWindowProcA) +FORWARDED_EXPORT(DefWindowProcW) +FORWARDED_EXPORT(DeferWindowPos) +FORWARDED_EXPORT(DeleteMenu) +FORWARDED_EXPORT(DeregisterShellHookWindow) +FORWARDED_EXPORT(DestroyAcceleratorTable) +FORWARDED_EXPORT(DestroyCaret) +FORWARDED_EXPORT(DestroyCursor) +FORWARDED_EXPORT(DestroyIcon) +FORWARDED_EXPORT(DestroyMenu) +FORWARDED_EXPORT(DestroyWindow) +FORWARDED_EXPORT(DialogBoxIndirectParamA) +FORWARDED_EXPORT(DialogBoxIndirectParamAorW) +FORWARDED_EXPORT(DialogBoxIndirectParamW) +FORWARDED_EXPORT(DialogBoxParamA) +FORWARDED_EXPORT(DialogBoxParamW) +FORWARDED_EXPORT(DispatchMessageA) +FORWARDED_EXPORT(DispatchMessageW) +FORWARDED_EXPORT(DlgDirListA) +FORWARDED_EXPORT(DlgDirListComboBoxA) +FORWARDED_EXPORT(DlgDirListComboBoxW) +FORWARDED_EXPORT(DlgDirListW) +FORWARDED_EXPORT(DlgDirSelectComboBoxExA) +FORWARDED_EXPORT(DlgDirSelectComboBoxExW) +FORWARDED_EXPORT(DlgDirSelectExA) +FORWARDED_EXPORT(DlgDirSelectExW) +FORWARDED_EXPORT(DragDetect) +FORWARDED_EXPORT(DragObject) +FORWARDED_EXPORT(DrawAnimatedRects) +FORWARDED_EXPORT(DrawCaption) +FORWARDED_EXPORT(DrawCaptionTempA) +FORWARDED_EXPORT(DrawCaptionTempW) +FORWARDED_EXPORT(DrawEdge) +FORWARDED_EXPORT(DrawFocusRect) +FORWARDED_EXPORT(DrawFrame) +FORWARDED_EXPORT(DrawFrameControl) +FORWARDED_EXPORT(DrawIcon) +FORWARDED_EXPORT(DrawIconEx) +FORWARDED_EXPORT(DrawMenuBar) +FORWARDED_EXPORT(DrawMenuBarTemp) +FORWARDED_EXPORT(DrawStateA) +FORWARDED_EXPORT(DrawStateW) +FORWARDED_EXPORT(DrawTextA) +FORWARDED_EXPORT(DrawTextExA) +FORWARDED_EXPORT(DrawTextExW) +FORWARDED_EXPORT(DrawTextW) +FORWARDED_EXPORT(EditWndProc) +FORWARDED_EXPORT(EmptyClipboard) +FORWARDED_EXPORT(EnableMenuItem) +FORWARDED_EXPORT(EnableScrollBar) +FORWARDED_EXPORT(EnableWindow) +FORWARDED_EXPORT(EndDeferWindowPos) +FORWARDED_EXPORT(EndDialog) +FORWARDED_EXPORT(EndMenu) +FORWARDED_EXPORT(EndPaint) +FORWARDED_EXPORT(EndTask) +FORWARDED_EXPORT(EnumChildWindows) +FORWARDED_EXPORT(EnumClipboardFormats) +FORWARDED_EXPORT(EnumDesktopWindows) +FORWARDED_EXPORT(EnumDesktopsA) +FORWARDED_EXPORT(EnumDesktopsW) +FORWARDED_EXPORT(EnumDisplayDevicesA) +FORWARDED_EXPORT(EnumDisplayDevicesW) +FORWARDED_EXPORT(EnumDisplaySettingsA) +FORWARDED_EXPORT(EnumDisplaySettingsW) +FORWARDED_EXPORT(EnumPropsA) +FORWARDED_EXPORT(EnumPropsExA) +FORWARDED_EXPORT(EnumPropsExW) +FORWARDED_EXPORT(EnumPropsW) +FORWARDED_EXPORT(EnumThreadWindows) +FORWARDED_EXPORT(EnumWindowStationsA) +FORWARDED_EXPORT(EnumWindowStationsW) +FORWARDED_EXPORT(EnumWindows) +FORWARDED_EXPORT(EqualRect) +FORWARDED_EXPORT(ExcludeUpdateRgn) +FORWARDED_EXPORT(ExitWindowsEx) +FORWARDED_EXPORT(FillRect) +FORWARDED_EXPORT(FindWindowA) +FORWARDED_EXPORT(FindWindowExA) +FORWARDED_EXPORT(FindWindowExW) +FORWARDED_EXPORT(FindWindowW) +FORWARDED_EXPORT(FlashWindow) +FORWARDED_EXPORT(FrameRect) +FORWARDED_EXPORT(FreeDDElParam) +FORWARDED_EXPORT(FullScreenControl) +FORWARDED_EXPORT(GetActiveWindow) +FORWARDED_EXPORT(GetAppCompatFlags) +FORWARDED_EXPORT(GetAsyncKeyState) +FORWARDED_EXPORT(GetCapture) +FORWARDED_EXPORT(GetCaretBlinkTime) +FORWARDED_EXPORT(GetCaretPos) +FORWARDED_EXPORT(GetClassInfoA) +FORWARDED_EXPORT(GetClassInfoExA) +FORWARDED_EXPORT(GetClassInfoExW) +FORWARDED_EXPORT(GetClassInfoW) +FORWARDED_EXPORT(GetClassLongA) +FORWARDED_EXPORT(GetClassLongW) +FORWARDED_EXPORT(GetClassNameA) +FORWARDED_EXPORT(GetClassNameW) +FORWARDED_EXPORT(GetClassWord) +FORWARDED_EXPORT(GetClientRect) +FORWARDED_EXPORT(GetClipCursor) +FORWARDED_EXPORT(GetClipboardData) +FORWARDED_EXPORT(GetClipboardFormatNameA) +FORWARDED_EXPORT(GetClipboardFormatNameW) +FORWARDED_EXPORT(GetClipboardOwner) +FORWARDED_EXPORT(GetClipboardViewer) +FORWARDED_EXPORT(GetCursor) +FORWARDED_EXPORT(GetCursorInfo) +FORWARDED_EXPORT(GetCursorPos) +FORWARDED_EXPORT(GetDC) +FORWARDED_EXPORT(GetDCEx) +FORWARDED_EXPORT(GetDesktopWindow) +FORWARDED_EXPORT(GetDialogBaseUnits) +FORWARDED_EXPORT(GetDlgCtrlID) +FORWARDED_EXPORT(GetDlgItem) +FORWARDED_EXPORT(GetDlgItemInt) +FORWARDED_EXPORT(GetDlgItemTextA) +FORWARDED_EXPORT(GetDlgItemTextW) +FORWARDED_EXPORT(GetDoubleClickTime) +FORWARDED_EXPORT(GetFocus) +FORWARDED_EXPORT(GetForegroundWindow) +FORWARDED_EXPORT(GetIconInfo) +FORWARDED_EXPORT(GetInputDesktop) +FORWARDED_EXPORT(GetInputState) +FORWARDED_EXPORT(GetInternalWindowPos) +FORWARDED_EXPORT(GetKBCodePage) +FORWARDED_EXPORT(GetKeyNameTextA) +FORWARDED_EXPORT(GetKeyNameTextW) +FORWARDED_EXPORT(GetKeyState) +FORWARDED_EXPORT(GetKeyboardLayout) +FORWARDED_EXPORT(GetKeyboardLayoutList) +FORWARDED_EXPORT(GetKeyboardLayoutNameA) +FORWARDED_EXPORT(GetKeyboardLayoutNameW) +FORWARDED_EXPORT(GetKeyboardState) +FORWARDED_EXPORT(GetKeyboardType) +FORWARDED_EXPORT(GetLastActivePopup) +FORWARDED_EXPORT(GetMenu) +FORWARDED_EXPORT(GetMenuCheckMarkDimensions) +FORWARDED_EXPORT(GetMenuContextHelpId) +FORWARDED_EXPORT(GetMenuDefaultItem) +FORWARDED_EXPORT(GetMenuItemCount) +FORWARDED_EXPORT(GetMenuItemID) +FORWARDED_EXPORT(GetMenuItemInfoA) +FORWARDED_EXPORT(GetMenuItemInfoW) +FORWARDED_EXPORT(GetMenuItemRect) +FORWARDED_EXPORT(GetMenuState) +FORWARDED_EXPORT(GetMenuStringA) +FORWARDED_EXPORT(GetMenuStringW) +FORWARDED_EXPORT(GetMessageA) +FORWARDED_EXPORT(GetMessageExtraInfo) +FORWARDED_EXPORT(GetMessagePos) +FORWARDED_EXPORT(GetMessageTime) +FORWARDED_EXPORT(GetMessageW) +FORWARDED_EXPORT(GetNextDlgGroupItem) +FORWARDED_EXPORT(GetNextDlgTabItem) +FORWARDED_EXPORT(GetOpenClipboardWindow) +FORWARDED_EXPORT(GetParent) +FORWARDED_EXPORT(GetPriorityClipboardFormat) +FORWARDED_EXPORT(GetProcessWindowStation) +FORWARDED_EXPORT(GetProgmanWindow) +FORWARDED_EXPORT(GetPropA) +FORWARDED_EXPORT(GetPropW) +FORWARDED_EXPORT(GetQueueStatus) +FORWARDED_EXPORT(GetScrollInfo) +FORWARDED_EXPORT(GetScrollPos) +FORWARDED_EXPORT(GetScrollRange) +FORWARDED_EXPORT(GetShellWindow) +FORWARDED_EXPORT(GetSubMenu) +FORWARDED_EXPORT(GetSysColor) +FORWARDED_EXPORT(GetSysColorBrush) +FORWARDED_EXPORT(GetSystemMenu) +FORWARDED_EXPORT(GetSystemMetrics) +FORWARDED_EXPORT(GetTabbedTextExtentA) +FORWARDED_EXPORT(GetTabbedTextExtentW) +FORWARDED_EXPORT(GetTaskmanWindow) +FORWARDED_EXPORT(GetThreadDesktop) +FORWARDED_EXPORT(GetTopWindow) +FORWARDED_EXPORT(GetUpdateRect) +FORWARDED_EXPORT(GetUpdateRgn) +FORWARDED_EXPORT(GetUserObjectInformationA) +FORWARDED_EXPORT(GetUserObjectInformationW) +FORWARDED_EXPORT(GetUserObjectSecurity) +FORWARDED_EXPORT(GetWindow) +FORWARDED_EXPORT(GetWindowContextHelpId) +FORWARDED_EXPORT(GetWindowDC) +FORWARDED_EXPORT(GetWindowLongA) +FORWARDED_EXPORT(GetWindowLongW) +FORWARDED_EXPORT(GetWindowPlacement) +FORWARDED_EXPORT(GetWindowRect) +FORWARDED_EXPORT(GetWindowRgn) +FORWARDED_EXPORT(GetWindowTextA) +FORWARDED_EXPORT(GetWindowTextLengthA) +FORWARDED_EXPORT(GetWindowTextLengthW) +FORWARDED_EXPORT(GetWindowTextW) +FORWARDED_EXPORT(GetWindowThreadProcessId) +FORWARDED_EXPORT(GetWindowWord) +FORWARDED_EXPORT(GrayStringA) +FORWARDED_EXPORT(GrayStringW) +FORWARDED_EXPORT(HideCaret) +FORWARDED_EXPORT(HiliteMenuItem) +FORWARDED_EXPORT(ImpersonateDdeClientWindow) +FORWARDED_EXPORT(InSendMessage) +FORWARDED_EXPORT(InflateRect) +FORWARDED_EXPORT(InsertMenuA) +FORWARDED_EXPORT(InsertMenuItemA) +FORWARDED_EXPORT(InsertMenuItemW) +FORWARDED_EXPORT(InsertMenuW) +FORWARDED_EXPORT(InternalGetWindowText) +FORWARDED_EXPORT(IntersectRect) +FORWARDED_EXPORT(InvalidateRect) +FORWARDED_EXPORT(InvalidateRgn) +FORWARDED_EXPORT(InvertRect) +FORWARDED_EXPORT(IsCharAlphaA) +FORWARDED_EXPORT(IsCharAlphaNumericA) +FORWARDED_EXPORT(IsCharAlphaNumericW) +FORWARDED_EXPORT(IsCharAlphaW) +FORWARDED_EXPORT(IsCharLowerA) +FORWARDED_EXPORT(IsCharLowerW) +FORWARDED_EXPORT(IsCharUpperA) +FORWARDED_EXPORT(IsCharUpperW) +FORWARDED_EXPORT(IsChild) +FORWARDED_EXPORT(IsClipboardFormatAvailable) +FORWARDED_EXPORT(IsDialogMessage) +FORWARDED_EXPORT(IsDialogMessageA) +FORWARDED_EXPORT(IsDialogMessageW) +FORWARDED_EXPORT(IsDlgButtonChecked) +FORWARDED_EXPORT(IsHungAppWindow) +FORWARDED_EXPORT(IsIconic) +FORWARDED_EXPORT(IsMenu) +FORWARDED_EXPORT(IsRectEmpty) +FORWARDED_EXPORT(IsWindow) +FORWARDED_EXPORT(IsWindowEnabled) +FORWARDED_EXPORT(IsWindowUnicode) +FORWARDED_EXPORT(IsWindowVisible) +FORWARDED_EXPORT(IsZoomed) +FORWARDED_EXPORT(KillSystemTimer) +FORWARDED_EXPORT(KillTimer) +FORWARDED_EXPORT(LoadAcceleratorsA) +FORWARDED_EXPORT(LoadAcceleratorsW) +FORWARDED_EXPORT(LoadBitmapA) +FORWARDED_EXPORT(LoadBitmapW) +FORWARDED_EXPORT(LoadCursorA) +FORWARDED_EXPORT(LoadCursorFromFileA) +FORWARDED_EXPORT(LoadCursorFromFileW) +FORWARDED_EXPORT(LoadCursorW) +FORWARDED_EXPORT(LoadIconA) +FORWARDED_EXPORT(LoadIconW) +FORWARDED_EXPORT(LoadImageA) +FORWARDED_EXPORT(LoadImageW) +FORWARDED_EXPORT(LoadKeyboardLayoutA) +FORWARDED_EXPORT(LoadKeyboardLayoutEx) +FORWARDED_EXPORT(LoadKeyboardLayoutW) +FORWARDED_EXPORT(LoadLocalFonts) +FORWARDED_EXPORT(LoadMenuA) +FORWARDED_EXPORT(LoadMenuIndirectA) +FORWARDED_EXPORT(LoadMenuIndirectW) +FORWARDED_EXPORT(LoadMenuW) +FORWARDED_EXPORT(LoadRemoteFonts) +FORWARDED_EXPORT(LoadStringA) +FORWARDED_EXPORT(LoadStringW) +FORWARDED_EXPORT(LockWindowStation) +FORWARDED_EXPORT(LockWindowUpdate) +FORWARDED_EXPORT(LookupIconIdFromDirectory) +FORWARDED_EXPORT(LookupIconIdFromDirectoryEx) +FORWARDED_EXPORT(MBToWCSEx) +FORWARDED_EXPORT(MB_GetString) +FORWARDED_EXPORT(MapDialogRect) +FORWARDED_EXPORT(MapVirtualKeyA) +FORWARDED_EXPORT(MapVirtualKeyExA) +FORWARDED_EXPORT(MapVirtualKeyExW) +FORWARDED_EXPORT(MapVirtualKeyW) +FORWARDED_EXPORT(MapWindowPoints) +FORWARDED_EXPORT(MenuItemFromPoint) +FORWARDED_EXPORT(MenuWindowProcA) +FORWARDED_EXPORT(MenuWindowProcW) +FORWARDED_EXPORT(MessageBeep) +//FORWARDED_EXPORT(MessageBoxA) +FORWARDED_EXPORT(MessageBoxExA) +FORWARDED_EXPORT(MessageBoxExW) +FORWARDED_EXPORT(MessageBoxIndirectA) +FORWARDED_EXPORT(MessageBoxIndirectW) +//FORWARDED_EXPORT(MessageBoxW) +FORWARDED_EXPORT(ModifyMenuA) +FORWARDED_EXPORT(ModifyMenuW) +FORWARDED_EXPORT(MoveWindow) +FORWARDED_EXPORT(MsgWaitForMultipleObjects) +FORWARDED_EXPORT(MsgWaitForMultipleObjectsEx) +FORWARDED_EXPORT(OemKeyScan) +FORWARDED_EXPORT(OemToCharA) +FORWARDED_EXPORT(OemToCharBuffA) +FORWARDED_EXPORT(OemToCharBuffW) +FORWARDED_EXPORT(OemToCharW) +FORWARDED_EXPORT(OffsetRect) +FORWARDED_EXPORT(OpenClipboard) +FORWARDED_EXPORT(OpenDesktopA) +FORWARDED_EXPORT(OpenDesktopW) +FORWARDED_EXPORT(OpenIcon) +FORWARDED_EXPORT(OpenInputDesktop) +FORWARDED_EXPORT(OpenWindowStationA) +FORWARDED_EXPORT(OpenWindowStationW) +FORWARDED_EXPORT(PackDDElParam) +FORWARDED_EXPORT(PaintDesktop) +FORWARDED_EXPORT(PeekMessageA) +FORWARDED_EXPORT(PeekMessageW) +FORWARDED_EXPORT(PostMessageA) +FORWARDED_EXPORT(PostMessageW) +FORWARDED_EXPORT(PostQuitMessage) +FORWARDED_EXPORT(PostThreadMessageA) +FORWARDED_EXPORT(PostThreadMessageW) +FORWARDED_EXPORT(PrivateExtractIconExA) +FORWARDED_EXPORT(PrivateExtractIconExW) +FORWARDED_EXPORT(PrivateExtractIconsA) +FORWARDED_EXPORT(PrivateExtractIconsW) +FORWARDED_EXPORT(PrivateKDBreakPoint) +FORWARDED_EXPORT(PtInRect) +FORWARDED_EXPORT(QuerySendMessage) +FORWARDED_EXPORT(RedrawWindow) +FORWARDED_EXPORT(RegisterClassA) +FORWARDED_EXPORT(RegisterClassExA) +FORWARDED_EXPORT(RegisterClassExW) +FORWARDED_EXPORT(RegisterClassW) +FORWARDED_EXPORT(RegisterClipboardFormatA) +FORWARDED_EXPORT(RegisterClipboardFormatW) +FORWARDED_EXPORT(RegisterHotKey) +FORWARDED_EXPORT(RegisterLogonProcess) +FORWARDED_EXPORT(RegisterServicesProcess) +FORWARDED_EXPORT(RegisterShellHookWindow) +FORWARDED_EXPORT(RegisterSystemThread) +FORWARDED_EXPORT(RegisterTasklist) +FORWARDED_EXPORT(RegisterWindowMessageA) +FORWARDED_EXPORT(RegisterWindowMessageW) +FORWARDED_EXPORT(ReleaseCapture) +FORWARDED_EXPORT(ReleaseDC) +FORWARDED_EXPORT(RemoveMenu) +FORWARDED_EXPORT(RemovePropA) +FORWARDED_EXPORT(RemovePropW) +FORWARDED_EXPORT(ReplyMessage) +FORWARDED_EXPORT(ReuseDDElParam) +FORWARDED_EXPORT(ScreenToClient) +FORWARDED_EXPORT(ScrollChildren) +FORWARDED_EXPORT(ScrollDC) +FORWARDED_EXPORT(ScrollWindow) +FORWARDED_EXPORT(ScrollWindowEx) +FORWARDED_EXPORT(SendDlgItemMessageA) +FORWARDED_EXPORT(SendDlgItemMessageW) +FORWARDED_EXPORT(SendMessageA) +FORWARDED_EXPORT(SendMessageCallbackA) +FORWARDED_EXPORT(SendMessageCallbackW) +FORWARDED_EXPORT(SendMessageTimeoutA) +FORWARDED_EXPORT(SendMessageTimeoutW) +FORWARDED_EXPORT(SendMessageW) +FORWARDED_EXPORT(SendNotifyMessageA) +FORWARDED_EXPORT(SendNotifyMessageW) +FORWARDED_EXPORT(SetActiveWindow) +FORWARDED_EXPORT(SetCapture) +FORWARDED_EXPORT(SetCaretBlinkTime) +FORWARDED_EXPORT(SetCaretPos) +FORWARDED_EXPORT(SetClassLongA) +FORWARDED_EXPORT(SetClassLongW) +FORWARDED_EXPORT(SetClassWord) +FORWARDED_EXPORT(SetClipboardData) +FORWARDED_EXPORT(SetClipboardViewer) +FORWARDED_EXPORT(SetConsoleReserveKeys) +FORWARDED_EXPORT(SetCursor) +FORWARDED_EXPORT(SetCursorContents) +FORWARDED_EXPORT(SetCursorPos) +FORWARDED_EXPORT(SetDebugErrorLevel) +FORWARDED_EXPORT(SetDeskWallpaper) +FORWARDED_EXPORT(SetDlgItemInt) +FORWARDED_EXPORT(SetDlgItemTextA) +FORWARDED_EXPORT(SetDlgItemTextW) +FORWARDED_EXPORT(SetDoubleClickTime) +FORWARDED_EXPORT(SetFocus) +FORWARDED_EXPORT(SetForegroundWindow) +FORWARDED_EXPORT(SetInternalWindowPos) +FORWARDED_EXPORT(SetKeyboardState) +FORWARDED_EXPORT(SetLastErrorEx) +FORWARDED_EXPORT(SetLogonNotifyWindow) +FORWARDED_EXPORT(SetMenu) +FORWARDED_EXPORT(SetMenuContextHelpId) +FORWARDED_EXPORT(SetMenuDefaultItem) +FORWARDED_EXPORT(SetMenuItemBitmaps) +FORWARDED_EXPORT(SetMenuItemInfoA) +FORWARDED_EXPORT(SetMenuItemInfoW) +FORWARDED_EXPORT(SetMessageExtraInfo) +FORWARDED_EXPORT(SetMessageQueue) +FORWARDED_EXPORT(SetParent) +FORWARDED_EXPORT(SetProcessWindowStation) +FORWARDED_EXPORT(SetProgmanWindow) +FORWARDED_EXPORT(SetPropA) +FORWARDED_EXPORT(SetPropW) +FORWARDED_EXPORT(SetRect) +FORWARDED_EXPORT(SetRectEmpty) +FORWARDED_EXPORT(SetScrollInfo) +FORWARDED_EXPORT(SetScrollPos) +FORWARDED_EXPORT(SetScrollRange) +FORWARDED_EXPORT(SetShellWindow) +FORWARDED_EXPORT(SetShellWindowEx) +FORWARDED_EXPORT(SetSysColors) +FORWARDED_EXPORT(SetSysColorsTemp) +FORWARDED_EXPORT(SetSystemCursor) +FORWARDED_EXPORT(SetSystemMenu) +FORWARDED_EXPORT(SetSystemTimer) +FORWARDED_EXPORT(SetTaskmanWindow) +FORWARDED_EXPORT(SetThreadDesktop) +FORWARDED_EXPORT(SetTimer) +FORWARDED_EXPORT(SetUserObjectInformationA) +FORWARDED_EXPORT(SetUserObjectInformationW) +FORWARDED_EXPORT(SetUserObjectSecurity) +FORWARDED_EXPORT(SetWindowContextHelpId) +FORWARDED_EXPORT(SetWindowLongA) +FORWARDED_EXPORT(SetWindowLongW) +FORWARDED_EXPORT(SetWindowPlacement) +FORWARDED_EXPORT(SetWindowPos) +FORWARDED_EXPORT(SetWindowRgn) +FORWARDED_EXPORT(SetWindowStationUser) +FORWARDED_EXPORT(SetWindowTextA) +FORWARDED_EXPORT(SetWindowTextW) +FORWARDED_EXPORT(SetWindowWord) +FORWARDED_EXPORT(SetWindowsHookA) +FORWARDED_EXPORT(SetWindowsHookExA) +FORWARDED_EXPORT(SetWindowsHookExW) +FORWARDED_EXPORT(SetWindowsHookW) +FORWARDED_EXPORT(ShowCaret) +FORWARDED_EXPORT(ShowCursor) +FORWARDED_EXPORT(ShowOwnedPopups) +FORWARDED_EXPORT(ShowScrollBar) +FORWARDED_EXPORT(ShowStartGlass) +FORWARDED_EXPORT(ShowWindow) +FORWARDED_EXPORT(ShowWindowAsync) +FORWARDED_EXPORT(SoftModalMessageBox) +FORWARDED_EXPORT(SubtractRect) +FORWARDED_EXPORT(SwapMouseButton) +FORWARDED_EXPORT(SwitchDesktop) +FORWARDED_EXPORT(SwitchToThisWindow) +FORWARDED_EXPORT(SystemParametersInfoA) +FORWARDED_EXPORT(SystemParametersInfoW) +FORWARDED_EXPORT(TabbedTextOutA) +FORWARDED_EXPORT(TabbedTextOutW) +FORWARDED_EXPORT(TileChildWindows) +FORWARDED_EXPORT(TileWindows) +FORWARDED_EXPORT(ToAscii) +FORWARDED_EXPORT(ToAsciiEx) +FORWARDED_EXPORT(ToUnicode) +FORWARDED_EXPORT(ToUnicodeEx) +FORWARDED_EXPORT(TrackMouseEvent) +FORWARDED_EXPORT(TrackPopupMenu) +FORWARDED_EXPORT(TrackPopupMenuEx) +FORWARDED_EXPORT(TranslateAccelerator) +FORWARDED_EXPORT(TranslateAcceleratorA) +FORWARDED_EXPORT(TranslateAcceleratorW) +FORWARDED_EXPORT(TranslateMDISysAccel) +FORWARDED_EXPORT(TranslateMessage) +FORWARDED_EXPORT(TranslateMessageEx) +FORWARDED_EXPORT(UnhookWindowsHook) +FORWARDED_EXPORT(UnhookWindowsHookEx) +FORWARDED_EXPORT(UnionRect) +FORWARDED_EXPORT(UnloadKeyboardLayout) +FORWARDED_EXPORT(UnlockWindowStation) +FORWARDED_EXPORT(UnpackDDElParam) +FORWARDED_EXPORT(UnregisterClassA) +FORWARDED_EXPORT(UnregisterClassW) +FORWARDED_EXPORT(UnregisterHotKey) +FORWARDED_EXPORT(UpdatePerUserSystemParameters) +FORWARDED_EXPORT(UpdateWindow) +FORWARDED_EXPORT(UserClientDllInitialize) +FORWARDED_EXPORT(UserRealizePalette) +FORWARDED_EXPORT(UserRegisterWowHandlers) +FORWARDED_EXPORT(ValidateRect) +FORWARDED_EXPORT(ValidateRgn) +FORWARDED_EXPORT(VkKeyScanA) +FORWARDED_EXPORT(VkKeyScanExA) +FORWARDED_EXPORT(VkKeyScanExW) +FORWARDED_EXPORT(VkKeyScanW) +FORWARDED_EXPORT(WCSToMBEx) +FORWARDED_EXPORT(WaitForInputIdle) +FORWARDED_EXPORT(WaitMessage) +FORWARDED_EXPORT(WinHelpA) +FORWARDED_EXPORT(WinHelpW) +FORWARDED_EXPORT(WindowFromDC) +FORWARDED_EXPORT(WindowFromPoint) +FORWARDED_EXPORT(keybd_event) +FORWARDED_EXPORT(mouse_event) +FORWARDED_EXPORT(wsprintfA) +FORWARDED_EXPORT(wsprintfW) +FORWARDED_EXPORT(wvsprintfA) +FORWARDED_EXPORT(wvsprintfW) + +#endif //BCOMPAT_USER32_H \ No newline at end of file