เราจะใช้ไฟล์ reverse1.exe ในการอธิบาย PE File structure ครับ
PE File ย่อมาจากคำว่า Portable Execution แปลว่า "ประมวลผลได้ด้วยตัวมันเอง ในขนาดพกพา" ที่มาคือสมัยก่อนนู้น จะมีสิ่งที่เกิดขึ้นมาก่อน คือไฟล์ประเภท COFF ย่อมาจาก Common Object File Format สำหรับ execution ในระบบ Unix
โดย COFF เป็นรูปแบบไฟล์อ็อบเจกต์ (object file format) ที่ถูกพัฒนาขึ้นครั้งแรกในระบบ Unix แล้ว Microsoft ได้นำแนวคิดของ COFF มาปรับปรุงและพัฒนาเป็นรูปแบบไฟล์ PE ซึ่งใช้สำหรับไฟล์ปฏิบัติการ (executable files) เช่น ทำให้การเชื่อมโยง Library มีความยืดหยุ่นมากขึ้น หรือ Dynamic ขึ้น (กลายเป็น DLL หรือ Dynamic Link Libraries ในปัจจุบัน) ใน Windows ซึ่งเน้นไปที่ CPU สถาปัตยกรรม x86 ครับ
PE File ประกอบด้วยโครงสร้างหลักๆอะไร้บาง
1. DOS Header
2. PE Header
3. Section ต่างๆ ซึ่งผมจะอธิบายแบ่งย่อยอีกที
ผมจะใช้ไฟล์ reverse1.exe ในการอธิบาย ยกตัวอย่างจริงไปเลยครับ ไฟล์นี้อย่างที่รู้มันคือโค้ดโปรแกรมง่ายๆ ที่ไม่ได้อันตรายอะไร ดังนั้นก็สามารถ Analyze บน Windows ได้
แต่ผมมีแนวคิดที่น่าสนใจนิดหน่อยต่างจากคนอื่นๆ นั่นก็คือ "หากเรารู้" ว่าไฟล์ .exe ที่เป็น executable file สำหรับ run บน Windows "เป็นไฟล์ไม่ปลอดภัย หรือ Known Threat" , เราสามารถเลือกทำการ Static Analysis ใน Linux ได้ครับ
เพราะแปลว่า อย่างน้อยที่สุด เราจะได้ไม่เผลอ "มือลั่น" ไปสั่ง execute file เข้าไปทำอันครายอะไร กับ Windows นั่นเอง
สำหรับเครื่องมือ PE Static Analysis ใน Windows / Linux มีอะไรบ้าง ?
ก็มีหลายโปรแกรมที่ใช้ได้ใน Linux เช่น Detect It Easy หรือเรียกว่า DIE / PE Frame / PE Tree / radare หรือ r2 / rizin / cutter / ghidra (ยอดนิยม)
แต่ตัวผม และเว็บไซต์ของผม จะเน้นไปใช้ rizin กับ cutter ครับ เหตุผลนั้น ง่ายๆ คือมัน "เข้ามือ" ครับ
rizin : website ลิ้งนี้
cutter : website คลิกที่ลิ้งนี้
rizin คือ command line tool ที่เป็น reverse engineer framework ที่ถูกต่อยอดมาจาก radare โดยที่ radare มีชื่อเสียงในด้าน RE มายาวนานในการทำ RE แบบ CLI และตอนนี้ก็มีการ re-write ใหม่เป็น r2 แล้วด้วย ใช้ดีมากๆ เลยนะ ไปลองกันได้
แต่ก็จะมีมุมมองบางอย่างของ Developer ที่ต่างออกไปเลยเกิด rizin ขึ้นมา
ที่ผมเลือก rizin นั้น ไม่ใช่ radre ไม่ดี , radare ก็มีโครงสร้างที่แข็งแรง แต่ rizin ผมลองจับๆดูแล้วมันเข้ามือผมมากกว่า และมี ui ที่ผมรู้สึกว่า modern กว่า เพื่อนๆลองเข้าเว็บของ rizin ไปศึกษาก็ได้ครับ
หรือแม้แต่ ghidra ที่ยอดนิยมสุดๆ แต่ผมมี "ความรู้สึกบางอย่างสไตล์ java" รู้สึกกับ Gui ของ ghidra ครับ ความรู้สึกนี้ส่งผลให้การใช้ ghidra ไม่เข้ามือมากนัก ก็เลยยังไม่ปักใจไปทาง ghidra ออกจะติสต์ๆหน่อยครับผม
แล้วถ้า rizin ไปต่อเป็น gui มีมั้ย แน่นอนมันก็คือ cutter , cutter ก็เป็น GUI ที่ครอบ rizin ไว้อีกที ทำให้ rizin ทรงพลังมากขึ้นไปอีก ใช้เข้ามือผมดี เลยมาทางนี้ละ
คงไม่ต้องรออะไรมากแล้ว เราก็ติดตั้ง rizin ได้เลยครับ ซึ่งลงได้ทั้ง Linux / Windows
หน้าเว็บลิ้งสำหรับดาวน์โหลด และติดตั้ง : https://rizin.re/install/
หลังจากติดตั้งเสร็จ เราก็จะเริ่มใช้ rizin ในการทำ PE File Static Analysis นะครับ
โดยปกติ ผมจะใช้ Linux ในการทำหรือชีวิตประจำวัน
แต่วันนี้ ณ วันที่เขียนบทความ ผมใช้ Windows เครื่องที่ทำงาน ผมขี้เกียจ switch ไปใช้ linux เพื่อเขียนบทความ เพราะยังไงตัว rizin ก็เป็น Cross Platform Reverse Engineer Framework อยู่แล้ว
ผมเลยจะยกตัวอย่างจาก Windows Usage นะครับ โดยการใช้ rizin ก็ต้องใช้ไฟล์ rizin.exe เพื่อทำงาน
มันถูกติดตั้งไว้ที่ C:\Program Files\Rizin\ ผมก็ใช้ powershell ทำการ cd เข้าไปเลย
PS C:\Program Files\Rizin\bin> ls
Directory: C:\Program Files\Rizin\bin
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2024-12-19 16:50 11776 rizin.exe
-a--- 2024-12-19 16:49 16300032 rz_analysis-0.7.dll
-a--- 2024-12-19 16:48 15971840 rz_asm-0.7.dll
-a--- 2024-12-19 16:47 1527808 rz_bin-0.7.dll
-a--- 2024-12-19 16:46 26624 rz_bp-0.7.dll
-a--- 2024-12-19 16:47 21504 rz_config-0.7.dll
-a--- 2024-12-19 16:46 139264 rz_cons-0.7.dll
-a--- 2024-12-19 16:50 2507776 rz_core-0.7.dll
-a--- 2024-12-19 16:46 83968 rz_crypto-0.7.dll
-a--- 2024-12-19 16:49 269824 rz_debug-0.7.dll
-a--- 2024-12-19 16:46 219136 rz_demangler-0.7.dll
-a--- 2024-12-19 16:46 29184 rz_diff-0.7.dll
-a--- 2024-12-19 16:49 59904 rz_egg-0.7.dll
-a--- 2024-12-19 16:46 33280 rz_flag-0.7.dll
-a--- 2024-12-19 16:46 242176 rz_hash-0.7.dll
-a--- 2024-12-19 16:48 125952 rz_il-0.7.dll
-a--- 2024-12-19 16:46 297472 rz_io-0.7.dll
-a--- 2024-12-19 16:47 20480 rz_lang-0.7.dll
-a--- 2024-12-19 16:46 53248 rz_magic-0.7.dll
-a--- 2024-12-19 16:50 193536 rz_main-0.7.dll
-a--- 2024-12-19 16:47 141312 rz_parse-0.7.dll
-a--- 2024-12-19 16:46 38400 rz_reg-0.7.dll
-a--- 2024-12-19 16:46 26112 rz_search-0.7.dll
-a--- 2024-12-19 16:49 53248 rz_sign-0.7.dll
-a--- 2024-12-19 16:46 47104 rz_socket-0.7.dll
-a--- 2024-12-19 16:46 17408 rz_syscall-0.7.dll
-a--- 2024-12-19 16:46 836608 rz_type-0.7.dll
-a--- 2024-12-19 16:46 1438208 rz_util-0.7.dll
-a--- 2024-12-19 16:50 10240 rz-asm.exe
-a--- 2024-12-19 16:50 10240 rz-ax.exe
-a--- 2024-12-19 16:50 10240 rz-bin.exe
-a--- 2024-12-19 16:50 10240 rz-diff.exe
-a--- 2024-12-19 16:50 10240 rz-find.exe
-a--- 2024-12-19 16:50 10240 rz-gg.exe
-a--- 2024-12-19 16:50 10240 rz-hash.exe
-a--- 2024-12-19 16:50 10240 rz-run.exe
-a--- 2024-12-19 16:50 10240 rz-sign.exe
-a--- 2024-12-19 16:50 51712 rz-test.exe
PS C:\Program Files\Rizin\bin>
เริ่มทำงานโดยพิมพ์ rizin ครับ
พิมพ์
.\rizin.exe แล้ว enter
ตรงหน้า prompt ของ shell จะเปลี่ยนไปเป็น [0x00000000]
เราก็ลองพิมพ์ ? แล้ว enter เพื่อจะทำให้เรารู้ว่า rizin ทำอะไรให้เราได้บ้าง
PS C:\Program Files\Rizin\bin> .\rizin.exe
-- Use the '[' and ']' keys in visual mode to adjust the screen width
[0x00000000]> ?
Usage: [.][times][cmd][~grep][@[@iter]addr][|>pipe] ; ...
| ![!] # Run given commands as in system(3) or shows command history
| #! [ ...] # Run interpreter
| $[?] # Alias commands and strings
| %[?] # Math commands
| &[jt=b-&?] # Manage tasks
| ([*-?] # Manage scripting macros
| *[=|] # Pointer read/write data/values
| .[ .-*(?] # Interpret commands
| /[?] # Search for bytes, regexps, patterns, ..
| :[?] # Command specifiers (table-output only for now)
| < # Push escaped string into the RzCons.readChar buffer
| >[?] # Redirection help ('>')
| ?*[j] [] # Search help
| @[?] # '@' help, temporary modifiers
| @@[?] # '@@' help, iterators
| _ # Print last output
| a[?] # Analysis commands
| b[j*-+fm] # Display or change the block size
| B[jqt] [] # Computes the possibles firmware locations in memory (CPU intensive)
| C[?] # Code metadata (comments, format, hints, ..)
| c[?] # Compare block with given data
| d # Debugger commands
| dex # Core plugin to visualize dex class information
| e[?] # List/get/set config evaluable vars
| f[?] # Manage flags
| F # FLIRT signature management
| g[?] # Generate shellcodes with rz_egg
| H[-+] # Rizin history commands.
| help # Generic help
| i[?] # Get info about opened binary file
| java # Core plugin to visualize java class information
| k[?] # Run sdb-query
| L[?] # List, unload, load rizin plugins
| o[?] # Open files and handle opened files
| p[?] # Print commands
| P # Project management
| q[!?] # Quit rizin
| R[?] # Connect with other instances of rizin
| r[j-+bh] # Resize file
| s[?] # Seek commands
| shell # Common shell commands
| t[?] # Types, noreturn, signatures, C parser and more
| v[?] # Enter visual panel mode
| V[?] # Enter visual mode
| w[?] # Write commands
| x[?] # Alias for 'px' (print hexadecimal)
| y[?] # Yank/paste bytes from/to memory
| |[?] # Pipe help ('|')
| ~[?] # Internal grep help ('~')
[0x00000000]>
ok ถ้าขึ้นมาแบบนี้แล้วแสดงว่า rizin เราพร้อมจะทำงานแล้วครับ ให้เรา พิมพ์ exit ออกมาก่อน เพื่อออกจาก shell ของ rizin
ทีนี้เราจะเริ่มทำงานกับไฟล์ reverse1.exe ใช่มั้ยครับ
เราก็สั่งไปที่ตำแหน่งไฟล์นั้นครับ ผมก็สั่งให้ rizin เลือกไฟล์ตาม path ที่วาง reverse1.exe ไว้แบบนี้
[0x00000000]> exit
PS C:\Program Files\Rizin\bin> .\rizin.exe "C:\Users\panupong.gtlc\Documents\web-re\reverse1.exe"
-- Execute a command on the visual prompt with cmd.vprompt
[0x1400013f0]>
พิมพ์คำสั่ง i แล้ว enter เพื่อ get information ของ PE File , กลุ่มคำสั่ง i ของ rizin จะเป็นกลุ่มคำสั่งเกี่ยวกับการดูข้อมูลไฟล์ต่างๆ
เราสามารถพิมพ์ i? หรือ i??? เพื่อให้ rizin สอนให้เบื้องต้นได้ว่า มีอะไรแนะนำเราอีก
และทุกคำสั่ง เช่น a , p , k ก็สามารถพิมพ์ ? หรือ ?? ต่อท้ายเพื่อให้ rizin สอนเราเบื้องต้นได้ครับ
สิ่งแรกที่เราต้องทำเสมอ คือคำสั่ง aaa ครับ , เป็นการให้ rizin ช่วยเราวิเคราะห์ข้อมูล pefile ทั้งหมด เพื่อเตรียมให้เราไล่สิ่งต่างๆ ในโครงสร้างไฟล์ต่อไป
จากนั้นเราก็ค่อย iH เพื่อดูข้อมูล Header File ครับ
[0x1400013f0]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls
[x] Analyze len bytes of instructions for references
[x] Check for classes
[x] Analyze local variables and arguments
[x] Type matching analysis for all functions
[x] Applied 0 FLIRT signatures via sigdb
[x] Propagate noreturn information
[x] Integrate dwarf function information.
[x] Resolve pointers to data sections
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x1400013f0]> iH
PE file header:
IMAGE_NT_HEADERS
Signature : 0x4550
IMAGE_FILE_HEADERS
Machine : 0x8664
NumberOfSections : 0x11
TimeDateStamp : 0x67f79660
PointerToSymbolTable : 0x14c00
NumberOfSymbols : 0x66b
SizeOfOptionalHeader : 0xf0
Characteristics : 0x26
IMAGE_OPTIONAL_HEADERS
Magic : 0x20b
MajorLinkerVersion : 0x2
MinorLinkerVersion : 0x2b
SizeOfCode : 0xfa00
SizeOfInitializedData : 0x12800
SizeOfUninitializedData : 0xc00
AddressOfEntryPoint : 0x13f0
BaseOfCode : 0x1000
ImageBase : 0x140000000
SectionAlignment : 0x1000
FileAlignment : 0x200
MajorOperatingSystemVersion : 0x4
MinorOperatingSystemVersion : 0x0
MajorImageVersion : 0x0
MinorImageVersion : 0x0
MajorSubsystemVersion : 0x5
MinorSubsystemVersion : 0x2
Win32VersionValue : 0x0
SizeOfImage : 0x22000
SizeOfHeaders : 0x600
CheckSum : 0x2473e
Subsystem : 0x3
DllCharacteristics : 0x160
SizeOfStackReserve : 0x200000
SizeOfStackCommit : 0x1000
SizeOfHeapReserve : 0x100000
SizeOfHeapCommit : 0x1000
LoaderFlags : 0x0
NumberOfRvaAndSizes : 0x10
RICH_FIELDS
IMAGE_DIRECTORY_ENTRY_IMPORT
VirtualAddress : 0x16000
Size : 0x820
IMAGE_DIRECTORY_ENTRY_EXCEPTION
VirtualAddress : 0x13000
Size : 0x5d0
IMAGE_DIRECTORY_ENTRY_BASERELOC
VirtualAddress : 0x19000
Size : 0xa0
IMAGE_DIRECTORY_ENTRY_TLS
VirtualAddress : 0x12060
Size : 0x28
IMAGE_DIRECTORY_ENTRY_IAT
VirtualAddress : 0x16220
Size : 0x1e0
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
VirtualAddress : 0x0
Size : 0xffff
[0x1400013f0]>
จะเห็นได้ว่า rizin ก็ให้ข้อมูลกับเราได้ไม่ต่างกับพวกโปรแกรม PE Bear เลย , แต่ดีกว่านิดนึงตรงที่ไล่ flow เบื้องต้นได้ และสามารถเขียน plug-in หรือ script เพิ่มเติมได้อีก , ก็อยู่ที่เราเอง จะวิเคราะห์อะไร หรือลงมือทำอะไรครับ , ทีนี้มาดู command ใหญ่ที่จะส่งข้อมูลออกมาปริมาณมากกันบ้าง
คือคำสั่ง ia ซึ่งคำสั่งนี้มีหน้าที่แสดงสรุปข้อมูลทั้งหมดให้เราครับ rizin จะทำการแบ่ง section ของส่วนประกอบต่างๆ เป็นสัดเป็นส่วนดีมาก
เราสามารถค่อยๆ ดูส่วนประกอบของไฟล์ทีละส่วนได้ จากคำสั่งนี้
ลองดูครับ
[0x1400013f0]> ia
[Info]
arch x86
cpu N/A
baddr 0x140000000
binsz 0x0001dc77
bintype pe
bits 64
retguard false
class PE32+
cmp.csum 0x0002473e
compiled Thu Apr 10 16:58:56 2025 UTC+7
compiler N/A
dbg_file N/A
endian LE
hdr.csum 0x0002473e
guid N/A
intrp N/A
laddr 0x00000000
lang c
machine AMD 64
maxopsz 16
minopsz 1
os windows
overlay false
cc ms
pcalign 0
rpath N/A
signed false
subsys Windows CUI
stripped false
crypto false
havecode true
va true
sanitiz false
static false
linenum true
lsyms false
canary false
PIE true
RELROCS false
NX true
[Imports]
nth vaddr bind type lib name
-------------------------------------------------------------------
1 0x140016220 NONE FUNC KERNEL32.dll DeleteCriticalSection
2 0x140016228 NONE FUNC KERNEL32.dll EnterCriticalSection
3 0x140016230 NONE FUNC KERNEL32.dll GetLastError
4 0x140016238 NONE FUNC KERNEL32.dll InitializeCriticalSection
5 0x140016240 NONE FUNC KERNEL32.dll IsDBCSLeadByteEx
6 0x140016248 NONE FUNC KERNEL32.dll LeaveCriticalSection
7 0x140016250 NONE FUNC KERNEL32.dll MultiByteToWideChar
8 0x140016258 NONE FUNC KERNEL32.dll SetUnhandledExceptionFilter
9 0x140016260 NONE FUNC KERNEL32.dll Sleep
10 0x140016268 NONE FUNC KERNEL32.dll TlsGetValue
11 0x140016270 NONE FUNC KERNEL32.dll VirtualProtect
12 0x140016278 NONE FUNC KERNEL32.dll VirtualQuery
13 0x140016280 NONE FUNC KERNEL32.dll WideCharToMultiByte
1 0x140016290 NONE FUNC msvcrt.dll __C_specific_handler
2 0x140016298 NONE FUNC msvcrt.dll ___lc_codepage_func
3 0x1400162a0 NONE FUNC msvcrt.dll ___mb_cur_max_func
4 0x1400162a8 NONE FUNC msvcrt.dll __getmainargs
5 0x1400162b0 NONE FUNC msvcrt.dll __initenv
6 0x1400162b8 NONE FUNC msvcrt.dll __iob_func
7 0x1400162c0 NONE FUNC msvcrt.dll __set_app_type
8 0x1400162c8 NONE FUNC msvcrt.dll __setusermatherr
9 0x1400162d0 NONE FUNC msvcrt.dll _amsg_exit
10 0x1400162d8 NONE FUNC msvcrt.dll _cexit
11 0x1400162e0 NONE FUNC msvcrt.dll _commode
12 0x1400162e8 NONE FUNC msvcrt.dll _errno
13 0x1400162f0 NONE FUNC msvcrt.dll _exit
14 0x1400162f8 NONE FUNC msvcrt.dll _fmode
15 0x140016300 NONE FUNC msvcrt.dll _initterm
16 0x140016308 NONE FUNC msvcrt.dll _lock
17 0x140016310 NONE FUNC msvcrt.dll _onexit
18 0x140016318 NONE FUNC msvcrt.dll _strtoui64
19 0x140016320 NONE FUNC msvcrt.dll _strtoi64
20 0x140016328 NONE FUNC msvcrt.dll _unlock
21 0x140016330 NONE FUNC msvcrt.dll abort
22 0x140016338 NONE FUNC msvcrt.dll calloc
23 0x140016340 NONE FUNC msvcrt.dll exit
24 0x140016348 NONE FUNC msvcrt.dll fprintf
25 0x140016350 NONE FUNC msvcrt.dll fputc
26 0x140016358 NONE FUNC msvcrt.dll free
27 0x140016360 NONE FUNC msvcrt.dll fwrite
28 0x140016368 NONE FUNC msvcrt.dll getc
29 0x140016370 NONE FUNC msvcrt.dll isspace
30 0x140016378 NONE FUNC msvcrt.dll isxdigit
31 0x140016380 NONE FUNC msvcrt.dll localeconv
32 0x140016388 NONE FUNC msvcrt.dll malloc
33 0x140016390 NONE FUNC msvcrt.dll memcpy
34 0x140016398 NONE FUNC msvcrt.dll memset
35 0x1400163a0 NONE FUNC msvcrt.dll realloc
36 0x1400163a8 NONE FUNC msvcrt.dll signal
37 0x1400163b0 NONE FUNC msvcrt.dll strerror
38 0x1400163b8 NONE FUNC msvcrt.dll strlen
39 0x1400163c0 NONE FUNC msvcrt.dll strncmp
40 0x1400163c8 NONE FUNC msvcrt.dll strtol
41 0x1400163d0 NONE FUNC msvcrt.dll strtoul
42 0x1400163d8 NONE FUNC msvcrt.dll tolower
43 0x1400163e0 NONE FUNC msvcrt.dll ungetc
44 0x1400163e8 NONE FUNC msvcrt.dll vfprintf
45 0x1400163f0 NONE FUNC msvcrt.dll wcslen
[Entries]
vaddr paddr hvaddr haddr type
-----------------------------------------------------
0x1400013f0 0x000009f0 ---------- 0x000000a8 program
[Exports]
nth paddr vaddr bind type size lib name
------------------------------------------------------------------------------------
0 0x00000600 0x140001000 GLOBAL FUNC 0 __mingw_invalidParameterHandler
1 0x00000610 0x140001010 GLOBAL FUNC 0 pre_c_init
2 0x00000730 0x140001130 GLOBAL FUNC 0 pre_cpp_init
3 0x00000780 0x140001180 GLOBAL FUNC 0 __tmainCRTStartup
4 0x000009d0 0x1400013d0 GLOBAL FUNC 0 WinMainCRTStartup
5 0x000009f0 0x1400013f0 GLOBAL FUNC 0 mainCRTStartup
6 0x00000a10 0x140001410 GLOBAL FUNC 0 atexit
7 0x00000a30 0x140001430 GLOBAL FUNC 0 __gcc_register_frame
8 0x00000a40 0x140001440 GLOBAL FUNC 0 __gcc_deregister_frame
9 0x00000a50 0x140001450 GLOBAL FUNC 0 scanf
10 0x00000aa4 0x1400014a4 GLOBAL FUNC 0 printf
11 0x00000af8 0x1400014f8 GLOBAL FUNC 0 main
12 0x00000b50 0x140001550 GLOBAL FUNC 0 __do_global_dtors
13 0x00000b90 0x140001590 GLOBAL FUNC 0 __do_global_ctors
14 0x00000c10 0x140001610 GLOBAL FUNC 0 __main
.........
.........
166 0x0000fda8 0x1400107a8 GLOBAL FUNC 0 _unlock
167 0x0000fe60 0x140010860 GLOBAL FUNC 0 vfprintf
168 0x0000fdd0 0x1400107d0 GLOBAL FUNC 0 free
[Classes]
address min max name super
---------------------------
[Symbols]
nth paddr vaddr bind type size lib name
---------------------------------------------------------------------------------------------
0 0x00000600 0x140001000 GLOBAL FUNC 0 __mingw_invalidParameterHandler
1 0x00000610 0x140001010 GLOBAL FUNC 0 pre_c_init
2 0x00000730 0x140001130 GLOBAL FUNC 0 pre_cpp_init
3 0x00000780 0x140001180 GLOBAL FUNC 0 __tmainCRTStartup
4 0x000009d0 0x1400013d0 GLOBAL FUNC 0 WinMainCRTStartup
5 0x000009f0 0x1400013f0 GLOBAL FUNC 0 mainCRTStartup
6 0x00000a10 0x140001410 GLOBAL FUNC 0 atexit
7 0x00000a30 0x140001430 GLOBAL FUNC 0 __gcc_register_frame
8 0x00000a40 0x140001440 GLOBAL FUNC 0 __gcc_deregister_frame
9 0x00000a50 0x140001450 GLOBAL FUNC 0 scanf
...........
156 0x0000fd58 0x140010758 GLOBAL FUNC 0 __set_app_type
157 0x0000fd68 0x140010768 GLOBAL FUNC 0 _amsg_exit
158 0x0000fd60 0x140010760 GLOBAL FUNC 0 __setusermatherr
159 0x0000fdc8 0x1400107c8 GLOBAL FUNC 0 fputc
160 0x0000fdf8 0x1400107f8 GLOBAL FUNC 0 localeconv
161 0x0000fd80 0x140010780 GLOBAL FUNC 0 _initterm
162 0x0000fdd8 0x1400107d8 GLOBAL FUNC 0 fwrite
163 0x0000fd90 0x140010790 GLOBAL FUNC 0 _onexit
164 0x0000fd78 0x140010778 GLOBAL FUNC 0 _errno
165 0x0000fe30 0x140010830 GLOBAL FUNC 0 strlen
166 0x0000fda8 0x1400107a8 GLOBAL FUNC 0 _unlock
167 0x0000fe60 0x140010860 GLOBAL FUNC 0 vfprintf
168 0x0000fdd0 0x1400107d0 GLOBAL FUNC 0 free
1 0x00012020 0x140016220 NONE FUNC 0 KERNEL32.dll imp.DeleteCriticalSection
2 0x00012028 0x140016228 NONE FUNC 0 KERNEL32.dll imp.EnterCriticalSection
3 0x00012030 0x140016230 NONE FUNC 0 KERNEL32.dll imp.GetLastError
4 0x00012038 0x140016238 NONE FUNC 0 KERNEL32.dll imp.InitializeCriticalSection
5 0x00012040 0x140016240 NONE FUNC 0 KERNEL32.dll imp.IsDBCSLeadByteEx
6 0x00012048 0x140016248 NONE FUNC 0 KERNEL32.dll imp.LeaveCriticalSection
7 0x00012050 0x140016250 NONE FUNC 0 KERNEL32.dll imp.MultiByteToWideChar
8 0x00012058 0x140016258 NONE FUNC 0 KERNEL32.dll imp.SetUnhandledExceptionFilter
9 0x00012060 0x140016260 NONE FUNC 0 KERNEL32.dll imp.Sleep
10 0x00012068 0x140016268 NONE FUNC 0 KERNEL32.dll imp.TlsGetValue
11 0x00012070 0x140016270 NONE FUNC 0 KERNEL32.dll imp.VirtualProtect
12 0x00012078 0x140016278 NONE FUNC 0 KERNEL32.dll imp.VirtualQuery
13 0x00012080 0x140016280 NONE FUNC 0 KERNEL32.dll imp.WideCharToMultiByte
1 0x00012090 0x140016290 NONE FUNC 0 msvcrt.dll imp.__C_specific_handler
2 0x00012098 0x140016298 NONE FUNC 0 msvcrt.dll imp.___lc_codepage_func
3 0x000120a0 0x1400162a0 NONE FUNC 0 msvcrt.dll imp.___mb_cur_max_func
4 0x000120a8 0x1400162a8 NONE FUNC 0 msvcrt.dll imp.__getmainargs
5 0x000120b0 0x1400162b0 NONE FUNC 0 msvcrt.dll imp.__initenv
.......
.......
44 0x000121e8 0x1400163e8 NONE FUNC 0 msvcrt.dll imp.vfprintf
45 0x000121f0 0x1400163f0 NONE FUNC 0 msvcrt.dll imp.wcslen
[Sections]
paddr size vaddr vsize align perm name type flags
-----------------------------------------------------------------------------------------------------------
0x00000600 0xfa00 0x140001000 0x10000 0x0 -r-x .text CNT_CODE,CNT_INITIALIZED_DATA
0x00010000 0x400 0x140011000 0x1000 0x0 -rw- .data CNT_INITIALIZED_DATA
0x00010400 0xe00 0x140012000 0x1000 0x0 -r-- .rdata CNT_INITIALIZED_DATA
0x00011200 0x600 0x140013000 0x1000 0x0 -r-- .pdata CNT_INITIALIZED_DATA
0x00011800 0x600 0x140014000 0x1000 0x0 -r-- .xdata CNT_INITIALIZED_DATA
0x00000000 0x0 0x140015000 0x1000 0x0 -rw- .bss CNT_UNINITIALIZED_DATA
0x00011e00 0xa00 0x140016000 0x1000 0x0 -rw- .idata CNT_INITIALIZED_DATA
0x00012800 0x200 0x140017000 0x1000 0x0 -rw- .CRT CNT_INITIALIZED_DATA
0x00012a00 0x200 0x140018000 0x1000 0x0 -rw- .tls CNT_INITIALIZED_DATA
0x00012c00 0x200 0x140019000 0x1000 0x0 -r-- .reloc CNT_INITIALIZED_DATA,MEM_DISCARDABLE
0x00012e00 0x200 0x14001a000 0x1000 0x0 -r-- .debug_aranges CNT_INITIALIZED_DATA,MEM_DISCARDABLE
0x00013000 0x1200 0x14001b000 0x2000 0x0 -r-- .debug_info CNT_INITIALIZED_DATA,MEM_DISCARDABLE
0x00014200 0x200 0x14001d000 0x1000 0x0 -r-- .debug_abbrev CNT_INITIALIZED_DATA,MEM_DISCARDABLE
0x00014400 0x200 0x14001e000 0x1000 0x0 -r-- .debug_line CNT_INITIALIZED_DATA,MEM_DISCARDABLE
0x00014600 0x200 0x14001f000 0x1000 0x0 -r-- .debug_frame CNT_INITIALIZED_DATA,MEM_DISCARDABLE
0x00014800 0x200 0x140020000 0x1000 0x0 -r-- .debug_str CNT_INITIALIZED_DATA,MEM_DISCARDABLE
0x00014a00 0x200 0x140021000 0x1000 0x0 -r-- .debug_line_str CNT_INITIALIZED_DATA,MEM_DISCARDABLE
[Memory]
name size address flags mirror
-------------------------------
[Strings]
nth paddr vaddr len size section type string
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0 0x00010400 0x140012000 15 16 .rdata ascii Enter a number:
1 0x00010413 0x140012013 18 19 .rdata ascii Number input = %d\n
2 0x000104a0 0x1400120a0 30 31 .rdata ascii Argument domain error (DOMAIN)
3 0x000104bf 0x1400120bf 27 28 .rdata ascii Argument singularity (SIGN)
4 0x000104e0 0x1400120e0 31 32 .rdata ascii Overflow range error (OVERFLOW)
5 0x00010500 0x140012100 36 37 .rdata ascii Partial loss of significance (PLOSS)
6 0x00010528 0x140012128 34 35 .rdata ascii Total loss of significance (TLOSS)
7 0x00010550 0x140012150 53 54 .rdata ascii The result is too small to be represented (UNDERFLOW)
8 0x00010586 0x140012186 13 14 .rdata ascii Unknown error
9 0x00010598 0x140012198 42 43 .rdata ascii _matherr(): %s in %s(%g, %g) (retval=%g)\n
10 0x000105e0 0x1400121e0 27 28 .rdata ascii Mingw-w64 runtime failure:\n
11 0x00010600 0x140012200 31 32 .rdata ascii Address %p has no image-section
...........
...........
282 0x00014bab 0x1400211ab 43 44 .debug_line_str ascii C:/buildroot/src/gcc-14.2.0/gcc/config/i386
283 0x00014bd7 0x1400211d7 9 10 .debug_line_str ascii libgcc2.c
284 0x00014be1 0x1400211e1 6 7 .debug_line_str ascii i386.h
285 0x00014be8 0x1400211e8 11 12 .debug_line_str ascii gbl-ctors.h
286 0x00014bf4 0x1400211f4 9 10 .debug_line_str ascii libgcc2.c
[0x1400013f0]>
ผมจะเขียนเล่าให้เห็นภาพใหญ่ของแต่ละส่วนแบบสั้นๆ ก่อนนะครับ
[Info] ข้อมูลพื้นฐานของ pe file นี้
[Imports] รายการ API ที่ไฟล์ PE นี้ใช้งาน โดยนำเข้าจากไลบรารีใด หรือ รายการ API ที่นำเข้า
[Entries] ตำแหน่ง address ที่จะเริ่มทำงานของโปรแกรม จะอยู่ที่ตำแหน่งไหน , ในวงการ reverse engineering จะเรียกว่า ตำแหน่งเริ่มต้นการทำงานของโปรแกรม (Entry Point)
[Exports] ฟังก์ชันที่ไฟล์ PE นี้ส่งออก (Export) ให้โปรแกรมอื่นเรียกใช้งาน หรือ รายการฟังก์ชันที่ส่งออก
[Symbols] เป็นสัญลักษณ์ที่ rizin สร้างขึ้นมาอำนวยควาามสะดวกให้เรา ในการไล่ flow ที่เครื่องมือ static analysis ก็จะมีแนวทางของตัวเองที่แตกต่างออกไป [Sections] ขอบเขต (Section) ต่าง ๆ ของไฟล์ PE และขนาด หรือ รายการขอบเขตและขนาด
[Strings] สายอักขระ (String) ที่พบในไฟล์ PE และตำแหน่งที่อยู่ หรือ รายการสายอักขระและตำแหน่ง
คำสั่ง i มีอะไรให้เราดูได้อีกบ้าง กดได้เต็มที่เลยครับ
[0x1400013f0]> i?
Usage: i[?] # Get info about opened binary file
| i[jqt] # Show info of current file
| ia[jq] # Show a summary of all info (imports, exports, sections, etc.)
| iA[jqt] # List archs
| ic[?] # List classes, fields and methods
| iC[j] # Show signature info (entitlements, ...)
| id[jqp] # Debug commands
| iD[l] # Demangle symbol for given language
| ie[jqt] # List entrypoints
| iee[jqt] # List entries/exits functions (e.g. preinit, init, fini)
| iE[jqt.] # List exports
| ih[jqt] # Show binary fields
| iH # Show binary headers
| ii[jqt] # List imports
| iI[jqt] # Show binary info
| ik[?] [
| il[jqt] # List libraries
| iL[jqt] [
| im[jqt] # Show info about predefined memory allocation
| iM[jqt] # Show main address
| ir[jqt] # List relocations
| iR[jt] [
| is[jqQt] # List symbols
| is.[jqt] # Current symbol
| iS[jqt] [
| iS.[jt] # Current section
| iS= # Show ascii-art color bars with the section ranges
| iSS[jt] [
| iSS.[jt] # Current segment
| iT[j] # Show file hashes
| iV[j] # Display file version info
| iw[*] # Show try/catch blocks
| ix[j] # Display source file line info
| ix.[j] # Display source file line info at current address
| ixf[j] # Display source file info
| iz[jqQt] # List strings
| izz[jqQt] # List strings in the whole binary
| iz- # Purge string at current address via bin.str.purge
| iZ[j*] # Guess size of binary program
[0x1400013f0]>
เอาละครับเพื่อไม่ให้ blog ยาวเกินไปและแบ่งไปยัง blog อื่นๆบ้าง สำหรับ part นี้ขอจบเท่านี้ก่อน
ตอนนี้ เราได้เริ่มต้นก้าวแรกของการ Static Analysis แล้วครับ