---
title: Debug libc with GDB
description: 為了動態觀察 libc 原始碼意外學到的招,紀錄一下
tags: CTF
lang: zh_tw
---
# Debug libc with GDB
[TOC]
## Intro

這篇達成的效果就是
你的 GDB 上半部會顯示 libc source code
中間會是對應的組合語言
下半部則是 GDB command line
然後這篇會再紀錄基本操作方式
最後附上官方文件連結
下面的步驟就帶一個實例
## 步驟
### 下載 source code
上網搜尋 glibc source code 就能搜到了吧
連結在 [註1](https://ftp.gnu.org/gnu/glibc/)
我這邊只想追蹤 malloc,把 malloc.c 複製出來到自訂的位置上
```
cp glibc-2.23/malloc/malloc.c /path/to/the/source/code/
```
### 編譯程式
在用 gcc 編譯時加上 `-g`,產生 debugging information
```
-g Produce debugging information in the operating system's native format (stabs,
COFF, XCOFF, or DWARF). GDB can work with this debugging information.
On most systems that use stabs format, -g enables use of extra debugging
information that only GDB can use; this extra information makes debugging work
better in GDB but probably makes other debuggers crash or refuse to read the
program. If you want to control for certain whether to generate the extra
information, use -gstabs+, -gstabs, -gxcoff+, -gxcoff, or -gvms (see below).
```
我的程式長這樣
```c
// test.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
malloc(0x20);
}
```
編譯
```
gcc test.c -o test -g
```
### GDB!
先正常用 gdb 打開你的程式
這邊用沒有裝任何套件的 gdb
```
gdb test
```
在 gdb 中下指令讓 gdb 知道 source code 在哪邊
```
directory /path/to/the/source/code/
```
再來就是進入 [TUI mode](https://sourceware.org/gdb/current/onlinedocs/gdb/TUI.html#TUI)
**只要按下 Ctrl+x 再按 a 進入 TUI mode**

斷點斷在 main,然後執行
```
b *main
r
```

**按下 Ctrl+x 再按 2 切換 layout**

此時按方向鍵上下你會發現是捲動 source code,不是自動填之前的指令
那是因為現在 active window 是 source code
**按下 Ctrl+x 再按 o 來切換 active window**
讓我們來看看主角 malloc 裡面的 source code
斷點斷在 `__libc_malloc` 中,並繼續執行
```
b *__libc_malloc
c
```

成功看到對應的組語啦!!
**此時使用 `ni` 是執行一條組合語言指令**
**而 `n` 是執行一行 source code**
中間組語想切換成 intel 格式嗎?
```
set disassembly-flavor intel
```
再切換回普通模式,一樣按 Ctrl+x 再按 a
再執行下一條指令`ni`,就能看到變化
想斷點斷在 source code 的某一行?
用以下指令
```
b malloc.c:2914
```
gdb 就會自動在對應的組合語言下斷點嚕
好奇某個變數現在的值是啥?

```
p/x nb
```
如圖中,可以看到 nb 的值現為 0x30
而且也能推測 `get_max_fast ()` 最終就是 `0x7ffff7dd37f8 <global_max_fast>`
他的值也能用以下指令抓出來
```
p/x global_max_fast
```
得到此值為 0x80
## Reference
1. [glibc source code](https://ftp.gnu.org/gnu/glibc/)
2. [GDB TUI mode](https://sourceware.org/gdb/current/onlinedocs/gdb/TUI.html#TUI)