【W(wǎng)SL-DEBUG】修復(fù)WSL下GDB無法debug的錯誤(2022-12-23)
GDB 在 WSL 下 debug 時提示 :?
warning: opening /proc/PID/mem file for lwp xxxxx.xxxxx failed: No such file or directory (2)
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x.......
錯誤發(fā)生的原因在于 WSL 中沒有對?/proc/PID/mem 提供支持。
老版本的 GDB 在找不到 /proc/PID/mem 文件時,會轉(zhuǎn)而使用 ptrace,而新版本的 GDB 則禁用了 ptrace,默認(rèn) /proc/PID/mem 是存在的。然而?WSL1 和 WSL2? 中目前都沒有這個文件。
解決方法:
修改 GDB 的二進(jìn)制,讓他支持 ptrace。
1. 打開 WSL,cd 到 gdb?的二進(jìn)制路徑,輸入?explorer.exe . (不要漏掉后面的點)用windows的文件資源管理器打開當(dāng)前目錄,找到 gdb,將他復(fù)制粘貼到 windows 中的任意目錄(不要放在 WSL 里)。
2. 用逆向工具 IDA?免費版(?官方下載地址:https://www.hex-rays.com/ida-free/?) 打開剛剛粘貼出來的 gdb,打開方式默認(rèn)即可。
3. 使用 " search for text " 查找 linux_proc_xfer_memory_partial

得到以下結(jié)果,看它的 function 地址:
????????

看上面紅框框出來的地方,我這里是 sub_30E3D0 (不同二進(jìn)制不一樣)。
4. 定位到上一步找到的 function?入口地址(.text:000000000030E3D0):

前面修改 rbp rsp 的那一坨不管他,直接看下圖紅框部分

導(dǎo)致 GDB 出錯的是紅框里的第二條指令,這是一個跳轉(zhuǎn)指令,當(dāng) gdb 發(fā)現(xiàn) mem 不存在,就從這里跳到錯誤處理點了。在這里,它的地址是 0x30E41D (記下來)

注意上圖在不同二進(jìn)制中可能不一樣,比如某些指令出現(xiàn)順序可能會不同,不用太在意,只需要找到 cmp esi 1 后面的那條跳轉(zhuǎn)指令就好啦。同時注意對比一下上下的幾條指令是不是都跟上圖長得差不多,不要找錯位置了(如果你在運行完第 5 步后發(fā)現(xiàn)地址不小心找錯了,那需要重新安裝 gdb,然后再次運行 5 中的命令)
5. 回到 WSL ,輸入以下命令,注意用你的二進(jìn)制中的跳轉(zhuǎn)指令地址替換 0x30E41D
echo -ne '\x90\x90' | sudo dd of=/usr/bin/gdb seek=$((0x30E41D)) bs=1 count=2 conv=notrunc
,回車。
再次運行g(shù)db:按序輸入以下命令(這里用于測試 gdb 的二進(jìn)制文件名為 ts)
gdb --> file ts?--> b main --> run --> 讓你下一個東西,選擇 y(yes) --> 下載完成后,不出意外的話,gdb 正常工作。

上面提示讓設(shè)置永久生效,可以將 set debuginfod enabled on 寫進(jìn) .gdbinit
在 home 目錄下?vim .gdbinit,把 "set debuginfod enabled on" 粘進(jìn)去,保存退出,搞定。
參考文獻(xiàn):https://github.com/microsoft/WSL/issues/8356