HOOK API(三)

—— HOOK 所有程序的 MessageBox

原文出处:http://www.cnblogs.com/fanling999/p/4595035.html

程序源代码:https://github.com/hfl15/windows_kernel_development/tree/master/demo_source_code/HoolAllMessageBox

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 codeWPARAM wParam,// message identifierLPARAM 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; 此处可以是显式导出StartHookStopHook

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实现

  1. 注入函数,保存新的,原来的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_LENGTHrep movsb}_asm{lea edi,oldCodeWmov esi,pfMsgBoxWcldmov ecx,CODE_LENGTHrep 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,MyMessageBoxWmov ebx,pfMsgBoxWsub eax,ebxsub eax,CODE_LENGTHmov dword ptr [newCodeW + 1],eax}HookOn();    //    开始HOOK

}

写内存函数

该函数主要完成向进程控制块写写指令的任务。供HookOn()和HookOff()调用,用来将原API入口,或新的API入口写入到进程的地址空间中。

/*将长度为length的pcode写入到地址lpAddress中。
*/
void WriteMemory(LPVOID lpAddress,BYTE* pcode,int length){//    保证本进程句柄不为NULLASSERT(hProcess != NULL);DWORD dwTemp,dwOldProtect,dwRet,dwWrited;// 修改API入口前length个字节为 jmp xxxxVirtualProtectEx(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 调用。
//
//        有关其他详细信息,//        请参阅 MFC 技术说明 33 和 58。
//// 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 codeWPARAM wParam,// message identifierLPARAM lParam // mouse coordinates
                        )
{return CallNextHookEx(hhk,nCode,wParam,lParam);
}/*将长度为length的pcode写入到地址lpAddress中。
*/
void WriteMemory(LPVOID lpAddress,BYTE* pcode,int length){//    保证本进程句柄不为NULLASSERT(hProcess != NULL);DWORD dwTemp,dwOldProtect,dwRet,dwWrited;// 修改API入口前length个字节为 jmp xxxxVirtualProtectEx(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_LENGTHrep movsb}_asm{lea edi,oldCodeWmov esi,pfMsgBoxWcldmov ecx,CODE_LENGTHrep 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,MyMessageBoxWmov ebx,pfMsgBoxWsub eax,ebxsub eax,CODE_LENGTHmov 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;
}

转载于:https://www.cnblogs.com/fanling999/p/4595035.html

HOOK API(三)—— HOOK 所有程序的 MessageBox相关推荐

  1. HOOK API(二)—— HOOK自己程序的 MessageBox

    0x00 前言 以下将给出一个简单的例子,作为HOOK API的入门.这里是HOOK 自己程序的MessageBox,即将自己程序对MessageBox API的调用重定向到自己实现的API中,在自己 ...

  2. 汇编Ring 3下实现 HOOK API

    [文章标题]汇编ring3下实现HOOK API [文章作者]nohacks(非安全,hacker0058) [作者主页]hacker0058.ys168.com [文章出处]看雪论坛(bbs.ped ...

  3. HOOK API技术

    HOOK API技术 HOOK学习笔记与心得 奇技淫巧之调试被远程线程注入的DLL windows核心编程_系统消息与自定义钩子hook使用 [Windows Dll Injection.Proces ...

  4. android hook api

    搞了好几个星期,终于有点头绪,欢迎交流.转载请注明出处http://blog.csdn.net/lingfong_cool/article/details/8109290. android安全可以从三 ...

  5. Windows Dll Injection、Process Injection、API Hook、DLL后门/恶意程序入侵技术

    catalogue 1. 引言 2. 使用注册表注入DLL 3. 使用Windows挂钩来注入DLL 4. 使用远程线程来注入DLL 5. 使用木马DLL来注入DLL 6. 把DLL作为调试器来注入 ...

  6. Hook API (C++)

    一.基本概念: 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且 所监视的窗口可以是其他进程所创建的.当消息到达后,在目标窗口处理函数 ...

  7. Ring3下Inline Hook API

    用CreateFile为例子,讲解一下Ring3下的Inline Hook API,基本原理很简单 1.获取CreateFile函数的地址 2.读取CreateFile函数的前8个字节 3.将Crea ...

  8. Windows内核API HOOK 之 Inline Hook

    来源:CSDN   作者:daiwen 名字起得好,Inline hook,乍一听,似乎很高深.此处的Inline,我以为,意指将汇编代码直接写入内核API的内存区域.Inline Hook不像用户态 ...

  9. Windows下Hook API技术小结 (转)

    1.基本概念 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的.当消息到达后,在目标窗口处理函数之前 ...

  10. HOOK大法实现不修改程序代码给程序添加功能

    [文章标题]: HOOK大法实现不修改程序代码给程序添加功能 [文章作者]: 0x18c0 [软件名称]: Scylla [使用工具]: OD.Stub_PE.ResHacker [版权声明]: 本文 ...

最新文章

  1. 【算法学习笔记】57. 前缀树 字典序优化技巧 STL学习 SJTU OJ 1366 前缀匹配
  2. hadoop1.2.1安装配置
  3. 【年度学术大会合集】SIGGRAPH,KDD,AAAI,NIPS…这些你想参加的会议
  4. Linux基础第一章 概述
  5. 正确解读PHP获取时间错误原因
  6. 《2017中国大数据及AI人才发展报告》均薪38万,招聘猛增6倍
  7. 专升本的学生和高考考上本科的学生一样吗
  8. Linux之父道歉后,Linux社区颁布开发人员行为准则
  9. Thinkphp5.1整合支付宝APP支付
  10. 基于R统计分析——样本与分布
  11. MySQL表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)
  12. 游戏中BUFF的实现
  13. 基于android系统的单词学习软件设计与开发【附项目源码+论文说明】分享
  14. 为什么android手机内存不够,安卓手机内存不足怎么办?安卓手机内存越来越小解决方法汇总...
  15. 一个主机可以接几个php,一台主机如何连接两个显示器
  16. android gif图片闪烁,Android中动态显示gif图片
  17. 如何基于SSM设计实现一个学生学籍管理系统
  18. 【转】 学习ios(必看经典)牛人40天精通iOS开发的学习方法【2015.12.2
  19. Problem E: 农夫果园
  20. matlab仿真及分析,CSMACD性能分析及MATLAB仿真.pdf

热门文章

  1. vsbutton中的集合编辑器怎么打开_理工科学生的好帮手,EdrawMath数学公式编辑器...
  2. 浅谈ES6中的rest参数
  3. linux SSH rsa认证方式登录需理清的问题
  4. 结对编程之求首尾相连数组中最大子数组的和
  5. YUM服务那些事---详解YUM服务
  6. [翻译]Monocular Visual Odometry using OpenCV
  7. xgboost算模型输出的解释
  8. 阿里云发布ET奥运大脑,推进奥运进入数字时代
  9. IDC预测:2021vCPE软硬件市场将达到30亿美元
  10. 介绍一下python getopt 模块