windows 如何解决LNK2019无法解析的外部符号DriverEntry在函数GsDriverEntry中引用?

ego6inou  于 2023-10-22  发布在  Windows
关注(0)|答案(5)|浏览(241)

当我在编译这个项目https://github.com/namazso/hdd_serial_spoofer时,
我收到了上面的错误信息,我该如何解决这个问题?我使用的是VS 2017和WDK 10。
(Must在发行版中编译,不支持调试模式。此项目中没有DriverEntry函数,hwid.cpp中的EntryPoint(void* ntoskrn,void* image,void* alloc)函数是真实的入口点。)
我做了很多研究,但仍然没有得到它的工作。我是一个菜鸟在内核模式驱动程序开发。

k4emjkb1

k4emjkb11#

只需在NTSTATUS返回值之前使用extern“C”,如下所示:

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

dzjeubhm2#

有几个原因产生的问题。在我的例子中,代码中的try/except可以在x64上编译,但不能在x86上编译。

链接器工具错误LNK 2019https://learn.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-error-lnk2019?view=msvc-170

qij5mzcb

qij5mzcb3#

该项目使用(一个显然被忽略的)选项
<EntryPointSymbol>EntryPoint定义为条目。
这是文档here,但目前的文档似乎意味着这是真的只有.exe和.dll项目。
从Windows驱动程序系统调用的消息的形式

NTSTATUS DriverInitialize(
  _DRIVER_OBJECT *DriverObject,
  PUNICODE_STRING RegistryPath
)

与项目中的EntryPoint不兼容

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;
    }
}

内核开发不适合胆小的人,在计算机上运行无效的内核代码可能会使 Boot 变得困难,或者在极端情况下损坏计算机。我没有检查项目中的任何代码的正确性。
请在虚拟机(vmware、virtualbox、hyper-v)中运行代码,以限制其可能造成的损害

pod7payv

pod7payv4#

这不是WDF直接支持的那种普通驱动程序。它是一个“无人驾驶的驱动程序”,它使用了一个没有文档的黑客,吸引了那些为了乐趣和利润而编写rootkit的程序员。DriverEntry()函数实际上不是驱动程序的入口点,它是回调函数。就像WinMain()函数实际上不是原生Win32程序的入口点一样。项目源代码中的EntryPoint()函数是本机驱动程序入口点的替代。请注意,该项目似乎有rootkitty般的行为,旨在欺骗一个简单的复制保护方案,检查驱动器序列号。
GsDriverEntry()函数是一个普通的Kendash驱动程序中的真实的入口点。它执行基本的初始化以支持/GS compiler option,旨在检测缓冲区溢出。完成后,它调用DriverEntry()。项目将此入口点替换为EntryPoint()。
此项目是使用旧版本的Visual Studio项目模板编写的。要使其正确构建,需要进行以下几项更改:

  • C/C++ >代码生成>安全检查。必须是“禁用安全检查(/GS-)",原始项目文件得到了这个权利。
  • 相同的属性页> Control Flow Guard。必须设置为“否”以防止链接器错误。此选项添加了无法工作且必须禁用的其他安全检查。
  • C/C++ >常规> SDL检查。使用箭头“从父项继承”覆盖,使选项显示为空。需要禁用的更多安全检查,会抑制sdl-与/gs-不兼容的警告。
  • 相同属性页>警告级别。设置为“Level 3(/W3)",取消有关未使用函数参数的警告。
  • Linker > Input > Additional parameters.单击箭头>编辑。取消勾选“Inherit from parent”复选框并更改为$(DDK_LIB_PATH)ntoskrnl. lib。请注意,Inherited values列表框中的$(KernelBufferOverflowLib)条目解析为bufferoverflowfastfailk.lib,它包含GsDriverEntry()并产生链接器错误。
  • 链接器>高级>入口点。必须是“EntryPoint”,原来的项目模板得到了正确的。

在此之后,它会变得干净。我没有测试产生的hwid.sys,看起来有点太邪恶,暴露我的机器。

nwwlzxa7

nwwlzxa75#

不要使用.cpp源文件来编写驱动程序。将它们更改为.c,应该可以工作。对我来说就是这样。
我知道这看起来微不足道,或者不太可能,但请记住Windows内核代码是C代码,Visual Studio会根据源文件的文件扩展名做出各种假设。

相关问题