从给定的共享库中查找代码中使用的函数/变量

从给定的共享库中查找代码中使用的函数/变量

我正在分析 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

相关内容