我对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_EXECUTEIMAGE_SCN_MEM_READIMAGE_SCN_MEM_WRITEIMAGE_SCN_MEM_DISCARDABLEIMAGE_SCN_CNT_CODEINIT部分似乎包含驱动程序条目,这意味着它可能用于确保驱动程序条目函数驻留在非分页内存中,而其余代码则允许分页。不过,我不太确定。我在驱动程序代码中没有看到任何证据表明开发人员显式地设置了页面标志,或者强制驱动程序进入一个单独的部分,所以看起来编译器是自动完成的。我还手动翻转了驱动程序二进制文件中的可写标志来测试它,而且它在不启用写入的情况下工作得很好,因此这意味着没有必要使用RWX。
所以,我的问题是:
我到目前为止看过的参考资料:
编辑,2022年:我忘了更新它,但是在我发布了这个问题一段时间后,我把它传递给了微软,结果它确实是MSVC链接器中的一个bug。他们错误地将包含DriverEntry的丢弃部分标记为RWX。这个问题是用VS2015解决的。
发布于 2015-06-30 19:31:07
在Windows环境中,INIT部分用于什么.
它通常用于DriverEntry()函数。
如何在Windows内核中处理可丢弃的部分?
它允许丢弃包含DriverEntry()函数代码的页。在初始化驱动程序之后不再需要它们。
为什么编译器会将驱动程序条目移动到INIT部分?
NDIS驱动程序通常包含
#pragma NDIS_INIT_FUNCTION(DriverEntry)它是WDK's inc/ddk/ndis.h头文件中的宏:
#define NDIS_INIT_FUNCTION(_F) alloc_text(INIT,_F)#pragma alloc_text是将函数移动到特定部分的方法之一。另一种常见的方法是将DriverEntry函数与#pragma code_seg(INIT)和#pragma code_seg()放在括号中。
为什么编译器将该节标记为RWX?
这需要考古学的挖掘。许多驱动程序是很久以前就开始使用的,很可能还会使用~VS6 6,那时的生活仍然很简单,程序员们戴着白帽。或者程序员使用了#实用化部分,还有一种命名部分的方法,它允许直接设置属性。现代工具链肯定做不到这一点,您可以从#实用化alloc_text获得RX。考虑到DriverEntry()存在的时间很短,任何使用ring0特权运行的恶意代码都会造成更大的实际损害,对它的担忧是没有什么意义的。
发布于 2022-07-10 15:58:55
我把这个信息传递给了微软,结果发现它是MSVC链接器中的一个bug。他们错误地将包含DriverEntry的丢弃部分标记为RWX。此问题已在2015中修复。
关于这个问题,我写了更详细的这里。
https://stackoverflow.com/questions/31142728
复制相似问题