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
Mengapa Trampoline
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:
- The Hook - Sebuah lompatan relatif 5 byte yang ditulis ke fungsi target untuk mengaitkannya, lompatan akan melompat dari fungsi yang terhubung ke kode kita.
- Proxy - Ini adalah fungsi yang kami tentukan. dimana hook yang ditempatkan pada fungsi target akan melompat ke Tempat Lain.
- 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