diff --git a/wrappers/CMakeLists.txt b/wrappers/CMakeLists.txt index 5558c74..394c68b 100644 --- a/wrappers/CMakeLists.txt +++ b/wrappers/CMakeLists.txt @@ -1,30 +1,57 @@ cmake_minimum_required(VERSION 3.13) -project(corkel32 C) +project(corkel32 C ASM_MASM) -set(CMAKE_BUILD_TYPE Release) +add_compile_definitions(_WIN32_WINNT=0x0400) -add_library(corkdebug OBJECT +add_library( + corkdebug OBJECT debug.c ) -link_libraries(corkdebug) +target_compile_definitions(corkdebug PRIVATE _CRT_SECURE_NO_WARNINGS=1) + +add_library( + detect486 OBJECT + detect486.asm +) + +add_library( + cas OBJECT + cas.asm +) + +include(CheckSymbolExists) +check_symbol_exists(RtlUnwind Windows.h HAS_RTL_UNWIND) # KERNEL32 => CORKEL32 -add_library(corkel32 SHARED +add_library( + corkel32 MODULE kernel32.c advapi32.c comdlg32.c corkel32.def ) +target_link_libraries(corkel32 PRIVATE corkdebug detect486 cas) +target_compile_definitions(corkel32 PRIVATE _CRT_SECURE_NO_WARNINGS=1) +if(HAS_RTL_UNWIND) + target_compile_definitions(corkel32 PRIVATE HAS_RTL_UNWIND=1) +endif() # NTDLL => CORNT -add_library(cornt SHARED +add_library( + cornt MODULE ntdll.c cornt.def ) +target_link_libraries(cornt PRIVATE corkdebug) +if(HAS_RTL_UNWIND) + target_compile_definitions(cornt PRIVATE HAS_RTL_UNWIND=1) +endif() # USER32 => CORUSR -add_library(corusr SHARED +add_library( + corusr MODULE user32.c corusr.def ) +target_link_libraries(corusr PRIVATE corkdebug) diff --git a/wrappers/advapi32.c b/wrappers/advapi32.c index 7384728..01f606a 100644 --- a/wrappers/advapi32.c +++ b/wrappers/advapi32.c @@ -1,4 +1,3 @@ -#define _WIN32_WINNT 0x0400 #include #include "debug.h" diff --git a/wrappers/cas.asm b/wrappers/cas.asm new file mode 100644 index 0000000..6e95593 --- /dev/null +++ b/wrappers/cas.asm @@ -0,0 +1,17 @@ +.486 +.MODEL FLAT + +.CODE + +OPTION PROLOGUE:NONE +OPTION EPILOGUE:NONE + +_InterlockedCompareExchange_486@12 PROC + mov ecx, DWORD PTR [esp + 4] ; dest + mov edx, DWORD PTR [esp + 8] ; exchange + mov eax, DWORD PTR [esp + 12] ; compare + lock cmpxchg DWORD PTR [ecx], edx + ret 12 +_InterlockedCompareExchange_486@12 ENDP + +END diff --git a/wrappers/cas.h b/wrappers/cas.h new file mode 100644 index 0000000..c2a0ef3 --- /dev/null +++ b/wrappers/cas.h @@ -0,0 +1,10 @@ +#ifndef CAS +#define CAS + +#ifndef STDCALL +#define STDCALL __stdcall +#endif + +long STDCALL InterlockedCompareExchange_486(long* dest, long exchange, long compare); + +#endif // CAS diff --git a/wrappers/comdlg32.c b/wrappers/comdlg32.c index f466caf..1294304 100644 --- a/wrappers/comdlg32.c +++ b/wrappers/comdlg32.c @@ -1,4 +1,3 @@ -#define _WIN32_WINNT 0x0400 #include #include "debug.h" diff --git a/wrappers/detect486.asm b/wrappers/detect486.asm new file mode 100644 index 0000000..dbd4686 --- /dev/null +++ b/wrappers/detect486.asm @@ -0,0 +1,28 @@ +.386 +.MODEL FLAT, STDCALL + +.CODE + +is_cpu_486_or_newer PROC + pushfd + pop eax + mov ebx, eax + xor eax, 40000h ; toggle the AC bit in EFLAGS (only available in 486 or newer) + push eax + popfd + pushfd + pop eax + cmp eax, ebx + jz is_386 + push ebx + popfd + xor eax, eax + inc eax + ret + +is_386: + xor eax, eax + ret +is_cpu_486_or_newer ENDP + +END diff --git a/wrappers/detect486.h b/wrappers/detect486.h new file mode 100644 index 0000000..2670d23 --- /dev/null +++ b/wrappers/detect486.h @@ -0,0 +1,10 @@ +#ifndef DETECT_486 +#define DETECT_486 + +#ifndef STDCALL +#define STDCALL __stdcall +#endif + +int STDCALL is_cpu_486_or_newer(void); + +#endif // DETECT_486 diff --git a/wrappers/kernel32.c b/wrappers/kernel32.c index aa5d734..bd8ea95 100644 --- a/wrappers/kernel32.c +++ b/wrappers/kernel32.c @@ -1,9 +1,11 @@ -#define _WIN32_WINNT 0x0400 - #include #include +#include "cas.h" #include "debug.h" +#include "detect486.h" + +static int has_cmpxchg = 0; typedef struct _FILE_NETWORK_OPEN_INFORMATION { LARGE_INTEGER CreationTime; @@ -848,8 +850,11 @@ BOOL WINAPI CORKEL32_FlushFileBuffers(HANDLE param_0) return FlushFileBuffers(param_0); } +#ifndef HAS_RTL_UNWIND // RtlUnwind is in KERNEL32 but has no header, so we must define it here extern NTAPI RtlUnwind(void* param_0, void* param_1, struct _EXCEPTION_RECORD* param_2, void* param_3); +#endif + void NTAPI CORKEL32_RtlUnwind(void* param_0, void* param_1, struct _EXCEPTION_RECORD* param_2, void* param_3) { Trace(TRACE_PASSTHROUGH, "RtlUnwind"); @@ -1775,10 +1780,14 @@ BOOL WINAPI CORKEL32_GetConsoleScreenBufferInfo(HANDLE hConsoleOutput, PCONSOLE_ } // Reimplemented -LONG WINAPI CORKEL32_InterlockedCompareExchange(LONG *dest, LONG xchg, LONG compare) +LONG WINAPI CORKEL32_InterlockedCompareExchange(LONG* dest, LONG xchg, LONG compare) { - LONG temp = *dest; + LONG temp; + if (has_cmpxchg) { + return InterlockedCompareExchange_486(dest, xchg, compare); + } + temp = *dest; Trace(TRACE_FORCE_DONT_PRINT, "InterlockedCompareExchange"); if (compare == *dest) { @@ -1924,3 +1933,12 @@ BOOL WINAPI CORKEL32_InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION cr return TRUE; } + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + if (fdwReason == DLL_PROCESS_ATTACH) { + has_cmpxchg = is_cpu_486_or_newer(); + } + + return TRUE; +} diff --git a/wrappers/ntdll.c b/wrappers/ntdll.c index f0486ae..5eca877 100644 --- a/wrappers/ntdll.c +++ b/wrappers/ntdll.c @@ -1,16 +1,18 @@ -#define _WIN32_WINNT 0x0400 #include #include "debug.h" -ULONG WINAPI CORNT_RtlNtStatusToDosError(NTSTATUS) +ULONG WINAPI CORNT_RtlNtStatusToDosError(NTSTATUS param_0) { Trace(TRACE_UNIMPLEMENTED, "RtlNtStatusToDosError"); // TODO: Stub return 0; } +#ifndef HAS_RTL_UNWIND extern NTAPI RtlUnwind(void* param_0, void* param_1, struct _EXCEPTION_RECORD* param_2, void* param_3); +#endif + VOID NTAPI CORNT_RtlUnwind(void *p0,void *p1,struct _EXCEPTION_RECORD *p2, void *p3) { Trace(TRACE_PASSTHROUGH, "RtlUnwind"); diff --git a/wrappers/user32.c b/wrappers/user32.c index 9dda09d..55badee 100644 --- a/wrappers/user32.c +++ b/wrappers/user32.c @@ -1,4 +1,3 @@ -#define _WIN32_WINNT 0x0400 #include #include "debug.h"