HOOK API(三)—— HOOK 所有程序的 MessageBox
HOOK API(三)
—— HOOK 所有程序的 MessageBox
0x00 前言
本实例要实现HOOK MessageBox,包括MessageBoxA和MessageBoxW,其实现细节与HOOK API(二)中介绍的基本类似,唯一不同的是,本实例要实现对所有程序的HOOK MessageBox,即无论系统中哪一个程序调用MessageBox都会被重定向到我们实现的新的API中。
之前说过,在Windows中,每个进程都有自己的地址空间,进程不能调用别的进程中的函数。这里涉及到一个关键,如何让我们实现的新的API调用地址存在于所有进程的地址空间中呢?如果这无法实现的话,其他进程就无法调用到我们所实现的API。这里涉及到的关键就是,如何将我们的代码注入到别的进程中。
这里有一个实现手段,就是将我们实现的代码随着系统钩子注入到目标进程中,我们在HOOK API (一)中讲过鼠标钩子,鼠标钩子一旦启动,就会存在于每个当前运行的进程中,实现对屏幕坐标的定位。还有一个关键就是,这样的钩子需要注入到多个目标进程中,那么这就要在动态链接库(DLL)中实现,然后启动某一主调进程将这样一个DLL注入到目标进程中,从而实现HOOK API。
本实例介绍如何将实现了HOOK MessageBox的DLL注入到所有进程中的过程。
0x01 HOOK DLL的实现
建立一个MFC DLL工程
由于被实例的DLL用于MFC框架,因此创建的是MFC DLL,需要的话,也可以建立其他类型的DLL工程。

