網絡安全攻防:軟件逆向之反匯編
1. 逆向工程
逆向工程(RE,Reverse Engineering)是一種技術過程,即對一項目標產品進行逆向分析及研究,從而演繹并得出該產品的處理流程、組織結構、功能性能規格等設計要素,以制作出功能相近,但又不完全一樣的產品。逆向工程源于商業及軍事領域中的硬件分析。其主要目的是,在不能輕易獲得必要的生產信息下,直接從成品的分析,推導出產品的設計原理。
2. 基本概念
機器碼(Machine Code):電腦CPU可直接解讀的數據,也被稱為原生碼(Native Code),與運行平臺有關。
匯編語言(Assembly Language):用助記符代替機器指令的操作碼,用地址符號或標號代替指令或操作數的地址,方便程序員編寫代碼。匯編語言和特定的機器語言指令集是一一對應的,不同平臺之間不可直接移植。主流的有ARM匯編和x86匯編。
CPU寄存器:用來暫時存儲指令、數據和地址,包括通用寄存器、專用寄存器和控制寄存器。逆向分析時需要注意特殊寄存器的變化。
WinAPI:Windows 操作系統中可用的內核應用程序編程接口,在 Windows 平臺研究學習逆向工程需要了解一些WinAPI編程。
3. 反匯編
反匯編是把目標代碼轉化為匯編代碼、將低級代碼轉化為高級代碼的過程。
以最著名的HelloWorld為例,先在Visual Studio中新建一個HelloWorld項目如下所示。
- //HelloWorld.cpp: 定義控制臺應用程序的入口點。
- #include"stdafx.h"
- #include<stdio.h>
- int_tmain(int argc,_TCHAR*argv[])
- {
- printf("HelloWorld\n");
- return 0;
- }
在生成→配置管理器→活動解決方案配置選擇Release。選擇Release模式生成可執行文件,程序代碼會更簡潔,方便調試,如圖1所示。
圖1 Release模式
此時生成的是HelloWorld.exe的可執行文件,已經不能直接看到程序的源碼。通過該可執行文件還原出匯編代碼的過程就是反匯編。我們用OllyDbg加載該程序可以輕松地看到反匯編代碼,如圖2所示。
圖2 反匯編代碼
4. 常見的工具
OllyDbg是一個新的動態追蹤工具,將IDA與SoftICE結合起來的思想,Ring 3級調試器,非常容易上手,已代替SoftICE成為當今最為流行的調試解密工具。同時還支持插件擴展功能,是目前最強大的調試工具。運行界面如圖3所示。
圖3 OllyDbg運行界面
IDA Pro 32/64:IDA Pro簡稱IDA(Interactive Disassembler),是一個世界頂級的交互式反匯編工具,有兩種可用版本。標準版(Standard)支持20多種處理器,高級版(Advanced)支持50多種處理器,運行界面如圖4所示。
圖4 IDA Pro運行界面
SoftIce:SoftIce是Compuware NuMega公司的產品,是Windows2000及之前的內核級調試工具,兼容性和穩定性極好,可在源代碼級調試各種應用程序和設備驅動程序,也可使用TCP/IP連接進行遠程調試。但目前微軟的Windbg方便性、可靠性及可用性遠遠超出SoftICE,且免費使用。所以SoftIce并沒有推后續版本。
WinDbg:WinDbg 是在 Windows 平臺下,強大的用戶態和內核態調試工具。相比較于Visual Studio,它是一個輕量級的調試工具,所謂輕量級指的是它的安裝文件大小較小,但是其調試功能,卻比Visual Studio更為強大。它的另外一個用途是可以用來分析Dump數據,程序運行如圖5所示。
圖5 WinDbg運行界面
5. 分類識別工具
在第一次拿到一個文件時,我們需要確定這是一個什么類型的文件。通??梢酝ㄟ^文件擴展名確定。有時候文件擴展名并沒有什么實際意義,所以不能通過擴展名來確定文件類型。
(1)file
在大多數 Linux 系統中都帶有這個實用工具。file 通過檢查某些特定字段來確定文件類型,如下。
- root@kail:~/Desktop# file HelloWorld.exe
- HelloWorld.exe: PE32 executable for MS Windows(console)Intel 80386 32-bit
- root@kali:~/Desktop# file a
- a:ASCII text
常見命令:file[-bchikLnNprsvz][-f namefile][-F separator][-mmagicfiles]file。命令參數及描述如表1所示。
表1 file命令參數及描述
(2)PE tools
PE tools用于分析Windows系統中正在運行的進程和可執行文件,主界面如圖6所示,列出了所有活動進程和每個進程調用的動態鏈接庫。
圖6 PE tools主界面
(3)PEiD
PEiD 是一款著名的查殼工具,其功能強大,幾乎可以偵測出所有的殼,其數量已超過470種PE文檔的加殼類型和簽名,運行界面如圖7所示。
圖7 PEiD運行界面
6. 摘要工具
一般情況下,我們可以獲得的都是二進制程序文件,所有也只能對二進制程序進行逆向。在對文件有了初步的了解和分類后,需要對特定的文件格式進行解析。
(1)nm
nm是names的縮寫。nm命令主要是用來列出某些文件中的符號,如一些函數和全局變量。在Linux下面重新編譯生成了Helloworld,用nm命令分別查看效果,命令:nm Helloworld,運行如下。
- root@kali:~/Desktop# nm Helloworld
- 00000000006008e8 B __bss_start
- 00000000006008e8 b completed.6979
- 00000000006008d8 D __data_start
- 00000000006008d8 W data_start
- 0000000000400420 t deregister_tm_clones
- 00000000004004a0 t__do_global_dtors_aux
- 00000000006006c8 t__do_global_dtors_aux_fini_array_entry
- 00000000006008e0 D__dso_handle
- 00000000006006d8 d_DYNAMIC
- 00000000006008e8 D_edata
- 00000000006008f0 B_end
- 0000000000400574 T_fini
- 00000000004004c0 t frame_dummy
- 00000000006006c0 t__frame_dummy_init_array_entry
- 00000000004006b8 r__FRAME_END__
- 00000000006008b0 d_GLOBAL_OFFSET_TABLE_
- w__gmon_start__
- 0000000000400590 r__GNU_EH_FRAME_HDR
- 0000000000400390 T_init
- 00000000006006c8 t__init_array_end
- 00000000006006c0 t__init_array_start
- 0000000000400580 R_IO_stdin_used
- w_ITM_deregisterTMCloneTable
- w_ITM_registerTMCloneTable
- 00000000006006d0 d__JCR_END__
- 00000000006006d0 d__JCR_LIST__
- w_Jv_RegisterClasses
- 0000000000400570 T__libc_csu_fini
- 0000000000400500 T__libc_csu_init
- U__libc_start_main@@GLIBC_2.2.5
- 00000000004004e6 T main
- U puts@@GLIBC_2.2.5
- 0000000000400460 t register_tm_clones
- 00000000004003f0 T_start
- 00000000006008e8 D__TMC_END__
輸出字符含義如表2所示。
表2 輸出字符含義
(2)ldd
ldd(List Dynamic Dependencies)是Linux上自帶的腳本,用來列出可執行文件所需的動態庫。命令:ldd Helloworld。
- root@kali:~/Desktop#ldd Helloworld
- linux-gate.so.1=>(0xb77ef000)
- libc.so.6=>/lib/tls/i686/cmov/libc.so.6(0xb7683000)
- /lib/ld-linux.so.2(0xb77f0000)
(3)Objdump
Objdump 是一個十分強大的工具,可以靈活地查詢文件的各種信息,有大概 30個可選項,可以通過objdump –help查詢。簡單查看反匯編代碼使用如下:Objdump-d helloworld,運行部分如下。
- root@kaili:~/Desktop# objdump-d Helloworld
- HelloWorld:文件格式 elf64-x86-64
- Disassembly of section.init:
- 0000000000400390 <_init>:
- 400390:48 83 ec 08 sub $0x8,%rsp
- 400394:48 8b 05 0d 05 20 00 mov 0x20050d(%rip),%rax #6008a8<_DYNAMIC+0x1d0>
- 40039b:48 85 c0 test %rax,%rax
- 40039e: 74 05 je 4003a5<_init+0x15>
- 4003a0: e8 3b 00 00 00 callq 4003e0<__libc_start_main@plt+0x10>
- 4003a5: 48 83 c4 08 add $0x8,%rsp
- 4003a9: c3 retq
- Disassembly of section.plt:
- 00000000004003b0 <puts@plt-0x10>:
- 4003b0:ff 35 02 05 20 00 pushq 0x200502(%rip) # 6008b8<_GLOBAL_OFFSET_TABLE_+0x8>
- 4003b6:ff 25 04 05 20 00 jmpq *0x200504(%rip) # 6008c0<_GLOBAL_OFFSET_TABLE_+0x10>
- 4003bc: 0f 1f 40 00 nopl 0x0(%rax)
(4)Otool
可以獲取OS X二進制文件的相關信息。類似objdump的實用工具。
(5)Dumpbin
微軟VisualStudio工具套件里的一個命令行工具。主要用于Windows PE文件相關信息的獲取。用法類似Objdump。
7. 深度檢測工具
strings實用工具專門用于提取文件中的字符串內容,通常使用該工具不會受到文件格式的限制。使用strings的默認設置(至少包含4個字符的7位ASCII序列)。用strings對Helloworld進行檢測,部分代碼如下。
- root@kaili:~/Desktop# strings Helloworld
- /lib64/ld-linux-x86-64.so.2
- libc.so.6
- puts
- __libc_start_main
- __gmon_start__
- GLIBC_2.2.5
- AWAVA
- AUATL
- []A\A]A^A_
- HelloWorld