编译glibc,以期源码调试

一、编译安装

我在这里下载了libc的源代码:wget http://ftp.gnu.org/gnu/glibc/glibc-2.31.tar.gz

(可以下载不同的版本,比如,把glibc-2.31换为glibc-2.27即可)

然后我们解压它,拿到源代码: tar -zxvf glibc-2.31.tar.gz

创建目录等:

cd glibc-2.31
mkdir build && cd build

接着就是编译安装:

CFLAGS="-g -g3 -ggdb -gdwarf-4 -Og -Wno-error" \
CXXFLAGS="-g -g3 -ggdb -gdwarf-4 -Og -Wno-error"
sudo ../configure --prefix=/home/zq/Desktop/glibc-2.31/64 --disable-werror
sudo make
sudo make install

 

二、报错和解决方案

在编译的过程中遇到了如下问题:

(1)使用ubuntu 16 ,编译libc-2.23和libc-2.27没有问题,但是在libc-2.31的时候报错:

*** These critical programs are missing or too old: compiler

应该是gcc的版本太低,升级的命令是这样的:

sudo add-apt-repository ppa:ubuntu-toolchain-r/test 
sudo apt-get update 
sudo apt-get install gcc-9
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 100
sudo update-alternatives --config gcc

 

(2)*** These critical programs are missing or too old: gawk

  解决办法是:sudo apt-get install gawk

(3)

/tmp/ccD0p2ka.s: Assembler messages:
/tmp/ccD0p2ka.s: Error: `loc1@GLIBC_2.2.5' can't be versioned to common symbol 'loc1'
/tmp/ccD0p2ka.s: Error: `loc2@GLIBC_2.2.5' can't be versioned to common symbol 'loc2'
/tmp/ccD0p2ka.s: Error: `locs@GLIBC_2.2.5' can't be versioned to common symbol 'locs'

  解决办法:把misc目录下的regexp.c做些修改

@@ -29,14 +29,18 @@
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_23)
 
-/* Define the variables used for the interface.  */
-char *loc1;
-char *loc2;
+#include <stdlib.h>    /* Get NULL.  */
+
+/* Define the variables used for the interface.  Avoid .symver on common
+   symbol, which just creates a new common symbol, not an alias.  */
+char *loc1 = NULL;
+char *loc2 = NULL;
+
 compat_symbol (libc, loc1, loc1, GLIBC_2_0);
 compat_symbol (libc, loc2, loc2, GLIBC_2_0);
 
 /* Although we do not support the use we define this variable as well.  */
-char *locs;
+char *locs = NULL;
 compat_symbol (libc, locs, locs, GLIBC_2_0);
 
 

  把如上代码保存为reg.patch文件

  然后修改regexp.c文件:patch ./glibc-2.23/misc/regexp.c  <  ./reg.patch

 

 (4)我在ubuntu 20 总不能编译成 glibc-2.23,于是我在ubuntu 16 编译了glibc-2.23,打包拷贝到ubuntu 20 然后解压

 

 

三、测试

现在我们不使用默认的libc,而是用刚刚安装的libc来编译一个程序,看看有没有安装成功:

写一个简单的程序:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main(){
    puts("hello world!");
    char * s1=malloc(0x20);
    read(0,s1,0x10);
    return 0;
}

我们使用指定的libc来编译:

 gcc -g -L /home/zq/Desktop/glibc-2.31/64/lib -Wl,--rpath=/home/zq/Desktop/glibc-2.31/64/libs -Wl,-I /home/zq/Desktop/glibc-2.31/64/lib/ld-2.31.so hello.c -o hello

我们现在去调试,程序里有malloc这个函数,我们就看一下它的源代码:

gdb hello

b malloc

r

 

但是我们做pwn题的时候,一般没有源代码,只是一个elf文件

当靶机libc版本和我们本地机器上libc版本不同的时候,就需要加载指定的libc,比如2.27 、2.31等

还是刚才那个程序,默认libc去编译它:gcc hello.c -o hello1

我们用ida看一下它是怎样寻找libc的,这里出现了ld-linux-x86-64.so.2的路径,估计会通过它,找到待加载的libc.so

 

 

我们试着把这个路径换为,我们期望加载的libc对应的ld-linux.so.2所在的目录,本来是想把它换为绝对路径(/home/zq/Desktop/glibc-2.31/64/lib/ld-linux-x86-64.so.2),但是好像行不通,于是缩减字符个数,换为相对路径

我们把elf文件挪到 /home/zq/Desktop/glibc-2.31/64 ,然后相对路径就是 ./lib/d-linux-x86-64.so.2 。

用ida去patch:

 

如果patch之后,运行报错: No such file or directory 

可以使用这个工具来patch:https://github.com/NixOS/patchelf

 

在hello1文件所在目录(即/home/zq/Desktop/glibc-2.31/64)写个脚本,看能不能正常调试:

from pwn import *
sh=gdb.debug("./hello1")
sh.interactive()

我们在read函数下断点,看下read的源代码:

再看一下堆块的情况:

程序加载了libc-2.31.so

 

posted @ 2021-01-23 01:36  田埂  阅读(4604)  评论(1编辑  收藏  举报