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

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

两个头文件

在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 * *)” (?GetEprocess@HelpTool@@SAJPEAXPEAPEAU_EPROCESS@@@Z),函数 “long __cdecl ProtectProcess(void *)” (?ProtectProcess@@YAJPEAX@Z) 中引用了该符号

符号类型不一致

我的源代码中,分别引用了上面的两个头文件。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     | ?GetEprocess@HelpTool@@SAJPEAXPEAPEAU_KPROCESS@@@Z (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$?GetEprocess@HelpTool@@SAJPEAXPEAPEAU_KPROCESS@@@Z
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$?GetEprocess@HelpTool@@SAJPEAXPEAPEAU_KPROCESS@@@Z
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@_0DJ@KDOKOJHK@?$FLProtectMyProcess?3?3HelpTool?$FN?3?5Ge@FNODOBFM@ ( ?? ?? ::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(报错方) 期望的符号是:?GetEprocess@HelpTool@@SAJPEAXPEAPEAU**_EPROCESS**@@@Z
    (参数为 struct _EPROCESS **)

  • HelpTool.obj导出的符号是:?GetEprocess@HelpTool@@SAJPEAXPEAPEAU**_KPROCESS**@@@Z
    (参数为 struct _KPROCESS **)

在编译 HelpTool.cpp 时,编译器认为 PEPROCESS 是 struct _KPROCESS *;而在编译 IoCtlHandler.cpp 时,PEPROCESS 被解析为 struct _EPROCESS *。

解决方案

我把参数中的peprocess改为了pvoid类型,反正eprocess在内核驱动开发中就是一个不透明的数据结构,最终都是要使用基址+偏移的方式访问其中的字段,索性让它直接为pvoid类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值