Linux環境與相關工具
這裡小結一下Linux二進位制分析相關的環境與工具的基礎知識。
Linux工具
Linux自帶了很多常用的binutils工具,這些工具可在http://www.gnu.org/software/binutils/中找到,其中包含許多用於二進位制分析和破解的工具。
GDB
GNU Debuger,具體的不用多說。
GNU binutils中的objdump
object dump是一種對程式碼進行快速反編譯的簡介方案,在反編譯簡單的、未被篡改的二進位制檔案時較為有用,可以讀取常用的ELF型別檔案,但對於如惡意軟體等較為複雜的反編譯任務則顯得侷限。
主要缺點是需要依賴ELF節頭,並且不會進行控制流分析。
一些常見用例:
檢視ELF檔案中所有節的資料或程式碼:
objdump -D <elf object>
只檢視ELF檔案中的程式程式碼:
objdump -d <elf object>
檢視所有符號:
objdump -tf <elf object>
GNU binutils中的objcopy
object copy將目標檔案的一部分或者全部內容拷貝到另外一個目標檔案中,或者實現目標檔案的格式轉換。其可以分析和修改任意型別的ELF檔案,修改ELF節,複製ELF節到ELF二進位制中或反之。
要將.data節從一個ELF檔案複製到另一個檔案中可用以下命令:
objcopy -only-section=.data <infile> <outfile>
strace
system call trace系統呼叫追蹤,是基於ptrace(2)系統呼叫的工具,通過在一個迴圈中使用PTRACE_SYSCALL請求來顯示執行中程式的系統呼叫syscalls活動相關的資訊以及程式執行中捕獲到的訊號量。
跟蹤程式:
strace /bin/ls -o ls.out
附加到一個現存的程序上:
strace -p <pid> -o daemon.out
原始輸出將會顯示每個系統呼叫的檔案描述編號,系統呼叫會將檔案描述符作為引數,如下:
SYS_read(3, buf, sizeof(buf));
若想檢視讀入到檔案描述符3中的所有資料,可執行如下命令:
strace -e read=3 /bin/ls
也可以使用-e write=fd命令檢視寫入的資料。
ltrace
library trace庫追蹤,與strace類似,用於解析共享庫即一個程式的連結資訊,並打印出用到的庫函式。還可以使用-S引數檢視系統呼叫。該命令通過解析可執行檔案的動態段,並打印出共享庫和靜態庫的實際符號和函式來提供更詳細的資訊。
ltrace <program> -o program.out
ftrace
function trace函式追蹤,與ltrace類似,另外還可以檢視二進位制檔案本身的函式呼叫,可以在https://github.com/elfmaster/ftrace中下載。
readelf
readelf是用於解析ELF二進位制檔案的工具。在進行反編譯之前,需要手機目標檔案相關的資訊,該命令可以提供收集資訊所需要的特定的ELF的所有資料。
查詢節頭表:readelf -S <object>
查詢程式頭表:readelf -l <object>
查詢符號表:readelf -s <object>
查詢ELF檔案頭資料:readelf -e <object>
查詢重定位入口:readelf -r <object>
查詢動態段:readelf -d <object>
ERESI——ELF反編譯系統介面
ERESI工程包含了許多Linux二進位制工具,具體檢視http://www.eresi-project.org。
裝置和檔案
/proc/<pid>/maps
/proc/<pid>/maps檔案儲存了一個程序映象的佈局,通過展現每個記憶體對映來實現,展現的內容包括可執行檔案、共享庫、棧、堆和VDSO等。對於快速解析一個程序的地址空間分佈十分有用。
/proc/kcore
/proc/kcore是proc檔案系統的一項,是Linux核心的動態核心檔案,是以ELF核心檔案的形式所展現出來的原生記憶體轉儲。GDB可以使用/proc/kcore來對核心進行除錯分析。
/boot/System.map
該檔案幾乎存在於所有的Linux版本中,包含了整個核心的所有符號。
/proc/kallsyms
/proc/kallsyms與/boot/System.map類似,/proc/kallsyms包含了核心中絕大部分的符號(若在CONFIG_KALLSYMS_ALL核心配置中指明則可以包含核心中全部的符號),區別是kallsyms是核心所屬的/proc的一個入口並且可以動態更新。假如安裝了新的LKM(Linux Kernel Module),符號會自動新增到/proc/kallsyms中。
/proc/iomem
/proc/iomem是一個proc入口,與/proc/<pid>/maps類似,不過其是跟系統記憶體相關的。
例如,查詢核心的text段所對映的實體記憶體位置,通過搜尋Kernel便可以檢視code/text段、data段和bss段的內容:
ECFS
Extended Core File Snapshot擴充套件核心檔案快照,是一種核心轉儲技術,專門為程序映象的高階取證分析所設計。可與https://github.com/elfmaster/ecfs中下載。
連結器相關環境指標
LD_PRELOAD環境變數
LD_PRELOAD環境變數可以設定成一個指定庫的路徑,動態連結時較其他庫有著更高的優先順序,允許預載入指定庫中的函式和符號覆蓋掉後續連結的庫中的函式和符號。即可以通過重定向共享庫函式來進行執行時修復。這項技術可用於繞過反除錯程式碼,也可以用作使用者機rootkit。
CTF中有示例參考HITB Binary 100。
LD_SHOW_AUXV環境變數
LD_SHOW_AUXV環境變數能夠通知程式載入器來展示程式執行時的輔助向量。輔助向量是放在程式棧上的資訊(通過核心的ELF常規載入方式),附帶了傳遞給動態連結器的程式相關的特定資訊。
連結器指令碼
連結器指令碼由連結器解釋,把程式劃分為節、記憶體和符號。gcc通過使用-T引數來指定連結器指令碼。預設的連結器指令碼可以使用ld –verbose命令檢視: