الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

API Hook مثال بسيط

مغلقرائج
بدأه B.M.AbdelAziZ في 8 مايو 2006 · 64 رد · 9,157 مشاهدة · في لغة Delphi
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم و رحمة الله و بركاته

شرح بسيط من صفر لأصفار..مثله!

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

مثلا الدالة TerminateProcessمن Help نجد:

اقتباس
BOOL TerminateProcess(

    HANDLE hProcess, // handle to the process

    UINT uExitCode  // exit code for the process 

  );

أي لتعريفها في Delphi مثلا بإسم جديد HookeD تكون من الشكل:

Var
HookeD: function(hProcess: THandle; uExitCode: UINT): BOOL; stdcall;

الدالة موجدة في kernel32.dll

نحصل على مكانها بإستخدام الدالة GetProcAddress

لإستخدام GetProcAddress نحتاج handle مقبض المكتبة Kernel32.dll

الذي نحصل عليه بدوره بإستخدام الدالة GetModuleHandle

طبعا إن كانت المكتبة غير موجود بالذاكرة يجب تحميلها بإستخدام الدالة LoadLibrary

h:= GetModuleHandle('kernel32.dll');
  if h = 0 then
    h:= LoadLibrary('kernel32.dll');
  @HookED:= GetProcAddress(h, 'TerminateProcess');

حيث نحصل على عنوان الدالة في HookeD

و h مقبض handle في دلفي ب THandle

نعرف دالتا الجديدة NewOne مثل الدالة القديمة تماما:

function NewOne(hProcess: THandle; uExitCode: UINT): BOOL; stdcall;
begin
//
end;

حان وقت العمل، نغير في برنامجنا في الذاكرة بإستخدام الدالة WriteProcessMemory

طبعا قبل التغيير نحفظ ما نريد تغييره في متغير OldBytes بقرائتها بإستخدام الدالة ReadProcessMemory

لكن ماذا نغير ؟

نغير ما نريد، لكن ماذا نريد ؟

نريد أن تنفذ دالتنا NewOne بدلا من الدالة HookeD التي تمثل الدالة TerminateProcess في ذاكرة برنامجنا

في الأخير كل من الدوال ما هي إلا أوامر في موضع ما في الذاكرة

ولكي تنفذ دالتنا يكفي تغيير الأوامر الأولى بأمر قفز لدالتنا أي JMP بلغة التجميع

و يمكننا أيضا أن نستعمل أمر إستدعاء Call

لكن في حالتنا نستخدم Retرجوع و لنقل لسبب ما لا يهما الأن...

يصبح ما نريد كتابته بالشكل:

Push XXXX
Ret

لمن لا يعرف لغة التجميع، تعني ضع XXXX في stack

ثم عد من حيث أتيت Ret

ْXXXX هو عنوان ما في الذاكرة، أين توجد دالتنا الجديدة

وهنا أكتشث ما يسمى Pointer مؤشر... أمزح

عند تجميع الأمرين فوق يصبحان

68
ْXXXX
C3

مكتوبة بنظام 16 أو Hex

في المجموع 6 حروف أو bytes

68 أمر Push

XXXX مؤشر دالتنا الجديدة

C3 أمر Ret

هممم...

نغير 6 حروف

وقبل تغييرها نحفظ 6 حروف القديمة لإرجاعها فيما بعد، حتى يكون العمل نظيف

لتسهيل الأمور قليلا ننشئ Typeنمط جديد للحروف نسميه مثلا T6Bytes

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

في المتغير NewBytes

P تساوي 69

R تساوي C3

addr مؤشر لا نعرفه إلا وقت التنفيذ

نستخدم الدوال كما هو مكتوب فوق:

  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 نكتب :

	TerminateProcess(DWORD(-1), 0);

الأن نكتب الكود السابق الذى يعمل Hook في زر ثاني

ننفذ البرنامج و نجرب أو لا بالضغط على الزر الأول عندها يتوقف عمل البرنامج

أي تم تنفيذ الدالة الأصلية TerminateProcess

الأن نعيد تنفيذ البرنامج لكن نظغط على الزر الثاني لعمل Hook ثم نضغط الزر الأول

لا يحدث شيئ لأنه تم تنفيذ دالتنا الجديدة NewOne و هذا هو المطلوب !

طبعا الدالة NewOne لا تعمل شيئ لأننا لم نكتب بها أي شيئ

يمكننا مثلا عرض رسالة تطلب من المستخدم إن أراد الخروج و في حالة موافته نستدعى الدالة الأصلية TerminateProcess و قبل ذلك نعيد الأمور كما كانت :

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;

وهنا إنتهى هذا المثال البسيط،

بالملف المرفق هذا المثال بدلفي و ملف تنفيذي لمن يريد تجربته

