• Tidak ada hasil yang ditemukan

Analisis Self Modifying Code Menggunakan Dynamic Binary Instrumentation

N/A
N/A
Protected

Academic year: 2017

Membagikan "Analisis Self Modifying Code Menggunakan Dynamic Binary Instrumentation"

Copied!
88
0
0

Teks penuh

(1)
(2)
(3)
(4)

Nama Lengkap : Teguh Prima Alko

Jenis Kelamin : Pria

Tempat, Tanggal

lahir : Pangkal Pinang, 2 Maret 1992

Kewarganegaraan : Indonesia

Status Hubungan : Belum Menikah

Tinggi , Berat : 175 cm , 73 kg

Agama : Islam

Alamat Lengkap : JL. R.H Fisabilillah No. 7 Tanjungpinang

Handphone : 081224746230

E-mail : teguh@cloudmail.de

RIWAYAT PENDIDIKAN

1998 – 2003 : SD Negeri 23 Tanjungpinang

2003 – 2006 : SMP Negeri 4 Tanjungpinang

2006 – 2009 : SMA Negeri 2 Tanjungpinang

2009 – 2016 : Universitas Komputer Indonesia, Fakultas Teknik dan Ilmu

(5)

Diajukan untuk Menempuh Ujian Akhir Sarjana

TEGUH PRIMAALKO 10109383

PROGRAM STUDI TEKNIK INFORMATIKA

FAKULTAS TEKNIK DAN ILMU KOMPUTER

(6)

iii

Sudah semestinya penulis berterimakasih kepada Allah Subhanahu wa

ta’ala yang telah memberikan energi untuk dapat menyelesaikan skripsi yang

berjudul “ANALISIS SELF-MODIFYING CODE MENGGUNAKAN

DYNAMIC BINARY INSTRUMENTATION”.

Maha kuasa Allah Subha nahu wa ta’ala telah mengirim anugerah dengan

orang-orang yang dapat menemani, membimbing dan mendukung

penyelesaian skripsi ini dengan cara yang sangat luar biasa. Untuk itu,

penulis ingin menyampaikan rasa terimakasih sebesar-besarnya kepada:

1. Ibunda penulis yang telah memberikan doa dan pengertian serta Suci A.

Ayu sebagai adik dari Penulis yang telah memberikan dukungan.

2. Bpk. Adam Mukharil Bachtiar, S.Kom., M.T., sebagai pembimbing

yang memotivasi dan memberikan pemahaman yang jernih kepada

penulis.

3. Adrian Negreanu dan Derek Bruening sebagai pengembang

DynamoRIO yang bersahabat dalam memberikan petunjuk

4. Aluh yang bersih keras agar Penulis tetap berjuang sampai lulus, Ipey

dengan nasihat dan konsep kedewasaanya, Domse yang selalu percaya

diri dengan absurdity-nya, Olih yang selalu menebar tawa ketika down,

Tetski dengan kelucuan emosionalnya dan Didiw sebagai sahabat

travelling dan refreshing ketika jenuh

5. Rekan-rekan seperjuangan skripsi yang ikhlas memberikan informasi

kepada Penulis yakni Rizkika Adam dan Arif serta Ali yang

memberikan cheer up dengan penuh determinasi

6. Yellow Truck, Bobber Cafe, Goethe-Institut, Double Eight Coffee dan

Caffetto atas ruang yang cozy dan kopi nikmatnya

(7)

iv

Bandung, 2 Maret 2016

(8)

v

ABSTRACT ... ii

KATA PENGANTAR ... iii

DAFTAR ISI ... v

DAFTAR GAMBAR ... viii

DAFTAR TABEL ... ix

DAFTAR LAMPIRAN ... xi

BAB I PENDAHULUAN ... 1

I.1 Latar Belakang Masalah ... 1

I.2 Perumusan Masalah ... 2

I.3 Maksud dan Tujuan Penelitian ... 2

I.4 Batasan Masalah ... 2

I.5 Metodologi Penelitian ... 3

I.6 Sistematika Penulisan ... 5

BAB II TINJAUAN PUSTAKA ... 7

II.1 Debugging ... 7

II.2 Macam-Macam Format Debugging ... 7

II.3 Instrumentation ... 8

II.4 Metode Binary Instrumentation ... 10

II.5 ELF ... 10

II.6 Self-Modifying Code ... 11

(9)

vi

II.11 Binary Analysis ... 19

II.12 Program Lifecycle Phase ... 20

II.12.1 Edit Time ... 20

II.12.2 Compile Time... 20

II.12.3 Link Time ... 20

II.12.4 Load Time ... 21

II.12.5 Run Time ... 21

II.13 Binary Translation ... 21

II.14 Intermediate Representation ... 21

BAB III ANALISIS SELF-MODIFYING CODE DAN PERANCANGAN DYNAMIC BINARY INSTRUMENTATION ... 23

III.1 Analisis Sistem ... 23

III.1.1 Analisis Masalah ... 23

III.1.2 Analisis Biner Program ... 23

III.1.3 Analisis Self-Modifying ... 24

III.1.4 Analisis Binary Translation ... 28

III.1.5 Analisis Sintaksis ... 30

III.1.6 Spesifikasi Intermediate Representation ... 41

III.1.7 Analisis Kebutuhan Non Fungsional ... 50

III.1.7.1. Analisis Perangkat Lunak ... 51

III.1.7.2. Analisis Perangkat Keras ... 51

(10)

vii

IV.1.1. Lingkungan Implementasi Sistem ... 63

IV.1.2. Implementasi Pembangunan Dynamic Binary Instrumentation ... 63

IV.1.3. Implementasi Pembuatan Random Test Case Generation ... 65

IV.2 Pengujian Sistem ... 65

BAB V KESIMPULAN DAN SARAN ... 75

(11)

77

Instrumentation,” in VEE '12 Proceedings of the 8th ACM SIGPLAN/SIGOPS conference on Virtual Execution Environments, New York, 2012.

[2] M. Probst, “Dynamic Binary Translation,” CD Laboratory for Compilation Techniques, 2003.

[3] N. Mavrogiannopoulos, N. Kisserli and B. Preneel, “A taxonomy of self -modifying code for obfuscation,” Computers and Security, vol. 30, no. 8, pp. 679-691, 2011.

[4] N. Nethercote, “Dynamic Binary Analysis and Instrumentation,” University of Cambridge Computer Laboratory, 2004.

[5] “The DynamoRIO API,” Google, 8 October 2015. [Online]. Available: http://dynamorio.org/docs/.

[6] K. Anand, M. Smithson, K. Elwazeer, A. Kotha, J. Gruen, N. Giles and R.

Barua, “A Compiler-level Intermediate Representation based Binary Analysis

and Rewriting System,” in EuroSys '13 Proceedings of the 8th ACM European Conference on Computer Systems, New York, 2013.

[7] “ELF,” OS Development, 7 August 2015. [Online]. Available: http://wiki.osdev.org/ELF.

[8] X. Xie, F. Liu, B. Lu and F. Xiang, “Mixed Obfuscation of Overlapping Instruction and Self-Modify Code Based on Hyper-Chaotic Opaque

(12)

[9] S. Blazy, V. Laporte and D. Pichardie, “Verified Abstract Interpretation Techniques for Disassembling Low-level Self-modifying Code,” in Interactive Theorem Proving, Springer International Publishing, 2014, pp.

128-143.

[10] B. Anckaert, M. Madou and K. D. Bosschere, “A Model for Self-Modifying

Code,” in Information Hiding, Springer Berlin Heidelberg, 2007, pp. 232-248.

[11] T. Touili, B. Cook and P. Jackson, “Computer Aided Verification,” in 22nd International Conference, CAV 2010, Edinburgh.

[12] N. M. Hai, M. Ogawa and Q. T. Tho, Obfuscation code localization based on

CFG generation of malware, Clermont-Ferrand: Springer, 2015.

[13] R. Mankadan, P. A. Kumar and R. Govindaraju, “CODE SECURITY BY

CONFUSING LOGIC FLOW USING SELF MODIFYING CODE,”

International Journal of Innovative Trends and Emerging Technologies, vol.

I, no. 2, 2015.

[14] J. Pogulis, “Generation of dynamic control-dependence graphs for binary

programs,” Linköping University, Department of Computer and Information

Science, Database and information techniques, 2014.

[15] M. Payer, A. Barresi and R. T. Gross, “Lockdown: Dynamic Control-Flow

Integrity,” ETH, Zürich, 2014.

[16] W. Arthur, B. Mehne, R. Das and T. Austin, “Getting in control of your control flow with control-data isolation,” in CGO '15 Proceedings of the 13th Annual IEEE/ACM International Symposium on Code Generation and

(13)

