From a9306a1408a862d90f48b3afd4539098242cdc5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Jab=C5=82o=C5=84ski?= Date: Sat, 13 Apr 2024 19:04:38 +0200 Subject: [PATCH 1/9] Implement changes for cmd.exe support --- COREDLL/Exports.def | 10 ++-- COREDLL/other.cpp | 113 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 107 insertions(+), 16 deletions(-) diff --git a/COREDLL/Exports.def b/COREDLL/Exports.def index 84dc2c9..5b139af 100644 --- a/COREDLL/Exports.def +++ b/COREDLL/Exports.def @@ -21,8 +21,8 @@ EXPORTS FindNextFileW=FindNextFileW_WCECL @181 FindFirstFileW=FindFirstFileW_WCECL @167 WaitForAPIReady @2562 - SetStdioPathW @1150 - GetStdioPathW @1149 + SetStdioPathW=SetStdioPathW_WCECL @1150 + GetStdioPathW=GetStdioPathW_WCECL @1149 DeviceIoControl=DeviceIoControl_WCECL @179 _wfopen @1145 fread @1120 @@ -31,7 +31,7 @@ EXPORTS _wcsupr @232 vfwprintf=vfwprintf_WCECL @721 fflush @1122 - fgetws @1143 + fgetws=fgetws_WCECL @1143 fputwc @1141 fputws @1144 _getstdfilex=_getstdfilex_WCECL @1100 @@ -133,7 +133,7 @@ EXPORTS towlower @194 towupper @195 MultiByteToWideChar @196 - WideCharToMultiByte @197 + WideCharToMultiByte=WideCharToMultiByte_WCECL @197 CompareStringW @198 LCMapStringW @199 SetLocaleInfoW @201 @@ -398,7 +398,7 @@ EXPORTS qsort @1052 rand @1053 realloc @1054 - _fileno @1124 + _fileno=_fileno_WCECL @1124 feof @1125 ferror @1126 clearerr @1127 diff --git a/COREDLL/other.cpp b/COREDLL/other.cpp index e00f39a..4d8172f 100644 --- a/COREDLL/other.cpp +++ b/COREDLL/other.cpp @@ -1,5 +1,6 @@ // other.cpp : contains unknown for me and other weird functions ) #include "stdafx.h" +#include // Functions HANDLE GetOwnerProcess_WCECL() @@ -87,7 +88,7 @@ int _snwprintf_WCECL(wchar_t * buf, size_t bufCount, const wchar_t * fmt, ...) va_list args; va_start(args, fmt); - auto result = _snwprintf(buf, bufCount, fmt, args); + auto result = _vsnwprintf(buf, bufCount, fmt, args); va_end(args); @@ -99,11 +100,11 @@ int _snwprintf_WCECL(wchar_t * buf, size_t bufCount, const wchar_t * fmt, ...) int __cdecl swscanf_WCECL(const wchar_t * buf, const wchar_t * fmt, ...) { #pragma warning( push ) -#pragma warning( disable: 4995 ) +#pragma warning( disable: 4995 4996 ) va_list args; va_start(args, fmt); - auto result = swscanf(buf, fmt, args); + auto result = vswscanf(buf, fmt, args); va_end(args); #pragma warning( pop ) @@ -114,11 +115,11 @@ int __cdecl swscanf_WCECL(const wchar_t * buf, const wchar_t * fmt, ...) int swprintf_WCECL(wchar_t * buf, const wchar_t * _format, ...) { #pragma warning( push ) -#pragma warning( disable: 4995 ) +#pragma warning( disable: 4995 4996 ) va_list args; va_start(args, _format); - auto result = swprintf(buf, _format, args); + auto result = vswprintf(buf, _format, args); va_end(args); #pragma warning( pop ) @@ -130,11 +131,11 @@ int swprintf_WCECL(wchar_t * buf, const wchar_t * _format, ...) int sprintf_WCECL(char* buffer, const char* format, ...) { #pragma warning( push ) -#pragma warning( disable: 4995 ) +#pragma warning( disable: 4995 4996 ) va_list args; va_start(args, format); - auto result = sprintf(buffer, format, args); + auto result = vsprintf(buffer, format, args); va_end(args); #pragma warning( pop ) @@ -193,12 +194,102 @@ void CeLogSetZones(DWORD dwZoneUser, // User-defined zones // wtf!? } +FILE* WINAPI _getstdfilex_WCECL(DWORD type) +{ + switch (type) + { + case 0: + return stdin; + case 1: + return stdout; + case 2: + return stderr; + default: + Assert32(FALSE); + return NULL; + } +} + +BOOL WINAPI SetStdioPathW_WCECL( + DWORD id, + PWSTR pwszPath) +{ + /* TODO: test */ + switch (id) + { + case 0: + return (_wfreopen(pwszPath, L"r", stdin) != NULL); + case 1: + return (_wfreopen(pwszPath, L"w", stdout) != NULL); + case 2: + return (_wfreopen(pwszPath, L"w", stderr) != NULL); + default: + Assert32(FALSE); + return NULL; + } +} + +BOOL WINAPI GetStdioPathW_WCECL( + DWORD id, + PWSTR pwszBuf, + LPDWORD lpdwLen) +{ + /* TODO: test */ + FILE* filePtr = _getstdfilex_WCECL(id); + HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(filePtr)); + if (GetFinalPathNameByHandleW(hFile, pwszBuf, *lpdwLen, 0) < *lpdwLen) + { + return TRUE; + } + + return FALSE; +} + +void* _fileno_WCECL(FILE* file) +{ + return (void*)_get_osfhandle(_fileno(file)); +} + +int WINAPI WideCharToMultiByte_WCECL( + UINT CodePage, + DWORD dwFlags, + LPCWSTR lpWideCharStr, + int cchWideChar, + LPSTR lpMultiByteStr, + int cbMultiByte, + LPCSTR lpDefaultChar, + LPBOOL lpUsedDefaultChar) +{ + return WideCharToMultiByte( + CodePage, + dwFlags, + lpWideCharStr, + cchWideChar, + lpMultiByteStr, + cbMultiByte, + lpDefaultChar, + lpUsedDefaultChar); +} + +wchar_t* fgetws_WCECL(wchar_t* w, int count, FILE* file) +{ + wchar_t* result = fgetws(w, count, file); + if (result == NULL && + file == stdin && count > 2) + { + result = w; + wsprintf(w, L""); + } + else + { + return result; + } + return result; +} + // Stubs Stub(_chkstk_WCECL); -Stub(WaitForAPIReady) -Stub(SetStdioPathW); -Stub(GetStdioPathW); -Stub(_getstdfilex_WCECL); // FILE* __cdecl _getstdfilex_WCECL(int a1) +Stub(WaitForAPIReady); Stub(RegisterDefaultGestureHandler_WCECL); Stub(CloseGestureInfoHandle_WCECL); Stub(GetGestureExtraArguments_WCECL); From 0228fb15a195461840b13111b0ba5e691d5987b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Jab=C5=82o=C5=84ski?= Date: Sat, 13 Apr 2024 19:15:48 +0200 Subject: [PATCH 2/9] Fix FindXXXFile functions --- COREDLL/other.cpp | 2 +- COREDLL/stdafx.h | 12 ++++++++++ COREDLL/winbase_wcecl.cpp | 47 +++++++++++++++++++++++++++++++++++---- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/COREDLL/other.cpp b/COREDLL/other.cpp index 4d8172f..065ddee 100644 --- a/COREDLL/other.cpp +++ b/COREDLL/other.cpp @@ -84,7 +84,7 @@ LCID WINAPI ConvertDefaultLocale_WCECL(LCID Locale) int _snwprintf_WCECL(wchar_t * buf, size_t bufCount, const wchar_t * fmt, ...) { #pragma warning( push ) -#pragma warning( disable: 4995 ) +#pragma warning( disable: 4995 4996) va_list args; va_start(args, fmt); diff --git a/COREDLL/stdafx.h b/COREDLL/stdafx.h index 7425020..60cc224 100644 --- a/COREDLL/stdafx.h +++ b/COREDLL/stdafx.h @@ -40,6 +40,18 @@ typedef struct tagWNDCLASSW_WCECL { LPCWSTR lpszClassName; } WNDCLASSW_WCECL, *PWNDCLASSW_WCECL, *LPWNDCLASSW_WCECL; +typedef struct tagWIN32_FIND_DATA_WCECL +{ + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwOID; + TCHAR cFileName[MAX_PATH]; +} WIN32_FIND_DATA_WCECL, *PWIN32_FIND_DATA_WCECL, *LPWIN32_FIND_DATA_WCECL; + // MACROS #undef RasHangUp #undef RasDial diff --git a/COREDLL/winbase_wcecl.cpp b/COREDLL/winbase_wcecl.cpp index d787df7..2d2444e 100644 --- a/COREDLL/winbase_wcecl.cpp +++ b/COREDLL/winbase_wcecl.cpp @@ -367,20 +367,59 @@ BOOL WINAPI DeleteFileW_WCECL(LPCWSTR lpFileName) auto result = DeleteFileW(lpFileName); return result; } +static void ConvertFindDataToWcecl( + LPWIN32_FIND_DATA_WCECL lpWceclData, + LPWIN32_FIND_DATAW lpFindData) +{ + wcscpy_s(lpWceclData->cFileName, + sizeof(lpWceclData->cFileName) / sizeof(*lpWceclData->cFileName), + lpFindData->cFileName); + lpWceclData->dwFileAttributes = lpFindData->dwFileAttributes; + lpWceclData->dwOID = lpFindData->dwReserved0; + lpWceclData->ftCreationTime = lpFindData->ftCreationTime; + lpWceclData->ftLastAccessTime = lpFindData->ftLastAccessTime; + lpWceclData->ftLastWriteTime = lpFindData->ftLastWriteTime; + lpWceclData->nFileSizeHigh = lpFindData->nFileSizeHigh; + lpWceclData->nFileSizeLow = lpFindData->nFileSizeLow; +} + +static void ConvertFindDataFromWcecl( + LPWIN32_FIND_DATAW lpFindData, + LPWIN32_FIND_DATA_WCECL lpWceclData) +{ + wcscpy_s(lpFindData->cFileName, + sizeof(lpFindData->cFileName) / sizeof(*lpFindData->cFileName), + lpWceclData->cFileName); + lpFindData->dwFileAttributes = lpWceclData->dwFileAttributes; + lpFindData->dwReserved0 = lpWceclData->dwOID; + lpFindData->ftCreationTime = lpWceclData->ftCreationTime; + lpFindData->ftLastAccessTime = lpWceclData->ftLastAccessTime; + lpFindData->ftLastWriteTime = lpWceclData->ftLastWriteTime; + lpFindData->nFileSizeHigh = lpWceclData->nFileSizeHigh; + lpFindData->nFileSizeLow = lpWceclData->nFileSizeLow; +} HANDLE WINAPI FindFirstFileW_WCECL( LPCWSTR lpFileName, - LPWIN32_FIND_DATAW lpFindFileData) + LPWIN32_FIND_DATA_WCECL lpFindFileData) { - auto result = FindFirstFileW(lpFileName, lpFindFileData); + WIN32_FIND_DATAW findData; + + ConvertFindDataFromWcecl(&findData, lpFindFileData); + auto result = FindFirstFileW(lpFileName, &findData); + ConvertFindDataToWcecl(lpFindFileData, &findData); return result; } BOOL WINAPI FindNextFileW_WCECL( HANDLE hFindFile, - LPWIN32_FIND_DATAW lpFindFileData) + LPWIN32_FIND_DATA_WCECL lpFindFileData) { - auto result = FindNextFileW(hFindFile, lpFindFileData); + WIN32_FIND_DATAW findData; + + ConvertFindDataFromWcecl(&findData, lpFindFileData); + auto result = FindNextFileW(hFindFile, &findData); + ConvertFindDataToWcecl(lpFindFileData, &findData); return result; } From 76e805c1ed5ae45db4fe89998fa535c8c0bc3f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Jab=C5=82o=C5=84ski?= Date: Sat, 13 Apr 2024 19:28:30 +0200 Subject: [PATCH 3/9] Add a very dirty hack for cmd.exe --- COREDLL/dllmain.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/COREDLL/dllmain.cpp b/COREDLL/dllmain.cpp index 552116b..a057a76 100644 --- a/COREDLL/dllmain.cpp +++ b/COREDLL/dllmain.cpp @@ -1,6 +1,8 @@ // dllmain.cpp : Defines the entry point for the DLL application. #include "stdafx.h" +typedef UINT(__cdecl* CE_ENTRYPOINT)(HINSTANCE, HINSTANCE, LPCWSTR, int); + #undef __stdcall // DllMain should be __stdcall always BOOL __stdcall DllMain(HMODULE hModule, DWORD ul_reason_for_call, @@ -11,6 +13,10 @@ BOOL __stdcall DllMain(HMODULE hModule, { case DLL_PROCESS_ATTACH: { + AllocConsole(); + freopen("CONOUT$", "w", stdout); + freopen("CONIN$", "r", stdin); + if (MessageBoxExW( NULL, L"Attach a debugger now?", @@ -27,7 +33,7 @@ BOOL __stdcall DllMain(HMODULE hModule, swprintf_s(CmdLineBuf, 256, L"%s -p %d", VSJitDebugger, GetCurrentProcessId()); StartupInfo.wShowWindow = TRUE; - + // MessageBoxW(NULL, CmdLineBuf, VSJitDebugger, 0); Assert32(CreateProcess( @@ -42,6 +48,15 @@ BOOL __stdcall DllMain(HMODULE hModule, CloseHandle(Info.hProcess); CloseHandle(Info.hThread); } + + MODULEINFO moduleInfo; + HMODULE hModule = GetModuleHandleW(NULL); + + GetModuleInformation(GetCurrentProcess(), hModule, &moduleInfo, sizeof(moduleInfo)); + CE_ENTRYPOINT entrypoint = (CE_ENTRYPOINT)moduleInfo.EntryPoint; + + LPCWSTR wstr = L""; + ExitProcess(entrypoint(hModule, NULL, wstr, 0)); break; }; // From d37c0a28bc3da61539286f6d50a47d52b63f2416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Jab=C5=82o=C5=84ski?= Date: Sun, 14 Apr 2024 00:52:43 +0200 Subject: [PATCH 4/9] Add initial entrypoint hijacking support --- COREDLL/dllmain.cpp | 126 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 117 insertions(+), 9 deletions(-) diff --git a/COREDLL/dllmain.cpp b/COREDLL/dllmain.cpp index a057a76..a4a79be 100644 --- a/COREDLL/dllmain.cpp +++ b/COREDLL/dllmain.cpp @@ -1,9 +1,124 @@ // dllmain.cpp : Defines the entry point for the DLL application. #include "stdafx.h" +#include "winuser_wcecl.h" typedef UINT(__cdecl* CE_ENTRYPOINT)(HINSTANCE, HINSTANCE, LPCWSTR, int); +void WceclEntrypointWrapper(); + +#pragma pack(push, 1) + +static struct +{ + BYTE Push; + void* Address; + BYTE Ret; +} +EntrypointHijackCode[] = { {0x68, WceclEntrypointWrapper, 0xC3} }; +static BYTE EntrypointRepairCode[sizeof(EntrypointHijackCode)]; +CE_ENTRYPOINT Entrypoint; + +#pragma pack(pop) + +static void WceclEntrypointWrapper() +{ + STARTUPINFOW startupInfo; + LPCWSTR commandLine; + BOOL bQuoted; + UINT result; + int nCmdShow; + + GetStartupInfoW(&startupInfo); + commandLine = GetCommandLineW(); + + /* FIXME: It seems WinCE programs do not want the image path to be included + in the commandLine passed to them. + + For now, find the first argument and skip its length worth of bytes + from the command line. */ + bQuoted = FALSE; + + while (*commandLine) + { + if (*commandLine == '"') + { + bQuoted = !bQuoted; + } + if (bQuoted == FALSE) + { + if (iswspace(*commandLine)) + { + while (iswspace(*commandLine)) commandLine++; + break; + } + } + commandLine++; + } + + nCmdShow = 1; + if (startupInfo.dwFlags & STARTF_USESHOWWINDOW) + { + switch (startupInfo.wShowWindow) + { + case SW_RESTORE: + nCmdShow = WINCE_SW_RESTORE; + break; + case SW_MAXIMIZE: + nCmdShow = WINCE_SW_MAXIMIZE; + break; + } + } + + memcpy(Entrypoint, EntrypointRepairCode, sizeof(EntrypointRepairCode)); + result = Entrypoint(GetModuleHandleW(NULL), NULL, commandLine, nCmdShow); + ExitProcess(result); +} + +static BOOL WceclPatchEntrypoint() +{ + MODULEINFO moduleInfo; + HMODULE hModule; + PIMAGE_DOS_HEADER dosHeader; + DWORD dwOld; + MEMORY_BASIC_INFORMATION mbi; + CE_ENTRYPOINT entrypoint; + + hModule = GetModuleHandleW(NULL); + dosHeader = (PIMAGE_DOS_HEADER)hModule; + + if (GetModuleInformation( + GetCurrentProcess(), + hModule, + &moduleInfo, + sizeof(moduleInfo)) == FALSE) + { + return FALSE; + } + entrypoint = (CE_ENTRYPOINT)moduleInfo.EntryPoint; + + /* Unprotect the entrypoint, so it is possible to hijack it, and + to later repair it. */ + + VirtualQuery(entrypoint, &mbi, sizeof(mbi)); + mbi.Protect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ); + mbi.Protect |= PAGE_EXECUTE_READWRITE; + + if (VirtualProtect( + mbi.BaseAddress, + mbi.RegionSize, + mbi.Protect, + &dwOld) == FALSE) + { + return FALSE; + } + + memcpy(EntrypointRepairCode, entrypoint, sizeof(EntrypointRepairCode)); + memcpy(entrypoint, EntrypointHijackCode, sizeof(EntrypointHijackCode)); + + Entrypoint = entrypoint; + + return TRUE; +} -#undef __stdcall // DllMain should be __stdcall always BOOL __stdcall DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved @@ -49,14 +164,7 @@ BOOL __stdcall DllMain(HMODULE hModule, CloseHandle(Info.hThread); } - MODULEINFO moduleInfo; - HMODULE hModule = GetModuleHandleW(NULL); - - GetModuleInformation(GetCurrentProcess(), hModule, &moduleInfo, sizeof(moduleInfo)); - CE_ENTRYPOINT entrypoint = (CE_ENTRYPOINT)moduleInfo.EntryPoint; - - LPCWSTR wstr = L""; - ExitProcess(entrypoint(hModule, NULL, wstr, 0)); + WceclPatchEntrypoint(); break; }; // From 610b3b0acb9193257d59fdc468dc595f68a3c003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Jab=C5=82o=C5=84ski?= Date: Sun, 14 Apr 2024 02:38:50 +0200 Subject: [PATCH 5/9] Move stdio related functions to a separate file --- COREDLL/COREDLL.vcxproj | 1 + COREDLL/COREDLL.vcxproj.filters | 3 ++ COREDLL/Exports.def | 2 +- COREDLL/other.cpp | 68 +-------------------------------- COREDLL/stdio_wcecl.cpp | 53 +++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 68 deletions(-) create mode 100644 COREDLL/stdio_wcecl.cpp diff --git a/COREDLL/COREDLL.vcxproj b/COREDLL/COREDLL.vcxproj index 1bb75cf..0143f94 100644 --- a/COREDLL/COREDLL.vcxproj +++ b/COREDLL/COREDLL.vcxproj @@ -258,6 +258,7 @@ Create Create + diff --git a/COREDLL/COREDLL.vcxproj.filters b/COREDLL/COREDLL.vcxproj.filters index b8a0a98..0b4ec21 100644 --- a/COREDLL/COREDLL.vcxproj.filters +++ b/COREDLL/COREDLL.vcxproj.filters @@ -77,6 +77,9 @@ Source Files + + Source Files + diff --git a/COREDLL/Exports.def b/COREDLL/Exports.def index 5b139af..36295d3 100644 --- a/COREDLL/Exports.def +++ b/COREDLL/Exports.def @@ -31,7 +31,7 @@ EXPORTS _wcsupr @232 vfwprintf=vfwprintf_WCECL @721 fflush @1122 - fgetws=fgetws_WCECL @1143 + fgetws @1143 fputwc @1141 fputws @1144 _getstdfilex=_getstdfilex_WCECL @1100 diff --git a/COREDLL/other.cpp b/COREDLL/other.cpp index 065ddee..973443e 100644 --- a/COREDLL/other.cpp +++ b/COREDLL/other.cpp @@ -194,59 +194,9 @@ void CeLogSetZones(DWORD dwZoneUser, // User-defined zones // wtf!? } -FILE* WINAPI _getstdfilex_WCECL(DWORD type) -{ - switch (type) - { - case 0: - return stdin; - case 1: - return stdout; - case 2: - return stderr; - default: - Assert32(FALSE); - return NULL; - } -} - -BOOL WINAPI SetStdioPathW_WCECL( - DWORD id, - PWSTR pwszPath) -{ - /* TODO: test */ - switch (id) - { - case 0: - return (_wfreopen(pwszPath, L"r", stdin) != NULL); - case 1: - return (_wfreopen(pwszPath, L"w", stdout) != NULL); - case 2: - return (_wfreopen(pwszPath, L"w", stderr) != NULL); - default: - Assert32(FALSE); - return NULL; - } -} - -BOOL WINAPI GetStdioPathW_WCECL( - DWORD id, - PWSTR pwszBuf, - LPDWORD lpdwLen) -{ - /* TODO: test */ - FILE* filePtr = _getstdfilex_WCECL(id); - HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(filePtr)); - if (GetFinalPathNameByHandleW(hFile, pwszBuf, *lpdwLen, 0) < *lpdwLen) - { - return TRUE; - } - - return FALSE; -} - void* _fileno_WCECL(FILE* file) { + /* https://stackoverflow.com/a/3989842 */ return (void*)_get_osfhandle(_fileno(file)); } @@ -271,22 +221,6 @@ int WINAPI WideCharToMultiByte_WCECL( lpUsedDefaultChar); } -wchar_t* fgetws_WCECL(wchar_t* w, int count, FILE* file) -{ - wchar_t* result = fgetws(w, count, file); - if (result == NULL && - file == stdin && count > 2) - { - result = w; - wsprintf(w, L""); - } - else - { - return result; - } - return result; -} - // Stubs Stub(_chkstk_WCECL); Stub(WaitForAPIReady); diff --git a/COREDLL/stdio_wcecl.cpp b/COREDLL/stdio_wcecl.cpp new file mode 100644 index 0000000..05d9fe4 --- /dev/null +++ b/COREDLL/stdio_wcecl.cpp @@ -0,0 +1,53 @@ +#include "stdafx.h" +#include + +FILE* WINAPI _getstdfilex_WCECL(DWORD type) +{ + switch (type) + { + case 0: + return stdin; + case 1: + return stdout; + case 2: + return stderr; + default: + Assert32(FALSE); + return NULL; + } +} + +BOOL WINAPI SetStdioPathW_WCECL( + DWORD id, + PWSTR pwszPath) +{ + /* TODO: test */ + switch (id) + { + case 0: + return (_wfreopen(pwszPath, L"r", stdin) != NULL); + case 1: + return (_wfreopen(pwszPath, L"w", stdout) != NULL); + case 2: + return (_wfreopen(pwszPath, L"w", stderr) != NULL); + default: + Assert32(FALSE); + return NULL; + } +} + +BOOL WINAPI GetStdioPathW_WCECL( + DWORD id, + PWSTR pwszBuf, + LPDWORD lpdwLen) +{ + /* TODO: test */ + FILE* filePtr = _getstdfilex_WCECL(id); + HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(filePtr)); + if (GetFinalPathNameByHandleW(hFile, pwszBuf, *lpdwLen, 0) < *lpdwLen) + { + return TRUE; + } + + return FALSE; +} \ No newline at end of file From 3976a6b9a6e61623c01eac592fbd90ac4c0286a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Jab=C5=82o=C5=84ski?= Date: Sun, 14 Apr 2024 18:43:04 +0200 Subject: [PATCH 6/9] Add instruction cache clearing (probably needed for ARM) --- COREDLL/dllmain.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/COREDLL/dllmain.cpp b/COREDLL/dllmain.cpp index a4a79be..6e26297 100644 --- a/COREDLL/dllmain.cpp +++ b/COREDLL/dllmain.cpp @@ -69,6 +69,7 @@ static void WceclEntrypointWrapper() } memcpy(Entrypoint, EntrypointRepairCode, sizeof(EntrypointRepairCode)); + FlushInstructionCache(GetCurrentProcess(), Entrypoint, sizeof(EntrypointRepairCode)); result = Entrypoint(GetModuleHandleW(NULL), NULL, commandLine, nCmdShow); ExitProcess(result); } @@ -113,7 +114,8 @@ static BOOL WceclPatchEntrypoint() memcpy(EntrypointRepairCode, entrypoint, sizeof(EntrypointRepairCode)); memcpy(entrypoint, EntrypointHijackCode, sizeof(EntrypointHijackCode)); - + FlushInstructionCache(GetCurrentProcess(), entrypoint, sizeof(EntrypointHijackCode)); + Entrypoint = entrypoint; return TRUE; @@ -167,7 +169,6 @@ BOOL __stdcall DllMain(HMODULE hModule, WceclPatchEntrypoint(); break; }; - // case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: From 0d548e26e13cda0c223585c4a2116b55c085f857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Jab=C5=82o=C5=84ski?= Date: Sun, 14 Apr 2024 19:15:54 +0200 Subject: [PATCH 7/9] Add #error for compiling on ARM I do not know ARM assembly, so I can't write the patching code for that. --- COREDLL/dllmain.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/COREDLL/dllmain.cpp b/COREDLL/dllmain.cpp index 6e26297..07f3dc2 100644 --- a/COREDLL/dllmain.cpp +++ b/COREDLL/dllmain.cpp @@ -5,6 +5,7 @@ typedef UINT(__cdecl* CE_ENTRYPOINT)(HINSTANCE, HINSTANCE, LPCWSTR, int); void WceclEntrypointWrapper(); +#ifdef _M_IX86 #pragma pack(push, 1) static struct @@ -14,11 +15,14 @@ static struct BYTE Ret; } EntrypointHijackCode[] = { {0x68, WceclEntrypointWrapper, 0xC3} }; +#pragma pack(pop) +#else +#error No patching code for non x86 architectures +#endif + static BYTE EntrypointRepairCode[sizeof(EntrypointHijackCode)]; CE_ENTRYPOINT Entrypoint; -#pragma pack(pop) - static void WceclEntrypointWrapper() { STARTUPINFOW startupInfo; From 49ff8348ff4fbd9a262b0ca9f1ff912f3ee91457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Jab=C5=82o=C5=84ski?= Date: Sun, 14 Apr 2024 19:23:22 +0200 Subject: [PATCH 8/9] Replace the #error directive with a FIXME comment --- COREDLL/dllmain.cpp | 7 +++++-- COREDLL/other.cpp | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/COREDLL/dllmain.cpp b/COREDLL/dllmain.cpp index 07f3dc2..58365a4 100644 --- a/COREDLL/dllmain.cpp +++ b/COREDLL/dllmain.cpp @@ -17,7 +17,7 @@ static struct EntrypointHijackCode[] = { {0x68, WceclEntrypointWrapper, 0xC3} }; #pragma pack(pop) #else -#error No patching code for non x86 architectures +/* FIXME: No patching code for architectures other than x86. */ #endif static BYTE EntrypointRepairCode[sizeof(EntrypointHijackCode)]; @@ -169,8 +169,11 @@ BOOL __stdcall DllMain(HMODULE hModule, CloseHandle(Info.hProcess); CloseHandle(Info.hThread); } - +#ifdef _M_IX86 WceclPatchEntrypoint(); +#else + /* FIXME: No patching code for architectures other than x86. */ +#endif break; }; case DLL_THREAD_ATTACH: diff --git a/COREDLL/other.cpp b/COREDLL/other.cpp index f330535..768421a 100644 --- a/COREDLL/other.cpp +++ b/COREDLL/other.cpp @@ -202,7 +202,7 @@ void* _fileno_WCECL(FILE* file) return result; } - /* https://stackoverflow.com/a/3989842 */ + /* https://stackoverflow.com/a/3989842 */ return (void*)_get_osfhandle(_fileno(file)); } From 94102ee31b97a3205cd00594d168da5437571380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Jab=C5=82o=C5=84ski?= Date: Sun, 14 Apr 2024 19:31:56 +0200 Subject: [PATCH 9/9] Fix an ARM compile error --- COREDLL/dllmain.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/COREDLL/dllmain.cpp b/COREDLL/dllmain.cpp index 58365a4..e5f381a 100644 --- a/COREDLL/dllmain.cpp +++ b/COREDLL/dllmain.cpp @@ -6,6 +6,10 @@ typedef UINT(__cdecl* CE_ENTRYPOINT)(HINSTANCE, HINSTANCE, LPCWSTR, int); void WceclEntrypointWrapper(); #ifdef _M_IX86 +#else +/* FIXME: No patching code for architectures other than x86. */ +#endif + #pragma pack(push, 1) static struct @@ -16,9 +20,6 @@ static struct } EntrypointHijackCode[] = { {0x68, WceclEntrypointWrapper, 0xC3} }; #pragma pack(pop) -#else -/* FIXME: No patching code for architectures other than x86. */ -#endif static BYTE EntrypointRepairCode[sizeof(EntrypointHijackCode)]; CE_ENTRYPOINT Entrypoint;