أتمنى أن يستفيد البعض و لو 0.0x%

API_HooK_simple_example_delphi_source___executable.rar

1
d4baa0.gif
#2

السلام عليكم

بارك الله فيك أخي Delta والله الموضوع ممتاز وشيق للغاية، ارجو أن تستمر في هذا الموضوع حتى يصبح مرجع وقاعدة لكل مبتدئ في برمجة ويندوز...

ملاحظة للفائدة: وجود مثل هذا الموضوع في قسم الدلفي شيء ممتاز، وإضافة نسخة منه إلى قسم API سيكون شيء اجمل :)

قسم الـ API لا توجد فيه مواضيع للمبتدئين مثل هذا الموضوع :)

قبل مدة وضعت سؤال حول هذا الموضوع، ولم أجد الإجابة المطلوبة بالضبط.

هذا هو الموضوع: /index.ph...topic=91980&hl=

اقرأ مشاركتي قبل الأخيرة وستجد أنك موضوعك هذا هو الإجابة المطلوبة بالتمام :)

مشكور مرة أخرى..

بس انا بصراحة مستغرب ، معقول ما فيه ولا رد ولا كلمة شكر ولا أي شي :|

لا تهتم أخي Delta للخمول من قبل الأعضاء، الموضوع ممتاز وقيم وألف شكر لك

أرجو أن تستمر في هذا المثال، ثم تنتقل إلى أمثلة أكبر، ثم تترك للمهتمين فرصة للبحث في مواقع أخرى، بعد أن يتملكوا الأساسيات :)

في انتظار بقية الدروس على أحر من جمر :)

السلام عليكم..

#3

xc-delphi-cx

حدث هذا معى أيضا و لا أدرى ماهذا بالضبط

تابع أخى DeltaAziz موضوع رائع

لا تراجع و لا إستسلام

#4

اعتقد ان المشرف قام بإخفاء الردود لانها لا تسمن ولا تغنى من جوع, نريد حوار واسئلة حول الموضوع المطروح وليس مجرد شكر وخلاص.

تخيلو يا اخوه لو اننى مررت بكل موضوع عجبني وكتبت فيه شكراً كم كان سيصبح عدد مشاركاتي؟

انا شخصياً إذا كتبت موضوع مثل هذا وجاء شخص وكتب لي شكراً اعتبرها إهانة, شو يعنى شكراً, هل انا عازمك على شاي ولا قهوة.؟ هذا موضوع علمي للنقاش يعنى اخذ وعطي وليس فقط شكراً ومعى السلامة...

موضوع رائع يا D وكان المفروض يكون فى قسم الAPI كما ذكر fafe0, السؤال هو لماذا قمت بربط المكتبه kernel32 اثناء عمل البرنامج بدل من عمل الربط اثناء اللنك كما هو معتاد؟؟

والسلام عليكم

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#5
DeltaAziz كتب:

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

شكرا لك أخ على هذا الموضوع.

عندي سؤال: هل هذا التعديل سيكون فقط أثناء التنفيذ فقط يعني ستقوم بpatch في ram دون اي تعديل في الملف الأصلي ntkernel أو في kernel32.dll؟

DeltaAziz كتب:

ولكي تنفذ دالتنا يكفي تغيير الأوامر الأولى بأمر قفز لدالتنا أي JMP بلغة التجميع

و يمكننا أيضا أن نستعمل أمر إستدعاء Call

لكن في حالتنا نستخدم Retرجوع و لنقل لسبب ما لا يهما الأن...

يصبح ما نريد كتابته بالشكل:

Push XXXX
Ret

لمن لا يعرف لغة التجميع، تعني ضع XXXX في stack

ثم عد من حيث أتيت Ret/color]

push تقوم بوضع dword في المكدس و pull تقوم باستخراجها من المكدس.

فكما في الديلفي لكل begin يوافقه end فإن لكل push توافقها pull ولكل call يجب أن تجد ret..

call تستخدم لأستدعاء إجرائية أو دالة: ما تقوم به هذه التعليمة بالضبط هو حفظ عنوان التعليمة التالية (التي تلي call مباشرة ) في المكدس و تمرر عنوان الإجرائية المستدعية في EIP..

تعليمة ret تعليمة تفيد إنتهاء الإجرائية أو الدالة : تقوم هذه التعليمة بعملية pull لكلمة dword من المكدس وتضعها كعنوان لل eip.

..

يعني في هذه التعليمات الثلاث قمت بوضع عنوان العودة في المكدس و أنهيت اإجرائية ب ret.. لأن في حقيقة الأمر هناك call سبقت أستدعاء الدالة, كأن أصبح هناك إستدعاء دالة وسط دالة اخرى..

هل هذا هو الهدف من هذه التركيبة للتعليمات؟

;)

