浅谈热补丁的钩取方式

小小小幸运  金牌会员 | 2024-6-25 13:29:34 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 844|帖子 844|积分 2532

前言

热补丁的钩取方式是为了办理内联钩取在多线程情况下会出错的情况,使用热补丁的钩取可以制止重复读写指令造成问题。
内联钩取潜伏问题

正常情况下,在每次跳转到自定义函数时必要将原始的指令(mov edi,edi)写回CreateProcessW函数内,为了后续正确调用CreateProcesW函数,在调用完毕之后,又必要进行挂钩的处理,即将mov指令修改为jmp指令。

但是在多线程的情况下就可能会出现下列问题,在进行mov指令窜改时可能会发生线程的切换,因为窜改指令的操作不是原子操作。那么在线程2时可能调用了CreateProcessW函数时可能跳转指令还没写完成,例如下图的jmp 0x12xx,而不是原本的jmp 0x1234就导致了执行出错。
[img=720,246.578]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202406241628293.png[/img]

为了办理此问题接纳了热补丁钩取。
热补丁钩取

热补丁是指在不停止体系运行进行应用。即不停止步调运行也能够修改体系库或步调中的执行逻辑。
这里以CreateProcessW为例子
在windbg中使用以下指令在CreateProcessW函数中打下断点
  1. .reload /f
  2. bp CreateProcessW
复制代码
可以看到CreateProcessW函数入口点是mov edi,edi指令,而在该指令上方有一段没用用到的空间,在windbg中使用int 3指令添补了。
[img=720,686.0689655172414]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202406241628294.png[/img]

而mov edi,edi指令本身没有现实意义,这就是微软在体系库预留的空间,用于打上热补丁。因为这个指令无论被修改成什么都不会影响步调的执行。
接着可以发现这跳指令的长度为2字节,因此可以使用任意的2字节长的指令替换mov edi,edi。
那么这里就必要探求可以完成跳转的指令,而且仅占用2字节完成对mov指令的替换。
【----帮助网安学习,以下所有学习资料免费领!加vx:dctintin,备注 “博客园” 获取!】
 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析陈诉
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)
在汇编中存在着短跳转指令可以完成跳转而且仅占用2字节,用以下例子来观察一下短跳转的指令。
  1. int main()
  2. {
  3.    // 使用标签作为跳转目标
  4.    __asm {
  5.        jmp short label;
  6.    };
  7.    // 标签处定义跳转目标
  8. label:
  9.    // 这里是跳转目标后的代码
  10.    return 0;
  11. }
复制代码
可以看到在跳转到标签label上时,接纳的跳转指令呆板码是EB开头的,而不是E9,而且指令长度也只有2字节。
[img=720,316.020482809071]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202406241628295.png[/img]

那么00是跳转的偏移值,根据该例子分析一下跳转偏移的盘算
  1. 跳转偏移 = 目标地址 - 当前地址 - 当前指令的长度
  2. 00      = 00731005 - 00731003 - 2
复制代码
可以看到盘算偏移的公式与jmp指令一致,只是跳转的指令的长度为5字节,而短跳转的指令长度为2字节,因此jmp指令也被称之为长跳转。
那么怎么配合短跳转进行一个钩取操作,如下图。我们可以借助短跳转使得指令执行到上述添补的区域,然后再使用jmp指令完成钩取的操作。这里必要留意的是空闲区域的空间大小必要大于5个字节,不然无法容纳jmp指令。
[img=720,317.2461273666093]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202406241628296.png[/img]

最终修改后钩取的效果如下图,在自定义函数中不在必要钩取与脱钩的操作,因为我们修改的指令不会影响正常的CreateProcessW函数执行。那么在既然不存在写操作,那么在多线程中也不会因为条件竞争导致还没写完就切换线程的情况。

那么代码实现部门如下,这里必要留意长跳转的指令0xE9,短跳转的指令为0xEB,这里先把偏移盘算好了0xF9,因此写好了,但是这个偏移值不是唯一值,只要找到的地址存在大于5字节的空闲区域都是可以的。紧接着就是修改函数内部的指令,将初始的指令修改为短跳转,然后再空闲区中添补长跳转即可。
  1. ...
  2.    //长跳转指令
  3.    BYTE pBuf[5] = { 0xE9, 0 };
  4.    //短跳转指令 + 偏移值
  5.    BYTE pShortJmp[2] = { 0xEB, 0xF9};
  6.    //获取模块地址
  7.    HMODULE hModule = GetModuleHandleA(szDllName);
  8.    //获取函数地址
  9.    FARPROC pfnOld = GetProcAddress(hModule, szFuncName);
  10.    //选中长跳转指令填充的地址,这里选择恰好能容纳jmp指令的位置
  11.    DWORD target = (DWORD)pfnOld - 5;
  12.    //计算跳转的偏移
  13.    DWORD dwAddress =  (DWORD)pfnNew - target - 5;
  14.    //修改区域的权限
  15.    VirtualProtect((LPVOID)target, 7, PAGE_EXECUTE_READWRITE, &dwOldProtect);
  16.    //将偏移填充到指令中
  17.    memcpy(&pBuf[1], &dwAddress, 4);
  18.    //将长跳转指令填充
  19.    memcpy((LPVOID)target, pBuf, 5);
  20.    //保存原始的两个字节
  21.    memcpy(pOldBytes, pfnOld, 2);
  22.    //将短跳转指令填充
  23.    memcpy(pfnOld, pShortJmp, 2);
  24.    VirtualProtect((LPVOID)target, 7, dwOldProtect, &dwOldProtect);
  25. ...
复制代码
在自定义函数中,只必要直接调用CreatePorcessW + 2的指令就可以完成原始CreateProcessW函数,不再必要挂钩脱钩的处理。
  1. ...
  2.    //调用CreateProcessW + 2
  3.     BOOL ret = ((LPFN_CreateProcessW)((DWORD)pfnOld + 2))(
  4.        applicationName,
  5.        lpCommandLine,
  6.        lpProcessAttributes,
  7.        lpThreadAttributes,
  8.        bInheritHandles,
  9.        dwCreationFlags,
  10.        lpEnvironment,
  11.        lpCurrentDirectory,
  12.        lpStartupInfo,
  13.        lpProcessInformation
  14.        );
  15. ...
复制代码
完整代码:
https://github.com/h0pe-ay/HookTechnology/tree/main/Hook-HotPatch
总结

优点:制止多线程出错
缺点:不一定有热补丁的条件,就是不一定存在有垃圾指令
如64位步调的CreateProcessW函数的第一条指令是mov r11,rsp,但是后续的指令都必要用到r11寄存器的值,因此该指令不是无用指令。就不能上述热补丁的方法。
[img=720,364.7040737893928]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202406241628298.png[/img]

更多网安技能的在线实操练习,请点击这里>>
  

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

小小小幸运

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表