編譯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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM