Author:bzhkl
That is original realized on code of russia ,The advantage of code is:
1. Don't first use hook on agency's function,be Called again ,Later hook again,Otherwise multithreading go wrong.
2. Non hard code ,The structure is better.
bool AfxHookCode(void* TargetProc, void* NewProc,void ** l_OldProc, int bytescopy = 5)
{
DWORD dwOldProtect;
::VirtualProtect((LPVOID)TargetProc, bytescopy, PAGE_EXECUTE_READWRITE, &dwOldProtect);
*l_OldProc = new unsigned char[bytescopy+5]; //Apple for Space for instruction of be covered to copyed.
memcpy(*l_OldProc, TargetProc, bytescopy); // Decided beforehandl to save code of be broken
*((unsigned char*)(*l_OldProc) + bytescopy) = 0xe9; // 我的内存的代码执行完 跳到原来的 代码 + 破坏的代码的长度 上去
//被破坏指令的长度 //E9 opcode长度 //算出偏移的OPCODE = 被HOOK函数地址的地址 + 破坏指令的长度 - 我分配内存的结束地址
*(unsigned int *)((unsigned char*)(*l_OldProc) +bytescopy + 1) = (unsigned int)(TargetProc) + bytescopy - ( (unsigned int)((*l_OldProc)) + 5 + bytescopy ) ; // 我内存代码跳到原来代码上的偏移
*(unsigned char*)TargetProc =(unsigned char)0xe9; //被HOOK的函数头改为jmp
//算出偏移的OPCODE = 代理函数地址 - 被HOOK函数地址
*(unsigned int*)((unsigned int)TargetProc +1) = (unsigned int)NewProc - ( (unsigned int)TargetProc + 5) ; //被HOOK的地方跳到我的新过程 接受过滤
::VirtualProtect((LPVOID)TargetProc, bytescopy, dwOldProtect, 0);
return true;
}
bool AfxUnHookCode(void* TargetAddress, void * l_SavedCode, unsigned int len)
{
DWORD dwOldProtect;
::VirtualProtect((LPVOID)TargetAddress, len, PAGE_EXECUTE_READWRITE, &dwOldProtect);
// Recover code of be broken
memcpy(TargetAddress, l_SavedCode, len);
::VirtualProtect((LPVOID)TargetAddress, len, dwOldProtect, 0);
return true;
}
unsigned int * OldProc;
typedef
int
(__stdcall * MYMESSAGEBOX) //用于调用自己分配内存处的代码强制转换
(
IN HWND hWnd,
IN LPCSTR lpText,
IN LPCSTR lpCaption,
IN UINT uType);
int
__stdcall // 这里不声明成stdcall的话 编译器认为是C声明方式 要自己平衡堆栈
MyMessageBox(
IN HWND hWnd,
IN LPCSTR lpText,
IN LPCSTR lpCaption,
IN UINT uType)
{
// 这里可以执行一些过滤行为 比如改变参数 或者 直接模拟返回正确的结果
if ( strcmp(lpText, "sample") == 0)
{
printf("filter");
return 1;
}
//强制转换成API函数类型 调用原来的函数
return ( (MYMESSAGEBOX) OldProc)(hWnd, lpText, lpCaption, uType);
}
int main()
{
MessageBox(0, "sample", "caption", MB_OK); //正常调用MSG
// 这里一定要传地址变量的地址 直接传地址的话 地址变量是一份拷贝 根本不能保存分配的内存的地址(在我看来 指针就是地址变量)
//当初写的时候调了3遍才知道这个原因- -
AfxHookCode((void*)MessageBox, (void*)MyMessageBox, (void**)&OldProc, 5);
MessageBox(0, "sample", "caption", MB_OK); //Be filtered
AfxUnHookCode((void*)MessageBox, OldProc, 5); // Recover code of be hook
getchar();
return 0;
}
{
DWORD dwOldProtect;
::VirtualProtect((LPVOID)TargetProc, bytescopy, PAGE_EXECUTE_READWRITE, &dwOldProtect);
*l_OldProc = new unsigned char[bytescopy+5]; //Apple for Space for instruction of be covered to copyed.
memcpy(*l_OldProc, TargetProc, bytescopy); // Decided beforehandl to save code of be broken
*((unsigned char*)(*l_OldProc) + bytescopy) = 0xe9; // 我的内存的代码执行完 跳到原来的 代码 + 破坏的代码的长度 上去
//被破坏指令的长度 //E9 opcode长度 //算出偏移的OPCODE = 被HOOK函数地址的地址 + 破坏指令的长度 - 我分配内存的结束地址
*(unsigned int *)((unsigned char*)(*l_OldProc) +bytescopy + 1) = (unsigned int)(TargetProc) + bytescopy - ( (unsigned int)((*l_OldProc)) + 5 + bytescopy ) ; // 我内存代码跳到原来代码上的偏移
*(unsigned char*)TargetProc =(unsigned char)0xe9; //被HOOK的函数头改为jmp
//算出偏移的OPCODE = 代理函数地址 - 被HOOK函数地址
*(unsigned int*)((unsigned int)TargetProc +1) = (unsigned int)NewProc - ( (unsigned int)TargetProc + 5) ; //被HOOK的地方跳到我的新过程 接受过滤
::VirtualProtect((LPVOID)TargetProc, bytescopy, dwOldProtect, 0);
return true;
}
bool AfxUnHookCode(void* TargetAddress, void * l_SavedCode, unsigned int len)
{
DWORD dwOldProtect;
::VirtualProtect((LPVOID)TargetAddress, len, PAGE_EXECUTE_READWRITE, &dwOldProtect);
// Recover code of be broken
memcpy(TargetAddress, l_SavedCode, len);
::VirtualProtect((LPVOID)TargetAddress, len, dwOldProtect, 0);
return true;
}
unsigned int * OldProc;
typedef
int
(__stdcall * MYMESSAGEBOX) //用于调用自己分配内存处的代码强制转换
(
IN HWND hWnd,
IN LPCSTR lpText,
IN LPCSTR lpCaption,
IN UINT uType);
int
__stdcall // 这里不声明成stdcall的话 编译器认为是C声明方式 要自己平衡堆栈
MyMessageBox(
IN HWND hWnd,
IN LPCSTR lpText,
IN LPCSTR lpCaption,
IN UINT uType)
{
// 这里可以执行一些过滤行为 比如改变参数 或者 直接模拟返回正确的结果
if ( strcmp(lpText, "sample") == 0)
{
printf("filter");
return 1;
}
//强制转换成API函数类型 调用原来的函数
return ( (MYMESSAGEBOX) OldProc)(hWnd, lpText, lpCaption, uType);
}
int main()
{
MessageBox(0, "sample", "caption", MB_OK); //正常调用MSG
// 这里一定要传地址变量的地址 直接传地址的话 地址变量是一份拷贝 根本不能保存分配的内存的地址(在我看来 指针就是地址变量)
//当初写的时候调了3遍才知道这个原因- -
AfxHookCode((void*)MessageBox, (void*)MyMessageBox, (void**)&OldProc, 5);
MessageBox(0, "sample", "caption", MB_OK); //Be filtered
AfxUnHookCode((void*)MessageBox, OldProc, 5); // Recover code of be hook
getchar();
return 0;
}
No comments:
Post a Comment