MSYS2+MinGW64下ldd与objdump检测DLL依赖差异原因问询
核心问题:MSYS2下ldd与objdump检测PE依赖差异的底层原因
一、环境与操作回顾
1. 环境配置
使用2022年9月版MSYS2(安装包msys2-x86_64-20220904.exe),执行以下命令安装组件:
pacman -Suy \ mingw-w64-x86_64-gcc \ base-devel development \ sys-utils \ mingw-w64-ucrt-x86_64-toolchain mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain \ libmodbus \ mingw-w64-x86_64-codelite
2. 编译操作
- 确认编译器路径:
$ which gcc && which g++ && which clang /mingw64/bin/gcc /mingw64/bin/g++ /mingw64/bin/clang codelite &
- 在Codelite中配置32位MinGW编译器:
make C:/c/msys64/mingw32/bin/mingw32-make.exe -j8 SHELL=sh.exe makedir mkdir -p
- 通过生成的Makefile编译32位程序:
C:\WINDOWS\system32\cmd.exe /C C:/c/msys64/mingw32/bin/mingw32-make.exe -j8 SHELL=sh.exe -e -f Makefile ...[cut]... C:/c/msys64/mingw32/bin/g++.exe -c protocol_writer.cpp" -g -O0 -Wall -o Debug/protocol_writer.cpp.o -I. -I. C:/c/msys64/mingw32/bin/g++.exe -c scan_dtsu666_main.cpp" -g -O0 -Wall -o Debug/scan_dtsu666_main.cpp.o -I. -I. C:/c/msys64/mingw32/bin/g++.exe -o Debug/modbus-dtu-dump @"modbus-dtu-dump.txt" -L. -lmodbus ====0 errors, 0 warnings====
3. 依赖检测结果
- MSYS2的
ldd(路径/usr/bin/ldd)输出:
$ ldd modbus-dtu-dump.exe ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffdf2c70000) ntdll.dll => /c/Windows/SysWOW64/ntdll.dll (0x77310000) wow64.dll => /c/WINDOWS/System32/wow64.dll (0x7ffdf2510000) wow64win.dll => /c/WINDOWS/System32/wow64win.dll (0x7ffdf1be0000)
- MinGW的
objdump(路径/mingw64/bin/objdump)输出:
$ objdump --private-headers modbus-dtu-dump.exe | grep 'DLL' DLL Name: libgcc_s_dw2-1.dll DLL Name: KERNEL32.dll DLL Name: libmodbus-5.dll DLL Name: msvcrt.dll DLL Name: libwinpthread-1.dll DLL Name: libstdc++-6.dll
二、差异底层原因分析
1. ldd的检测逻辑与读取内容
你使用的是MSYS2原生的/usr/bin/ldd,它基于Cygwin实现,核心逻辑是模拟系统加载器加载程序,而非静态解析PE文件结构:
- 该ldd主要针对MSYS2自身的ELF格式程序,对MinGW生成的PE程序支持有限,不会直接读取PE文件的
Import Table(导入表)。 - 由于编译出的是32位PE程序,在64位MSYS2环境下,ldd会触发Windows的WOW64兼容层加载流程,此时输出的是WOW64层运行32位程序必须的底层系统DLL,而非程序直接导入的依赖。
- MinGW运行时DLL不在MSYS2 ldd的默认搜索路径中,因此无法被检测识别。
2. objdump的检测逻辑与读取内容
/mingw64/bin/objdump是MinGW配套的PE解析工具,它直接静态解析PE文件的Import Table:
- 导入表中仅记录程序编译时明确导入的DLL,包括MinGW运行时库、libmodbus依赖以及程序直接调用的Windows系统DLL(如
KERNEL32.dll、msvcrt.dll)。 ntdll.dll、wow64.dll等属于Windows加载器在启动32位程序时,由WOW64层自动加载的系统组件,不会被写入PE的导入表,因此objdump不会输出这些内容。
3. 路径配置的补充说明
若使用MinGW专属的ldd(路径/mingw32/bin/ldd或/mingw64/bin/ldd),而非MSYS2的/usr/bin/ldd,它会正确解析PE导入表,并搜索MinGW的DLL路径,输出结果将与objdump的直接依赖列表一致,同时会补充显示各DLL的实际路径。
三、64位编译的补充验证
切换到64位编译后,程序为64位PE,MSYS2的/usr/bin/ldd可直接加载检测,不会触发WOW64,因此能显示正确依赖,但核心差异的本质仍是两款工具的检测逻辑不同:一个依赖系统加载器与搜索路径,一个静态解析PE结构。
内容的提问来源于stack exchange,提问作者daisy reiss-zahn
相关产品推荐
相关产品推荐