سأتغيب عن المنتدى وستكون لي زيارات خفيفة بين الحين و الحين

يا صاحب الهم إن الهم منفرج.....................أبشر بخير فإن الفارج الله.

اليأس يقطع أحيانا بصاحبه..........................لا تيأس فإن الكافي الله.

الله يحدث بعد العسر ميسرة.........................لا تفزعن فإن الصانع الله.

إذا بليت فثق بالله وارض به...................فإن الذي يكشف البلوى هو الله.

و الله ما لك غير الله من أحد.......................فحسبك الله في كل لك الله

أخوكم مراد

27_06_06_05_21_41_1151410901logo_adl_wal_ihsan.jpg

#6

أنا لم أشكره ولكن طلبت منه شرح الـ API ومن ثم لنفهم API hook

********************************************************************************

آخر وصايا سيدنا محمد صلى الله عليه وسلم:الصلاة الصلاة وما ملكت أيمانكم

66850879_b6e633000d_m.jpg

هاجر اللذائذ وانبـرى ليثـاً بادغـال الشـرا

بـاع الحيـاة رخيـصـة لله والله اشـتـرى

خذو مني فؤادي وامنحوني سلاحي أمتطي صهو المنون

فإني لم أعش لأذوق ذلاً ولا لأذوب في حضن حنون

موقع الفريق الاسلامي المتحد للبرمجة والإلكترونيات

إيميلي هو:Aboalnoor@maktoob.com

ياهو :adnanalabuo@yahoo.com

هوت ميل:AdnanAlabuo@hotmail.com

مدونتي الخاصة

#7

آسف على التكرار، وارجو حذف الرد المكرر، حدث ذلك دون قصد .. ولم أتمكن من حذفه بنفسي، لا يوجد عندي صلاحية لحذف الرد، فقط أستطيع تحريره !

@ DeltaAziz

اقتباس
68

ْXXXX

C3

مكتوبة بنظام 16 أو Hex

في المجموع 6 حروف أو bytes

أخي دلتا ما هي الحروف الستة ؟؟ هل تقصد 68 و C3 ؟ لكن هذه 4 حروف ! .. أرجو توضيح هذه النقطة

وأيضاً:

اقتباس
في المتغير NewBytes

P تساوي 69

R تساوي C3

addr مؤشر لا نعرفه إلا وقت التنفيذ

نستخدم الدوال كما هو مكتوب فوق:

CODE

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;

ذكرت أن قيمة P في NewBytes ستكون 69 ولكن في الكود وضعتها 68 ... هل هذا مجرد خطأ في الطباعة ؟؟

@ ikossan

يمكن أنت تعرف هذا الموقع من قبل ( موقع madshi )، بس هذه مقالة جيدة - يمكن تفيدك ويمكن انت تعلم أكثر مما ذكر فيها -

http://help.madshi.net/ApiHookingMethods.htm

@ Aboalnoor-Delphi7

اقتباس
أنا لم أشكره ولكن طلبت منه شرح الـ API ومن ثم لنفهم API hook

لا أظن من الحكمة شرح API لأن الشرح كله موجود في Delphi Help ، وإذا لم تجد في ملف المساعدة الدالة المطلوبة ستجدها في MSDN

يعني شرح آخر لهذه الدوال، هو مضيعة للوقت والجهد. " وتظل هذه وجهة نظر خاصة "

السلام عليكم ورحمة الله وبركاته.

تم تعديل هذه المشاركة بواسطة fafe0 في 10 مايو 2006 في 15:43

#8

هل لي ان اشارك قليلا؟

الهدف من PUSH / RET هو تطبيق امر JMP بتعليمتين بدل تعليمة, اعتقد ان السبب الذي يلمح اليه الاخ DeltaAziz هو عدم معرفة الـ opcode الاولى لتعليمة القفز؟ لا اعتقد ان افتراضي صحيح لان البايت سيكون 0E9h لانه سيكون لتعليمة قفز طويلة.

ليس هناك ما يسمى Pull لكن التعليمة المعاكسة لـ PUSH هي POP.

تعليمة الـ CALL عندما يتم تنفيذها فانه يتم وضع عنوان العودة في الـ stack والذي يشير الى التعليمة التي تلي امر CALL وعندما يتم استدعاء RET فانه يتم اعادة الـ dword من قمة المكدس الى EIP وبالتالي يتم نقل التنفيذ فعليا الى التعليمة التي تلي CALL ويكمل التنفيذ الصحيح للبرنامج.

اخيرا, P من المفترض ان تساوي 068h واعتقد انه خطأ طباعة لا اكثر لان PUSH لا تملك اكثر من بايت بداية.

اما بخصوص الحروف الستة فالمقصود بها "البايتات", لديك 6 بايتات "68 C3 X X X X" كل X تمثل بايت.

