HTCinside



5 Teknik Anti Debugging yang Akan Melindungi Perangkat Lunak Anda

Saat menerbitkan produk perangkat lunak kami, kami semua menggunakannya untuk menulis dalam EULA “Anda tidak boleh merekayasa balik, mendekompilasi, atau membongkar Perangkat Lunak”. Namun dalam banyak situasi, kata-kata bukanlah perlindungan terbaik dan Anda benar-benar perlu memperkenalkan beberapa alat teknis untuk mencegah pembalikan perangkat lunak dan melindungi pengetahuan Anda agar tidak diungkapkan.

Ada beberapa pendekatan teknologi untuk mencegah rekayasa balik perangkat lunak: anti-debug, anti-dump, dan lain-lain. Dalam posting ini, kami akan fokus pada beberapa metode anti-debug, karena metode tersebut merupakan inti dari perlindungan anti-reverse-engineering. Melampirkan debugger ke proses yang diteliti untuk menjalankannya selangkah demi selangkah adalah tahap yang sangat penting dari setiap pekerjaan pembalikan – jadi mari kita lihat alat apa yang dapat kita gunakan untuk membuat hidup pembalik lebih sulit.


Ada beberapa hal yang ingin saya sebutkan di awal. Yang pertama adalah bahwa tidak ada perlindungan antipeluru universal atau 100% dari rekayasa balik perangkat lunak. Selalu ada cara bagi pembalik untuk masuk, satu-satunya strategi yang kami miliki adalah membuat pekerjaannya sekeras dan menghabiskan tenaga sebanyak mungkin.

Selanjutnya, ada beberapa teknik anti reverse engineering dan khususnya metode anti-debug, termasuk perlindungan berbasis waktu atau bahkan teknologi khusus yang disematkan kode seperti nanomit. Dalam posting ini, kami hanya akan mempertimbangkan beberapa pendekatan standar khusus untuk sistem berbasis Windows, yang paling populer.

Pendekatan yang diwakili di bawah ini dijelaskan secara umum.

Isi


Isi

  1. Fungsi bawaan untuk memeriksa keberadaan debugger
  2. Menyembunyikan utas
  3. Tandai Cek
  4. Deteksi titik putus
  5. Penanganan Pengecualian: SEH
  6. Kesimpulan

1 – Fungsi bawaan untuk memeriksa keberadaan debugger

Sistem Windows memberi kami beberapa alat siap pakai untuk membangun perlindungan anti-debug sederhana. Salah satu teknik anti debug paling sederhana didasarkan pada pemanggilan fungsi IsDebuggerPresent. Fungsi ini mengembalikan TRUE jika debugger mode pengguna sedang men-debug proses.

Fungsi ini mengacu pada PEB (Process Environment Block, struktur sistem tertutup) dan khususnya bidang BeingDebugged-nya. Pembalik ketika melewati teknik perlindungan tersebut menggunakan fakta ini: mis. menerapkan injeksi DLL, mereka mengatur nilai BeingDebugged ke 0 tepat sebelum pemeriksaan ini dilakukan dalam kode yang dilindungi.

Beberapa kata tentang di mana melakukan pemeriksaan tersebut. Fungsi utama bukanlah pilihan terbaik: pembalik biasanya memeriksanya terlebih dahulu dalam daftar yang dibongkar. Lebih baik melakukan pemeriksaan anti-debug di TLS Callback, seperti yang dipanggil sebelum titik panggilan masuk dari modul utama yang dapat dieksekusi.

Opsi pemeriksaan fungsional lainnya adalah CheckRemoteDebuggerPresent. Berbeda dengan fungsi yang dijelaskan di atas, ia memeriksa apakah proses paralel lain sedang men-debug suatu proses. Ini didasarkan pada fungsi NtQueryInformationProcess dan khususnya nilai ProcessDebugPort.


2 – Menyembunyikan utas

Sementara kelompok metode sebelumnya dibangun untuk memeriksa keberadaan debugger, yang satu ini akan memberikan perlindungan aktif darinya.

Dimulai dengan Windows 2000, fungsi NtSetInformationThread menerima bendera baru bernama ThreadHideFromDebugger. Ini adalah teknik anti debugging yang sangat efisien yang disediakan di OS Windows. Sebuah utas dengan set bendera ini berhenti untuk mengirim pemberitahuan acara debug, termasuk breakpoints dan lainnya sehingga menyembunyikan dirinya dari debugger apa pun. Menyiapkan ThreadHideFromDebugger untuk utas utama akan secara signifikan memperumit proses melampirkan debugger ke utas.

Kelanjutan logis diperkenalkan di Windows Vista dengan fungsi NtCreateThreadEx. Ini memiliki parameter CreateFlags, yang mengatur antara lain flag THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER. Proses dengan flag set ini akan disembunyikan dari debugger.

3 – Pemeriksaan Bendera

Menjalankan debugging dapat dideteksi oleh nilai yang berubah dari flag yang berbeda di berbagai sistem dan struktur proses.


