مقدمه: API Hook اصلاً چیست؟
فرض کن برنامهای این کد را اجرا میکند:
MessageBoxA(
NULL,
"Hello",
"Test",
MB_OK
);جریان اجرا:
Application => MessageBoxA => user32.dll => Windows
حالا اگر بتوانیم قبل از اجرای MessageBoxA کنترل را بگیریم:
Application => MyHookFunction => Log or Modify => Original MessageBoxA
به این کار Hook میگویند.
خب Hook چه کاربردی دارد؟
مثلاً:
- لاگ کردن فایلهایی که باز میشوند
- لاگ کردن ترافیک شبکه
- مانیتور کردن USB
- انجام Profiling
- انجام Debugging
مثلاً هر بار برنامه:
CreateFile(...)صدا زد:
CreateFile(C:\temp\a.txt)
CreateFile(C:\temp\b.txt)
CreateFile(C:\temp\c.txt)را لاگ کنیم.
چرا DLL Injection لازم است؟
و یا چطور Hook من داخل Process قربانی اجرا شود؟
فرض کن برنامه Notepad اجرا شده است. ویندوز خودش DLL ما را داخل Notepad لود نمیکند.
بنابراین باید فایل Hook.dll را داخل برنامه Notepad تزریق کنیم.
معماری کلی
سه بخش داریم:
Injector.exe
Victim.exe
Hook.dll
برنامه Victim
برنامهای که قرار است Hook شود.
مثلاً:
int main(){
while(true)
{
MessageBoxA(
NULL,
"Hello",
"Victim",
MB_OK
);
}
}فایل Hook DLL
بعد از لود شدن باید Hook کرده و عملیات مدنظر ما را انجام دهد.
BOOL APIENTRY DllMain(...){
InstallHook();
DoSomeWork();
return TRUE;
}برنامه Injector
این برنامه وظیفه پیدا کردن پروسس قربانی (Victim)، باز کردن آن پروسس و تزریق DLL در فضای حافظه آن برنامه را دارد.
حالا DLL Injection از نظر مفهومی چگونه کار میکند؟
فرض کنید DLL اینجاست:
C:\Hook.dll
ما به Process قربانی میگوییم:
LoadLibrary("C:\\Hook.dll");
اما از داخل Process خودمان نمیخواهیم اجرا شود.
میخواهیم داخل Process قربانی اجرا شود.
پس:
Process A => Process B => LoadLibrary("Hook.dll")
را در Process B اجرا میکنیم.
ایده کلی تزریق
مراحل:
OpenProcess
VirtualAllocEx
WriteProcessMemory
CreateRemoteThread
مرحله اول
از طریق PID مربوط به پروسس قربانی، هندل آن را استخراج کرده و باز (OpenProcess) میکنیم.
مرحله دوم
با استفاده از VirtualAllocEx داخل حافظه قربانی فضا میگیریم.
مرحله سوم
با استفاده از WriteProcessMemory مسیر DLL را در حافظه قربانی مینویسیم.
مرحله چهارم
از طریق CreateRemoteThread تابع LoadLibraryA را در Process قربانی اجرا میکنیم. با این جریان:
Injector => CreateRemoteThread => Victim => LoadLibraryA => Hook.dll
بعد از Inject چه اتفاقی میافتد؟
ویندوز DllMain(DLL_PROCESS_ATTACH) را صدا میزند و در نتیجه این کد:
BOOL APIENTRY DllMain(...){
InstallHook();
DoSomeWork();
return TRUE;
}اجرا میشود.
حالا Hook چگونه نصب میشود؟
فرض کن MessageBoxA در حافظه این شکلی است:
MessageBoxA:
55
8B EC
83 EC 10
...
چند بایت اول را برمیداریم:
55
8B EC
83 EC 10
و به جایش:
JMP MyHook
میگذاریم.
نتیجه:
قبل:
Application => MessageBoxA
بعد:
Application => MessageBoxA => JMP => MyHook
پس Trampoline چیست؟
مشکل:
اگر تمام MessageBoxA را نابود کنیم Original Function دیگر وجود ندارد. پس بایتهای اصلی را کپی میکنیم در یک حافظه جدید
55
8B EC
83 EC 10
و آخر اجرای توابع خودمان، برمیگردیم و
JMP Back
میگذاریم. در نتیجه به این صورت:
Application => Hook => Trampoline => Original Function
کتابخانه MinHook چه میکند؟
کتابخانههایی مثل MinHook و Detours این کارها را انجام میدهند:
Find Function
Patch Function
Create Trampoline
Manage Memory
بنابراین لازم نیست خودتون اسمبلی بنویسین.
مثال عملی
برای مشاهده یک مثال عملی به مقاله آموزش ساده DLL Injection و API Hook با MinHook در C++ مراجعه کنید.