鼠标钩子回调函数
我们的DLL要跟随鼠标钩子注入到目标进程中,而鼠标钩子是系统钩子,我们需要实现其钩子回调函数。
|
/* 鼠标钩子子过程,目的是加载本dll到使用鼠标的程序中。 鼠标钩子的作用:当鼠标在某程序窗口中时,就会加载我们这个dll。 */ LRESULT CALLBACK MouseProc( int nCode, // hook code WPARAM wParam,// message identifier LPARAM lParam // mouse coordinates ) { return CallNextHookEx(hhk,nCode,wParam,lParam); } |
安装鼠标钩子
调用SetWindowsHookEx() API可以安装鼠标钩子,其中SetWindowsHookEx() 原型如下:
HHOOK SetWindowsHookEx( int idHook,HOOKPROC lpfn, INSTANCE hMod,DWORD dwThreadId )
参数:
idHook表示钩子类型,它是和钩子函数类型一一对应的。比如,WH_KEYBOARD表示安装的是键盘钩子,WH_MOUSE表示是鼠标钩子等等。
Lpfn是钩子函数的地址。
HMod是钩子函数所在的实例的句柄。对于线程钩子,该参数为NULL;对于系统钩子,该参数为钩子函数所在的DLL句柄。
dwThreadId 指定钩子所监视的线程的线程号。对于全局钩子,该参数为NULL。
返回值:
SetWindowsHookEx返回所安装的钩子句柄。
|
// // 安装钩子 // BOOL WINAPI StartHook(HWND hWnd) { g_hWnd = hWnd; hhk = ::SetWindowsHookEx(WH_MOUSE,MouseProc,g_hInstance,0); if (hhk == NULL) { return FALSE; } else { return TRUE; } } |
卸载鼠标钩子
|
// // 卸载钩子 // BOOL WINAPI StopHook() { /* 卸载钩子时,一定要记得恢复原API入口。 这里恢复的只是主程序的原API入口,其它程序的API入口还没有被恢复。 因此我们必须处理dll退出过程,即在函数ExitInstance()中,调用恢复 API入口的函数HookOff(),只有这样,其它程序再次调用原API时,才不 会发生错误。 当我们HOOK所有程序的某个系统API时,千万要注意在ExitInstance()中 调用HookOff()!!!!! */ HookOff(); if (hhk!=NULL) { UnhookWindowsHookEx(hhk); FreeLibrary(g_hInstance); } return TRUE; } |
导出我们的安装和卸载函数
.def内容如下:
将StarHook和StopHook函数导出,一遍主程序安装和卸载HOOK程序。
|
; HookDll.def : 声明 DLL 的模块参数。 LIBRARY "HookMessageBox" EXPORTS ; 此处可以是显式导出 StartHook StopHook |
MFC DLL的InitInstance()函数
|
/* dll程序入口,当程序加载dll时,会执行InitInstance() */ BOOL CHookDllApp::InitInstance() { CWinApp::InitInstance(); g_hInstance = AfxGetInstanceHandle();// 获取当前DLL实例句柄 AdjustPrivileges(); // 提高权限 DWORD dwPid = ::GetCurrentProcessId(); hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,0,dwPid); if (hProcess == NULL) { CString str; str.Format(_T("OpenProcess fail, and error code = %d"),GetLastError()); AfxMessageBox(str); return FALSE; } Inject(); // 开始注入 return TRUE; } |
MFC DLL的ExitInstance()函数
|
int CHookDllApp::ExitInstance() { /* dll退出时,一定要记得恢复原API的入口!!! 我们编写的dll会被注入到所有目标进程中,若dll退出时,没有恢复原API入口, 那么被挂钩的程序再次调用该API时,会发生错误。 因为我们的dll程序已经退出,但原API的入口仍为我们所定义的API的入口,这 时被挂钩的程序无法找到我们实现的API,然而原API的地址又没有被恢复,也就 调用不到原API,这时程序自然会发生崩溃了。 */ HookOff(); return CWinApp::ExitInstance(); } |
HOOK API实现
- 注入函数,保存新的,原来的API的入口
该函数的主要功能是保存新的和原来的API入口,并且在最后启动HOOK。需要注意的是,这个函数只能被调用一次,即只能进行一次注入操作。
|
/* 注入 */ void Inject() { if ( TRUE == bIsInJected) { return; } bIsInJected = TRUE; // 保证只调用一次 // // 获取函数 // HMODULE hmodle = ::LoadLibrary(_T("User32.dll")); oldMsgBoxA = (TypeMsgBoxA) ::GetProcAddress(hmodle,"MessageBoxA"); pfMsgBoxA = (FARPROC)oldMsgBoxA; oldMsgBoxW = (TypeMsgBoxW) ::GetProcAddress(hmodle,"MessageBoxW"); pfMsgBoxW = (FARPROC)oldMsgBoxW; if (pfMsgBoxA == NULL) { AfxMessageBox(_T("获取 MessageBoxA 函数失败")); return; } if ( pfMsgBoxW == NULL) { AfxMessageBox(_T("获取 MessageBoxW 函数失败")); return; } // // 保存原API地址 // _asm { lea edi,oldCodeA // 取数组基地址 mov esi,pfMsgBoxA // API地址 cld // 设置方向 mov ecx,CODE_LENGTH rep movsb } _asm { lea edi,oldCodeW mov esi,pfMsgBoxW cld mov ecx,CODE_LENGTH rep movsb } // // 将新地址复制到入口 // newCodeA[0] = newCodeW [0] = 0xe9; // jmp 指定代码 _asm { lea eax,MyMessageBoxA // 新API地址 mov ebx,pfMsgBoxA // 原API地址 sub eax,ebx sub eax,CODE_LENGTH // 跳转地址 = 新API地址 - 原API地址 - 指令长度 mov dword ptr [newCodeA+1],eax // eax 32bit = 4 BYTE } _asm { lea eax,MyMessageBoxW mov ebx,pfMsgBoxW sub eax,ebx sub eax,CODE_LENGTH mov dword ptr [newCodeW + 1],eax } HookOn(); // 开始HOOK } |
- 写内存函数
该函数主要完成向进程控制块写写指令的任务。供HookOn()和HookOff()调用,用来将原API入口,或新的API入口写入到进程的地址空间中。
|
/* 将长度为length的pcode写入到地址lpAddress中。 */ void WriteMemory(LPVOID lpAddress,BYTE* pcode,int length) { // // 保证本进程句柄不为NULL // ASSERT(hProcess != NULL); DWORD dwTemp,dwOldProtect,dwRet,dwWrited; // // 修改API入口前length个字节为 jmp xxxx // VirtualProtectEx(hProcess,lpAddress,length,PAGE_READWRITE,&dwOldProtect); dwRet = WriteProcessMemory(hProcess,lpAddress,pcode,length,&dwWrited); if ( 0 == dwRet || 0 == dwWrited) { AfxMessageBox(_T("哭!!写入失败")); } VirtualProtectEx(hProcess,lpAddress,length,dwOldProtect,&dwTemp); } |
- 用新API地址替换原API地址
|
/* 用新API地址替换原API地址 */ void HookOn() { ASSERT(hProcess != NULL); DWORD dwTemp,dwOldProtect,dwRet,dwWrited; WriteMemory(pfMsgBoxA,newCodeA,CODE_LENGTH); WriteMemory(pfMsgBoxW,newCodeW,CODE_LENGTH); } |
- 恢复原API地址
|
/* 恢复原API地址 */ void HookOff() { ASSERT(hProcess != NULL); DWORD dwTemp,dwOldProtect,dwRet,dwWrited; WriteMemory(pfMsgBoxA,oldCodeA,CODE_LENGTH); WriteMemory(pfMsgBoxW,oldCodeW,CODE_LENGTH); } |
- 新API定义
|
/* 自己用于替换的API */ int WINAPI MyMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCation,UINT uType) { int nRet = 0; HookOff(); nRet = ::MessageBoxA(hWnd,"哈哈 ^_^,MessageBoxA 被 HOOK 咯",lpCation,uType); nRet = ::MessageBoxA(hWnd,lpText,lpCation,uType); HookOn(); return nRet; } int WINAPI MyMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCation,UINT uType) { int nRet = 0; HookOff(); nRet = ::MessageBoxW(hWnd,_T("O(∩_∩)O哈哈~,MMessageBoxW 被 HOOK 咯"),lpCation,uType); nRet = ::MessageBoxW(hWnd,lpText,lpCation,uType); HookOn(); return nRet; } |
- 提升权限函数
这段代码并不是必须的,但有些时候会出现程序权限不足以获取进程句柄的情况,这个时候需要在代码执行前调用该函数来提高程序的权限。
|
/* 提升权限 */ bool AdjustPrivileges() { HANDLE hToken; TOKEN_PRIVILEGES tp; TOKEN_PRIVILEGES oldtp; DWORD dwSize=sizeof(TOKEN_PRIVILEGES); LUID luid; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED) return true; else return false; } if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { CloseHandle(hToken); return false; } ZeroMemory(&tp, sizeof(tp)); tp.PrivilegeCount=1; tp.Privileges[0].Luid=luid; tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED; /* Adjust Token Privileges */ if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) { CloseHandle(hToken); return false; } // close handles CloseHandle(hToken); return true; } |
0x02 HOOK 窗体实现

