75
..::[ARTeam Tutorial]::.. PORTABLE EXECUTABLE FILE FORMAT Category : Relates to cracking, unpacking, reverse engineering Level : Intermediate Test OS : XP Pro SP2 Author : Goppit Translated by : kienmanowar (REA-cRaCkErTeAm) Tools Used: Hexeditor (any will do) PEBrowse Pro http://www.smidgeonsoft.prohosting.com/download/PEBrowse.zip PeiD http://www.secretashell.com/codomain/peid/download.html LordPE http://mitglied.lycos.de/yoda2k/LordPE/LPE-DLX.ZIP (get DLX-b update also) HexToText http://www.buttuglysoftware.com/HexToTextMFC.zip OllyDbg http://home.t-online.de/home/Ollydbg/odbg110.zip ResHacker http://delphi.icm.edu.pl/ftp/tools/ResHack.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

PE Tutorials

Embed Size (px)

Citation preview

Page 1: PE Tutorials

..::[ARTeam Tutorial]::.. PORTABLE EXECUTABLE FILE FORMAT

Category :

Relates to cracking, unpacking, reverse engineering

Level :

Intermediate

Test OS :

XP Pro SP2

Author : Goppit

Translated by :

kienmanowar (REA-cRaCkErTeAm)

Tools Used:

Hexeditor (any will do)

PEBrowse Pro http://www.smidgeonsoft.prohosting.com/download/PEBrowse.zip

PeiD http://www.secretashell.com/codomain/peid/download.html

LordPE http://mitglied.lycos.de/yoda2k/LordPE/LPE-DLX.ZIP (get DLX-b update also)

HexToText http://www.buttuglysoftware.com/HexToTextMFC.zip

OllyDbg http://home.t-online.de/home/Ollydbg/odbg110.zip

ResHacker http://delphi.icm.edu.pl/ftp/tools/ResHack.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

Page 2: PE Tutorials

1

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).

Page 3: PE Tutorials

2

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 b nh .

Tuy nhiên nó không c sao chép l i m t cách chính xác bên trong b nh . Các windows loader s quy t nh ph n nào c n c ánh x lên b nh và b qua nh ng ph n khác. Ph n d li u mà không

c ánh x lên c t t i phía cu i c a file sau b t kì ph n nào mà s c ánh x lên b nh ví d Debug Information.

C ng v y v trí c a m t m c trong file trên a s luôn luôn khác bi t v i v trí c a nó khi c n p vào trong b nh b i vì s qu n lý b nh o d a trên các trang mà Windows s d ng. Khi các sections c n p vào trong b nh RAM chúng c c n kh p v i 4KB memory Pages, m i section s b t u trên

Page 4: PE Tutorials

3

mô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.

Thu t ng b nh o (virtual memory) thay th vi c cho Software truy c p tr c ti p lên b nh v t lý (physical memory), b x lý và h i u hành t o ra m t l p vô hình (invisible layer) gi a chúng. B t k l n nào m t c g ng c t o ra truy c p t i b nh , b vi x lý s tra c u m t page table bi t xem có nh ng Process mà a ch b nh v t lý ang th c s c s d ng. Nó s không ph i là m t vi c làm thi t th c có m t table entry cho m i byte c a b nh (Page table s l n h n t ng b nh v t lý), 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 :

1. Nó cho phép s t o thành c a nh ng không gian a ch ph c t p. M t không gian a ch là m t page table c cô l p ch cho phép truy c p t i b nh mà thích h p v i ch ng trình hi n t i ho c

process. Nó m b o r ng nh ng ch ng trình b cô l p , cách ly hoàn toàn v i các ch ng trình khác và m t khi x y ra l i khi n cho m t ch ng trình b crash thì nó s không th nh h ng , h y ho i t i không gian a ch c a các ch ng trình khác .

2. Nó cho phép b vi x lý áp t nh ng lu t l nào ó i v i vi c b nh c truy c p th nào.Nh ng sections c òi h i , yêu c u trong PE file b i vì nh ng khu v c khác nhau trong file c i x m t cách khác bi t b i ch ng trình qu n lý b nh khi m t module c n p. 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 ng d ng c ng có th s d ng nhi u b nh h n là không gian hi n có c a b nh v t lý b i vì h

Page 5: PE Tutorials

4

th 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ô l p mà có th c s d ng running nh là m t module.

2. The DOS Header :

T t c các file PE b t u b ng DOS Header , vùng này chi m gi 64 bytes u tiên c a file. Nó c dùng trong tr ng h p ch ng trình c a b n ch y trên n n DOS, do ó h i u hành DOS có th nh n 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 MS-DOS-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 c a Mark Zbikowsky m t trong nh ng ng i sáng t o chính c a MS-DOS), các giá tr này là d u hi u

Page 6: PE Tutorials

5

thô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 :

Page 7: PE Tutorials

6

Signature là m t DWORD ch a nh ng giá tr nh sau 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). FileHeader bao g m 20 bytes ti p theo c a PE file ,nó ch a thông tin v s b trí v t lý và nh ng c tính c a file. Ví d : s l ng các sections.

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 ng

NumberOfSections 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 :

Page 8: PE Tutorials

7

i u này có th c ki m tra l i b ng cách s d ng b t c m t công c PE nào. Ví d : Công c PEBrowsePro

Ho c s d ng m t công c khá n i ti ng là LorDPE :

Page 9: PE Tutorials

8

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 :

Page 10: PE Tutorials

9

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. N u section u tiên là t i 401000h và kích th c c a nó là 10 bytes, v y section ti p theo là t i 402000h

Page 11: PE Tutorials

10

cho 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.

Cách b trí m i th c a PE Header có th c quan sát m t cách tr c quan thông qua hình nh minh h a sau ây trong ch ng trình HexEditor. Chú ý r ng

DOS Header và ph n c a PE Header là luôn luôn cùng kích th c (and shape) khi c quan sát trong ch ng trình HexEditor. Ph n DOS Stub có th thay i theo kích th c :

Page 12: PE Tutorials

11

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 .

Ti p theo b n nh n chu t ph i trên PE Header và ch n Dump in CPU . Sau ó trong c a s Hex window , l i nh n chu t ph i m t l n n a và ch n Special --> PE Header .

Chúng ta s có c thông tin nh sau :

Page 13: PE Tutorials

12

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 :

Page 14: PE Tutorials

13

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_DESCRIPTOR array

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.

Page 15: PE Tutorials

14

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 :

Page 16: PE Tutorials

15

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 trong

tr 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.

Page 17: PE Tutorials

16

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.

Page 18: PE Tutorials

17

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)

Data Sections :

Section .bss bi u di n d li u không c kh i t o cho ng d ng , bao g m toàn b các bi n ã c khai báo là bi n t nh trong m t hàm ho c là m t module ngu n.

Section .rdata bi u di n d li u ch c ra (read only) , ví d nh nh ng chu i, các h ng, và thông tin th m c debug.

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 :

Page 19: PE Tutorials

18

ây là m t ch ng trình r t m nh ph c v cho m c ích Cracking vì nó s hi n th m t cách nhanh chóng các h p tho i bao g m c nh ng chi ti t v vi c ng kí sai c ng nh các nag screens. M t ng d ng shareware có th th ng b Cracked ch b ng vi c xóa b resource h p tho i nagscreen trong ResHacker.

Export Data Section :

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.

Debug Information Section :

Thông tin Debug c t ban u trong Section .debug . nh d ng PE File c ng h tr các file debug khác nhau (th ng c nh n bi t v i ph n m r ng là .dbg) nh là m t cách th c c a vi c t p h p thông tin debug t i m t v trí t p trung. Section debug ch a thông tin debug , nh ng nh ng th m c debug l i 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.

Page 20: PE Tutorials

19

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 c

thê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 :

Page 21: PE Tutorials

20

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 :

Page 22: PE Tutorials

21

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 address-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).

Page 23: PE Tutorials

22

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

Page 24: PE Tutorials

23

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 file

Dll 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 .

Ng i l p trình viên có th ch rõ s th t b t u trong m t .def file. L y ví d , các b ng trong hình minh h a trên có th b t u t i 200. mà i phó tr c s c n thi t cho 200 ph n t r ng u tiên trong m ng , thành ph n nBase l u gi giá tr b t u và trình loader tr các s th t t

nó thu c ch m c th t trong EAT.

Export Forwarding :

ôi khi các hàm có v c Exported t m t file Dll c thù, nh ng trên th c t các hàm này l i n m trong m t file Dll hoàn toàn khác. i u này c g i là Export Forwarding . L y ví d , trong h i u 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

