易语言资源网 - 做最全的易语言资源下载社区
精易论坛授权登录
当前位置:易语言资源网 > C++ > 帖子内容

(内核级)修改物理虚拟网卡MAC地址   [复制链接]

    2024-06-06 09:02:47
    C++
    易语言资源网
    633 次浏览
    来源链接

首先,不要问我有什么用这个问题很无聊。开发语言

实现原理通过对内核层ndis,netio 的虚函数HOOK 实现的最接近底层获取实现的劫持。技术解释r3层要获取mac无论使用什么方法最终进入内核态只有NtDeviceIoControlFile函数。其中微软封装的获取mac函数只有iphlpapi模块,另外也可以通过NtDeviceIoControlFile 的IOCTL_NDIS_QUERY_GLOBAL_STATS操作码得到mac。在NtDeviceIoControlFile 进入内核态后会通过irp派遣执行nsiproxy-netio-ndis,最终由ndis从已经加载在内核的网卡驱动设备列表枚举出已经开系统启动时加载到内存的mac值,最后依次返回到应用层。这里要说明的是IOCTL_NDIS_QUERY_GLOBAL_STATS 可以返回的是  8字节的mac地址 和 0x104字节的mac 地址和一些网卡信息通过irphook很好实现对IOCTL_NDIS_QUERY_GLOBAL_STATS 获取的内容篡改。而iphlpapi获取的有两种,一种是SendARP ,另外一种 GetAdaptersInfo。GetAdaptersInfo进入irp后也是经过nsiproxy-netio-ndis最后去调用ndisNsiEnumerateAllInterfaceInformation内核函数。它是一次性完成的,ndisNsiEnumerateAllInterfaceInformation会返回所有网卡的所有信息。

开发起因之前分析过一个某大厂的驱动文件,其后来使用的内核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会在这里实现,在我的测试源码中易语言也写有这部分。



点我下载 (已有 41 次下载)

[错误报告]   上一篇:取文件hash值-控制台程序-支持文件/...     下一篇:[例程]NX线程池 MySql连接池 超...