Windows NT menyertakan variabel global bernama NtGlobalFlag dengan satu set flag, yang digunakan untuk penelusuran sistem dan debug. Struktur PEB yang disebutkan di atas mencakup bidang NtGlobalFlag-nya sendiri. Selama debug, nilai bidang ini diubah dengan beberapa set bendera tertentu. Memeriksa tanda ini dapat menghasilkan pemicu untuk perlindungan anti-debugging.

Eksekusi dapat mengatur ulang flag NtGlobalFlag dari struktur PEB melalui struktur khusus bernama IMAGE_LOAD_CONFIG_DIRECTORY, yang berisi parameter konfigurasi khusus untuk pemuat sistem. Ini memiliki bidang GlobalFlagsClear, yang mengatur ulang flag NtGlobalFlag dari PEB. Secara default, struktur ini tidak ditambahkan ke executable, tetapi dapat ditambahkan nanti. Fakta bahwa executable tidak memiliki struktur ini atau nilai GlobalFlagsClear sama dengan 0, sedangkan bidang terkait yang disimpan di disk atau di memori proses yang sedang berjalan tidak nol, menunjukkan adanya debugger tersembunyi. Pemeriksaan ini dapat diimplementasikan dalam kode yang dapat dieksekusi.

Grup flag lainnya adalah heap proses. Ada dua bidang dalam struktur _HEAP yang sesuai: Flags dan ForceFlags. Keduanya mengubah nilainya ketika proses yang sesuai di-debug dan dengan demikian dapat menjadi dasar pemeriksaan dan perlindungan anti-debug.

Satu lagi pemeriksaan flag, yang dapat digunakan untuk mendeteksi debugger, adalah pemeriksaan Trap Flag (TF). Itu ada di register EFLAGS. Ketika TF sama dengan 1, CPU menghasilkan INT 01h (pengecualian «Single Step») setelah setiap eksekusi instruksi yang mendukung proses debugging.

4 – Deteksi titik putus

Breakpoints adalah bagian penting dari setiap proses debugging dan dengan demikian mendeteksi mereka, kami dapat mendeteksi dan menetralisir debugger. Taktik anti debugging berdasarkan deteksi breakpoint adalah salah satu yang paling kuat dan sulit untuk dilewati.

Ada dua jenis breakpoint: perangkat lunak dan perangkat keras.

Breakpoint perangkat lunak diatur oleh debugger dengan menyuntikkan instruksi int 3h ke dalam kode. Dengan demikian, metode deteksi debugger didasarkan pada penghitungan dan kontrol checksum dari fungsi yang sesuai.

Tidak ada metode universal untuk melawan perlindungan ini – seorang peretas harus menemukan potongan kode yang menghitung checksum dan mengganti nilai yang dikembalikan dari semua variabel terkait.

Breakpoint perangkat keras diatur menggunakan register debug khusus: DR0-DR7. Dengan menggunakannya, pengembang dapat mengganggu eksekusi program dan mentransfer kontrol ke debugger. Perlindungan anti-debug dapat dibangun dengan memeriksa nilai-nilai register ini atau menjadi lebih proaktif dan secara paksa mengatur ulang nilainya untuk menghentikan debugging menggunakan fungsi SetThreadContext.

5 – Penanganan Pengecualian: SEH

Penanganan Pengecualian Terstruktur atau SEH adalah mekanisme yang memungkinkan aplikasi menerima pemberitahuan tentang situasi luar biasa dan menanganinya alih-alih sistem operasi. Pointer ke SEH handler diberi nama SEH frames dan ditempatkan ke stack. Ketika sebuah eksepsi dibangkitkan, ia ditangani oleh frame SEH pertama dalam stack. Jika tidak tahu apa yang harus dilakukan dengannya, itu diteruskan ke yang berikutnya di tumpukan dan seterusnya sampai penangan sistem.

Saat aplikasi sedang di-debug, debugger harus mencegat kontrol setelah generasi 3 jam int, atau penangan SHE akan mengambilnya. Ini dapat digunakan untuk mengatur perlindungan anti-debug: kita dapat membuat penangan SEH kita sendiri dan meletakkannya di atas tumpukan dan kemudian memaksa generasi int 3h. Jika penangan kami mendapatkan kontrol, prosesnya tidak di-debug – jika tidak, kami dapat memaksa tindakan anti-debug saat kami mendeteksi debugger.

Kesimpulan

Ini hanyalah beberapa teknik anti-debugging dari berbagai macam teknik tersebut.

Praktik yang baik adalah menggabungkan berbagai teknik anti pembalikan sehingga lebih sulit untuk melewati perlindungan. Pemeriksaan tambahan dapat memperlambat eksekusi aplikasi, itulah sebabnya teknik perlindungan terkuat biasanya diterapkan pada modul inti yang berisi teknologi dan pengetahuan yang dipatenkan. Akhirnya, ini adalah trade-off antara tingkat keamanan kode dan kinerja aplikasi.

Saya ingin menyebutkan bahwa rekayasa balik perangkat lunak tidak selalu ilegal dan terkadang dapat diterapkan selama proses penelitian untuk tugas-tugas seperti peningkatan kompatibilitas, patching, penggunaan antarmuka sistem yang tidak berdokumen, dll. Layanan rekayasa balik hukum disampaikan oleh para profesional juga menangani perlindungan anti-debugging tetapi dari sisi lain – melewatinya.