windows - 如果标记为 RWX,可丢弃部分对内核驱动程序有什么影响?

标签 windows security kernel driver ndis

我对 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 部分似乎包含驱动程序入口,这意味着它可能用于确保驱动程序入口函数驻留在非分页内存中,而其余代码允许分页.不过,我不完全确定。我在驱动程序代码中看不到任何证据表明开发人员明确设置了页面标志,或者强制驱动程序进入一个单独的部分,所以看起来编译器自动完成了。我还手动翻转了驱动程序二进制文件中的可写标志以对其进行测试,并且它在没有启用写入的情况下工作正常,因此这意味着不需要 RWX。

所以,我的问题是:

  • INIT 部分在 Windows 驱动程序上下文中的用途是什么?为什么将其标记为可丢弃?
  • Windows 内核如何处理可丢弃的部分?我对 how ReactOS handles them 有一些想法但这仍然很模糊,并没有太大帮助。
  • 为什么编译器会将驱动程序入口移动到 INIT 部分?
  • 当 RX 足够且 RWX 可能构成安全问题时,为什么编译器会将此部分标记为 RWX?

到目前为止我看过的引用资料:


编辑,2022:我忘了更新这个,但在我发布这个问题一段时间后,我将它传递给了 Microsoft,结果证明它是 MSVC 链接器中的一个错误。他们错误地将包含 DriverEntry 的丢弃部分标记为 RWX。此问题已在 VS2015 中修复。

最佳答案

What is the INIT section used for in the context of a Windows...

它通常用于 DriverEntry() 函数。

How are discardable sections treated in the Windows kernel?

它允许丢弃包含 DriverEntry() 函数代码的页面。初始化驱动程序后不再需要它们。

Why would the compiler move the driver entry to an INIT section?

NDIS 驱动程序通常包含

   #pragma NDIS_INIT_FUNCTION(DriverEntry)

这是WDK的inc/ddk/ndis.h头文件中的一个宏:

   #define NDIS_INIT_FUNCTION(_F)      alloc_text(INIT,_F)

#pragma alloc_text 是将函数移动到特定部分的方法之一。另一种常见的方法是将 DriverEntry 函数与 #pragma code_seg(INIT)#pragma code_seg() 括起来。

Why would the compiler mark the section as RWX

这需要考古挖掘。许多驱动程序是很久以前开始的,并且可能仍在使用 ~VS6,那时候生活还很简单,程序员戴着白帽子。或者也许程序员使用了#pragma section,这是另一种命名部分的方法,它允许直接设置属性。现代工具链肯定不会这样做,您从#pragma alloc_text 获得 RX。考虑到 DriverEntry() 的生存时间非常短,并且任何以 ring0 权限运行的恶意代码都可能造成更多的实际损害,因此担心它没有什么意义。

关于windows - 如果标记为 RWX,可丢弃部分对内核驱动程序有什么影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31142728/

相关文章:

windows - 玩框架看不到JRE

php - 这个 mail() 函数对于 header 注入(inject)是安全的吗?

c - 函数原型(prototype)与否?

linux - 如何从 "struct linux_binprm"获取 argv?

sql-server - SQL 和 ColdFusion 加密

linux - 添加其他对象后内核模块未加载

windows - Windows 10 上的 react-native cli 工具语法错误

c++ - Windows 上的字符串大小与 Linux 上的不同

c# - Web 浏览器控件忽略 FEATURE_BROWSER_EMULATION reg 条目

cookies - 当通过 https 连接时,将用户密码存储在 Cookie 中有什么风险?