« Everything looks different from another cracker point of view »

« There are 11 types of people, those who understand binary, those who don't, well I'm the rest »

« ?Do you speak Binary »

me W4R3ZD00D/

#9
ikossan كتب:

شكرا لك أخ على هذا الموضوع.

عندي سؤال: هل هذا التعديل سيكون فقط أثناء التنفيذ فقط يعني ستقوم بpatch  في ram دون اي تعديل في الملف الأصلي ntkernel  أو في kernel32.dll؟

push تقوم بوضع dword في المكدس و pull تقوم باستخراجها من المكدس.

فكما في الديلفي لكل begin يوافقه end فإن لكل push توافقها pull  ولكل call يجب أن تجد ret..

call تستخدم لأستدعاء إجرائية أو دالة: ما تقوم به هذه التعليمة بالضبط هو حفظ عنوان التعليمة التالية (التي تلي call مباشرة ) في المكدس و تمرر عنوان الإجرائية المستدعية في EIP..

تعليمة ret تعليمة تفيد إنتهاء الإجرائية أو الدالة : تقوم هذه التعليمة بعملية pull لكلمة dword من المكدس وتضعها كعنوان لل eip.

..

يعني في هذه التعليمات الثلاث قمت بوضع عنوان العودة في المكدس و أنهيت اإجرائية ب ret.. لأن في حقيقة الأمر هناك call سبقت أستدعاء الدالة, كأن أصبح هناك إستدعاء دالة وسط دالة اخرى..

هل هذا هو الهدف من هذه التركيبة للتعليمات؟

;)

السلام عليكم

يا اخي استخدم مصطلحات متعارف عليها

لم افهم ما هو المكدس؟

ما هي الاجرائيه؟

ما هي التعليمه؟

#10
اقتباس
السؤال هو لماذا قمت بربط المكتبه kernel32 اثناء عمل البرنامج بدل من عمل الربط اثناء اللنك كما هو معتاد؟؟

سؤال صعب

لأن من علمني قال Its Dynamic-link libraries -> always Dynamic load it

أمزح...

المكتبة kernel32 مربوطة من قبل والأمر LoadLibrary لن ينفذ أبدا في هذا المثال

والأمر سيختلف لو كانت الدالة التي نريد في مكتبة أخرى غير مربوطة يجب تحميلها للحصول على المقبض handle

اقتباس
عندي سؤال: هل هذا التعديل سيكون فقط أثناء التنفيذ فقط يعني ستقوم بpatch في ram دون أي تعديل في الملف الأصلي ntkernel أو في kernel32.dll؟

في مثالنا هذا يتم التعديل في الذاكرة فقط أي Patch في RAM كما كتبته

برنامجنا المتأثر الوحيد من Hook

هذا نوع بسيط من Hook هناك أنواع أخرى يشمل التغيير كل Process يعمل على الجهاز أو ما يسمى Wide Hook

سنتطرق لها بأمثلة مقبلة إن شاء الله

اقتباس
يعني في هذه التعليمات الثلاث قمت بوضع عنوان العودة في المكدس و أنهيت اإجرائية ب ret.. لأن في حقيقة الأمر هناك call سبقت أستدعاء الدالة, كأن أصبح هناك إستدعاء دالة وسط دالة اخرى..

هل هذا هو الهدف من هذه التركيبة للتعليمات؟

كما تعرف لا يمكن تغيير EIP مباشرة

أمر Ret ماهو إلا أمر قفز لموضع قيمته مكتوبة في المكدس وضعت بالأمر Push

و شكرا أخي مراد على كلمة المكدس بحثت عنها في رأسي و لم أجدها فكتبت Stack أو كما نقول la pile

اقتباس
طلبت منه شرح الـ API ومن ثم لنفهم API hook

لا يوجد شيء اسمه شرح API

القصد Win32 API أو Windows API

API = Application programming interface

باختصار مجموعة من الدوال يوفرها صاحب التطبيق / البيئة / النظام لمن يريد البرمجة في تلك البيئة أو النظام أو التطبيق

Yousof كتب:
لم افهم ما هو المكدس؟

ما هي الاجرائيه؟

ما هي التعليمه؟

وهاهو الموضوع يتحول ل أشياء أخرى....

المكدس = Stack

إجرائية = Procedure

التعليمة = Instruction

صح!

اقتباس
ما هي الحروف الستة ؟؟ هل تقصد 68 و C3 ؟ لكن هذه 4 حروف ! .. أرجو توضيح هذه النقطة

...

ذكرت أن قيمة P في NewBytes ستكون 69 ولكن في الكود وضعتها 68 ... هل هذا مجرد خطأ في الطباعة ؟؟

نعم خطأ في الطباعة 68 بالنظام 16

P حرف

XXXX أربعة حروف

