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(hProcessTHandleuExitCodeUINT): BOOLstdcall

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

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

PHP كود :
function NewOne(hProcessTHandleuExitCodeUINT): BOOLstdcall;
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;
   
addrPointer;
   
RByte;
 
end;
Var
 
OldBytesNewBytesT6Bytes

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

PHP كود :
if ReadProcessMemory(DWORD(-1),
   @
HookeD, @OldBytesSizeOf(OldBytes), Dwthen
 begin
   NewBytes
.P:= $68;
   
NewBytes.R:= $C3;
   
NewBytes.addr:= @NewOne;
   
WriteProcessMemory(DWORD(-1),
     @
HookeD, @NewBytesSizeOf(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, @OldBytesSizeOf(OldBytes), Dw);
    
HookeD(hProcessuExitCode);
  
end

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

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


الملفات المرفقة
.rar   API_HooK_simple_example_delphi_source.rar (الحجم : 129.49 ك ب / التحميلات : 734)
[-] كل من 5 users say قال شكرا ل محمد عبد العزيز على المشاركة المفيدة
  • mohamed49, Ben.Ja, Rever7eR, Eagle Master, haniid
الرد
#2
بارك الله فيك وجزاك خيرا.
بالمناسبة متى نلجأ إلى API hook ؟ عندما لا يتوفر النظام على الدالة (في حالة تغير النظام) فقط ؟؟؟
شكرا كثيرا.
الرد
#3

هناك حالات كثيرة لاستعمال API Hook ( بطرقه المختلفة)
مثال تريد برمجة قاموس او مترجم فوري، مباشرة بوضع الفارة على اي كلمة في اي برنامج تظهر لك الترجمة، هنا تستخدم Hook لدوال API المسؤولة عن اخراج النصوص مثل TextOut و DrawText غيرها
مثال اخر تريد برمجة برنامج حماية او مضاد فيروسات، هنا تعمل Hook لعدد كبير من الدوال وعند استدعاءها اما تسمح بذلك او تمنعه حسب رغبة المستخدم
فقط فكر في الجملة 'استدعاء دالتي بدلا من دالة النظام' وانظر للافاق المتاحة
والسلام عليكم
[-] كل من 4 users say قال شكرا ل محمد عبد العزيز على المشاركة المفيدة
  • mohamed49, Eagle Master, invocker, haniid
الرد
#4
شكرا اخي DeltaAziz
يعني مجرد استدعائي للدالة من المكتبة بعد معرفه عنوانها (مكانها) هذة العملية هي ال API Hook !!
الرد
#5
إقتباس :مجرد استدعائي للدالة من المكتبة بعد معرفه عنوانها
ليس الاستدعاء وانما التغيير لكي تستدعى دالتنا نحن، وهذا ابسط نوع من API Hook لان تاثيرة يكون على برنامجنا فقط، دون باقي البرامج التي تعمل بالذاكرة
باختصار:
Hook = قبض
API Hook = قبض دالة API
[-] كل من 1 user says قال شكرا ل محمد عبد العزيز على المشاركة المفيدة
  • Eagle Master
الرد
#6
السلام عليكم
أود ان أسالك سؤال أخى ؟
هل من الممكن التغيير فى ملف Exe بنفس الطريقة تبع الهووك التى كنت تتحدث عنها أم لا
سؤال ثانى : هل هذا ما يطلق عليه Runtime injection وهى طريقة لجعل الفيروسات تملك صلاحيات
أعلى فى النظام وتختفى من البروسيس (طريقة من طرق الرووت كيت ) ؟

أعذرنى لأنى حديث المعرفة بالدلفى ولكنى كنت مبرمج vb6 وقررت تعلم الدلفى مؤخرا


وشكرا أخوك الشبح الصغير
الرد
#7

إقتباس :هل من الممكن التغيير فى ملف Exe بنفس الطريقة تبع الهووك
نعم، ممكن وهذه قصة اخرى، هذا الموضوع فقط عن التغيير في ذاكرة برنامجنا

إقتباس :هل هذا ما يطلق عليه Runtime injection
لا، هذا Hook اي قبض وليس حقن Injection
الرد
#8
اخي ديلتا...

إقتباس :نعم، ممكن وهذه قصة اخرى
هل الطريقة تعتمد تقريبا على نفس الشئ؟

ام انك تقصد بقصة اخرى... يعني انه شئ آخر
يحتاج الى شرح آخر :confused::pRolleyes

اذا ما عليك الى شرحه ... الله يبارك فيك
الرد
#9
إقتباس :ام انك تقصد بقصة اخرى...
باختصار التعديل على الملف التنفيذي بحاجة لفهم جيد لبنية الملف التنفيذي Win32 PE
الموضوع عن Hook وبنية PE موضوع اخر
[-] كل من 1 user says قال شكرا ل محمد عبد العزيز على المشاركة المفيدة
  • mohamed49
الرد
#10
السلام عليكم
1- مادا تعني (في داكرة برنامجنا ؟؟) أنا كنت أعتقد ان البرنامج يحمل للداكرة على شكل تعليمات (hex/asm)
و المعالج هو المسؤول عن التشفير و الترجمة يعني أن العنوان كيف يكون مخزن في البرنامج التنفيدي.

و ما الفرق بين مقبض البرنامج و رقم التعريف id

2- في ما يخص 6 وحداة لمادا 6 ؟؟ كقيم hex :
1 byte لـ 63
حجم الدالة ؟؟ أيعني أنها 4 وحدات (يجب هنا أن تكون في نظام 32 بيت ؟؟؟ (32=4))
1 byte لـ c3

ملاحظة : درس قمة شكرا لك .
I'M Fly Like A G6

الرد


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


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