关于Hook,有一本书讲的比较清楚,最近刚刚看完,《Rootkits: Subverting the Windows Kernel》

http://www.amazon.com/Rootkits-Subverting-Windows-Greg-Hoglund/dp/0321294319

总结下来,Hook的方法有以下几种:

1.修改各种table,IAT/IDT/SSDT

涉及到函数调用的原理,OS,每个bin文件都会维护各种Table,函数调用,系统调用,中断响应都会reference这些table来确定跳转的目的地址。

所以,通过修改这些table的信息,可以达到一些hook的目的

2.修改函数入口的汇编

特别是win32,函数的入口前几个Byte的汇编都是蛮规律的,修改函数入口的几个Byte,用一个jump指令来替换,jump到hook的函数,执行完了再jump回来。

这个办法是下面会详细讲到的。

3.安装filter Driver.

自己create一个driver,通过IoAttachDevice/IoDetachDevice来附加到对应的设备,以后每次发给设备的信息都会先送到我们的driver里面。

会涉及到windows driver,IRP, IRP stack等知识。

4.修改Kernel object。

当我们进入kernel mode的时候,我们就可以修改很多kernel的结构,譬如process list。Processs list是一个LIST_ENTRY的双链表。

通过回去当前的process,可以遍历到所有的process。

对于每个Process的LIST_ENRTY,我们可以修改对应的FLINK,BLINK,来remove一个节点。

所以那些通过遍历process LIST_ENTRY来遍历Process的办法,我们就可以隐藏相应的Process.

/******** 下面会具体讨论Solution 2 *******/

Mark:SetWindowsHookEx,好像可以修改文件的IAT表来Hook...

这两天在想怎么port到x64上去,发现有一些的一些难点:

1. compiler for X64 don't support inline assemble了,所以不能用汇编来修改a.写保护,b.添加jmp指令

2. x64版本函数入栈的方式不像x86那么规律了,每个函数入口指令都不一样

为了hook正常运行,需要保证在调回到函数执行时,ebp,esp,堆栈内容都要保持不变

想到的办法:

函数入口直接改写成call xxx,并保存原来的指令,在ret之前修改stack里面的返回地址为原函数入口,并且恢复 for NdisRegisterxxx

么啥好办法yet...强制该汇编....

Helps:

windows提供一下函数_disable(), __writecr0(ULONG)等来替代一些原本需要汇编来做的操作。(注册表可以cancel写保护)

单独写.asm文件,这个貌似没什么帮助

=================

原理蛮好理解的,就是替换了windows api函数入口的汇编代码,用一个5个byte的长跳转jmp指令跳转到自己写的函数,执行完之后再jmp回来。

先来看一段windows x86函数入口前后的汇编指令(平台有别):

(Ps: 5byte的nop指令一般都是compiler预留,可用于patch一个长跳转, move edi,edi: 2byte可替换成一个段跳转)

-5: nop
-4: nop
-3: nop
-2: nop
-1: nop
function:
0000-0000: move edi, edi
0000-0002: push ebp
0000-0003: move ebp, esp
0000-0005: sub esp, xxxx

不过有几个地方我还是蛮困惑的:

1.因为函数调用的时候有很多register是上下文相关的,compiler帮忙都配置好了用哪些register。怎么保证跳转过去的函数使用的register跟先前的能够匹配呢。

[Answer]: function call的时候,会把需要保存的register保存到stack, Jmp过去之后,不从register里面拿信息,所以也不会影响。当然platform dependent,不同的调用规范行为不一样,这里讨论windows 32bit,linux函数调用的时候会把一些参数放在register里,以提高速度。

2.hook函数执行完之后,在jmp回到先前函数+5的地方开始执行,这时候register context也可能都改变了啊。

[Answer]:不依赖register的值,只要stack没有破坏,ebp没被改坏就没事,一般都是ebp+xx, ebp-xx来拿参数的,其实就算esp变了也不要紧,函数结束一般都有mov esp, ebp 恢复esp的值。

3.先前函数那5个byte对应的指令怎么办,略过了?要是先前函数+5的地址不是一个完整的指令起始地址呢?

