使用简单的C++编写内核模式程序?

12

我准备深入内核领域,我的问题与编程语言有关。我看过大部分教程都是用C语言编写的。我目前使用的是C++和汇编语言编程。我之前也学过C语言,但没有多少使用经验。我想知道是否可能仅使用简化的C++在内核模式下进行编程,而不使用任何高级构造?基本上,我试图避免两种语言之间存在的细微差异(例如C语言中没有boolmain函数没有自动返回0,真正微小的差异)。我不会使用模板、类等。那么,在没有任何主要麻烦的情况下,是否可以使用简单的C++在内核模式下进行编程?


你是指Windows内核开发还是其他操作系统的开发? - Thierry Franzetti
Windows内核开发,抱歉。 - devjeetroy
1
如果您认为C语言过于简单,那么C++就更加复杂了... - sehe
4
你可能想阅读微软对该主题的评论。如果阅读后有更具体的问题,请另外提出新问题。 - Jerry Coffin
我并不是这个意思,我只是想说不要使用任何主要的C++语言特性。 - devjeetroy
2
在不使用主要 C++ 特性的情况下,使用 C++ 是相当困难的。 - Dave Rager
4个回答

18
即使没有官方支持,你也可以使用C++作为Windows内核开发的开发语言。但需要注意以下几点:
  • 必须定义新的和删除的操作符来映射到ExAllocatePoolWithTag和ExFreePool。

  • 尽量避免虚拟函数。似乎无法控制对象vtable的位置,如果它在可分页部分中并且您的代码在IRQL >= DISPATCH_LEVEL下被调用,则可能会产生意外结果。

  • 如果仍然需要使用虚拟方法表,请在IRQL>=DISPATCH_LEVEL之前锁定.rdata段后再使用。

除此类限制,您可以使用C ++进行驱动程序开发。

1
+1 对于虚函数表的陷阱。我正要提到同样的事情。 - Dave Rager
谢谢!我看到这里涉及到一些复杂性。你会建议使用C还是C++?我有点困惑。 - devjeetroy
2
将C++用作更好的C是可行的。问题出现在编译器生成代码时——包括模板、虚函数表、默认构造函数和标量删除存根等内容。您无法控制C++编译器决定发出这些内容的可执行文件部分,这意味着当需要它们的代码不能进行分页时,它们可能是可分页的。这可能会导致一些严重的问题。不过,如果您小心谨慎,可以避免这种情况。 - Stewart
3
在WDK 8中,可以在类级别上实现分页控制,从而确保vtable的位置。另一个值得一提的事情是不要使用异常。 - SomeWittyUsername

4

3
如果你仔细编写代码,了解每个定义、运算符、调用等背后的确切含义,那么使用C++编写内核代码就不会有问题。上面评论中提到的Microsoft文档是一份很好的阅读材料,因为它描述了C++不如C透明或无法提供类似重要保证的情况,从而让你知道应该避免哪些问题。

3

微软编写了一份指南。基本上他们告诉我们要避免使用除了C++的松散变量声明规则以外的任何东西... 唉。不过也不可能那么糟糕,但是这里有一些需要记住的例子:

  • 分页池中分配的内存可能会被分页出去。如果您在IRQL高于PASSIVE_LEVEL时尝试访问它,则会出现问题(或者至少当客户抱怨您的驱动程序使系统蓝屏时,您会偶尔遇到这种情况)!在低内存系统下测试您的驱动程序并加以负载!
  • 非分页池是有限的,您很可能无法从中分配所有所需。
  • 堆栈比用户模式下小得多,约为12-24K。
  • 任何涉及内核浮点路径的操作都必须受到KeSaveFloatingPointStateKeRestoreFloatingPointState的保护。
  • C++异常:不行

阅读指南了解更多。现在,如果您可以确保生成的代码遵循这些规则,请继续使用C++。


2
这个指南有点过时。Max NonPaged池的大小是物理RAM的一半,那么将所有代码标记为非页面的内存消耗量有多少?其他几点是正确的。 - Christopher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接