file DLL và tên hàm mà nó c Forwarded. Trong ví d tr c nó s là NTDLL.RtlAllocHeap.

Page 25: PE Tutorials

24

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.

8. The Import Section :

Import Section (th ng c bi t d i tên .idata) bao g m thông tin v t t c các hàm c imported b i file th c thi t các file Dlls. Thông tin này c l u tr trong m t vài c u trúc d li u. Ph n quan trong 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 :

Page 26: PE Tutorials

25

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.

Thành ph n Name1 ch a m t con tr (RVA) t i chu i tên ACSII c a file DLL.

Thành ph n cu i cùng ó là FirstThunk, nó c ng ch a RVA c a m t m ng các c u trúc IMAGE_THUNK_DATA

m t b n sao c a m ng u tiên. N u nh hàm c miêu t là m t bound import (xem bên d i) thì FirstThunk ch a

a ch th c s c a hàm thay vì m t RVA t i m t IMAGE_THUNK_DATA. Nh ng c u trúc này c nh ngh a nh sau :

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 function t DLL. Các m ng c tr t i b i OriginalFirstThunk và FirstThunk ch y song song và

Page 27: PE Tutorials

26

c 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.

s d ng nó theo m t cách khác, có nhi u các c u trúc IMAGE_IMPORT_BY_NAME . B n t o ra hai m ng , sau ó i n vào hai m ng này các RVAs c a các c u trúc IMAGE_IMPORT_BY_NAME, vì v y c hai m ng này cùng ch a các giá tr gi ng nh nhau. Bây gi b n có th gán RVA c a m ng u tiên cho OriginalFirstThunk và RVA c a m ng th hai cho FirstThunk.

S l ng các ph n t trong các m ng OriginalFirstThunk và FirstThunk ph thu c vào s l ng c a các hàm c imported t file DLL. L y ví d , n u PE file import 10 hàm t file dll là user32.dll, thì thành ph n Name1 trong c u trúc IMAGE_IMPORT_DESCRIPTOR s ch a RVA c a chu i user32.dll và s là 10 IMAGE_THUNK_DATA trong m i m ng.

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ó.

ó là cách th c mà trình Windows loader có th vi t l i IAT khi nó hi n có trong m t section ch c (readonly section). T i th i i m n p h th ng thi t l p m t cách t m th i các thu c tính c a các trang ch a d li u import c ho c ghi.

Khi import table c kh i t o các trang c thi t l p tr l i v i các thu c tính c b o v nguyên b n c a chúng.

Page 28: PE Tutorials

27

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.

Cách th c hi u qu g i hàm GetMessage gi ng nh d i ây :

0040100C CALL DWORD PTR [00405030 ]

Còn cách th c kém hi u qu là nh sau :

0040100C CALL [00402200] ....... .......

00402200 JMP DWORD PTR [00405030]

L y ví d , ph ng pháp th hai c ng thu c m t k t qu t ng t nh ng s d ng 5 byte thêm vào c a code và m t th i gian lâu h n th c thì b i vì extra jump.

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].

Page 29: PE Tutorials

28

N 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

a ch chính xác là ã có r i. S liên k t là k t qu c a ý t ng này.

Có m t ti n ích c t tên là bind.exe i kèm v i các trình biên d ch c a Microsoft , ki m tra IAT (m ng FirstThunk) c a m t PE file và thay th các IMAGE_THUNK_DATA Dword b ng a ch c a các import functions. Khi file c n p, trình PE loader ph i ki m tra các a ch ó có h p l không. N u phiên b n c a file DLL không kh p v i m t file trong PE file ho c n u các file DLLs c n ph i c xây d ng l i, trình PE loader bi t r ng các a ch c liên k t là h t hi u l c và nó d o qua b ng Import Name Table (Original FirstThunk array) tính toán các a ch m i.

B i v y m c dù INT là không c n thi t cho m t file th c thi n p, n u nó không hi n di n file th c thi không th c liên k t. Trong m t th i gian dài trình linker c a Borland là TLINK không t o m t INT vì 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 :

Page 30: PE Tutorials

29

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.

Thành ph n NumberOfModuleForwarderRefs ch a s l ng các c u trúc IMAGE_BOUND_FORWARDER_REF mà tr c ti p theo c u trúc này. C u trúc này c nh ngh a nh sau :

Nh b n có th nhìn th y chúng gi ng y h t nh c u trúc bên trên ngo i tr thành ph n cu i cùng c dành riêng trong b t kì tình hu ng nào.Lý do có hai c u trúc t ng t nhau là khi liên k t ng c l i m t hàm mà c forwared t i m t file DLL khác, tính ch t h p l c a forwared DLL ó ph i c ki m tra c ng t i th i gian n p.

IMAGE_BOUND_FORWARDER_REF ch a thông tin chi ti t v các forwarded DLLs.

L y ví d nh hàm HeapAlloc trong kernel32.dll c forwarded t hàm RtlAllocateHeap trong file ntldll.dll. N u chúng ta t o ra m t ng d ng mà import hàm HeapAlloc và c s d ng bind.exe trong

ng d ng, ó s là m t IMAGE_BOUND_IMPORT_DESCRIPTOR cho kernel32.dll c theo b i m t IMAGE_BOUND_FORWARDER_REF cho ntldll.dll.

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 :

Ph n vi t này tuy là không c n thi t nh ng nó dành cho nh ng ai mu n i sâu nghiên c u thêm v s ho t ng c a h i u hành (OS).

What The Loader Does

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 tra m i DLL s export section và sau ó IAT c ch nh s a tr t i a ch hàm c imported th c s .

Page 31: PE Tutorials

30

N 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) . 4. Update the module's load count as well as any others brought in by this DLL

Page 32: PE Tutorials

31

5. 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

Page 33: PE Tutorials

32

file 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 i

which 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

u ã c ki m tra.

10. Navigating Imports :

Navigating Imports on Disk

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úng

ta 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 :

Page 34: PE Tutorials

33

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

Chú ý quan tr ng :

Các tr ng OriginalFirstThunk fields trong ví d c a chúng ta t t c u c 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 :

Page 35: PE Tutorials

34

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 null-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 :

Page 36: PE Tutorials

35

N u

nh 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.

Chú ý quan tr ng : các hàm trong các DLLs h th ng luôn luôn h ng v b t u t i a ch 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 :

Page 37: PE Tutorials

36

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 user32.dll.)

Navigating Imports in Memory

Load file c a chúng ta vào trong Olly và m t l n n a hãy quan sát c a s Memory Map :

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:

Page 38: PE Tutorials

37

N u chúng ta quan sát t i l i g i t i hàm DeleteCriticalSection t i 00401B12 chúng ta s th y nh sau:

Nh các b n th y trên hình minh h a có m t l nh

"CALL 00401314" nh ng Olly s thay th b ng tên c a hàm cho chúng ta. 401314 là a ch c a the jmp stub pointing to the IAT. Chú ý r ng nó là ph n c a m t b ng jmp thunk table ã c nói n ph n tr c :

T i ây chúng ta l i quan sát th y có m t l nh nh y

"JMP DWORD PTR DS:[0042D0B4]" ,nh ng l i m t l n n a Olly ã thay th b ng symbolic name cho chúng ta. a ch 0042D0B4 ch a c u trúc Image_Thunk_Data structure trong IAT mà ã c overwritten b i trình loader b ng a ch th c s c a hàm trong kernel32.DLL: 7C91188A. ó là nh ng gì mà chúng ta ã tìm th y thông qua vi c rightclicking and selecting Follow Import in Disassembler và c ng t dumped file ph n trên.

Page 39: PE Tutorials

38

11. Adding Code to a PE File :

Vi c thêm code vào m t PE file là m t i u r t c n thi t không nh ng có th crack m t protection scheme mà còn có th c ng d ng trong vi c thêm các ch c n ng vào trong PE file. Có 3 ph ng pháp chính có th add code vào trong m t file th c thì là :

1. Thêm vào m t section hi n t i

khi có ch cho o n code c a b n.

2. M r ng section hi n t i khi không ch .

3. Thêm m t section m i hoàn toàn.

Adding to an existing section

Chúng ta c n m t section trong file mà c ánh x v i các quy n th c thi trong b nh vì v y n gi n nh t chúng ta hãy th c hành v i CODE section.

Sau ó chúng ta c n m t vùng ch a toàn byte 00 (00 byte padding) trong section này. Vùng này c g i v i m t tên chung là caves có th tìm c m t cave phù h p v i nh ng gì chúng ta mong i , chúng ta s quan sát t i CODE section . Chi ti t thông

qua ch ng trình LorPE :