ٌR حرف

المجموع 6، وأقصد بحرف Byte

Dahaka كتب:
هل لي ان اشارك قليلا؟

ليس هناك ما يسمى Pull لكن التعليمة المعاكسة لـ PUSH هي POP.

إن كان لك في Delphi فمرحبا بك، نحن لا نشجع VB هنا :P

Pop لكن Pull تعني نفس الشيئ

Dahaka كتب:
اعتقد ان السبب الذي يلمح اليه الاخ DeltaAziz هو عدم معرفة الـ opcode الاولى لتعليمة القفز؟

:D تظنني لا أعرف Opcode JMP...

كيف تفكر هكذا ؟ ويفترض أنك تستخدم المنقح كثيرا...

أعد قرائة ما هو مكتوب فوق:

لكن في حالتنا نستخدم Retرجوع و لنقل لسبب ما لا يهما الأن...

ولن اذكره الأن

d4baa0.gif
#11

الاخ دلتا عزيز

حاول ان تضيف بعض الاكواد بلغة السي او السي بلس بلس

اعرف ان هذا الموضوع بالدلفي و لكن حاول

شكرا لك

#12

حسناً, أريد ان اسال سؤال, افرض اني قمت بعمل hook على دالة ما في kernel32.dll ولتكن كما في المثال هنا TerminateProcess, قمت باستخدام تعليمة JMP بدلا من PUSH/RET لكي اقوم بالاشارة الى الجزء في برنامجي الذي اريد تنفيذه عند طلب تلك الدالة, السؤال هو, هل من الواجب ان يتم تحويل الكود الى ملف DLL ام ان ملف EXE ينفع, ما اقصده اني كتبت ملف exe وقمت بجعله يقوم بالتعديل على بداية دالة بعد ان قمت بحفظ البايتات القديمة واستخدمتها في انشاء تعليمات (كي لا افقد اي شئ بكتابتها لو كانت تعليمة MOV فقد يختلف بايت البداية) حيث تقوم بالتعديل في بايتات تابعة لتعليمة NOP, وبفرض اني اقوم بامساك برنامج اخر في الذاكرة من خلال CreateProcess اريد ان اقوم باجراء تعديل عليه عندما يتم طلب TerminateProcess ببارامتر معين لنفرض انه الـ handle الخاص بالـ process التي اقوم بامساكها في الذاكرة بـ CreateProcess[suspended] بحيث عندما يتم طلب الدالة ينتقل التنفيذ الى برنامجي ليقوم بالتحقق من ثان dword في المكدس وهي الـ handle فان تطابقت قام باجراء التعديل المطلوب والا تم النقل الى حيث توجد التعليمات التي قمنا بانشائها من خلال تبديل الـ NOPs ومن ثم يتم اعادة التنفيذ الى التعليمة التالية في kernel32.dll والتي لم يتم التعديل عليها ليتم التنفيذ الصحيح.

(تحرير: عذرا ان كانت مشاركتي ستقوم بالخروج عن الافكار الاساسية للـ hooking الى مسالة اخرى قد لا تكون في "مثال بسيط" :) للاسف قسم البرمجة بدوال API غير متاح الان لي :P )

تم تعديل هذه المشاركة بواسطة Dahaka في 10 مايو 2006 في 16:38

« Everything looks different from another cracker point of view »

« There are 11 types of people, those who understand binary, those who don't, well I'm the rest »

« ?Do you speak Binary »

me W4R3ZD00D/

#13
Yousof كتب:
الاخ دلتا عزيز

حاول ان تضيف بعض الاكواد بلغة السي او السي بلس بلس

اعرف ان هذا الموضوع بالدلفي و لكن حاول

أخي الكريم من قواعد المشاركة فوق ممنوع توجيه الؤال لشخص معين...

و نحن في قسم Delphi , يمكن لمن يريد من الإخوة كتابة نفس الكود ب C بسهولة...

لا تنتظر مني أكواد C هنا...

d4baa0.gif
#14
Dahaka كتب:
ليس هناك ما يسمى Pull لكن التعليمة المعاكسة لـ PUSH هي POP.

أعتذر لأنني خلطت بين تعليمتي Intel و هي الزوج push/pop و بين تعليمتي motorola وهي push/pull..

لأن أول assembler درسناه كان خاص بمعالج motorolma 6809. ;) دائما أرتكب نفس الخطاء عند كتابة بعض الأكواد في assembly لديلفي ..

DeltaAziz كتب:
كما تعرف لا يمكن تغيير EIP  مباشرة

أمر  Ret ماهو إلا أمر قفز لموضع قيمته مكتوبة في  المكدس وضعت بالأمر Push

و شكرا أخي مراد على كلمة المكدس بحثت عنها في رأسي و لم أجدها فكتبت  Stack أو كما نقول la pile

