All 5 phases of the open-source Decal rebuild: Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil) Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs - DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters - Decal.Core, DecalControls, DecalRender, D3DService Phase 3: C++ shims for Inject.DLL (D3D9 hooking) and LauncherHook.DLL Phase 4: DenAgent WinForms tray application Phase 5: WiX installer and build script 25 C# projects building with 0 errors. Native C++ projects require VS 2022 + Windows SDK (x86). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
96 lines
2.5 KiB
C++
96 lines
2.5 KiB
C++
// LobbyHook.cpp : Defines the entry point for the DLL application.
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "forcelib.h"
|
|
#include "apihook.h"
|
|
|
|
bool bInject;
|
|
BOOL __stdcall Replacement_CreateProcessA( LPCSTR a0, LPSTR a1, LPSECURITY_ATTRIBUTES a2, LPSECURITY_ATTRIBUTES a3, BOOL a4, DWORD a5, LPVOID a6, LPCSTR a7, LPSTARTUPINFO a8, LPPROCESS_INFORMATION a9 );
|
|
|
|
static cHookDescriptor _hooks[] =
|
|
{
|
|
{ eByName, _T( "kernel32.dll" ), _T( "CreateProcessA" ), 93, reinterpret_cast< DWORD >( Replacement_CreateProcessA ), 0 },
|
|
};
|
|
|
|
BOOL __stdcall Replacement_CreateProcessA( LPCSTR a0, LPSTR a1, LPSECURITY_ATTRIBUTES a2, LPSECURITY_ATTRIBUTES a3, BOOL a4, DWORD a5,LPVOID a6, LPCSTR a7, LPSTARTUPINFO a8, LPPROCESS_INFORMATION a9 )
|
|
{
|
|
static long s_recursion = 0;
|
|
bInject = strstr( a1, "client.exe" ) ? true : false;
|
|
|
|
BOOL bResult;
|
|
|
|
if( s_recursion++ == 0 && bInject)
|
|
{
|
|
HKEY key = NULL;
|
|
|
|
char szDllPath[ MAX_PATH ];
|
|
memset( szDllPath, 0, sizeof( szDllPath ) );
|
|
|
|
HRESULT hr = RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Software\\Decal\\Agent"), 0, KEY_READ, &key );
|
|
|
|
if( hr == ERROR_SUCCESS )
|
|
{
|
|
DWORD dwChars = MAX_PATH - 1;
|
|
if( RegQueryValueEx( key, "AgentPath", NULL, NULL, (LPBYTE) szDllPath, &dwChars ) == ERROR_SUCCESS )
|
|
strcat( szDllPath, "\\Inject.dll" );
|
|
|
|
RegCloseKey (key);
|
|
}
|
|
|
|
PROCESS_INFORMATION ProcInfo;
|
|
memset( &ProcInfo, 0, sizeof( PROCESS_INFORMATION ) );
|
|
|
|
bResult = CreateProcess( const_cast< char * >( a0 ),
|
|
a1, a2, a3, a4, CREATE_SUSPENDED, /* a5 - Creation Flags */
|
|
a6, const_cast< char * >( a7 ), a8, &ProcInfo /* a9 - Proc Info */ );
|
|
|
|
if (FindWindow (NULL, "Decal Agent") != NULL)
|
|
{
|
|
ForceLibrary( szDllPath, &ProcInfo );
|
|
}
|
|
|
|
ResumeThread( ProcInfo.hThread );
|
|
}
|
|
else
|
|
{
|
|
bResult = CreateProcess( a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 );
|
|
}
|
|
|
|
s_recursion--;
|
|
|
|
return bResult;
|
|
}
|
|
|
|
HANDLE g_hLobbySemaphore = NULL;
|
|
|
|
BOOL APIENTRY DllMain( HANDLE hModule, DWORD dwCallReason, LPVOID lpReserved )
|
|
{
|
|
switch( dwCallReason )
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
{
|
|
// Alright, we're loaded into the lobby process.
|
|
// Hook CreateProcessA and bail.
|
|
hookFunctionsByExport( "AsheronsCall.dll", _hooks, 1, true );
|
|
|
|
TCHAR tszBuffer [256];
|
|
|
|
_stprintf (tszBuffer, _T("__LOBBYHOOK_%d"), ::GetCurrentProcessId ());
|
|
g_hLobbySemaphore = ::CreateSemaphore (NULL, 0, 1, tszBuffer);
|
|
break;
|
|
}
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
{
|
|
// Detaching
|
|
// Unhook CreateProcessA and bail.
|
|
hookFunctionsByExport( "AsheronsCall.dll", _hooks, 1, false );
|
|
::CloseHandle (g_hLobbySemaphore);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|