Trong hình minh h a trên chúng ta quan sát th y VirtualSize nh h n SizeOfRawData.Virtual size bi u di n s l ng code th c s . Còn kích th c c a raw data xác nh s l ng c a không gian c s d ng cho file trên a c ng c a b n. Chú ý r ng virtual size trong tr ng h p này là th p h n v i virtual size trên a c ng. ó là b i vì các trình compiler th ng làm tròn kích th c lên s p x p m t section trên m t vài ranh gi i. Trong ch ng trình Hexeditor quan sát t i phía cu i c a CODE section (phía tr c c a DATA section b t u t i 2A400h) , chúng ta có c nh sau :

Page 40: PE Tutorials

39

Không gian thêm này là hoàn toàn không c s d ng và không c ánh x vào trong b nh . Chúng ta c n ph i b o m ch c ch n r ng nh ng câu l nh mà chúng ta t vào không gian này s c n p vào trong b nh . Chúng ta th c hi n i u ó b ng cách b ng cách ch nh s a thu c tính size (Size attribute). Ngay bây gi chúng ta th y là kích th c o c a Section này là 29E88, ó là b i vì t t c các trình compiler u c n.Còn i v i chúng ta chúng ta ph i c n t ng lên m t chút n a, vì v y trong LordPE ta thay i virtual size c a CODE section lên thành 29FFF , ó là kích th c l n nh t mà chúng ta có th s d ng (Toàn b Raw size ch có 2A000). th c hi n c i u này , chúng ta chu t ph i t i dòng CODE và ch n edit header, th c hi n thay i v i giá tr trên và save l i .

Sau khi th c hi n xong chúng ta ã có m t không gian thích h p l u gi o n patch code c a chúng ta.

i u duy nh t mà chúng ta ã thay i là VirtualSize DWORD cho CODE section trong b ng Section Table. Chúng ta c ng có th th c hi n c công vi c này b ng tay thông qua ch ng trình HexEditor.

minh h a thêm n a cho công vi c này chúng ta s ti n hành thêm vào ch ng trình ví d c a chúng ta m t ch ng trình ASM nh th c hi n vi c chi m l y i u khi n c a entry point và sau ó ch tr v s th c thi cho OriginalEntryPoint. T t c công vi c này c làm thông qua Ollydbg.

u tiên chúng ta ý trong LordPE thì EntryPoint là 0002ADB4 và ImageBase là 400000. Khi chúng ta load ch ng trình vào trong Olly thì EP s là 0042ADB4. Chúng ta s thêm m t s dòng sau và sau ó thay i entry point t i dòng u tiên c a o n code :

MOV EAX,0042ADB4 ; Load in EAX the Original Entry Point (OEP) JMP EAX ; Jump to OEP

Chúng ta s các l nh trên t i a ch 0002A300h nh chúng ta ã quan sát trên ch ng trình Hexeditor. convert RAW offset này sang m t RVA s d ng cho Olly ta s s d ng công th c sau ây (Xem

thêm ph n ph l c)

:

RVA = raw offset - raw offset of section +virtual offset of section +ImageBase = 2A300h - 400h +1000h + 400000h = 42AF00h.

Page 41: PE Tutorials

40

Sau ó ta load ch ng trình vào trong Olly và nh y t i target section c a chúng ta (nh n Ctrl + G và gõ vào giá tr ã tính toán c trên là 42AF00h). Sau khi t i v trí này, ta nh n Space, gõ vào dòng u tiên c a o n code trên sau ó nh n assemble. Ti p theo làm t ng t v i dòng code th hai. Ta có c t ng t nh hình minh h a d i ây :

Ti p theo nh n chu t ph i, ch n tùy ch n Copy to Executable and All modifications.Ti p theo ch n Cpy all, m t c a s m i s xu t hi n. Trên c a s m i này ti p t c nh n chu t ph i và ch n Save File v v..Bây gi chúng ta quay tr l i v i LordPE (hay ch ng trình HexEditor) và thay i EntryPoint thành 0002AF00 (ImageBase Subtracted), ch n Save và nh n OK. Chúng ta Run ch ng trình ki m tra và reopen nó trong Olly xem New EntryPoint c a chúng ta.

Trong ch ng trình HexEditor chúng ta s quan sát th y nh sau, chú ý o n c Highlight :

M c dù ây ch là m t o n tiny patch , nh ng chúng ta hoàn toàn có không gian cho 386 bytes c a New code.

Enlarging an Existing Section

N u nh không có không gian t i phía cu i c a section .text thì chúng ta c n ph i m r ng nó. i u này a ra m t s v n nh sau :

1. N u section c followed b i các section khác thì b n s c n ph i d ch chuy n các following sections lên t o không gian.

2. Có r t nhi u các references khác nhau bên trong các file headers mà s c n ph i c i u ch nh n u b n thay i kích th c c a file.

Page 42: PE Tutorials

41

3. Các References gi a các sections khác nhau ( ví d references t i data values t code section) s c n ph i c i u ch nh. V th c t là h u nh không th th c hi n c n u nh th u vi c re-compiling and re-linking file g c.

H u h t các v n nêu trên u có th tránh c b ng cách n i thêm và section cu i cùng trong file exe. Nó ch ng có liên quan gì t i section ó n u nh chung ta có th thay i khi n nó phù h p v i yêu c u c a chúng ta b ng cách thay i tr ng Characteristic trong Section Table b ng tay ho c b ng LordPE.

u tiên chúng ta tìm n section cu i cùng và thay i nó sao cho nó thành readable and executable.

Nh chúng ta ã nói trên code section ch là ý t ng cho m t patch b i vì các characteristics flags c a nó là 60000020 , i u ó có ngh a là o n mà có th th c thi c và có th c c (executable and readable) (Xin xem thêm ph n ph l c). Tuy nhiên n u chúng ta t o n mã và d li u vào trong section này thì chúng ta s nh n c m t page fault vì nó không ph i là writeable. thay i i u này chúng ta s c n ph i thêm flag 800000000 mà s cho ta m t giá tr m i là E0000020 cho code, executable, readable and writable.

T ng t nh v y n u section cu i cùng là .reloc thì flags th ng s là 42000040 cho initialized data, discardable and read-only. có th s d ng c section này chúng ta ph i thêm code, executable and writable và chúng ta ph i tr discardable m b o ch c ch n r ng trình loader s ánh x section này vào trong b nh .

i u này s cho chúng ta m t giá tr m i là E0000060.

Các công vi c trên có th th c hi n thành công b ng tay b ng cách thêm flags và ch nh s a l i tr ng Characteristics c a Section header thông qua ch ng trình HexEditor ho c LordPE. Trong ví d c a chúng ta thì section cu i cùng là Resources :

Page 43: PE Tutorials

42

i u này s cho chúng ta m t giá tr Characteristics cu i cùng là F0000060. Nh hình minh h a trên chúng ta quan sát th y RawSize (on disk) c a section này là 8E00h bytes nh ng t t c chúng d ng nh ang c s d ng (the VirtualSize c ng gi ng h t). Bây gi chúng ta ch nh l i chúng và c ng 100h

bytes vào c hai m r ng section , giá tr m i chúng ta có c là 8F00h. Có m t vài giá tr quan tr ng khác c ng c n c thay i. Tr ng SizeOfImage trong PE Header c n ph i c t ng lên b ng cách c ng thêm vào giá tr gi ng nh chúng ta ã thêm m r ng cho section ó là 100h. Do ó giá tr SizeOfImage s thay i 0003CE00h thành 0003CF00h.

Có 2 tr ng khác n a mà không c th hi n trong LordPE b i vì chúng ít quan tr ng ó là : SizeOfCode và SizeOfInitialisedData trong Optional Header. ng d ng s v n th c thi mà không c n

c ch nh s a nh ng có l b n nên thay i l i chúng cho tr n v n.Chúng ta s ph i thay i l i chúng b ng tay. C hai u là DWORDs t i các offset 1C và 20 t i m b t u c a PE header. (xem thêm ph n ph l c).

Page 44: PE Tutorials

43

Các giá tr 0002A000 và 0000DE00 t ng ng v i các v trí xác nh nh các b n ã th y trên hình minh h a.Khi chúng ta c ng thêm 100h vào thì các giá tr này s là 0002A100 và 0000DF00.Sau ó chúng ta s

o ng c th t c a cac giá tr trên thành 00 A1 02 00 và 00 00 DF 00. Cu i cùng copy và paste 100h of 00 bytes (16 hàng trong trình Hexeditor) lên phía cu i c a Section và l u l i thay i. Ch y file ki m tra các l i.

Adding a New Section

