2018-08-23 23:53:23 +08: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-11 12:29:12 +08:00
# include "texthook.h"
2019-06-02 14:09:17 +08:00
# include "hookfinder.h"
2019-01-04 06:52:16 +08:00
# include "util.h"
2021-11-07 20:54:34 +08:00
# include "MinHook.h"
2018-08-23 23:53:23 +08:00
2019-02-28 00:33:17 +08: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-17 11:51:10 +08:00
WinMutex viewMutex ;
2018-08-25 00:50:20 +08:00
2018-11-11 13:34:42 +08:00
namespace
{
2018-12-02 04:52:52 +08:00
AutoHandle < > hookPipe = INVALID_HANDLE_VALUE , mappedFile = INVALID_HANDLE_VALUE ;
2019-02-17 11:51:10 +08:00
TextHook ( * hooks ) [ MAX_HOOK ] ;
2018-12-02 04:52:52 +08:00
int currentHook = 0 ;
2018-11-11 13:34:42 +08:00
}
2018-11-11 12:29:12 +08:00
DWORD WINAPI Pipe ( LPVOID )
{
2019-10-04 04:00:19 +08:00
for ( bool running = true ; running ; hookPipe = INVALID_HANDLE_VALUE )
2018-11-11 12:29:12 +08:00
{
DWORD count = 0 ;
BYTE buffer [ PIPE_BUFFER_SIZE ] = { } ;
2018-12-02 04:52:52 +08:00
AutoHandle < > hostPipe = INVALID_HANDLE_VALUE ;
2018-11-11 12:29:12 +08:00
2019-02-17 11:51:10 +08:00
while ( ! hostPipe | | ! hookPipe )
2018-11-11 12:29:12 +08:00
{
2019-02-17 11:51:10 +08: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-11 12:29:12 +08:00
}
2019-02-17 11:51:10 +08:00
DWORD mode = PIPE_READMODE_MESSAGE ;
SetNamedPipeHandleState ( hostPipe , & mode , NULL , NULL ) ;
2018-11-11 12:29:12 +08:00
* ( DWORD * ) buffer = GetCurrentProcessId ( ) ;
WriteFile ( hookPipe , buffer , sizeof ( DWORD ) , & count , nullptr ) ;
2018-11-11 13:34:42 +08:00
ConsoleOutput ( PIPE_CONNECTED ) ;
2018-11-11 12:29:12 +08: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 13:49:11 +08: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-11 03:06:43 +08:00
RemoveHook ( info . address , 0 ) ;
2018-11-11 12:29:12 +08:00
}
break ;
2019-06-02 14:09:17 +08:00
case HOST_COMMAND_FIND_HOOK :
{
auto info = * ( FindHookCmd * ) buffer ;
2019-08-20 04:15:08 +08:00
if ( * info . sp . text ) SearchForText ( info . sp . text , info . sp . codepage ) ;
else SearchForHooks ( info . sp ) ;
2019-06-02 14:09:17 +08:00
}
break ;
2018-11-11 12:29:12 +08:00
case HOST_COMMAND_DETACH :
{
running = false ;
}
break ;
}
}
2019-10-04 04:00:19 +08:00
MH_Uninitialize ( ) ;
for ( auto & hook : * hooks ) hook . Clear ( ) ;
2018-11-11 12:29:12 +08:00
FreeLibraryAndExitThread ( GetModuleHandleW ( ITH_DLL ) , 0 ) ;
}
2020-03-24 09:37:11 +08:00
void TextOutput ( ThreadParam tp , BYTE ( * buffer ) [ PIPE_BUFFER_SIZE ] , int len )
2018-11-11 12:29:12 +08:00
{
2020-03-24 09:37:11 +08: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-11 12:29:12 +08:00
* ( ThreadParam * ) buffer = tp ;
2019-06-04 05:58:30 +08:00
WriteFile ( hookPipe , buffer , sizeof ( tp ) + len , DUMMY , nullptr ) ;
2018-11-11 12:29:12 +08:00
}
2018-12-02 04:52:52 +08:00
void ConsoleOutput ( LPCSTR text , . . . )
2018-11-11 12:29:12 +08:00
{
2018-12-02 04:52:52 +08:00
ConsoleOutputNotif buffer ;
va_list args ;
va_start ( args , text ) ;
2019-06-02 14:09:17 +08:00
vsnprintf ( buffer . message , MESSAGE_SIZE , text , args ) ;
2019-06-04 05:58:30 +08:00
WriteFile ( hookPipe , & buffer , sizeof ( buffer ) , DUMMY , nullptr ) ;
2019-06-02 14:09:17 +08:00
}
2019-06-09 12:48:30 +08:00
void NotifyHookFound ( HookParam hp , wchar_t * text )
2019-06-02 14:09:17 +08:00
{
HookFoundNotif buffer ( hp , text ) ;
2019-06-04 05:58:30 +08:00
WriteFile ( hookPipe , & buffer , sizeof ( buffer ) , DUMMY , nullptr ) ;
2018-11-11 12:29:12 +08:00
}
2019-02-28 00:33:17 +08:00
void NotifyHookRemove ( uint64_t addr , LPCSTR name )
2018-11-11 12:29:12 +08:00
{
2019-02-28 00:33:17 +08:00
if ( name ) ConsoleOutput ( REMOVING_HOOK , name ) ;
2018-11-11 12:29:12 +08:00
HookRemovedNotif buffer ( addr ) ;
2019-06-04 05:58:30 +08:00
WriteFile ( hookPipe , & buffer , sizeof ( buffer ) , DUMMY , nullptr ) ;
2018-11-11 12:29:12 +08:00
}
2018-09-21 10:42:15 +08:00
BOOL WINAPI DllMain ( HINSTANCE hModule , DWORD fdwReason , LPVOID )
2018-08-23 23:53:23 +08:00
{
switch ( fdwReason )
{
case DLL_PROCESS_ATTACH :
{
2019-02-17 11:51:10 +08:00
viewMutex = WinMutex ( ITH_HOOKMAN_MUTEX_ + std : : to_wstring ( GetCurrentProcessId ( ) ) , & allAccess ) ;
2018-08-23 23:53:23 +08:00
if ( GetLastError ( ) = = ERROR_ALREADY_EXISTS ) return FALSE ;
DisableThreadLibraryCalls ( hModule ) ;
// jichi 9/25/2013: Interprocedural communication with vnrsrv.
2019-02-17 11:51:10 +08: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-11 12:29:12 +08:00
memset ( hooks , 0 , HOOK_BUFFER_SIZE ) ;
2018-08-23 23:53:23 +08:00
2018-08-26 03:45:25 +08:00
MH_Initialize ( ) ;
2018-08-23 23:53:23 +08:00
2019-02-17 11:51:10 +08:00
CloseHandle ( CreateThread ( nullptr , 0 , Pipe , nullptr , 0 , nullptr ) ) ; // Using std::thread here = deadlock
2018-08-23 23:53:23 +08:00
}
break ;
case DLL_PROCESS_DETACH :
{
2018-11-11 13:34:42 +08:00
MH_Uninitialize ( ) ;
2019-10-04 04:00:19 +08:00
UnmapViewOfFile ( hooks ) ;
2018-08-23 23:53:23 +08:00
}
break ;
}
return TRUE ;
}
2018-11-11 12:29:12 +08:00
void NewHook ( HookParam hp , LPCSTR lpname , DWORD flag )
2018-08-23 23:53:23 +08:00
{
2019-08-20 04:15:08 +08: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-04 06:52:16 +08:00
{
2019-08-20 04:15:08 +08:00
ConsoleOutput ( HOOK_FAILED ) ;
( * hooks ) [ currentHook ] . Clear ( ) ;
2019-01-04 06:52:16 +08:00
}
2018-08-23 23:53:23 +08:00
}
2018-08-26 03:45:25 +08:00
2019-06-11 03:06:43 +08:00
void RemoveHook ( uint64_t addr , int maxOffset )
2018-08-23 23:53:23 +08:00
{
2019-06-11 03:06:43 +08:00
for ( auto & hook : * hooks ) if ( abs ( ( long long ) ( hook . address - addr ) ) < = maxOffset ) return hook . Clear ( ) ;
2018-08-23 23:53:23 +08:00
}
2018-12-21 23:10:51 +08:00
// EOF