Professional Documents
Culture Documents
PE Tutorials PDF
PE Tutorials PDF
Tools Used:
PeiD http://www.secretashell.com/codomain/peid/download.html
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
Snippet
http://win32assembly.online.fr/files/sc.zip
Creator
First_Thunk
http://www.angelfire.com/nt/teklord/FirstThunk.zip
Rebuilder
IIDKing http://www.reteam.org/tools/tf23.zip
Cavewriter http://sandsprite.com/CodeStuff/cavewriter.zip
L im 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.
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 ?
1
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.
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
2
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.
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 cn 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
3
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 .
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
4
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).
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)
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 :
5
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.
6
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
7
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 :
8
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)
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
9
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).
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.
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 :
10
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 .
11
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.
12
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.
13
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.
14
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.
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 cn pt 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.
15
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.
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.
16
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.
Data Sections :
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 :
17
â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.
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.
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.
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.
18
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.
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 :
19
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)
20
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.
21
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 ak 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 ó.
22
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.
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.
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.
24
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]
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 .
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).
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ó.
26
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.
27
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".
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.
The Bound_Import_Directory
28
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 .
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).
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 .
29
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).
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 :
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.
31
file th c thi c n p, nh ng ng cl ih i u hành Win9x hay XP s cho phép môt ng d ng không có
imports nào cn p
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.
32
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
33
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).
â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 :
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 :
34
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 :
35
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.)
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 :
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 ):
36
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:
37
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à :
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 :
38
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 :
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.
39
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.
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.
40
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.
41
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.
42
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.
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 :
43
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)
44
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à :
45
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 ó.
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.
46
convert m t offset m i thành RVA (xem thêm ph n ph l c) :
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.
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).
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.
47
(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.
48
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 :
49
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 :
50
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 .
51
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) :
52
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 :
53
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)
54
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 :
55
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.
56
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.
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 :
58
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.
59
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 :
60
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 ph t c,
mong các b n b quá cho .
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.
61
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 :
62
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 :
63
15. Complete PE Offset Reference :
The DOS Header :
The PE Header :
08 DWORD TimeDateStamp Date & time image was created by the linker
64
0C DWORD PointerToSymbolTable Zero or offset of COFF symbol table in older files
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
4C DWORD Reserved1
65
Amount of memory allocated by loader for image.
50 DWORD SizeOfImage
Must be a multiple of SectionAlignment
66
A4 DWORD size of Base Relocation Directory
E8 DWORD IMAGE_DATA_DIRECTORY14 RVA of COM Header (top level info & metadata...
67
0C DWORD virtual address RVA where section begins in memory
68
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
FLAG EXPLANATION
00000008 Section should not be padded to next boundary
00000020 Section contains code
Section contains initialised data (which will become
00000040
initialised with real values before the file is launched)
Section contains uninitialised data (which will be initialised
00000080
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
69
80000000 Section is writable
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
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.
70
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:
71
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à :
The conversion from a virtual offset to a raw offset just goes the other way round. The general formula is:
There are also automated tools to perform the above conversions. Pressing the "FLC" button on the PE
Ch ng trình Offset Calculator c ng cho phép m t conversion one-way from RVA to Raw Offset.
72
Ch ng trình RVA Calculator cho phép onversion both ways:
..::[The End]::..
03/08/2005
73
>>>> If you have any suggestions, comments or corrections email me: kienbigmummy[at]gmail.com
74