Trong m t vài tình hu ng b n có th c n ph i t o ra m t b n sao c a m t section ang t n t i phá v các self-checking procedures (Ví d nh SafeDisk) ho c t o ra m t section m i l u code khi các thông tin thu c quy n s h u riêng c b sung thêm vào cu i c a file (as in Delphi compiled apps).

Công vi c u tiên c n làm là ph i tìm n tr ng NumberOfSections trong PE header và t ng tr ng này lên 1.Nh ã nói trong nh ng ph n tr c h u h t m i s thay i có th c th c hi n b ng ch ng trình LordPE ho c b ng tay thông qua ch ng trình HexEditor.Bây gi trong ch ng trình HexEditor c a b n hãy copy và paste 100h of 00 bytes (16 rows) lên ph n cu i c a file và ánh d u offset c a dòng m i

u tiên. Trong tr ng h p c a chúng ta ó là 00038200h. ó s là n i b t u section m i c a chúng ta và s i t i tr ng RawOffset field c a Section Header.Khi chúng ta ây thì ch c ch n ó là th i i m t t t ng SizeOfImage lên 100h nh chúng ta ã làm tr c.

Ti p theo chúng ta s tìm t i các section headers b t u t i offset F8 t PE header.

It is not necessary for these to be terminated by a header full of zeros. S l ng các headers c a ra b i NumberOfSections và ó th ng là m t vài không gian t i phía cu i tr c khi b n thân các sections b t u.( aligned to the FileAlignment value). Tìm n section cu i cùng và thêm m t giá tr m i sau nó :

Ph n ti p theo mà chúng ta ph i làm là quy t nh xem các thành ph n Virtual Offset/Virtual Size/Raw Offset and Raw Size nào c n có. có th quy t nh c i u này chúng ta xem xét các giá tr sau :

Virtual offset of formerly last section (.rsrc): 34000h Virtual size of formerly last section (.rsrc): 8E00h Raw offset of formerly last section (.rsrc): 2F400h Raw size of formerly last section (.rsrc): 8E00h Section Alignment: 1000h File Alignment: 200h

Page 45: PE Tutorials

44

RVA và raw offset c a section m i c a chúng ta ph i c c n ch nh v i boundaries trên.RAW Offset c a section là 00038200h nh chúng ta ã nói trên (which luckily fits with FileAlignment). có c Virtual Offset c a section c a chúng ta thì chúng ta ph i tính toán giá tr này : VirtualAddress of .rsrc + VirtualSize of .rsrc = 3CE00h. Vì SectionAlignment c a chúng ta là 1000h chúng ta ph i làm tròn giá tr này lên g n gi ng nh 1000 t c là 3D000h. Vì v y hãy i n vào header c a section c a chúng ta :

