温故:Windows API拦截框架

Windows 系统API通常前5字节为固定的,因此改成JMP刚好合适:
 mov edi, edi 
 push ebp
 mov ebp, esp
我要介绍的方法用了很久,稳定性相当不错的说。
定义一个中继函数 用来跳转到原函数+5字节处。
定义一个假函数,用来处理参数,然后返还给中继函数,假函数中可以伪造参数以及返回值。。你懂得
需要注意函数在代码段,需要修改内存属性,否则写入不了jmp指令。




DWORD GetApiAddress(char* ApiName, char* moudleName)
{
    return (DWORD)::GetProcAddress(::GetModuleHandleA(moudleName), ApiName);
}
//WINUSERAPI int WINAPI MessageBoxA( _In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType)
DWORD org_saveMessageBoxAdreesAdd5Byte = 0;
__declspec(naked) int __stdcall TmpMessageBoxA(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType)
{
    __asm {
        /*  nop
            nop
            nop
            nop
            nop */
        mov edi, edi 
        push ebp
        mov ebp, esp
        jmp org_saveMessageBoxAdreesAdd5Byte

    }
}

int __stdcall HookIngMessageBoxA(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType)
{
    /*  OutputDebugStringA("此API被修改");**/
    return TmpMessageBoxA(hWnd, "已经被修改指令的MessageBoxA", lpCaption, uType);
}

bool  IsHook = false;//是否已经HOOK过  HOOK只需要执行一次
void CMFCApplication1App::HookMessage()
{
    if (IsHook == false)
    {
        //获取指定API地址
        DWORD _gMessageBoxA = GetApiAddress("MessageBoxA", "user32.dll");
        //修改指令   API头五个字节   为Jmp
        /*
        mov edi , edi
        push        ebp
        mov         ebp, esp*/
        DWORD oldProtect = 0;//保存原始内存读写权限
                             //修改中继函数 和 目标函数的 读写权限
        ::VirtualProtect((LPVOID)_gMessageBoxA, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
        ::VirtualProtect((LPVOID)TmpMessageBoxA, 5, PAGE_EXECUTE_READWRITE, &oldProtect);

        //1.拷贝 目标函数的原始5字节 到 中继函数中
        //2.把目标函数地址+5字节保存起来 在中继函数中跳转
        //3.动态计算jmp指令后4字节的机器码
        //目标地址  -  原始地址  - 5 =  机器码


        org_saveMessageBoxAdreesAdd5Byte = _gMessageBoxA + 5; 


        DWORD jmp_code = (DWORD)HookIngMessageBoxA - _gMessageBoxA - 5;
        *((byte*)(_gMessageBoxA)) = 0xe9;//jmp
        *((DWORD*)(_gMessageBoxA + 1)) = jmp_code;
        IsHook = true;
    }

    ::MessageBoxA(NULL, "txt", "测试", 0);



}

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值