نعم هذه هي الحكمة من استعمال push + ret..

أنا أيضا أجد صعوبة كبيرة في ترجمة المصطلحات العلمية وعادةَ ما أكتب مصطلح عربي+ مقابله بالإنجليزي أو في أصعب الحالات أرفق المصطلح بالفرنسية (دول شمال/غرب أفريقيا كلها تتكلم الفرنسية, حتى الدراسة فهي باللغة الفرنسية).

DeltaAziz كتب:
لا يوجد شيء اسمه شرح API

القصد Win32 API أو Windows API

API = Application programming interface

باختصار مجموعة من الدوال يوفرها صاحب التطبيق / البيئة / النظام لمن يريد البرمجة في تلك البيئة أو النظام أو التطبيق

كنت قد كتبت مقدمة بسيطة عن دوال api win32 واستعمالاتها في ديلفي قد تفيد الأخ السائل Aboalnoor-Delphi7 :

Windows API 32 programming, ما هي ال API؟

وهناك موضوع أكثر من رائع لللأخ الشمري في منتدى ++C.. ويمكنك كذلك تفحص منتدى Api windows.

شكرا fafe0, جاري القراءة .

سأتغيب عن المنتدى وستكون لي زيارات خفيفة بين الحين و الحين

يا صاحب الهم إن الهم منفرج.....................أبشر بخير فإن الفارج الله.

اليأس يقطع أحيانا بصاحبه..........................لا تيأس فإن الكافي الله.

الله يحدث بعد العسر ميسرة.........................لا تفزعن فإن الصانع الله.

إذا بليت فثق بالله وارض به...................فإن الذي يكشف البلوى هو الله.

و الله ما لك غير الله من أحد.......................فحسبك الله في كل لك الله

أخوكم مراد

27_06_06_05_21_41_1151410901logo_adl_wal_ihsan.jpg

#15
Dahaka كتب:
حسناً, أريد ان اسال سؤال, افرض اني قمت بعمل hook على دالة ما في kernel32.dll ولتكن كما في المثال هنا TerminateProcess, قمت باستخدام تعليمة JMP بدلا من PUSH/RET لكي اقوم بالاشارة الى الجزء في برنامجي الذي اريد تنفيذه عند طلب تلك الدالة, السؤال هو, هل من الواجب ان يتم تحويل الكود الى ملف DLL ام ان ملف EXE ....

كل من DLL و EXE عبارة عن موديل Module

لا أعرف كيف تكتب بالعربية

DLL: lodable module

EXE: executable module

ما تريد القيام به يحتاج توضيح أكثر

راسلني على الخاص لأنه خارج هذا الموضوع

d4baa0.gif
#16
Yousof كتب:
السلام عليكم

يا اخي استخدم مصطلحات متعارف عليها

لم افهم ما هو المكدس؟

ما هي الاجرائيه؟

ما هي التعليمه؟

نعم هناك مشكل في المصطلحات, لهذا أفضل إستعمال زوج: عربي/إنجليزي سيكون اسلم وأقرب للفهم.

ألمصكلحات أجابك عنها DeltaAziz:

DeltaAziz كتب:
وهاهو الموضوع يتحول ل أشياء أخرى....

المكدس = Stack=pile(french)

إجرائية = Procedure= function

التعليمة = Instruction = Mnemoinic (in assembler argo)

صح!

DeltaAziz كتب:
P حرف

XXXX أربعة حروف

ٌR حرف

المجموع 6، وأقصد بحرف Byte

مشكل مصطلحات :lol كانت intel تسمي اكبر سعة size للسجلات registry في المعالج "بالكلمة" word. ثم اشتغنت عن هذا الإصطلاح عند ظهور معالجات 32bit.

فأصبح الإصطلاح هو:

nible =quartet=??= 4bits

Byte=octet= ?? = 8bits

word= mot = كلمة= 16bits=2Bytes

DWord(double word)=double mot = 32bits=4Bytes=2Words

QWord= 64bits=2Dwords=4Words=8Bytes

TWord= 80Bits = 10Bytes

...

ما قصده DeltaAziz بالحرف فهي Byte وليس niblle يعني C9 تعد byte واحدة وليس إثنتين.

تم تعديل هذه المشاركة بواسطة ikossan في 10 مايو 2006 في 17:25

سأتغيب عن المنتدى وستكون لي زيارات خفيفة بين الحين و الحين

يا صاحب الهم إن الهم منفرج.....................أبشر بخير فإن الفارج الله.

اليأس يقطع أحيانا بصاحبه..........................لا تيأس فإن الكافي الله.

الله يحدث بعد العسر ميسرة.........................لا تفزعن فإن الصانع الله.

إذا بليت فثق بالله وارض به...................فإن الذي يكشف البلوى هو الله.

