UNPACKING EXECUTABLE
[Link]
Salah satu cara agar suatu program tidak dapat dianalisa dengan mudah yaitu dengan melakukan
packing terhadap executable.
PE File
Suatu file executable mempunyai struktur standar, dimana dengan mempelajari struktur ini seseorang
dapat memodifikasi suatu executable.
Bagian teratas dari suatu PE File (executable) adalah MZ DOS Header. Bagian ini diawali dengan string
“MZ”. Pada bagian ini juga terdapat pengecekan jika program berjalan di dalam mode DOS.
Bagian selanjutnya yaitu PE Header. Bagian ini diawali dengan string “PE”. Pada bagian ini terdapat
informasi mengenai program seperti Machine Type, Date/Time Stamp, OEP dan lain-lain. OEP atau
Original EntryPoint merupakan lokasi dimana kode mulai dieksekusi.
Setelah PE Header terdapat bagian Section Table yang berisi informasi-informasi untuk setiap sections
pada program. Informasi ini dikemas dengan menggunakan tabel. Setiap tabel memiliki nama, hak akses
dan ukuran. Proses pengalokasian memory untuk setiap section akan berdasarkan informasi pada table
ini.
Bagian terakhir dari PE File yaitu Sections. Section terdiri dari bagian-bagian yang berisi informasi
ataupun data. Pada sections inilah kode program dapat tersimpan.
Gambar 1. Bagian-bagian PE File.
Import Address Table
Import Address Table (IAT) merupakan suatu tabel yang berisikan informasi lokasi di memory mengenai
fungsi apa saja yang akan digunakan oleh suatu program. Misalkan pada suatu program terdapat kode
untuk menghapus file, maka umumnya fungsi API yang dipanggil adalah DeleteFile yang terdapat pada
file [Link]. Fungsi-fungsi API pada IAT ini pun sering dijadikan acuan Antivirus untuk menentukan
suatu program tergolong malware atau tidak.
Ketika suatu progam di-compile dan IAT pun terbentuk, compiler tidak mengetahu lokasi pada memory
suatu file DLL. Lokasi pada memory ini bersifat dinamis berdasarkan sistem operasi ataupun services
pack, sehingga setelah program di-compile, IAT hanya berisikan fungsi API yang akan digunakan dan file
DLL yang akan digunakan, sedangkan alamat fungsi hanya berisi pointer kosong .
Saat program dijalankan, Windows akan mencari IAT melalui PE Header dan mengisi lokasi memory dari
setiap fungsi API yang terdapat pada IAT.
Gambar 2. Informasi Pada IAT
PE Packer
Salah satu cara yang digunakan malware agar tidak dengan mudah dianalisa yaitu dengan menggunakan
program berjenis PE Packer. Sebagai contoh yaitu Brontok yang menggunakan MEW , KSpoold dan
Grogotix yang menggunakan UPX atau PendekarBlank yang menggunakan PECompact. Ada masih banyak
lagi malware yang menggunakan packer agar mempunyai ukuran file yang kecil dan tidak mudah
dianalisa oleh penganalisa malware.
Program di dalam program, itulah perumpamaan executable yang telah di-pack. Ketika program
dijalankan maka “program yang di luar” akan menjalankan “program yang di dalam”. Secara garis besar
program yang akan di-pack akan di-compress dan ketika program dijalankan, “program yang di luar”
akan meng-decompress “program yang di dalam” ke memory.
Berikut skenario yang sukses saat program yang telah di-pack dijalankan :
- Windows mengecek validitas MZ DOS Header
- Windows mengumpukan informasi pada PE Header yang berisi Machine Type, jumlah Sections,
EntryPoint, ImageBase dll.
- Windows membaca Section Table dan mengalokasikan memory untuk melakukan mapping
image dari executable ke memory.
- Windows mengisi IAT dengan pointer/alamat fungsi di memory.
- Kode pada EntryPoint aktif dan proses unpacking berlangsung untuk men-decompess image dari
program yang di-pack.
- IAT pada image diperbaiki oleh program secara manual .
- Stack Register pada program akan dikosongkan agar tidak berpengaruh ke image.
- Program memanggil kode di EntryPoint image pada image.
- Image atau program yang di-pack tereksekusi.
Gambar 3. Tampilan PEiD
Untuk mendeteksi suatu executable telah di-pack atau tidak, Anda bisa menggunakan program seperti
PEiD. Untuk mendeteksi executable yang telah di-pack juga dapat dilakukan melalui analisa heuristic
secara manual. Berikut analisa yang dapat digunakan untuk menentukan suatu file di-pack :
- Hanya terdapat sedikit fungsi pada IAT, misalnya LoadLibraryA dan GetProcAddress.
- Jumlah section sedikit dimana ada satu section yang berukuran besar.
- Nama section yang tidak umum.
- Tidak terdapat resource umum pada program seperti string table dan dialogs.
Unpacking
Tujuan dari unpacking yaitu untuk mengembalikan executable ke kondisi awal yaitu kondisi sebelum di-
pack. Jika Anda membuka executable yang telah di-pack menggunakan OllyDBG maka kode yang terlihat
merupakan kode dari stub/loader. Dengan mengembalikan executable ke kondisi awal, seseorang dapat
melakukan penganalisaan secara langsung terhadap executable tersebut. Sebagai contoh, seorang
penganalisa malware dapat langsung melihat string atau men-decompile suatu executable.
Untuk melakukan unpacking pada executable, langkah yang yang dilakukan yaitu :
- Mencari lompatan Original EntryPoint alias OEP jump. OEP jump akan menuju ke EntryPoint dari
program yaitu lokasi awal kode pada program saat dijalankan. EntryPoint pada program ini yaitu
program yang telah di-pack alias image yang di-decompress ke memory.
- Setelah menemukan OEP, dikarenakan image dari program ada di memory, maka yang perlu
dilakukan yaitu melakukan dumping dari memory ke disk.
- Mengubah EntryPoint pada image yang di-dump.
- Memperbaiki IAT pada image yang di-dump
Demo Unpacking
Program packer yang akan digunakan yaitu UPX versi terbaru yaitu UPX 3.07w. Buatlah program
sederhana menggunakan VB6 dengan nama Lazy_UnpackMe.exe. Mari mengintip program tersebut
menggunakan PEid. Informasi yang ditampilkan pada PEid yaitu “Microsoft Visual Basic 5.0 / 6.0” .
Buka UPX melalui CMD, ketikan sintak berikut untuk meng-compress :
UPX -9 C:\Lazy_UnpackMe.exe
Gambar 4. Menjalankan UPX 3.07w
Gambar 5. Membuka Lazy_UnpackMe.exe yang telah di-pack dengan PEid
Bandingkan ukuran nama Lazy_UnpackMe.exe sebelum dan sesudah di-pack. Ukuran nama
Lazy_UnpackMe.exe setelah di-pack akan lebih kecil dibandingkan Lazy_UnpackMe.exe yang masih
orisinil. Buka kembali Lazy_UnpackMe.exe yang telah di-pack menggunakan PEid. Kali ini keterangan
yang diberikan yaitu “UPX 0.89.6 - 1.02 / 1.05 - 2.90 -> Markus & Laszlo”. Untuk meng-unpack executable
yang telah di-pack menggunakan UPX dapat dilakukan secara mudah. Hal ini karena UPX menyediakan
fitur untuk mend-decompress yaitu dengan pemakaian parameter “-d”. Baiklah, “UPX –d” merupakana
cara otomatis, bagaimana melakukan unpacking secara manual?
Persiapan pertama yang diperlukan yaitu OllYDBG atau program debugger yang Anda senangi. Buka
Lazy_UnpackMe.exe menggunakan OllyDBG. Anda akan dibawa ke tampilan yang berisi :
00405570 > $ 60 PUSHAD
00405571 . BE 00504000 MOV ESI,Lazy_Unp.00405000
00405576 . 8DBE 00C0FFFF LEA EDI,DWORD PTR DS:[ESI+FFFFC000]
0040557C . 57 PUSH EDI
0040557D . 83CD FF OR EBP,FFFFFFFF
00405580 . EB 10 JMP SHORT Lazy_Unp.00405592
Instruksi pertama yang ditemukan adalah POPAD. POPAD merupakan instruksi untuk me-reset stack
register agar menjadi NULL. Berdasarkan skenario pada tulisan sebelumnya, setelah mengosongkan stack
register maka OEP akan mulai dipanggil.
Pencet F8 atau Step Over agar instruksi bergerak ke baris selanjutnya yaitu :
00405571 . BE 00504000 MOV ESI,Lazy_Unp.00405000
Pada jendela Registers (FPU), pada register ESP perrtama, klik kanan pada alamat tersebut dan pilih
menu Follow in Dump. Pada gambar 6 dapat dilihat alamat yaitu 0012FF6C.
Gambar 6. Follow in Dump
Gambar 7. Memasang hardware breakpoint
Pada jendela bagian kiri bawah, blok empat bytes pertama kemudian klik kanan dan pilih menu
Breakpoint – Hardware on access – Dword. Jalankan program dengan memencet F9. Program akan
berhenti karena breakpoint yang telah terpasang, yaitu pada 004056F7 :
004056F7 . 8D4424 80 LEA EAX,DWORD PTR SS:[ESP-80]
004056FB > 6A 00 PUSH 0
004056FD . 39C4 CMP ESP,EAX
004056FF .^ 75 FA JNZ SHORT Lazy_Unp.004056FB
00405701 . 83EC 80 SUB ESP,-80
00405704 .- E9 43BAFFFF JMP Lazy_Unp.0040114C
Sampai saat ini, Anda dapat menghapus hardware breakpoint karena tidak digunakan lagi, yaitu melalui
menu Debug – Hardware breakpoints – Delete1. Langkah selanjutnya yaitu mencari loncatan terdekat
yaitu pada 00405704. Pasang kembali breakpoint pada 00405704 dengan memilih baris tersebut dan
memencet F2. . Alamat tersebut adalah loncatan yang akan berisi OEP.
Restart program dengan memencet Ctrl-F2. Jalankan kembali program dengan memencet F9 hingga
berhenti di :
00405704 .- E9 43BAFFFF JMP Lazy_Unp.0040114C
Pencet F8 dan Anda akan dibawa ke OEP, yaitu :
0040114C 68 88124000 PUSH Lazy_Unp.00401288
00401151 E8 EEFFFFFF CALL Lazy_Unp.00401144 ; JMP to [Link]
Selanjutnya yang harus dilakukan yaitu proses dump dari image ke disk. Untuk itu diperlukan program
dumper seperti LordPE Deluxe. Buka LordPE Deluxe dan klik kanan pada proses Lazy_UnpackMe.exe dan
pilih dump full. Simpan file dengan nama [Link].
Setelah image didapatkan, langkah berikutnya yaitu memperbaiki IAT. Agar lebih mudah, Anda dapat
menggunakan program ImportREC untuk memperbaiki IAT. Jalankan ImportREC dan pilih proses
Lazy_UnpackMe.exe. Pada isian OEP, isi dengan alamat OEP pada OllyDBG yaitu 0040114C kemudian
nilai tersebut dikurangi 00400000 sehingga menghasilkan nilai 0000114C. Nilai 00400000 merupakan
ImageBase pada program. OEP yang akan diisi pada ImportREC ini merupakan Relative Virtual Address
(RVA). Untuk mendapatkan nilai ini, rumus yang dipakai yaitu RVA EntryPoint = OEP – ImageBase.
Gambar 8. Memperbaiki IAT menggunakan ImportRec
Langkah berikutnya untuk memperbaiki IAT yaitu memencet tombol Get Imports. JIka langkah-langkah
yang dilakukan dari awal telah benar, maka akan muncul fungsi-fungsi yang akan di-import pada daftar
Imported Function Found. Pencet tombol klik Fix Dump dan pilih file [Link], kemudian akan
muncul file baru dengan nama Dumped_.exe. Jika Anda mengecek file Dumped_.exe menggunakan PEiD,
maka informasi yang akan ditampilan adalah “Microsoft Visual Basic 5.0 / 6.0”. Artinya file Dumped_.exe
sudah dalam keadaan tidak di-pack. Jalankan Dumped_.exe dan program akan berjalan dengan baik.
Anti Debugging
Kebanyakan program PE Packer dilengkapi dengan kemampuan untuk mendeteksi program debbuger
seperti OllyDBG. Teknik pendeteksian debugger dan dumper ini pun bervariasi, mulai dari penggunaan
fungsi API IsDebuggerPresent, FindWindow hingga pemakaian teknologi virtual machines.
Dengan adanya teknik anti debugging ini, untuk melakukan unpacking haruslah dilakukan patching atau
pemodifikasian secara manual untuk menonaktifkan teknik anti debugging yang terdapat pada program.
Sebagai contoh source code VB6 yang menggunakan IsDebuggerPresent :
Private Declare Function IsDebuggerPresent Lib "[Link]" () As Long
Private Sub Form_Load()
If Not IsDebuggerPresent Then
MsgBox "Debugger Not Present"
Else
MsgBox "Debugger Present"
End If
End Sub
Jika program dengan source code tersebut di compile dan dibuka menggunakan OllyDBG, pada saat
memencet F9 program akan mengeluarkan pesan “Debugger Present”. Bagaimana jika pesan tersebut
diganti menjadi rutin untuk menutup program? Tentunya proses unpacking akan berhenti. Oleh karena
itu salah satu cara melewati pendeteksian ini yaitu dengan menggunakan patching. Berikut cuplikan kode
di anti debugging di atas pada OllyDBG :
00401A50 /74 43 JE SHORT Project1.00401A95
00401A52 . |8D55 9C LEA EDX,DWORD PTR SS:[EBP-64]
00401A55 . |8D4D DC LEA ECX,DWORD PTR SS:[EBP-24]
00401A58 . |C745 A4 AC184>MOV DWORD PTR SS:[EBP-5C],Project1.00401>; UNICODE "Debugger Not
Present"
00401A5F . |C745 9C 08000>MOV DWORD PTR SS:[EBP-64],8
00401A66 . |FF15 70104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarDu>; MSVBVM60.__vbaVarDup
00401A6C . |8D45 AC LEA EAX,DWORD PTR SS:[EBP-54]
00401A6F . |8D4D BC LEA ECX,DWORD PTR SS:[EBP-44]
00401A72 . |50 PUSH EAX
00401A73 . |8D55 CC LEA EDX,DWORD PTR SS:[EBP-34]
00401A76 . |51 PUSH ECX
00401A77 . |52 PUSH EDX
00401A78 . |8D45 DC LEA EAX,DWORD PTR SS:[EBP-24]
00401A7B . |57 PUSH EDI
00401A7C . |50 PUSH EAX
00401A7D . |FF15 1C104000 CALL DWORD PTR DS:[<&MSVBVM60.#595>] ; [Link]
00401A83 . |8D4D AC LEA ECX,DWORD PTR SS:[EBP-54]
00401A86 . |8D55 BC LEA EDX,DWORD PTR SS:[EBP-44]
00401A89 . |51 PUSH ECX
00401A8A . |8D45 CC LEA EAX,DWORD PTR SS:[EBP-34]
00401A8D . |52 PUSH EDX
00401A8E . |8D4D DC LEA ECX,DWORD PTR SS:[EBP-24]
00401A91 . |50 PUSH EAX
00401A92 . |51 PUSH ECX
00401A93 . |EB 41 JMP SHORT Project1.00401AD6
00401A95 > \8D55 9C LEA EDX,DWORD PTR SS:[EBP-64]
00401A98 . 8D4D DC LEA ECX,DWORD PTR SS:[EBP-24]
00401A9B . C745 A4 DC184>MOV DWORD PTR SS:[EBP-5C],Project1.00401>; UNICODE "Debugger
Present"
Pada baris pertama yang berisi alamat 00401A50 berisi instruksi untuk meloncat ke baris 00401A95.
Loncatan ini bertujuan untuk memanggil kotak pesan yang berisi “Debugger Present”, dimana artinya
loncatan ini merupakan loncatan yang akan dipanggil ketika program menemukan debugger melalui
fungsi IsDebuggerPresent. Untuk membalikan skema kode di atas, Anda cukup mengganti baris tersebut
dari :
00401A50 /74 43 JE SHORT Project1.00401A95
menjadi
00401A50 /74 43 JNZ SHORT Project1.00401A95
JNZ alias JNE merupakan kebalikan logika dari instruksi JE.
JNE = Jump (if) Not Equal
JE = Jump (if) Equal
Selain dengan melakukan patching secara manual, ada beberapa plugin pada OllyDBG yang dapat
digunakan untuk melewati proteksi dari anti debugging seperti Hide Debugger atau Olly Advanced.
Generic Unpacker
Selain melakukan debugging secara manual, untuk melakukan unpacking dapat juga dilakukan secara
otomatis menggunakan program unpacker seperti PEiD atau Quick Unpack. Berikut cara unpacking
Lazy_UnpackMe.exe menggunakan PEiD :
- Buka Lazy_UnpackMe.exe menggunakan PeiD
- Klik tombol ->
- Pilih menu Plugins – PEid Generic Unpacker
- Klik tombol -> pada jendela baru
- Klik tombol Unpack
- Klik Yes jika ada konfirmasi untuk memperbaiki IAT
- File baru pun tercipta dengan nama Lazy_UnpackMe.exe.unpacked_.exe
Gambar 9. Unpacking otomatis menggunakan PEiD
Sangat mudah dan cepat bukan? OEP dapat dicari oleh PeID secara otomatis beserta perbaikan terhadap
IAT. Hampir semua program packer yang beredar luas dapat di-unpack mengguanak PEiD. Bandingkan
jika Anda harus melakukan debugging secara bertahap menggunakan OllyDBG? Penggunaan generic
unpacker seperti PEiD dapat menghemat waktu untuk melakukan unpacking. Namun tidak semua
executable yang telah di-pack dapat di-unpack menggunakan program berjenis generic unpacker ini,
misalnya packer yang bersifat home made atau pun yang mempunyai kompleksitas tersendiri pada
pemroteksian. OllyDBG pun mempunyai fasilitas OllyScript, dimana dengan adanya OllyScript ini,
seseorang dapat menulis script untuk melakukan debugging secara otomatis.
Kesimpulan
Untuk melakukan unpacking, hal yang harus dilakukan yaitu menunggu packer me-load image program
asli. Setelah menemukan OEP, langkah selanjutnya akan lebih muda yaitu dump image ke disk,
mengubah EntryPoint image menjadi OEP yang ditemukan dan perbaiki IAT.
Umumnya, PE Packer sering digunakan untuk memroteksi suatu software agar tidak mudah di-crack.
Namun ketergantungan kepada program PE Packer saja tidaklah cukup. Sekali teknik unpacking pada
packer tersebut diketahui, berakhirlah proteksi dari software tersebut. Oleh karena itu, menggunakan
proteksi internal yang kokoh dan bersifat pribadi merupakan alternative yang lebih baik daripada packer
yang bersifat publik.
PE Packer juga sering digunakan oleh malware agar sulit untuk dianalisa. Packer ini biasa berjenis home
made alias tidak bersifat public. Dengan executable yang telah di-pack, penganalisa malware tidak dapat
menganalisa exe secara static alias penganalisa tidak dapat memahami kode malware pada decompiler
atau disassembler. Oleh karena itu, unpacking diperlukan untuk membedah malware atau bahkan dapat
disalahgunakan juga untuk membuat crack program.
Lebih Lanjut
[Link]
[Link]
[Link]