diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e9962a..170f78a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,10 @@ cmake_minimum_required(VERSION 3.13) + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug" CACHE STRING + "Build type options: Debug Release RelWithDebInfo MinSizeRel" FORCE) +endif () + project(wibo LANGUAGES CXX) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") @@ -6,7 +12,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") find_package(Filesystem REQUIRED) set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -Wall -g") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -Wall") include_directories(.) add_executable(wibo dll/advapi32.cpp diff --git a/Dockerfile b/Dockerfile index 54943b1..d1c1dab 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,8 +8,7 @@ RUN apk add --no-cache cmake ninja g++ linux-headers binutils COPY . /wibo # Build static binary -# Replace with RelWithDebInfo when -O2 crash is fixed -RUN cmake -S /wibo -B /wibo/build -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-static" \ +RUN cmake -S /wibo -B /wibo/build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-static" \ && cmake --build /wibo/build \ && strip -g /wibo/build/wibo diff --git a/common.h b/common.h index a73e3e6..5c2cda5 100644 --- a/common.h +++ b/common.h @@ -6,7 +6,10 @@ #include #include -#define WIN_FUNC __attribute__((stdcall)) +// On Windows, the incoming stack is aligned to a 4 byte boundary. +// force_align_arg_pointer will realign the stack to match GCC's 16 byte alignment. +#define WIN_ENTRY __attribute__((force_align_arg_pointer)) +#define WIN_FUNC WIN_ENTRY __attribute__((stdcall)) #define DEBUG_LOG(...) wibo::debug_log(__VA_ARGS__) namespace user32 { diff --git a/dll/kernel32.cpp b/dll/kernel32.cpp index 83fff2f..658644c 100644 --- a/dll/kernel32.cpp +++ b/dll/kernel32.cpp @@ -933,17 +933,45 @@ namespace kernel32 { } unsigned int WIN_FUNC GetSystemDirectoryA(char *lpBuffer, unsigned int uSize) { - strcpy(lpBuffer, "C:\\Windows\\System32"); - return strlen(lpBuffer); + DEBUG_LOG("GetSystemDirectoryA(%p, %u)\n", lpBuffer, uSize); + if (lpBuffer == nullptr) { + return 0; + } + + const char* systemDir = "C:\\Windows\\System32"; + const auto len = strlen(systemDir); + + // If the buffer is too small, return the required buffer size. + // (Add 1 to include the NUL terminator) + if (uSize < len + 1) { + return len + 1; + } + + strcpy(lpBuffer, systemDir); + return len; } unsigned int WIN_FUNC GetWindowsDirectoryA(char *lpBuffer, unsigned int uSize) { - strcpy(lpBuffer, "C:\\Windows"); - return strlen(lpBuffer); + DEBUG_LOG("GetWindowsDirectoryA(%p, %u)\n", lpBuffer, uSize); + if (lpBuffer == nullptr) { + return 0; + } + + const char* systemDir = "C:\\Windows"; + const auto len = strlen(systemDir); + + // If the buffer is too small, return the required buffer size. + // (Add 1 to include the NUL terminator) + if (uSize < len + 1) { + return len + 1; + } + + strcpy(lpBuffer, systemDir); + return len; } unsigned int WIN_FUNC GetCurrentDirectoryA(unsigned int uSize, char *lpBuffer) { - DEBUG_LOG("GetCurrentDirectoryA\n"); + DEBUG_LOG("GetCurrentDirectoryA(%u, %p)\n", uSize, lpBuffer); std::filesystem::path cwd = std::filesystem::current_path(); std::string path = files::pathToWindows(cwd); diff --git a/dll/lmgr.cpp b/dll/lmgr.cpp index 866f4de..9a65919 100644 --- a/dll/lmgr.cpp +++ b/dll/lmgr.cpp @@ -1,13 +1,13 @@ #include "common.h" namespace lmgr { - int lp_checkout(int a, int b, const char* c, const char* d, int e, const char* f, int* out) { + int WIN_ENTRY lp_checkout(int a, int b, const char* c, const char* d, int e, const char* f, int* out) { DEBUG_LOG("lp_checkout %d %d %s %s %d %s\n", a, b, c, d, e, f); *out = 1234; return 0; } - int lp_checkin() { + int WIN_ENTRY lp_checkin() { DEBUG_LOG("lp_checkin\n"); return 0; }