学习windows 应用层 inline hook 原理总结

简介: inline hook 实际上就是指 通过改变目标函数头部的代码来使改变后的代码跳转到我们自己设置的一个函数里,产生hook。 今天就拿MessageBoxA这个api函数来做实验。功能就是当程序调用MessageBoxA 时,我们打印出MessageBoxA的参数   大概代码结构应该是这样...

inline hook 实际上就是指 通过改变目标函数头部的代码来使改变后的代码跳转到我们自己设置的一个函数里,产生hook。

今天就拿MessageBoxA这个api函数来做实验。功能就是当程序调用MessageBoxA 时,我们打印出MessageBoxA的参数

 

大概代码结构应该是这样

typedef int (WINAPI
    *MessageBox_type) (
    __in_opt HWND hWnd,
    __in_opt LPCSTR lpText,
    __in_opt LPCSTR lpCaption,
    __in UINT uType) ;

MessageBox_type RealMessageBox;

//我们自己的MessageBox,每调用MessageBox都要跳到myMessageBox来处理
int WINAPI
    myMessageBox(
    __in_opt HWND hWnd,
    __in_opt LPCSTR lpText,
    __in_opt LPCSTR lpCaption,
    __in UINT uType)
{
    //下面打印MessageBox参数
    printf("hwnd:%8X lpText:%s lpCaption:%s,uType:%8X",hWnd,lpText,lpCaption,uType); 
    return RealMessageBox(hWnd,lpText,lpCaption,uType); //现在开始调用真正的MessageBox
}

VOID HookMessageBoxA()
{

}

int _tmain(int argc, _TCHAR* argv[])
{
    HookMessageBoxA();  //hook操作
    ::MessageBoxA(NULL,"hook test","tip",MB_OK); //执行api MessageBox
    return 0;
}

我们先看看汇编是怎样调用MessageBoxA的

 

MessageBox流程

首先看到,MessageBoxA里面

mov edi,edi
mov ebp
mov ebp,esp
刚好是5个字节,5个字节可以做一个远jmp

直接汇编改成我们自己的jmp

改后结果如下

image

单步执行发现hook成功。但程序崩溃。原因主要是由于

我们破坏了真正的MessageBox使们想要调用真正的MessageBox时也会调用失败了,所以我们要调用真正的MessageBox时要加上头部被我们换掉的部分,我们要内联汇编,里面不能含有编译器自动添加的代码,所以在myMessageBox头部要加上 _declspec(naked)

vs2010的debug版本每执行一个函数都要 cmp esi,esp 来验证堆栈的。所以还要加一句push esi 和pop esi

//我们自己的MessageBox,每调用MessageBox都要跳到myMessageBox来处理
_declspec(naked)  void WINAPI
    myMessageBox(
    __in_opt HWND hWnd,
    __in_opt LPCSTR lpText,
    __in_opt LPCSTR lpCaption,
    __in UINT uType)
{
        __asm
    {
        PUSH ebp
        mov ebp,esp

        /*
        vs2010 debug 编译后的代码由于要cmp esi esp来比较堆栈。
        所以这里在调用非__asm函数前push一下esi
        */
        push esi
    }
    //下面打印MessageBox参数
    printf("hwnd:%8X lpText:%s lpCaption:%s,uType:%8X",hWnd,lpText,lpCaption,uType); 

    __asm
    {
        /*
        vs2010 debug 编译后的代码由于要cmp esi esp来比较堆栈。
        所以这里在调用非__asm函数前push一下esi
        */
        pop esi

        mov ebx,RealMessageBox
        add ebx,5
        jmp ebx
    }
}

下面说一下用代码来写MessageBoxA着呢5个字节

首先要懂得 JMP指令转换公式推导  不懂的话 看 http://www.cnblogs.com/zhangdongsheng/archive/2012/12/06/2804234.html

 

先声明一个JMP结构体。注意前面加 #pragma pack(1)来避免内存对齐的一些规则

#pragma pack(1)
typedef struct _JMPCODE
{
    BYTE jmp;
    DWORD addr;
}JMPCODE,*PJMPCODE;

接下来写hook函数

VOID HookMessageBoxA()
{
    JMPCODE jcode;
    jcode.jmp = 0xe9;//jmp
    jcode.addr = (DWORD)myMessageBox - (DWORD)RealMessageBox - 5; 

    RealMessageBox = MessageBoxA;
    ::WriteProcessMemory(GetCurrentProcess(),MessageBoxA,&jcode,sizeof(JMPCODE),NULL);
}

现在测试成功。

image

 

