如何解决LNK2019错误:在函数GsDriverEntry中引用了未解析的外部符号DriverEntry?

6

当我正在编译这个项目 https://github.com/namazso/hdd_serial_spoofer 的时候,遇到了上述错误信息,请问我该如何解决?我正在使用vs 2017和wdk 10。

(必须在发布模式下编译,不支持调试模式。此项目中没有DriverEntry函数,hwid.cpp中的EntryPoint(void* ntoskrn, void* image, void* alloc)函数是真正的入口点。)

我做了很多研究,但仍然无法使其工作。我是内核模式驱动程序开发的新手。


你尝试过以发布模式编译吗? - OrdoFlammae
5个回答

6
该项目使用(显然被忽略的)选项<EntryPointSymbol>EntryPoint定义为入口点。
这在此处有文档记录,但当前的文档似乎只适用于.exe和.dll项目。
所调用的消息形式来自Windows驱动程序系统。
NTSTATUS DriverInitialize(
  _DRIVER_OBJECT *DriverObject,
  PUNICODE_STRING RegistryPath
)

不兼容项目中的入口点。
EntryPoint(void* ntoskrn, void* image, void* alloc)

这并不糟糕,因为调用EntryPoint的参数都没有被使用。所以最简单的实现方法是:
extern "C"
{
    DRIVER_INITIALIZE DriverEntry;
    _Use_decl_annotations_
        NTSTATUS
        DriverEntry(
            struct _DRIVER_OBJECT  *DriverObject,
            PUNICODE_STRING  RegistryPath
        )
    {
        EntryPoint(NULL, NULL, NULL);
        return STATUS_SUCCESS;
    }
}

内核开发不是一件容易的事情,如果在计算机上运行无效的内核代码可能会导致启动困难,在极端情况下甚至会损坏计算机。我没有审核过项目中任何代码的正确性。

请在虚拟机(vmware、virtualbox、hyper-v)中运行代码,以限制它可能造成的破坏。


抱歉问了一些愚蠢的问题,我现在已经弄明白了。 - iouvxz

5
这不是一般的驱动程序,WDF直接支持的那种。它是一种“无驱驱动程序”,使用了一种未经记录的黑客技术,吸引了那些为了乐趣和利润而编写rootkit的程序员。DriverEntry()函数实际上不是驱动程序的入口点,而是回调函数。就像WinMain()函数实际上不是本地Win32程序的入口点一样。项目源代码中的EntryPoint()函数是本地驱动程序入口点的替代品。请注意,该项目似乎具有类rootkit的行为,旨在欺骗检查驱动器序列号的简单复制保护方案。
在正常的KMDF驱动程序中,GsDriverEntry()函数是真正的入口点。它执行必要的初始化以支持/GS编译器选项,旨在检测缓冲区溢出。完成后,它调用DriverEntry()。该项目将此入口点替换为EntryPoint()。
该项目是使用Visual Studio项目模板的旧版本编写的。需要进行几个更改才能正确构建。
  • C/C++ > 代码生成 > 安全检查。必须为“禁用安全检查 (/GS-)”,原始项目文件已经正确设置。
  • 相同的属性页面 > 控制流保护。必须设置为“否”以防止链接器错误。此选项添加了无法工作且必须禁用的其他安全检查。
  • C/C++ > 常规 > SDL 检查。使用下拉箭头覆盖为“继承自父级”,使选项为空白。需要禁用更多的安全检查,抑制 sdl- 与 /gs- 不兼容的警告。
  • 相同的属性页面 > 警告级别。覆盖为“Level3 (/W3)”,抑制有关未使用函数参数的警告。
  • 链接器 > 输入 > 附加依赖项。单击下拉箭头 > 编辑。取消选中“从父级继承”复选框并更改为 $(DDK_LIB_PATH)ntoskrnl.lib。请注意,Inherited values 列表框中的 $(KernelBufferOverflowLib) 条目解析为 bufferoverflowfastfailk.lib,它包含 GsDriverEntry() 并产生链接器错误。
  • 链接器 > 高级 > 入口点。必须为“EntryPoint”,原始项目模板设置正确。

在这之后,它会进行干净的构建。我没有测试生成的hwid.sys文件,因为它看起来有点邪恶,不想让我的机器受到影响。


2
不要使用 ".cpp" 源代码文件来编写驱动程序。将它们改成 ".c" 文件即可,这对我很有效。记住,Windows 内核代码是 C 代码,Visual Studio 会根据源代码文件的扩展名作出各种假设。

1
只需在NTSTATUS返回值前加上extern "C"即可,就像这样:

extern "C" NTSTATUS

extern "C" NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
 //your driver code
}

0

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