و الله ما لك غير الله من أحد.......................فحسبك الله في كل لك الله

أخوكم مراد

27_06_06_05_21_41_1151410901logo_adl_wal_ihsan.jpg

#17

سؤال

في حاجه مو قادر أفهمها بالكود هنا

اللى واضح من اسم الـ function عمَل hook على داله

طيب فين ReadProcessMemory and WriteProcessMemory

VirtualProtect ايش تعمل هناااا

function HookCode(TargetProc, NewProc: pointer; var OldProc: pointer): boolean;
var
  Address: longword;
  OldProtect: longword;
  OldFunction: pointer;
  Proc: pointer;
begin
  Result := False;
  try
    Proc := TargetProc;
    Address := longword(NewProc) - longword(Proc) - 5;
    VirtualProtect(Proc, 5, PAGE_EXECUTE_READWRITE, OldProtect);
    GetMem(OldFunction, 255);
    longword(OldFunction^) := longword(Proc);
    byte(pointer(longword(OldFunction) + 4)^) := SaveOldFunction(Proc, pointer(longword(OldFunction) + 5));
    byte(pointer(Proc)^) := $e9;
    longword(pointer(longword(Proc) + 1)^) := Address;
    VirtualProtect(Proc, 5, OldProtect, OldProtect);
    OldProc := pointer(longword(OldFunction) + 5);
  except
    Exit;
  end;
  Result := True;
end;
#18
DeltaAziz كتب:
إن كان لك في Delphi فمرحبا بك، نحن لا نشجع VB هنا :P

Pop لكن Pull تعني نفس الشيئ

:D تظنني لا أعرف Opcode JMP...

كيف تفكر هكذا ؟ ويفترض أنك تستخدم المنقح كثيرا...

أعد قرائة ما هو مكتوب فوق:

لكن في حالتنا نستخدم Retرجوع و لنقل لسبب ما لا يهما الأن...

ولن اذكره الأن

كنت اعتقد ان هذا قسم ال VB :lol:

لا طبعا لم اعتقد انك لا تعرف ما هو الـ opcode التابع للـ jmp بمختلف اشكاله لهذا ذكرت "اني لا اعتقد ان افتراضي صحيح" ;)

اما بخصوص السبب.. بسيطة, اسالك عنه على الخاص :)

« Everything looks different from another cracker point of view »

« There are 11 types of people, those who understand binary, those who don't, well I'm the rest »

« ?Do you speak Binary »

me W4R3ZD00D/

#19
xc-delphi-cx كتب:
سؤال

في حاجه مو قادر أفهمها بالكود هنا

اللى واضح من اسم الـ function عمَل hook على داله

طيب فين ReadProcessMemory and WriteProcessMemory

VirtualProtect ايش تعمل هناااا

function HookCode(TargetProc, NewProc: pointer; var OldProc: pointer): boolean;
var
  Address: longword;
  OldProtect: longword;
  OldFunction: pointer;
  Proc: pointer;
begin
  Result := False;
  try
    Proc := TargetProc;
    Address := longword(NewProc) - longword(Proc) - 5;
    VirtualProtect(Proc, 5, PAGE_EXECUTE_READWRITE, OldProtect);
    GetMem(OldFunction, 255);
    longword(OldFunction^) := longword(Proc);
    byte(pointer(longword(OldFunction) + 4)^) := SaveOldFunction(Proc, pointer(longword(OldFunction) + 5));
    byte(pointer(Proc)^) := $e9;
    longword(pointer(longword(Proc) + 1)^) := Address;
    VirtualProtect(Proc, 5, OldProtect, OldProtect);
    OldProc := pointer(longword(OldFunction) + 5);
  except
    Exit;
  end;
  Result := True;
end;

هل ذكر Delta ان الكود انتهى الى هنا وانك قمت بعمل hook على الدالة؟! لا طبعا لهذا ما زلت لم ترى استخدام ReadProcessMemory و WriteProcessMemory

اما بخصوص VirtualProtect, اي مكتبة من مكاتب النظام لا تملك سماحيات الكتابة فيها والا لحدثت كوارث لذا نستخدم VirtualProtect لنقوم بتغيير السماحيات على المكاتب في الذاكرة من R (Read) الى RWE (ReadWrite Execute) عبر VirtualProtect التي تسمح بتغيير السماحيات مع الاحتفاظ بالسماحيات القديمة في البارامتر الاخير OldProtect

« Everything looks different from another cracker point of view »

« There are 11 types of people, those who understand binary, those who don't, well I'm the rest »

« ?Do you speak Binary »

me W4R3ZD00D/

#20
اقتباس
في حاجه مو قادر أفهمها بالكود هنا

اللى واضح من اسم الـ function عمَل hook على داله

