Api Hook مثال بسيط, Hook للدالة TerminateProcess
#1
بسم الله الرحمن الرحيم

بإختصار API hook هو التعديل بحيث تستدعى دالتنا بدلا من دالة API

مثال الدالة TerminateProcessمن Help نجد:
إقتباس :
BOOL TerminateProcess(
HANDLE hProcess, // handle to the process
UINT uExitCode // exit code for the process
);

لتعريفها في Delphi مثلا بإسم جديد HookeD تكون من الشكل:
PHP كود :
Var
HookeD: function(hProcess: THandle; uExitCode: UINT): BOOL; stdcall; 

الدالة موجدة في kernel32.dll
نحصل على مكانها بإستخدام الدالة GetProcAddress
لإستخدام GetProcAddress نحتاج handle مقبض المكتبة Kernel32.dll
الذي نحصل عليه بدوره بإستخدام الدالة GetModuleHandle
طبعا إن كانت المكتبة غير موجود بالذاكرة يجب تحميلها بإستخدام الدالة LoadLibrary
PHP كود :
h:= GetModuleHandle('kernel32.dll');
 if 
h = 0 then
   h
:= LoadLibrary('kernel32.dll');
 @
HookED:= GetProcAddress(h, 'TerminateProcess'); 

حيث نحصل على عنوان الدالة في HookeD
و h مقبض handle في دلفي ب THandle
نعرف دالتا الجديدة NewOne مثل الدالة القديمة تماما:

PHP كود :
function NewOne(hProcess: THandle; uExitCode: UINT): BOOL; stdcall;
begin
//
end; 

حان وقت العمل، نغير في برنامجنا في الذاكرة بإستخدام الدالة WriteProcessMemory
طبعا قبل التغيير نحفظ ما نريد تغييره في متغير OldBytes بقرائتها بإستخدام الدالة ReadProcessMemory
لكن ماذا نغير ؟
نغير ما نريد، لكن ماذا نريد ؟
نريد أن تنفذ دالتنا NewOne بدلا من الدالة HookeD التي تمثل الدالة TerminateProcess في ذاكرة برنامجنا
في الأخير كل من الدوال ما هي إلا أوامر في موضع ما في الذاكرة
ولكي تنفذ دالتنا يكفي تغيير الأوامر الأولى بأمر قفز لدالتنا أي JMP بلغة التجميع
و يمكننا أيضا أن نستعمل أمر إستدعاء Call
لكن في حالتنا نستخدم Retرجوع و لنقل لسبب ما لا يهما الأن...
يصبح ما نريد كتابته بالشكل:

PHP كود :
Push XXXX
Ret 

لمن لا يعرف لغة التجميع، تعني ضع XXXX في stack
ثم عد من حيث أتيت Ret
ْXXXX هو عنوان ما في الذاكرة، أين توجد دالتنا الجديدة
وهنا أكتشث ما يسمى Pointer مؤشر... أمزح
عند تجميع الأمرين فوق يصبحان

PHP كود :
68
ْXXXX
C3 

مكتوبة بنظام 16 أو Hex
في المجموع 6 حروف أو bytes
68 أمر Push
XXXX مؤشر دالتنا الجديدة
C3 أمر Ret
هممم...
نغير 6 حروف
وقبل تغييرها نحفظ 6 حروف القديمة لإرجاعها فيما بعد، حتى يكون العمل نظيف
لتسهيل الأمور قليلا ننشئ Typeنمط جديد للحروف نسميه مثلا T6Bytes

PHP كود :
type
 T6Bytes 
= packed record
   P
: Byte;
   
addr: Pointer;
   
R: Byte;
 
end;
Var
 
OldBytes, NewBytes: T6Bytes; 

في المتغير NewBytes
P تساوي 69
R تساوي C3
addr مؤشر لا نعرفه إلا وقت التنفيذ
نستخدم الدوال كما هو مكتوب فوق:

PHP كود :
if ReadProcessMemory(DWORD(-1),
   @
HookeD, @OldBytes, SizeOf(OldBytes), Dw) then
 begin
   NewBytes
.P:= $68;
   
NewBytes.R:= $C3;
   
NewBytes.addr:= @NewOne;
   
WriteProcessMemory(DWORD(-1),
     @
HookeD, @NewBytes, SizeOf(NewBytes), Dw);
 
end; 

نجرب إستدعاء الدالة TerminateProcess في زر مثلا Button نكتب :
PHP كود :
TerminateProcess(DWORD(-1), 0); 

الأن نكتب الكود السابق الذى يعمل Hook في زر ثاني
ننفذ البرنامج و نجرب أو لا بالضغط على الزر الأول عندها يتوقف عمل البرنامج
أي تم تنفيذ الدالة الأصلية TerminateProcess
الأن نعيد تنفيذ البرنامج لكن نظغط على الزر الثاني لعمل Hook ثم نضغط الزر الأول
لا يحدث شيئ لأنه تم تنفيذ دالتنا الجديدة NewOne و هذا هو المطلوب !
طبعا الدالة NewOne لا تعمل شيئ لأننا لم نكتب بها أي شيئ
يمكننا مثلا عرض رسالة تطلب من المستخدم إن أراد الخروج و في حالة موافته نستدعى الدالة الأصلية TerminateProcess و قبل ذلك نعيد الأمور كما كانت :

PHP كود :
if MessageBox(Form1.Handle, 'Close ?', 'API HooK',
    
MB_YESNO or MB_ICONQUESTION or MB_DEFBUTTON2) = IDYES then
  begin
    WriteProcessMemory
(DWORD(-1), @HookeD, @OldBytes, SizeOf(OldBytes), Dw);
    
HookeD(hProcess, uExitCode);
  
end; 

وهنا إنتهى هذا المثال البسيط،
بالملف المرفق هذا المثال بدلفي و ملف تنفيذي لمن يريد تجربته

ملاحظة: هذا شرح بسيط من صفر لأصفار..مثله! كتبته من قبل في ArabTeam2000-forum


الملفات المرفقة
.rar   API_HooK_simple_example_delphi_source.rar (الحجم : 129.49 ك ب / التحميلات : 734)
[-] كل من 5 users say قال شكرا ل محمد عبد العزيز على المشاركة المفيدة
  • mohamed49, Ben.Ja, Rever7eR, Eagle Master, haniid
الرد


الردود في هذا الموضوع
Api Hook مثال بسيط, Hook للدالة TerminateProcess - بواسطة محمد عبد العزيز - 25-02-2009, 09:17 AM

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم