学习 API HOOK

本文介绍了一种名为InlineHook的技术,该技术允许用户拦截并修改Windows系统API调用的行为。通过改写API函数头部的指令来实现拦截,进而执行自定义代码,并在完成后恢复原有API的功能。文章提供了一个具体的示例——HOOKMessageBoxW函数,并详细解释了其实现步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

API HOOK

更新日期:2010-12-31

━━━━━━━━━━━━━━━━━━━━━━━━

收集了一些关于Hook API的资料,跟大家分享!在新的一年即将到来之际,祝福大家永远快乐!阿弥陀佛!

下载地址:(请不要使用下载工具,否则可能出错)
http://cid-3ba16e78a53d2d3d.office.live.com/self.aspx/VC/HookAPI.zip

粘贴以下代码到一个控制台程序

/****************************************************************************
一、本地HOOK API(Inline HOOK):
    HOOK MessageBoxW 这个,让它跳到我们自己的函数处理之后再调用原来的MessageBoxW,
    这种本地的HOOK API应该是最简单的HOOK API而且它的作用也不是很明显,但是可以了解什么是HOOK API.

二、原理:
    找到API函数在内存中的地址,改写函数头几个字节为JMP指令跳转到自己的代码,
    执行完毕再执行API开头几个字节的内容再跳回原地址。这种方法对CPU有较大的依赖性,
    而且在多线程环境下可能出问题,当改写函数代码的时候有可能此函数正在被执行,
    这样做可能导致程序出错。

三、使用以下代码说明:
    当hook一个新的API时,需要修改以下代码几个地方:
    比如hook ShowWindow(HWND hWnd,int nCmdShow) 为例

    1.API的函数的参数列表:
        替换:HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType
        为:  HWND hWnd,int nCmdShow

    2.修改新的API函数。照这MSDN里面写就可以了
        修改:int WINAPI NewAPI(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) 
        为:  BOOL ShowWindow(HWND hWnd,int nCmdShow)

    3.修改GetProcAddress的第二个参数为"ShowWindow"

四、此代码修改自网上的资料,对原作者表示感谢!

五、收集了一些关于Hook API的资料,跟大家分享!愿大家生活愉快!阿弥陀佛!
    下载地址:(请不要使用下载工具,否则可能出错)
    http://cid-3ba16e78a53d2d3d.office.live.com/self.aspx/VC/HookAPI.zip

****************************************************************************/


#include <windows.h>
#include <iostream>
using namespace std;

#ifndef ASSERT
#include <crtdbg.h>
#define ASSERT(X) _ASSERT(X);
#endif


//API函数类型
typedef int (WINAPI* pDefaultAPI)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);

pDefaultAPI pOldAPI = NULL;            //此指针pOldAPI保存原来API函数的地址(通过GetProcAddress获取)
char szOldAPI[5] = {0};                //存放原来API函数在内存中的前5个字节
char szNewAPI[5] = {(char)0xe9};    //存放我们处理后的5个字节,JMP指令(1个字节)+新函数地址(4个字节)

BOOL WINAPI NewAPI(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) 
{    
    cout<<"调用了新的API"<<endl;

    //还原为原来的API
    WriteProcessMemory((void*)-1, pOldAPI, szOldAPI, 5, NULL);
   
    //调用原来的API
    MessageBoxW(hWnd, lpText, lpCaption, uType);
   
    //修改为新的API(我们自己的)
    WriteProcessMemory((void*)-1, pOldAPI, szNewAPI, 5, NULL);

    return 1;
}


bool HookAPI()
{
    //找到API函数在内存中的地址
    HMODULE hModule = LoadLibrary("User32.Dll");
    pOldAPI = (pDefaultAPI)GetProcAddress(hModule, "MessageBoxW");
    ASSERT(pOldAPI);
    if (!pOldAPI)
    {
        FreeLibrary(hModule);
        return false;
    }

    //改写函数头几个字节为JMP指令跳转到自己的代码,
    DWORD dwJmpAddr = 0;
    dwJmpAddr = (DWORD)NewAPI - (DWORD)pOldAPI - 5;
    memcpy(szNewAPI + 1, &dwJmpAddr, 4);
    FreeLibrary(hModule);
    ReadProcessMemory ((void*)-1, pOldAPI, szOldAPI, 5, NULL);    //读出原来的前5个字节
    WriteProcessMemory((void*)-1, pOldAPI, szNewAPI, 5, NULL);    //写入我们处理后的5个字节

    return true;
}


int main()
{
    if (!HookAPI())
        ::MessageBox(NULL,TEXT("HookAPI Error"),NULL,MB_OK);

    MessageBoxW(GetForegroundWindow(), L"Inline Hook:MessageBox", L"HOOK API", MB_OK);

    return 0;
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值