hookman.h
5.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#pragma once
// hookman.h
// 8/23/2013 jichi
// Branch: ITH/HookManager.h, rev 133
#include "host/avl_p.h"
#include "host/textthread.h"
#include "winmutex/winmutex.h"
namespace pugi {
class xml_node;
}
class Profile;
enum { MAX_REGISTER = 0xf };
enum { MAX_PREV_REPEAT_LENGTH = 0x20 };
struct ProcessRecord {
DWORD pid_register;
DWORD hookman_register;
DWORD module_register;
//DWORD engine_register; // jichi 10/19/2014: removed
HANDLE process_handle;
HANDLE hookman_mutex;
HANDLE hookman_section;
LPVOID hookman_map;
};
class ThreadTable : public MyVector<TextThread *, 0x40>
{
public:
virtual void SetThread(DWORD number, TextThread *ptr);
virtual TextThread *FindThread(DWORD number);
};
struct IHFSERVICE TCmp { char operator()(const ThreadParameter *t1, const ThreadParameter *t2); };
struct IHFSERVICE TCpy { void operator()(ThreadParameter *t1, const ThreadParameter *t2); };
struct IHFSERVICE TLen { int operator()(const ThreadParameter *t); };
typedef DWORD (*ProcessEventCallback)(DWORD pid);
class IHFSERVICE HookManager : public AVLTree<ThreadParameter, DWORD, TCmp, TCpy, TLen>
{
public:
HookManager();
~HookManager();
// jichi 12/26/2013: remove virtual modifiers
TextThread *FindSingle(DWORD pid, DWORD hook, DWORD retn, DWORD split);
TextThread *FindSingle(DWORD number);
ProcessRecord *GetProcessRecord(DWORD pid);
DWORD GetProcessIDByPath(LPCWSTR str); // private
void RemoveSingleThread(DWORD number);
//void LockHookman();
//void UnlockHookman();
void ResetRepeatStatus();
void ClearCurrent();
void AddLink(WORD from, WORD to);
void UnLink(WORD from);
void UnLinkAll(WORD from);
void SelectCurrent(DWORD num);
void DetachProcess(DWORD pid);
void SetCurrent(TextThread *it);
void AddConsoleOutput(LPCWSTR text);
// jichi 10/27/2013: Add const; add space.
void DispatchText(DWORD pid, const BYTE *text, DWORD hook, DWORD retn, DWORD split, int len, bool space);
void ClearText(DWORD pid, DWORD hook, DWORD retn, DWORD split); // private
void RemoveProcessContext(DWORD pid); // private
void RemoveSingleHook(DWORD pid, DWORD addr);
void RegisterThread(TextThread*, DWORD); // private
void RegisterPipe(HANDLE text, HANDLE cmd, HANDLE thread);
void RegisterProcess(DWORD pid, DWORD hookman, DWORD module);
void UnRegisterProcess(DWORD pid);
//void SetName(DWORD);
DWORD GetCurrentPID(); // private
HANDLE GetCmdHandleByPID(DWORD pid);
ConsoleCallback RegisterConsoleCallback(ConsoleCallback cf)
{ return (ConsoleCallback)_InterlockedExchange((long*)&console,(long)cf); }
ConsoleWCallback RegisterConsoleWCallback(ConsoleWCallback cf)
{ return (ConsoleWCallback)_InterlockedExchange((long*)&wconsole,(long)cf); }
ThreadEventCallback RegisterThreadCreateCallback(ThreadEventCallback cf)
{ return (ThreadEventCallback)_InterlockedExchange((long*)&create,(long)cf); }
ThreadEventCallback RegisterThreadRemoveCallback(ThreadEventCallback cf)
{ return (ThreadEventCallback)_InterlockedExchange((long*)&remove,(long)cf); }
ThreadEventCallback RegisterThreadResetCallback(ThreadEventCallback cf)
{ return (ThreadEventCallback)_InterlockedExchange((long*)&reset,(long)cf); }
ThreadEventCallback RegisterAddRemoveLinkCallback(ThreadEventCallback cf)
{ return (ThreadEventCallback)_InterlockedExchange((long*)&addRemoveLink, (long)cf); }
ProcessEventCallback RegisterProcessAttachCallback(ProcessEventCallback cf)
{ return (ProcessEventCallback)_InterlockedExchange((long*)&attach,(long)cf); }
ProcessEventCallback RegisterProcessDetachCallback(ProcessEventCallback cf)
{ return (ProcessEventCallback)_InterlockedExchange((long*)&detach,(long)cf); }
ProcessEventCallback RegisterProcessNewHookCallback(ProcessEventCallback cf)
{ return (ProcessEventCallback)_InterlockedExchange((long*)&hook,(long)cf); }
ProcessEventCallback ProcessNewHook() { return hook; }
TextThread *GetCurrentThread() { return current; } // private
ProcessRecord *Records() { return record; } // private
ThreadTable *Table() { return thread_table; } // private
//DWORD& SplitTime() { return split_time; }
//DWORD& RepeatCount() { return repeat_count; }
//DWORD& CyclicRemove() { return cyclic_remove; }
//DWORD& GlobalFilter() { return global_filter; }
void ConsoleOutput(LPCSTR text) { if (console) console(text); } // not thread safe
void ConsoleOutputW(LPCWSTR text) { if (wconsole) wconsole(text); } // not thread safe
void OnThreadCreate(pugi::xml_node profile_node, TextThread* thread);
void GetProfile(DWORD pid, pugi::xml_node profile_node);
private:
typedef win_mutex<CRITICAL_SECTION> mutex_type;
mutex_type hmcs;
TextThread *current;
ConsoleCallback console; // jichi 12/25/2013: add console output callback
ConsoleWCallback wconsole;
ThreadEventCallback create,
remove,
reset,
addRemoveLink;
ProcessEventCallback attach,
detach,
hook;
DWORD current_pid;
ThreadTable *thread_table;
HANDLE destroy_event;
ProcessRecord record[MAX_REGISTER + 1];
HANDLE text_pipes[MAX_REGISTER + 1],
cmd_pipes[MAX_REGISTER + 1],
recv_threads[MAX_REGISTER + 1];
WORD register_count,
new_thread_number;
// jichi 1/16/2014: Stop adding new threads when full
bool IsFull() const; // { return new_thread_number >= MAX_HOOK; }
bool IsEmpty() const { return !new_thread_number; }
void HookManager::AddThreadsToProfile(Profile& pf, const ProcessRecord& pr, DWORD pid);
};
// EOF