逆向分析之”花”。windows的Hook是程序设计中最为灵活多变的技巧之一。Hook有两种含义:1、系统提供的消息Hook机制;2、自定义的Hook编程技巧,
Hook(钩子)是WINDOWS提供的一种消息处理机制平台,是指在程序正常运
行中接受信息之前预先启动的函数,用来检查和修改传给该程序的信息,(钩子)实
际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,
在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。
钩取方式
如图,一般有三种API钩取方式:
下面都以Notepad.exe的WriteFile() API为例钩取
方式1——动态-进程内存
直接在API加载时调用钩取
动态-进程内存-代码-调试技术
若在生成exe文件是出现这个错误“GetModuleHandleW”: 不能将参数 1 从“const char [10]”转换为“LPCWSTR” 解决方法:
项目菜单->属性->配置属性->常规->项目默认值->字符集改为未设置
生成hook.exe 额,在调试的时候,运行hook.exe pid后发现nopad卡住啦,尴尬,怀疑可能是要在32位的系统下,然后又在32位的系统下运行,发现并不是系统问题。又怀疑是不是编译的时候开啦ALSR啦,关掉ALSR,还是不行,得看看代码啦。原来是代码错啦,这。。。。
运行结果:
总结: 这是代码动态注入,通过附件进程,触发异常,通过异常获取WriteFile()函数的信息,在WriteFile()函数首地址下断点,然后截取控制流程,再次触发异常,恢复WriteFile()函数首地址,并且获取线程的上下文,然后将WriteFile()函数读取的缓冲区读出,然后转换成目标数据后写入WriteFile()函数的缓冲区,恢复线程上下文,继续运行就可以hook成功啦。
方式2——IAT钩取
IAT的hook原理:在保持运行代码不变的前提下,将IAT中保存的API起始地址变为用户的起始地址。如图:
钩取前
钩取后
下面以计算器为例,讲解IAT的dll的hook.
hookiat.dll的hookiat.cpp
我们再看看hookd.exe的cpp
运行结果:
钩取
脱钩
个人总结:通过PE文件的结构,先获取线程基址,从ImageBase开始,经由PE签名找到IDT:
ImageBase->IDT->IAT(dll)->函数
方式3——进程隐藏
进程隐藏就是将要隐藏的进程藏在其他的进程中,实现进程隐藏的关键不是进程本身,而是其他进程。其中用户模式下最常用的是ntdll.ZwQuerySystemInformation() API钩取技术。
假如我们要隐藏test.exe进程,那么就要钩取ProcExp.exe(进程查看器或taskmgr.exe任务管理器)的ntdll.ZwQuerySystemInformation() API,
2个问题
1、钩取的进程数
如果进程查看器和任务管理器多开几个,那么进程钩取一个,那是不可以的,所以要钩取系统中运行的所有进程。
2、新创进程
如果当钩取了系统中运行的所有进程,这时又新建一个ProcExp.exe,而这个进程又没有被钩取。
解决
对于上面2个问题,我们隐藏test.exe进程时需要钩取系统中运行的所有进程的ntdll.ZwQuerySystemInformation() API,并且对后面将要启动的所有进程也进行相同的操作(当然这是全自动的啦),这叫全局钩取。
来源
逆向工程核心原理
最后,文学还是很重要的,借助诗圣两句提高文学素养
绝代有佳人,幽居在空谷。
但见新人笑,那闻旧人哭。
——佳人