Inline Hooking

Juli 17, 2018 | ,

Apa itu Inline hooking ? 
Inline hooking adalah metode mencegat panggilan ke fungsi target, yang terutama digunakan oleh antivirus, sandbox, dan malware. Gagasan umum adalah untuk mengarahkan fungsi ke kita sendiri, sehingga kita dapat melakukan pemrosesan sebelum dan / atau setelah fungsi melakukan fungsinya; ini bisa termasuk: memeriksa parameter, shimming, logging, spoofing mengembalikan data, dan menyaring panggilan. Rootkit cenderung menggunakan Hooking untuk mengubah data yang dikembalikan dari panggilan sistem untuk menyembunyikan kehadirannya, sementara perangkat lunak keamanan menggunakannya untuk mencegah / memantau operasi yang berpotensi jahat. Hook ditempatkan dengan memodifikasi kode secara langsung dalam fungsi target (modifikasi inline), biasanya dengan menimpa beberapa byte pertama dengan lompatan; ini memungkinkan eksekusi untuk diarahkan sebelum fungsi melakukan pemrosesan apa pun. Kebanyakan mesin hooking menggunakan lompatan relatif 32-bit (opcode 0xE9), yang mengambil 5 byte ruang.




Bagaimana itu bekerja
Kami akan menggunakan hook berbasis trampolin, yang memungkinkan kami untuk mencegat fungsi, sementara masih dapat memanggil yang asli (tanpa melepasnya terlebih dahulu). hook ini terdiri dari 3 bagian:
  1. The Hook - Sebuah lompatan relatif 5 byte yang ditulis ke fungsi target untuk mengaitkannya, lompatan akan melompat dari fungsi yang terhubung ke kode kita.
  2. Proxy - Ini adalah fungsi yang kami tentukan. dimana hook yang ditempatkan pada fungsi target akan melompat ke Tempat Lain.
  3. The Trampoline - Digunakan untuk memotong hook sehingga kita dapat memanggil fungsi yang terhubung secara normal.

Mengapa Trampoline
Katakanlah kita ingin mengaitkan MessageBoxA, mencetak parameter dari dalam fungsi proxy, kemudian menampilkan kotak pesan: Untuk menampilkan kotak pesan, kita perlu memanggil MessageBoxA (yang mengalihkan fungsi proksi kita, yang kemudian memanggil MessageBoxA ). Jelas memanggil MessageBoxA dari dalam fungsi proksi kami hanya akan menyebabkan rekursi tanpa batas dan program dengan akhirnya crash karena tumpukan overflow.
kita hanya dapat melepas hooking MessageBoxA dari dalam fungsi proxy, memanggilnya, lalu meng hook bagian itu; tetapi jika beberapa utas memanggil MessageBoxA pada saat yang sama, ini akan menyebabkan kondisi balapan dan kemungkinan crash program.
Sebaliknya, apa yang bisa kita lakukan adalah menyimpan 5 byte pertama dari MessageBoxA (ini ditimpa oleh hook kita), maka ketika kita perlu memanggil MessageBoxA yang tidak terhubung, kita dapat mengeksekusi 5 byte pertama yang tersimpan, diikuti dengan lompatan 5 byte ke dalam MessageBoxA (langsung setelah hook). Jika Anda mengalami kesulitan memvisualisasikan itu, saya telah membuat grafik panggilan.
 
Gambar Atas adalah panggilan normal ke MessageBoxA yang belum di Hooking, bagian bawah adalah panggilan menggunakan trampolin kami untuk melewati Hooking.
 
Selama 5 byte pertama bukanlah instruksi relatif, mereka dapat dieksekusi di mana saja (karena sangat jarang bagi fungsi untuk menggunakan instruksi relatif sejak awal, jadi kita tidak perlu benar-benar menangani ini). Masalah yang harus kita tangani adalah jika 5 byte pertama dari fungsi tidak membuat n seluruh instruksi).
Dalam contoh, 5 byte pertama dari fungsi membuat tepat 3 instruksi (mov edi, edi; push ebp; mov ebp, esp), namun, jika misalnya, instruksi pertama adalah 10 byte panjang dan kita hanya menyimpan 5 byte : trampolin akan mencoba menjalankan setengah instruksi dan program akan meledak. Untuk menyiasati ini, kita harus overhaul/bongkar pasang untuk mendapatkan panjang setiap instruksi, jadi kita dapat memastikan hanya untuk menyalin seluruh instruksi. Skenario kasus terbaik adalah yang pertama n instruksi menambahkan hingga tepat 5 byte, kasus terburuk adalah jika instruksi pertama adalah 4 byte dan yang kedua adalah 16 (panjang maksimum instruksi x86), kita harus menyimpan 20 byte (4 + 16), artinya trampolin kita harus berukuran 25 byte (ruang untuk instruksi hingga 20 byte dan lompatan 5 byte kembali ke fungsi yang terhubung). Penting untuk dicatat bahwa lompatan return harus melompat ke fungsi n byte yang terhubung, di mana n adalah banyak instruksi yang kita simpan di trampolin.
 
 
 
 

0 komentar:

Posting Komentar