做ctf的pwn题时, 碰到dlresolve,IO_file或者堆上的一些题目时,如果重新编译带符号表的libc和ld,会方便我们程序的调试。 这里以ubuntu 16.04下libc-2.23版本为例,说明如何编译和使用libc和ld
glibc2.23下载地址
sudo mkdir -p /dbg/
sudo chown xxx:xxx /dbg/ # xxx为你的用户名
cd /dbg/
tar -xzvf ~ /glibc-2.23.tar.gz
cp -R glibc-2.23 build_i386 && cp -R glibc-2.23 build_x64
需要注意,如果使用虚拟机,请不要在共享区域编译。在不同文件系统下,会因为ln的硬链接无法建立而报错导致编译失败。
cd /dbg/build_x64
mkdir build && cd build
CFLAGS=" -g -g3 -ggdb -gdwarf-4 -Og"
CXXFLAGS=" -g -g3 -ggdb -gdwarf-4 -Og"
../configure --prefix=/dbg/glibc/
make -j4
make install
若不需要调试信息, CFLAGS,CXXFLAGS保存默认即可
# 安装如下依赖库
sudo apt-get install build-essential module-assistant
sudo apt-get install gcc-multilib g++-multilib
cd /dbg/build_i386
mkdir build && cd build
CC=" gcc -m32" CXX=" g++ -m32" \
CFLAGS=" -g -g3 -ggdb -gdwarf-4 -Og -Wno-error" \
CXXFLAGS=" -g -g3 -ggdb -gdwarf-4 -Og" \
../configure --prefix=/path/to/install --host=i686-linux-gnu
make -j4
make install
/dbg/glibc/lib 和 /dbg/glibc_i386/lib 中分别分别可以找到64位和32位的libc和ld
r = process ("/dbg/glibc/lib/ld-2.23.so ./level6_x64" .split (" " )) # ld会从/dbg/glibc/lib中加载libc
# 如果程序需要加载系统的so,可以
r = process ("/dbg/glibc/lib/ld-2.23.so --library-path /lib/x86_64-linux-gnu/ ./level7_x64" .split (" " )) # 改变加载动态库so路径
# 或者将系统so复制到/dbg/glibc/lib/路径中
B. 改变LD_LIBRARY_PATH环境变量,但是这样只用我们编译libc,不能调ld
os .environ ['LD_LIBRARY_PATH' ] = '/dbg/glibc/lib/'
C. 用gdb调试时,如果没有出现C代码, 可以“add-symbol-file /dbg/glibc/lib/ld-2.23.so ld_address” ,其中ld_address是动态库的加载地址