linux下二進位制檔案分析
一 背景
也許大家都遇到過這種場景,就是有二進位制程式碼,比如深度分析下此檔案到底是什麼格式的圖片等,這篇文章就記錄我分析下二進位制可執行檔案的過程,已經自己讀寫二進位制檔案的一些坑。分析的二進位制執行檔案為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>
intmain(void)
{
shortshs[5]={1,234,567,789,890};
intins[5]={890,88111,23333,7777,6666};
FILE*fp=fopen("a.bin","wb");
for(inti=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");
shorta;
intb;
for(inti=0;i<5;i++){
fread(&a,sizeof(short),1,fp);
fread(&b,sizeof(int),1,fp);
printf("i:%da:%d,b:%d\n",i,a,b);
}
fclose(fp);
return0;
}
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
強大地方在於可以指定系統呼叫的型別:
-etrace=set
只跟蹤指定的系統呼叫.例如:-etrace=open,close,rean,write表示只跟蹤這四個系統呼叫.預設的為set=all.
-etrace=file
只跟蹤有關檔案操作的系統呼叫.
-etrace=process
只跟蹤有關程序控制的系統呼叫.
-etrace=network
跟蹤與網路有關的所有系統呼叫.
-estrace=signal
跟蹤所有與系統訊號有關的系統呼叫
-etrace=ipc
跟蹤所有與程序通訊有關的系統呼叫
-eabbrev=set
設定strace輸出的系統呼叫的結果集.-v等與abbrev=none.預設為abbrev=all.
-eraw=set
將指定的系統呼叫的引數以十六進位制顯示.
-esignal=set
指定跟蹤的系統訊號.預設為all.如signal=!SIGIO(或者signal=!io),表示不跟蹤SIGIO訊號.
-eread=set
輸出從指定檔案中讀出的資料.例如:
-eread=3,5
-ewrite=set
比如以下命令:
還有很多有用的選項,有興趣的可以嘗試下。
3.3 GDB命令
gdb命令其實是我們最常用的,除錯程式的利器,用來檢視二進位制檔案的結構,非常合適,可以把程式執行起來通過gdb -p pid
方便地除錯。
也可如下執行:
基本命令說明下:
setargs設定引數
bmain設定中斷位置為main函式
r開始執行
l列印當前的函式內容
p列印變數值
四 圖形化介面分析二進位制執行檔案
網上找到一個圖形化介面分析二進位制程式的,名字叫Relyze
雖然是收費的,但是可以正常用一段時間,一段時間後才提示,介面如下,強大之處在於可以顯示呼叫關係資訊等。
其實原理都類似,沒有比命令列更多的功能,只是看起來更方便而已。
4.1 基本檔案資訊
4.2 頭和段資訊檢視
4.3 搜尋
4.4 呼叫關係圖
雙擊可以看到呼叫關係圖資訊,便於做進一步分析。
其他的也沒啥特殊點了,有興趣的朋友可以下載試試。
五 詩詞欣賞
浣溪沙
[宋][秦觀]
漠漠輕寒上小樓,曉陰無賴似窮秋,淡煙流水畫屏幽。
自在飛花輕似夢,無邊絲雨細如愁,寶簾閒掛小銀鉤。