一 背景
也許大家都遇到過這種場景,就是有二進制代碼,比如深度分析下此檔案到底是什麼格式的圖檔等,這篇文章就記錄我分析下二進制可執行檔案的過程,已經自己讀寫二進制檔案的一些坑。分析的二進制執行檔案為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:%dn", 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 調用關系圖
輕按兩下可以看到調用關系圖資訊,便于做進一步分析。
其他的也沒啥特殊點了,有興趣的朋友可以下載下傳試試。
五 詩詞欣賞
浣溪沙
[宋] [秦觀]
漠漠輕寒上小樓,曉陰無賴似窮秋,淡煙流水畫屏幽。
自在飛花輕似夢,無邊絲雨細如愁,寶簾閑挂小銀鈎。