[17] V. Pappas, M. Polychronakis and A. D. Keromytis, “Dynamic Reconstruction of Relocation Information for Stripped Binaries,” in Research in Attacks, Intrusions and Defenses, Springer International Publishing, 2014, pp. 68-87.

[18] T. Vilkeliskis, “Automated unpacking of executables using Dynamic Binary

Instrumentation,” Department of Computer Science, Stevens Institute of

Technology, 2009.

[19] . A. Roy, S. Hand and T. Harris, “Hybrid binary rewriting for memory access

instrumentation,” in VEE '11 Proceedings of the 7th ACM SIGPLAN/SIGOPS international conference on Virtual execution environments, New York,

2011.

[20] J. Ming, D. Xu, L. Wang and D. Wu, “LOOP: Logic-Oriented Opaque

Predicate Detection in Obfuscated Binary Code,” in CCS '15 Proceedings of the 22nd ACM SIGSAC Conference on Computer and Communications

Security, 2015.

[21] H. Guo, J. Pang, Y. Zhang, F. Yue and R. Zhao, “HERO: A novel malware

detection framework based on binary translation,” in Intelligent Computing and Intelligent Systems (ICIS), Xiamen, 2010.

[22] H. Guan, E. Zhu, H. Wang, R. Ma, Y. Yang and B. Wang, “SINOF: A dynamic-static combined framework for dynamic binary translation,” Journal of Systems Architecture, vol. 58, no. 8, pp. 305-317, 2012.

[23] M. Braun, M. Buchwald and A. Zwinkau, “FIRM: A Graph-Based

(14)

1

BAB I

PENDAHULUAN

I.1 Latar Belakang Masalah

Self-Modifying Code berperan penting dalam pengembangan perangkat

lunak komersil terutama pada kasus proteksi lisensi dari pembajakan dan

malicious software dalam menyembunyikan eksistensinya. SMC juga sering

dikombinasikan dengan teknik anti-debugging lainnya seperti obfuscation. Hal

tersebut menjadi tantangan pada dunia reverse engineering karena sulit dianalis

secara statis. Aplikasi debugger umumnya hanya mengontrol data tetap pada

program dan memori saja. Salah satu menyiasatinya adalah dengan mendampingi

debugger dengan metode instrumentasi. Instrumentasi pada pemograman

digunakan untuk beberapa tujuan seperti hasil penggunaan memori, statistik

performansi maupun pengecekan bug dari segi kegunaan dan keamananan.

Instrumentasi beroperasi dengan menanamkan kode monitoring ke dalam

spesifik komponen program pada level sumber kode maupun biner. Pada kasus

program Self-Modifying Code terdapat pola subtitusi fungsi yang membuat proses

monitoring lepas dari pemindaian. Hal tersebut merupakan kelemahan dari

instrumentasi statis yang bekerja sebelum program dijalankan atau hanya

memindai binernya saja. Dengan kata lain subtitusi fungsi tidak dapat diketahui

karena terjadi pada saat eksekusi program. Kesulitan lain yang akan dihadapi oleh

reverse engineer adalah waktu yang diperlukan untuk memecahkan subtitusi

tersebut dan akan selalu berganti setiap kali ditemukan polanya, maka dari itu

perubahan harus dapat ditebak akan seperti apa selanjutnya.

Berdasarkan kendala tersebut diperlukan suatu analisis secara dinamis pada

saat program ditahap runtime. Dengan menggunakan metode Dynamic Binary

Instrumentation diharapkan dapat menganalisis Self-Modifying Code saat program

sedang memodifikasi dirinya. Instrumentasi dinamis pada biner juga menjaga

(15)

proses subtitusi fungsi dari Self-modifying Code itu sendiri. Proses DBI dilakukan

hampir tanpa interaksi reverse engineer atau menganalisis secara otomatis,

dengan begitu kasus dapat cepat diselesaikan.

I.2 Perumusan Masalah

Berdasarkan permasalahan yang telah dikemukakan pada latar belakang

dapat dirumuskan, kesulitan melakukan reverse engineering terhadap program

Self-Modifying Code sebagai usaha anti debugging.

I.3 Maksud dan Tujuan Penelitian

Maksud dari penelitian ini adalah menganalisis teknik Self-Modifying Code

menggunakan metode DBI(Dynamic Binary Instrumentation).

Adapun tujuan yang akan dicapai dalam penelitian ini adalah memperoleh

hasil analisis Self-Modifying Code yang mudah dimengerti dengan keluaran

intermediate representation untuk mempermudah reverse engineer dalam menilai

tindak lanjut pada proses debugging.

I.4 Batasan Masalah

Batasan masalah yang digunakan untuk Dynamic Binary Instrumentation

adalah sebagai berikut:

1. Dynamic Binary Instrumentation menggunakan Open Source Framework

DynamoRIO.

2. DynamoRIO digunakan dengan integrasi API (Application Programming

Interface) LLVM untuk memperoleh keluaran intermediate

representation

3. DynamoRIO plugin yang dibangun bertujuan memberikan nasihat atas

pola Self-Modifying Code

4. DynamoRIO plugin yang dibangun bukan sebagai patcher atau mengubah

program Self-Modifying Code menjadi non-Self-Modifying Code

5. DynamoRIO plugin dibangun menggunakan bahasa pemograman C++

(16)

Sedangkan batasan masalah pada kasus Self-Modifying Code terdiri dari:

1. Program Self-Modifying Code berformat ELF (Executable and Linkable

Format)

2. Program Self-Modifying Code mempunyai instruksi arsitektur x86_64 atau

AMD64(little endian)

3. Program Self-Modifying Code dianalisis dengan metode Dynamic Binary

Instrumentation

4. Program Self-Modifying Code dianalisis dengan tujuan menemukan set

instruksi pengganti dengan mudah

5. Program Self-Modifying Code bukan kompilasi JIT(Just-in-Time)

I.5 Metodologi Penelitian

Metodologi yang digunakan dalam penelitian ini adalah metode

eksperimental karena dilakukan pengujian berulang – ulang dan kasus dapat diuji

dengan metode lainnya. Adapun untuk analisis permasalahan digunakan metode

DBI(Dynamic Binary Instrumentation).

1. Metode Pengumpulan Data

a. Metode Studi Pustaka

Mencari literatur yang terkait dengan Self-Modifying Code dan Dynamic

Binary Instrumentation.

b. Metode Wawancara

Berupa tanya jawab dengan reverse engineer melalui e-mail dan forum

online. Metode ini digunakan untuk mendapat data – data pada sistem.

2. Metode Analisis Dynamic Binary Instrumentation

Metode yang digunakan dalam penelitian ini adalah DBI(Dynamic Binary

Instrumentation) dengan menggunakan framework dari DynamoRIO. DynamoRIO

beroperasi dengan menggeser eksekusi sebuah aplikasi dari petunjuk aslinya ke

(17)

menempati ruang alamat aplikasi tersebut dan memiliki kendali penuh atas

eksekusi, mengambil alih setiap kali kontrol meninggalkan cache code atau ketika

sistem operasi langsung mentransfer kontrol ke aplikasi (kernel-mediated control

transfers).

Gambar I.1 Proses DynamoRIO

DynamoRIO menyalin kode aplikasi satu blok dasar dinamis setiap waktu

ke dalam kode cache blok dasarnya. Sebuah blok yang langsung menargetkan

blok lain sudah ditempati dalam cache yang terkait blok tersebut untuk

menghindari kembali ke dispatcher. Urutan eksekusi dari blok dasar yang sering

muncul digabungkan menjadi traces yang ditempatkan secara terpisah.

DynamoRIO membuat traces tersebut tersedia melalui antarmuka untuk

(18)

I.6 Sistematika Penulisan

Sistematika penulisan ini disusun untuk memberikan gambaran umum

tentang penelitian yang dijalankan. Sistematika penulisan penelitian ini adalah

sebagai berikut:

BAB I PENDAHULUAN

Menguraikan tentang latar belakang permasalahan, mencoba merumuskan

inti permasalahan yang dihadapi, menentukan tujuan dan kegunaan

penelitian, yang kemudian diikuti dengan pembatasan masalah, asumsi, serta

sistematika penulisan.

BAB II. TINJAUAN PUSTAKA

Membahas berbagai konsep dasar dan teori-teori yang berkaitan dengan

topik penelitian yang dilakukan dan hal-hal yang berguna dalam proses

analisis permasalahan serta tinjauan terhadap penelitian-penelitian serupa yang

telah pernah dilakukan sebelumnya termasuk sintesisnya.

BAB III. ANALISIS SELF-MODIFYING CODE DAN PERANCANGAN

DYNAMIC BINARY INSTRUMENTATION

Bab ini berisi tentang analisis masalah, analisis biner program, analisis

non-fungsionalitas serta analisis perancangan metode yang digunakan. Selain itu

pada bab ini memaparkan perancangan sistem yang akan dianalisis.

