天天看點

linux 字元串截取_linux下可執行檔案分析

linux 字元串截取_linux下可執行檔案分析

一 背景

也許大家都遇到過這種場景,就是有二進制代碼,比如深度分析下此檔案到底是什麼格式的圖檔等,這篇文章就記錄我分析下二進制可執行檔案的過程,已經自己讀寫二進制檔案的一些坑。分析的二進制執行檔案為linux下的可執行檔案。

二 常用二進制檔案靜态分析指令

2.1 file基本資訊檢視

linux下有個最常用的通用指令,來分析任何檔案的基本格式,那就是

file

,來看下:

linux 字元串截取_linux下可執行檔案分析

可以看到基本資訊,比如是什麼類型檔案,隻是概述,還有些其他選項,可以用

-h

檢視。

2.2 ldd動态連結庫資訊

動态連結庫,即沒有在編譯連結的時候直接打入到程式中的,而是運作時候動态加載了,進而節省記憶體,通過動态連接配接庫,我們可以知道這個可執行檔案用了哪些動态庫,方法也比較簡單。

linux 字元串截取_linux下可執行檔案分析

這是我寫的一個小程式的動态連結庫資訊,通過連結庫分析的資訊也同樣比較少,用這個指令多檢視依賴連結庫找不到的問題。

2.3 nm符号檢視

nm可以列出二進制可執行檔案,動态庫,靜态庫中的符号資訊,包括符号的類型,符号名稱,比如函數名,全局變量等,通過這些資訊可以看到不少有用的資訊,通過函數名猜函數功能,使用的幫助如下:

linux 字元串截取_linux下可執行檔案分析

配合grep資訊可以很友善的進行符号搜尋:

linux 字元串截取_linux下可執行檔案分析

對于一些動态庫,直接nm可能查不到資訊,可以通過

nm -D

指令檢視。

2.4 strings 檢視二進制檔案中的字元串

strings資訊可以列印二進制檔案中的字元串資訊,結合grep進行搜尋,用

grep

指令其實可以直接在二進制檔案中搜尋内容,但是不夠直覺,用strings看起來的更直覺些:

linux 字元串截取_linux下可執行檔案分析

strings 會把任何可列印字元串都顯示出來,比nm的内容更多,截取部分如下:

linux 字元串截取_linux下可執行檔案分析

2.5 objdump 将二進制代碼轉彙編指令

objdump是個值得深入學習的指令,不光可以還原彙編指令,還可以讀取二進制中特定段的資訊,更可怕的是,如果我們的程式是以

-g -o0

等調試不優化的情況下,用

objdump -S

指令可能盡可能地還原源代碼資訊(沒看錯,是還原出源代碼資訊),其實也可以了解這些資訊是完整的在可執行檔案中的,要不然gdb調試的時候沒辦法單步追蹤了,測試如下:

linux 字元串截取_linux下可執行檔案分析

2.6 readelf 讀取ELF檔案格式

如果二進制檔案是ELF格式的,通過

file

檔案可以檢視檔案格式.使用

readelf

指令可以友善分析ELF檔案的結構,比如節資訊,elf頭檔案資訊,比如我們在分析檔案是否為病毒檔案的時候,需要讀取elf檔案頭資訊,做一些特征的判斷,或作為特征參與機器學習的判斷。

linux 字元串截取_linux下可執行檔案分析

還有些其他指令,有興趣的小夥伴,可以通過

-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 檢視庫函數調用情況

linux 字元串截取_linux下可執行檔案分析

3.1.2 ltrace 檢視庫函數調用占用時間

這在檢視系統調用耗時很有用。

# -T 是檢視調用時間開銷
ltrace -T
#-t -tt -ttt 是檢視調用絕對時間,t越多越精确
ltrace -t
           
linux 字元串截取_linux下可執行檔案分析

3.1.3 ltrace 檢視系統調用資訊

ltrace -S
           
linux 字元串截取_linux下可執行檔案分析

系統調用資訊顯然比庫函數顯示更多,追蹤更複雜的情況可以使用。

還有

-p pid

追蹤具體的進行id的調用情況也很有用,這裡面就不舉例子了。 如果沒有這個指令,如果是centos環境可以通過

yum install -y ltrace

安裝。

3.2 strace

strace和ltrace的指令差不多,strace更偏向于系統調用的追蹤或信号産生的情況。安裝指令

yum -y install strace

linux 字元串截取_linux下可執行檔案分析

強大地方在于可以指定系統調用的類型:

-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 
           

比如以下指令:

linux 字元串截取_linux下可執行檔案分析

還有很多有用的選項,有興趣的可以嘗試下。

3.3 GDB指令

gdb指令其實是我們最常用的,調試程式的利器,用來檢視二進制檔案的結構,非常合适,可以把程式運作起來通過

gdb -p pid

友善地調試。 也可如下運作:

linux 字元串截取_linux下可執行檔案分析

基本指令說明下:

set args 設定參數
b main 設定中斷位置為main函數
r 開始運作
l 列印目前的函數内容
p 列印變量值
           

四 圖形化界面分析二進制執行檔案

網上找到一個圖形化界面分析二進制程式的,名字叫

Relyze

雖然是收費的,但是可以正常用一段時間,一段時間後才提示,界面如下,強大之處在于可以顯示調用關系資訊等。 其實原理都類似,沒有比指令行更多的功能,隻是看起來更友善而已。

4.1 基本檔案資訊

linux 字元串截取_linux下可執行檔案分析

4.2 頭和段資訊檢視

linux 字元串截取_linux下可執行檔案分析

4.3 搜尋

linux 字元串截取_linux下可執行檔案分析

4.4 調用關系圖

輕按兩下可以看到調用關系圖資訊,便于做進一步分析。

linux 字元串截取_linux下可執行檔案分析

其他的也沒啥特殊點了,有興趣的朋友可以下載下傳試試。

五 詩詞欣賞

浣溪沙
[宋] [秦觀]

漠漠輕寒上小樓,曉陰無賴似窮秋,淡煙流水畫屏幽。
自在飛花輕似夢,無邊絲雨細如愁,寶簾閑挂小銀鈎。