PORTABLE EXECUTABLE FILE FORMAT Category : Relates to cracking, unpacking, reverse engineering Hexeditor any will do PEBrowse Pro http://www.smidgeonsoft.prohosting.com/download/PEBrow
Trang 1::[ARTeam Tutorial]::
PORTABLE EXECUTABLE FILE FORMAT
Category : Relates to cracking, unpacking, reverse engineering
Hexeditor (any will do)
PEBrowse Pro http://www.smidgeonsoft.prohosting.com/download/PEBrowse.zip
BaseCalc included in this archive
and metioned in the text:
Snippet Creator http://win32assembly.online.fr/files/sc.zip First_Thunk
Rebuilder http://www.angelfire.com/nt/teklord/FirstThunk.zip IIDKing http://www.reteam.org/tools/tf23.zip
Cavewriter http://sandsprite.com/CodeStuff/cavewriter.zip
Trang 2
L i m u :
Bài vi t này nh m m c ích i chi u thông tin t nhi u ngu n khác nhau và trình bày nó theo m t
ph ng pháp mà nh ng ng i m i b t u có th ti p c n d dàng nh t.M c dù bài vi t c trình bày
m t cách t m trong nhi u ph n, tuy nhiên nó c nh h ng theo m c ích reverse code
engineering cho nên các thông tin không c n thi t s c b qua B n s nh n th y r ng trong bài vi t này tôi ã vay m n r t nhi u t các bài vi t khác nhau ã c công b , ph bi n và t t c các tác gi
c a nh ng bài vi t ó ã c tôi nh c n v i lòng c m n sâu s c trong ph n tài li u tham kh o phía
cu i c a bài vi t này
PE là nh d ng file riêng c a Win32 T t c các file có th th c thi c trên Win32 (ngo i tr các t p tin VxDs và các file Dlls 16 bit) u s d ng nh d ng PE Các file Dlls 32 bit, các file COMs, các i u khi n OCX , các ch ng trình ng d ng nh trong Control Pannel (.CPL files) và các ng d ng NET t t
c u là nh d ng PE Th m chí các ch ng trình i u khi n Kernel mode c a các h i u hành NT
c ng s d ng nh d ng PE
T i sao chúng ta l i c n ph i tìm hi u v nó? Có 2 lý do chính nh sau : Th nh t chúng ta mu n thêm
các o n code vào trong nh ng file th c thi (ví d : k thu t Keygen Injection ho c thêm các ch c n ng)
và th hai là th c hi n công vi c unpacking b ng tay (manual unpacking) các file th c thi H u h t m i s quan tâm u d n v lý do th hai, ó là vì ngày nay h u nh các ph n m m shareware nào c ng u
c Packed l i v i m c ích là làm gi m kích th c c a file ng th i cung c p thêm m t l p b o v cho file
bên trong m t file th c thi ã b Packed thì các b ng import tables th ng th ng là ã b thay i, làm
m t hi u l c và ph n d li u thì luôn b mã hóa Các ch ng trình packer s chèn thêm mã l nh (code)
unpack file trong b nh vào lúc th c thi và sau ó nh y t i OEP (original entry point) ( ây là n i mà
ch ng trình g c th c s b t u th c thi, thi hành.) N u chúng ta tìm c cách (dump) k t xu t vùng nh này sau khi mà ch ng trình packer hoàn t t c quá trình unpacking file th c thi, ng th i thêm vào ó chúng ta c ng c n ph i ch nh s a l i Section và b ng import tables tr c khi mà ng d ng
c a chúng ta s run Làm th nào chúng ta có th th c hi n c i u này n u nh chúng ta không có
hi u bi t tí t o nào v nh d ng PE file ?
Ch ng trình th c thi c tôi s d ng làm ví d xuyên su t toàn b bài vi t này là BASECALC.EXE ,
m t ch ng trình r t h u ích t trang Web c a Fravia, nó cho phép tính toán và chuy n i gi a các s h decimal, hex , binary và octal Ch ng trình này c tác gi c a nó coded b ng ngôn ng Borland Dephi 2.0 , chính vì th mà nó là m t file lý t ng tôi l y làm ví d minh h a làm th nào trình biên d ch Borland cho OriginalFirstThunks null (Chi ti t h n s c c p ph n sau)
Trang 3
1 C u trúc c b n (Basic Structure) :
Hình minh h a d i ây s cho chúng ta th y c c u trúc c b n c a m t PE file
m c t i thi u nh t thì m t PE file s có 2 Sections : 1 cho o n mã (code) và 1 cho ph n d li u (data)
M t ch ng trình ng d ng ch y trên n n t ng Windows NT có 9 sections c xác nh tr c có tên là
.text , bss , rdata , data , rsrc , edata , idata , pdata , và debug M t s ch ng trình ng d ng l i không c n t t c nh ng sections này, trong khi các ch ng trình khác có th c nh ngh a v i nhi u sections h n phù h p v i s c n thi t riêng bi t c a chúng
Nh ng sections mà hi n th i ang t n t i và xu t hi n thông d ng nh t trong m t file th c thi là :
1 Executable Code Section, có tên là text (Micro$oft) ho c là CODE (Borland)
2 Data Sections, có nh ng tên nh data, rdata ho c bss (Micro$oft) hay DATA (Borland)
3 Resources Section, có tên là rsrc
4 Export Data Section, có tên là edata
5 Import Data Section có tên là idata
6 Debug Information Section, có tên là debug
Nh ng cái tên này th c s là không thích h p khi chúng b l i b i h i u hành (OS) và chúng là tài
li u ph c v cho l i ích c a các l p trình viên M t i m quan tr ng khác n a là c u trúc c a môt PE file trên a là chính xác , úng n gi ng h t nh khi nó c n p vào trong b nh vì v y b n có th xác
nh thông tin chính xác c a file trên a mà b n có th s mu n tìm ki m nó khi file c n p vào trong
Trang 4môt Page m i M t tr ng trong PE header s thông báo cho h th ng bi t có bao nhiêu b nh c n c riêng ra cho vi c ánh x trong file B nh o c gi i thích ph n d i ây.
vì v y thay th vi c b vi x lý phân chia b nh thành các trang i u này có m t s l i th nh sau :
T i th i i m n p , ch ng trình qu n lý b nh thi t l p nh ng quy n truy c p lên các trang b
nh cho các sections khác nhau d a trên nh ng thi t l p c a chúng trong Section header i u này
s quy t nh rõ m t section ã cho là có th c c (readable) , có th ghi c (writeable) hay
có th th c thi c (executable) i u này có ngh a là m i section ph i c b t u trên m t trang m i Tuy nhiên , kích th c trang m c nh cho h i u hành Windows là 4096 bytes (1000h) và nó s là lãng phí s p các file th c thi vào m t ranh gi i 4KB Page trên a khi mà
i u này s làm cho chúng tr nên quá l n h n m c c n thi t B i vì i u này, PE header có hai
tr ng alignment khác nhau là : Section alignment và file alignment Section alignment là cách
các sections c s p trong b nh nh ã nói trên Còn File Alignment (s d ng 512 bytes hay
200h) là cách các section c s p trong file trên a và là kích th c c a nhi u sector t i u quá trình loading (loading process)
3 Nó cho phép m t file ánh s trang (paging file) c s d ng trên c ng l u tr các trang
m t cách t m th i t b nh v t lý khi chúng không c s d ng L y ví d nh sau, n u m t
ng d ng ã c n p nh ng ang trong tình tr ng r nh r i (idle) ,không gian a ch c a nó có
th c ánh trang bên ngoài a t o ra không gian cho các ng d ng khác c n c n p vàp trong b nh RAM N u nh tình hình o l n , h i u hành có th n p m t cách d dàng
ng d ng u tiên tr l i b nh RAM và h i ph c l i s thi hành t i n i mà nó b ng ng l i M t
Trang 5th ng có th s d ng c ng nh là m t n i l u tr th c p b t c khi nào mà b nh v t lý không còn không gian l u tr
Khi PE file ã c n p vào trong b nh b i windows loader, phiên b n trong b nh này c bi t n
nh là m t module a ch b t u n i mà ánh x file b t u c g i là m t HMODULE M t module
trong b nh bi u di n t t c o n mã , d li u và toàn b tài nguyên t m t file th c thi mà i u này là
c n thi t cho s thi hành khi mà thu t ng Proccess v c b n tham chi u t i m t không gian a ch cô
bi t nó nh là m t file th c thi h p l và thi hành DOS stub , ph n mà ã c l u tr tr c ti p sau
Header H u h t DOS stub th ng s d ng hàm 9 c a ng t int 21h hi n ra m t chu i kí t thông báo
t ng t nh sau : "This program must be run under Microsoft Windows" nh ng nó có th là m t
ch ng trình DOS ang phát tri n m nh (full-blown DOS program) (Nói tóm l i là DOS Stub ch là m t
ch ng trình DOS EXE nh hi n th m t thông báo l i th ng là nh trên, chính do header này c t
n m u c a file , cho nên các virus DOS có th lây nhi m vào PE image chính xác t i DOS stub Tuy nhiên ch ng trình DOS Stub v n còn c gi l i vì lí do t ng thích v i các h th ng Windows 16-bit) Khi xây d ng m t ng d ng phát tri n trên n n t ng Windows , ch ng trình linker liên k t m t stub
program m c nh có tên g i là WINSTUB.EXE vào trong file th c thi c a b n B n có th ghi è , ph
quy t cách hành s c a ch ng trình linker m c nh này b ng cách thay th m t ch ng trình based c a riêng b n thay cho WINSTUB và s d ng STUB: m t tùy ch n c a ch ng trình linker khi liên k t file th c thi
DOS Header là m t c u trúc c nh ngh a trong các file windows.inc ho c winnt.h (N u nh b n có
m t ch ng trình d ch h p ng ho c m t trình biên d ch ã c cài t trên máy , b n s tìm th y các
file này trong th m c \include\) Nó có 19 thành ph n (members) mà trong ó thành ph n magic và
lfanew là áng chú ý
Trong PE file , ph n magic c a DOS Header ch a giá tr 4Dh, 5Ah ( ó chính là các kí t MZ , vi t t t
Trang 6thông báo cho chúng ta bi t ây là DOS Header h p l MZ là 2 bytes u tiên mà b n s nhìn th y trong
b t kì m t PE file nào , khi file ó c m b ng m t ch ng trình Hex editor (Xem hinh minh h a phía
d i)
Nh b n ã nhìn th y trong hình minh h a phía trên, b n th y r ng ph n lfanview là m t giá tr DWORD
(t c là m t Double Word = 4bytes) và nó n m v trí cu i cùng c a DOS Header và ng tr c c a n i
b t u DOS Stub Nó ch a offset c a PE Header, có liên quan n ph n u file (file beginning)
Windows Loader s tìm ki m offset này vì v y nó có th b qua Dos Stub và i tr c ti p t i PE Header
Hình minh h a trên ã giúp ích cho chúng ta r t nhi u khi nó ch cho ta th y rõ kích th c c a t ng
ph n t i u này cho phép chúng ta truy xu t nh ng thông tin mà chúng ta quan tâm d a trên vi c m
s l ng các bytes t i m b t u c a section ho c m t i m có th nh n bi t c
Nh chúng ta ã nói trên, DOS Header chi m 64 bytes u tiên c a file ví d 4 hàng u c nhìn
th y trong m t ch ng trình Hex Editor trong hình minh h a d i ây.Giá tr DWORD cu i cùng tr c
i m b t u DOS Stub ch a nh ng giá tr 00h 01h 00h 00h ý n vi c reverse tr t t byte , i u này
s giúp chúng ta bi t 00 00 01 00h là nh ng offset n i mà PE Header b t u PE Header b t u v i
ph n signatures c a nó là 50h, 45h, 00h, 00h (Các kí t PE c i kèm b i các giá tr t n cùng là 0)
N u t i tr ng Signature c a PE Header , b n tìm th y m t NE signature ó ch không ph i là PE , thì lúc này b n ang làm vi c v i môt file NE Windows 16-bit C ng t ng t nh vây, n u b n th y là LE
n m t i Signature field thì có ngh a là nó cho ta bi t ó là m t trình i u khi n thi t b o Window 3.x
(VxD) Còn t i ó là m t LX thì ó là d u hi u c a m t file cho OS/2 2.0
OKi t m ngh chút xíu !! Chúng ta s ti p t c th o lu n trong ph n ti p theo c a bài vi t này : )
3 The PE Header :
PE Header là thu t ng chung i di n cho m t c u trúc c t tên là IMAGE_NT_HEADERS C u
trúc này bao g m nh ng thông tin thi t y u c s d ng b i loader IMAGE_NT_HEADERS có 3
thành ph n và c nh ngh a trong file windows.inc nh sau :
Trang 7
OptionalHeader luôn luôn hi n di n và c t o thành b i 224 bytes ti p theo Nó ch a thông tin v s
Logic bên trong c a m t file PE Ví d : AddressOfEntryPoint Kích th c c a nó c qui nh b i
m t thành ph n c a FileHeader Các c u trúc c a nh ng thành ph n này c ng c nh ngh a trong file
windows.inc
FileHeader c nh ngh a gi ng nh hình minh h a d i dây :
H u h t nh ng thành ph n này không còn h u ích i v i chúng ta nh ng chúng ta ph i thay i thành
ph n NumberOfSections n u nh chúng ta mu n thêm ho c xóa b t kì sections nào trong m t PE File
Characteristics bao g m các c mà các c này xác nh nh ng th hi n chúng ta bi t c PE File mà chúng ta làm vi c là m t file có th th c thi (executable) hay là m t file DLL Quay tr l i ví d c a
chúng ta trong màn hình HexEditor, chúng ta có th tìm th y NumberOfSections b ng vi c m m t DWORD và m t WORD (6 bytes) t ch b t u c a PE Header (T c là giá tr DWORD chính là
Signature còn giá tr WORD chính là Machine) (note : tr ngNumberOfSections c s d ng b i viruses vì nhi u lí do khác nhau L y ví d , tr ng này có th b thay i b ng cách viruses s gia t ng nó lên thêm m t section m i vào PE image và t o n virus body vào section ó Các h th ng
Windows NT có th ch p nh n t i 96 sections trong m t PE file Trên h th ng s d ng Win95 thì không
ki m tra k ph n section number) Xem hình minh h a d i ây :
Trang 9
Ho c th m chí n u b n ang s d ng PEiD b n c ng có th ki m nghi m c i u này b ng cách nh n
vào button là Subsystem :
Chú ý : PEiD là m t công c c c kì h u ích Ch c n ng chính c a nó là dùng scan Executable files
và ch cho chúng ta bi t c lo i Packer mà File này c s d ng cho vi c nén và protect file Ngoài ra
i kèm v i PEiD là m t Plugin không kém ph n quan tr ng, ó chính là Krypto ANALyser Khi b n s
d ng Plug-in này thì nó s cho chúng ta bi t c file ó có s d ng nh ng m t mã (cryptography) gì
Ch ng h n : CRC, MD4, MD5 ho c SHA v v Th m chí công c này c ng s d ng các danh sách c
ng i dùng nh ngh a v các Packer signatures Tóm l i PEiD là công c u tiên c s d ng khi chúng ta b t tay vào công vi c unpacking
Chúng ta ti p t c nghiên c u t i thành ph n ti p theo là OptionalHeader, nó chi m 224 bytes , trong ó
128 bytes cu i cùng s ch a thông tin v Data Directory Nó c nh ngh a gi ng nh hình minh h a
d i ây :
Trang 10
AddressOfEntryPoint RVA ( a ch o t ng i) c a câu l nh u tiên mà s c th c thi khi
ch ng trình PE Loader s n sàng run PE File(thông th ng nó tr t i section text hay CODE) N u
nh b n mu n làm thay i lu ng c a th t th c hi n , b n c n ph i thay i l i giá tr trong tr ng này thành m t RVA m i và do ó câu l nh t i giá tr RVA m i này s c th c thi u tiên Các ch ng trình Packer th ng thay th giá tr này b ng giá tr decompression stub c a chúng, sau ó s thi hành s
nh y tr v i m b t u c a ch ng trình hay còn g i v i tên thông d ng là OEP M t l u ý thêm n a
là ch b o v StarForce thì CODE section s không có m t , hi n di n trong file trên a nh ng l i
c ghi lên b nh o trong quá trình th c thi Vì th mà giá tr trong tr ng này là m t VA (xem thêm
ph n ph l c s c c p bên d i) (note : ây th c s là m t tr ng c t y u và c c kì quan tr ng
b i vì tr ng này s b thay i b i h u h t các ki u lây nhi m virus tr t i i m th c thi th c s c a virus code)
ImageBase a ch n p c u tiên cho PE File L y ví d : N u nh giá tr trong tr ng này là
400000h, PE Loader s c g ng n p file vào trong không gian a ch o mà b t u t i 400000h T
c u tiên ây có ngh a là PE Loader không th n p file t i a ch ó n u nh có m t module nào khác ã chi m gi vùng a ch này 99 % các tr ng h p giá tr c a ImageBase luôn là 400000h
SectionAlignment Ph n liên k t c a các Sections trong b nh Khi file th c thi c ánh x vào trong b nh , thì m i section ph i b t u t i m t a ch o mà là m t b i s c a giá tr này Giá tr c a
tr ng này nh nh t là 0x1000(4096 bytes), nh ng trình các trình linkers c a Borland th ng s d ng các giá tr m c nh l n h n, ví d nh là 0x10000(64KB) L y ví d nh sau : N u giá tr t i tr ng này là
4096 (1000h), thì m i section ti p theo s ph i b t u t i v trí mà section tr c ó c ng v i 4096 bytes
Trang 11cho dù là không gian a ch gi a 401000h và 402000h s h u nh không c s d ng.(note: h u h t các Win32 viruses s d ng tr ng này tính toán v trí chính xác c a virus body nh ng l i không thay i
tr ng này)
FileAlignment Ph n liên k t c a các Section trong file L y ví d : n u giá tr c th c a tr ng này là
512 (200h), thì m i section ti p theo s ph i b t u t i v trí mà sections tr c ó c ng v i 200h N u section u tiên là t i offets 200h, và có kích th c là 10 bytes, v y thì section ti p theo s c nh v
ta i ch offet là 400h : Không gian gi a file offsets 522 và 1024 là không s d ng c/ho c không
c nh ngh a
SizeOfImage - Toàn b kích th c c a PE image trong b nh Nó là t ng c a t t c các headers và sections c liên k t t i SectionAlignment
SizeOfHeaders - Kích th c c a t t c các headers + section table.Nói tóm l i , giá tr này là b ng kích
th c file tr i kích th c c t ng h p c a toàn b sections trong file B n c ng có th s d ng giá tr này nh m t file offset c a Section u tiên trong PE file
DataDirectory M t m ng cùa 16 IMAGE_DATA_DIRECTORY structures, m i m t ph n có liên quan t i m t c u trúc d li u quan tr ng trong PE File ch ng h n nh import address table C u trúc
quan tr ng này s c th o lu n chi ti t trong nh ng ph n ti p theo
Trang 12
Bên c nh các công c PE ã c c p trên, ch ng trình debug c a thích là OllyDbg c ng có
th phân tích c PE Headers thông qua vi c hi n th thông tin m t cách y và có ý ngh a Dùng
OllyDbg load file ví d c a chúng ta vào trong Olly và nh n Alt + M ho c b m vào nút M m c a s Memory Map - c a s này s cho chúng ta th y c PE File ã c n p vào trong b nh
Trang 13
4 The Data Directory :
Tóm t t l i ph n tr c , chúng ta ã bi t c r ng Data Directory là 128 bytes cu i cùng c a
OptionalHeader , và l n l t là nh ng thành ph n cu i cùng c a PE Header IMAGE_NT_HEADERS
Nh chúng ta ã t ng nói, Data Directory là m t m ng c a 16 c u trúc IMAGE_DATA_DIRECTORY
structures, c m i 8 bytes thì m i ph n l i có liên quan v i m t c u trúc d li u quan tr ng trong PE File
M i m ng tham chi u t i m t m c ã c nh ngh a tr c , ví d nh là import table C u trúc c a
Data Directory có 2 thành ph n mà bao g m thông tin v v trí và kích th c c a c u trúc d li u trong
nh ng i u ã bàn n :
VirtualAddress là m t a ch o t ng i (relative virtual address) c a c u trúc d li u (xem ph n sau)
isize bao g m kích th c theo bytes c a c u trúc d li u
16 directories mà nh ng c u trúc này tham chi u n , b n thân chúng c nh ngh a trong file
window.inc :
Trang 14
L y ví d , chúng ta s d ng ch ng trình LordPE Trong LordPE , ph n Data Directory cho file ví d
c a chúng ta ch ch a 4 thành ph n ( ã c tôi khoanh màu trong hình v ) 12 thành ph n còn l i không c s d ng và c i n giá tr là 0 :
Nh các b n ã th y trong hinh minh h a trên, tr ng import table bao g m thông tin v RVA và kích th c c a IMAGE_IMPORT_DESCRIPTORarray the Import Directory Trong ch ng trình HexEditor, hình minh h a bên d i ây ch cho chúng ta th y PE Header v i ph n data directory c tô nét ngoài b ng màu M i m t khu v c c khoanh này bi u di n cho m t c u trúc
IMAGE_DATA_DIRECTORY Giá tr DWORD u tiên chính là VirtualAddress còn giá tr cu i cùng chính là isize
Trang 15
Trong hình minh h a trên, thì Import Table c tô b ng màu h ng 4 bytes u tiên là RVA 02D000h (NB reserver oder) Kích th c c a Import Table là 181Eh bytes Nh chúng ta ã nói trên thì v trí
c a nh ng data directories t ph n u c a PE Header là luôn luôn gi ng nhau Ví d : giá tr DWORD
80 bytes t ph n u c a PE Header luôn luôn là RVA c a Import Table
xác nh c v trí c a m t directory c bi t, b n xác nh rõ a ch t ng i t data directory Sau ó s d ng a ch o xác nh section nào directory trong M t khi b n phân tích section nào
ch a directory , thì Section Header cho section ó sau ó s c s d ng tìm ra offset chính xác
5 The Section Table :
Section Table là thành ph n ti p theo ngay sau PE Header.Nó là m t m ng c a nh ng c u trúc
IMAGE_SECTION_HEADER, m i ph n t s ch a thông tin v m t section trong PE File ví d nh
thu c tính c a nó và offset o (virtual offset) Các b n hãy nh l i r ng s l ng các sections chính là thành ph n th 2 c a FileHeader (6 bytes t ch b t u c a PE Header) N u có 8 sections trong PE File, thì s có 8 b n sao c a c u trúc này trong table.M i m t c u trúc Header (header structure) là 40 bytes và
s không có thêm padding gi a chúng (Padding ây có ngh a là s không chèn thêm các bytes có giá
tr 00h vào).C u trúc này c nh ngh a trong file windows.inc nh sau :
Trang 16
Xin nh c l i m t l n n a , không ph i t t c các thành ph n trên u h u ích Tôi s ch miêu t nh ng thành ph n th c s là quan tr ng mà thôi
Name1 - (NB this field is 8 bytes) Tên này ch là là m t nhãn và th m chí là có th tr ng Chú ý r ng
ây không ph i là m t chu i ASCII vì v y nó không c n ph i k t thúc b ng vi c thêm các s 0
VirtualSize (DWORD union) Kích th c th t s c a section's data theo bytes Nó có th nh h n kích
th c c a section trên a (SizeOfRawData) và s là nh ng gì mà trình loader nh rõ ví trí trong b nh cho section này
VirtualAddress RVA c a section Trình PE loader s phân tích và s d ng giá tr trong tr ng này khi
nó ánh x section vào trong b nh Vì v y n u giá tr trong tr ng này là 1000h và PE File c n p t i
i ch 400000h , thì section s c n p t i a ch là 401000h
SizeOfRawData Kích th c c a section s data trong file trên a, c làm tròn lên b i s ti p theo c a
s liên k t file b i trình biên d ch
PointerToRawData (Raw Offset) thành ph n này th c s r t h u d ng b i vì nó là offset t v trí b t
u c a file cho t i ph n section s data N u nó có giá tr là 0 , thì section s data không c ch a trong file và s không b bó bu c vào th i gian n p (load time) Trình PE Loader s s d ng giá tr trongtr ng này tìm ki m ph n data trong section là âu trong file
Characteristics - Bao g m các c ví d nh section này có th ch a executable code, initialized data ,
uninitialized data , có th c ghi ho c c (Xem thêm ph n ph l c)
NOTE : Khi b n ti n hành tìm ki m m t section c th nào ó , nó có th ph t l toàn b PE Header và
b t u phân tích section headers b ng cách tìm ki m section name trong c a s ASCII c a ch ng trình HexEditor c a b n
Quay tr l i ví d c a chúng ta , trong c a s HexEditor file c a chúng ta có 8 sections nh chúng ta ã nhìn th y trong section PE Header
Trang 17
Sau khi có c Section Headers chúng ta s tìm ki m các sections.Trong file trên a , m i section b t
u t i m t offset mà là b i s l n c a giá tr FileAlignment c tìm th y trong OptionalHeader Gi a
các section s data s là các byte 00 c thêm vào
Khi c n p lên RAM , các sections luôn luôn b t u trên m t ranh gi i trang (page boundary) vì v y byte u tiên c a m i section t ng ng v i m t trang b nh (memory page) Các trang trên nh ng b vi
x lý x86 CPU là 4KB aligned , trong khi trên IA-64 là 8KB aligned Giá tr liên k t (aligment value) này
c l u tr trong SectionAlignment , và c ng c l u trong OptionalHeader
L y m t ví d , n u nh OptionalHeader k t thúc t i file offset 981 và FileAlignment là 512, thì section
u tiên s b t u t i byte 1024 Chú ý r ng b n có th tìm nh ng section thông qua PointerToRawData
ho c là VirtualAddress, vì v y không c n ph i lo ng i b n kho n v alignments
Trong hình minh h a trên , ImportData Section (.idata) s b t u t i offset 0002AC00h (highlighted pink, NB reverse byte order) t v trí b t u c a file Kích th c c a nó , do ã c qui nh là
DWORD nên nó s là 1A00h bytes
6 The PE File Sections :
Là nh ng sections ch a n i dung chính c a file, bao g m code, data, resources và nh ng thông tin khác
c a file th c thi M i section có m t Header và m t body (d li u thô raw data : là d li u ch a c x
lý ho c ch a c nh khuôn th c, nó ch a c s p x p, biên t p s a ch a ho c ch a c bi u di n
l i d i d ng d truy tìm và phân tích) Nh ng Section Headers thì c ch a trong Section Table
nh ng nh ng Section Bodies l i không có m t c u trúc file c ng r n Chúng có th c s p x p h u nh theo b t kì cách nào khi m t trình linker mu n t ch c chúng , v i i u ki n là Header c i n thông tin y có th gi i mã d li u
Trang 18
M t ch ng trình ng d ng c thù trên h i u hành Windows NT có 9 sections c nh ngh a tr c
có tên là text, bss, rdata, rsrc, edata, idata, pdata và debug M t vài ch ng trình không c n ph i
có t t c c các sections này , trong khi m t s ch ng trình ng d ng khác l i nh ngh a thêm nhi u sections khác phù h p v i nh ng yêu c u riêng bi t c a chúng
Executable Code Section :
Trong h i u hàn Windows NT t t c các o n mã (code segment) t p trung vào m t sections n l
c g i là text ho c là CODE T khi h i u hành Windows NT chuy n sang s d ng m t h th ng
qu n lý b nh o d a trên trang, thì có m t section code l n d dàng h n trong vi c qu n lý i v i h
i u hành c ng nh i v i nh ng ng i phát tri n ng d ng Section này c ng ch a i m t nh p (entry point) mà ã c c p ph n trên và b ng jump thunk table tr t i IAT (xem thêm ph n import theory)
T t c nh ng bi n khác (ngo i tr nh ng bi n t ng , mà ch xu t hi n trên Stack ) c l u tr trong
Section data ó là nh ng ng d ng ho c là nh ng bi n toàn c c module.
Resources Section :
Section rsrc ch a các thông tin resource cho m t module 16 bytes u tiên bao g m m t Header gi ng
nh nh ng section khác, nh ng d li u c a Section này h n n a c c u trúc vào trong m t resource tree và c quan sát t t nh t thông qua vi c s d ng m t ch ng trình resource editor M t ch ng trình
khá n i ti ng ó là ResHacker, ây là m t ch ng trình mi n phí cho phép ch nh s a , thêm m i, xóa, thay th và sao chép các Resources :
Trang 19
Section edata ch a Export Directory cho m t ch ng trình ng d ng ho c file Dll Khi bi u di n,
section này bao g m các thông tin v tên và a ch c a nh ng hàm exported functions Chúng ta s nói
ti p v v n này sau , m t ph n r t quan tr ng ti p theo
Import Data Section :
Section idata ch a nh ng thông tin khác nhau v nh ng hàm imported functions bao g m c Import
Directory và b ng Import Address Table Chúng ta c ng s nói ti p v v n này ph n sau
n m trong Section rdata nh ã c c p ph n trên M i m t th m c s liên quan t i thông tin
Debug trong Section debug
Base Relocations Section :
Khi mà trình linker t o ra m t file Exe, nó chu n b m t n i mà t i ó file s c ánh x vào trong b
nh D a trên i u này, trình linker s t các các a ch th t c a o n mã và nh ng m c d li u vào trong file th c thi N u vì b t c lý do gì file th c thi k t thúc quá trình n p m t n i nào ó n u không trong ph m vi không gian a ch o , thì nh ng a ch này s b trình linker t vào trong image không úng Thông tin c l u trong Section reloc cho phép trình PE loader fix nh ng a ch này trong
loaded image vì v y chúng s l i chính xác M t khác, n u trình loader có th n p file t i nh ng a ch base address c th a nh n b i trình linker , thì d li u Section reloc là không c n thi t và b l i
Trang 20
Các m c trong section reloc c g i b i Base relocation vì s s d ng c a chúng ph thu c vào a ch base address c a loaded image Base Relocation n gi n ch là m t danh sách c a các v trí trong image
mà yêu c u m t giá tr cthêm vào chúng nh d ng c a d li u base relocation h i ph c t p Các
m c base relocation c nén (packed) trong m t chu i c a các ph n dài bi n i M i ph n di n t các Relocation thay th cho m t trang 4KB trong image
Hãy xem m t ví d hi u cách h at ng c a base relocation M t file th c thi c liên k t v i m t a
ch c s c a 0x10000 T i offset 0x2134 bên trong image là m t con tr ch a a ch c a m t chu i Chu i b t u t i a ch v t lý là 0x14002, vì v y con tr s ch a giá tr là 0x14002 Sau ó b n n p file,
nh ng trình loader quy t nh r ng nó c n ph i ánh x image b t u t i a ch v t lý là 0x60000 S chênh l ch gi a trình linker d a trên a ch n p và a ch n p th c s c g i là delta Trong tr ng
h p ví d c a chúng ta thì delta là 0x50000 bytes cao trong b nh , nh v y là chu i (bây gi t i a ch
là 0x64002) Con tr t i chu i gi ây không còn ng n a File th c thi ch a m t base relocation i
di n cho v trí b nh (memory location) n i mà con tr t i chu i tr v gi i quy t m t base
relocation , trình loader c ng thêm giá tr delta vào giá tr g c ban u t i a ch base relocation Trong
tr ng h p c a chúng ta , trình loader s c ng giá tr delta là 0x50000 vào giá tr con tr ban u là (0x14002) , và l u k t qu tr l i là (0x64002) vào trong b nh c a con tr Vì th chu i bây gi s có
a ch th c là t i 0x64002 , v y là m i th u t t p
7 The Export Sections :
Section này có liên quan m t cách c bi t t i các file Dlls Ph n thông tin c trích d i ây t Win32
Programmer s Reference s gi i thích t i sao :
Các hàm có th c exported b i m t Dll theo hai cách : by name ho c by ordinal only M t s
th t hay m t ch s là m t s 16-bit (WORD sized) mà duy nh t ch ra m t hàm trong m t file Dll riêng bi t Con s này là duy nh t ch bên trong file Dll nó tham chi u t i Chúng ta s nói v exporting
b ng s th t ph n sau
N u nh m t hàm c exported b ng tên , khi các file Dll khác ho c các file th c thi mu n g i hàm này
, chúng s cùng s d ng tên c a hàm ho c ch s c a hàm trong hàm GetProcAddress mà tr v a ch
c a hàm trong file Dll c a nó Tài li u Win32 Programmer s Reference s gi i thích thêm v ph ng
th c ho t ng c a hàm GetProcAddress (M c dù trong th c t thông tin v hàm này r t nhi u, không
ch nh ng tài li u c vi t b i M$, nh ng thông tin khác s c p sau) Các b n hãy chú ý n nh ng
ph n mà tôi ã ánh d u b ng vi n màu :
Trang 21
Hàm GetProcAddress có th làm c i u này b i vì các tên và a ch c a nh ng exported function
c s p x p trong m t c u trúc c nh ngh a r t t t trong Export Directory Chúng ta có th tìm
th y Export Directory b i vì chúng ta bi t nó là thành ph n u tiên trong data directory và RVA c a nó
c ch a t i offset 78h t n i b t u c a PE Header (Xin xem thêm ph n ph l c)
C u trúc export c g i là IMAGE_EXPORT_DIRECTORY Có 11 thành ph n trong c u trúc này
nh ng có m t s không quan tr ng :
Trang 22
nName Internal name c a module Tr ng này th c s c n thi t b i vì tên c a file có th b thay i
b i ng i s d ng N u i u ó x y ra , trình PE loader s s d ng Internal name này
nBase B t u c a s th t hay s ch s (Tr ng này c s d ng l y nh ng index trong of-function array xem bên d i)
NumberOfFunctions T ng s các hàm mà c exported b i module
NumberOfNames S l ng các Symbols c exported b ng name Giá tr này không ph i là s l ng
c a t t c các hàm/symbols trong module l y c con s này, b n c n ph i ki m tra
NumberOfFunctions Nó có th là 0 Trong tr ng h p y, module có th export b ng ordinal only N u không có hàm / symbol c exported trong tr ng h p u tiên , thì RVA c a b ng Export table trong data directory s là 0
AddressOfFunctions m t RVA tr t i m t m ng c a các con tr t i các hàm trong module Export Address Table (EAT) s d ng nó theo cách khác, nh ng RVA tr t i các hàm trong module c
gi l i trong m t m ng và tr ng này tr t i u c a m ng ó
AddressOfNames m t RVA tr t i m t m ng các RVA c a tên các hàm c l u trong module
Export Name Table (ENT)
AddressOfNameOrdinals m t RVA tr t i m t m ng 16 bit mà ch a các ordinals c a các named functions Export Ordinal Table (EOT)
Trang 23
Nh v y c u trúc IMAGE_EXPORT_DIRECTORY tr t i 3 m ng và m t b ng nh ng chu i kí t
ASCII M ng quan tr ng là EAT, vì nó là m t m ng c a các con tr hàm mà ch a a ch c a các
exported functions Hai m ng th hai là (ENT và EOT) ch y song song theo th t s p x p t ng d n d a trên tên c a các hàm m t phép tìm ki m nh phân cho tên c a hàm có th c th c hi n và s a k t
qu là s th t c a hàm ó c tìm th y vào trong m t m ng khác.S th t ch n gi n là m t ch s bên trong EAT i v i hàm ó
Tr c ây m ng EOT t n t i nh là m t liên k t gi a tên và a ch , nó không th ch a nhi u ph n t h n
m ng ENT Ví d : m i m t tên có th có m t và ch m t a ch t ng ng i u ng c l i là không úng : m t a ch có th có nhi u tên t ng ng v i nó N u ó là nh ng hàm v i tên bí danh tham chi u n cùng m t a ch thì ENT s có nhi u ph n t h n là EOT
Trang 24
L y ví d , n u m t file Dll export 40 hàm , thì nó ph i có 40 thành ph n trong m ng c tr b i
AddressOfFunctions (EAT) và tr ng NumberOfFunctions ph i ch a 40 giá tr
tìm ki m m t hàm t tên c a nó, H i u hành (OS) u tiên s tìm nh ng giá tr c a
NumberOfFunction và NumberOfNames trong Export Directory Ti p theo nó s d o qua các m ng
c tr b i AddressOfNames (ENT) và AddressOfNameOrdinals (EOT) m t cách ng th i, tìm
ki m tên c a hàm N u nh tên c a hàm c tìm th y trong ENT, thì giá tr t ng ng v i ph n t trong EOT c trích xu t và s d ng nh là ch m c bên trong EAT
L y ví d , trong file Dll 40 hàm c a chúng ta trên chúng ta mu n tìm ki m hàm X N u chúng ta tìm tên hàm X(gián ti p thông qua con tr khác) t i ph n t th 39 trong ENT , chúng ta nhìn vào ph n t th
39 c a EOT và th y 5 giá tr Sau ó chúng ta xét ph n t th 5 c a EAT tìm ki m RVA c a hàm X
N u nh b n ã s n có s th t c a m t hàm , b n có th tìm th y a ch c a nó b ng cách i tr c ti p
t i EAT M c dù có c a ch c a m t hàm thông qua s th t c a nó thì d dàng h n và nhanh h n
r t nhi u so v i vi c s d ng tên c a hàm , thì ng c l i i u b t l i là s g p khó kh n trong vi c qu n lý module N u nh fileDll c nâng c p / c p nh t và s th t c a các hàm b thay i, thì các ch ng trình khác mà ch y d a trên file Dll này s b Break
Exporting by Ordinal Only :
NumberOfFunctions ph i ít nh t là b ng v i NumberOfNames Tuy nhiên th nh tho ng trong m t s
tr ng h p thì NumberOfNames l i ít h n NumberOfFunctions Khi m t hàm c Exported thông qua s th t , nó không có danh sách trong c hai m ng ENT và EOT nó không có tên Nh ng hàm mà không có tên thì c Exported thông qua s th t
L y ví d nh sau , n u ta có 70 hàm nh ng ch có duy nh t 40 m c trong ENT , v y thì có ngh a là có 30 hàm trong module mà c Exported b ng s th t V y bây gi làm th nào chúng ta tìm ra nh ng hàm ó là gì? i u này không d dàng B n ph i tìm ra b ng ph ng pháp lo i tr , l y ví d : nh ng m c trong EAT mà không c tham chi u b i EOT ch a RVAs c a các hàm c Exported b ng s th t
hành WinNT , Win2k và WinXP, hàm trong kernel32.dll là HeapAlloc c forwarded t hàm
RtlAllocHeap c Exported b i ntdll.dll File NTDLL.DLL c ng ch a các API b m sinh mà t ng tác
tr c ti p v i kernel windows Forwarding c th c hi n t i th i i m liên k t thông qua m t câu l nh
c bi t trong DEF file
Forwarding là m t k thu t mà Microsoft s d ng a ra m t t p h p các API thông d ng và che
d u s khác bi t n n t ng gi a h h i u hành NT v i h 9X Các ng d ng không có c nhi m v
g i các hàm trong t p h p các API b m sinh vì i u này s phá v kh n ng t ng thích gi a Win9x và 2K/XP i u này có th gi i thích t i sao các file th c thi b Packed có th c unpacked và có b ng imports c a chúng c xây d ng l i b ng tay trên m t OS có th không run c trên OS khác b i h
th nng API forwarding ho c m t vài chi ti t khác ã b ch nh s a
Khi m t Symbol (Hàm) c Forwarded RVA c a nó m t cách rõ ràng không th là m t an code ho c
a ch d li u trong module hi n t i thay th , b ng EAT ch a m t con tr t i m t chu i ASCII c a
Trang 25
N u v y thì m c EAT cho m t hàm tr t i m t a ch bên trong Export Section (ví d chu i ASCII) thay
vì h n là tr ra ngoài vào m t file DLL khác, thì b n bi t r ng hàm ó ã c forwarded
nh t c a section này là ImportDirectory và ImportAddressTable mà chúng ta s nói n ti p theo ây
Trong m t s file th c thi có th c ng có các directories là Bound_Import và Delay_Import
Delay_Import directory , v i chúng ta nó không quan tr ng l m nh ng chúng ta s c p t i
Bound_Import directory ph n ti p sau.
Trình Windows loader ch u trách nhi m v vi c n p t t c các file Dll mà ng d ng s d ng và ánh x chúng vào trong không gian a ch process Nó ph i tìm a ch c a t t c các imported functions trong các file Dlls khác nhau c a chúng và s p t chúng s n sàng s d ng cho các file th c thi c n p
a ch c a các hàm bên trong m t file Dll không ph i là nh ng a ch t nh mà thay i khi các phiên
b n c c p nh t hóa c a file Dll c released , vì v y các ng d ng không th c xây d ng s
d ng các a ch hàm hardcoded B i vì ó là m t c ch c phát tri n cho phép nh ng thay i mà không c n ph i t o ra nhi u s thay i, ch nh s a i v i o n mã c a file th c thi vào lúc chay i u này ã c hoàn thành thông qua vi c s d ng m t Import Address Table (IAT) ây là m t b ng c a
nh ng con tr t i các a ch hàm mà ã c i n vào b i trình Windows loader khi các file Dll c
n p
B ng vi c s d ng m t b ng con tr , trình loader không c n ph i thay i nh ng a ch c a các imported functions trong o n mã l nh mà chúng c g i T t c nh ng th mà nó ph i làm là thêm a ch chính xác vào m t n i riêng l trong b ng import và công vi c c a nó c hoàn t t
The Import Directory :
Import Directory th c s là m t m ng c a các c u trúc IMAGE_IMPORT_DESCRIPTOR M i c u
trúc là 20 bytes và ch a thông tin v m t DLL mà PE file c a chúng ta import các hàm vào L y ví d ,
n u PE file c a chúng ta import các hàm t 10 file DLL khác nhau, thì s có 10 c u trúc
IMAGE_IMPORT_DESCRIPTOR trong m ng này Không có tr ng nào ch cho ta bi t s l ng c a các c u trúc trong m ng này thay th , c u trúc cu i cùng s có các tr ng c i n y các giá tr 0 (zeros)
Cùng v i Export Directory, b n có th tìm th y Import Directory âu b ng vi c quan sát t i Data
Directory (80 bytes t ch b t u c a PE Header) Trong ó thì thành ph n u tiên và cu i cùng là quan tr ng nh t :
Trang 26
Thành ph n u tiên OriginalFirstThunk , là m t DWORD union, có th t i m t th i i m là m t t p
h p c a các c Tuy nhiên, Microsoft ã thay i ý ngh a c a nó và không bao gi lo l ng c p nh t file
WINNT.H Tr ng này th c s ch a RVA c a m t m ng các c u trúc IMAGE_THUNK_DATA [Ti n
ây c ng nói luôn, t union c c p trên ch ng qua ch là m t s nh ngh a l i c a cùng m t n i
c a b nh T union trên không ch a 2 DWORDS nh ng ch duy nh t m t có th ch a ho c
OriginalFirstThunk data hay Characteristics data mà thôi]
Thành ph n ti p theo là TimeDateStamp c t là 0 tr khi file th c thi c gi i h n khi nó ch a -1 (xem bên d i) Thành ph n ti p là ForwarderChain c s d ng cho vi c liên k t old-style và thành
ph n này s không c c p n ây
M i IMAGE_THUNK_DATA là m t DWORD union mà th c t ch có m t c a hai giá tr Trong file
trên a nó ch a s th t c a imported function ho c là m t RVA t i m t c u trúc
IMAGE_IMPORT_BY_NAME M t khi ã c n p m t c u trúc s c tr t i b i FirsThunk c
vi t è lên b ng a ch c a các hàm imported function.- vi c này tr thành Import Address Table
M i c u trúc IMAGE_IMPORT_BY_NAME c nh ngh a nh hình minh h a d i ây :
Hint Ch a ch m c(index) bên trong Export Address Table c a file DLL các hàm hi n có trong ó
Tr ng này c s d ng b i trình PE Loader vì v y nó có th tìm ki m hàm trong Export Address Table
c a DLL m t cách nhanh chóng Tên t i ó mà ch m c c dùng , và n u nó không t ng ng thì m t phép tìm ki m nh phân c th c hi n tìm ki m tên Thông th ng giá tr này không c n thi t và m t vài trình linker t tr ng này là 0
Name1 bao g m tên c a imported function Tên là m t null-terminated ASCII string Chú ý r ng kích
th c c a Name1 c nh ngh a là m t byte nh ng trên th c t nó là m t tr ng có kích th c thay
i.Do ó không có ph ng pháp nào bi u di n m t tr ng có kích th c thay i trong m t c u trúc
C u trúc mà c cung c p cho b n có th tham chi u t i nó thông qua các tên miêu t
Nh ng ph n quan tr ng nh t là các tên imported DLL và các m ng c a các c u trúc
IMAGE_THUNK_DATA M i c u trúc IMAGE_THUNK_DATA t ng ng v i m t imported
Trang 27c k t thúc b ng m t Null DWORD ó là c p phân tách c a các m ng c a các c u trúc
IMAGE_THUNK_DATA cho m i imported DLL.
Hai m ng song song , t ng ng c g i b i các tên khác nhau nh ng cái tên chung nh t là Import
Address Table ( cho m t c tr b i FirstThunk) và Import Name Table hay Import Lookup Table
(cho m t c tr b i OriginalFirstThunk)
T i sao l i có hai m ng t ng ng c a các con tr t i nh ng c u trúc IMAGE_IMPORT_BY_NAME
? Các Import Name Table c nguyên và không bao gi c ch nh s a.Các Import Address
Table c vi t l i v i nh ng a ch hàm th c s b i trình loader Trình loader l p l i thông qua m i con
tr t i các hàm và tìm ki m a ch c a hàm mà m i c u trúc tham chi u t i Trình loader sau ó s vi t
l i con tr t i IMAGE_IMPORT_BY_NAME b ng a ch c a hàm Các m ng c a nh ng RVAs trong
Import Name Tables gi nguyên không b thay i vì v y n u c n thi t tìm tên c a các hàm imported , trình PE loader có th v n tìm th y chúng
M c dù IAT c tr t i b i entry number 12 trong Data Directory , m t vài ch ng trình linkers không thi t l p danh sách th m c này và tuy nhiên trình ng d ng s ch y Trình loader ch s d ng i u này ánh d u m t cách t m th i IAT khi read-write trong lúc import resolution và có th gi i quy t các import mà không c n nó
Trang 28
Các l i g i t i các hàm c import x y ra thông qua m t con tr hàm trong IAT L y ví d , hãy t ng
t ng r ng a ch 00405030 tham chi u t i 1 hàm c a danh sác trong m ng FirstThunk mà ã c vi t
l i b i trình loader b ng a c a hàm GetMessage trong file USER32.DLL
T i sao các l i g i t i hàm c imported l i c th c hi n theo cách này? Ch ng trình biên d ch có
th không phân bi t gi a các l i g i hàm thông th ng trong cùng m t module và các hàm c imported cho ra cùng m t u ra gi ng nhau : CALL [XXXXXXXX]
T i ây thì XXXXXXXX ph i là m t a ch code th c s (không ph i là m t con tr ) c i n vào sau
ó b i ch ng trình linker Trình linker không bi t a ch c a hàm c imported và vì v y ph i cung
c p ph n thay th c a o n mã (code) The jump stub seen above
Cách t i u c s d ng là cách s d ng trình the _declspec(dllimport) modifier thông báo cho
ch ng trình biên d ch r ng hàm hi n có bên trong m t file DLL Nó s có k t qu là CALL DWORD PTR [XXXXXXXX]
Trang 29N u nh _declspec(dllimport) không c s d ng khi biên d ch m t file th c thi thì s có m t t p h p
l n c a các jump stubs cho các hàm c imported xác nh l n nhau n m âu trong o n mã l nh
i u này c bi t b i các tên khác nhau ví d nh "transfer area", "trampoline" or "jump thunk table"
Functions Exported by Ordinal Only:
Nh chúng ta ã th o lu n trong ph n v Export section, thì m t s hàm c exported thông qua s th
t Trong tr ng h p này , s không có c u trúc IMAGE_IMPORT_BY_NAME cho hàm ó trong
module c a l i g i (caller s module) Thay vào ó, IMAGE_THUNK_DATA cho hàm ó ch a s th t
c a hàm
Tr c khi file th c thi c n p, b n có th cho bi t n u m t c u trúc IMAGE_THUNK_DATA ch a
m t s th t ho c m t RVA b ng cách xem xét bit có ý ngh a quan tr ng nh t (MSB) hay bit cao.N u
c thi t l p thì 31 bits th p h n c xem nh là m t giá tr s th t N u không c set ,thì giá tr là
m t RVA t i m t IMAGE_IMPORT_BY_NAME Microsoft cung c p m t h ng s có ích cho vi c ki m
tra bit MSB c a m t DWORD, ó là IMAGE_ORDINAL_FLAG32 Nó có giá tr là 80000000h
L y ví d , n u m t hàm c exported thông qua s th t và s th t c a nó là 1234h, thì
IMAGE_THUNK_DATA cho hàm ó s là 80001234h
Bound Imports :
Khi trình Loader n p m t PE file vào trong b nh , nó ki m tra b ng import table và n p các file DLLs
c yêu c u vào không gian a ch x lý Sau ó nó d o qua m ng c tr b i FirstThunk và thay th
IMAGE_THUNK_DATA b ng nh ng a ch th c s c a các import functions Giai o n này t n khá
nhi u th i gian N u vì m t lý do ch a bi t ng i l p trình có th d oán a ch c a các hàm m t cách
chính xác, trình PE loader không ph i s a các IMAGE_THUNK_DATA m i l n PE file th c thi y nh
v y các file c t o b i Borland không th c liên k t.Chúng ta s xem xét t m quan tr ng khác c a
vi c thi u INT trong các section ti p theo
The Bound_Import_Directory
Thông tin trình loader s d ng xác nh n u a ch c liên k t là h p l c l u gi trong m t c u
trúc là IMAGE_BOUND_IMPORT_DESCRIPTOR M t bound excutable ch a m t danh sách các c u
trúc , m t cho m i DLL c imported mà c liên k t :
Trang 30
Thành ph n TimeDateStamp ph i kh p v i TimeDateStamp c a exporting DLL s header N u nh
không kh p, trình loader th a nh n r ng binary c liên k t t i là wrong DLL và s vá l i danh sách import i u này có th x y ra n u phiên b n c a exporting DLL không kh p ho c n u nó c n ph i c
s p x p l i trong b nh
Thành ph n OffsetModuleName ch a offset (không ph i là RVA) t
IMAGE_BOUND_IMPORT_DESCRIPTOR u tiên cho t i tên c a DLL trong null-terminated ASCII
Chú ý : Tên c a các hàm b n thân chúng không c bao g m trong nh ng c u trúc này khi trình loader
bi t nh ng hàm nào c liên k t t IMAGE_IMPORT_DESCRIPTOR (xem trên)
9 The Windows Loader :
Khi m t file th c thi ch y, trình windows loader s t o ra m t không gian a ch o cho process và ánh
x executalble module t a vào trong không gian a ch c a process Nó c g ng n p image t i a ch
c s c u tiên và ánh x các section vào trong b nh (memory) Trình loader s xem xét t m
section table và ánh x m i section t i a ch c tính toán b ng cách công thêm RVA c a section v i
a ch c s Các page attributes c thi t l p theo s yêu c u c i m c a section Sau khi ánh x các section vào trong b nh , trình loader th c hi n b trí các relocation n u a ch n p không b ng v i a
ch c s c u tiên trong ImageBase
B ng import table sau ó c ki m tra và b t kì file DLLs nào c yêu c u s c ánh x vào trong không gian a ch c a process.Sau ó t t c DLL modules c nh v và ánh x vào, trình loader ki m
Trang 31N u nh symbol không t n t i ( ây là tr ng h p r t hi m g p), trình loader s thông báo l i M t khi t t
c các module c yêu c u ã c n p s thi hành c chuy n t i entry point c a ng d ng
Ph n quan tr ng c a thích trong RCE ó chính là vi c loading các file DLLs và gi i quy t các
imports Process này b làm ph c t p b i r t nhi u các hàm internal (forwarded) và các routines t p trung trong file ntdll.dll mà không h c ch ng minh b ng t i li u b i Micro$oft.Nh chúng ta ã nói ph n
tr c function forwarding là 1 cách cho M$ expose m t t p Win32 API thông d ng, ph bi n và che
d u các hàm c p th p mà có th khác nhau i v i t ng phiên b n c a h i u hành Nhi u hàm kernel32 quen thu c ví d nh hàm GetProcAddress n gi n ch bao b c xung quanh các ntdll.dll exports ví d
nh LdrGetProcAddress (mà hàm này th c hi n công vi c chính)
có th th y rõ nh ng i u này b n c n cài t ch ng trình Windbg và Windows Symbol Package (
c cung c p b i M$) ho c m t ch ng trình kernel-mode debugger gi ng nh SoftIce B n ch có th xem nh ng hàm này trong Olly n u nh b n c u hình Olly s d ng M$ symbolserver, n u không thì
t t c nh ng gì b n quan sát th y ch là các pointers và các a ch b nh mà không có tên c a các hàm Tuy nhiên Olly là m t trình debugger trên user-mode và nó s ch cho các b n th y c nh ng gì ang
x y ra khi ng d ng c a b n c n p và nó s không cho phép b n quan sát th y loading process M c
dù ch c n ng c a ch ng trình Windbg còn h n ch không th so sánh v i Olly nh ng nó t ng thích t t
v i h i u hành và s cho ta th y c quá trình loading process :
Nh các b n th y có r t nhi u hàm APIs c liên k t cùng v i quá trình n p m t file th c thi, t t c t p
trung trên hàm LoadLibraryExW trong kernel32.dll mà l n l t d n n hàm n i t i LdrpLoadDll trong ntdll.dll Hàm này tr c ti p g i 6 subroutines n a là LdrpCheckForLoadedDll, LdrpMapDll,
LdrpWalkImportDescriptor, LdrpUpdateLoadCount, LdrpRunInitializeRoutines, và
LdrpClearLoadInProgress th c hi n nh ng nhi m v sau :
1 Ki m tra xem n u module ã s n sàng n p vào
2 Ánh x module và các thông tin h tr vào trong b nh
3 D o qua b ng import descriptor table c a module (find other modules this one is importing)
Trang 325 Kh i t o module
6 Xóa some sort of flag, indicating that the load has finished
M t DLL có th import các module khác mà b t u m t t ng c a th vi n thêm vào Trình loader s c n
ph i l p l i t u n cu i m i module , ki m tra xem n u nó c n c n p và sau ó ki m tra nh ng
ph thu c c a nó ó là lý do có s xu t hi n c a LdrpWalkImportDescriptor ây
LdrpWalkImportDescriptor có hai subroutines ó là : LdrpLoadImportModule và LdrpSnapIAT
u tiên nó b t u b ng hai l i g i t i RtlImageDirectoryEntryToData xác nh v trí Bound Imports Descriptor và các b ng Import Descriptor Chú ý r ng trình loader s ki m tra bound imports u tiên- m t ng d ng khi th c thi nh ng không có m t import directory có th có các bound imports thay
th
Ti p theo LdrpLoadImportModule xây d ng m t Unicode string cho m i DLL c tìm th y trong
Import Directory và sau ó giao cho LdrpCheckForLoadedDll nh n ra if they have already been loaded
Ti p n a LdrpSnapIAT routine ki m tra m i DLL c tham chi u t i trong Import Directory thay th cho 1 giá tr -1 (ie again checks for bound imports first) Sau ó nó thay i memory protection c a IAT thành PAGE_READWRITE và ti n hành ki m tra m i entry trong IAT tr c khi chuy n t i
LdrpSnapThunk subroutine
LdrpSnapThunk s d ng m t ch s c a hàm xác nh a ch c a nó và quy t nh nó có c
forward hay là không M t khác nó g i LdrpNameToOrdinal s d ng m t phép tìm ki m nh phân trên
export table xác nh ch s m t cách nhanh chóng N u hàm không c tìm th y thì nó tr v
STATUS_ENTRYPOINT_NOT_FOUND, ng c l i n u tìm th y thì nó thay th entry trong IAT b ng
entry point c a API và tr v cho LdrpSnapIAT khôi ph c l i memory protection nó ã thay i t i lúc
b t u công vi c c a nó, g i NtFlushInstructionCache b t bu c m t cache refresh trên memory
block có ch a IAT, và sau ó tr v l i cho LdrpWalkImportDescriptor
ó là m t khác bi t c bi t gi a các h i u hành Window mà trong ó Win2k nh n m nh r ng ntdll.dll
c n p gi ng nh m t bound import ho c trong import directory bình th ng tr c khi cho phép m t
Trang 33file th c thi c n p, nh ng ng c l i h i u hành Win9x hay XP s cho phép môt ng d ng không có imports nào c n p
Ph n khái quát ng n g n này ã c n gi n hóa i r t nhi u nh ng v n minh h a c làm th nào
m t l i g i t i LoadLibrary làm t ng lên m t t ng c a vi c n các subroutines n i t iwhich are deeply nested and recursive in places Trình loader ph i ki m tra m i API c imported tính toán m t a ch
th c trong b nh và ki m tra n u m t API ã c imported M i DLL c imported có th d n n các modules thêm vào và process s b l p l i h t l n này n l n khác cho t i khi t t c các ph thu c
N u nh các b n mu n tìm ki m thông tin v các hàm c imported t file DLL ("foo" from DLL
"bar",), u tiên các b n tìm RVA c a Import Directory t Data Directory, tìm a ch ó trong ph n raw section data và bây gi b n có m t m ng c a các IMAGE_IMPORT_DESCRIPTORs L y thành
viên c a m ng này mà liên quan t i bar.dll b ng cách ki m tra các strings c tr t i b i tr ng Name
Khi b n ã tìm th y IMAGE_IMPORT_DESCRIPTOR úng, follow FirstThunk c a nó và n m l y con tr t i m ng các m ng IMAGE_THUNK_DATAs, ki m tra k các RVAs và tìm ki m the function
"foo"
Quay tr l i ví d c a chúng ta trong ch ng trình Hexeditor, chúng ta s tìm v trí c a b ng import table quan sát nh ng gì chúng ta c n tìm ki m.Nh chúng ta ã nói ph n tr c, RVA c a Import
Directory c l u trong DWORD 80h bytes t PE Header mà trong ví d c a chúng ta là offset 180h và
RVA là 2D000h (xem l i ph n Data Directory) Bây gi chúng ta ph i chuy n i RVA ó sang m t raw offset nghiên c u k ph m vi chính xác c a file c a chúngta trên a Ki m tra Section Table xem
xét section nào mà a ch c a Import Directory n m trong Trong tr ng h p c a chúng ta, thì Import
Directory b t u t i n i b t u c a idata section và chúng ta bi t r ng section table l u gi các raw
offset trong PointerToRawData DWORD Trong ví d c a chúng ta thì offset là 2AC00h (xem ph n
section table) B t kì m t trình PE Editor nào c ng cho chúng ta k t qu nh bên d i ây Ví d ta dùng LordPE, ta có nh sau :
S khác bi t gi a RVA và Raw offset là 2D000h 2AC00h = 2400h Hãy chú ý t i i u này b i vì nó s
có ích cho vi c chuy n i các offsets Xem thêm ph n ph l c có thêm các thông tin v vi c chuy n
i các RVAs
T i Offset 2AC00h chúng ta có Import Directory m t m ng c a các
IMAGE_IMPORT_DESCRIPTORs m i m ng là 20 bytes và l p l i cho m i import library (DLL) cho
t i khi c k t thúc b i 20 bytes có giá tr 00h Trong ch ng trình HexEditor chúng ta quan sát th y
c nh sau t i 2AC00h :
Trang 34
M i m t nhóm 5 DWORDs bi u di n 1 IMAGE_IMPORT_DESCRIPTOR Nhóm u tiên ch cho ta
th y r ng trong file PE này các thành ph n OriginalFirstThunk, TimeDateStamp và ForwarderChain
c thi t l p là 0 Cu i cùng là chúng ta i n m t t p h p c a t t 5 DWORDs c thi t l p là 0.( trên hình c tô b ng màu ) mà ch cho chúng ta bi t ây là k t thúc c a m ng.Chúng ta có th th y chúng ta ang import các hàm t 8 DLLs
set là 0 ó là i n hình chung cho các file th c thi c t o ra b ng trình compiler &l inker c a Borland
và là i u áng ghi nh trong lí do s p c p sau ây Trong m t file th c thi b Packed thì các con tr
FirstThunk pointers s b làm m t hi u l c nh ng có th th nh tho ng c xây d ng l i b ng cách sao chép l i b n sao OriginalFirstThunks(which many simple packers do not seem to bother removing) ó
th c s là m t i u có ích c g i là First_Thunk Rebuilder by Lunar_Dust mà s th c hi n i u này Tuy nhiên, v i Borland khi ã t o file thì i u này là không th b i vì OriginalFirstThunks t t c u là
Zero và không có INT :
L i quay tr l i ví d c a chúng ta trên, tr ng Name1 field c a IMAGE_IMPORT_DESCRIPTOR
u tiên ch a RVA 00 02 D5 30h (NB reverse byte order) Chuy n i giá tr này sang m t raw offset
b ng cách tr i giá tr 2400h (nh ã nói trên) và chúng ta có là 2B130h N u chúng ta quan sát trong
PE file c a chúng ta chúng ta s th y tên c a DLL :
Trang 35
Ti p t c , tr ng FirstThunk field ch a RVA 00 02 D0 B4h mà sau khi convert chúng s có c Raw offset là 2ACB4h Hãy ghi nh i u này ây là offset t i m ng c a các c u trúc DWORD-sized
IMAGE_THUNK_DATA structures IAT i u này s khi n cho bit có ý ngh a quan tr ng nh t c a nó
c set (it will start with 8) và ph n th p h n s ch a s th t c a hàm c imported, ho c n u MSB không c set nó s ch a RVA khác t i tên c a hàm (IMAGE_IMPORT_BY_NAME)
Trong file c a chúng ta , giá tr DWORD t i 2ACB4h là 00 02 D5 3E:
ây là m t RVA khác mà khi convert sang RAW offset là 2B13E Th i i m này nó s là m t terminated ASCII string Nh chúng ta quan sát th y d i ây :
Vì v y tên c a c a API u tiên c imported t kernel32.dll là DeleteCriticalSection Có th b n ý
n 2 zero bytes tr c tên c a hàm ó là ph n t Hint element mà th ng c set là 00 00
T t c nh ng i u này có th c xác minh l i thông qua ch ng trình PE Browse Pro phân tích IAT
nh hình minh h a d i ây :
Trang 36
N unh file c loaded vào trong b nh , c dumped và ki m tra b ng ch ng trình Hex editor thì giá tr DWORD t i RVA 2D0B4h mà contained 3E D5 02 00 trên a s c overwritten b i trình loader
b ng a ch c a hàm DeleteCriticalSection trong kernel32.dll :
Allowing for reverse byte order this is 7C91188A
7XXXXXXX và cùng t i ch gi ng nhau m i khi các ch ng trình c n p Tuy nhiên chúng hay thay i n u b n cài t l i OS c a b n và khác nhau gi a máy tính này và máy tính khác :
Các a ch c ng khác nhau tùy theo t ng h i u hành, l y ví d :
Trang 37
Trình Windows Upadate c ng th nh tho ng thay i v trí c s c a các DLLs h th ng ó là lí do t i sao m t s ng i th ng chú ý n vi c dành th i gian tìm cho c i m t breakpoint n i ti ng là
point-h trên h th ng c a mình (it is prone to change unexpectedly since it is in a function inside
Chú ý r ng a ch c a idata section là 42D000 t ng ng v i RVA 2D000 mà chúng ta ã nói ph n
tr c Kích th c c làm tròn lên là 2000 v a khít v i memory page boundaries
C a s chính c a Olly là CPU s ch cho chúng ta th y nh ng a ch CODE section (from 401000 to 42AFFF) B n c ng có th ki m tra IAT trong c a s disassembly n u nó n m trong CODE section.Trong h u h t các tr ng h p nó s n m trong section riêng c a nó eg : idata nh ng b n có th xem nó trong c a s Hex-dump trong Olly b ng cách Right click vào và ch n Dump in CPU C a s name (nh n Ctrl + N) s cho chúng ta th y c các hàm c imported:
Rightclicking b t kì m t hàm nào và sau ó ch n Find References to Import s cho b n th y jump thunk stub và the instances in the code n i mà hàm ó c g i (ch có 1 trong tr ng h p c a chúng ta ):
Chú ý : trong c t Comment b n s th y r ng Olly ã xác nh là hàm DeleteCriticalSection trong
kernel32.dll là th c s c forwarded t i RtlDeleteCriticalSection trong ntdll.dll (xem ph n gi i thích
Export Fowarding)
Ti p t c Rightclicking và ch n Follow Import in Disassembler, Olly s cho chúng ta th y a ch trong DLL thích h p n i mà code c a hàm b t u Ví d : b t u t i 7C91188A trong ntdll.DLL: