首先,不要问我有什么用这个问题很无聊。开发语言
开发起因之前分析过一个某大厂的驱动文件,其后来使用的内核HOOK技术,堪称神龙不见首尾。排除使用虚拟化技术后,几乎把整个内核翻烂了都看不见他挂钩的痕迹,并且在它有可能执行的函数完全没有发现它的任何调用,我很郁闷,研究了有2个多月。在研究过程中发现内核很多可以挂钩的地方,现在开源的就是其中一种。除了ntoskrnl灯下黑较少之外,其他相关对硬件操作(如网卡 硬盘 等外设驱动)几乎到处可以HOOK,当然,这些核心驱动也是在PG的监视下的,但是他们有很多空间可以对其进行魔改。在我上诉困扰的研究期间,我光对文件系统的HOOK 在内核层中都发现了不下十处不被PG监视的可挂钩区域。
使用方法易语言的调用源码、驱动源码和成品都打包在压缩包中,安装驱动后点修改即可。特殊说明由于是从完整工程里面临时拆分出来的,所以源码比较乱。在win10测试正常,7系统可能需要修改wdk重新编译驱动
在对IOCTL_NDIS_QUERY_GLOBAL_STATS处理部分,之前上传的,这一部分代码是从吾爱破解论坛开源的代码申引过来的,源码中和原贴也有注明该部分是转载,但是没想到原贴作者很不大度,于是将其部分完全删除!开源的原因纯属知识共享,因此,我花了五分钟时间找了个更加优秀简单的HOOK位置,让使用易语言的朋友也能了解这一部分实现过程,以下详细解析上述2种挂钩位置的摸索经过。
1.ndisNsiEnumerateAllInterfaceInformation这一部分底层函数主要是由iphlpapi模块调用,最终进入内核过程是nsiproxy-netio-ndis,本源码中对netio模块进行hook,挂钩其虚函数。在跟踪这一系列签派时发现,最终实现是从netio进入 NsiEnumerateObjectsAllParametersEx进入的ndis模块,而netio是最后一给拥有虚函数指针的模块,所有我们将在这里挂钩。我们在使用IDA 分析的时候,发现函数首中有一段NsiNmpList,网卡设备列表的数据结构数组
并且向下跟踪后,会发现是从 v81 = (*((__int64 (__fastcall **)(__int128 *))v23 + 8))(v102); 这里进入实现call(这里便是我提到的虚函数。)
于是我们只需要获取到NsiNmpList这个指针地址,如同伪代码一样枚举,而后修改这个函数的指针便能实现HOOK,详情源码所示。在这个函数的回调过程中会得到一个 struct iphl { ULONG64 x3; ULONG64 x4; ULONG64 x5; ULONG64 x6; ULONG64 x7; ULONG64 x8; ULONG64 x9; PCHAR macData; SIZE_T macBuffsize; PCHAR NetData; SIZE_T NetBuffsize; SIZE_T Count; };如此结构的数组,依次遍历修改macData 便可实现修改效果。
2.IOCTL_NDIS_QUERY_GLOBAL_STATS由于借鉴的原作者这一部分不允许引用他的代码否则会发生诉讼,所以我重新找了一份更加简单的挂钩方法,代码量只有原来的十分之一。
我们在ida对ndis进行反编译 ,直接搜索IOCTL_NDIS_QUERY_GLOBAL_STATS操作码0x170002后会到达如下代码段。
在单步跟踪后我们发现,mac是由ndisQueryDeviceOid这个函数返回出来的,我们在ndisQueryDeviceOid这个函数,对返回的地址下写入硬件断点,最终达到如下位置。
我返回上一层地址,发现这里是一个虚函数,那么操作空间就来了
在我们自己手打计算出这个虚函数地址 回调函数直接复制原函数的伪代码便能实现IOCTL_NDIS_QUERY_GLOBAL_STATS操作码的HOOK
IOCTL_NDIS_QUERY_GLOBAL_STATS 一般是用于DeviceIoControl主动通讯获取mac 或者wmi的获取mac会在这里实现,在我的测试源码中易语言也写有这部分。