طيب فين ReadProcessMemory and WriteProcessMemory

VirtualProtect ايش تعمل هناااا

المثال بهذا الموضوع بسيط الهدف منه توضيح معنا API Hook فقط

فيما يخص ReadProcessMemory للقرائة من ذاكرة البرنامج، هناك طرق أخرى للقرائة من الذاكرة لو كانت عند الصلاحية لذلك، و هذا هو دور الدالة الأخرى VirtualProtect

d4baa0.gif
#21
DeltaAziz كتب:
حان وقت العمل، نغير في برنامجنا في الذاكرة بإستخدام الدالة WriteProcessMemory

طبعا قبل التغيير نحفظ ما نريد تغييره في متغير OldBytes بقرائتها بإستخدام الدالة ReadProcessMemory

لكن ماذا نغير ؟

نغير ما نريد، لكن ماذا نريد ؟

نريد أن تنفذ دالتنا NewOne بدلا من الدالة HookeD التي تمثل الدالة TerminateProcess في ذاكرة برنامجنا

في الأخير كل من الدوال ما هي إلا أوامر في موضع ما في الذاكرة

أخ DeltaAziz ماذا تقصد بـ " نغير في برنامجنا في الذاكرة " وماذا تقصد بـ " ذاكرة برنامجنا " ؟

هل كل برنامج عنده ذاكرة خاصة ؟؟

انا حسب علمي هي ذاكرة واحدة في الحاسب !!

أرجو توضيح هذه النقطة...

حقيقة أنا لا أعرف كيف تعمل البرامج في ويندوز وكيف تستخدم الذاكرة، وكل ما أعرفه عن الذاكرة أنها مكان يستخدم لحفظ المتغيرات وعناوين دوال معينة... ولا أستطيع أن أتخايل حقيقة الذاكرة في الحاسب...

يا حبذا لو تعطينا أنت أو الإخوة نبذة بسيطة عن هذا الموضوع، أو رابط فيه توضيح لهذه النقطة المهمة .

وشكراً لكم.

#22
fafe0 كتب:
ماذا تقصد بـ " نغير في برنامجنا في الذاكرة " وماذا تقصد بـ " ذاكرة برنامجنا " ؟

هل كل برنامج عنده ذاكرة خاصة ؟؟

انا حسب علمي هي ذاكرة واحدة في الحاسب  !!

نغير ببرنامجنا بالذاكرة ما يسمى memory patch

نعم لكل برنامج ذاكرته الخاصة، بالنسبة له هو الوحيد بالميدان :D

ذاكرة إفتراضية و هذا أحد مهام نظام التشغيل Windows

نعم ذاكرة الحاسب واحدة وهي الذاكرة الفيزيائة إن صح التعبير

لمزيد من التفلصيل إقرأ هذا المقال

Virtual Memory in Windows XP

d4baa0.gif
#23
DeltaAziz كتب:
المثال بهذا الموضوع بسيط الهدف منه توضيح معنا API Hook فقط

فيما يخص ReadProcessMemory للقرائة من ذاكرة البرنامج، هناك طرق أخرى للقرائة من الذاكرة لو كانت عند الصلاحية لذلك، و هذا هو دور الدالة الأخرى VirtualProtect

القراءة لا تحتاج الى VirtualProtect, الكتابة هي ما يحتاج هذا.

« Everything looks different from another cracker point of view »

« There are 11 types of people, those who understand binary, those who don't, well I'm the rest »

« ?Do you speak Binary »

me W4R3ZD00D/

#24
Dahaka كتب:
القراءة لا تحتاج الى VirtualProtect, الكتابة هي ما يحتاج هذا.

لا يا حبيبي

هناك ثلاث:

read / write / execute

تنفيذ / كتابة / قرائة

إقراء جيدا ما كتبت فوق: لو عندك الصلاحية

d4baa0.gif
#25
"DeltaAziz" كتب:
لا يا حبيبي

هناك ثلاث:

read / write / execute

تنفيذ / كتابة / قرائة

إقراء جيدا ما كتبت فوق: لو عندك الصلاحية

لكني قرات هذا وافهمه جيدا :)

كل القطع في الـ modules تملك سماحية قراءة Read الا ما تم تعديله من خلال pe tool, كل مكتبات النظام وملفات الـ dll التي سنتعامل معها لها سماحية قراءة من خلال الذاكرة وبما ان ReadProcessMemory لا تهتم الا بهذه السماحية فاذن VirtualProtect غير مهمه لها قبل ان نشرع باستخدام WriteProcessMemory.

« Everything looks different from another cracker point of view »

« There are 11 types of people, those who understand binary, those who don't, well I'm the rest »

« ?Do you speak Binary »

me W4R3ZD00D/

هذا الموضوع مغلق.

مواضيع مشابهة