记一次符号类型不一致导致的链接错误

发布时间:2026/7/30 2:17:18
记一次符号类型不一致导致的链接错误 记一次符号类型不一致导致的链接错误两个头文件在WDK中有两个头文件ntddk.h:包含 wdm.h传统的 NT 架构驱动非即插即用ntifs.h:包含 ntddk.h 和 wdm.h文件系统驱动、文件系统过滤驱动由于 ntifs.h 已经包含了 ntddk.h只需包含 ntifs.h 即可。同时包含两者可能导致类型重定义等编译错误。报错信息IoCtlHandler.obj : error LNK2019: 无法解析的外部符号 “public: static long __cdecl HelpTool::GetEprocess(void *,struct _EPROCESS * *)” (?GetEprocessHelpToolSAJPEAXPEAPEAU_EPROCESSZ)函数 “long __cdecl ProtectProcess(void *)” (?ProtectProcessYAJPEAXZ) 中引用了该符号符号类型不一致我的源代码中分别引用了上面的两个头文件。Windows WDK 头文件如 wdm.h / ntifs.h中的 PEPROCESS 定义会根据预处理器宏尤其是NT_KERNEL或 _KERNEL_MODE来决定到底是引用 _EPROCESS 还是 _KPROCESS。检查HelpTool.obj中导出的符号发现dumpbin /SYMBOLS .\HelpTool.obj Microsoft (R) COFF/PE Dumper Version 14.51.36252.0 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file .\HelpTool.obj File Type: COFF OBJECT COFF SYMBOL TABLE 000 01058D9C ABS notype Static | comp.id 001 C0010990 ABS notype Static | feat.00 002 00000000 SECT1 notype Static | .drectve Section length 2F, #relocs 0, #linenums 0, checksum 0 004 00000000 SECT2 notype Static | .debug$S Section length 2028, #relocs 0, #linenums 0, checksum 0 006 00000000 SECT3 notype Static | .bss Section length 1, #relocs 0, #linenums 0, checksum 0, selection 2 (pick any) 008 00000000 SECT3 notype External | ExPoolZeroingNativelySupported 009 00000000 SECT4 notype Static | .text$mn Section length 62, #relocs 3, #linenums 0, checksum 4519E64B, selection 1 (pick no duplicates) 00B 00000000 SECT5 notype Static | .debug$S Section length 144, #relocs 8, #linenums 0, checksum 0, selection 5 (pick associative Section 0x4) 00D 00000000 UNDEF notype External | __imp_DbgPrintEx 00E 00000000 UNDEF notype External | __imp_PsLookupProcessByProcessId 00F 00000000 SECT4 notype () External | ?GetEprocessHelpToolSAJPEAXPEAPEAU_KPROCESSZ (public: static long __cdecl HelpTool::GetEprocess(void *,struct _KPROCESS * *)) 010 00000000 SECT4 notype Label | $LN6 011 00000000 SECT6 notype Static | .xdata Section length C, #relocs 0, #linenums 0, checksum B9123A2D, selection 5 (pick associative Section 0x4) 013 00000000 SECT6 notype Static | $unwind$?GetEprocessHelpToolSAJPEAXPEAPEAU_KPROCESSZ 014 00000000 SECT7 notype Static | .pdata Section length C, #relocs 3, #linenums 0, checksum 92CEA7C6, selection 5 (pick associative Section 0x4) 016 00000000 SECT7 notype Static | $pdata$?GetEprocessHelpToolSAJPEAXPEAPEAU_KPROCESSZ 017 00000000 SECT8 notype Static | .text$s Section length 39, #relocs 0, #linenums 0, checksum 81C4C899, selection 2 (pick any) 019 00000000 SECT8 notype External | ??_C_0DJKDOKOJHK?$FLProtectMyProcess?3?3HelpTool?$FN?3?5GeFNODOBFM ( ?? ?? ::FNODOBFM::string) 01A 00000000 SECT9 notype Static | .debug$S Section length 3C, #relocs 2, #linenums 0, checksum 0, selection 5 (pick associative Section 0x3) 01C 00000000 SECTA notype Static | .debug$T Section length 7C, #relocs 0, #linenums 0, checksum 0 01E 00000000 SECTB notype Static | .chks64 Section length 58, #relocs 0, #linenums 0, checksum 0 String Table Size 0x145 bytes Summary 1 .bss 58 .chks64 21A8 .debug$S 7C .debug$T 2F .drectve C .pdata 62 .text$mn 39 .text$s C .xdata对比两个编译单元看到的函数签名IoCtlHandler.cpp报错方 期望的符号是GetEprocessHelpToolSAJPEAXPEAPEAU**_EPROCESS**Z参数为 struct _EPROCESS **HelpTool.obj导出的符号是?GetEprocessHelpToolSAJPEAXPEAPEAU**_KPROCESS**Z参数为 struct _KPROCESS **在编译 HelpTool.cpp 时编译器认为 PEPROCESS 是 struct _KPROCESS *而在编译 IoCtlHandler.cpp 时PEPROCESS 被解析为 struct _EPROCESS *。解决方案我把参数中的peprocess改为了pvoid类型反正eprocess在内核驱动开发中就是一个不透明的数据结构最终都是要使用基址偏移的方式访问其中的字段索性让它直接为pvoid类型。