- StartHook
|
HINSTANCE g_hinstDll = NULL; // // 开始 HOOK // void CHookWindowDlg::OnBnClickedButtonStart() { // TODO: 在此添加控件通知处理程序代码 g_hinstDll = LoadLibrary(_T("HookDll.dll")); if ( NULL == g_hinstDll) { AfxMessageBox(_T("加载 HookDll.dll 失败")); } typedef BOOL (CALLBACK *HookStart)(HWND hwnd); HookStart hookStart = NULL; hookStart = (HookStart)::GetProcAddress(g_hinstDll,"StartHook"); if ( NULL == hookStart) { AfxMessageBox(_T("获取 StartHook 函数失败")); return; } bool ret = hookStart(m_hWnd); if (ret) { m_list.InsertItem(m_list.GetItemCount(),_T("启动钩子成功")); m_list.EnsureVisible(m_list.GetItemCount()-1,FALSE); } else { m_list.InsertItem(m_list.GetItemCount(),_T("启动钩子失败")); m_list.EnsureVisible(m_list.GetItemCount()-1,FALSE); } } |
- StopHook
|
// // 终止 HOOK // void CHookWindowDlg::OnBnClickedButtonStop() { // TODO: 在此添加控件通知处理程序代码 typedef BOOL (CALLBACK* HookStop)(); HookStop hookStop = NULL; if (NULL == g_hinstDll) // 一定要加这个判断,若不为空的话就不需要在重新加载,否则会是不同的实例 { g_hinstDll = LoadLibrary(_T("HookDll.dll")); if (g_hinstDll == NULL) { AfxMessageBox(_T("加载 HookDll.dll 失败")); return; } } hookStop = ::GetProcAddress(g_hinstDll,"StopHook"); if (hookStop == NULL) { AfxMessageBox(_T("获取 StopHook 失败")); FreeLibrary(g_hinstDll); g_hinstDll=NULL; return; } hookStop(); if (g_hinstDll!= NULL) { ::FreeLibrary(g_hinstDll); } m_list.InsertItem(m_list.GetItemCount(),_T("终止HOOK成功")); } |
- MessageBoxA
|
// MessageBoxA void CHookWindowDlg::OnBnClickedButtonMsga() { // TODO: 在此添加控件通知处理程序代码 MessageBoxA(m_hWnd,"这是正常的MessageBoxA...","哈哈",0); } |
- MessageBoxW
|
// MessageBoxW void CHookWindowDlg::OnBnClickedButtonMsgw() { // TODO: 在此添加控件通知处理程序代码 MessageBoxW(_T("这是正常的MessageBoxW..."),_T("呵呵"),0); } |
0x03 测试
本实例在自己实现的API中打印一句自己的话,然后再弹出原本的对话框。测试结果如下:
- 启动钩子

