forked from Public-Mirror/Textractor
refactor
This commit is contained in:
parent
290ef57490
commit
05fa52f589
@ -26,55 +26,7 @@ namespace { // unnamed
|
|||||||
//enum { MAX_ENTRY = 0x40 };
|
//enum { MAX_ENTRY = 0x40 };
|
||||||
|
|
||||||
#define HM_LOCK win_mutex_lock<HookManager::mutex_type> d_locker(hmcs) // Synchronized scope for accessing private data
|
#define HM_LOCK win_mutex_lock<HookManager::mutex_type> d_locker(hmcs) // Synchronized scope for accessing private data
|
||||||
// jichi 9/23/2013: wine deficenciy on mapping sections
|
|
||||||
// Whe set to false, do not map sections.
|
|
||||||
//bool ith_has_section = true;
|
|
||||||
|
|
||||||
// jichi 9/28/2013: Remove ConsoleOutput from available hooks
|
|
||||||
//LPWSTR HookNameInitTable[]={ L"ConsoleOutput" , HOOK_FUN_NAME_LIST };
|
|
||||||
//LPCWSTR HookNameInitTable[] = {HOOK_FUN_NAME_LIST};
|
|
||||||
//LPVOID DefaultHookAddr[HOOK_FUN_COUNT];
|
|
||||||
|
|
||||||
//BYTE null_buffer[4]={0,0,0,0};
|
|
||||||
//BYTE static_small_buffer[0x100];
|
|
||||||
//DWORD zeros[4]={0,0,0,0};
|
|
||||||
//WCHAR user_entry[0x40];
|
|
||||||
|
|
||||||
bool GetProcessPath(HANDLE hProc, __out LPWSTR path)
|
|
||||||
{
|
|
||||||
PROCESS_BASIC_INFORMATION info;
|
|
||||||
LDR_DATA_TABLE_ENTRY entry;
|
|
||||||
PEB_LDR_DATA ldr;
|
|
||||||
PEB peb;
|
|
||||||
if (NT_SUCCESS(NtQueryInformationProcess(hProc, ProcessBasicInformation, &info, sizeof(info), 0)))
|
|
||||||
if (info.PebBaseAddress)
|
|
||||||
if (NT_SUCCESS(NtReadVirtualMemory(hProc, info.PebBaseAddress, &peb,sizeof(peb), 0)))
|
|
||||||
if (NT_SUCCESS(NtReadVirtualMemory(hProc, peb.Ldr, &ldr, sizeof(ldr), 0)))
|
|
||||||
if (NT_SUCCESS(NtReadVirtualMemory(hProc, (LPVOID)ldr.InLoadOrderModuleList.Flink,
|
|
||||||
&entry, sizeof(LDR_DATA_TABLE_ENTRY), 0)))
|
|
||||||
if (NT_SUCCESS(NtReadVirtualMemory(hProc, entry.FullDllName.Buffer,
|
|
||||||
path, MAX_PATH * 2, 0)))
|
|
||||||
return true;
|
|
||||||
path = L"";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetProcessPath(DWORD pid, __out LPWSTR path)
|
|
||||||
{
|
|
||||||
CLIENT_ID id;
|
|
||||||
OBJECT_ATTRIBUTES oa = {};
|
|
||||||
HANDLE hProc;
|
|
||||||
id.UniqueProcess = pid;
|
|
||||||
id.UniqueThread = 0;
|
|
||||||
oa.uLength = sizeof(oa);
|
|
||||||
if (NT_SUCCESS(NtOpenProcess(&hProc , PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, &oa, &id))) {
|
|
||||||
bool flag = GetProcessPath(hProc, path);
|
|
||||||
NtClose(hProc);
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
path = L"";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
@ -141,39 +93,6 @@ DWORD GetHookName(LPSTR str, DWORD pid, DWORD hook_addr, DWORD max)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7/2/2015 jichi: This function is not used and removed
|
|
||||||
//int GetHookNameByIndex(LPSTR str, DWORD pid, DWORD index)
|
|
||||||
//{
|
|
||||||
// if (!pid)
|
|
||||||
// return 0;
|
|
||||||
//
|
|
||||||
// //if (pid == 0) {
|
|
||||||
// // wcscpy(str, HookNameInitTable[0]);
|
|
||||||
// // return wcslen(HookNameInitTable[0]);
|
|
||||||
// //}
|
|
||||||
// DWORD len = 0;
|
|
||||||
// //::man->LockProcessHookman(pid);
|
|
||||||
// ProcessRecord *pr = ::man->GetProcessRecord(pid);
|
|
||||||
// if (!pr)
|
|
||||||
// return 0;
|
|
||||||
// //NtWaitForSingleObject(pr->hookman_mutex,0,0); //already locked
|
|
||||||
// Hook *hks = (Hook *)pr->hookman_map;
|
|
||||||
// if (hks[index].Address()) {
|
|
||||||
// NtReadVirtualMemory(pr->process_handle, hks[index].Name(), str, hks[index].NameLength() << 1, &len);
|
|
||||||
// len = hks[index].NameLength();
|
|
||||||
// }
|
|
||||||
// //NtReleaseMutant(pr->hookman_mutex,0);
|
|
||||||
// return len;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//int GetHookString(LPWSTR str, DWORD pid, DWORD hook_addr, DWORD status)
|
|
||||||
//{
|
|
||||||
// LPWSTR begin=str;
|
|
||||||
// str+=swprintf(str,L"%4d:0x%08X:",pid,hook_addr);
|
|
||||||
// str+=GetHookName(str,pid,hook_addr);
|
|
||||||
// return str-begin;
|
|
||||||
//}
|
|
||||||
|
|
||||||
void ThreadTable::SetThread(DWORD num, TextThread *ptr)
|
void ThreadTable::SetThread(DWORD num, TextThread *ptr)
|
||||||
{
|
{
|
||||||
int number = num;
|
int number = num;
|
||||||
@ -220,26 +139,7 @@ static const char sse_table_eq[0x100]={
|
|||||||
-1,1,-1,1, -1,1,-1,1, -1,1,-1,1, -1,1,-1,1, //0, compare 1
|
-1,1,-1,1, -1,1,-1,1, -1,1,-1,1, -1,1,-1,1, //0, compare 1
|
||||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 //f, equal
|
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 //f, equal
|
||||||
};
|
};
|
||||||
char original_cmp(const ThreadParameter *t1, const ThreadParameter *t2)
|
|
||||||
{
|
|
||||||
//Q_ASSERT(t1 && t2);
|
|
||||||
int t = t1->pid - t2->pid;
|
|
||||||
if (t == 0) {
|
|
||||||
t = t1->hook - t2->hook;
|
|
||||||
if (t == 0) {
|
|
||||||
t = t1->retn - t2->retn;
|
|
||||||
if (t == 0) {
|
|
||||||
t = t1->spl-t2->spl;
|
|
||||||
if (t == 0) return 0;
|
|
||||||
return t1->spl > t2->spl ? 1 : -1;
|
|
||||||
}
|
|
||||||
else return t1->retn > t2->retn ? 1 : -1;
|
|
||||||
}
|
|
||||||
else return t1->hook > t2->hook ? 1: -1;
|
|
||||||
}
|
|
||||||
else return t1->pid > t2->pid ? 1 : -1;
|
|
||||||
//return t>0?1:-1;
|
|
||||||
}
|
|
||||||
char TCmp::operator()(const ThreadParameter* t1, const ThreadParameter* t2)
|
char TCmp::operator()(const ThreadParameter* t1, const ThreadParameter* t2)
|
||||||
//SSE speed up. Compare four integers in const time without branching.
|
//SSE speed up. Compare four integers in const time without branching.
|
||||||
//The AVL tree branching operation needs 2 bit of information.
|
//The AVL tree branching operation needs 2 bit of information.
|
||||||
@ -546,9 +446,6 @@ void HookManager::RegisterProcess(DWORD pid)
|
|||||||
|
|
||||||
swprintf(str, ITH_HOOKMAN_MUTEX_ L"%d", pid);
|
swprintf(str, ITH_HOOKMAN_MUTEX_ L"%d", pid);
|
||||||
record[register_count - 1].hookman_mutex = IthOpenMutex(str);
|
record[register_count - 1].hookman_mutex = IthOpenMutex(str);
|
||||||
if (!GetProcessPath(pid, path))
|
|
||||||
path[0] = 0;
|
|
||||||
//swprintf(str,L"%.4d:%s", pid, wcsrchr(path, L'\\') + 1); // jichi 9/25/2013: this is useless?
|
|
||||||
current_pid = pid;
|
current_pid = pid;
|
||||||
if (attach)
|
if (attach)
|
||||||
attach(pid);
|
attach(pid);
|
||||||
@ -824,17 +721,6 @@ ProcessRecord *HookManager::GetProcessRecord(DWORD pid)
|
|||||||
//return pr;
|
//return pr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD HookManager::GetProcessIDByPath(LPCWSTR str)
|
|
||||||
{
|
|
||||||
WCHAR path[MAX_PATH];
|
|
||||||
for (int i = 0; i < 8 && record[i].process_handle; i++) {
|
|
||||||
::GetProcessPath(record[i].process_handle, path);
|
|
||||||
if (_wcsicmp(path,str) == 0)
|
|
||||||
return record[i].pid_register;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD HookManager::GetCurrentPID() { return current_pid; }
|
DWORD HookManager::GetCurrentPID() { return current_pid; }
|
||||||
|
|
||||||
HANDLE HookManager::GetCmdHandleByPID(DWORD pid)
|
HANDLE HookManager::GetCmdHandleByPID(DWORD pid)
|
||||||
|
@ -47,7 +47,6 @@ extern CRITICAL_SECTION detachCs;
|
|||||||
|
|
||||||
Settings *settings;
|
Settings *settings;
|
||||||
HWND dummyWindow;
|
HWND dummyWindow;
|
||||||
HANDLE pipeExistsEvent;
|
|
||||||
BOOL running;
|
BOOL running;
|
||||||
|
|
||||||
#define ITH_SYNC_HOOK IthMutexLocker locker(::hookMutex)
|
#define ITH_SYNC_HOOK IthMutexLocker locker(::hookMutex)
|
||||||
@ -140,7 +139,7 @@ IHFSERVICE void IHFAPI CloseHost()
|
|||||||
EnterCriticalSection(&::hostCs);
|
EnterCriticalSection(&::hostCs);
|
||||||
if (::running)
|
if (::running)
|
||||||
{
|
{
|
||||||
::running = FALSE;
|
::running = false;
|
||||||
delete man;
|
delete man;
|
||||||
delete settings;
|
delete settings;
|
||||||
CloseHandle(::hookMutex);
|
CloseHandle(::hookMutex);
|
||||||
@ -220,12 +219,11 @@ IHFSERVICE bool IHFAPI InjectProcessById(DWORD processId, DWORD timeout)
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
IHFSERVICE bool IHFAPI DetachProcessById(DWORD pid)
|
IHFSERVICE bool IHFAPI DetachProcessById(DWORD processId)
|
||||||
{
|
{
|
||||||
ITH_SYNC_HOOK;
|
ITH_SYNC_HOOK;
|
||||||
DWORD command = HOST_COMMAND_DETACH, unused;
|
DWORD command = HOST_COMMAND_DETACH;
|
||||||
HANDLE commandPipe = man->GetCmdHandleByPID(pid);
|
return WriteFile(man->GetCmdHandleByPID(processId), &command, sizeof(command), nullptr, nullptr);
|
||||||
return commandPipe && WriteFile(commandPipe, &command, sizeof(command), &unused, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IHFSERVICE void IHFAPI GetHostHookManager(HookManager** hookman)
|
IHFSERVICE void IHFAPI GetHostHookManager(HookManager** hookman)
|
||||||
|
@ -54,7 +54,6 @@ namespace
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (*str <= FILTER_LIMIT)
|
else if (*str <= FILTER_LIMIT)
|
||||||
{ // jichi 10/27/2013: 1 byte
|
{ // jichi 10/27/2013: 1 byte
|
||||||
|
@ -16633,8 +16633,8 @@ bool InsertPPSSPPHooks()
|
|||||||
|
|
||||||
ConsoleOutput("vnreng: PPSSPP: enter");
|
ConsoleOutput("vnreng: PPSSPP: enter");
|
||||||
|
|
||||||
if (!WinVersion::queryFileVersion(process_path_, PPSSPP_VERSION))
|
//if (!WinVersion::queryFileVersion(process_path_, PPSSPP_VERSION))
|
||||||
ConsoleOutput("vnreng: failed to get PPSSPP version");
|
// ConsoleOutput("vnreng: failed to get PPSSPP version");
|
||||||
|
|
||||||
InsertPPSSPPHLEHooks();
|
InsertPPSSPPHLEHooks();
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "include/defs.h"
|
#include "include/defs.h"
|
||||||
#include "ithsys/ithsys.h"
|
#include "ithsys/ithsys.h"
|
||||||
#include "ccutil/ccmacro.h"
|
#include "ccutil/ccmacro.h"
|
||||||
|
#include "util/util.h"
|
||||||
#include <cstdio> // for swprintf
|
#include <cstdio> // for swprintf
|
||||||
//#include "ntinspect/ntinspect.h"
|
//#include "ntinspect/ntinspect.h"
|
||||||
//#include "winseh/winseh.h"
|
//#include "winseh/winseh.h"
|
||||||
@ -58,7 +59,6 @@ namespace { FilterRange _filter[IHF_FILTER_CAPACITY]; }
|
|||||||
FilterRange *filter = _filter;
|
FilterRange *filter = _filter;
|
||||||
|
|
||||||
WCHAR hm_section[0x100];
|
WCHAR hm_section[0x100];
|
||||||
HINSTANCE hDLL;
|
|
||||||
HANDLE hSection;
|
HANDLE hSection;
|
||||||
bool running,
|
bool running,
|
||||||
live = false;
|
live = false;
|
||||||
@ -73,7 +73,6 @@ HANDLE
|
|||||||
extern DWORD enter_count;
|
extern DWORD enter_count;
|
||||||
//extern LPWSTR current_dir;
|
//extern LPWSTR current_dir;
|
||||||
extern DWORD engine_type;
|
extern DWORD engine_type;
|
||||||
extern DWORD module_base;
|
|
||||||
AVLTree<char, FunctionInfo, SCMP, SCPY, SLEN> *tree;
|
AVLTree<char, FunctionInfo, SCMP, SCPY, SLEN> *tree;
|
||||||
|
|
||||||
namespace { // unnamed
|
namespace { // unnamed
|
||||||
@ -124,20 +123,6 @@ void AddAllModules()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestRefreshProfile()
|
|
||||||
{
|
|
||||||
if (::live) {
|
|
||||||
BYTE buffer[0x80] = {}; // 11/14/2013: reset to zero. Shouldn't it be 0x8 instead of 0x80?
|
|
||||||
*(DWORD *)buffer = -1;
|
|
||||||
*(DWORD *)(buffer + 4) = 1;
|
|
||||||
*(DWORD *)(buffer + 8) = 0;
|
|
||||||
IO_STATUS_BLOCK ios;
|
|
||||||
CliLockPipe();
|
|
||||||
NtWriteFile(hookPipe, 0, 0, 0, &ios, buffer, HEADER_SIZE, 0, 0);
|
|
||||||
CliUnlockPipe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
DWORD GetFunctionAddr(const char *name, DWORD *addr, DWORD *base, DWORD *size, LPWSTR *base_name)
|
DWORD GetFunctionAddr(const char *name, DWORD *addr, DWORD *base, DWORD *size, LPWSTR *base_name)
|
||||||
@ -154,33 +139,22 @@ DWORD GetFunctionAddr(const char *name, DWORD *addr, DWORD *base, DWORD *size, L
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved)
|
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID unused)
|
||||||
{
|
{
|
||||||
static HANDLE pipeThread,
|
static HANDLE pipeThread;
|
||||||
hCmdThread;
|
|
||||||
|
|
||||||
CC_UNUSED(lpReserved);
|
|
||||||
|
|
||||||
//static WCHAR dll_exist[] = L"ITH_DLL_RUNNING";
|
|
||||||
static WCHAR dll_exist[] = ITH_CLIENT_MUTEX;
|
|
||||||
static HANDLE hDllExist;
|
|
||||||
|
|
||||||
// jichi 9/23/2013: wine deficenciy on mapping sections
|
|
||||||
// Whe set to false, do not map sections.
|
|
||||||
//static bool ith_has_section = true;
|
|
||||||
|
|
||||||
switch (fdwReason) {
|
switch (fdwReason) {
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
{
|
{
|
||||||
static bool attached_ = false;
|
static bool attached = false;
|
||||||
if (attached_) // already attached
|
if (attached) // already attached
|
||||||
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
attached_ = true;
|
}
|
||||||
|
attached = true;
|
||||||
|
|
||||||
LdrDisableThreadCalloutsForDll(hModule);
|
DisableThreadLibraryCalls(hModule);
|
||||||
|
|
||||||
//IthBreak();
|
|
||||||
::module_base = (DWORD)hModule;
|
|
||||||
|
|
||||||
//if (!IthInitSystemService()) {
|
//if (!IthInitSystemService()) {
|
||||||
// GROWL_WARN(L"Initialization failed.\nAre you running game on a network drive?");
|
// GROWL_WARN(L"Initialization failed.\nAre you running game on a network drive?");
|
||||||
@ -223,8 +197,6 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hDllExist = IthCreateMutex(dll_exist, 0);
|
|
||||||
hDLL = hModule;
|
|
||||||
::running = true;
|
::running = true;
|
||||||
::current_available = ::hookman;
|
::current_available = ::hookman;
|
||||||
::tree = new AVLTree<char, FunctionInfo, SCMP, SCPY, SLEN>;
|
::tree = new AVLTree<char, FunctionInfo, SCMP, SCPY, SLEN>;
|
||||||
@ -254,11 +226,6 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved)
|
|||||||
NtClose(pipeThread);
|
NtClose(pipeThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hCmdThread) {
|
|
||||||
NtWaitForSingleObject(hCmdThread, 0, (PLARGE_INTEGER)&timeout);
|
|
||||||
NtClose(hCmdThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TextHook *man = ::hookman; man->RemoveHook(); man++);
|
for (TextHook *man = ::hookman; man->RemoveHook(); man++);
|
||||||
//LARGE_INTEGER lint = {-10000, -1};
|
//LARGE_INTEGER lint = {-10000, -1};
|
||||||
while (::enter_count)
|
while (::enter_count)
|
||||||
@ -276,7 +243,6 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved)
|
|||||||
delete ::tree;
|
delete ::tree;
|
||||||
IthCloseSystemService();
|
IthCloseSystemService();
|
||||||
NtClose(hmMutex);
|
NtClose(hmMutex);
|
||||||
NtClose(hDllExist);
|
|
||||||
//} ITH_EXCEPT {}
|
//} ITH_EXCEPT {}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@ -310,7 +276,7 @@ DWORD NewHook(const HookParam &hp, LPCSTR name, DWORD flag)
|
|||||||
ConsoleOutput("vnrcli:NewHook: hook inserted");
|
ConsoleOutput("vnrcli:NewHook: hook inserted");
|
||||||
//ConsoleOutputW(name);
|
//ConsoleOutputW(name);
|
||||||
//swprintf(str,L"Insert address 0x%.8X.", hookman[current].Address());
|
//swprintf(str,L"Insert address 0x%.8X.", hookman[current].Address());
|
||||||
RequestRefreshProfile();
|
NotifyHookInsert(0);
|
||||||
} else
|
} else
|
||||||
ConsoleOutput("vnrcli:NewHook:WARNING: failed to insert hook");
|
ConsoleOutput("vnrcli:NewHook:WARNING: failed to insert hook");
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "include/types.h"
|
#include "include/types.h"
|
||||||
|
|
||||||
void ConsoleOutput(LPCSTR text); // jichi 12/25/2013: Used to return length of sent text
|
void ConsoleOutput(LPCSTR text); // jichi 12/25/2013: Used to return length of sent text
|
||||||
DWORD NotifyHookInsert(DWORD addr);
|
void NotifyHookInsert(DWORD addr);
|
||||||
DWORD NewHook(const HookParam &hp, LPCSTR name, DWORD flag = HOOK_ENGINE);
|
DWORD NewHook(const HookParam &hp, LPCSTR name, DWORD flag = HOOK_ENGINE);
|
||||||
DWORD RemoveHook(DWORD addr);
|
DWORD RemoveHook(DWORD addr);
|
||||||
DWORD SwitchTrigger(DWORD on);
|
DWORD SwitchTrigger(DWORD on);
|
||||||
|
@ -17,29 +17,7 @@
|
|||||||
#include "ccutil/ccmacro.h"
|
#include "ccutil/ccmacro.h"
|
||||||
#include <cstdio> // for swprintf
|
#include <cstdio> // for swprintf
|
||||||
|
|
||||||
//#include <ITH\AVL.h>
|
HANDLE hookPipe;
|
||||||
//#include <ITH\ntdll.h>
|
|
||||||
WCHAR detach_mutex[0x20];
|
|
||||||
//WCHAR write_event[0x20];
|
|
||||||
//WCHAR engine_event[0x20];
|
|
||||||
|
|
||||||
//WCHAR recv_pipe[] = L"\\??\\pipe\\ITH_PIPE";
|
|
||||||
//WCHAR command[] = L"\\??\\pipe\\ITH_COMMAND";
|
|
||||||
wchar_t recv_pipe[] = ITH_TEXT_PIPE;
|
|
||||||
wchar_t command[] = ITH_COMMAND_PIPE;
|
|
||||||
|
|
||||||
LARGE_INTEGER wait_time = {-100*10000, -1};
|
|
||||||
LARGE_INTEGER sleep_time = {-20*10000, -1};
|
|
||||||
|
|
||||||
DWORD engine_type;
|
|
||||||
DWORD module_base;
|
|
||||||
|
|
||||||
HANDLE hookPipe,
|
|
||||||
hCommand,
|
|
||||||
hDetach; //,hLose;
|
|
||||||
//InsertHookFun InsertHook;
|
|
||||||
//IdentifyEngineFun IdentifyEngine;
|
|
||||||
//InsertDynamicHookFun InsertDynamicHook;
|
|
||||||
|
|
||||||
// jichi 9/28/2013: protect pipe on wine
|
// jichi 9/28/2013: protect pipe on wine
|
||||||
// Put the definition in this file so that it might be inlined
|
// Put the definition in this file so that it might be inlined
|
||||||
@ -94,7 +72,7 @@ DWORD WINAPI PipeManager(LPVOID unused)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteFile(::hookPipe, &::currentProcessId, sizeof(::currentProcessId), &count, nullptr);
|
WriteFile(::hookPipe, &::currentProcessId, sizeof(::currentProcessId), nullptr, nullptr);
|
||||||
|
|
||||||
for (int i = 0, count = 0; count < ::currentHook; i++)
|
for (int i = 0, count = 0; count < ::currentHook; i++)
|
||||||
{
|
{
|
||||||
@ -125,6 +103,29 @@ DWORD WINAPI PipeManager(LPVOID unused)
|
|||||||
buffer[count] = 0;
|
buffer[count] = 0;
|
||||||
NewHook(*(HookParam *)(buffer + 4), (LPSTR)(buffer + 4 + sizeof(HookParam)), 0);
|
NewHook(*(HookParam *)(buffer + 4), (LPSTR)(buffer + 4 + sizeof(HookParam)), 0);
|
||||||
break;
|
break;
|
||||||
|
case HOST_COMMAND_REMOVE_HOOK:
|
||||||
|
{
|
||||||
|
DWORD removalAddress = *(DWORD *)(buffer + 4);
|
||||||
|
HANDLE hookRemovalEvent = OpenEventW(SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, ITH_REMOVEHOOK_EVENT);
|
||||||
|
|
||||||
|
TextHook *in = hookman;
|
||||||
|
for (int i = 0; i < currentHook; in++)
|
||||||
|
{
|
||||||
|
if (in->Address()) i++;
|
||||||
|
if (in->Address() == removalAddress)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (in->Address())
|
||||||
|
{
|
||||||
|
in->ClearHook();
|
||||||
|
}
|
||||||
|
|
||||||
|
SetEvent(hookRemovalEvent);
|
||||||
|
CloseHandle(hookRemovalEvent);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case HOST_COMMAND_DETACH:
|
case HOST_COMMAND_DETACH:
|
||||||
::running = false;
|
::running = false;
|
||||||
break;
|
break;
|
||||||
@ -146,199 +147,20 @@ DWORD WINAPI PipeManager(LPVOID unused)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD WINAPI WaitForPipe(LPVOID lpThreadParameter) // Dynamically detect ITH main module status.
|
|
||||||
{
|
|
||||||
CC_UNUSED(lpThreadParameter);
|
|
||||||
|
|
||||||
//swprintf(engine_event,L"ITH_ENGINE_%d",currentProcessId);
|
|
||||||
swprintf(::detach_mutex, ITH_DETACH_MUTEX_ L"%d", currentProcessId);
|
|
||||||
//swprintf(lose_event,L"ITH_LOSEPIPE_%d",currentProcessId);
|
|
||||||
//hEngine=IthCreateEvent(engine_event);
|
|
||||||
//NtWaitForSingleObject(hEngine,0,0);
|
|
||||||
//NtClose(hEngine);
|
|
||||||
|
|
||||||
//while (!engine_registered)
|
|
||||||
// NtDelayExecution(0, &wait_time);
|
|
||||||
|
|
||||||
//LoadEngine(L"ITH_Engine.dll");
|
|
||||||
//u.engine = engine_base; // jichi 10/19/2014: disable the second dll
|
|
||||||
HANDLE hPipeExist = IthOpenEvent(ITH_PIPEEXISTS_EVENT);
|
|
||||||
IO_STATUS_BLOCK ios;
|
|
||||||
//hLose=IthCreateEvent(lose_event,0,0);
|
|
||||||
if (hPipeExist != INVALID_HANDLE_VALUE)
|
|
||||||
while (::running) {
|
|
||||||
::hookPipe = INVALID_HANDLE_VALUE;
|
|
||||||
hCommand = INVALID_HANDLE_VALUE;
|
|
||||||
while (NtWaitForSingleObject(hPipeExist, 0, &wait_time) == WAIT_TIMEOUT)
|
|
||||||
if (!::running)
|
|
||||||
goto _release;
|
|
||||||
GROWL_MSG(L"Pipe connected");
|
|
||||||
HANDLE hMutex = IthCreateMutex(ITH_GRANTPIPE_MUTEX, 0);
|
|
||||||
NtWaitForSingleObject(hMutex, 0, 0);
|
|
||||||
while (::hookPipe == INVALID_HANDLE_VALUE||
|
|
||||||
hCommand == INVALID_HANDLE_VALUE) {
|
|
||||||
NtDelayExecution(0, &sleep_time);
|
|
||||||
if (::hookPipe == INVALID_HANDLE_VALUE)
|
|
||||||
::hookPipe = IthOpenPipe(recv_pipe, GENERIC_WRITE);
|
|
||||||
if (hCommand == INVALID_HANDLE_VALUE)
|
|
||||||
hCommand = IthOpenPipe(command, GENERIC_READ);
|
|
||||||
}
|
|
||||||
//NtClearEvent(hLose);
|
|
||||||
CliLockPipe();
|
|
||||||
NtWriteFile(::hookPipe, 0, 0, 0, &ios, &::currentProcessId, sizeof(::currentProcessId), 0, 0);
|
|
||||||
CliUnlockPipe();
|
|
||||||
for (int i = 0, count = 0; count < ::currentHook; i++)
|
|
||||||
if (hookman[i].RecoverHook()) // jichi 9/27/2013: This is the place where built-in hooks like TextOutA are inserted
|
|
||||||
count++;
|
|
||||||
//ConsoleOutput(dll_name);
|
|
||||||
//OutputDWORD(tree->Count());
|
|
||||||
NtReleaseMutant(hMutex,0);
|
|
||||||
NtClose(hMutex);
|
|
||||||
|
|
||||||
|
|
||||||
::live = true;
|
|
||||||
|
|
||||||
// jichi 7/17/2014: Always hijack by default or I have to wait for it is ready
|
|
||||||
Engine::hijack();
|
|
||||||
ConsoleOutput("vnrcli:WaitForPipe: pipe connected");
|
|
||||||
|
|
||||||
::hDetach = IthCreateMutex(::detach_mutex,1);
|
|
||||||
while (::running && NtWaitForSingleObject(hPipeExist, 0, &sleep_time) == WAIT_OBJECT_0)
|
|
||||||
NtDelayExecution(0, &sleep_time);
|
|
||||||
::live = false;
|
|
||||||
|
|
||||||
for (int i = 0, count = 0; count < ::currentHook; i++)
|
|
||||||
if (hookman[i].RemoveHook())
|
|
||||||
count++;
|
|
||||||
if (!::running) {
|
|
||||||
IthCoolDown(); // jichi 9/28/2013: Use cooldown instead of lock pipe to prevent from hanging on exit
|
|
||||||
//CliLockPipe();
|
|
||||||
//NtWriteFile(::hookPipe, 0, 0, 0, &ios, man, 4, 0, 0);
|
|
||||||
NtWriteFile(::hookPipe, 0, 0, 0, &ios, hookman, 4, 0, 0);
|
|
||||||
//CliUnlockPipe();
|
|
||||||
IthReleaseMutex(::hDetach);
|
|
||||||
}
|
|
||||||
NtClose(::hDetach);
|
|
||||||
NtClose(::hookPipe);
|
|
||||||
}
|
|
||||||
_release:
|
|
||||||
//NtClose(hLose);
|
|
||||||
NtClose(hPipeExist);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI CommandPipe(LPVOID lpThreadParameter)
|
|
||||||
{
|
|
||||||
CC_UNUSED(lpThreadParameter);
|
|
||||||
DWORD command;
|
|
||||||
BYTE buff[0x400] = {};
|
|
||||||
HANDLE hPipeExist;
|
|
||||||
hPipeExist = IthOpenEvent(ITH_PIPEEXISTS_EVENT);
|
|
||||||
IO_STATUS_BLOCK ios={};
|
|
||||||
|
|
||||||
if (hPipeExist != INVALID_HANDLE_VALUE)
|
|
||||||
while (::running) {
|
|
||||||
while (!::live) {
|
|
||||||
if (!::running)
|
|
||||||
goto _detach;
|
|
||||||
NtDelayExecution(0, &sleep_time);
|
|
||||||
}
|
|
||||||
// jichi 9/27/2013: Why 0x200 not 0x400? wchar_t?
|
|
||||||
switch (NtReadFile(hCommand, 0, 0, 0, &ios, buff, 0x200, 0, 0)) {
|
|
||||||
case STATUS_PIPE_BROKEN:
|
|
||||||
case STATUS_PIPE_DISCONNECTED:
|
|
||||||
NtClearEvent(hPipeExist);
|
|
||||||
continue;
|
|
||||||
case STATUS_PENDING:
|
|
||||||
NtWaitForSingleObject(hCommand, 0, 0);
|
|
||||||
switch (ios.Status) {
|
|
||||||
case STATUS_PIPE_BROKEN:
|
|
||||||
case STATUS_PIPE_DISCONNECTED:
|
|
||||||
NtClearEvent(hPipeExist);
|
|
||||||
continue;
|
|
||||||
case 0: break;
|
|
||||||
default:
|
|
||||||
if (NtWaitForSingleObject(::hDetach, 0, &wait_time) == WAIT_OBJECT_0)
|
|
||||||
goto _detach;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ios.uInformation && ::live) {
|
|
||||||
command = *(DWORD *)buff;
|
|
||||||
switch(command) {
|
|
||||||
case HOST_COMMAND_NEW_HOOK:
|
|
||||||
//IthBreak();
|
|
||||||
buff[ios.uInformation] = 0;
|
|
||||||
//buff[ios.uInformation + 1] = 0;
|
|
||||||
NewHook(*(HookParam *)(buff + 4), (LPSTR)(buff + 4 + sizeof(HookParam)), 0);
|
|
||||||
break;
|
|
||||||
case HOST_COMMAND_REMOVE_HOOK:
|
|
||||||
{
|
|
||||||
DWORD rm_addr = *(DWORD *)(buff+4);
|
|
||||||
HANDLE hRemoved = IthOpenEvent(ITH_REMOVEHOOK_EVENT);
|
|
||||||
|
|
||||||
TextHook *in = hookman;
|
|
||||||
for (int i = 0; i < currentHook; in++) {
|
|
||||||
if (in->Address()) i++;
|
|
||||||
if (in->Address() == rm_addr) break;
|
|
||||||
}
|
|
||||||
if (in->Address())
|
|
||||||
in->ClearHook();
|
|
||||||
IthSetEvent(hRemoved);
|
|
||||||
NtClose(hRemoved);
|
|
||||||
} break;
|
|
||||||
#if 0 // Temporarily disabled as these operations are not used by VNR
|
|
||||||
case HOST_COMMAND_MODIFY_HOOK:
|
|
||||||
{
|
|
||||||
DWORD rm_addr = *(DWORD *)(buff + 4);
|
|
||||||
HANDLE hModify = IthOpenEvent(ITH_MODIFYHOOK_EVENT);
|
|
||||||
TextHook *in = hookman;
|
|
||||||
for (int i = 0; i < currentHook; in++) {
|
|
||||||
if (in->Address())
|
|
||||||
i++;
|
|
||||||
if (in->Address() == rm_addr)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (in->Address())
|
|
||||||
in->ModifyHook(*(HookParam *)(buff + 4));
|
|
||||||
IthSetEvent(hModify);
|
|
||||||
NtClose(hModify);
|
|
||||||
} break;
|
|
||||||
case HOST_COMMAND_HIJACK_PROCESS:
|
|
||||||
Engine::hijack();
|
|
||||||
break;
|
|
||||||
#endif // 0
|
|
||||||
case HOST_COMMAND_DETACH:
|
|
||||||
::running = false;
|
|
||||||
::live = false;
|
|
||||||
goto _detach;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_detach:
|
|
||||||
NtClose(hPipeExist);
|
|
||||||
NtClose(hCommand);
|
|
||||||
Util::unloadCurrentModule(); // jichi: this is not always needed
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
//extern "C" {
|
|
||||||
void ConsoleOutput(LPCSTR text)
|
void ConsoleOutput(LPCSTR text)
|
||||||
{ // jichi 12/25/2013: Rewrite the implementation
|
{ // jichi 12/25/2013: Rewrite the implementation
|
||||||
if (!live || !text)
|
if (!::live)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
enum { buf_size = 0x50 };
|
}
|
||||||
BYTE buf[buf_size]; // buffer is needed to append the message header
|
|
||||||
size_t text_size = strlen(text) + 1;
|
|
||||||
size_t data_size = text_size + 8;
|
|
||||||
|
|
||||||
BYTE *data = (data_size <= buf_size) ? buf : new BYTE[data_size];
|
DWORD textSize = strlen(text) + 1;
|
||||||
*(DWORD *)data = HOST_NOTIFICATION; //cmd
|
DWORD dataSize = textSize + 8;
|
||||||
*(DWORD *)(data + 4) = HOST_NOTIFICATION_TEXT; //console
|
BYTE *buffer = new BYTE[dataSize];
|
||||||
memcpy(data + 8, text, text_size);
|
*(DWORD*)buffer = HOST_NOTIFICATION; //cmd
|
||||||
|
*(DWORD*)(buffer + 4) = HOST_NOTIFICATION_TEXT; //console
|
||||||
IO_STATUS_BLOCK ios;
|
memcpy(buffer + 8, text, textSize);
|
||||||
NtWriteFile(hookPipe, 0, 0, 0, &ios, data, data_size, 0, 0);
|
WriteFile(::hookPipe, buffer, dataSize, nullptr, nullptr);
|
||||||
if (data != buf)
|
|
||||||
delete[] data;
|
|
||||||
}
|
}
|
||||||
//if (str) {
|
//if (str) {
|
||||||
// int t, len, sum;
|
// int t, len, sum;
|
||||||
@ -399,21 +221,18 @@ void ConsoleOutput(LPCSTR text)
|
|||||||
// ::engine_registered = true;
|
// ::engine_registered = true;
|
||||||
// return 0;
|
// return 0;
|
||||||
//}
|
//}
|
||||||
DWORD NotifyHookInsert(DWORD addr)
|
void NotifyHookInsert(DWORD addr)
|
||||||
{
|
{
|
||||||
if (live) {
|
if (!::live)
|
||||||
BYTE buffer[0x10];
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BYTE buffer[0xc];
|
||||||
*(DWORD*)buffer = HOST_NOTIFICATION;
|
*(DWORD*)buffer = HOST_NOTIFICATION;
|
||||||
*(DWORD*)(buffer + 4) = HOST_NOTIFICATION_NEWHOOK;
|
*(DWORD*)(buffer + 4) = HOST_NOTIFICATION_NEWHOOK;
|
||||||
*(DWORD*)(buffer + 8) = addr;
|
*(DWORD*)(buffer + 8) = addr;
|
||||||
*(DWORD *)(buffer + 0xc) = 0;
|
WriteFile(::hookPipe, buffer, 0xc, nullptr, nullptr);
|
||||||
IO_STATUS_BLOCK ios;
|
return;
|
||||||
CliLockPipe();
|
|
||||||
NtWriteFile(hookPipe,0,0,0,&ios,buffer,0x10,0,0);
|
|
||||||
CliUnlockPipe();
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
//} // extern "C"
|
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
Loading…
x
Reference in New Issue
Block a user