我对PE文件部分标志中的DISCARDABLE
标志感兴趣,特别是在Windows驱动程序(在这种情况下为NDIS)的情况下。 我注意到INIT
部分在我正在审查的驱动程序中被标记为RWX,这看起来很奇怪 – 好的安全实践说你应该采用W ^ X策略。
该部分的转储如下:
Name Virtual Size Virtual Addr Raw Size Raw Addr Reloc Addr LineNums RelocCount LineNumCount Characteristics INIT 00000B7E 0000E000 00000C00 0000B200 00000000 00000000 0000 0000 E2000020
特点映射到:
IMAGE_SCN_MEM_EXECUTE
IMAGE_SCN_MEM_READ
IMAGE_SCN_MEM_WRITE
IMAGE_SCN_MEM_DISCARDABLE
IMAGE_SCN_CNT_CODE
INIT
部分似乎包含驱动程序条目,这意味着它可以用来确保驱动程序的入口函数驻留在非分页的内存中,而其余的代码允许分页。 虽然我不完全确定。 我可以在驱动程序代码中看到没有证据显示开发人员显式设置页面标志,或者强制驱动程序进入单独的部分,因此看起来像编译器自动执行的。 我还手动翻转驱动程序二进制文件中的可写标志来testing它,并且它没有写入启用就可以正常工作,这意味着不需要RWX。
所以,我的问题是:
我到目前为止看过的参考文献:
在Windows环境中使用的INIT部分是什么?
它通常用于DriverEntry()函数。
在Windows内核中如何处理可丢弃的部分?
它允许包含DriverEntry()函数代码的页面被丢弃。 驱动程序初始化后不再需要它们。
为什么编译器将驱动程序条目移到INIT节?
NDIS驱动程序通常包含
#pragma NDIS_INIT_FUNCTION(DriverEntry)
这是WDK的inc / ddk / ndis.h头文件中的一个宏:
#define NDIS_INIT_FUNCTION(_F) alloc_text(INIT,_F)
#pragma alloc_text
是将函数移动到特定部分的方法之一。 另一个通用的方法是用#pragma code_seg(INIT)
和#pragma code_seg()
#pragma code_seg(INIT)
DriverEntry函数。
为什么编译器将该部分标记为RWX
这需要考古挖掘。 很多司机很早以前就开始了,很可能还会使用〜VS6,回来的时候生活还不简单,程序员戴白帽子。 或者,也许程序员使用了#pragma部分,而另一种命名部分的方式,它允许直接设置属性。 一个现代的工具链肯定不会这样做,你从#pragma alloc_text获得RX。 考虑到DriverEntry()生活的时间很短,任何以ring0权限运行的恶意代码都可能造成更多的实际损害,所以没什么意义。