IDA 正確加載 libc.so 等動態庫的調試信息


問題分析

在動態調試程序的時候,用gdb調試到libc的時候能正確加載符號信息,但同樣的程序用IDA調試到libc的時候卻缺失了libc中的許多符號,

這其實是IDA沒有正確加載DWARF調試信息(debuginfo)所導致的

根本原因是系統中沒有對應的調試信息(可以裝libc6-dbg),或是調試信息所在的位置不正確

到網上找了一圈,發現IDA不能像gdb一樣指定調試信息所在的目錄,所以即便下載了調試信息也沒辦法直接加載,於是事情就變得有點復雜了

IDA官網上給出的解釋是當前僅支持加載PDB,而不支持加載DWARF

Currently, only PDB files are supported.

不過去逆一下linux_server就會發現,其實IDA是支持加載DWARF的,只不過調試信息的路徑默認為空,而且IDA沒有提供方法對其進行修改

 

解決方法有四種

第零種方法:使用Load DWARF file插件,不過這個好像只能加載主程序的調試信息

第一種方法:把調試信息拷貝到優先級高的/usr/lib/debug/.build-id下,再通過patch修改linux_server的調試信息加載目錄

第二種方法:給調試信息換個名字,比如libc-2.23.so.debug,避免和原來的libc-2.23.so重名

第三種方法:用IDC腳本加載調試信息

第四種方法:把調試信息附加到動態庫上

這里推薦使用第一種方法,不用每次都修改二進制文件,比較方便

 

如圖,雖然用的是帶調試信息的libc,但是Load debug symbols的時候Output window會輸出如下錯誤信息,這是因為加載了錯誤的libc-2.23.so

 

解決方案

准備工作

首先要下載libc對應的調試信息,對應的方法比較多

1、sudo apt-get install libc6-dbg

2、https://github.com/matrix1001/glibc-all-in-one

3、https://mirror.tuna.tsinghua.edu.cn/ubuntu/pool/main/g/glibc/下載對應版本的libc6-dbg_*.deb包,再用dpkg -i安裝

 

解決方法一

下面主要用libc6-dbg演示,另外兩種方法同理

切換工作目錄到/usr/lib/debug/lib/x86_64-linux-gnu

執行以下命令,復制調試信息到/usr/lib/debug/.build-id下

for file in `ls`
do
        buildid=`readelf -n $file|grep 'Build ID'|awk '{print $3}'`
        dir=`echo $buildid | cut -c1-2`
        fn=`echo $buildid | cut -c3-`
        sudo mkdir -p /usr/lib/debug/.build-id/$dir
        sudo cp $file /usr/lib/debug/.build-id/$dir/$fn
        sudo cp $file /usr/lib/debug/.build-id/$dir/${fn}.debug
done

再對linux_server進行修改

1、在.rodata段中找地方寫入字符串/usr/lib/debug/

2、對0x4163A3處的指令進行修改,將操作數改成字符串/usr/lib/debug/的所在位置

這樣在調試的時候,IDA就會到/usr/lib/debug/.build-id下加載調試信息了

當需要加載libc信息的時候進行以下操作

1、Start/Attach debugged process

2、Pause debugged process

3、Modules->libc-2.23.so->Load debug info

4、Modules->libc-2.23.so->Analyze module

 

解決方法二

下面主要用glibc-all-in-one演示,另外兩種方法同理

切換工作目錄到glibc-all-in-one/libs/2.23-0ubuntu10_amd64

然后執行以下命令,對libc進行修改

objcopy -R .gnu_debuglink ./libc-2.23.so
objcopy --add-gnu-debuglink=libc-2.23.so.debug ./libc-2.23.so
mv .debug/libc-2.23.so .debug/libc-2.23.so.debug

再執行以下命令修改要調試的文件,使其加載修改后的libc

patchelf --set-interpreter `pwd`/ld-2.23.so 你的程序
patchelf --replace-needed libc.so.6 `pwd`/libc-2.23.so 你的程序

當需要加載libc信息的時候進行以下操作

1、Start/Attach debugged process

2、Pause debugged process

3、Modules->libc-2.23.so->Load debug info

4、Modules->libc-2.23.so->Analyze module

 

解決方法三

先用IDA打開對應的調試信息

選擇File->Produce file->Dump database to IDC file...

打開導出的IDC腳本進行修改

1、寫一個函數,將base設置為調用腳本時IDA的EA所選中的地址

static ask_libcbase(void)
{
  auto ea=get_screen_ea();
  base=ask_addr(ea,"input libc base");
}

2、將原來地址的0X7EFE替換為base-0X7EFE21CF9000+0X7EFE,這里的0X7EFE21CF9000是libc加載的基地址,要根據實際導出的IDC腳本進行修改

3、注釋掉delete_*函數調用

4、注釋掉create_*函數調用

5、注釋掉make_*函數調用

當需要加載libc信息的時候進行以下操作

1、Start/Attach debugged process

2、Pause debugged process

3、Modules->libc-2.23.so->Jump to moudle base

4、File->Script File

5、Modules->libc-2.23.so->Analyze module

 

解決方法四

參考:https://stackoverflow.com/questions/15977961/how-to-undo-strip-i-e-add-symbols-back-to-stripped-binary

 

運行結果

用IDA來Start或者Attach你的程序

點擊右側的Modules->libc-2.23.so->Load debug symbols

 等待左下角顯示AU:idle加載完成,此時仍有Name信息加載不全的問題

 再點擊Modules->libc-2.23.so->Analyze module

然后耐心等待調試信息加載完成

最后的效果如下,_IO_FILE_plus_1等結構體都能被很好地識別,在右側注釋中有對應的成員信息,而且偽代碼也能正常生成了

 

注意事項

apt里的patchelf是0.9版本的,有Bug

要自己到Github上編譯0.10版本的才能正常使用

 

參考文獻

1、https://blog.csdn.net/chinainvent/article/details/24129311?reload

2、https://www.douban.com/note/350501219/

3、https://stackoverflow.com/questions/34293646/how-to-add-debug-symbols-to-stripped-elf-binaries

4、https://stackoverflow.com/questions/15977961/how-to-undo-strip-i-e-add-symbols-back-to-stripped-binary

5、https://www.hex-rays.com/products/ida/support/idadoc/1457.shtml


免責聲明!

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



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