我正在分析 linux 平台(redhat)上的一个大型 C++ 项目,特别是其中使用的共享库。如何从特定的共享库中找到此项目中使用的符号(函数/变量)?
首先,我在二进制文件上运行以下命令:
readelf -d binaryName | grep -i "Shared library"
我得到了我的项目中使用的共享库的列表(ldd 显示了更长的列表,因为这些共享库也有自己的依赖项)例如
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libuv.so.1]
0x0000000000000001 (NEEDED) Shared library: [libssl.so.1.1]
0x0000000000000001 (NEEDED) Shared library: [libcrypto.so.1.1]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
现在有没有办法找出libuv.so.1
项目代码库中使用的符号。谁能建议一些路线图?
答案1
nm -uD /path/to/your/binary
将列出二进制文件中所有未定义的动态符号。然后您需要将其与输出相匹配
nm -gD /path/to/a/library
对于命令列出的每个库,readelf
以确定哪个库提供每个符号。
请注意,这并不一定给出完整的图片;特别是,通过访问的库和符号libdl
不会被考虑在内。如果你愿意的话跑步二进制文件,并且它使用 GNU C 库的动态加载器(ld.so
或者更确切地说,在 Linux 上),您可以通过在其环境中ld-linux.so
运行带有 set 的二进制文件来详细列出所有符号绑定。详情LD_DEBUG=bindings
请参阅。man ld.so
答案2
使用已接受答案中提供的信息和这里,我创建了以下脚本来查找二进制文件中当前使用的所有符号(取自共享库)。该脚本采用 1 个参数,即二进制文件的名称(如果二进制文件与脚本位于不同的目录中,则需要路径)。
该脚本将显示输入中给出的二进制文件所需的共享库。所有符号将转储到输出文件(result.txt)
#!/bin/bash
if [ "$#" -ne 1 ]
then
echo "1 argument needed in the script"
echo "e.g. $0 [binary name(complete path)]"
exit
fi
if [ -f $1 ]
then
echo "Going to find the unresolved symbols found in \"$1\""
else
echo "Binary file \"$1\" not found. Check name/path."
fi
binaryFile=$1
lddOutput=(`ldd $binaryFile | awk '{print $3}' | grep -v "0x" | awk 'NF >0'`)
#echo "$lddOutput"
sharedDependencies=()
echo "Given below are the shared libraries used in $1"
for lib in "${lddOutput[@]}"
do
sharedDependencies+=($lib)
ls -lrta $lib
done
rm -f allSymbols.temp
rm -f result.txt
# Iterate the loop to read and print each array element
#echo -e "\nGiven below are the dependencies found for $binaryFile\n"
#echo "SharedDependencies: ${sharedDependencies}"
for lib in "${sharedDependencies[@]}"
do
#echo "Will search below lib in sharedDependencies"
#echo $lib
#Create list of all text symbols from all the libraries
#for symbol in `nm -gD $lib | awk '{$1=""}1' | grep " T \| W \| V \| w \| v \| t " | awk '{print $2}'`;
#for symbol in `nm -gD $lib | grep -i " T \| W \| V "`;
nm -gD $lib | grep -i " T \| W \| V \| I " | while read symbol;
do
string=
sym=
#echo -e "\nsymbol->$symbol" >> debug.txt
n=`echo $symbol | awk "{print NF}"`
#echo -e "n->$n\n" >> debug.txt
if [ $n -eq 2 ]
then
sym=`echo $symbol | awk '{print $2}'`
else
sym=`echo $symbol | awk '{print $3}'`
fi
string="$lib contains $sym"
echo $string >> allSymbols.temp
#echo $string >> debug.txt
done
done
undefinedDynamicSymbols=`nm -uD $binaryFile | awk '{print $2}'`
#echo -e "\n\nUndefinedDynamicSymbols\n$undefinedDynamicSymbols\n"
for undefinedSymbol in $undefinedDynamicSymbols;
do
echo $undefinedSymbol >> result.txt
grep -w $undefinedSymbol allSymbols.temp >> result.txt
echo -e "\n" >> result.txt
done
echo "symbols dumped in result.txt"
rm -f allSymbols.temp