refactor and start using pipe instead of section to get hook info
This commit is contained in:
parent
ae6656441b
commit
ffbb081bcc
@ -363,23 +363,8 @@ bool GetHookParam(DWORD pid, DWORD hook_addr, HookParam& hp)
|
|||||||
{
|
{
|
||||||
if (!pid)
|
if (!pid)
|
||||||
return false;
|
return false;
|
||||||
ProcessRecord *pr = ::man->GetProcessRecord(pid);
|
hp = man->GetHook(pid, hook_addr).hp;
|
||||||
if (!pr)
|
return true;
|
||||||
return false;
|
|
||||||
bool result = false;
|
|
||||||
WaitForSingleObject(pr->hookman_mutex, 0);
|
|
||||||
const Hook *hks = (Hook *)pr->hookman_map;
|
|
||||||
for (int i = 0; i < MAX_HOOK; i++)
|
|
||||||
{
|
|
||||||
if (hks[i].Address() == hook_addr)
|
|
||||||
{
|
|
||||||
hp = hks[i].hp;
|
|
||||||
result = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ReleaseMutex(pr->hookman_mutex);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring GetEntryString(TextThread& thread)
|
std::wstring GetEntryString(TextThread& thread)
|
||||||
@ -506,7 +491,7 @@ bool IsUnicodeHook(const ProcessRecord& pr, DWORD hook)
|
|||||||
{
|
{
|
||||||
bool res = false;
|
bool res = false;
|
||||||
WaitForSingleObject(pr.hookman_mutex, 0);
|
WaitForSingleObject(pr.hookman_mutex, 0);
|
||||||
auto hooks = (const Hook*)pr.hookman_map;
|
auto hooks = (const OldHook*)pr.hookman_map;
|
||||||
for (DWORD i = 0; i < MAX_HOOK; i++)
|
for (DWORD i = 0; i < MAX_HOOK; i++)
|
||||||
{
|
{
|
||||||
if (hooks[i].Address() == hook)
|
if (hooks[i].Address() == hook)
|
||||||
|
@ -257,7 +257,7 @@ std::wstring GetHookNameByAddress(const ProcessRecord& pr, DWORD hook_address)
|
|||||||
{
|
{
|
||||||
std::wstring hook_name;
|
std::wstring hook_name;
|
||||||
WaitForSingleObject(pr.hookman_mutex, 0);
|
WaitForSingleObject(pr.hookman_mutex, 0);
|
||||||
auto hooks = (const Hook*)pr.hookman_map;
|
auto hooks = (const OldHook*)pr.hookman_map;
|
||||||
for (int i = 0; i < MAX_HOOK; ++i)
|
for (int i = 0; i < MAX_HOOK; ++i)
|
||||||
{
|
{
|
||||||
auto& hook = hooks[i];
|
auto& hook = hooks[i];
|
||||||
|
@ -29,10 +29,10 @@ HookManager::HookManager() :
|
|||||||
detach(nullptr),
|
detach(nullptr),
|
||||||
hook(nullptr),
|
hook(nullptr),
|
||||||
new_thread_number(0),
|
new_thread_number(0),
|
||||||
threadTable(),
|
textThreadsByParams(),
|
||||||
processRecordsByIds()
|
processRecordsByIds()
|
||||||
{
|
{
|
||||||
TextThread* consoleTextThread = threadTable[{0, -1UL, -1UL, -1UL}] = new TextThread({ 0, -1UL, -1UL, -1UL }, new_thread_number++, splitDelay);
|
TextThread* consoleTextThread = textThreadsByParams[{0, -1UL, -1UL, -1UL}] = new TextThread({ 0, -1UL, -1UL, -1UL }, new_thread_number++, splitDelay);
|
||||||
consoleTextThread->Status() |= USING_UNICODE;
|
consoleTextThread->Status() |= USING_UNICODE;
|
||||||
SetCurrent(consoleTextThread);
|
SetCurrent(consoleTextThread);
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ HookManager::~HookManager()
|
|||||||
|
|
||||||
TextThread *HookManager::FindSingle(DWORD number)
|
TextThread *HookManager::FindSingle(DWORD number)
|
||||||
{
|
{
|
||||||
for (auto i : threadTable)
|
for (auto i : textThreadsByParams)
|
||||||
{
|
{
|
||||||
if (i.second->Number() == number)
|
if (i.second->Number() == number)
|
||||||
{
|
{
|
||||||
@ -77,7 +77,7 @@ void HookManager::RemoveSingleHook(DWORD pid, DWORD addr)
|
|||||||
{
|
{
|
||||||
HM_LOCK;
|
HM_LOCK;
|
||||||
std::vector<ThreadParameter> removedThreads;
|
std::vector<ThreadParameter> removedThreads;
|
||||||
for (auto i : threadTable)
|
for (auto i : textThreadsByParams)
|
||||||
{
|
{
|
||||||
if (i.second->PID() == pid && i.second->Addr() == addr)
|
if (i.second->PID() == pid && i.second->Addr() == addr)
|
||||||
{
|
{
|
||||||
@ -91,7 +91,7 @@ void HookManager::RemoveSingleHook(DWORD pid, DWORD addr)
|
|||||||
}
|
}
|
||||||
for (auto i : removedThreads)
|
for (auto i : removedThreads)
|
||||||
{
|
{
|
||||||
threadTable.erase(i);
|
textThreadsByParams.erase(i);
|
||||||
}
|
}
|
||||||
SelectCurrent(0);
|
SelectCurrent(0);
|
||||||
}
|
}
|
||||||
@ -100,7 +100,7 @@ void HookManager::RemoveProcessContext(DWORD pid)
|
|||||||
{
|
{
|
||||||
HM_LOCK;
|
HM_LOCK;
|
||||||
std::vector<ThreadParameter> removedThreads;
|
std::vector<ThreadParameter> removedThreads;
|
||||||
for (auto i : threadTable)
|
for (auto i : textThreadsByParams)
|
||||||
{
|
{
|
||||||
if (i.second->PID() == pid)
|
if (i.second->PID() == pid)
|
||||||
{
|
{
|
||||||
@ -114,7 +114,7 @@ void HookManager::RemoveProcessContext(DWORD pid)
|
|||||||
}
|
}
|
||||||
for (auto i : removedThreads)
|
for (auto i : removedThreads)
|
||||||
{
|
{
|
||||||
threadTable.erase(i);
|
textThreadsByParams.erase(i);
|
||||||
}
|
}
|
||||||
SelectCurrent(0);
|
SelectCurrent(0);
|
||||||
}
|
}
|
||||||
@ -159,9 +159,9 @@ void HookManager::DispatchText(DWORD pid, const BYTE *text, DWORD hook, DWORD re
|
|||||||
HM_LOCK;
|
HM_LOCK;
|
||||||
ThreadParameter tp = {pid, hook, retn, spl};
|
ThreadParameter tp = {pid, hook, retn, spl};
|
||||||
TextThread *it;
|
TextThread *it;
|
||||||
if (!(it = threadTable[tp]))
|
if (!(it = textThreadsByParams[tp]))
|
||||||
{
|
{
|
||||||
it = threadTable[tp] = new TextThread(tp, new_thread_number++, splitDelay);
|
it = textThreadsByParams[tp] = new TextThread(tp, new_thread_number++, splitDelay);
|
||||||
if (create)
|
if (create)
|
||||||
{
|
{
|
||||||
create(it);
|
create(it);
|
||||||
@ -175,7 +175,7 @@ void HookManager::AddConsoleOutput(LPCWSTR text)
|
|||||||
if (text)
|
if (text)
|
||||||
{
|
{
|
||||||
int len = wcslen(text) * 2;
|
int len = wcslen(text) * 2;
|
||||||
TextThread *console = threadTable[{0, -1UL, -1UL, -1UL}];
|
TextThread *console = textThreadsByParams[{0, -1UL, -1UL, -1UL}];
|
||||||
console->AddSentence(std::wstring(text));
|
console->AddSentence(std::wstring(text));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,6 +202,18 @@ HANDLE HookManager::GetHostPipe(DWORD pid)
|
|||||||
return processRecordsByIds[pid] ? processRecordsByIds[pid]->hostPipe : nullptr;
|
return processRecordsByIds[pid] ? processRecordsByIds[pid]->hostPipe : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Hook HookManager::GetHook(DWORD processId, DWORD addr)
|
||||||
|
{
|
||||||
|
HM_LOCK;
|
||||||
|
return hooksByAddresses[{ processId, addr, 0, 0}];
|
||||||
|
}
|
||||||
|
|
||||||
|
void HookManager::SetHook(DWORD processId, DWORD addr, Hook hook)
|
||||||
|
{
|
||||||
|
HM_LOCK;
|
||||||
|
hooksByAddresses[{ processId, addr, 0, 0}] = hook;
|
||||||
|
}
|
||||||
|
|
||||||
void AddHooksToProfile(Profile& pf, const ProcessRecord& pr);
|
void AddHooksToProfile(Profile& pf, const ProcessRecord& pr);
|
||||||
DWORD AddThreadToProfile(Profile& pf, const ProcessRecord& pr, TextThread* thread);
|
DWORD AddThreadToProfile(Profile& pf, const ProcessRecord& pr, TextThread* thread);
|
||||||
void MakeHookRelative(const ProcessRecord& pr, HookParam& hp);
|
void MakeHookRelative(const ProcessRecord& pr, HookParam& hp);
|
||||||
@ -220,7 +232,7 @@ void HookManager::GetProfile(DWORD pid, pugi::xml_node profile_node)
|
|||||||
void AddHooksToProfile(Profile& pf, const ProcessRecord& pr)
|
void AddHooksToProfile(Profile& pf, const ProcessRecord& pr)
|
||||||
{
|
{
|
||||||
WaitForSingleObject(pr.hookman_mutex, 0);
|
WaitForSingleObject(pr.hookman_mutex, 0);
|
||||||
auto hooks = (const Hook*)pr.hookman_map;
|
auto hooks = (const OldHook*)pr.hookman_map;
|
||||||
for (DWORD i = 0; i < MAX_HOOK; ++i)
|
for (DWORD i = 0; i < MAX_HOOK; ++i)
|
||||||
{
|
{
|
||||||
if (hooks[i].Address() == 0)
|
if (hooks[i].Address() == 0)
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include "host/textthread.h"
|
#include "host/textthread.h"
|
||||||
#include "winmutex/winmutex.h"
|
#include "winmutex/winmutex.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
#include "vnrhook/include/types.h"
|
||||||
|
|
||||||
namespace pugi {
|
namespace pugi {
|
||||||
class xml_node;
|
class xml_node;
|
||||||
@ -23,7 +25,12 @@ struct ProcessRecord {
|
|||||||
HANDLE hookman_section;
|
HANDLE hookman_section;
|
||||||
LPVOID hookman_map;
|
LPVOID hookman_map;
|
||||||
HANDLE hostPipe;
|
HANDLE hostPipe;
|
||||||
//std::unordered_map<DWORD, Hook> hooksByAddress;
|
};
|
||||||
|
|
||||||
|
struct Hook
|
||||||
|
{
|
||||||
|
HookParam hp;
|
||||||
|
std::wstring name;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef DWORD (*ProcessEventCallback)(DWORD pid);
|
typedef DWORD (*ProcessEventCallback)(DWORD pid);
|
||||||
@ -41,11 +48,10 @@ class DLLEXPORT HookManager
|
|||||||
public:
|
public:
|
||||||
HookManager();
|
HookManager();
|
||||||
~HookManager();
|
~HookManager();
|
||||||
// jichi 12/26/2013: remove virtual modifiers
|
|
||||||
TextThread *FindSingle(DWORD number);
|
TextThread *FindSingle(DWORD number);
|
||||||
ProcessRecord *GetProcessRecord(DWORD pid);
|
ProcessRecord *GetProcessRecord(DWORD pid);
|
||||||
//void LockHookman();
|
Hook GetHook(DWORD processId, DWORD addr);
|
||||||
//void UnlockHookman();
|
void SetHook(DWORD processId, DWORD addr, Hook hook);
|
||||||
void ClearCurrent();
|
void ClearCurrent();
|
||||||
void SelectCurrent(DWORD num);
|
void SelectCurrent(DWORD num);
|
||||||
void SetCurrent(TextThread *it);
|
void SetCurrent(TextThread *it);
|
||||||
@ -85,7 +91,8 @@ public:
|
|||||||
void GetProfile(DWORD pid, pugi::xml_node profile_node);
|
void GetProfile(DWORD pid, pugi::xml_node profile_node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<ThreadParameter, TextThread*, ThreadParameterHasher> threadTable;
|
std::unordered_map<ThreadParameter, TextThread*, ThreadParameterHasher> textThreadsByParams;
|
||||||
|
std::unordered_map<ThreadParameter, Hook, ThreadParameterHasher> hooksByAddresses; // Artikash 7/17/2018: retn and spl should always be zero when accessing this!
|
||||||
std::unordered_map<DWORD, ProcessRecord*> processRecordsByIds;
|
std::unordered_map<DWORD, ProcessRecord*> processRecordsByIds;
|
||||||
|
|
||||||
CRITICAL_SECTION hmcs;
|
CRITICAL_SECTION hmcs;
|
||||||
|
@ -68,7 +68,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID unused)
|
|||||||
|
|
||||||
DLLEXPORT bool StartHost()
|
DLLEXPORT bool StartHost()
|
||||||
{
|
{
|
||||||
|
|
||||||
preventDuplicationMutex = CreateMutexW(nullptr, TRUE, ITH_SERVER_MUTEX);
|
preventDuplicationMutex = CreateMutexW(nullptr, TRUE, ITH_SERVER_MUTEX);
|
||||||
if (GetLastError() == ERROR_ALREADY_EXISTS || ::running)
|
if (GetLastError() == ERROR_ALREADY_EXISTS || ::running)
|
||||||
{
|
{
|
||||||
@ -101,7 +100,6 @@ DLLEXPORT void CloseHost()
|
|||||||
|
|
||||||
DLLEXPORT bool InjectProcessById(DWORD processId, DWORD timeout)
|
DLLEXPORT bool InjectProcessById(DWORD processId, DWORD timeout)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (processId == GetCurrentProcessId())
|
if (processId == GetCurrentProcessId())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -158,11 +156,11 @@ DLLEXPORT DWORD InsertHook(DWORD pid, const HookParam *hp, std::string name)
|
|||||||
|
|
||||||
BYTE buffer[PIPE_BUFFER_SIZE] = {};
|
BYTE buffer[PIPE_BUFFER_SIZE] = {};
|
||||||
*(DWORD*)buffer = HOST_COMMAND_NEW_HOOK;
|
*(DWORD*)buffer = HOST_COMMAND_NEW_HOOK;
|
||||||
memcpy(buffer + 4, hp, sizeof(HookParam));
|
*(HookParam*)(buffer + sizeof(DWORD)) = *hp;
|
||||||
if (name.size()) strcpy((char*)buffer + 4 + sizeof(HookParam), name.c_str());
|
if (name.size()) strcpy((char*)buffer + sizeof(DWORD) + sizeof(HookParam), name.c_str());
|
||||||
|
|
||||||
DWORD unused;
|
DWORD unused;
|
||||||
WriteFile(commandPipe, buffer, 4 + sizeof(HookParam) + name.size(), &unused, nullptr);
|
WriteFile(commandPipe, buffer, sizeof(DWORD) + sizeof(HookParam) + name.size(), &unused, nullptr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,12 +171,12 @@ DLLEXPORT DWORD RemoveHook(DWORD pid, DWORD addr)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
HANDLE hookRemovalEvent = CreateEventW(nullptr, TRUE, FALSE, ITH_REMOVEHOOK_EVENT);
|
HANDLE hookRemovalEvent = CreateEventW(nullptr, TRUE, FALSE, ITH_REMOVEHOOK_EVENT);
|
||||||
BYTE buffer[8];
|
BYTE buffer[sizeof(DWORD) * 2] = {};
|
||||||
*(DWORD*)buffer = HOST_COMMAND_REMOVE_HOOK;
|
*(DWORD*)buffer = HOST_COMMAND_REMOVE_HOOK;
|
||||||
*(DWORD*)(buffer + 4) = addr;
|
*(DWORD*)(buffer + sizeof(DWORD)) = addr;
|
||||||
|
|
||||||
DWORD unused;
|
DWORD unused;
|
||||||
WriteFile(commandPipe, buffer, 8, &unused, nullptr);
|
WriteFile(commandPipe, buffer, sizeof(DWORD) * 2, &unused, nullptr);
|
||||||
WaitForSingleObject(hookRemovalEvent, 1000);
|
WaitForSingleObject(hookRemovalEvent, 1000);
|
||||||
CloseHandle(hookRemovalEvent);
|
CloseHandle(hookRemovalEvent);
|
||||||
man->RemoveSingleHook(pid, addr);
|
man->RemoveSingleHook(pid, addr);
|
||||||
|
@ -61,32 +61,37 @@ DWORD WINAPI TextReceiver(LPVOID lpThreadParameter)
|
|||||||
|
|
||||||
if (*(DWORD*)buffer == HOST_NOTIFICATION)
|
if (*(DWORD*)buffer == HOST_NOTIFICATION)
|
||||||
{
|
{
|
||||||
|
USES_CONVERSION;
|
||||||
switch (*(DWORD*)(buffer + 4)) // Artikash 7/17/2018: Notification type
|
switch (*(DWORD*)(buffer + 4)) // Artikash 7/17/2018: Notification type
|
||||||
{
|
{
|
||||||
case HOST_NOTIFICATION_NEWHOOK:
|
case HOST_NOTIFICATION_NEWHOOK:
|
||||||
|
man->SetHook(processId,
|
||||||
|
((HookParam*)(buffer + sizeof(DWORD) * 2))->address,
|
||||||
{
|
{
|
||||||
|
*(HookParam*)(buffer + sizeof(DWORD) * 2), // Hook address
|
||||||
break;
|
std::wstring(A2W(
|
||||||
|
(const char*)buffer + sizeof(DWORD) * 2 + sizeof(HookParam) // Hook name
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
break;
|
||||||
case HOST_NOTIFICATION_TEXT:
|
case HOST_NOTIFICATION_TEXT:
|
||||||
USES_CONVERSION;
|
man->AddConsoleOutput(A2W((LPCSTR)(buffer + sizeof(DWORD) * 2))); // Text
|
||||||
man->AddConsoleOutput(A2W((LPCSTR)(buffer + 8)));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD hook = *(DWORD*)buffer;
|
|
||||||
DWORD retn = *(DWORD*)(buffer + 4);
|
|
||||||
DWORD split = *(DWORD*)(buffer + 8);
|
|
||||||
// jichi 9/28/2013: Debug raw data
|
// jichi 9/28/2013: Debug raw data
|
||||||
//ITH_DEBUG_DWORD9(RecvLen - 0xc,
|
//ITH_DEBUG_DWORD9(RecvLen - 0xc,
|
||||||
// buffer[0xc], buffer[0xd], buffer[0xe], buffer[0xf],
|
// buffer[0xc], buffer[0xd], buffer[0xe], buffer[0xf],
|
||||||
// buffer[0x10], buffer[0x11], buffer[0x12], buffer[0x13]);
|
// buffer[0x10], buffer[0x11], buffer[0x12], buffer[0x13]);
|
||||||
|
man->DispatchText(processId, buffer + HEADER_SIZE,
|
||||||
const BYTE *data = buffer + HEADER_SIZE; // th
|
*(DWORD*)buffer, // Hook address
|
||||||
int dataLength = bytesRead - HEADER_SIZE;
|
*(DWORD*)(buffer + sizeof(DWORD)), // Return address
|
||||||
man->DispatchText(processId, data, hook, retn, split, dataLength);
|
*(DWORD*)(buffer + sizeof(DWORD) * 2), // Split
|
||||||
|
bytesRead - HEADER_SIZE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ DWORD GetHookName(LPSTR str, DWORD pid, DWORD hook_addr, DWORD max)
|
|||||||
if (!pr)
|
if (!pr)
|
||||||
return 0;
|
return 0;
|
||||||
WaitForSingleObject(pr->hookman_mutex, 0);
|
WaitForSingleObject(pr->hookman_mutex, 0);
|
||||||
const Hook *hks = (const Hook *)pr->hookman_map;
|
const OldHook *hks = (const OldHook *)pr->hookman_map;
|
||||||
for (int i = 0; i < MAX_HOOK; i++)
|
for (int i = 0; i < MAX_HOOK; i++)
|
||||||
if (hks[i].Address() == hook_addr) {
|
if (hks[i].Address() == hook_addr) {
|
||||||
len = hks[i].NameLength();
|
len = hks[i].NameLength();
|
||||||
|
@ -253,7 +253,7 @@ enum {
|
|||||||
// - 0x0 dwAddr hook address
|
// - 0x0 dwAddr hook address
|
||||||
// - 0x4 dwRetn return address
|
// - 0x4 dwRetn return address
|
||||||
// - 0x8 dwSplit split value
|
// - 0x8 dwSplit split value
|
||||||
#define HEADER_SIZE 0xc
|
#define HEADER_SIZE sizeof(DWORD) * 3
|
||||||
|
|
||||||
#define TIMEOUT 5000 // 5 seconds
|
#define TIMEOUT 5000 // 5 seconds
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ struct SendParam {
|
|||||||
HookParam hp;
|
HookParam hp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Hook { // size: 0x80
|
struct OldHook { // size: 0x80
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
LPSTR hook_name;
|
LPSTR hook_name;
|
||||||
int name_length;
|
int name_length;
|
||||||
|
@ -339,8 +339,6 @@ DWORD TextHook::UnsafeSend(DWORD dwDataBase, DWORD dwRetn)
|
|||||||
BYTE *pbData,
|
BYTE *pbData,
|
||||||
pbSmallBuff[SMALL_BUFF_SIZE];
|
pbSmallBuff[SMALL_BUFF_SIZE];
|
||||||
DWORD dwType = hp.type;
|
DWORD dwType = hp.type;
|
||||||
if (!::live) // the pipe thread is busy
|
|
||||||
return 0;
|
|
||||||
//if ((dwType & NO_CONTEXT) == 0 && HookFilter(dwRetn))
|
//if ((dwType & NO_CONTEXT) == 0 && HookFilter(dwRetn))
|
||||||
// return 0;
|
// return 0;
|
||||||
|
|
||||||
@ -730,26 +728,6 @@ int TextHook::ClearHook()
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextHook::ModifyHook(const HookParam &hp)
|
|
||||||
{
|
|
||||||
//WCHAR name[0x40];
|
|
||||||
DWORD len = 0;
|
|
||||||
if (hook_name)
|
|
||||||
len = ::strlen(hook_name);
|
|
||||||
LPSTR name = 0;
|
|
||||||
if (len) {
|
|
||||||
name = new char[len + 1];
|
|
||||||
//ITH_MEMSET_HEAP(name, 0, sizeof(wchar_t) * (len + 1)); // jichi 9/26/2013: zero memory
|
|
||||||
strcpy(name, hook_name);
|
|
||||||
}
|
|
||||||
ClearHook();
|
|
||||||
InitHook(hp, name);
|
|
||||||
InsertHook();
|
|
||||||
if (name)
|
|
||||||
delete[] name;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TextHook::RecoverHook()
|
int TextHook::RecoverHook()
|
||||||
{
|
{
|
||||||
if (hp.address) {
|
if (hp.address) {
|
||||||
|
@ -26,7 +26,7 @@ void InitFilterTable();
|
|||||||
|
|
||||||
// jichi 9/25/2013: This class will be used by NtMapViewOfSectionfor
|
// jichi 9/25/2013: This class will be used by NtMapViewOfSectionfor
|
||||||
// interprocedure communication, where constructor/destructor will NOT work.
|
// interprocedure communication, where constructor/destructor will NOT work.
|
||||||
class TextHook : public Hook
|
class TextHook : public OldHook
|
||||||
{
|
{
|
||||||
int UnsafeInsertHookCode();
|
int UnsafeInsertHookCode();
|
||||||
DWORD UnsafeSend(DWORD dwDataBase, DWORD dwRetn);
|
DWORD UnsafeSend(DWORD dwDataBase, DWORD dwRetn);
|
||||||
@ -40,7 +40,6 @@ public:
|
|||||||
int RecoverHook();
|
int RecoverHook();
|
||||||
int RemoveHook();
|
int RemoveHook();
|
||||||
int ClearHook();
|
int ClearHook();
|
||||||
int ModifyHook(const HookParam&);
|
|
||||||
int SetHookName(LPCSTR name);
|
int SetHookName(LPCSTR name);
|
||||||
int GetLength(DWORD base, DWORD in); // jichi 12/25/2013: Return 0 if failed
|
int GetLength(DWORD base, DWORD in); // jichi 12/25/2013: Return 0 if failed
|
||||||
void CoolDown(); // jichi 9/28/2013: flush instruction cache on wine
|
void CoolDown(); // jichi 9/28/2013: flush instruction cache on wine
|
||||||
|
@ -41,8 +41,7 @@ FilterRange *filter = _filter;
|
|||||||
|
|
||||||
WCHAR hm_section[0x100];
|
WCHAR hm_section[0x100];
|
||||||
HANDLE hSection;
|
HANDLE hSection;
|
||||||
bool running,
|
bool running;
|
||||||
live = false;
|
|
||||||
int currentHook = 0,
|
int currentHook = 0,
|
||||||
user_hook_count = 0;
|
user_hook_count = 0;
|
||||||
DWORD trigger = 0;
|
DWORD trigger = 0;
|
||||||
@ -121,7 +120,6 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID unused)
|
|||||||
// jichi 10/2/2103: Cannot use __try in functions that require object unwinding
|
// jichi 10/2/2103: Cannot use __try in functions that require object unwinding
|
||||||
//ITH_TRY {
|
//ITH_TRY {
|
||||||
::running = false;
|
::running = false;
|
||||||
::live = false;
|
|
||||||
|
|
||||||
Engine::terminate();
|
Engine::terminate();
|
||||||
|
|
||||||
|
@ -56,13 +56,11 @@ DWORD WINAPI PipeManager(LPVOID unused)
|
|||||||
ReleaseMutex(pipeAcquisitionMutex);
|
ReleaseMutex(pipeAcquisitionMutex);
|
||||||
CloseHandle(pipeAcquisitionMutex);
|
CloseHandle(pipeAcquisitionMutex);
|
||||||
|
|
||||||
::live = true;
|
|
||||||
Engine::hijack();
|
Engine::hijack();
|
||||||
ConsoleOutput("vnrcli:WaitForPipe: pipe connected");
|
ConsoleOutput("vnrcli:WaitForPipe: pipe connected");
|
||||||
|
|
||||||
while (::running)
|
while (::running)
|
||||||
{
|
{
|
||||||
Sleep(STANDARD_WAIT);
|
|
||||||
if (!ReadFile(hostPipe, buffer, PIPE_BUFFER_SIZE / 2, &count, nullptr)) // Artikash 5/21/2018: why / 2? wchar_t?
|
if (!ReadFile(hostPipe, buffer, PIPE_BUFFER_SIZE / 2, &count, nullptr)) // Artikash 5/21/2018: why / 2? wchar_t?
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@ -72,18 +70,20 @@ DWORD WINAPI PipeManager(LPVOID unused)
|
|||||||
{
|
{
|
||||||
case HOST_COMMAND_NEW_HOOK:
|
case HOST_COMMAND_NEW_HOOK:
|
||||||
buffer[count] = 0;
|
buffer[count] = 0;
|
||||||
NewHook(*(HookParam *)(buffer + 4), (LPSTR)(buffer + 4 + sizeof(HookParam)), 0);
|
NewHook(*(HookParam *)(buffer + sizeof(DWORD)), // Hook parameter
|
||||||
|
(LPSTR)(buffer + 4 + sizeof(HookParam)), // Hook name
|
||||||
|
0
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case HOST_COMMAND_REMOVE_HOOK:
|
case HOST_COMMAND_REMOVE_HOOK:
|
||||||
{
|
{
|
||||||
DWORD removalAddress = *(DWORD *)(buffer + 4);
|
|
||||||
HANDLE hookRemovalEvent = OpenEventW(SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, ITH_REMOVEHOOK_EVENT);
|
HANDLE hookRemovalEvent = OpenEventW(SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, ITH_REMOVEHOOK_EVENT);
|
||||||
|
|
||||||
TextHook *in = hookman;
|
TextHook *in = hookman;
|
||||||
for (int i = 0; i < currentHook; in++)
|
for (int i = 0; i < currentHook; in++)
|
||||||
{
|
{
|
||||||
if (in->Address()) i++;
|
if (in->Address()) i++;
|
||||||
if (in->Address() == removalAddress)
|
if (in->Address() == *(DWORD *)(buffer + sizeof(DWORD))) // Hook address
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -102,8 +102,9 @@ DWORD WINAPI PipeManager(LPVOID unused)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CloseHandle(::hookPipe);
|
||||||
|
CloseHandle(hostPipe);
|
||||||
|
|
||||||
::live = false;
|
|
||||||
for (int i = 0, count = 0; count < ::currentHook; i++)
|
for (int i = 0, count = 0; count < ::currentHook; i++)
|
||||||
{
|
{
|
||||||
if (hookman[i].RemoveHook())
|
if (hookman[i].RemoveHook())
|
||||||
@ -111,44 +112,31 @@ DWORD WINAPI PipeManager(LPVOID unused)
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CloseHandle(::hookPipe);
|
|
||||||
CloseHandle(hostPipe);
|
|
||||||
}
|
}
|
||||||
FreeLibraryAndExitThread(::currentModule, 0);
|
FreeLibraryAndExitThread(::currentModule, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleOutput(LPCSTR text)
|
void ConsoleOutput(LPCSTR text)
|
||||||
{ // jichi 12/25/2013: Rewrite the implementation
|
|
||||||
if (!::live)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD textSize = strlen(text) + 1;
|
|
||||||
DWORD dataSize = textSize + 8;
|
|
||||||
BYTE *buffer = new BYTE[dataSize];
|
|
||||||
*(DWORD*)buffer = HOST_NOTIFICATION; //cmd
|
|
||||||
*(DWORD*)(buffer + 4) = HOST_NOTIFICATION_TEXT; //console
|
|
||||||
memcpy(buffer + 8, text, textSize);
|
|
||||||
DWORD unused;
|
|
||||||
WriteFile(::hookPipe, buffer, dataSize, &unused, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Artikash 7/3/2018: TODO: Finish using this in vnrhost instead of section to deliver hook name
|
|
||||||
void NotifyHookInsert(HookParam hp, LPCSTR name)
|
|
||||||
{
|
{
|
||||||
if (!::live)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
BYTE buffer[PIPE_BUFFER_SIZE];
|
BYTE buffer[PIPE_BUFFER_SIZE];
|
||||||
*(DWORD*)buffer = HOST_NOTIFICATION;
|
*(DWORD*)buffer = HOST_NOTIFICATION;
|
||||||
*(DWORD*)(buffer + 4) = HOST_NOTIFICATION_NEWHOOK;
|
*(DWORD*)(buffer + sizeof(DWORD)) = HOST_NOTIFICATION_TEXT;
|
||||||
*(HookParam*)(buffer + 8) = hp;
|
strcpy((char*)buffer + sizeof(DWORD) * 2, text);
|
||||||
strcpy((char*)buffer + 8 + sizeof(HookParam), name);
|
|
||||||
DWORD unused;
|
DWORD unused;
|
||||||
WriteFile(::hookPipe, buffer, strlen(name) + 8 + sizeof(HookParam), &unused, nullptr);
|
WriteFile(::hookPipe, buffer, strlen(text) + sizeof(DWORD) * 2, &unused, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Artikash 7/3/2018: TODO: Finish using this in vnrhost instead of section to deliver hook info
|
||||||
|
void NotifyHookInsert(HookParam hp, LPCSTR name)
|
||||||
|
{
|
||||||
|
BYTE buffer[PIPE_BUFFER_SIZE];
|
||||||
|
*(DWORD*)buffer = HOST_NOTIFICATION;
|
||||||
|
*(DWORD*)(buffer + sizeof(DWORD)) = HOST_NOTIFICATION_NEWHOOK;
|
||||||
|
*(HookParam*)(buffer + sizeof(DWORD) * 2) = hp;
|
||||||
|
strcpy((char*)buffer + sizeof(DWORD) * 2 + sizeof(HookParam), name);
|
||||||
|
DWORD unused;
|
||||||
|
WriteFile(::hookPipe, buffer, strlen(name) + sizeof(DWORD) * 2 + sizeof(HookParam), &unused, nullptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user