Hook DLL 中的函数
#define MakePtr( cast, ptr, addValue )( cast )( ( DWORD )( ptr ) + ( DWORD )( addValue ) ) void *InterceptDllCall( HMODULE hModule, char *szDllName, char *szFunctionName, DWORD pNewFunction ) { PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pNTHeader; PIMAGE_IMPORT_DESCRIPTOR pImportDesc; PIMAGE_THUNK_DATA pThunk; DWORD dwOldProtect; DWORD dwOldProtect2; void *pOldFunction; if( !( pOldFunction = GetProcAddress( GetModuleHandle( szDllName ), szFunctionName ) ) ) return 0; pDosHeader = ( PIMAGE_DOS_HEADER )hModule; if( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE ) return( NULL ); pNTHeader = MakePtr( PIMAGE_NT_HEADERS, pDosHeader, pDosHeader->e_lfanew ); if( pNTHeader->Signature != IMAGE_NT_SIGNATURE || ( pImportDesc = MakePtr( PIMAGE_IMPORT_DESCRIPTOR, pDosHeader, pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress ) ) == ( PIMAGE_IMPORT_DESCRIPTOR )pNTHeader ) return( NULL ); while( pImportDesc->Name ) { char *szModuleName = MakePtr( char *, pDosHeader, pImportDesc->Name ); if( !stricmp( szModuleName, szDllName ) ) break; pImportDesc++; } if( pImportDesc->Name == NULL ) return( NULL ); pThunk = MakePtr( PIMAGE_THUNK_DATA, pDosHeader, pImportDesc->FirstThunk ); while( pThunk->u1.Function ) { if( pThunk->u1.Function == ( DWORD )pOldFunction ) { VirtualProtect( ( void * )&pThunk->u1.Function, sizeof( DWORD ), PAGE_EXECUTE_READWRITE, &dwOldProtect ); pThunk->u1.Function = pNewFunction; VirtualProtect( ( void * )&pThunk->u1.Function, sizeof( DWORD ), dwOldProtect, &dwOldProtect2 ); return( pOldFunction ); } pThunk++; } return( NULL ); }用法: 例如Hook MessageBoxA 函数 首先建立一个DLL工程 自定义一个和MesageBoxA参数和返回值一样的函数
int WINAPI sysMessageBox( HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption, UINT uType) { MessageBox(0,"From hook ed MessegeBoxA",0,0); return(MessageBox(hWnd,lpText,lpCaption, uType)); }然后调用如下:
InterceptDllCall(GetModuleHandle(NULL ) ,"User32.dll" ,"MessageBoxA" ,(DWORD)&sysMessageBox );Hook类的成员函数
// set value to pointer fo a function template <typename T> inline void SetFuncPointerVal(T &func, DWORD val) { __asm { push eax push ebx mov eax, [val] mov ebx, [func] mov [ebx], eax pop ebx pop eax } } // oldFunc Old member function // newFunc New function which we want to redirect to it when calling old one // outOldFunc We return the pointer to oldFunc by this parameter #define HookMemberFunc(oldFunc, newFunc, outOldFunc) / { / DWORD _pold1st, _pold2nd; / __asm / { / mov _pold1st, offset oldFunc /*get the 1st call target address*/ / } / /*get the 2nd jump target address*/ / memcpy(&_pold2nd, (char*)_pold1st+1, 4); / _pold2nd += 5 + _pold1st; / SetFuncPointerVal(outOldFunc, _pold2nd); /*get the 2nd jump address as function pointer and return it*// DWORD _pnew; / /* then we overwrite the 2nd jump address with the function of ourselves*// __asm { mov _pnew, offset newFunc } / _pnew -= (DWORD)_pold1st + 5; / DWORD _dwOldProtect, _dwOldProtect2; / VirtualProtect( ( char * )_pold1st + 1, 4, PAGE_EXECUTE_READWRITE, &_dwOldProtect ); / memcpy((char*)_pold1st+1, &_pnew, 4); / VirtualProtect( ( char * )_pold1st + 1, 4, _dwOldProtect, &_dwOldProtect2 ); / }用法示例如下:
class Base; typedef void (Base::*AOut)(); AOut func; class Base { public: virtual void Output() = 0; virtual void aaa() = 0; }; class A: public Base { public: void Output() { cout << "sdfsdf"; } void aaa() { cout << "aaa"; } }; void newOutput() { cout << "hooked" << endl; A *pa; __asm { mov [pa], ecx } (pa->*func)(); } int _tmain(int argc, _TCHAR* argv[]) { HookMemberFunc(A::Output, newOutput, func); Base *a = new A(); a->aaa(); a->Output(); // 此时, 这行语句将会调用newOutput (a->*func)(); // 这才是调用原来的A::Output ::LoadLibrary("apihook.dll"); MessageBox(NULL, "sdf", "sdf", MB_OK); return 0; }
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2305
- 用户1336
- 访客11455432
每日一句
Talent without working hard is nothing.
没有努力,天份不代表什么。
没有努力,天份不代表什么。
MySQL 数据库优化
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
免ROOT实现模拟点击任意位置
Mobaxterm终端神器
CreateProcessW要注意的细节问题
Autonomous NAT Traversal
【教程】win10 彻底卸载edge浏览器
eclipse工程基于Xposed的一个简单Hook
排名前5的开源在线机器学习
Mac OS最简单及(Karabiner)快捷键设置
发一款C++编写的麻将
VMware NAT端口映射外网访问虚拟机linux
独家发布最新可用My-AutoPost——wordpress 采集器
新会员