一 背景
也許大家都遇到過這種場景,就是有二進制代碼,比如深度分析下此文件到底是什么格式的圖片等,這篇文章就記錄我分析下二進制可執行文件的過程,已經自己讀寫二進制文件的一些坑。分析的二進制執行文件為linux下的可執行文件。
二 常用二進制文件靜態分析命令
2.1 file基本信息查看
linux下有個最常用的通用命令,來分析任何文件的基本格式,那就是file
,來看下:
可以看到基本信息,比如是什么類型文件,只是概述,還有些其他選項,可以用-h
查看。
2.2 ldd動態鏈接庫信息
動態鏈接庫,即沒有在編譯鏈接的時候直接打入到程序中的,而是運行時候動態加載了,從而節省內存,通過動態連接庫,我們可以知道這個可執行文件用了哪些動態庫,方法也比較簡單。 這是我寫的一個小程序的動態鏈接庫信息,通過鏈接庫分析的信息也同樣比較少,用這個命令多查看依賴鏈接庫找不到的問題。
2.3 nm符號查看
nm可以列出二進制可執行文件,動態庫,靜態庫中的符號信息,包括符號的類型,符號名稱,比如函數名,全局變量等,通過這些信息可以看到不少有用的信息,通過函數名猜函數功能,使用的幫助如下:
配合grep信息可以很方便的進行符號搜索:
對於一些動態庫,直接nm可能查不到信息,可以通過nm -D
命令查看。
2.4 strings 查看二進制文件中的字符串
strings信息可以打印二進制文件中的字符串信息,結合grep進行搜索,用grep
命令其實可以直接在二進制文件中搜索內容,但是不夠直觀,用strings看起來的更直觀些: strings 會把任何可打印字符串都顯示出來,比nm的內容更多,截取部分如下:
2.5 objdump 將二進制代碼轉匯編指令
objdump是個值得深入學習的指令,不光可以還原匯編指令,還可以讀取二進制中特定段的信息,更可怕的是,如果我們的程序是以-g -o0
等調試不優化的情況下,用objdump -S
指令可能盡可能地還原源代碼信息(沒看錯,是還原出源代碼信息),其實也可以理解這些信息是完整的在可執行文件中的,要不然gdb調試的時候沒辦法單步追蹤了,測試如下:
2.6 readelf 讀取ELF文件格式
如果二進制文件是ELF格式的,通過file
文件可以查看文件格式.使用readelf
指令可以方便分析ELF文件的結構,比如節信息,elf頭文件信息,比如我們在分析文件是否為病毒文件的時候,需要讀取elf文件頭信息,做一些特征的判斷,或作為特征參與機器學習的判斷。

還有些其他命令,有興趣的小伙伴,可以通過-h
命令還原看下。
三 動態查看文件結構
3.1 ltrace 跟蹤進程調用庫函數過程
這也是一個很棒的命令,我們可以查看程序執行的時候調用庫函數信息,還可以在線查看執行的進程的庫函數調用情況,找幾個比較典型的命令,測試的代碼比較簡單如下:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
short shs[5] ={1,234,567,789,890};
int ins[5] ={890,88111,23333,7777,6666};
FILE * fp = fopen("a.bin","wb");
for (int i = 0; i < 5; i++) {
fwrite(&shs[i],sizeof(short),1,fp);
fwrite(&ins[i],sizeof(int),1,fp);
}
printf("read....\n");
fclose(fp);
fp = fopen("a.bin","rb");
short a;
int b;
for (int i = 0; i <5;i++) {
fread(&a,sizeof(short),1,fp);
fread(&b,sizeof(int),1,fp);
printf("i:%d a:%d,b:%d\n", i,a,b);
}
fclose(fp);
return 0;
}
3.1.1 ltrace 查看庫函數調用情況

3.1.2 ltrace 查看庫函數調用占用時間
這在查看系統調用耗時很有用。
# -T 是查看調用時間開銷
ltrace -T
#-t -tt -ttt 是查看調用絕對時間,t越多越精確
ltrace -t

3.1.3 ltrace 查看系統調用信息
ltrace -S
系統調用信息顯然比庫函數顯示更多,追蹤更復雜的情況可以使用。
還有-p pid
追蹤具體的進行id的調用情況也很有用,這里面就不舉例子了。 如果沒有這個命令,如果是centos環境可以通過yum install -y ltrace
安裝。
3.2 strace
strace和ltrace的命令差不多,strace更偏向於系統調用的追蹤或信號產生的情況。安裝命令 yum -y install strace
強大地方在於可以指定系統調用的類型:
-e trace=set
只跟蹤指定的系統 調用.例如:-e trace=open,close,rean,write表示只跟蹤這四個系統調用.默認的為set=all.
-e trace=file
只跟蹤有關文件操作的系統調用.
-e trace=process
只跟蹤有關進程控制的系統調用.
-e trace=network
跟蹤與網絡有關的所有系統調用.
-e strace=signal
跟蹤所有與系統信號有關的 系統調用
-e trace=ipc
跟蹤所有與進程通訊有關的系統調用
-e abbrev=set
設定 strace輸出的系統調用的結果集.-v 等與 abbrev=none.默認為abbrev=all.
-e raw=set
將指 定的系統調用的參數以十六進制顯示.
-e signal=set
指定跟蹤的系統信號.默認為all.如 signal=!SIGIO(或者signal=!io),表示不跟蹤SIGIO信號.
-e read=set
輸出從指定文件中讀出 的數據.例如:
-e read=3,5
-e write=set
比如以下命令:
還有很多有用的選項,有興趣的可以嘗試下。
3.3 GDB命令
gdb命令其實是我們最常用的,調試程序的利器,用來查看二進制文件的結構,非常合適,可以把程序運行起來通過gdb -p pid
方便地調試。 也可如下運行: 基本命令說明下:
set args 設置參數
b main 設置中斷位置為main函數
r 開始運行
l 打印當前的函數內容
p 打印變量值
四 圖形化界面分析二進制執行文件
網上找到一個圖形化界面分析二進制程序的,名字叫Relyze
雖然是收費的,但是可以正常用一段時間,一段時間后才提示,界面如下,強大之處在於可以顯示調用關系信息等。 其實原理都類似,沒有比命令行更多的功能,只是看起來更方便而已。
4.1 基本文件信息

4.2 頭和段信息查看

4.3 搜索

4.4 調用關系圖
雙擊可以看到調用關系圖信息,便於做進一步分析。
其他的也沒啥特殊點了,有興趣的朋友可以下載試試。
五 詩詞欣賞
浣溪沙
[宋] [秦觀]
漠漠輕寒上小樓,曉陰無賴似窮秋,淡煙流水畫屏幽。
自在飛花輕似夢,無邊絲雨細如愁,寶簾閑掛小銀鈎。