BAB IV. IMPLEMENTASI DAN PENGUJIAN SISTEM

Bab ini menerangkan tentang pengujian sistem berdasarkan pada metode yang

digunakan dengan menggunakan unit testing dan menjelaskan apakah sudah

benar-benar sesuai dengan analisis dan perancangan yang telah dilakukan.

BAB V. KESIMPULAN DAN SARAN

(19)
(20)

7

BAB II

TINJAUAN PUSTAKA

II.1 Debugging

Bug pada perangkat lunak merupakan sebuah kesalahan dalam program atau

sistem yang menyebabkan setidaknya satu fungsional atau non-fungsional

menjadi terganggu. Debugging adalah sebuah proses sistematis memerika

program dari bug. Debugging sendiri diambil dari kata bug yang fokus utamanya

memang untuk melepas bug. Namun, tujuan akhirnya tidak selalu untuk

memperbaiki program, beberapa reverse engineer melakukannya agar dapat

mengambil keuntungan tertentu seperti eksploitasi.

Pada umumnya debugging adalah bagaimana menciptakan suatu masalah

seperti input diluar ekspektasi atau dengan membuat test case sembarangan (black

box testing) sampai menimbulkan crash. Setelah program mencapai keadaan

crash kemudian debugger mengeksaminasi status program dimana terjadi urutan

letak masalah atau dikenal sebagai call stack. Beberapa call stack memiliki

informasi yang kurang jelas atau implisit tergantung dari tingkatan kompleksnya

sebuah program.

II.2 Macam-Macam Format Debugging

Format Debugging merupakan desain data yang tersimpan dalam program

untuk mempermudah debugger dalam menganalisis. Macam – macam format

debugging diantaranya:

1. STAB (symbol table) menyimpan informasi debug ke bagian simbolis file

objek yang umumnya digunakan oleh executable pada sistem operasi

UNIX terdahulu dan digunakan hingga sekarang untuk alasan

kompabilitas.

2. DWARF (debug with arbitrary record format) menggunakan file objek

untuk menyimpan informasi debug dengan struktur pohon di mana setiap

simpul mewakili tipe data, variabel atau fungsi. DWARF menjadi standar

(21)

II.3 Instrumentation

Instrumentasi dalam istilah pemograman adalah tindakan menanamkan kode

monitoring ke dalam sistem perangkat lunak. Instrumentasi dapat dilakukan

dengan cara transformasi biner program, manipulasi link-time, hooks khusus

dalam virtual machine(bahasa pemograman tingkat tinggi/interpreter) atau dengan

transformasi pada sumber kode. Keluaran yang dihasilkan berupa peristiwa yang

terjadi pada program dalam konteks spesifik, tidak meluas atau hanya bergantung

pada komponen dan fungsi yang ditinjau.

Kelemahan instrumentasi terletak pada jangkauannya yang mengurucut ke

fungsi target sehingga memungkinkan kode yang di-instrument lepas dari

eksamen atau tidak sampai mencapai poin eksekusi ketika fungsi tersebut

memanggil fungsi lainnya. Instrumentor juga berperan menggapai memori yang

diakuisisi program dan membuat kinerja program menjadi lamban atau bahkan

crash. Hal tersebut sangat bergantung pada kondisi environment atau resource

yang dimiliki.

Dalam menentukan instrumentasi apa yang cocok untuk digunakan perlu

dilihat ketersediaan informasi program. Adapun kategori tersebut dikategorikan

berdasarkan language agnostic yakni:

1. DLL(Dynamic Link Library) Rewriting

Instrumentasi dijalankan saat setelah siklus kompilasi/linking dimana

penggunaan hasil cache merupakan DLL yang telah dimodifikasi

2. In Place Instrumentation

Sama dengan DLL rewriting akan tetapi DLL tidak dimodifikasi begitu juga

dengan target program. Fungsi – fungsi di-hook tepat untuk tugas yang

diperlukan ketika DLL tersebut dimuat atau di-load pertama kali saat startup

atau setelah panggilan LoadLibrary

(22)

Mirip dengan in place instrumentation tetapi hanya menginstrumentasi

sebuah fungsi saat pertama kali fungsi tersebut dieksekusi

4. Intermediate Language Instrumentation

Instrumentasi pada bahasa tingkat menengah adalah memonitor aktivitas

eksekusi sebelum bahasa tingkat menengah dikompilasi ke dalam instruksi

executable oleh virtual machine atatu interpreter

5. Intermediate Language Instrumentation via Reflection

Java dan .Net keduanya memberikan API refleksi yang memungkinkan

penemuan metadata tentang metode. Dengan menggunakan data tersebut dapat

dibuat metode baru dengan on-the-fly instrumentation yang ada seperti dengan

instrumentasi bahasa tingkat menengah disebutkan sebelumnya.

6. Compile Time Instrumentation

Teknik ini digunakan pada waktu kompilasi untuk menyisipkan instruksi

yang tepat ke dalam aplikasi selama kompilasi. Kelemahannya membutuhkan

usaha pembangunan linking yang besar.

7. Source Code Instrumentation

Teknik ini digunakan untuk memodifikasi kode sumber dengan menyisipkan

kode instrumentasi yang sesuai dengan dekorator sebelum masing-masing fungsi.

8. Link Time Instrumentation

Teknik ini sangat berguna ketika dibutuhkannya penggantian memory

allocators seperti fungsi realloc dengan tracing allocators. Hal tersebut berkaitan

dengan pencarian bug pada memori seperti buffer overflow atau memory leak

9. IAT Hooking Instrumentation

Instrumentasi ini melibatkan modifikasi import address table untuk fungsi

terkait dalam DLL atau Unix shared object. Hanya dengan patch lokasi import

(23)

II.4 Metode Binary Instrumentation

Binary Instrumentation merupakan proses memodifikasi instruksi sebuah

program ketika eksekusi. Modifikasi tersebut dapat diaplikasikan pada file

executable, file objek maupun file kelas pada semua fase seperti waktu kompilasi,

linking pustaka, load time atau run-time. Dynamic Instrumentation beroperasi

dengan menanamkan kode dinamis ke dalam program tanpa harus rekompilasi.

Dynamic Binary Instrumentation dapat menganalisis eksekusi program secara

step-by-step pada konteks memori dan register dan hanya menganalisis kode yang

dieksekusi.

Dynamic Binary Instrumentation adalah sebuah metode analisis tingkah

laku aplikasi secara runtime pada saat eksekusi melalui penanaman kode

instrumentasi. Kode intrumentasi tersebut mengeksekusi sebagai bagian dari

instruksi asli. DBI dibagi atas dua berdasarkan cara kerjanya yaitu light-weight

dan heavy-weight. Light-weight DBI beroperasi pada instruksi stream secara

spesifik berdasarkan arsitektur dan status perlakuan analisis sedangkan

heavy-weight beroperasi secara abstrak pada stream dan status instruksinya [2].

Berbeda dengan Static Binary Instrumentation yang memodifikasi file

executable maupun pustakanya dengan pendekatan sebelum eksekusi program.

Instrumentasi biner dinamis memanipulasi saat program di tahap sudah dimuat

dalam memori. Instrumentasi biner secara statis mempunyai keunggulan dalam

hal performansi karena DBI melakukan penyisipan sebelum eksekusiyang

berakibat akses informasi seperti nama variabel menjadi sulit.

II.5 ELF

ELF (Executable and Linking Format) ialah format file executable standar

UNIX System V seperti Linux yang dibagi beberapa seksi seperti .text untuk

kode, .data untuk variabel global, .rodata yang umumnya menyimpan strings

konstan, .bss(Block Started by Symbol) data segment yang mengandung variabel

statis representasi oleh zero-valued(pengosongan memori) ketika eksekusi dimulai

dan .stab untuk simbol debugging. File ELF juga berisi header yang

(24)

Gambar II.1 ELF Diagram

ELF dahulunya disebut Extensible Linking Format karena dapat direlokasi

dengan mudah mengandalkan linking dan loading DSO (dynamically linked

shared objects). Namun, ELF juga mampu mendukung position independent code

yang menghindari pengalamatan secara absolut atau tidak membutuhkan relokasi

sama sekali. Hal tersebut berbeda dengan pustaka statis walaupun ELF juga

mendukung sistem portable.

II.6 Self-Modifying Code

Self-Modifying Code adalah sebuah teknik pemograman dimana program

(25)

merupakan cetusan dari Rice’s theorem dimana untuk setiap properti non-trivial

dari fungsi parsial, tidak ada metode umum dan efektif yang dapat memutuskan

apakah suatu algoritma mengkalkulasi fungsi parsial properti tersebut. Logika

Self-Modifying Code pada dasarnya menggunakan ekspresi lambda kalkulus

dalam subtitusi fungsi.