- 单击"MessageBoxA"按钮,调用MessageBoxA函数
可以看到,先弹出了我们自己的对话框,然后才弹出真正的对话框。


- 单击"MessageBoxW"按钮,调用MessageBoxW函数。
可以看到,先弹出我们的对话框,然后才弹出真正的对话框。


- 记事本的对话框也被HOOK了。
打开技术本,打开查找对话框,然后输入一个字符串,"查找一下",这个时候同样先弹出我们的对话框,然后才弹出原来的,找不到对话框。


0x04 附录——HOOK DLL关键源码
|
// HookDll.cpp : 定义 DLL 的初始化例程。 // #include "stdafx.h" #include "HookDll.h" #include <Windows.h> #ifdef _DEBUG #define new DEBUG_NEW #endif /* 全局共享变量 */ #pragma data_seg("Share") HWND g_hWnd = NULL ; // 主窗口句柄 HINSTANCE g_hInstance = NULL; // 本dll实例句柄 HHOOK hhk = NULL; // 鼠标钩子句柄 #pragma data_seg() #pragma comment(linker,"/section:Share,rws") HANDLE hProcess = NULL; // 当前进程 BOOL bIsInJected = FALSE; // 是否已注入标记 TCHAR* msgToMain = new TCHAR[200]; // 发给主调程序的信息 /* 原函数定义 */ typedef int (WINAPI *TypeMsgBoxA)(HWND hWnd,LPCSTR lpText, LPCSTR lpCaption,UINT uType); typedef int (WINAPI *TypeMsgBoxW)(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType); TypeMsgBoxA oldMsgBoxA = NULL; // 用于保存原函数地址 TypeMsgBoxW oldMsgBoxW = NULL; // 用于保存原楷书地址 FARPROC pfMsgBoxA = NULL; // 指向原函数地址的远指针 FARPROC pfMsgBoxW = NULL; // 指向原函数地址的远指针 #define CODE_LENGTH 5 BYTE oldCodeA[CODE_LENGTH]; // 保存原来API入口代码 BYTE oldCodeW[CODE_LENGTH]; // 保存原来API入口代码 BYTE newCodeA[CODE_LENGTH]; // 保存新API入口代码,jmp xxxx BYTE newCodeW[CODE_LENGTH]; // 保存新API入口代码,jmp xxxx /* 自己编写的API */ int WINAPI MyMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCation,UINT uType); int WINAPI MyMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCation,UINT uType); /* 其它函数原型声明 */ void HookOn(); // 开始HOOK void HookOff(); // 关闭HOOK void Inject(); // 注入 BOOL WINAPI StartHook(HWND hWnd); // 加载钩子 BOOL WINAPI StopHook(); // 卸载钩子 bool AdjustPrivileges(); // 提升权限 // //TODO: 如果此 DLL 相对于 MFC DLL 是动态链接的, // 则从此 DLL 导出的任何调入 // MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到 // 该函数的最前面。 // // 例如: // // extern "C" BOOL PASCAL EXPORT ExportedFunction() // { // AFX_MANAGE_STATE(AfxGetStaticModuleState()); // // 此处为普通函数体 // } // // 此宏先于任何 MFC 调用 // 出现在每个函数中十分重要。这意味着 // 它必须作为函数中的第一个语句 // 出现,甚至先于所有对象变量声明, // 这是因为它们的构造函数可能生成 MFC // DLL 调用。 // // 有关其他详细信息, 。 // // CHookDllApp BEGIN_MESSAGE_MAP(CHookDllApp, CWinApp) END_MESSAGE_MAP() // CHookDllApp 构造 CHookDllApp::CHookDllApp() { // TODO: 在此处添加构造代码, // 将所有重要的初始化放置在 InitInstance 中 } // 唯一的一个 CHookDllApp 对象 CHookDllApp theApp; // CHookDllApp 初始化 /* dll程序入口,当程序加载dll时,会执行InitInstance() */ BOOL CHookDllApp::InitInstance() { CWinApp::InitInstance(); g_hInstance = AfxGetInstanceHandle();// 获取当前DLL实例句柄 AdjustPrivileges(); // 提高权限 DWORD dwPid = ::GetCurrentProcessId(); hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,0,dwPid); if (hProcess == NULL) { CString str; str.Format(_T("OpenProcess fail, and error code = %d"),GetLastError()); AfxMessageBox(str); return FALSE; } Inject(); // 开始注入 return TRUE; } int CHookDllApp::ExitInstance() { /* dll退出时,一定要记得恢复原API的入口!!! 我们编写的dll会被注入到所有目标进程中,若dll退出时,没有恢复原API入口, 那么被挂钩的程序再次调用该API时,会发生错误。 因为我们的dll程序已经退出,但原API的入口仍为我们所定义的API的入口,这 时被挂钩的程序无法找到我们实现的API,然而原API的地址又没有被恢复,也就 调用不到原API,这时程序自然会发生崩溃了。 */ HookOff(); return CWinApp::ExitInstance(); } /* 提升权限 */ bool AdjustPrivileges() { HANDLE hToken; TOKEN_PRIVILEGES tp; TOKEN_PRIVILEGES oldtp; DWORD dwSize=sizeof(TOKEN_PRIVILEGES); LUID luid; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED) return true; else return false; } if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { CloseHandle(hToken); return false; } ZeroMemory(&tp, sizeof(tp)); tp.PrivilegeCount=1; tp.Privileges[0].Luid=luid; tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED; /* Adjust Token Privileges */ if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) { CloseHandle(hToken); return false; } // close handles CloseHandle(hToken); return true; } /* 鼠标钩子子过程,目的是加载本dll到使用鼠标的程序中。 鼠标钩子的作用:当鼠标在某程序窗口中时,就会加载我们这个dll。 */ LRESULT CALLBACK MouseProc( int nCode, // hook code WPARAM wParam,// message identifier LPARAM lParam // mouse coordinates ) { return CallNextHookEx(hhk,nCode,wParam,lParam); } /* 将长度为length的pcode写入到地址lpAddress中。 */ void WriteMemory(LPVOID lpAddress,BYTE* pcode,int length) { // // 保证本进程句柄不为NULL // ASSERT(hProcess != NULL); DWORD dwTemp,dwOldProtect,dwRet,dwWrited; // // 修改API入口前length个字节为 jmp xxxx // VirtualProtectEx(hProcess,lpAddress,length,PAGE_READWRITE,&dwOldProtect); dwRet = WriteProcessMemory(hProcess,lpAddress,pcode,length,&dwWrited); if ( 0 == dwRet || 0 == dwWrited) { AfxMessageBox(_T("哭!!写入失败")); } VirtualProtectEx(hProcess,lpAddress,length,dwOldProtect,&dwTemp); } /* 用新API地址替换原API地址 */ void HookOn() { ASSERT(hProcess != NULL); DWORD dwTemp,dwOldProtect,dwRet,dwWrited; WriteMemory(pfMsgBoxA,newCodeA,CODE_LENGTH); WriteMemory(pfMsgBoxW,newCodeW,CODE_LENGTH); } /* 恢复原API地址 */ void HookOff() { ASSERT(hProcess != NULL); DWORD dwTemp,dwOldProtect,dwRet,dwWrited; WriteMemory(pfMsgBoxA,oldCodeA,CODE_LENGTH); WriteMemory(pfMsgBoxW,oldCodeW,CODE_LENGTH); } /* 注入 */ void Inject() { if ( TRUE == bIsInJected) { return; } bIsInJected = TRUE; // 保证只调用一次 // // 获取函数 // HMODULE hmodle = ::LoadLibrary(_T("User32.dll")); oldMsgBoxA = (TypeMsgBoxA) ::GetProcAddress(hmodle,"MessageBoxA"); pfMsgBoxA = (FARPROC)oldMsgBoxA; oldMsgBoxW = (TypeMsgBoxW) ::GetProcAddress(hmodle,"MessageBoxW"); pfMsgBoxW = (FARPROC)oldMsgBoxW; if (pfMsgBoxA == NULL) { AfxMessageBox(_T("获取 MessageBoxA 函数失败")); return; } if ( pfMsgBoxW == NULL) { AfxMessageBox(_T("获取 MessageBoxW 函数失败")); return; } // // 保存原API地址 // _asm { lea edi,oldCodeA // 取数组基地址 mov esi,pfMsgBoxA // API地址 cld // 设置方向 mov ecx,CODE_LENGTH rep movsb } _asm { lea edi,oldCodeW mov esi,pfMsgBoxW cld mov ecx,CODE_LENGTH rep movsb } // // 将新地址复制到入口 // newCodeA[0] = newCodeW [0] = 0xe9; // jmp 指定代码 _asm { lea eax,MyMessageBoxA // 新API地址 mov ebx,pfMsgBoxA // 原API地址 sub eax,ebx sub eax,CODE_LENGTH // 跳转地址 = 新API地址 - 原API地址 - 指令长度 mov dword ptr [newCodeA+1],eax // eax 32bit = 4 BYTE } _asm { lea eax,MyMessageBoxW mov ebx,pfMsgBoxW sub eax,ebx sub eax,CODE_LENGTH mov dword ptr [newCodeW + 1],eax } HookOn(); // 开始HOOK } // // 安装钩子 // BOOL WINAPI StartHook(HWND hWnd) { g_hWnd = hWnd; hhk = ::SetWindowsHookEx(WH_MOUSE,MouseProc,g_hInstance,0); if (hhk == NULL) { return FALSE; } else { return TRUE; } } // // 卸载钩子 // BOOL WINAPI StopHook() { /* 卸载钩子时,一定要记得恢复原API入口。 这里恢复的只是主程序的原API入口,其它程序的API入口还没有被恢复。 因此我们必须处理dll退出过程,即在函数ExitInstance()中,调用恢复 API入口的函数HookOff(),只有这样,其它程序再次调用原API时,才不 会发生错误。 当我们HOOK所有程序的某个系统API时,千万要注意在ExitInstance()中 调用HookOff()!!!!! */ HookOff(); if (hhk!=NULL) { UnhookWindowsHookEx(hhk); FreeLibrary(g_hInstance); } return TRUE; } /* 自己用于替换的API */ int WINAPI MyMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCation,UINT uType) { int nRet = 0; HookOff(); nRet = ::MessageBoxA(hWnd,"哈哈 ^_^,MessageBoxA 被 HOOK 咯",lpCation,uType); nRet = ::MessageBoxA(hWnd,lpText,lpCation,uType); HookOn(); return nRet; } int WINAPI MyMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCation,UINT uType) { int nRet = 0; HookOff(); nRet = ::MessageBoxW(hWnd,_T("O(∩_∩)O哈哈~,MMessageBoxW 被 HOOK 咯"),lpCation,uType); nRet = ::MessageBoxW(hWnd,lpText,lpCation,uType); HookOn(); return nRet; } |
HOOK API(三)—— HOOK 所有程序的 MessageBox的更多相关文章
- HOOK API(二)—— HOOK自己程序的 MessageBox
HOOK API(二) —— HOOK自己程序的 MessageBox 0x00 前言 以下将给出一个简单的例子,作为HOOK API的入门.这里是HOOK 自己程序的MessageBox,即将自己程 ...
- HOOK API(二) —— HOOK自己程序的 MessageBox
转载来源:https://www.cnblogs.com/hookjc/ 0x00 前言 以下将给出一个简单的例子,作为HOOK API的入门.这里是HOOK 自己程序的MessageBox,即将自己 ...
- 汇编Ring 3下实现 HOOK API
[文章标题]汇编ring3下实现HOOK API [文章作者]nohacks(非安全,hacker0058) [作者主页]hacker0058.ys168.com [文章出处]看雪论坛(bbs.ped ...
- HOOK API(三) —— HOOK 所有程序的 MessageBox
转载来源:https://www.cnblogs.com/hookjc/ 0x00 前言 本实例要实现HOOK MessageBox,包括MessageBoxA和MessageBoxW,其实现细节与H ...
- Windows Dll Injection、Process Injection、API Hook、DLL后门/恶意程序入侵技术
catalogue 1. 引言2. 使用注册表注入DLL3. 使用Windows挂钩来注入DLL4. 使用远程线程来注入DLL5. 使用木马DLL来注入DLL6. 把DLL作为调试器来注入7. 使用c ...
- HOOK API入门之Hook自己程序的MessageBoxW(简单入门)
说到HOOK,我看了很多的资料和教程,无奈就是学不会HOOK,不懂是我的理解能力差,还是你们说的 不够明白,直到我看了以下这篇文章,终于学会了HOOK: http://blog.sina.com.cn ...
- HOOK API (一)——HOOK基础+一个鼠标钩子实例
HOOK API (一)——HOOK基础+一个鼠标钩子实例 0x00 起因 最近在做毕业设计,有一个功能是需要实现对剪切板的监控和进程的防终止保护.原本想从内核层实现,但没有头绪.最后决定从调用层入手 ...
- HOOK大法实现不修改程序代码给程序添加功能
[文章标题]: HOOK大法实现不修改程序代码给程序添加功能[文章作者]: 0x18c0[软件名称]: Scylla[使用工具]: OD.Stub_PE.ResHacker[版权声明]: 本文原创于0 ...
- 汇编 -- Hook API (MessageBoxW)
说到HOOK.我看了非常多的资料和教程.无奈就是学不会HOOK.不懂是我的理解能力差.还是你们说的 不够明确,直到我看了下面这篇文章,最终学会了HOOK: http://blog.sina.com.c ...
随机推荐
- [置顶] Android系统移植与调试之------->如何修改Android设备状态条上音量加减键在横竖屏的时候的切换与显示
这两天由于一个客户的要求,将MID竖屏时候的状态条上的音量键去掉.所以尝试修改了一下,成功了,分享一下经验. 先看一下修改后的效果图,如下所示 . 横屏的时候:有音量加减键 竖屏的时候:音量加减键被去 ...
- 面向对象程序设计-C++_课时11new & delete
Dynamic memory allocation new new int; new Stash; new int[10]; new返回这个对象的指针 delete delete p; delete[ ...
- 关于android:screenOrientation="portrait" 横竖屏切换
当在AndroidManifest.xml文件中定义了android:screenOrientation="portrait",就表示当我们切换横竖屏的时候,屏幕的内容始终以竖屏显 ...
- Android解析XML
在Android平台上可以使用Simple API for XML(SAX) . Document Object Model(DOM)和Android附带的pull解析器解析XML文件. 下面是本例子 ...
- matlab GUI之常用对话框(四)-- 输入对话框 inputdlg、目录对话框 uigetdir、列表对话框 listdlg
常用对话框(四) 1.输入对话框 inputdlg answer = inputdlg(prompt) answer = inputdlg(prompt,dlg_title) answer = in ...
- Ubuntu 14.04 静态IP设置
1. 编辑/etc/network/interfaces vim /etc/network/interfaces 2.将以下五项添加到/etc/network/interfaces中 Static d ...
- 数据持久化------Archiving(归档,解档)
其中TRPerson为自定义的继承自NSObject的类的子类 其中有两个属性,name 和 age .h文件 #import @interface TRPerson : NSObject<& ...
- ubuntu 源码安装 swig
1. 下载 swig 源码 http://www.swig.org/survey.html 填写一个简单的问卷,即可进入 sourceforge 下载. 2. 安装 g++ sudo apt-get ...
- [暂停一天]从零开始PHP学习 - 第六天
今天这个系列没有时间去写了 在公司完善一个项目 已经备好6瓶咖啡 两天 + 一夜 完成这个项目 真是苦逼 诶 反正这几天 明白一个道理:别以为你多牛B 你不会的东西多了! 比你牛B的人也多 ...
- 对discuz的代码分析学习(三)mysql驱动
一. 属性分析 1.tablepre :表名称前缀 2.version : 数据库版本 3.drivertype:驱动类型 4.querynu ...