2018-08-23 11:53:23 -04:00
// main.cc
// 8/24/2013 jichi
// Branch: ITH_DLL/main.cpp, rev 128
// 8/24/2013 TODO: Clean up this file
# include "main.h"
# include "defs.h"
# include "engine/match.h"
2018-11-10 23:29:12 -05:00
# include "texthook.h"
2019-06-02 02:09:17 -04:00
# include "hookfinder.h"
2019-01-03 17:52:16 -05:00
# include "util.h"
2021-11-07 05:54:34 -07:00
# include "MinHook.h"
2018-08-23 11:53:23 -04:00
2019-02-27 11:33:17 -05:00
extern const char * PIPE_CONNECTED ;
extern const char * INSERTING_HOOK ;
extern const char * REMOVING_HOOK ;
extern const char * HOOK_FAILED ;
extern const char * TOO_MANY_HOOKS ;
2019-02-16 22:51:10 -05:00
WinMutex viewMutex ;
2018-08-24 12:50:20 -04:00
2018-11-11 00:34:42 -05:00
namespace
{
2018-12-01 15:52:52 -05:00
AutoHandle < > hookPipe = INVALID_HANDLE_VALUE , mappedFile = INVALID_HANDLE_VALUE ;
2019-02-16 22:51:10 -05:00
TextHook ( * hooks ) [ MAX_HOOK ] ;
2018-12-01 15:52:52 -05:00
int currentHook = 0 ;
2018-11-11 00:34:42 -05:00
}
2018-11-10 23:29:12 -05:00
DWORD WINAPI Pipe ( LPVOID )
{
2019-10-03 16:00:19 -04:00
for ( bool running = true ; running ; hookPipe = INVALID_HANDLE_VALUE )
2018-11-10 23:29:12 -05:00
{
DWORD count = 0 ;
BYTE buffer [ PIPE_BUFFER_SIZE ] = { } ;
2018-12-01 15:52:52 -05:00
AutoHandle < > hostPipe = INVALID_HANDLE_VALUE ;
2018-11-10 23:29:12 -05:00
2019-02-16 22:51:10 -05:00
while ( ! hostPipe | | ! hookPipe )
2018-11-10 23:29:12 -05:00
{
2019-02-16 22:51:10 -05:00
WinMutex connectionMutex ( CONNECTING_MUTEX , & allAccess ) ;
std : : scoped_lock lock ( connectionMutex ) ;
WaitForSingleObject ( AutoHandle < > ( CreateEventW ( & allAccess , FALSE , FALSE , PIPE_AVAILABLE_EVENT ) ) , INFINITE ) ;
hostPipe = CreateFileW ( HOST_PIPE , GENERIC_READ | FILE_WRITE_ATTRIBUTES , FILE_SHARE_READ , nullptr , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , nullptr ) ;
hookPipe = CreateFileW ( HOOK_PIPE , GENERIC_WRITE , FILE_SHARE_READ , nullptr , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , nullptr ) ;
2018-11-10 23:29:12 -05:00
}
2019-02-16 22:51:10 -05:00
DWORD mode = PIPE_READMODE_MESSAGE ;
SetNamedPipeHandleState ( hostPipe , & mode , NULL , NULL ) ;
2018-11-10 23:29:12 -05:00
* ( DWORD * ) buffer = GetCurrentProcessId ( ) ;
WriteFile ( hookPipe , buffer , sizeof ( DWORD ) , & count , nullptr ) ;
2018-11-11 00:34:42 -05:00
ConsoleOutput ( PIPE_CONNECTED ) ;
2018-11-10 23:29:12 -05:00
Engine : : Hijack ( ) ;
while ( running & & ReadFile ( hostPipe , buffer , PIPE_BUFFER_SIZE , & count , nullptr ) )
switch ( * ( HostCommandType * ) buffer )
{
case HOST_COMMAND_NEW_HOOK :
{
auto info = * ( InsertHookCmd * ) buffer ;
2019-06-10 01:49:11 -04:00
static int userHooks = 0 ;
NewHook ( info . hp , ( " UserHook " + std : : to_string ( userHooks + = 1 ) ) . c_str ( ) , 0 ) ;
}
break ;
case HOST_COMMAND_REMOVE_HOOK :
{
auto info = * ( RemoveHookCmd * ) buffer ;
2019-06-10 15:06:43 -04:00
RemoveHook ( info . address , 0 ) ;
2018-11-10 23:29:12 -05:00
}
break ;
2019-06-02 02:09:17 -04:00
case HOST_COMMAND_FIND_HOOK :
{
auto info = * ( FindHookCmd * ) buffer ;
2019-08-19 16:15:08 -04:00
if ( * info . sp . text ) SearchForText ( info . sp . text , info . sp . codepage ) ;
else SearchForHooks ( info . sp ) ;
2019-06-02 02:09:17 -04:00
}
break ;
2018-11-10 23:29:12 -05:00
case HOST_COMMAND_DETACH :
{
running = false ;
}
break ;
}
}
2019-10-03 16:00:19 -04:00
MH_Uninitialize ( ) ;
for ( auto & hook : * hooks ) hook . Clear ( ) ;
2018-11-10 23:29:12 -05:00
FreeLibraryAndExitThread ( GetModuleHandleW ( ITH_DLL ) , 0 ) ;
}
2020-03-23 19:37:11 -06:00
void TextOutput ( ThreadParam tp , BYTE ( * buffer ) [ PIPE_BUFFER_SIZE ] , int len )
2018-11-10 23:29:12 -05:00
{
2020-03-23 19:37:11 -06:00
if ( len < 0 | | len > PIPE_BUFFER_SIZE - sizeof ( tp ) ) ConsoleOutput ( " Textractor: something went very wrong (invalid length %d at hook address %I64d) " , len , tp . addr ) ;
2018-11-10 23:29:12 -05:00
* ( ThreadParam * ) buffer = tp ;
2019-06-03 17:58:30 -04:00
WriteFile ( hookPipe , buffer , sizeof ( tp ) + len , DUMMY , nullptr ) ;
2018-11-10 23:29:12 -05:00
}
2018-12-01 15:52:52 -05:00
void ConsoleOutput ( LPCSTR text , . . . )
2018-11-10 23:29:12 -05:00
{
2018-12-01 15:52:52 -05:00
ConsoleOutputNotif buffer ;
va_list args ;
va_start ( args , text ) ;
2019-06-02 02:09:17 -04:00
vsnprintf ( buffer . message , MESSAGE_SIZE , text , args ) ;
2019-06-03 17:58:30 -04:00
WriteFile ( hookPipe , & buffer , sizeof ( buffer ) , DUMMY , nullptr ) ;
2019-06-02 02:09:17 -04:00
}
2019-06-09 00:48:30 -04:00
void NotifyHookFound ( HookParam hp , wchar_t * text )
2019-06-02 02:09:17 -04:00
{
HookFoundNotif buffer ( hp , text ) ;
2019-06-03 17:58:30 -04:00
WriteFile ( hookPipe , & buffer , sizeof ( buffer ) , DUMMY , nullptr ) ;
2018-11-10 23:29:12 -05:00
}
2019-02-27 11:33:17 -05:00
void NotifyHookRemove ( uint64_t addr , LPCSTR name )
2018-11-10 23:29:12 -05:00
{
2019-02-27 11:33:17 -05:00
if ( name ) ConsoleOutput ( REMOVING_HOOK , name ) ;
2018-11-10 23:29:12 -05:00
HookRemovedNotif buffer ( addr ) ;
2019-06-03 17:58:30 -04:00
WriteFile ( hookPipe , & buffer , sizeof ( buffer ) , DUMMY , nullptr ) ;
2018-11-10 23:29:12 -05:00
}
2018-09-20 22:42:15 -04:00
BOOL WINAPI DllMain ( HINSTANCE hModule , DWORD fdwReason , LPVOID )
2018-08-23 11:53:23 -04:00
{
switch ( fdwReason )
{
case DLL_PROCESS_ATTACH :
{
2019-02-16 22:51:10 -05:00
viewMutex = WinMutex ( ITH_HOOKMAN_MUTEX_ + std : : to_wstring ( GetCurrentProcessId ( ) ) , & allAccess ) ;
2018-08-23 11:53:23 -04:00
if ( GetLastError ( ) = = ERROR_ALREADY_EXISTS ) return FALSE ;
DisableThreadLibraryCalls ( hModule ) ;
// jichi 9/25/2013: Interprocedural communication with vnrsrv.
2019-02-16 22:51:10 -05:00
mappedFile = CreateFileMappingW ( INVALID_HANDLE_VALUE , & allAccess , PAGE_EXECUTE_READWRITE , 0 , HOOK_SECTION_SIZE , ( ITH_SECTION_ + std : : to_wstring ( GetCurrentProcessId ( ) ) ) . c_str ( ) ) ;
hooks = ( TextHook ( * ) [ MAX_HOOK ] ) MapViewOfFile ( mappedFile , FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE , 0 , 0 , HOOK_BUFFER_SIZE ) ;
2018-11-10 23:29:12 -05:00
memset ( hooks , 0 , HOOK_BUFFER_SIZE ) ;
2018-08-23 11:53:23 -04:00
2018-08-25 15:45:25 -04:00
MH_Initialize ( ) ;
2018-08-23 11:53:23 -04:00
2019-02-16 22:51:10 -05:00
CloseHandle ( CreateThread ( nullptr , 0 , Pipe , nullptr , 0 , nullptr ) ) ; // Using std::thread here = deadlock
2018-08-23 11:53:23 -04:00
}
break ;
case DLL_PROCESS_DETACH :
{
2018-11-11 00:34:42 -05:00
MH_Uninitialize ( ) ;
2019-10-03 16:00:19 -04:00
UnmapViewOfFile ( hooks ) ;
2018-08-23 11:53:23 -04:00
}
break ;
}
return TRUE ;
}
2018-11-10 23:29:12 -05:00
void NewHook ( HookParam hp , LPCSTR lpname , DWORD flag )
2018-08-23 11:53:23 -04:00
{
2019-08-19 16:15:08 -04:00
if ( + + currentHook > = MAX_HOOK ) return ConsoleOutput ( TOO_MANY_HOOKS ) ;
if ( lpname & & * lpname ) strncpy_s ( hp . name , lpname , HOOK_NAME_SIZE - 1 ) ;
ConsoleOutput ( INSERTING_HOOK , hp . name ) ;
RemoveHook ( hp . address , 0 ) ;
if ( ! ( * hooks ) [ currentHook ] . Insert ( hp , flag ) )
2019-01-03 17:52:16 -05:00
{
2019-08-19 16:15:08 -04:00
ConsoleOutput ( HOOK_FAILED ) ;
( * hooks ) [ currentHook ] . Clear ( ) ;
2019-01-03 17:52:16 -05:00
}
2018-08-23 11:53:23 -04:00
}
2018-08-25 15:45:25 -04:00
2019-06-10 15:06:43 -04:00
void RemoveHook ( uint64_t addr , int maxOffset )
2018-08-23 11:53:23 -04:00
{
2019-06-10 15:06:43 -04:00
for ( auto & hook : * hooks ) if ( abs ( ( long long ) ( hook . address - addr ) ) < = maxOffset ) return hook . Clear ( ) ;
2018-08-23 11:53:23 -04:00
}
2018-12-21 10:10:51 -05:00
// EOF