really finish rewrite. everything works (afaict). still messy but thats not new lol

This commit is contained in:
Akash Mozumdar 2018-06-02 14:29:32 -04:00
parent fb56457cdb
commit 337038d684
5 changed files with 61 additions and 772 deletions

View File

@ -325,14 +325,7 @@ void ClickButton(HWND hWnd, HWND h)
} }
else if (h == hwndClear) else if (h == hwndClear)
{ {
WCHAR pwcEntry[128] = {}; man->ClearCurrent();
DWORD dwId = ComboBox_GetCurSel(hwndCombo);
int len = ComboBox_GetLBText(hwndCombo, dwId, pwcEntry);
dwId = std::stoul(pwcEntry, NULL, 16);
if (dwId == 0)
man->ClearCurrent();
else
man->RemoveSingleThread(dwId);
} }
else if (h == hwndTop) else if (h == hwndTop)
{ {

View File

@ -7,7 +7,6 @@
# DEFINES += _CRT_NON_CONFORMING_SWPRINTFS # DEFINES += _CRT_NON_CONFORMING_SWPRINTFS
set(vnrhost_src set(vnrhost_src
avl_p.h
config.h config.h
hookman.h hookman.h
host.h host.h

View File

@ -1,588 +0,0 @@
#pragma once
// avl_p.h
// 8/23/2013 jichi
// Branch: ITH/AVL.h, rev 133
#include "config.h"
#include <cstring>
enum { STACK_SIZE = 32 };
//#ifndef ITH_STACK
//#define ITH_STACK
template<class T, int stack_size>
class MyStack
{
int index;
T s[stack_size];
public:
MyStack(): index(0)
{ ::memset(s, 0, sizeof(s)); } // jichi 9/21/2013: assume T is atomic type
T &back() { return s[index-1]; }
int size() { return index; }
void push_back(const T &e)
{
if (index < stack_size)
s[index++]=e;
}
void pop_back() { index--; }
T &operator[](int i) { return s[i]; }
};
//#endif // ITH_STACK
// jichi 9/22/2013: T must be a pointer type which can be deleted
template <class T, class D>
struct IHFSERVICE TreeNode
{
//typedef TreeNode<T, D> Self;
TreeNode() :
Left(nullptr), Right(nullptr), Parent(nullptr)
, rank(1)
, factor('\0'), reserve('\0')
//, key()
//, data()
{
::memset(&key, 0, sizeof(key)); // jcihi 9/26/2013: zero memory
::memset(&data, 0, sizeof(data)); // jcihi 9/26/2013: zero memory
}
TreeNode(const T &k, const D &d) :
Left(nullptr), Right(nullptr), Parent(nullptr)
, rank(1)
, factor('\0'), reserve('\0') // jichi 9/21/2013: zero reserve
, key(k)
, data(d)
{}
TreeNode *Successor()
{
TreeNode *Node,
*ParentNode;
Node = Right;
if (!Node) {
Node = this;
for (;;) {
ParentNode = Node->Parent;
if (!ParentNode)
return nullptr;
if (ParentNode->Left == Node)
break;
Node = ParentNode;
}
return ParentNode;
}
else
while (Node->Left)
Node = Node->Left;
return Node;
}
TreeNode *Predecessor()
{
TreeNode *Node,
*ParentNode;
Node = Left;
if (!Node) {
Node = this;
for(;;) {
ParentNode = Node->Parent;
if (!ParentNode)
return nullptr;
if (ParentNode->Right == Node)
break;
Node = ParentNode;
}
return ParentNode;
}
else
while (Node->Right)
Node = Node->Right;
return Node;
}
int height()
{
if (!this) // jichi 9/26/2013: what?!
return 0;
int l = Left->height(),
r = Right->height(),
f = factor;
if (l - r + f != 0)
__debugbreak();
f = l > r ? l : r;
return f + 1;
}
TreeNode *Left,
*Right,
*Parent;
unsigned short rank;
char factor,
reserve;
T key;
D data;
};
template<class T,class D>
struct NodePath
{
NodePath() { ::memset(this, 0, sizeof(NodePath)); } // jichi 11/30/2013: This is the original code in ITH
NodePath(TreeNode<T,D> *n, int f): Node(n), fact(f) {}
TreeNode<T,D> *Node;
union { char factor; int fact; };
};
template <class T, class D, class fComp, class fCopy, class fLength>
class AVLTree
{
protected:
TreeNode<T*, D> head;
fComp fCmp;
fCopy fCpy;
fLength fLen;
public:
// - Construction -
AVLTree() {}
virtual ~AVLTree() { DeleteAll(); }
// - Properties -
TreeNode<T*, D> *TreeRoot() const { return head.Left; }
// - Actions -
void DeleteAll()
{
while (head.Left)
DeleteRoot();
}
TreeNode<T*, D> *Insert(const T *key, const D &data)
{
if (head.Left) {
MyStack<TreeNode<T*, D> *,STACK_SIZE> path;
TreeNode<T*,D> *DownNode, *ParentNode, *BalanceNode, *TryNode, *NewNode; //P,T,S,Q
ParentNode = &head;
path.push_back(ParentNode);
char factor,f;
BalanceNode = DownNode = head.Left;
for (;;) { //The first part of AVL tree insert. Just do as binary tree insert routine and record some nodes.
factor = fCmp(key,DownNode->key);
if (factor == 0)
return DownNode; //Duplicate key. Return and do nothing.
TryNode = _FactorLink(DownNode, factor);
if (factor == -1)
path.push_back(DownNode);
if (TryNode) { //DownNode has a child.
if (TryNode->factor != 0) { //Keep track of unbalance node and its parent.
ParentNode = DownNode;
BalanceNode = TryNode;
}
DownNode = TryNode;
}
else
break; //Finished binary tree search;
}
while (path.size()) {
path.back()->rank++;
path.pop_back();
}
size_t sz = fLen(key) + 1;
T *new_key = new T[sz];
::memset(new_key, 0, sz * sizeof(T)); // jichi 9/26/2013: Zero memory
fCpy(new_key, key);
TryNode = new TreeNode<T*, D>(new_key, data);
_FactorLink(DownNode, factor) = TryNode;
TryNode->Parent = DownNode;
NewNode = TryNode;
//Finished binary tree insert. Next to do is to modify balance factors between
//BalanceNode and the new node.
TreeNode<T*, D> *ModifyNode;
factor = fCmp(key, BalanceNode->key);
//factor=key<BalanceNode->key ? factor=-1:1; //Determine the balance factor at BalanceNode.
ModifyNode = DownNode = _FactorLink(BalanceNode,factor);
//ModifyNode will be the 1st child.
//DownNode will travel from here to the recent inserted node (TryNode).
while (DownNode != TryNode) { //Check if we reach the bottom.
f = fCmp(key,DownNode->key);
//f=_FactorCompare(key,DownNode->key);
DownNode->factor = f;
DownNode = _FactorLink(DownNode, f);//Modify balance factor and travels down.
}
//Finshed modifying balance factor.
//Next to do is check the tree if it's unbalance and recover balance.
if (BalanceNode->factor == 0) { //Tree has grown higher.
BalanceNode->factor = factor;
_IncreaseHeight(); //Modify balance factor and increase the height.
return NewNode;
}
if (BalanceNode->factor + factor == 0) { //Tree has gotten more balanced.
BalanceNode->factor = 0; //Set balance factor to 0.
return NewNode;
}
//Tree has gotten out of balance.
if (ModifyNode->factor == factor) //A node and its child has same factor. Single rotation.
DownNode = _SingleRotation(BalanceNode, ModifyNode, factor);
else //A node and its child has converse factor. Double rotation.
DownNode = _DoubleRotation(BalanceNode, ModifyNode, factor);
//Finished the balancing work. Set child field to the root of the new child tree.
if (BalanceNode == ParentNode->Left)
ParentNode->Left = DownNode;
else
ParentNode->Right = DownNode;
return NewNode;
}
else { //root null?
size_t sz = fLen(key) + 1;
T *new_key = new T[sz];
::memset(new_key, 0, sz * sizeof(T)); // jichi 9/26/2013: Zero memory
fCpy(new_key, key);
head.Left = new TreeNode<T *, D>(new_key, data);
head.rank++;
_IncreaseHeight();
return head.Left;
}
}
bool Delete(T *key)
{
NodePath<T*,D> PathNode;
MyStack<NodePath<T*,D>,STACK_SIZE> path; //Use to record a path to the destination node.
path.push_back(NodePath<T*,D>(&head,-1));
TreeNode<T*,D> *TryNode,*ChildNode,*BalanceNode,*SuccNode;
TryNode=head.Left;
char factor;
for (;;) { //Search for the
if (TryNode == 0)
return false; //Not found.
factor = fCmp(key, TryNode->key);
if (factor == 0)
break; //Key found, continue to delete.
//factor = _FactorCompare( key, TryNode->key );
path.push_back(NodePath<T*,D>(TryNode,factor));
TryNode = _FactorLink(TryNode,factor); //Move to left.
}
SuccNode = TryNode->Right; //Find a successor.
factor = 1;
if (SuccNode == 0) {
SuccNode = TryNode->Left;
factor = -1;
}
path.push_back(NodePath<T*,D>(TryNode,factor));
while (SuccNode) {
path.push_back(NodePath<T*,D>(SuccNode, -factor));
SuccNode = _FactorLink(SuccNode,-factor);
}
PathNode = path.back();
delete[] TryNode->key; // jichi 9/22/2013: key is supposed to be an array
TryNode->key = PathNode.Node->key; //Replace key and data field with the successor or predecessor.
PathNode.Node->key = nullptr;
TryNode->data = PathNode.Node->data;
path.pop_back();
_FactorLink(path.back().Node,path.back().factor) = _FactorLink(PathNode.Node,-PathNode.factor);
delete PathNode.Node; //Remove the successor from the tree and release memory.
PathNode = path.back();
for (int i=0; i<path.size(); i++)
if (path[i].factor==-1)
path[i].Node->rank--;
for (;;) { //Rebalance the tree along the path back to the root.
if (path.size()==1) {
_DecreaseHeight();
break;
}
BalanceNode = PathNode.Node;
if (BalanceNode->factor == 0) { // A balance node, just need to adjust the factor. Don't have to recurve since subtree height stays.
BalanceNode->factor=-PathNode.factor;
break;
}
if (BalanceNode->factor == PathNode.factor) { // Node get more balance. Subtree height decrease, need to recurve.
BalanceNode->factor = 0;
path.pop_back();
PathNode = path.back();
continue;
}
//Node get out of balance. Here raises 3 cases.
ChildNode = _FactorLink(BalanceNode, -PathNode.factor);
if (ChildNode->factor == 0) { // New case different to insert operation.
TryNode = _SingleRotation2( BalanceNode, ChildNode, BalanceNode->factor );
path.pop_back();
PathNode = path.back();
_FactorLink(PathNode.Node, PathNode.factor) = TryNode;
break;
}
else {
if (ChildNode->factor == BalanceNode->factor) // Analogous to insert operation case 1.
TryNode = _SingleRotation( BalanceNode, ChildNode, BalanceNode->factor );
else if (ChildNode->factor + BalanceNode->factor == 0) // Analogous to insert operation case 2.
TryNode = _DoubleRotation( BalanceNode, ChildNode, BalanceNode->factor );
}
path.pop_back(); //Recurse back along the path.
PathNode = path.back();
_FactorLink(PathNode.Node, PathNode.factor) = TryNode;
}
return true;
}
D &operator [](T *key)
{ return (Insert(key,D())->data); }
TreeNode<T*,D> *Search(const T *key)
{
TreeNode<T*,D> *Find=head.Left;
char k;
while (Find != 0) {//&&Find->key!=key)
k = fCmp(key, Find->key);
if (k == 0) break;
Find = _FactorLink(Find, k);
}
return Find;
}
TreeNode<T*,D> *SearchIndex(unsigned int rank)
{
unsigned int r = head.rank;
if (rank == -1)
return 0;
if (++rank>=r)
return 0;
TreeNode<T*,D> *n=&head;
while (r!=rank) {
if (rank>r) {
n=n->Right;
rank-=r;
r=n->rank;
} else {
n=n->Left;
r=n->rank;
}
}
return n;
}
TreeNode<T*,D> *Begin()
{
TreeNode<T*,D> *Node = head.Left;
if (Node)
while (Node->Left) Node = Node->Left;
return Node;
}
TreeNode<T*,D> *End()
{
TreeNode<T*,D> *Node=head.Left;
if (Node)
while (Node->Right) Node = Node->Right;
return Node;
}
unsigned int Count() const { return head.rank - 1; }
template <class Fn>
Fn TraverseTree(Fn &f)
{ return TraverseTreeNode(head.Left,f); }
protected:
bool DeleteRoot()
{
NodePath<T*,D> PathNode;
MyStack<NodePath<T*,D>,STACK_SIZE> path; //Use to record a path to the destination node.
path.push_back(NodePath<T*,D>(&head,-1));
TreeNode<T*,D> *TryNode,*ChildNode,*BalanceNode,*SuccNode;
TryNode=head.Left;
char factor;
SuccNode=TryNode->Right; //Find a successor.
factor=1;
if (SuccNode==0)
{
SuccNode=TryNode->Left;
factor=-1;
}
path.push_back(NodePath<T*,D>(TryNode,factor));
while (SuccNode) {
path.push_back(NodePath<T*,D>(SuccNode,-factor));
SuccNode=_FactorLink(SuccNode,-factor);
}
PathNode=path.back();
delete[] TryNode->key; // jichi 9/22/2013: key is supposed to be an array
TryNode->key=PathNode.Node->key; //Replace key and data field with the successor.
PathNode.Node->key = nullptr;
TryNode->data=PathNode.Node->data;
path.pop_back();
_FactorLink(path.back().Node,path.back().factor) = _FactorLink(PathNode.Node,-PathNode.factor);
delete PathNode.Node; //Remove the successor from the tree and release memory.
PathNode=path.back();
for (int i=0;i<path.size();i++)
if (path[i].factor==-1)
path[i].Node->rank--;
for (;;) { //Rebalance the tree along the path back to the root.
if (path.size() == 1) {
_DecreaseHeight();
break;
}
BalanceNode = PathNode.Node;
if (BalanceNode->factor == 0) { // A balance node, just need to adjust the factor. Don't have to recurse since subtree height not changed.
BalanceNode->factor=-PathNode.factor;
break;
}
if (BalanceNode->factor==PathNode.factor) { // Node get more balance. Subtree height decrease, need to recurse.
BalanceNode->factor=0;
path.pop_back();
PathNode=path.back();
continue;
}
//Node get out of balance. Here raises 3 cases.
ChildNode = _FactorLink(BalanceNode, -PathNode.factor);
if (ChildNode->factor == 0) { // New case different to insert operation.
TryNode = _SingleRotation2( BalanceNode, ChildNode, BalanceNode->factor );
path.pop_back();
PathNode=path.back();
_FactorLink(PathNode.Node, PathNode.factor) = TryNode;
break;
} else {
if (ChildNode->factor == BalanceNode->factor) // Analogous to insert operation case 1.
TryNode = _SingleRotation( BalanceNode, ChildNode, BalanceNode->factor );
else if (ChildNode->factor + BalanceNode->factor == 0) // Analogous to insert operation case 2.
TryNode = _DoubleRotation( BalanceNode, ChildNode, BalanceNode->factor );
}
path.pop_back(); // Recurve back along the path.
PathNode=path.back();
_FactorLink(PathNode.Node, PathNode.factor) = TryNode;
}
return true;
}
template <class Fn>
Fn TraverseTreeNode(TreeNode<T*,D> *Node, Fn &f)
{
if (Node) {
if (Node->Left)
TraverseTreeNode(Node->Left,f);
f(Node);
if (Node->Right)
TraverseTreeNode(Node->Right,f);
}
return f;
}
TreeNode<T*,D> *_SingleRotation(TreeNode<T*,D> *BalanceNode, TreeNode<T*,D> *ModifyNode, char factor)
{
TreeNode<T*,D> *Node = _FactorLink(ModifyNode, -factor);
_FactorLink(BalanceNode, factor) = Node;
_FactorLink(ModifyNode, -factor) = BalanceNode;
if (Node)
Node->Parent = BalanceNode;
ModifyNode->Parent = BalanceNode->Parent;
BalanceNode->Parent = ModifyNode;
BalanceNode->factor = ModifyNode->factor = 0; //After single rotation, set all factor of 3 node to 0.
if (factor == 1)
ModifyNode->rank += BalanceNode->rank;
else
BalanceNode->rank -= ModifyNode->rank;
return ModifyNode;
}
TreeNode<T*,D> *_SingleRotation2(TreeNode<T*,D> *BalanceNode, TreeNode<T*,D> *ModifyNode, char factor)
{
TreeNode<T*,D> *Node = _FactorLink(ModifyNode, -factor);
_FactorLink(BalanceNode, factor) = Node;
_FactorLink(ModifyNode, -factor) = BalanceNode;
if (Node) Node->Parent = BalanceNode;
ModifyNode->Parent = BalanceNode->Parent;
BalanceNode->Parent = ModifyNode;
ModifyNode->factor = -factor;
if (factor == 1)
ModifyNode->rank+=BalanceNode->rank;
else
BalanceNode->rank-=ModifyNode->rank;
return ModifyNode;
}
TreeNode<T*,D> *_DoubleRotation(TreeNode<T*,D> *BalanceNode, TreeNode<T*,D> *ModifyNode, char factor)
{
TreeNode<T*,D> *DownNode = _FactorLink(ModifyNode, -factor);
TreeNode<T*,D> *Node1, *Node2;
Node1 = _FactorLink(DownNode, factor);
Node2 = _FactorLink(DownNode, -factor);
_FactorLink(ModifyNode, -factor) = Node1;
_FactorLink(DownNode, factor) = ModifyNode;
_FactorLink(BalanceNode, factor) = Node2;
_FactorLink(DownNode, -factor) = BalanceNode;
if (Node1)
Node1->Parent = ModifyNode;
if (Node2)
Node2->Parent = BalanceNode;
DownNode->Parent = BalanceNode->Parent;
BalanceNode->Parent = DownNode;
ModifyNode->Parent = DownNode;
//Set factor according to the result.
if (DownNode->factor == factor) {
BalanceNode->factor = -factor;
ModifyNode->factor = 0;
} else if (DownNode->factor == 0)
BalanceNode->factor = ModifyNode->factor = 0;
else {
BalanceNode->factor = 0;
ModifyNode->factor = factor;
}
DownNode->factor = 0;
if (factor==1) {
ModifyNode->rank -= DownNode->rank;
DownNode->rank += BalanceNode->rank;
} else {
DownNode->rank += ModifyNode->rank;
BalanceNode->rank -= DownNode->rank;
}
return DownNode;
}
TreeNode<T*,D>* &__fastcall _FactorLink(TreeNode<T*,D> *Node, char factor)
//Private helper method to retrieve child according to factor.
//Return right child if factor>0 and left child otherwise.
{ return factor>0? Node->Right : Node->Left; }
void Check()
{
unsigned int k = (unsigned int)head.Right;
unsigned int t = head.Left->height();
if (k != t)
__debugbreak();
}
void _IncreaseHeight()
{
unsigned int k = (unsigned int)head.Right;
head.Right = (TreeNode<T*,D>*)++k;
}
void _DecreaseHeight()
{
unsigned int k = (unsigned int)head.Right;
head.Right = (TreeNode<T*,D>*)--k;
}
};
struct SCMP
{
char operator()(const char *s1,const char *s2)
{
int t = _stricmp(s1, s2);
return t == 0 ? 0 : t > 0 ? 1 :-1;
}
};
struct SCPY { char *operator()(char *dest, const char *src) { return strcpy(dest, src); } };
struct SLEN { int operator()(const char *str) { return strlen(str); } };
struct WCMP
{
char operator()(const wchar_t *s1,const wchar_t *s2)
{
int t =_wcsicmp(s1, s2);
return t == 0 ? 0 : t > 0 ? 1 : -1;
}
};
struct WCPY { wchar_t *operator()(wchar_t *dest, const wchar_t *src) { return wcscpy(dest,src); } };
struct WLEN { int operator()(const wchar_t *str) { return wcslen(str); } };
// EOF

View File

@ -79,76 +79,6 @@ DWORD GetHookName(LPSTR str, DWORD pid, DWORD hook_addr, DWORD max)
return len; return len;
} }
void ThreadTable::SetThread(DWORD num, TextThread *ptr)
{
int number = num;
if (number >= size) {
while (number >= size)
size <<= 1;
TextThread **temp;
//if (size < 0x10000) {
temp = new TextThread*[size];
if (size > used)
::memset(temp, 0, (size - used) * sizeof(TextThread *)); // jichi 9/21/2013: zero memory
memcpy(temp, storage, used * sizeof(TextThread *));
//}
delete[] storage;
storage = temp;
}
storage[number] = ptr;
if (ptr == nullptr) {
if (number == used - 1)
while (storage[used - 1] == 0)
used--;
} else if (number >= used)
used = number + 1;
}
TextThread *ThreadTable::FindThread(DWORD number)
{ return number <= (DWORD)used ? storage[number] : nullptr; }
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, //1, compare 2
-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, //3, compare 3
-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, //1, compare 2
-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, //7, compare 4
-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, //1, compare 2
-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, //3, compare 3
-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, //1, compare 2
-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
};
char TCmp::operator()(const ThreadParameter* t1, const ThreadParameter* t2)
//SSE speed up. Compare four integers in const time without branching.
//The AVL tree branching operation needs 2 bit of information.
//One bit for equality and one bit for "less than" or "greater than".
{
union{__m128 m0;__m128i i0;};
union{__m128 m1;__m128i i1;};
union{__m128 m2;__m128i i2;};
int k0,k1;
i1 = _mm_loadu_si128((const __m128i*)t1);
i2 = _mm_loadu_si128((const __m128i*)t2);
i0 = _mm_cmpgt_epi32(i1,i2);
k0 = _mm_movemask_ps(m0);
i1 = _mm_cmpeq_epi32(i1,i2);
k1 = _mm_movemask_ps(m1);
return sse_table_eq[k1*16+k0];
}
void TCpy::operator()(ThreadParameter* t1, const ThreadParameter* t2)
{ memcpy(t1,t2,sizeof(ThreadParameter)); }
int TLen::operator()(const ThreadParameter* t) { return 0; }
// Artikash 5/31/2018: required for unordered_map to work with struct key // Artikash 5/31/2018: required for unordered_map to work with struct key
bool operator==(const ThreadParameter& one, const ThreadParameter& two) bool operator==(const ThreadParameter& one, const ThreadParameter& two)
{ {
@ -168,14 +98,11 @@ HookManager::HookManager() :
, detach(nullptr) , detach(nullptr)
, hook(nullptr) , hook(nullptr)
, current_pid(0) , current_pid(0)
, thread_table(nullptr)
, destroy_event(nullptr)
, register_count(0)
, new_thread_number(0) , new_thread_number(0)
, threadTable() , threadTable()
, processRecordsByIds() , processRecordsByIds()
{ {
TextThread* consoleTextThread = threadTable[{0, -1UL, -1UL, -1UL}] = new TextThread(0, -1, -1, -1, threadTable.size()); TextThread* consoleTextThread = threadTable[{0, -1UL, -1UL, -1UL}] = new TextThread(0, -1, -1, -1, new_thread_number++);
consoleTextThread->Status() |= USING_UNICODE; consoleTextThread->Status() |= USING_UNICODE;
SetCurrent(consoleTextThread); SetCurrent(consoleTextThread);
} }
@ -226,6 +153,7 @@ void HookManager::SelectCurrent(DWORD num)
void HookManager::RemoveSingleHook(DWORD pid, DWORD addr) void HookManager::RemoveSingleHook(DWORD pid, DWORD addr)
{ {
HM_LOCK; HM_LOCK;
std::vector<ThreadParameter> removedThreads;
for (auto i : threadTable) for (auto i : threadTable)
{ {
if (i.second->PID() == pid && i.second->Addr() == addr) if (i.second->PID() == pid && i.second->Addr() == addr)
@ -235,56 +163,42 @@ void HookManager::RemoveSingleHook(DWORD pid, DWORD addr)
remove(i.second); remove(i.second);
} }
delete i.second; delete i.second;
threadTable[i.first] = nullptr; removedThreads.push_back(i.first);
} }
} }
SetCurrent(0); for (auto i : removedThreads)
}
void HookManager::RemoveSingleThread(DWORD number)
{
if (number == 0)
return;
HM_LOCK;
for (auto i : threadTable)
{ {
if (i.second->Number() == number) threadTable.erase(i);
{
if (remove)
{
remove(i.second);
}
delete i.second;
threadTable[i.first] = nullptr;
}
} }
SetCurrent(0); SelectCurrent(0);
} }
void HookManager::RemoveProcessContext(DWORD pid) void HookManager::RemoveProcessContext(DWORD pid)
{ {
HM_LOCK; HM_LOCK;
for (auto i : threadTable) std::vector<ThreadParameter> removedThreads;
{ for (auto i : threadTable)
if (i.second->PID() == pid) {
{ if (i.second->PID() == pid)
if (remove) {
{ if (remove)
remove(i.second); {
} remove(i.second);
delete i.second; }
threadTable[i.first] = nullptr; delete i.second;
} removedThreads.push_back(i.first);
} }
SetCurrent(0); }
for (auto i : removedThreads)
{
threadTable.erase(i);
}
SelectCurrent(0);
} }
void HookManager::RegisterThread(TextThread* it, DWORD num)
{ thread_table->SetThread(num, it); }
void HookManager::RegisterProcess(DWORD pid, HANDLE hostPipe) void HookManager::RegisterProcess(DWORD pid, HANDLE hostPipe)
{ {
HM_LOCK; HM_LOCK;
wchar_t str[0x40],
path[MAX_PATH];
ProcessRecord* record = processRecordsByIds[pid] = new ProcessRecord; ProcessRecord* record = processRecordsByIds[pid] = new ProcessRecord;
record->hostPipe = hostPipe; record->hostPipe = hostPipe;
@ -307,43 +221,42 @@ void HookManager::RegisterProcess(DWORD pid, HANDLE hostPipe)
void HookManager::UnRegisterProcess(DWORD pid) void HookManager::UnRegisterProcess(DWORD pid)
{ {
//HM_LOCK; HM_LOCK;
////ConsoleOutput("vnrhost:UnRegisterProcess: lock"); //ConsoleOutput("vnrhost:UnRegisterProcess: lock");
////EnterCriticalSection(&hmcs); //EnterCriticalSection(&hmcs);
//int i; ProcessRecord pr = *processRecordsByIds[pid];
//for (i = 0; i < MAX_REGISTER; i++) CloseHandle(pr.hookman_mutex);
// if(record[i].pid_register == pid) UnmapViewOfFile(pr.hookman_map);
// break; CloseHandle(pr.process_handle);
CloseHandle(pr.hookman_section);
//NtClose(text_pipes[i]);
//NtClose(cmd_pipes[i]);
//NtClose(recv_threads[i]);
//NtClose(record[i].hookman_mutex);
//if (i < MAX_REGISTER) { ////if (::ith_has_section)
// NtClose(text_pipes[i]); //NtUnmapViewOfSection(NtCurrentProcess(), record[i].hookman_map);
// NtClose(cmd_pipes[i]); ////else
// NtClose(recv_threads[i]); //// delete[] record[i].hookman_map;
CloseHandle(processRecordsByIds[pid]->hookman_mutex);
// //if (::ith_has_section) //NtClose(record[i].process_handle);
// NtUnmapViewOfSection(NtCurrentProcess(), record[i].hookman_map); //NtClose(record[i].hookman_section);
// //else
// // delete[] record[i].hookman_map;
// NtClose(record[i].process_handle); //for (; i < MAX_REGISTER; i++) {
// NtClose(record[i].hookman_section); // record[i] = record[i+1];
// text_pipes[i] = text_pipes[i+1];
// for (; i < MAX_REGISTER; i++) { // cmd_pipes[i] = cmd_pipes[i+1];
// record[i] = record[i+1]; // recv_threads[i] = recv_threads[i+1];
// text_pipes[i] = text_pipes[i+1]; // if (text_pipes[i] == 0)
// cmd_pipes[i] = cmd_pipes[i+1]; // break;
// recv_threads[i] = recv_threads[i+1]; //}
// if (text_pipes[i] == 0) //register_count--;
// break; //if (current_pid == pid)
// } // current_pid = register_count ? record[0].pid_register : 0;
// register_count--;
// if (current_pid == pid)
// current_pid = register_count ? record[0].pid_register : 0;
RemoveProcessContext(pid); RemoveProcessContext(pid);
//}
////pid_map->Clear(pid>>2); //pid_map->Clear(pid>>2);
//if (register_count == 1) //if (register_count == 1)
// NtSetEvent(destroy_event, 0); // NtSetEvent(destroy_event, 0);
@ -390,7 +303,7 @@ void HookManager::DispatchText(DWORD pid, const BYTE *text, DWORD hook, DWORD re
TextThread *it; TextThread *it;
if (!(it = threadTable[tp])) if (!(it = threadTable[tp]))
{ {
it = threadTable[tp] = new TextThread(pid, hook, retn, spl, threadTable.size()); it = threadTable[tp] = new TextThread(pid, hook, retn, spl, new_thread_number++);
if (create) if (create)
{ {
create(it); create(it);
@ -558,9 +471,6 @@ void GetCode(const HookParam &hp, LPWSTR buffer, DWORD pid)
ptr += swprintf(ptr, L"@%X", hp.address); ptr += swprintf(ptr, L"@%X", hp.address);
} }
// jichi 1/16/2015
bool HookManager::IsFull() const { return new_thread_number >= MAX_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);
@ -616,15 +526,7 @@ void MakeHookRelative(const ProcessRecord& pr, HookParam& hp)
void HookManager::AddThreadsToProfile(Profile& pf, const ProcessRecord& pr, DWORD pid) void HookManager::AddThreadsToProfile(Profile& pf, const ProcessRecord& pr, DWORD pid)
{ {
HM_LOCK; HM_LOCK;
for (int i = 0; i < thread_table->Used(); ++i) AddThreadToProfile(pf, pr, current);
{
TextThread* tt = thread_table->FindThread(i);
if (tt == NULL || tt->GetThreadParameter()->pid != pid)
continue;
//if (tt->Status() & CURRENT_SELECT || tt->Link() || tt->GetComment())
if (tt->Status() & CURRENT_SELECT)
AddThreadToProfile(pf, pr, tt);
}
} }
DWORD AddThreadToProfile(Profile& pf, const ProcessRecord& pr, TextThread* thread) DWORD AddThreadToProfile(Profile& pf, const ProcessRecord& pr, TextThread* thread)

View File

@ -4,7 +4,7 @@
// 8/23/2013 jichi // 8/23/2013 jichi
// Branch: ITH/HookManager.h, rev 133 // Branch: ITH/HookManager.h, rev 133
#include "host/avl_p.h" #include "config.h"
#include "host/textthread.h" #include "host/textthread.h"
#include "winmutex/winmutex.h" #include "winmutex/winmutex.h"
#include <unordered_map> #include <unordered_map>
@ -29,17 +29,6 @@ struct ProcessRecord {
HANDLE hostPipe; HANDLE hostPipe;
}; };
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); typedef DWORD (*ProcessEventCallback)(DWORD pid);
struct ThreadParameterHasher struct ThreadParameterHasher
@ -50,7 +39,7 @@ struct ThreadParameterHasher
} }
}; };
class IHFSERVICE HookManager : public AVLTree<ThreadParameter, DWORD, TCmp, TCpy, TLen> class IHFSERVICE HookManager
{ {
public: public:
HookManager(); HookManager();
@ -58,7 +47,6 @@ public:
// jichi 12/26/2013: remove virtual modifiers // jichi 12/26/2013: remove virtual modifiers
TextThread *FindSingle(DWORD number); TextThread *FindSingle(DWORD number);
ProcessRecord *GetProcessRecord(DWORD pid); ProcessRecord *GetProcessRecord(DWORD pid);
void RemoveSingleThread(DWORD number);
//void LockHookman(); //void LockHookman();
//void UnlockHookman(); //void UnlockHookman();
void ResetRepeatStatus(); void ResetRepeatStatus();
@ -71,7 +59,6 @@ public:
void DispatchText(DWORD pid, const BYTE *text, DWORD hook, DWORD retn, DWORD split, int len, bool space); void DispatchText(DWORD pid, const BYTE *text, DWORD hook, DWORD retn, DWORD split, int len, bool space);
void RemoveProcessContext(DWORD pid); // private void RemoveProcessContext(DWORD pid); // private
void RemoveSingleHook(DWORD pid, DWORD addr); void RemoveSingleHook(DWORD pid, DWORD addr);
void RegisterThread(TextThread*, DWORD); // private
void RegisterProcess(DWORD pid, HANDLE hostPipe); void RegisterProcess(DWORD pid, HANDLE hostPipe);
void UnRegisterProcess(DWORD pid); void UnRegisterProcess(DWORD pid);
//void SetName(DWORD); //void SetName(DWORD);
@ -123,7 +110,6 @@ private:
detach, detach,
hook; hook;
DWORD current_pid; DWORD current_pid;
ThreadTable *thread_table;
HANDLE destroy_event; HANDLE destroy_event;
ProcessRecord record[MAX_REGISTER + 1]; ProcessRecord record[MAX_REGISTER + 1];
HANDLE text_pipes[MAX_REGISTER + 1], HANDLE text_pipes[MAX_REGISTER + 1],
@ -132,9 +118,6 @@ private:
WORD register_count, WORD register_count,
new_thread_number; 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); void HookManager::AddThreadsToProfile(Profile& pf, const ProcessRecord& pr, DWORD pid);
}; };