能力值:
( LV12,RANK:300 )
|
-
-
2 楼
这个问题提得比较好。这点是对驱动进行IAT HOOK和对Ring3程序进行IAT HOOK的一个不同点,如果没有注意的话,我们很容易忽视。
这个问题的关键在于,由于驱动占用内核内存,为了节省内核资源消耗,在驱动中可以指定一个区段为“可丢弃的”,一般也就是INIT段,这个区段一般包括DriverEntry函数等内容,在DriverEntry调用完之后,这个区段里的内容不再需要被使用到,就可以被系统丢弃,这时这个区段的地址对于驱动来说实际上就不再有效了。
而WINDDK编译成的驱动的导入表相关结构,恰恰位于INIT段之中。因为导入表结构的存在只是为了在驱动加载时系统能够按照其结构填充IAT,驱动加载完毕后,就只需要IAT表存在,就可以正常工作,其他导入表结构如_IMAGE_IMPORT_DESCRIPTOR等没有必要再存在。因此DDK编译时就把这部分结构放在INIT段内,从而在驱动加载完之后丢弃。
而既然这块内存在加载后会被丢弃,那么在加载完成之后其内容就会发生不可预知的改变,从而不再有效。
因此,如果按照楼主说的,直接使用驱动模块在内核加载的首地址加导入表偏移来获取,会发现读取到的结果完全是错误的。
楼主可以使用WINDBG的Local Kernel Debug试一下手工读取ntoskrnl.exe等驱动的导入表结构,就会发现与你直接解析文件读取到的结果完全不一样。
正因为驱动加载完后导入表结构已经被清除了,在对驱动做IAT HOOK的时候,才必须通过直接读取硬盘中的文件自己做映像来读取导入表结构。
注意,对于导出表来说没有这个问题,因为导出表是为了让其他模块能够使用该模块中导出的函数和数据结构,因此导出表结构在驱动加载后仍然完好。
|
能力值:
( LV12,RANK:300 )
|
-
-
3 楼
当然,这是事后IAT HOOK,如果你是采用PsSetLoadImageNotifyRoutine,在驱动模块加载后的回调函数中进行IAT HOOK,那么此时DriverEntry还没有被调用,INIT段还没有被丢弃,驱动内存中的导入表结构就应该仍然有效,就不需要自己把文件进行映像再读取了。
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
谢谢楼上,讲的很详细
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
那驱动程序能用类似upx压缩的方式进行压缩吗?
|
能力值:
( LV3,RANK:20 )
|
-
-
6 楼
学习,学习...
|
能力值:
( LV4,RANK:50 )
|
-
-
7 楼
感谢分享!
|
|
|