[Answer]:本代码刚好在jmp到hook_func的时候,执行了同样的5byte指令,而且本代码hook的函数入口+5byte都刚好是完整的指令地址,这些都是tricky的地方,不通用。

http://www.cnblogs.com/StudyRush/archive/2011/03/06/1966553.html 这篇文章对于函数调用写的比较清楚。

粗略的先post一些code.

VOID DisableIntChangeRight( PULONG pOldAttr){ULONG uAttr;_asm{cli;push eax;mov eax, cr0;mov uAttr, eax;and eax, 0FFFEFFFFh; // CR0 16 BIT = 0mov cr0, eax;pop eax;};*pOldAttr = uAttr;
}
VOID EnableIntRestoreRight( ULONG uOldAttr ){_asm{push eax;mov eax, uOldAttr;mov cr0, eax;pop eax;sti;};
}
VOID InterceptFunction( PDEVICE_EXTENSION deviceExtension, HOOKINDEX Index, PVOID pOriginalFunc, PVOID pDestFunc){UINT uAttrib;UINT OffsetJump;UCHAR JumpCode[] = { 0xe9, 0x01, 0x02, 0x03, 0x04}; // Code inserted to pOriginalFunc to jump to pDestFuncPCHAR pString = NULL;if (deviceExtension->CodeHooked[Index] == TRUE){DebugPrint((ERROR, "Function %s already hooked.\n", pString));return;}else {DebugPrint((INFO, "Function %s hooked.\n", pString));DisableIntChangeRight(&uAttrib);
        // First backup to be overwritten code.RtlCopyMemory((PCHAR)(deviceExtension->BackupCode[Index]), (PCHAR)pOriginalFunc, \                                              sizeof(deviceExtension->BackupCode[Index]));// Second calculate jmp pDestFunc and overwriteOffsetJump = (UINT)pDestFunc - (UINT)pOriginalFunc - 5;*(PUINT)&JumpCode[1] = OffsetJump;RtlCopyMemory((PCHAR)pOriginalFunc, JumpCode, sizeof(JumpCode));deviceExtension->BackAddress[Index] = (ULONG_PTR)pOriginalFunc + 5;deviceExtension->CodeHooked[Index] = TRUE;EnableIntRestoreRight(uAttrib);}return;
}VOID RestoreFunction( PDEVICE_EXTENSION deviceExtension, HOOKINDEX Index){UINT uAttrib;PCHAR pString = NULL;if (deviceExtension->CodeHooked[Index]){DebugPrint((TRACE, "Function %s restored.\n", pString));DisableIntChangeRight(&uAttrib);deviceExtension->CodeHooked[Index] = FALSE;RtlCopyMemory((PCHAR)(deviceExtension->BackAddress[Index] - 5),(PCHAR)(deviceExtension->BackupCode[Index]), sizeof(deviceExtension->BackupCode[Index]));EnableIntRestoreRight(uAttrib);}else {DebugPrint((TRACE, "Function %s is not hooked at all.\n", pString));}return;
}

  

转载于:https://www.cnblogs.com/zzSoftware/p/3285894.html

写一篇Hook Driver.相关推荐

  1. 如何写一篇好的技术博客

    在工作过程中,发现对很多东西都一知半解,不是很透澈,到头来很容易模糊,如果有一篇好的技术博客予以总结,一来即使忘记了,回国头来再看,仍然能 够从自己的思路中恢复:二来总结一下,还会发现一些潜在问题:三 ...

  2. [译] 如何写一篇杀手级的软件工程师简历

    原文地址:How to write a killer Software Engineering résumé 原文作者:Terrence Kuo 译文出自:掘金翻译计划 本文永久链接:github.c ...

  3. 想写一篇关于.net下COM工作原理的文章

    今天想写一篇关于.net下COM工作原理的文章.花了大概3个小时,文章也写的差不多了,可是越写到后来越发现自己的观点以及想法越错误. 边写边查MSDN,最后不得不放弃发布这篇文章了.虽然花了好几个小时 ...

  4. 如何写一篇MBA论文-涉及matlab建模

    如何写一篇MBA论文? 知乎 · 19 个回答方向,具体一点,不要太大.战略管理.薪酬管理.绩效考核.营销管理,客户关系管理.供应链管理.供应商选择与评价,库存问题..论文模式第1章:绪论第2章:现状 ...

  5. 怎样写一篇优秀论文?看完受益匪浅!

    我在念书的时候,有一位欧洲史.英国史的大师 Lawrence Stone ,他目前已经过世了,曾经有一本书访问十位最了不起的史学家,我记得他在访问中说了一句非常吸引人注意的话,他说他英文文笔相当好,所 ...

  6. 用计算机弹奏曲子童年,5.这首曲子使我想起了我的童年.十.书面表达现在.计算机游戏非常盛行.这是一件好事还是一件坏事?请你用英语写一篇短文来陈述自己的观点.并说明理由.字数:80-120....

    5.这首曲子使我想起了我的童年.十.书面表达现在.计算机游戏非常盛行.这是一件好事还是一件坏事?请你用英语写一篇短文来陈述自己的观点.并说明理由.字数:80-120.[查看更多] 题目列表(包括答案和 ...

  7. 如何写一篇合格的论文(清华大学刘知远)

    目录 你需要知道的真相: 一篇论文的典型结构 Introduction 怎么写(先写introduction再写abstract) (1)起手介绍研究任务和意义 (2)随后简介面向这个任务的已有方法 ...

  8. element-UI组件el-button样式覆写 - 生效篇

    踩坑:el-button样式覆写 表单代码参考: <!-- 表单区域 --> <div class="wd1200 form-container">< ...

  9. 软件设计师 一年考几次_一年写106篇文章如何帮助我成长为设计师

    软件设计师 一年考几次 by Tiffany Eaton 蒂芙尼·伊顿(Tiffany Eaton) 一年写106篇文章如何帮助我成长为设计师 (How writing 106 articles in ...

最新文章

  1. java基本数据类型自动转包装类_java基本数据类型和包装类相互转换
  2. 【RAC】RAC 实现IP访问控制
  3. 为什么选择Netty作为基础通信组件?
  4. 2021-11-18哈希值
  5. 【渝粤题库】国家开放大学2021春1258房屋建筑混凝土结构设计题目
  6. 46个PPT下载丨QCon 2019年全球软件开发大会PPT
  7. 基于JAVA+Servlet+JSP+MYSQL的二手房交易系统
  8. 【MyBatis笔记】07-MyBatis 核心配置文件
  9. How MapReduce Works
  10. android viewpager切换无法显示fragment问题
  11. js便签笔记(5)——Dean Edwards大牛的跨浏览器AddEvent()设计(不知道是不是jQuery事件系统的原型)...
  12. php拍照虚线上传图片,照片怎么添加白色虚线 给照片上的人物周围添加虚线描边效果|照片处理工具...
  13. 毕业设计 大学生心理健康管理平台
  14. 华为云文字识别关键技术和特别需要注意的事宜
  15. 从零开始学习3D可视化之爆炸图
  16. 与 WinHTTP Web Proxy Auto-Discovery Service 服务相依的 DHCP Client 服务因下列错误而无法启动
  17. 第七十三集 KVM虚拟化☜(゚ヮ゚☜)
  18. 解决台式机麦克风不可用问题,只有音频输出,无音频输入
  19. 域用户指定计算机,什么是AD域,如何设置AD域用户仅登录到指定的计算机
  20. 为什么易语言程序被360和windows安全中心认作是病毒?

热门文章

  1. python 自动登录网站_python实现网站用户名密码自动登录功能
  2. 场论 梯度 旋度 散度
  3. ios 搭建php,超级签名网源码+ios分发+签名端本地化+文字搭建教程_PHP源码
  4. json 文档拆分工具_如何把PDF多页文档拆为单页?快看高手私藏实用的技巧
  5. 魅族android面试题,【魅族小米IT面试题】面试问题:Android… - 看准网
  6. oracle catalog命令,使用Catalog命令注册RMAN备份集
  7. Lesson6 how to use HTML QT Widgets
  8. Lesson 4 Part 2 Softmax Regression
  9. Lesson 1 Hello World
  10. 自动划分-------训练集+验证集+测试集(code,自己设置比例)