完整源代码如下:

// hook_blog_writer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>

typedef int (WINAPI
    *MessageBox_type) (
    __in_opt HWND hWnd,
    __in_opt LPCSTR lpText,
    __in_opt LPCSTR lpCaption,
    __in UINT uType) ;

MessageBox_type RealMessageBox = MessageBoxA;

//我们自己的MessageBox,每调用MessageBox都要跳到myMessageBox来处理
_declspec(naked)  void WINAPI
    myMessageBox(
    __in_opt HWND hWnd,
    __in_opt LPCSTR lpText,
    __in_opt LPCSTR lpCaption,
    __in UINT uType)
{
        __asm
    {
        PUSH ebp
        mov ebp,esp

        /*
        vs2010 debug 编译后的代码由于要cmp esi esp来比较堆栈。
        所以这里在调用非__asm函数前push一下esi
        */
        push esi
    }
    //下面打印MessageBox参数
    printf("hwnd:%8X lpText:%s lpCaption:%s,uType:%8X",hWnd,lpText,lpCaption,uType); 

    __asm
    {
        /*
        vs2010 debug 编译后的代码由于要cmp esi esp来比较堆栈。
        所以这里在调用非__asm函数前push一下esi
        */
        pop esi

        mov ebx,RealMessageBox
        add ebx,5
        jmp ebx
    }
}


#pragma pack(1)
typedef struct _JMPCODE
{
    BYTE jmp;
    DWORD addr;
}JMPCODE,*PJMPCODE;

VOID HookMessageBoxA()
{
    JMPCODE jcode;
    jcode.jmp = 0xe9;//jmp
    jcode.addr = (DWORD)myMessageBox - (DWORD)RealMessageBox - 5; 

    RealMessageBox = MessageBoxA;
    ::WriteProcessMemory(GetCurrentProcess(),MessageBoxA,&jcode,sizeof(JMPCODE),NULL);
}

int _tmain(int argc, _TCHAR* argv[])
{
    HookMessageBoxA();  //hook操作
    ::MessageBoxA(NULL,"hook test","tip",MB_OK); //执行api MessageBox
    return 0;
}

 

 

相关文章
|
20天前
|
网络安全 Windows
Windows server 2012R2系统安装远程桌面服务后无法多用户同时登录是什么原因?
【11月更文挑战第15天】本文介绍了在Windows Server 2012 R2中遇到的多用户无法同时登录远程桌面的问题及其解决方法,包括许可模式限制、组策略配置问题、远程桌面服务配置错误以及网络和防火墙问题四个方面的原因分析及对应的解决方案。
|
24天前
|
监控 安全 网络安全
使用EventLog Analyzer日志分析工具监测 Windows Server 安全威胁
Windows服务器面临多重威胁,包括勒索软件、DoS攻击、内部威胁、恶意软件感染、网络钓鱼、暴力破解、漏洞利用、Web应用攻击及配置错误等。这些威胁严重威胁服务器安全与业务连续性。EventLog Analyzer通过日志管理和威胁分析,有效检测并应对上述威胁,提升服务器安全性,确保服务稳定运行。
|
25天前
|
监控 安全 网络安全
Windows Server管理:配置与管理技巧
Windows Server管理:配置与管理技巧
65 3
|
29天前
|
存储 安全 网络安全
Windows Server 本地安全策略
由于广泛使用及历史上存在的漏洞,Windows服务器成为黑客和恶意行为者的主要攻击目标。这些系统通常存储敏感数据并支持关键服务,因此组织需优先缓解风险,保障业务的完整性和连续性。常见的威胁包括勒索软件、拒绝服务攻击、内部威胁、恶意软件感染等。本地安全策略是Windows操作系统中用于管理计算机本地安全性设置的工具,主要包括用户账户策略、安全选项、安全设置等。实施强大的安全措施,如定期补丁更新、网络分段、入侵检测系统、数据加密等,对于加固Windows服务器至关重要。
|
2月前
|
边缘计算 安全 网络安全
|
2月前
|
数据安全/隐私保护 Windows
安装 Windows Server 2019
安装 Windows Server 2019
|
2月前
|
网络协议 Windows
Windows Server 2019 DHCP服务器搭建
Windows Server 2019 DHCP服务器搭建
|
2月前
|
网络协议 定位技术 Windows
Windows Server 2019 DNS服务器搭建
Windows Server 2019 DNS服务器搭建
|
2月前
|
安全 网络协议 数据安全/隐私保护
Windows Server 2019 搭建并加入域
Windows Server 2019 搭建并加入域