lengshizai 2024-02-27 23:10 采纳率: 31.7%
浏览 15
已结题

汇编hook举例并讲解(通俗易懂,学习用)

问题:学习汇编hook过程中自己的hook影响到堆栈导致程序崩溃
下面给出一段汇编 要求以指定形式hook指定地址;
要求以call跳转 或jmp跳转各实现一次hook并分别讲解,以下是 我的代码形式;
请给出一个通俗易懂的讲解以便于学习。

005B1139   | 8B0D D0CE3301     | mov     ecx, dword ptr [133CED0]            |
005B113F   | 8B4424 04         | mov     eax, dword ptr [esp+4]              |
005B1143   | 6A 22             | push    22                                  |
005B1145   | 50                | push    eax                                 |
005B1146   | 8B11              | mov     edx, dword ptr [ecx]                |
005B1148   | 68 4E040000       | push    44E                                 |HOOK目标地址
005B114D   | FF12              | call    dword ptr [edx]                     | 
005B114F   | C3                | ret                                         |

HOOK代码如下:

void HOOK测试()
{
     DWORD Hook地址 =0x005B1148;//上面代码里备注那个
    DWORD Hook子程序指针 = (DWORD)跳转;
    DWORD 跳转值 = Hook子程序指针 - Hook地址 - 0x5;

    DWORD old = 0;//存放原来的属性
     //修改内存页面属性
    VirtualProtect((PVOID)Hook, 32, PAGE_EXECUTE_READWRITE, &old);
   
// 注意下行指令的备注 : // 这里如果是jmp 跳转 填0xE9? call 跳转填 0xE8?
    *(BYTE*)Hook地址 = 0xE8; 
    *(DWORD*)(Hook地址 + 0x1) = 跳转值;
    VirtualProtect((PVOID)Hook地址, 32, old, &old);//恢复页面属性;
}


//  实现功能  也就是 求助的代码部分
void 跳转()

{
     _asm 
    {    
        pushad
    } 
   
// 这里是要实现的功能  ,比如拦截  比如检测;
    _asm 
    {
        popad
       //这里应该怎样书写
      //  写这个? push    0x44E?
     
    }
}

要求 分别以Call 跳转 或 JMP跳转的方式 给出 函数 :跳转的代码(格式同上文给出);
并查看上文中备注部分的问题。
由于初学,部分描述可能不到位,请给出一段代码实现以下功能:
在 拦截 或者检测 那 实现 printf(11111\n");

所给出的示例 将在测试及学习后,如成功即采纳。

  • 写回答

17条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-02-27 23:11
    关注

    引自微信小程序:皆我百晓生

    首先,您在汇编代码中选择的HOOK目标地址是0x005B1148。要实现对该地址进行Hook并调用自定义函数(即跳转()),可以使用JMP或CALL指令。下面分别以JMP和CALL为例来说明,并补充完成跳转()函数。

    1. JMP跳转方式:

    void HOOK测试()
    {
        DWORD Hook地址 = 0x005B1148;
        DWORD Hook子程序指针 = (DWORD)跳转;
        DWORD 跳转值 = Hook子程序指针 - Hook地址 - 5; // 对于JMP,需要减去5,因为JMP相对偏移量不包含下一条指令大小
    
        DWORD oldProtect;
        VirtualProtect((PVOID)Hook地址, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
    
        *(BYTE*)Hook地址 = 0xE9; // 使用JMP指令
        *(DWORD*)(Hook地址 + 1) = 跳转值;
    
        VirtualProtect((PVOID)Hook地址, 5, oldProtect, &oldProtect);
    }
    
    // 实现功能
    void 跳转()
    {
        __asm
        {
            pushad
            push 0x44E // 如果原始代码需要保留这个参数,这里也应压栈
            push offset fmt_str // 压入格式化字符串地址
            call printf // 调用printf函数输出内容
            add esp, 8 // 清理堆栈,恢复esp
            popad
            jmp 原始目标地址 // 在这里填写原始被HOOK的目标地址,以便执行完我们的操作后继续执行原流程
        }
    
        const char* fmt_str = "11111\n";
    }
    

    2. CALL跳转方式:

    void HOOK测试()
    {
        DWORD Hook地址 = 0x005B1148;
        DWORD Hook子程序指针 = (DWORD)跳转;
        DWORD 跳转值 = Hook子程序指针 - Hook地址 - 5; // 对于CALL,也需要减去5,因为CALL相对偏移量不包含下一条指令大小
    
        DWORD oldProtect;
        VirtualProtect((PVOID)Hook地址, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
    
        *(BYTE*)Hook地址 = 0xE8; // 使用CALL指令
        *(DWORD*)(Hook地址 + 1) = 跳转值;
    
        VirtualProtect((PVOID)Hook地址, 5, oldProtect, &oldProtect);
    }
    
    // 实现功能
    void 跳转()
    {
        __asm
        {
            pushad
            push 0x44E // 如果原始代码需要保留这个参数,这里也应压栈
            push offset fmt_str // 压入格式化字符串地址
            call printf // 调用printf函数输出内容
            add esp, 8 // 清理堆栈,恢复esp
            popad
            ret // 使用CALL跳转时,无需手动跳回原始目标地址,因为call会自动返回到下一条指令
        }
    
        const char* fmt_str = "11111\n";
    }
    

    注意:

    • 上述示例中的“原始目标地址”需要根据实际情况获取。
    • 需要注意的是,HOOK操作需谨慎处理堆栈平衡,确保在hook函数执行完毕后,堆栈状态与原始代码一致。在上述示例中,我们模拟了对原始参数的保存和恢复,以及在调用printf之后清理堆栈的操作。
    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月5日
  • 修改了问题 2月27日
  • 创建了问题 2月27日

悬赏问题

  • ¥15 软件工程用例图的建立(相关搜索:软件工程用例图|画图)
  • ¥15 如何在arcgis中导出拓扑关系表
  • ¥15 处理数据集文本挖掘代码
  • ¥15 matlab2017
  • ¥15 在vxWorks下TCP/IP编程,总是connect()报错,连接服务器失败: errno = 0x41
  • ¥15 AnolisOs7.9如何安装 Qt_5.14.2的运行库
  • ¥20 求:怎么实现qt与pcie通信
  • ¥50 前后端数据顺序不一致问题,如何解决?(相关搜索:数据结构)
  • ¥15 基于蒙特卡罗法的中介效应点估计代码
  • ¥15 罗技G293和UE5.3