The first 8 bytes will be Name1 (max. 8 chars e.g. "NEW" will be 4E 45 57 00 00 00 00 00 (byte order not reversed)

The next DWORD is VirtualSize = 100h (with reverse byte order = 00 01 00 00) The next DWORD is VirtualAddress = 3D000h (with reverse byte order = 00 D0 03 00) The next DWORD is SizeOfRawData = 100h (with reverse byte order = 00 01 00 00) The next DWORD is PointerToRawData = 38200h (with reverse byte order = 00 82 03 00) The next 12 bytes can be left null The final DWORD is Characteristics = E0000060 (for code, executable, read and write as discussed above)

Trong trình HexEditor chúng ta s th y nh sau :

L u l i thay i , chúng s run ch ng trình và ki m tra trong LordPE :

Page 46: PE Tutorials

45

12. Adding Imports to an Executable :

Ph ng pháp này th ng c s d ng nhi u nh t trong tr ng h p Patching m t App khi mà chúng ta không có các hàm API mà chúng ta c n.

thêm section m i, thì thông tin t i thi u nh t c yêu c u b i trình loader t o ra m t IAT h p l là :

1. M i Dll ph i c khai báo v i m t IMAGE_IMPORT_DESCRIPTOR (IID), nh k t thúc Import Directory b ng m t null-filled.

2. M i IID c n ít nh t 2 tr ng là Name1 và FirstThunk, ph n còn l i có th c set là 0(setting OriginalFirstThunk = FirstThunk i.e. duplicating the RVAs also works).

3. M i entry c a FirstThunk ph i là m t RVA t i m t Image_Thunk_Data (the IAT) mà l n l t ch a m t further RVA t i API name.Tên ph i là m t chu i null terminated ASCII c a dài có th thay i và

c i tr c b i 2 bytes (hint) mà có th c thi t l p là 0.

Page 47: PE Tutorials

46

4. N u các IIDs ã c thêm thì tr ng isize c a Import Table trong Data Directory có th c n ph i thay

i. Các IAT entries trong Data Directory không c n ph i c ch nh s a.

Vi c vi t import data m i trong m t ch ng trình HexEditor và sau ó dán vào trong target c a b n có th s t n r t nhi u th i gian.Có các công c có s n có th th c hi n c m t cách t ng quá trình này (Ví d : SnippetCreator, IIDKing, Cavewriter) nh ng vi c tìm hi u cách th c hi n công vi c này b ng tay nh th nào v n là t t h n c . Nhi m v chính là n i thêm m t IID m i lên ph n cu i c a b ng Import Table b n s c n có 20 bytes cho m i DLL c s d ng, ng quên 20 bytes dành cho null-terminator. Trong h u h t t t c các tr ng h p s không có không gian nào t i phía cu i c a Import Table hi n hành vì v y chúng ta s t o m t b n sao và xây d ng l i nó m t n i nào ó.

Step 1 - create space for new a new IID

Công vi c này liên quan n các b c sau ây :

1. D ch chuy n t t c các IIDs t i m t v trí mà t i ó có không gian.V trí này có th b t kì âu; phía cu i c a section .idata hi n th i ho c m t section m i hoàn toàn.

2. C p nh t RVA c a Import Directory m i trong Data Directory c a PE Header.

3. N u c n thi t, làm tròn kích th c c a section n i mà b n ã t Import Table m i vì v y m i th u c ánh x vào trong b nh (ví d : VirtualSize of the .idata section rounded up 1000h).

4. Ch y nó và n u nh nó làm vi c thì chuy n t i b c 2. N u nó không ki m tra các injected descriptors c ánh x vào trong b nh và RVA c a Import Directory là chính xác ..

IMPORTANT NOTE: Các IIDs FirstThunk và OriginalFirstThunk ch a các RVAs- RELATIVE ADDRESSES

có ngh a là các b n có th c t và dán Import Directory (IIDs) b t kì âu b n mu n trong PE file (taking into account the destination has to mapped into memory) và thay i RVA (và kích th c n u c n thi t) c a Import Directory trong Data Directory s khi n cho ng d ng ho t ng m t cách hoàn h o.

Quay tr l i ng d ng c a chúng ta trong trình Hexeditor, IID u tiên và null terminator c tô b ng ng bao màu .Nh b n nhìn th y trong hình v d i ây không có không gian tr ng nào sau null

IID:

Tuy nhiên có m t s l ng không gian l n t i ph n cu i c a section .idata tr c khi section .rdata b t u. Chúng ta s copy và paste các IIDs hi n th i c a ra phía trên t i offset 2C500h t i v trí m i

này :

Page 48: PE Tutorials

47

convert m t offset m i thành RVA (xem thêm ph n ph l c) :

VA = RawOffset - RawOffsetOfSection + VirtualOffsetOfSection = 2C500 - 2AC00 + 2D000 = 2E900h

V y thay i a ch o c a import table trong Data Directory t 2D000 thành 2E900. Bây gi ch nh s a l i header c a section .idata và thay i VirtualSize b ng v i RawSize vì v y trình loader s ánh x toàn b section vào. Ch y th ng d ng c a chúng ta test.

Step 2 - Add the new DLL and function details

Công vi c này bao g m m t s b c sau :

1. Thêm null-terminated ASCII strings các tên c a DLL c a b n và hàm vào không gian còn tr ng trong section .idata. Tên hàm s th c s là m t c u trúc Image_Import_By_Name c preceded b i m t null DWORD. (the hint field).

2. Tính toán các RVAs c a các string trên.

3. Thêm RVA c a tên DLL vào tr ng Name1 c a IID m i c a b n.

4. Tìm DWORD sized space khác n a và t vào nó RVA c a hint/function name. Nó s tr thành Image_Thunk_Data ho c IAT c a DLL m i c a chúng ta.

5. Tính toán RVA c a Image_Thunk_Data DWORD trên và thêm nó vào tr ng FirstThunk c a IID m i c a b n.

6. Ch y ng d ng test API m i c a b n ã s n sàng c g i

i n vào IDD m i c a chúng ta , chúng ta ít nh t ph i có các tr ng là Name1 và FirstThunk (các tr ng khác có th nulled). Nh chúng ta ã bi t, tr ng Name1 ch a thông tin RVA tên c a DLL trong null-terminated ASCII. Tr ng FirstThunk ch a RVA c a m t c u trúc Image_Thunk_Data mà l n l t ch a RVA khác n a c a tên hàm trong null-terminated ASCII. Tên tuy nhiên c i tr c b i 2 bytes (Hint) mà c thi t l p là zero.

L y m t ví d , chúng ta mu n s d ng hàm LZCopy mà copy toàn b m t file ngu n t i m t file ích. N u file ngu n c a chúng ta c nén b ng trình ng d ng Microsoft File Compression Utility

Page 49: PE Tutorials

48

(COMPRESS.EXE), thì hàm này t o ra m t file ích ã c gi i nén. N u nh file ngu n không b nén , thì hàm này s nhân ôi file g c lên.

Hàm mà chúng ta nói trên n m trong file dll là lz32.dll mà hi n th i không c s d ng b i ch ng trình ng d ng c a chúng ta. Vì v y u tiên chúng ta c n ph i thêm strings cho các tên là lz32.dll và LZCopy . Trong trình Hexeditor chúng ta cu n lên trên t ch b ng import table m i c a chúng ta v

phía cu i c a d li u ã t n t i tr c ó và thêm tên DLL sau ó là tên hàm lên ph n cu i này . Chú ý, các bytes null sau m i string và null DWORD tr c tên hàm :

Chúng ta c n ph i tình l i các RVA c a chúng :

RVA = RawOffset - RawOffsetOfSection + VirtualOffsetOfSection + ImageBase RVA of DLL name = 2C420 - 2AC00 + 2D000 = 2E820h (20 E8 02 00 in reverse) RVA of function name = 2C430 - 2AC00 + 2D000 = 2E830h (30 E8 02 00 in reverse)

Giá tr u tiên có th n m trong tr ng Name1 c a IDD m i c a chúng ta nh ng giá tr th hai thì ph i n m trong m t c u trúc Image_Thunk_Data structure, v i RVA c a chúng, chúng ta sau ó có th t vào trong tr ng FirstThunk (and OriginalFirstThunk) c a IDD m i c a chúng ta.Chúng ta s t c u trúc Image_Thunk_Data structure bên d i tên hàm t i offset 2C440 và tính toán RVA mà chúng ta s

t vào FirstThunk.

RVA of Image_Thunk_Data = 2C440 - 2AC00 + 2D000 = 2E840 (40 E8 02 00 in reverse)

N u chúng ta i n d li u trong trình HexEditor chúng ta s th y nh sau :

Page 50: PE Tutorials

49

Cu i cùng chúng ta l u l i nh ng gì chúng ta ã th c hi n , ch y th ng d ng và load nó vào ch ng trình PEBrowse :

Page 51: PE Tutorials

50

có th g i c hàm m i c a chúng ta , chúng ta c n ph i s d ng o n code sau :

CALL DWORD PTR [XXXXXXXX] where XXXXXXXX = RVA of Image_Thunk_Data + ImageBase.

Trong ví d c a chúng ta trên i v i hàm LZCopy, XXXXXXXX = 2E840 + 400000 = 42E840 vì v y chúng ta s vi t là :

CALL DWORD PTR [0042E840]

Chú ý cu i cùng : Dù là n u chúng ta ã thêm m t hàm c s d ng b i m t DLL mà s n sàng c dùng trong kernel32.dll , chúng ta s v n c n ph i t o ra m t IDD m i cho nó cho phép chúng ta có th t o m t IAT m i t i m t v trí thu n l i nh trên.

Ph n ti p theo , ây ch là m t ph n c thêm vào trong section này. S có m t cách t ng hoàn toàn th c hi n các công vi c nh ã nói trên :

Page 52: PE Tutorials

51

Chú ý , Ch ng trình SnippetCreator thêm các jump-thunks stubs c a các imports m i vào trong code c a b n trong khi v i các ch ng trình khác b n hoàn toàn ph i th c hi n i u này b ng tay .

Page 53: PE Tutorials

52

13. Introduction to Packers :

Trong ph n này chúng ta s m x s tác ng c a m t

ch ng trình Packer n gi n i v i ng d ng c a chúng ta và c p t i 2 ph ng pháp chính c a vi c Patching m t file th c thi ã b Packed b ng cách Unpacking ho c inline-patching. Chúng ta s s d ng Packer UPX 1.25 b i vì ây th c s là m t ch ng trình nén file th c thi và không s d ng b t kì m t m t c ch b o v cao c p nào.Tác gi c a ch ng trình này là Marcus & Laszlo.

u tiên chúng ta dùng PeiD Scan file c a chúng ta (file ban u ch a b Packed) :

Ti p theo chúng ta s pack ng d ng c a chúng ta b ng ch ng trình UPX. ây là ch ng trính s d ng giao di n command line do ó chúng ta ph i m nó trong DOS , sau ó chúng ta gõ nh sau : "upx basecalc.exe":

Page 54: PE Tutorials

53

Sau ó chúng ta hãy ý r ng kích th c ch ng trình c a chúng ta ã gi m xu ng t 225kb xu ng còn 91kb và trong PeiD chúng ta quan sát th y nh sau :

S d ng ch ng trình PEBrowse Pro chúng ta quan sát th y trình Packer s thêm vào app c a chúng ta 3 sections là UPX0, UPX1 and .rsrc. Resource section bây gi ch a import directory nh ng cho m i DLL thì ch có duy nh t m t ho c 2 hàm c imported

các hàm khác ã bi n m t :

Page 55: PE Tutorials

54

Chú ý r ng section .rsrc ã c gi l i tên g c c a nó m c dù th m chí các ph n khác ã b thay i. Thú v n a là this dates back to a bug trong hàm LoadTypeLibEx trong oleaut32.dll in Win95 mà rsrc ã s d ng tìm ki m và n p resource section. i u này gây ra m t l i n u section b i tên.

(This created an error if the section was renamed. Although this bug has been fixed it seems most packers do not rename the rsrc section for compatibility reasons)

B ng vi c m ng d ng c a chúng ta trong LordPE và nh n vào Compare button chúng ta có th m b n g c c a ng d ng và quan sát s thay i c a các headers :

Page 56: PE Tutorials

55

Khi chúng ta m ng d ng trong Olly , chúng ta s nh n c m t Message Box thông báo r ng file th c thi c a chúng ta ã b packed. Ch vi c nh n Ok và chúng ta s t i EntryPoint :

Page 57: PE Tutorials

56

Trình Packer UPX ã nén ng d ng c a chúng ta và ã thêm the code b ng m t stub có ch a gi i thu t

decompress.EntryPoint c a ng d ng ã b thay i b t u o n stub và sau ó khi stub th c hi n xong công vi c c a nó , h ng th c thi c a ch ng trình s nh y v original entrypoint (OEP) b t u ch ng trình bây gi ã c unpacked c a chúng ta.

Lý do c n b n i phó v i nó là cho ch ng trình Sub decompress ng d ng c a chúng ta vào trong b nh và sau ó dump vùng nh này vào m t file có c b n sao c a ch ng trình ã c unpacked. Tuy nhiên ng d ng s không th c thi theo úng cách c a nó ó là b i vì file c dumped s có các sections riêng c a nó c aligned to memory page boundaries ch không ph i file alignment values, do ó entrypoint s v n tr t i decompression stub và Import directory rõ ràng là sai và s c n ph i ch nh s a l i.

Chú ý r ng trong Olly entrypoint c a chúng ta n m t i câu l nh u tiên là PUSHAD. Câu l nh PUSHAD này là vi t t t c a PUSH ALL DOUBLE , th c hi n vi c l u t t c n i dung c a các thanh ghi 32 bit vào trong Stack , b t u t EAX cho n EDI.Theo ó Stub s th c hi n công vi c c a nó và sau ó k t thúc b ng m t câu l nh POPAD tr c l nh nh y t i OEP. POPAD sao chép l i n i dung c a các

thanh ghi t Stack. i u này có ngh a là stub s ph i ph c h i l i m i th và exited without trace tr c khi th c s Run ng d ng. Vì v y ph ng pháp này là ý t ng cho nhi u packer thông d ng khác ví d nh ASPack.

T th i i m c a câu l nh PUSHAD u tiên, nh ng n i dung c a Stack t i level ó ph i c hoàn toàn không c ng t i cho t i khi g p c câu l nh POPAD.N u nh chúng ta t m t Hardware breakpoint lên 4 bytes u tiên c a stack t i th i i m th c hi n l nh PUSHAD thì Olly s break t i th i i m khi mà 4 bytes này c truy c p t i câu l nh POPAD và chúng ta s t i úng câu l nh nh y t i

OEP c a chúng ta.

u tiên chúng ph i th c hi n câu l nh PUSHAD b ng cách nh n F7 m t l n. Ti p theo chúng ta s t m t BP c a chúng ta.Thanh ghi ESP (Stack Pointer) luôn luôn tr t i c a nh Stack do ó Right click lên ESP và ch n Follow in Dump Chúng ta s có c nh sau :

Ti p theo Highlight DWORD u tiên c a Stack trong c a s Dump , chu t ph i và ch n BP>HardWare on Access>DWORD:

Page 58: PE Tutorials

57

Ti p theo nh n F9 n Run ch ng trình và Olly s Break. Chúng ta quan sát s th y có l nh JMP t i OEP. OEP mà chúng ta th y ây có ImageBase là 400000h c c ng thêm vào , do ó chúng ta mu n tìm th y Real OEP thì chúng ta ph i tr i giá tr ImageBase trên. Cho nên ta có OEP là : 0002ADB4h.

N u nh b n mu n gian l n ây có m t cách nhanh chóng mà luôn luôn có hi u qu v i UPX. n gi n ch là b n cu n chu t t i phía cu i c a o n code trong màn hình CPU trong Olly và phía tr c t t c ch b t u c a zero padding thì b n s th y c câu l nh POPAD nh trên.

NOTE: Các Packer khác mà c ng s d ng c ch PUSHAD/POPAD có th nh y t i OEP b ng cách s d ng m t l nh PUSH y giá tr c a OEP lên trên nh c a Stack c followed b i câu câu l nh RET. CPU s ngh là ây là m t return t m t hàm call và theo thói quen thì d a ch tr v c t lên

nh c a Stack.

B c ti p theo chúng ta nh n F7 th c hi n l nh JMP và chúng ta s t i OEP. T i ây chúng ta s s d ng Plugin c a Olly là OllyDump Dump file này. Chu t ph i t i OEP sau ó ch n OllyDump, chúng ta s có c màn hình nh sau , th c hi n nh hình minh h a :

Page 59: PE Tutorials

58

Note that OllyDump has already worked out the base address and size of image (which you could see by looking in the memory map window) and has offered to correct the entrypoint for us (although we could do this manually in the hexeditor). Nh n Dump và save file v i tên nào ó mà b n mu n (eg as basecalc_dmp.exe). Gi nguyên tr ng thái c a Olly sau khi ã th c hi n Dump.

Th t không may m n khi chúng ta quan sát file c dump thì th y nó b m t icon và n u nh chúng ta c tình Run file thì chúng ta s nh n c thông báo nh sau :

Chúng ta nh n c thông báo trên là b i vì h u qu c a v n alignment mà tôi ã c p trên kích th c c a file c ng ã t ng. Chúng ta m app c a chúng ta trong LordPE và quan sát t i các Sections. Các giá tr Raw offset và Raw Size ã sai. Chúng ta s ph i t o các giá tr Raw b ng v i giá tr các Virtual cho m i Section cho ng d ng c a chúng ta cho nó h at ng. Nh n chu t ph i t i UPX0 section và ch n edit header:

Page 60: PE Tutorials

59

Bây gi chúng ta s làm cho RawOffset b ng VirtualAddress và RawSize b ng VirtualSize. L p l i thao tác này cho m i Sections sau ó nh n Save và Exit (this is what the "fix raw size" checkbox in OllyDump does automatically). Bây gi chúng ta quan sát th y app ã có icon nh ng khi ch y ng d ng c a chúng ta , ta s nh n c m t l i khác là : "The application failed to initialize properly". Có l i này là b i vì chúng ta ch a fix imports.

Vi c Fix imports này chúng ta hoàn toàn có th th c hi n c b ng tay . Tuy nhiên s t n r t nhi u th i gian và công s c n u nh chúng ta có nhi u hàm c imported v..v. Do ó ây chúng ta s s d ng ch ng trình ImpREC 1.6F by MackT th c hi n m t cách t ng.

Ch ng trình ImpREC c n ph i attach t i m t process ang ch y và c ng c n packed file tìm imports. Kh i ng ImpREC và th c hi n theo các b c sau :

1. Ch n Basecalc.exe trong danh sách Attach (it should still be running in Olly). 2. Ti p theo nh p OEP c a chúng ta là 2ADB4 vào trong textbox OEP. 3. Nh n nút IAT AutoSearch và nh n OK trên messagebox. 4. Nh n nút Get Imports . 5. Nh n Show Invalid

trong tr ng h p c a chúng ta không có invalid nào. 6. Nh n Fix Dump và ch n file mà chúng ta ã dump là basecalc_dmp.exe. 7. Okie ..Thoát kh i ImpREC.

Page 61: PE Tutorials

60

Ch ng trình ImpREC s l u file ã fix v i tên nh sau : basecalc_dmp_.exe. Chúng ta ch y th file này ki m tra. N u nh chúng ta phân tích file này chúng ta s th y kích th c c a nó ã t ng lên và có

thêm m t section n a có tên là mackt

ó là n i mà ImpREC a import data m i :

Vì UPX ch là m t ch ng trình nén, nó n gi n ch là l y existing import data và l u nó l i trong resource section mà không encrypting or damaging it. ó là lý do t i sao ImpREC có th tìm c t t c các vaild imports mà không c n ph i resorting to tracing or rebuilding nó ch l y import directory t file th c thi ã b packed trong b nh và transfer nó t i section m i trong file th c thi ã c unpacked.

Gi chúng ta hãy Scan file ã c unpacked trong PEID xem :

Page 62: PE Tutorials

61

Trên ây ch là ph n minh h a các b c c n thi t cho vi c th c hi n unpack m t file th c thi ã b packed b ng m t packer n gi n. Tuy nhiên có r t nhi u các packers cao c p mà các packer này thêm r t nhi u các c ch b o v khác nhau ví d nh : antidebugging và anti-tampering tricks, encryption of code và IAT, stolen bytes, API redirection, etc mà trong ph m vi c a bài vi t này tôi không th c p h t c, mong các b n b quá cho .

Trong m t s tr ng h p n u nh c n thi t chúng ta ph i Patch m t file ã b packed , i u này giúp chúng ta có th tránh c vi c không c n ph i unpacking file thì có m t k thu t c s d ng ó là inline patching . Nó liên quan n vi c patching code t i th i i m runtime trong b nh sau khi quá

trình decompression stub ã hoàn thành xong công vi c c a mình và cu i cùng nh y t i OEP th c thi ng d ng. Nói cách khác ,chúng ta i cho n khi ng d ng c a chúng ta ã c unpacked trong b

nh , thì nh y t i patching code mà chúng ta ã injected, cu i cùng sau ó nh y tr v OEP.

minh h a cho k thu t này chúng ta s inject code vào trong file th c thi ã b packed c a chúng ta b n ra m t thông báo và cho chúng ta bi t khi ng d ng ã c unpacked trong b nh . Sau ó khi chúng ta nh n OK thì s nh y t i OEP và ng d ng s th c thi m t cách bình th ng.

Nhi m v u tiên là chúng ta ph i tìm ki m m t n i cho o n code c a chúng ta vì v y hãy m packed app vào trong trình Hexeditor và tìm ki m m t kho ng không gian phù h p còn g i là suitable "cave". Kho ng không gian tr ng này n m t i phía cu i c a section là t t h n c b i vì nó ít c s d ng b i packer và có th m r ng c b ng cách n i r ng section n u th y c n thi t (Xin xem l i ph n

adding code to a PE file.) B n có th quan sát th y hi u qu c a Packer UPX

kho ng không gian chúng ta c n là r t khó tuy nhiên v n có m t kho ng nh (small cave) t n t i ây.Bây gi chúng ta thêm "Unpacked..." và "Now back to OEP" trong ASCII column c a ch ng trình HexEditor. T ng t nh hình minh h a d i ây :

Page 63: PE Tutorials

62

i u này s ánh d u d u v t c a chúng ta patch trong Olly mà không c n ph i lo l ng v vi c tính

toán các VAs. L u l i nh ng thay i và m ng d ng c a chúng ta trong Olly. Chu t ph i t i c a s Hex window và ch n search for binary string. Bây gi nh p vào là "Unpacked" và ý t i VA c a 2 strings. Trong c a s CPU Window, nh n chu t ph i và ch n Goto expression. Nh p a ch c a string u tiên và b n s quan sát 2 strings trong hexadecimal form. Olly ã không analysed nó m t cách úng n do ó nó hi n th không ra thành m t o n code không có ý ngh a gì. Highlight o n code (the next free row underneath) và nh n Space Bar assemble the following instructions :

PUSH 0 PUSH 440C30 [address of first string] PUSH 440C40 [address of second string] PUSH 0 CALL MessageBoxA JMP 42ADB4

Make a note of the address of our first PUSH instruction - 440C4E. o n code c a chúng ta s trông nh sau trong Olly :

Ti p theo chu t ph i và ch n

copy to executable, selection. Trong c a s m i xu t hi n , rightclick và ch n save file etc. If we check in the hexeditor we see our code has been added:

Page 64: PE Tutorials

63

Cu i cùng chúng ta c n ph i thay i l nh JMP t i phía cu i c a UPX stub nh y t i o n code c a chúng ta. Tìm l nh nh y này nh ã c p ph n trên, doubleclick vào JMP instruction assemble và thay i address thành 440C4E. L u l i thay i m t l n n a và run app c a chúng ta test :

Clicking OK resumes BaseCalc.!!!!!!!!!!!!!

14. References & Further Reading :

The Portable Executable Format -- Micheal J. O'Leary The Portable Executable File Format from Top to Bottom -- Randy Kath Peering Inside the PE: A Tour of the Win32 Portable Executable File Format -- Matt Pietrek An In-Depth Look into the Win32 Portable Executable File Format (2 parts)-- Matt Pietrek Windows 95 Programming Secrets -- Matt Pietrek Linkers and Loaders -- John R Levine Secrets of Reverse Engineering -- Eldad Eilam PE.TXT -- Bernd Luevelsmeyer Converting virtual offsets to raw offsets and vice versa -- Rheingold PE Tutorial -- Iczelion The Portable Executable File Format -- KGL PE Notes, Understanding Imports -- yAtEs Win32 Programmer's Reference What Goes On Inside Windows 2000: Solving the Mysteries of the Loader -- Russ Osterlund Tool Interface Standard (TIS) Formats Specification for Windows Adding Imports by Hand -- Eduardo Labir (Havok), CBJ Enhancing functionality of programs by adding extra code -- c0v3rt+ Working Manually with Import Tables -- Ricardo Narvaja All tutorials concerning manual unpacking (especially those from ARTeam, with special reference to the Beginner Olly series by Shub and Gabri3l.

Page 65: PE Tutorials

64

15. Complete PE Offset Reference :

The DOS Header :

OFFSET SIZE NAME EXPLANATION

00 WORD e_magic Magic DOS signature MZ (4Dh 5Ah)

02 WORD e_cblp Bytes on last page of file

04 WORD e_cp Pages in file

06 WORD e_crlc Relocations

08 WORD e_cparhdr Size of header in paragraphs

0A WORD e_minalloc Minimum extra paragraphs needed

0C WORD e_maxalloc Maximum extra paragraphs needed

0E WORD e_ss Initial (relative) SS value

10 WORD e_sp Initial SP value

12 WORD e_csum Checksum

14 WORD e_ip Initial IP value

16 WORD e_cs Initial (relative) CS value

18 WORD e_lfarlc File address of relocation table

1A WORD e_ovno Overlay number

1C WORD e_res[4] Reserved words

24 WORD e_oemid OEM identifier (for e_oeminfo)

26 WORD e_oeminfo OEM information; e_oemid specific

28 WORD e_res2[10] Reserved words

3C DWORD

e_lfanew Offset to start of PE header

The PE Header :

00 DWORD Signature PE Signature PE.. (50h 45h 00h 00h)

04 WORD Machine 014Ch = Intel 386, 014Dh = Intel 486, 014Eh = Intel 586, 0200h = Intel 64-bit, 0162h=MIPS

06 WORD NumberOfSections Number Of Sections

08 DWORD TimeDateStamp Date & time image was created by the linker

Page 66: PE Tutorials

65

0C DWORD PointerToSymbolTable Zero or offset of COFF symbol table in older files

10 DWORD NumberOfSymbols Number of symbols in COFF symbol table

14 WORD SizeOfOptionalHeader Size of optional header in bytes (224 in 32bit exe)

16 WORD Characteristics see below

18 **********

START OF OPTIONAL HEADER

**************************************

18 WORD Magic 010Bh=32-bit executable image 020Bh=64-bit executable image 0107h=ROM image

1A BYTE MajorLinkerVersion Major version number of the linker

1B BYTE MinorLinkerVersion Minor version number of the linker

1C DWORD SizeOfCode size of code section or sum if multiple code sections

20 DWORD SizeOfInitializedData as above

24 DWORD SizeOfUninitializedData as above

28 DWORD AddressOfEntryPoint Start of code execution, optional for DLLs, zero when none present

2C DWORD BaseOfCode RVA of first byte of code when loaded into RAM

30 DWORD BaseOfData RVA of first byte of data when loaded into RAM

34 DWORD ImageBase Preferred load address

38 DWORD SectionAlignment Alignment of sections when loaded in RAM

3C DWORD FileAlignment Alignment of sections in file on disk

40 WORD MajorOperatingSystemVersion Major version no. of required operating system

42 WORD MinorOperatingSystemVersion Minor version no. of required operating system

44 WORD MajorImageVersion Major version number of the image

46 WORD MinorImageVersion Minor version number of the image

48 WORD MajorSubsystemVersion Major version number of the subsystem

4A WORD MinorSubsystemVersion Minor version number of the subsystem

4C DWORD Reserved1

Page 67: PE Tutorials

66

50 DWORD SizeOfImage

Amount of memory allocated by loader for image. Must be a multiple of SectionAlignment

54 DWORD SizeOfHeaders Offset of first section, multiple of FileAlignment

58 DWORD CheckSum Image checksum (only required for kernel-mode drivers and some system DLLs).

5C WORD Subsystem 0002h=Windows GUI, 0003h=console

5E WORD DllCharacteristics

0001h=per-process library initialization 0002h=per-process library termination 0003h=per-thread library initialization 0004h=per-thread library termination

60 DWORD SizeOfStackReserve Number of bytes reserved for the stack

64 DWORD SizeOfStackCommit Number of bytes actually used for the stack

68 DWORD SizeOfHeapReserve Number of bytes to reserve for the local heap

6C DWORD SizeOfHeapCommit Number of bytes actually used for local heap

70 DWORD LoaderFlags This member is obsolete.

74 DWORD NumberOfRvaAndSizes Number of directory entries.

78 **********

START OF DATA DIRECTORY **************************************

78 DWORD IMAGE_DATA_DIRECTORY0 RVA of Export Directory

7C DWORD size of Export Directory

80 DWORD IMAGE_DATA_DIRECTORY1 RVA of Import Directory (array of IIDs)

84 DWORD size of Import Directory (array of IIDs)

88 DWORD IMAGE_DATA_DIRECTORY2 RVA of Resource Directory

8C DWORD size of Resource Directory

90 DWORD IMAGE_DATA_DIRECTORY3 RVA of Exception Directory

94 DWORD size of Exception Directory

98 DWORD IMAGE_DATA_DIRECTORY4 Raw Offset of Security Directory

9C DWORD size of Security Directory

A0 DWORD IMAGE_DATA_DIRECTORY5 RVA of Base Relocation Directory

Page 68: PE Tutorials

67

A4 DWORD size of Base Relocation Directory

A8 DWORD IMAGE_DATA_DIRECTORY6 RVA of Debug Directory

AC DWORD size of Debug Directory

B0 DWORD IMAGE_DATA_DIRECTORY7 RVA of Copyright Note

B4 DWORD size of Copyright Note

B8 DWORD IMAGE_DATA_DIRECTORY8 RVA to be used as Global Pointer (IA-64 only)

BC DWORD Not used

C0 DWORD IMAGE_DATA_DIRECTORY9 RVA of Thread Local Storage Directory

C4 DWORD size of Thread Local Storage Directory

C8 DWORD IMAGE_DATA_DIRECTORY10 RVA of Load Configuration Directory

CC DWORD size of Load Configuration Directory

D0 DWORD IMAGE_DATA_DIRECTORY11 RVA of Bound Import Directory

D4 DWORD size of Bound Import Directory

D8 DWORD IMAGE_DATA_DIRECTORY12 RVA of first Import Address Table

DC DWORD total size of all Import Address Tables

E0 DWORD IMAGE_DATA_DIRECTORY13 RVA of Delay Import Directory

E4 DWORD size of Delay Import Directory

E8 DWORD IMAGE_DATA_DIRECTORY14 RVA of COM Header (top level info & metadata...

EC DWORD size of COM Header ...in .NET executables)

F0 DWORD ZERO (Reserved) Reserved

F4 DWORD ZERO (Reserved) Reserved

F8 **********

START OF SECTION TABLE *******Offsets shown from here********

00 8 Bytes Name1 Name of first section header

08 DWORD misc (VirtualSize) Actual size of data in section

Page 69: PE Tutorials

68

0C DWORD virtual address RVA where section begins in memory

10 DWORD SizeOfRawData Size of data on disk (multiple of FileAlignment)

14 DWORD pointerToRawData Raw offset of section on disk

18 DWORD pointerToRelocations Start of relocation entries for section, zero if none

1C DWORD PointerToLinenumbers Start of line-no. entries for section, zero if none

20 WORD NumberOfRelocations This value is zero for executable images.

22 WORD NumberOfLineNumbers Number of line-number entries for section.

24 DWORD Characteristics see end of page below

00 8 Bytes Name1 Name of second section header

**********

Repeats for rest of sections **************************************

The Export Table :

OFFSET

SIZE NAME EXPLANATION

00 DWORD

Characteristics Set to zero (currently none defined)

04 DWORD

TimeDateStamp often set to zero

08 WORD MajorVersion user-defined version number, otherwise zero

0A WORD MinorVersion as above

0C DWORD

Name RVA of DLL name in null-terminated ASCII

10 DWORD

Base First valid exported ordinal, normally=1

14 DWORD

NumberOfFunctions Number of entries in EAT

18 DWORD

NumberOfNames Number of entries in ENT

1C DWORD

AddressOfFunctions RVA of EAT (export address table)

20 DWORD

AddressOfNames RVA of ENT (export name table)

24 DWORD

AddressOfNameOrdinals

RVA of EOT (export ordinal table)

The Import Table :

OFFSET SIZE NAME EXPLANATION

00 DWORD

OriginalFirstThunk RVA to Image_Thunk_Data

04 DWORD

TimeDateStamp zero unless bound against imported DLL

08 DWORD

ForwarderChain pointer to 1st redirected function (or 0)

0C DWORD

Name1 RVA to name in null-terminated ASCII

10 DWORD

FirstThunk RVA to Image_Thunk_Data

Page 70: PE Tutorials

69

Image Characteristics Flags :

FLAG EXPLANATION

0001 Relocation info stripped from file

0002 File is executable (no unresolved external references)

0004 Line numbers stripped from file

0008 Local symbols stripped from file

0010 Lets OS aggressively trim working set

0020 App can handle >2Gb addresses

0080 Low bytes of machine word are reversed

0100 requires 32-bit WORD machine

0200 Debugging info stripped from file into .DBG file

0400 If image is on removable media, copy and run from swap file

0800 If image is on a network, copy and run from swap file

1000 System file

2000 File is a DLL

4000 File should only be run on a single-processor machine

8000 High bytes of machine word are reversed

Section Characteristics Flags :

FLAG EXPLANATION

00000008 Section should not be padded to next boundary

00000020 Section contains code

00000040 Section contains initialised data (which will become initialised with real values before the file is launched)

00000080 Section contains uninitialised data (which will be initialised as 00 byte values before launch)

00000200 Section contains comments for the linker

00000800 Section contents will not become part of image

00001000 Section contents comdat (Common Block Data)

00008000 Section contents cannot be accessed relative to GP

00100000 to 00800000 Boundary alignment settings

01000000 Section contains extended relocations

02000000 Section can be discarded (e.g. .reloc)

04000000 Section is not cacheable

08000000 Section is pageable

10000000 Section is shareable

20000000 Section is executable

40000000 Section is readable

Page 71: PE Tutorials

70

80000000 Section is writable

16. Relative Virtual Addressing Explained :

Trong m t file th c thi hay m t file DLL, thì RVA luôn luôn là a ch c a m t item khi c n p vào trong b nh , v i base address (ImageBase) c a imaging file c tr i : RVA = VA ImageBase do dó VA = RVA + ImageBase.

It's exactly the same thing as file offset but it's relative to a point in virtual address space, not the beginning of the PE file. Ví d :N u m t PE file n p t i a ch 400000h trong virtual address (VA) space và ch ng trình b t u th c thi t i virtual address 401000h, chúng ta có th nói r ng ch ng trình b t u th c thi t i RVA 1000h. An VA is relative to the starting VA of the module. The RVA of an item will almost always differ from its position within the file on disk - the offset. This is a pitfall for newcomers to PE programming. Most of the addresses in the PE file are RVAs and are meaningful only when the PE file is loaded into memory by the PE loader

Thu t ng "Virtual Address" c s d ng

b i vì Windows t o ra m t không gian a ch o riêng bi t cho m i process, không l thu c vào physical memory. Cho h u h t t t c các m c ích , m t virtual address c xem xét ch là m t address. Nh nói trên, m t virtual address là không th d oán tr c

c nh m t RVA, b i vì trình loader không th load the image at its preferred base address.

T i sao PE file format l i s d ng RVA?

ó là làm gi m b t quá trình n p c a trình loader. ó là b i vì n u

m t module có th c relocated b t kì v trí nào trong không gian a ch o , nó s gây tr ng i cho trình loader fix m i hardcoded address trong module. Nh ng ng c l i , n u t t c relocatable items trong file use RVA, there is no need for the loader to fix anything: nó ch n gi n relocates toàn b moduel t i

m t new starting VA.

Converting virtual offsets to raw offsets and vice versa (from Rheingold)

Chuy n i các raw offsets (the one in a file you see in a HexEditor) thành virtual offsets (the one you see in a debugger) là c c k h u ích n u nh b n làm vi c v i PE Header. Chính vì lý do này b n c n ph i bi t m t vài giá tr t PE Header. B n c n ph i bi t ImageBase, the name of the section in which your offset lies. D i ây b n s xem m t ví d c a m t PE Header t i m b t u c a file (where it is actually a MZ header until offset 80h) cho t i ph n cu i nh ngh a các sections (offset 23Fh). Ví d này

c minh h a b ng ch ng trình notepad.exe.

Page 72: PE Tutorials

71

Ví d 1

- Converting raw offset 7800h to a virtual offset:

ImageBase (DWORD value 34h bytes after the PE header begins, in our case B4h) là 40000h. The Section Table starts F8h bytes after the PE header starts, in our case 178h. It is this part:

The colored values tell us the following values :

Page 73: PE Tutorials

72

The Virtual Size và các giá tr c ánh màu da cam trong output c a trình Hexeditor trên là không quan tr ng i v i quá trình chuy n i

nh ng s có nh ng ch c n ng khác(see Section Table page).

Chúng ta mu n convert raw offset 7800h. i u này d ng nh là rõ ràng b i

offset này n m trong

.rsrc section b i vì .rsrc b t u t i 7000h (Raw Offset) và 6000h bytes long (Raw Size). Offset 7800h is located 800h bytes sau ch b t u c a section trong file. Vì t t c các sections ã c copy vào trong memory just like they are in the file, this address will be found 800h bytes after the section starts in memory (7000h; Virtual Offset). The offset we search is at 7800h. This is absolutely not common that the raw offset equals the virtual offset (without ImageBase). In this case it is only because the sections start at the same offset in memory and in the file.

Công th c chung là :

RVA = RawOffset_YouHave - RawOffsetOfSection + VirtualOffsetOfSection + ImageBase

(ImageBase = DWORD value 34h bytes after the PE header begins)

The conversion from a virtual offset to a raw offset just goes the other way round. The general formula is:

Raw Offset = RVA_YouHave - ImageBase - VirtualOffsetOfSection + RawOffsetOfSection

For 40A000 that is: 40A000-400000-7000+7000 = A000

There are also automated tools to perform the above conversions. Pressing the "FLC" button on the PE

Trình Editor c a LordPE s cho phép chúng

ta convert an RVA to an offset:

Ch ng trình Offset Calculator c ng cho phép m t conversion one-way from RVA to Raw Offset.

Page 74: PE Tutorials

73

Ch ng trình RVA Calculator cho phép onversion both ways:

..::[The End]::..

03/08/2005

--++--==[ Greatz Thanks To ]==--++-- - Thank to my family, Computer_Angel, Moonbaby , Zombie_Deathman, Littleboy, Benina, QHQCrker, the_Lighthouse, Hoadongnoi, Nini ... all REA s members, HacNho,RongChauA,Deux, tlandn, dqtln , ARTEAM (especially Goppit) .... all my friend, and YOU.

--++--==[ Special Thanks To ]==--++-- - coruso_trac, patmsvn, trm_tr v..v.. and all brothers in VSEC

Page 75: PE Tutorials

74

>>>> If you have any suggestions, comments or corrections email me: kienbigmummy[at]gmail.com