Self-Modifying Code kerap kali diidentikkan dengan salah satu teknik

obfuscation namun, program tidak serta merta menjadi kompleks dalam hal

analisis melainkan performa program yang membaik dan baris kode yang lebih

efisien. Rata – rata program obfuscated adalah memberikan junk yang tidak

berarti untuk mengelabui analis sedangkan Self-Modifying Code umumnya

mengambil jalan potong untuk instruksi yang lebih sederhana.

Berdasarkan fungsinya Self-Modifying Code dibagi atas beberapa tujuan.

Adapun contoh diantaranya yang sering digunakan adalah sebagai berikut:

1. Self-Checksumming

Program melakukan pengecekan integritas terhadap variasi segmen kode saat

eksekusi untuk memastikan bahwa biner program tidak diubah. Verifikasi berada

pada segmen memori dengan status segmentation fault atau program dihentikan

dengan signal handler interupsi tertentu jika terdeteksi ketidaksesuaian. Hal ini

bukan mengecek apakah hash checksum dari keseluruhan biner berbeda

melainkan keutuhan dari instruksi program. Adapun contoh dari Self-Checksum

dapat dilihat pada pseudocode assembly berikut:

add (rbx), r15 ;membaca memori

sub 1, ecx ;looping counter secara decrement

add rdi, rax

xor r14, rdi

add rcx, rdx

add rbx, rdi

xor rax, rdx ;modifikasi register jump_target yaitu rdx dan rdi

xor r15, rdi

(26)

add rdi, r14 ;modifikasi checksum dengan rdx dan rdi

xor rdx, -8(rsp) ;modifikasi checksum dalam stack

xor r15, r13

add r14, r12

rol r15

xor rdi, rbx ;membuat pseudorandom akses memori

and mask1, ebx

or mask2, rbx

xor rdx, rsp

and mask3, esp

or mask4, rsp

and 0x180, edx ;Modifikasi penunjuk stack dan alamat target_jump

and 0x1, rdi

add rdi, rdx

add rdi, rdi

add rdi, rdx

or mask, rdx ;membuat alamat target_jump

xor rdx, r15 ;Menambahkan alamat target_jump ke dalam checksum

mov rax, rdi

Enkripsi dapat diimplementasikan pada biner executable dan didekripsi pada

saat program dijalankan. Biasanya menggunakan instruksi aritmetik

XOR(exclusive-or) maupun polymorphic dengan menambahkan operasi bit

instruksi ADD(addition) dan SUB(subtraction). Contoh Self-Decrypt dapat

dilihat pada pseudocode assembly berikut:

main:

pop rsi ; pop alamat data

(27)

dienkripsi

Biner executable dapat diperkecil ukuran datanya dengan teknik kompresi

yang kemudian diekstrak ke memori untuk mendapatkan fungsi program

sebenarnya. Algoritma kompresi yang digunakan sama dengan metode untuk

kompresi file seperti Huffman/Lempel-Ziv, Welch,

Lempel-Ziv-Markov dan PAQ akan tetapi header atau magic program tetap sebagaimana

executable semestinya. Berikut contoh self-extract dalam bahasa pemograman

(28)

4. Self-Repairing

Self-Error-Correcting atau Self-Healing code merupakan upaya untuk

memperbaiki perangkat lunak dari error dengan sendirinya agar tidak pernah

crash. Hal ini merupakan topik lanjutan dari SMC karena menggunakan

kecerdasan buatan dalam implementasinya. Konsep dari Self-Repairing adalah

menyalin instruksi clean untuk memperbaiki jika ada satu atau lebih instruksinya

rusak. Adapun contohnya dapat dilihat pada pseudocode assembly berikut yang

merupakan safepoint pada hardisk atau S.M.A.R.T. (Self-Monitoring, Analysis

and Reporting Technology)

disk:

movb cl, (si) ; Jumlah sektor yang akan dibaca

push si ; Simpan si

mov si, #LOADOFF+ext_rw ;

movb 2(si), cl ; Mengisi blok yang akan ditransfer

mov 4(si), bx ; alamat buffer

pop si ; Mengeluarkan si ke poin alamat array

!jmp rdeval

add 1(si), ax ; Pembaharuan alamat oleh sector baca

adcb 3(si), ah

subb (si), al ; Decrement jumlah sektor dengan sector

baca

jnz load ;

add si, #4 ; memperbaiki alamat selanjutnya

(29)

yang dibaca

jnz load ; Baca instruksi selanjutnya

5. Self-Testing

Self-Testing Code bertujuan me-refactoring kode agar dapat menguji testcase

dengan sendirinya. Pendekatan ini mirip dengan built-in test akan tetapi eksekusi

bersifat jika peristiwa tertentu terjadi seperti kegagalan fungsi progam (bug)

dalam menjalankan tugasnya. Adapun contohnya dapat dilihat pada pseudocode

berikut:

loop: UMUL R4,R3,R2,R1 ; multiplikasi

ADD R5,R4,R3 ; tambah words

Anti-debugging adalah salah satu upaya untuk menghambat reverse

engineering sehingga analis tidak dapat menggunakan debugger untuk

(30)

perangkat lunak dan infeksi dari program lain seperti malware (malicious

software). Pada dasarnya semua sistem proteksi software primitif dibagi atas dua

ide yaitu checks dan landmines. Checks menghasilkan nilai ubahan atau jalan

eksekusi kode berbasis status item yang dicek sedangkan landmines seperti crash,

hang, scramble yang menginterupsi alat analisis atau debugger itu sendiri.

Beberapa bahasa pemograman telah menyediakan fungsi built-in berupa

API (Application Programming Interface) untuk pendeteksian debugger dan

virtual machine. Selanjutnya programmer dapat memutuskan apakah debugger

diizinkan untuk menganalisis atau tidak. Anti-debugging juga dapat diciptakan

oleh compiler yang fungsinya menghapus readable strings (metadata) termasuk

informasi debug atau dengan memberikan obfuscation agar instruksi program

menjadi kompleks.

II.8 DynamoRIO

DynamoRIO adalah salah satu framework atau alat Dynamic Binary

Instrumentation yang tersedia multiplatform dan sumber terbuka. Alat tersebut

merupakan kombinasi dari Dynamo, sebuah mesin optimasi dinamis yang

dikembangkan oleh peniliti dari HP dan RIO yaitu runtime instropection and

optimization engine yang dikembangkan oleh MIT. DynamoRIO mendukung

analisis aplikasi pada sistem operasi seperti Windows, Linux dan OSX yang

mempunyai arsitektur x86, AMD64 dan ARM.

Salah satu kelebihan DynamoRIO adalah analisis sudut pandangnya yang

menanamkan kode instrumentasi ketika binary fragment sedang dimasukkan ke

dalam fragment cache. Hal tersebut sangat berguna untuk mencegat akses memori

di dalam aplikasi. Ketika fragmen sedang dibuat, pustaka analisis DynamoRIO

berperan masuk ke instruksi dalam fragmen yang dihasilkan. Menggunakan

pengetahuan tersebut memungkinkan analis merancang pustaka analisis yang

dapat mencegat memori dalam membaca dan menulis ketika aplikasi dieksekusi.

Performansi merupakan kendala besar dalam instrumentasi biner dinamis.

(31)

performansi karena menggunakan rekompilasi JIT(Just-in-Time) terhadap seksi

kode yang memerlukan kerja ekstra. Namun untuk mengatasi logika kompleks

DynamoRIO dirasa tidak mumpuni karena ketersediaan pada kode cache terbatas.

Berikut ini dapat dilihat benchmark dalam analisis perangkat lunak chromium

yang menggunakan beberapa pustaka seperti kriptografi hingga multimedia

Gambar II.2 DynamoRIO Benchmark

PIN berulang kali melakukan iterasi untuk memastikan instruksi yang

kompleks benar-benar valid. Sedangkan Inference DynamoRIO yang merupakan

modifikasi khusus untuk target program hanya memerlukan informasi sederhana

dari arus instruksi berjalannya sebuah program karena informasi lainnya sudah

terdapat pada pustaka analisis yang dibuat.

II.9 Profiling

Profiling dalam informasi teknologi adalah aktivitas mengumpulkan

informasi penggunaan resources dan waktu yang diperlukan untuk menjalankan

suatu aplikasi. Profiling umumnya bertujuan untuk menemukan apa yang

(32)

dapat berupa penggunaan instruksi, panggilan fungsi diikuti waktu eksekusi

hingga aplikasi berhenti dalam bentuk teks maupun visualisasi grafik. Profiling

dapat dilakukan dengan kode instrumentasi yang ditanam pada biner program atau

pada level kode sumber.

Peristiwa yang terjadi pada program dapat diukur dengan statistik atau

benchmarks. Dengan memberikan kerja berat pada aplikasi, benchmarking lebih

