[GDB] 在 gdb 裡面顯示 process 當前環境變數的值
今天想要查一個 process 所使用的環境變數的值,
如果程式正在執行的話,可以直接印出 /proc/<pid>/environ 的內容,例如:
cat /proc/12345/environ
但如果今天是拿到一個 crash dump 的話,當然就沒辦法這麼做了~
用 gdb 開啟 core dump 之後,可以用 show environment 指令,
秀出程式執行開始時的環境變數值:
(gdb) show environment XDG_SESSION_ID=57462 TERM=xterm-256color SHELL=/bin/bash HISTSIZE=1000 OLDPWD=/root SSH_TTY=/dev/pts/5 QT_GRAPHICSSYSTEM_CHECKED=1 USER=root PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin LANG=en_US.UTF-8 PS1=\[\e[0;32m\]\u@\h \[\e[0;33m\]\w\[\e[0m\] \$ SHLVL=1 HOME=/root LOGNAME=root XDG_RUNTIME_DIR=/run/user/0 _=/usr/bin/gdb
但要注意的是這個方法只能秀出程式執行開始時,環境變數的值~
如果程式在執行當中,有增加或設定新的環境變數值,是看不到的…
舉例來說,我預期 core dump 裡的那個 process,
應該要有 P7ZIP_HOME_DIR 這個環境變數,可是卻找不到:
(gdb) show environment P7ZIP_HOME_DIR Environment variable "P7ZIP_HOME_DIR" not defined.
查了一下,下面的指令可以秀出前一百個「目前」的環境變數,
如果環境變數沒有這麼多個的話,就會看到 Address out of bounds 的訊息:
(gdb) x/100s *environ 0x7fffbec1c481: "XDG_SESSION_ID=55672" 0x7fffbec1c496: "HOSTNAME=localhost" 0x7fffbec1c4a4: "SHELL=/bin/bash" 0x7fffbec1c4b4: "TERM=xterm-256color" 0x7fffbec1c4c8: "HISTSIZE=1000" 0x7fffbec1c565: "SSH_TTY=/dev/pts/0" 0x7fffbec1c578: "QT_GRAPHICSSYSTEM_CHECKED=1" 0x7fffbec1c594: "USER=root" ....... ....... 0x7fffbec1d000: <Address 0x7fffbec1d000 out of bounds> 0x7fffbec1d000: <Address 0x7fffbec1d000 out of bounds> ....... .......
問題是要從這一大串輸出中,找到我們要的環境變數 P7ZIP_HOME_DIR,還真的是頗耗眼力…
幸好 gdb 可以利用 logging 加上 shell command 的功能,讓我們可以用 grep 的方式找到想要的字串~
方法是先用 set logging on 把 logging 打開,這時輸出都會寫到 gdb.txt,
再執行剛剛的 x/100s 指令秀出目前的環境變數值,接著把 logging 關掉,
最後再用 shell 指令來呼叫 grep 來過濾想找的字串~
下面就是用這幾個步驟,找出 P7ZIP_HOME_DIR 這個環境變數的值:
(gdb) set logging on Copying output to gdb.txt. (gdb) x/100s *environ 0x7fffbec1c481: "XDG_SESSION_ID=55672" 0x7fffbec1c496: "HOSTNAME=localhost" 0x7fffbec1c4a4: "SHELL=/bin/bash" 0x7fffbec1c4b4: "TERM=xterm-256color" 0x7fffbec1c4c8: "HISTSIZE=1000" 0x7fffbec1c565: "SSH_TTY=/dev/pts/0" 0x7fffbec1c578: "QT_GRAPHICSSYSTEM_CHECKED=1" 0x7fffbec1c594: "USER=root" ....... ....... 0x7fffbec1d000: <Address 0x7fffbec1d000 out of bounds> 0x7fffbec1d000: <Address 0x7fffbec1d000 out of bounds> ....... ....... (gdb) set logging off Done logging to gdb.txt. (gdb) shell grep P7 gdb.txt 0x7fffbec1c66a: "P7ZIP_HOME_DIR=/var/tool/p7zip"
參考資料:
Debugging with GDB: Your program’s environment
Finding environment variables with gdb, to exploit a buffer overflow
stackoverflow: How to grep on gdb print