저는 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