memberikan informasi maksimal. Variasi kondisi membuat benchmarking dan

profiling menjadi dua hal yang berbeda. Aktivitas profiling pada dasarnya tidak

dibebani tugas yang berat melainkan tingkah laku pada status normal.

II.10 Tracing

Tracing dalam istilah pemograman merupakan salah satu teknik debugging

yang digunakan untuk memahami proses berjalannya sebuah program. Tracing

sering kali dikomparasikan dengan logging karena berupa catatan seperti file apa

saja yang dibuka, pustaka apa saja yang dipanggil dan sebagainya. Terdapat

beberapa level dalam mekanisme trace yaitu Verbose, Debug, Info, Warning,

Error, Fatal dan Silent. Buffer yang ditampilkan juga melingkupi bagian Main,

System, Radio, Events bahkan Crash.

Keluaran trace paling popular adalah backtrace atau stacktrace dimana

beberapa stack frame yang menjadi masalah pada program dikembalikan sampai

ke pangkal fungsi utama aplikasi. Stacktrace pada bahasa pemograman tingkat

tinggi di-handle oleh interpreter dan berisi poin baris kode yang

menginterpretasikan referensi masalah sedangkan, bahasa tingkat rendah

memerlukan simbol debug atau jika tidak ada, keluaran berupa bahasa mesin atau

assembly.

II.11 Binary Analysis

Analisis biner adalah sebuah pendekatan membongkar program dengan

disassembly atau dekompilasi untuk tujuan reverse engineering. Pekerjaan ini

dilakukan ketika analis tidak memiliki sumber kode. Aktivitas analisis biner

(33)

mendukung terjemahan yang sederhana ke dalam byte code atau emulasi sebagai

binary translation. Hal tersebut berkenaan bahasa mesin atau assembly sulit

dimengerti terutama pada aplikasi berskala besar yang mempunyai jutaan

instruksi.

Biner program juga dapat direpresentasikan dalam bahasa tingkat

menengah namun, bahasa tersebut sangat independen tergantung compiler yang

mengkompilasinya. Alat analisis biner berperan langsung dalam dekompilasi ke

bahasa independen tersebut. Analisis biner juga dapat dilakukan secara dinamis

dengan mengeksekusi program pada real dan virtual processor. Terminologi

analisis biner sangat dekat dengan runtime analysis karena keterbatasan analisis

statis yang tidak mumpuni untuk perangkat lunak berproteksi.

II.12 Program Lifecycle Phase

Fase umum dari hidupnya sebuah perangkat lunak dari sumber kode hingga

menjadi biner yang dijalankan meliputi:

II.12.1 Edit Time

Edit time adalah fase dimana ketika kode program sedang diubah artinya

status program bisa jadi belum ditahap konsisten. Perubahan biasanya dilakukan

oleh programmer namun, dapat pula dilakukan oleh generator, alat desain atau

dengan sistem meta-programming. Contohnya seperti pengecekan syntax atau

analisis sumber kode maupun merubah bahasa pemograman satu ke yang lainnya.

II.12.2 Compile Time

Compile time adalah fase setelah sumber kode diterjemahkan kedalam

bahasa mesin oleh compiler. Pada tahap kompilasi terjadi pengecekan atas

konsistensi kode yang diubah dan menghasilkan sebuah file executable. Untuk

bahasa pemograman tingkat tinggi yang menggunakan interpreter, kompilasi

berupa merubah sumber kode menjadi bytecode.

II.12.3 Link Time

Link time adalah fase menghubungkan pustaka dengan program yang

(34)

atau bahkan ketika eksekusi. Linking kerap kali dikaitkan dengan kompilasi

walaupun sebenarnya tahap ini terpisah. Linking juga merupakan penggabungan

beberapa file objek menjadi satu buah executable.

II.12.4 Load Time

Load time adalah fase ketika file executable dipanggil dan ditempatkan

dalam memori yang aktif sebagai bagian dari mulainya eksekusi. Sederhanya

adalah tahap dimana program pertama kali dijalankan yang mana sudah tidak lagi

berupa file melainkan menjadi kesatuan atau pengalamatan interface pada kernel.

II.12.5 Run Time

Run time adalah fase dimana program sedang berjalan normal maupun

tidak normal seperti hang. Di tahap ini program berada di status sudah

mengakuisisi memori dan dapat mulai bekerja secara multi threading atau

menciptakan proses child.

II.13 Binary Translation

Binary Translation adalah proses menerjemahkan kode mesin (biner) dari

satu set instruksi ke instruksi lainnya. Sistem yang menggunakan hal tersebut

direferensikan sebagai emulator. Kebanyakan Binary Translation mempunyai

fungsi alat migrasi untuk transisi arsitektur lama ke yang baru. Penerjamahan

biner dapat dilakukan secara statis (seluruh biner ke target platform) maupun

dinamis dengan menerjemahkan kode saat eksekusi secara parsial berdasarkan

fungsi yang diinginkan [3].

Beberapa Dynamic Binary Translation menggunakan “fast return” atau

indirect branch/call prediction dalam pendekatan mengindari overhead. Pada

processors terbaru prediksi menggunakan dua level adaptif predictor. Instruksi

tersebut berkontribusi lebih dari satu bit ke history buffer. Prosesor tanpa

mekanisme tersebut secara sederhana memprediksi sebuah indirect jump ke lokasi

yang sama terakhir kalinya. Contoh sederhana implementasi dari Binary

(35)

II.14 Intermediate Representation

IR atau sering disebut bahasa tingkat menengah merupakan representasi

program diantara sumber kode dan biner (assembly). Hal tersebut sangat

independen tergantung pada compiler maupun interpreter-nya. Representasi dapat

digambarkan melalui graph seperti AST (Abstract Syntax Tree) maupun biner

dalam bytecode. Bytecode mempunyai tujuan retargetable untuk merekonstruksi

kembali kedalam biner. Pada dasarnya IR memiliki contoh padanan menampilkan

algortitma sebagai berikut:

Reverse engineer dalam dunia komputer adalah orang yang mempunyai

tugas merekayasa hasil objek baik perangkat keras maupun lunak untuk

mengubah atau mengembalikkan informasi sumbernya. Pada biner aktivitasnya

meliputi membaca kode mesin assembly untuk program executable dan membaca

hexademical untuk objek lainnya seperti gambar atau video yang kemudian

direplikasi atau patching menjadi sesuai keinginan reverse engineer.

Terdapat bermacam-macam teknik reverse engineering untuk perangkat

lunak diantaranya melakukan analisis secara statis(disassembly) langsung pada

biner program hingga memasukkanya dalam ruang lingkup debugger. Beberapa

reverse engineer melakukan instrumentasi atau menyisipkan program bantuan

untuk melakukan analisis secara otomatis dan bermain di area memori. Untuk

reverse engineer yang tidak biasa dengan hal tersebut biasanya menggunakan

intermediate representation sebagai acuan dalam mengolah data yang menjadi

(36)

23

BAB III

ANALISIS SELF-MODIFYING CODE DAN PERANCANGAN

DYNAMIC BINARY INSTRUMENTATION

III.1 Analisis Sistem

Subbab analisis ini membahas mengenai analisis masalah, analisis biner

program, analisis kebutuhan nun fungsional, analisis teknik Self-Modifying Code

dan perancangan Dynamic Binary Instrumentation.

III.1.1 Analisis Masalah

Masalah yang menjadi latar belakang pada penelitian ini adalah bagaimana

menganalisis Self-Modifying Code setelah dikompilasi ke dalam biner program

untuk memahami cara kerjanya menggunakan metode DBI(Dynamic Binary

Instrumentation). Adapun spesifikasi masalah adalah pengaruh Self-Modifying

Code sebagai usaha anti analisis dalam membuat proses debugging menjadi sulit,

kendala Dynamic Binary Instrumentation dalam menganalisis program serta

konfigurasi environment yang berbeda-beda.

III.1.2 Analisis Biner Program

Analisis Biner adalah proses menganalisis dan menggambarkan

bagaimana program dalam bekerja menjalankan tugasnya. Teknik analisis biner

memiliki ruang lingkup yang luas. Selain meliputi biner yang melibatkan sistem

operasi, analisis biner juga memodelkan aspek–aspek yang terkait dengan

instruksi independen arsitektur. Instruksi yang perlu diketahui untuk menganalisis

program Self-Modifying Code adalah transfer kontrol tidak kondisional seperti:

Tabel III.1 Transfer Kontrol

Instruksi Keterangan

JMP JMP(Jump) adalah transfer kontrol satu arah dan tidak menyimpan alamat

(37)

CALL CALL(Call Procedure) mendorong alamat kembali ke stack dan transfer

kontrol ke prosedur

RET RET(Return From Procedure) memunculkan alamat kembali dari stack dan

mengembalikan kontrol ke lokasi tersebut

Tidak ada urutan standar dalam analisis biner karena setiap proses debugging

adalah seni. Adapun langkah-langkah yang diambil untuk analisis biner

Self-Modifying Code dengan Dynamic Binary Instrumentation adalah sebagai berikut:

1. Memeriksa fungsi de-obfuscation routine dengan disassembly secara statis.

Hal ini dapat dilakukan dengan alat seperti objdump maupun debugger seperti

GDB.

2. Setelah mengetahui fungsi dimana terjadi Self-Modifying Code, dilakukan

pembangunan instrumentasi untuk memonitoring fungsi tersebut.

3. Selanjutnya program Self-Modifying Code dijalankan dengan invokasi

instrumentor dalam hal ini DynamoRIO

4. Setelah hasil analisis berupa keluaran intermediate reprsesentation

dilanjutkan dengan membuat script sederhana atau patcher untuk

memecahkan Self-Modifying Code tersebut

5. Membuat laporan cara kerja dengan teliti apa yang sebenarnya dilakukan oleh

kesuluruhan program

III.1.3 Analisis Teknik Self-Modifying

Self-Modifying Code yang dianalisis merupakan perspektif telah menjadi

program executable artinya tidak ada akses untuk sumber kode. Informasi yang

tersedia hanya kode assembly pada biner dimana setiap routine harus

diidentifikasi terlebih dahulu untuk mendapatkan fungsi yang mengolah

modifikasi. Terdapat tiga kasus yang akan diuji diantara lain Self-Checksumming,

(38)

1. Self-Checksumming

Program Self-Modifying yang memverifikasi keaslian kode selama eksekusi

terdapat sisipan produser kode perhitungan checksum. Sebuah algoritma

checksum menghitung hash melewati berbagai kode kritis yang tidak boleh

diubah. Verifikasi tersebut membandingkan hasil perhitungan checksum terhadap

nilai yang tertera secara hard-coded dalam fungsi program. Kegagalan verifikasi

menunjukkan dugaan modifikasi dari program dimana integritas tidak lagi

terjamin.

Dimisalkan sebuah program yang dapat dijalankan hanya dengan adanya

lisensi yang valid. Program harus dapat melindungi modifikasi kode yang

melakukan cek lisensi. Reverse engineer mungkin menghapus fungsi pengecekan

lisensi tersebut dengan cukup memasukkan instruksi jump pada kode dimana cek

lisensi berada. Artinya pengecekan dilewati atau tidak dieksekusi sama sekali.

Adapun contoh self-checking checksum dapat dilihat pada pseudocode berikut:

Selfcheck(checksum, nonce, codeStart, codeEnd,

codeSize) {

while (iteration < 2500000)

{

eksekusi. Bagian codeStart, codeEnd dan codeSize didefinisikan pada seksi

(39)

2. Self-Decrypting

Idealnya perangkat lunak yang mendekripsi bagian dirinya hanya berisi

decryptor stub (informasi yang digunakan untuk mendekripsi) dan kode yang

terenkripsi. Ada banyak varian dari metode enkripsi, beberapa diantaranya

cendrung statis (dengan kunci dekripsi) dan yang lainnya dengan polymorphic

atau mengubah kunci dekripsi. Hal ini dilakukan dalam rangka untuk membuat

ruang lingkup debugger atau emulasi pada antivirus berhenti. Adapun klasifikasi

enkripsi biner dibedakan berdasarkan bagaimana kode tersebut didekripsi yaitu:

1. Dengan kunci statis (dekripsi routine sangat mudah dimengerti)

2. Kunci yang berubah-ubah sewaktu-waktu(looping dengan increment +1,

mudah dimengerti namun sedikit kerja ekstra untuk reverse engineer)

3. Tanpa kunci atau hanya operasi bit (contoh instruksi circular shift atau

penggeseran seperti not, rol, ror, x-bit swap)

4. Kunci dengan eksternal dependensi(Berganti terus menerus dan tidak

mempunyai pola spesifik seperti pada pengalamatan modul poin entri atau

alamat virtual di memori untuk executable)

5. Tanpa kunci sama sekali(kode dekripsi didapatkan dengan brute force)

Cryptanalysis dapat dilakukan dengan menggunakan metode Stream Cipher

Attack atau memanfaatkan informasi yang muncul berkali-kali. Adapun kasus

polymorphic self-decryption dapat dilihat pada pseudocode assembly berikut:

LEA SI,...

Berdasarkan kode diatas kunci dekripsi akan berganti dengan multiple

execution dikarenakan stack pointer diinilisiasi sebelum looping. Berdasarkan

(40)

byte,word dan dword sebagai kunci atau kode metadata seperti alamat relative

dan absolute pada memori sebagai kuncinya untuk enkripsi yang lebih baik.

3. Self-Extracting

Sederhananya Self-Extracting melakukan unpacking satu atau lebih segmen

yang mengandung data konstan ke dalam blok yang dialokasikan pada memori

executable dan kemudian memulai proses langsung melompat pada kode

sebenarnya. Dengan kata lain sama seperti self-decrypting dimana terdapat

decompressor dan program loaders. Self-Extracting dibangun menggunakan

packers yaitu UPX(Ultimate Packer for eXecutable).

Ketika packing executable menggunakan UPX, semua seksi seperti .text dan

.data dikompresi dengan penamaan UPX0, UPX1 dan seterusnya. Kemudian UPX

menambahkan seksi kode diakhir yang mengandung keseluruhan dekompresi saat

eksekusi. Berikut ini langkah-langkah yang dilakukan oleh UPX:

1. Eksekusi dimulai dengan OEP(Original Entry Point) baru

2. Menyimpan status register menggunakan instruksi PUSHAD

3. Semua packed atau pemadatan di-unpack dalam memori

4. Memuat kembali alamat import table orisinil dari file executable

5. Memuat kembali status register asli menggunakan instruksi POPAD

(41)

III.1.4 Analisis Binary Translation

Program yang emodifikasi bagian dirinya menimbulkan masalah ketika

kode yang telah diterjemahkan berganti menjadi program asing. Jika binary

translators tidak menyadari akan hal tersebut, binary translator akan

mengeksekusi kode asal saat sebelum diterjemahkan. Analisis Binary Translation

dilakukan berkenaan dengan desain keluaran yang akan dihasilkan berupa

representasi bahasa pemograman tingkat menengah.

Performansi pada proses translasi biner juga patut diperhatikan. Adapun

konsep yang dapat mempengaruhi proses translasi biner menjadi cepat atau

bahkan lamban adalah sebagai berikut:

1. Looping Translation

Proses penerjemahan berjalan pada unit dasar blok. Sebuah blok dasar

adalah aliran langsung instruksi dengan instruksi cabang (JMP, call, dll) di

tail namun bukan di dalam fungsi. Sebuah blok dasar diterjemahkan dapat

langsung dijalankan pada CPU. Ketika instruksi branch terakhir

dijalankan, kemudian ditentukan apakah target branch sudah

diterjemahkan. Jika iya, Translator hanya bisa melompat disana. Jika

tidak, Translator harus menerjemahkan blok dasar pertama. Panggilan

untuk mengirimkan trampolin ditambahkan ke setiap blok dasar yang

diterjemahkan.

for (;;) {

if (!(translated_pc = find_translation(pc)) translated_pc = translate_basic_block(pc); execute(translated_pc);

}

2. Direct Branch

Branch langsung adalah jika target dapat ditentukan pada saat

penerjemahan. Misalnya, memanggil fungsi tetap merupakan branch

langsung. Jika hanya ada satu target yang deterministik untuk branch

maka penerjemahan akan sangat mudah untuk dioptimalkan. Ketika

(42)

dahulu apakah sudah dijalankan. Jika iya, binary translator dapat dengan

mudah meng-encode target branch. Jika tidak, bangun trampolin seperti:

push $patch_addr push $target_pc

jmp dbt_find_direct_internal

Dimana patch_addr adalah pointer ke target branch langsung dalam

instruksi branch asli. dbt_find_direct_internal adalah fungsi perakitan

untuk menyimpan dan memulihkan konteks program. Ketika fungsi

tersebut dipanggil selanjutnya adalah menerjemahkan blok dasar yang

hilang dengan menerjemahkan translated_pc ke patch_addr. Oleh karena

itu ketika instruksi branch asli ditemui kedua kalinya, langsung melompat

ke target yang benar tanpa overhead.

3. Indirect Branch

Karena Branch tidak langsung tidak dapat ditentukan pada saat

penerjemahan maka, diselesaikan pada saat runtime. Efektivitasnya

langsung mempengaruhi kinerja sistem DBT.

4. Return Handling

Instruksi ret adalah bentuk khusus dari percabangan tidak langsung yang

sangat mudah diprediksi. Beberapa sistem DBT menggunakan pendekatan

"fast return" untuk meminimalkan terjadinya overhead. Ketika call

dijalankan, binary translator mendorong alamat pengirim yang

diterjemahkan, bukan alamat pengirim asli untuk stack. Masalah utama

dari pendekatan ini adalah tidak transparan untuk aplikasi pokok, dan fitur

tertentu seperti exception handling akan gagal jika alamat kembali diubah.

DynamoRIO menerapkan teknik yang disebut "return cache". Kembalinya

cache bermaksud tabel hash terdiri dari pemetaan dari alamat kembali. Setiap

hash bucket memiliki hanya satu entri. Ketika instruksi panggilan dijalankan, pc

yang diterjemahkan dari alamat pengirim ditulis ke hash table bucket. Ketika

instruksi kembali dijalankan, alamat pengirim di stack diiris dan melompat masuk

(43)

Untuk menangani kasus ini, sebuah stub sederhana ditambahkan setelah instruksi

panggilan.

1. Call return pair optimization

CPU modern memiliki mekanisme prediksi branch yang maju untuk

meningkatkan efisiensi eksekusi. Salah satu optimasi tersebut disebut "return

stack buffer". Hal tersebut merupakan ring buffer yang mirip dengan alamat

kembali cache. Ketika instruksi call dijalankan, alamat kembali dimasukkan ke

buffer. Ketika instrruksi ret dijalankan, tumpukan atas muncul dan digunakan

sebagai prediksi alamat target. Untuk mengambil keuntungan dari ini, instruksi

call dan ret harus dalam pasangan. Dalam sistem penerjemahan biner tradisional

dinamis dua instruksi tersebut biasanya diimplementasikan menggunakan

instruksi jmp ke berbagai trampolin yang benar-benar hilang optimasinya dari

return stack buffer.

2. CPUID Emulation

Karena setiap instruksi harus secara eksplisit diharapkan agar bekerja

seluruhnya. Informasi CPUID tidak dapat ditinggalkan dari host langsung ke

target aplikasi. Pertimbangan dukungan instruksi khusus seperti AVX langsung

menggunakan CPUID asli yang membuat aplikasi berpikir dapat menggunakan

instruksi AVX. Oleh karena itu binary translator harus mencegat instruksi

CPUID dan menutupi keluar fitur tersebut.

III.1.5 Analisis Sintaksis

Parsing atau Syntatic Analysis menggunakan DCFG(Dynamic

Control-Flow Graph) yang mana menambahkan data dari sebuah spesifik eksekusi

program. Biasanya CFG didefinisikan secara statis dan tidak mengandung

informasi tentang jalur eksekusi dari setiap beban kerja tertentu. Adapun

kelebihan DCFG antara lain:

1. Sebuah DCFG berisi node awal yang tidak memiliki node pendahulu

dan pengganti node-nya berisi instruksi pertama yang dieksekusi per

(44)

penerus dan pendahulunya berisi instruksi terakhir yang dieksekusi

per thread.

2. Setiap edge DCFG ditambah dengan jumlah yang dinamis untuk

menunjukkan berapa kali dilalui per thread oleh eksekusi program

yang diberikan. Kecuali untuk awal dan akhir node, hitungan dinamis

setiap node adalah sama dengan jumlah dari semua edge yang masuk,

yang juga sama dengan jumlah dari semua edge keluar nya.

3. Sebuah DCFG tidak perlu mengandung node atau edge yang tidak

dieksekusi. Sebuah DCFG diperbolehkan mengandung node dan edge

yang tidak dieksekusi atau hanya akan memiliki jumlah nol.

4. Sebuah DCFG berisi edge yang mewakili semua jalur kode eksekusi

sebenarnya, bahkan untuk non-control-flow. Sebagai contoh, sebuah

instruksi floating-point yang menyebabkan pengecualia selama

eksekusi dapat menciptakan keunggulan untuk kode

exception-handling.

Blok di DCFG dapat dikombinasikan menjadi tingkat yang lebih tinggi untuk

konstruksi seperti perulangan, rutinitas dan biner images. Data dinamis seperti

jumlah iterasi loop dapat disimpulkan dari jumlah edge dasar. Format DCFG

memungkinkan penyimpanan informasi pada proses, termasuk images konstituen,

simbol, data debug, dan kontrol.

Jenis dari elemen dideskripsikan menggunakan format JSON yang

mempunyai list untuk setiap strukturnya. Hal tersebut nantinya disimpan

sementara dalam memori untuk mempermudah penerjemahan biner dalam hal

parsing. Adapun spesifikasinya sebagai berikut:

1. Top-level structure

Nilai dari Top-level adalah sebuah objek atau urutan pasangan nilai kunci.

Bagian utama dari aliran DCFG ditandai dalam objek tingkat atas yang

terdaftar secara singkat dibawah dan diperluas dalam sisa dokumen berikut

(45)

1. Versi format

2. Daftar pengidentifikasi (id) digunakan untuk referensi string kemudian

di-stream seperti nama file, jenis edge dan node khusus.

3. Data proses berisi id, jumlah instruksi per-thread, serta daftar images

dari biner seperti alamat dan ukuran Load, daftar simbol, sumber

berkas, garis nomor debug data, daftar node blok dasar, daftar rutinitas

dan loop konstituen.

2. Versi

Versi mayor dan minor dari format file terdaftar sebagai dua tag terpisah

di objek tingkat atas. Maksudnya adalah bahwa format DCFG akan kemabali

dan maju secara kompatibel sebanyak mungkin. Kompatibilitas berarti bahwa

versi ke depan tidak harus mengubah tag yang telah ditentukan atau

menghapus data non-opsional. Kompatibilitas ke depan berarti bahwa

penambahan harus dilakukan parser untuk format yang sudah ada harus

mampu membaca format ke depan jika mengabaikan tag yang diketahui.

Jika kompatibilitas rusak, atau jika fitur baru utama ditambahkan, nomor

versi utama harus bertambah dan nomor versi minor ulang ke nol. Jika tidak,

perubahan format lain dibuat nomor versi minor yang bertambah. Ketika

dikonversi ke teks, versi mayor dan versi minor dipisahkan oleh sebuah titik

(".") dan versi minor harus ditampilkan sebagai dua digit yang memungkinkan

hingga versi 99 tanpa kebingungan karena nilai tempat desimal, misalnya 2.03

mendahului 2.12.

3. Nama File

Daftar nama file yang digunakan untuk menghemat ruang adalah dengan

mengizinkan nama file direferensikan nanti oleh pengidentifikasi bilangan bulat,

bukan string panjang yang mungkin perlu diulang berkali-kali. Adapun yang

(46)

1. Seperti layaknya semua string, karakter khusus harus lolos memenuhi

format string JSON.

2. Parsers tidak boleh berasumsi bahwa id mulai dengan satu atau berurutan

dalam pemesanan tertentu.

3. Semua nama file yang digunakan dalam aliran DCFG disimpan dalam

tabel yang sama, termasuk untuk images dan file sumber.

4. Jenis Edge

Daftar jenis edge digunakan untuk menghemat ruang dengan mengizinkan

jenis edge untuk kemudian direferensikan dengan pengenal bilangan bulat, bukan

string yang seharusnya perlu diulang berkali-kali. Adapun jenis string edge yang

telah ditentukan dapat dilihat pada tabel berikut:

Tabel III.2 Nilai String Jenis Edge

Nilai String Jenis Edge Keterangan

ENTRY Edge pertama dilalui dalam DCFG yang menjadi

tanda dari mulainya node ke blok dasar pertama

eksekusi

EXIT Edge terkahir dilalui dalam DCFG yang menjadi

tanda dari berakhirnya node ke blok dasar akhir

eksekusi

BRANCH Mewakilkan semua branch yang tidak diketahui

CONDITIONAL_BRANCH Mewakilkan semua jenis conditional branch baik

direct maupun indirect

UNCONDITIONAL_BRANCH Mewakilkan semua jenis unconditional branch baik

direct maupun indirect

DIRECT_BRANCH Sebuah direct untuk conditional branch

(47)

DIRECT_CONDITIONAL_BRANCH Sebuah direct untuk conditional branch

INDIRECT_CONDITIONAL_BRANCH Sebuah indirect untuk conditional branch

DIRECT_UNCONDITIONAL_BRANCH Sebuah direct untuk unconditional branch

INDIRECT_UNCODITIONAL_BRANCH Sebuah indirect untuk unconditional branch

REP Sebuah Edge yang mengindikasikan sebuah

instruksi dengan prefix “REP” atau repeated.

FALL_THROUGH Sebuah Edge yang mengindikasikan instruksi pada

alamat selanjutnya telah dieksekusi.

CALL Mewakilkan semua jenis call yang tidak diketahui

DIRECT_CALL Sebuah direct call yang mempunyai satu alamat

statis

INDIRECT_CALL Sebuah indirect call yang mempunyai satu alamat

dinamis

RETURN Sebuah return biasanya dipanggil dari routine

CALL_BYPASS Mengindikasikan control flow dalam sebuah routine

tanpa diikuti call

SYSTEM_CALL Sebuah call khusus ke sistem routine

SYSTEM_RETURN Sebuah return dari sistem routine

SYSTEM_CALL_BYPASS Sama seperti CALL_BYPASS akan tetapi untuk

sistem routine

CONTEXT_CHANGE Sebuah Edge yang dibuat dari semua instruksi

non-control-flow

CONTEXT_CHANGE_RETURN Sebuah return dari handler context-change

CONTEXT_CHANGE_BYPASS Sama seperti CALL_BYPASS akan tetapi untuk

handler context-change

EXCLUDED_CODE_BYPASS Sebuah Edge yang digunakan untuk memlihara

control flow yang tidak termasuk wilayah kode dari

(48)

5. Node Khusus

Daftar node khusus digunakan untuk menghemat ruang dengan mengizinkan

node yang akan kemudian direferensikan oleh pengidentifikasi bilangan. Berikut

yang harus diperhatikan adalah:

1. Parser tidak boleh berasumsi bahwa id dimulai dengan satu atau berurutan

dalam urutan tertentu.

2. Parser tidak boleh berasumsi bahwa id tetap atau sama antara DCFG.

Misalnya node “START” mungkin memiliki id=1 dalam satu DCFG dan

id=3 di lain.

6. Data Proses

Semua data untuk proses disimpan dalam objek yang muncul di kolom

PROCESS_DATA dari tabel PROSES. Kunci dalam objek dapat dilihat pada

table sebagai berikut:

Tabel III.3 Proses Objek

Proses Objek Nilai

INSTR_COUNT Integer: jumlah instruksi untuk proses yang melewati

seluruh thread

INSTR_COUNT_PER_THREAD Array: Setiap integer dari setiap jumlah insruksi untuk

proses per-thread

IMAGES Tabel image

EDGES Tabel edge

7. Images

Semua images untuk suatu proses yang disimpan dalam tabel muncul setelah

(49)

Tabel III.4 Images

Heading Nilai

IMAGE_ID Integer dapat dimulai dengan nol

LOAD_ADDR Sebuah integer yang mengandung alamat base yang dimuat oleh sistem

operasi

SIZE Sebuah integer yang mengandung ukuran image

IMAGE_DATA Sebuah objek JSON yang mengandung data image

8. Simbol

Semua simbol untuk images yang diberikan, disimpan dalam tabel yang

muncul setelah kunci SYMBOLS dalam data objek images. Adapun

klasifikasinya sebagai berikut:

Tabel III.5 Simbol Images

Heading Nilai

NAME String yang mengandung nama simbol

ADDR_OFFSET Integer yang mengandung alamat base dari relativitas simbol ke alamat load

yang mengandung image

SIZE Sebuah integer yang mengandung ukuran simbol dalam bytes

9. Informasi Sumber

Semua informasi sumber debug images yang diberikan, disimpan dalam tabel

yang muncul setelah kunci SOURCE_DATA dalam data objek images simbol.

(50)

Tabel III.6 Informasi Sumber

Heading Nilai

FILE_NAME_ID Integer id dari nama file tabel yang mempresentasikan file sumber kode

dari data debug

LINE_NUM Sebuah integer yang mempresentasikan garis nomor file referensi sumber

kode

ADDR_OFFSET Sebuah integer yang mengandung alamat base dari relativitas data debug

yang mengandung image

SIZE Sebuah integer yang mengandung ukuran data dalam bytes

NUM_INSTR Sebuah integer yang mengandung angka dari instruksi oleh data debug

10.Blok Dasar

Semua blok dasar untuk images yang diberikan, disimpan dalam tabel yang

muncul setelah kunci BASIC_BLOCKS dalam images objek data informasi

sumber. Sebuah blok dasar hanya memiliki satu poin entri dan satu titik keluar.

Dasar blok didefinisikan secara dinamis, sehingga dapat bervariasi dari run-to-run

pada beban kerja yang sama, hal ini bergantung pada edge dalam CFG yang

dilalui. Variasi tersebut dapat mencakup tidak hanya blok dasar yang disertakan

tetapi juga awal dan akhir alamat masing-masing. Adapun klasifikasinya dapat

(51)

Tabel III.7 Blok Dasar

Heading Nilai

NODE_ID Sebuah integer id dan harus unik menyeluruh pada proses, tidak

hanya image

ADDR_OFFSET Sebuah integer yang mengandung instruksi pertama dalam relativitas

blok dasar ke alamat load dari image

SIZE Sebuah integer yang mengandung ukuran blok dala bytes

NUM_INSTRS Sebuah integer yang mengandung angka instruksi dalam blok

LAST_INSTR_OFFSET Sebuah integer yang mengandung alamat instruksi akhir dalam

relativitas blok dasar ke alamat pertama instruksi

COUNT Sebuah integer yang mengandung jumlah angka dari waktu blok

yang telah dieksekusi menyeluruh pada thread

11.Routines

Semua informasi rutin untuk images yang diberikan, disimpan dalam tabel

yang muncul setelah kunci ROUTINES dalam data objek images blok dasar.

Rutinitas harus mengikuti aturan berikut:

1. Sebuah routine dapat memiliki hanya satu entri (routine dapat memiliki

beberapa poin exit)

2. Setiap node dalam routines harus dicapai dari entri node. Hal ini berarti

bahwa setiap node harus menjadi penerus langsung (target edge) dari entri

node atau node lain dalam routines. Edge antar routine (call, returns,

context changes, dll) tidak diperbolehkan dalam traversal tersebut.

Namun, setiap node yang dicapai dari entri node tidak diperlukan untuk

berada di routines yang sama. Hal tersebut memungkinkan untuk

pembagian routines ketika ada beberapa node masuk, melompat antara

(52)

3. Setiap node dalam routines harus dalam images yang dikandung.

4. Setiap simpul dari suatu images (kecuali awal dan akhir) akan muncul di

tepat satu routine.

Dengan demikian alamat dan ukuran routines tidak akan selalu sesuai dengan

yang ada di tabel simbol. Routines juga dapat dimasukkan dengan edge selain

calls dan dapat keluar selain returns. Adapun spesifikasinya dapat dilihat pada

tabel berikut:

Tabel III.8 Routines

Heading Nilai

ENTRY_NODE_ID Sebuah integer id dari blok dasar

EXIT_NODE_IDS Array dari id blok dasar yang mengindikasikan satu atau lebih edges

yang meninggalkan routine

NODES Tabel node

12.Loops

Semua informasi loop untuk routine disimpan dalam tabel yang muncul di

bawah kolom LOOPS dalam tabel routine. Loop didefinisikan dengan algoritma

standar graph-traversal. Kendala tersebut dapat diberlakukan sebagai berikut:

1. Sebuah loop hanya dapat memiliki satu head node

2. Sebuah loop dapat memiliki beberapa back-edge

Gambar

Gambar I.1 Proses DynamoRIO
Gambar II.1 ELF Diagram
Gambar II.2 DynamoRIO Benchmark
Tabel III.1 Transfer Kontrol
+7

Referensi

Dokumen terkait

dengan kode sumber yang berkarakteristik sekuen, menggunakan algoritma adaptive local alignment dan pendekatan bahasa menengah dapat mendeteksi kemiripan antar program

pemrosesan gambar menggunakan alat pemindai (scanner) atau perangkat kamera pada komputer yang telah terintegrasi dengan program tertentu yang telah dibuat dan

Sistem presensi siswa menggunakan kode QR berbasis Android ini dapat digunakan untuk melakukan presensi siswa dengan membaca kode QR pada kartu siswa sebagai data kehadiran

Dari semua simulasi yang dilakukan pada sistem IEEE 30 bus dengan 6 unit pembangkit, terlihat bahwa terdapat selisih biaya pembangkitan antara UC, SCUC Normal, dan SCUC

Sistem presensi siswa menggunakan kode QR berbasis Android ini dapat digunakan untuk melakukan presensi siswa dengan membaca kode QR pada kartu siswa sebagai data kehadiran

Nordrassil Project adalah web yang dapat menciptakan DDL maupun kode sumber aplikasi basis data. Tujuan dari penelitian ini adalah untuk membantu programmer, atau

· Pembentukan dan penyisipan kode autentikasi dapat dilakukan dengan melakukan pengolahan bit dan disisipkan pada bit paritas dari berkas yang dihasilkan pada Program

Pentingnya dilakukan analisis ketepatan pengisian kode diagnosis pada dokumen rekam medis karena apabila kode diagnosis tidak tepat atau tidak sesuai dengan ICD-10 maka dapat