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

[ تمت الإجابة ]API - Hook

مغلق
بدأه الاخير زمانه في 2 سبتمبر 2006 · 24 رد · 5,013 مشاهدة · في أرشيف قسم Windows APIs
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ،

هناك مثال من قبل الاخ محمد في منتدى دلفي حول عمل هوك للدالة TerminateProcess ،

حاولت ان احوله الى لغة السي لكن تواجهني بعض المشاكل ،،

لذا ارجو المساعدة من اصحاب العلم ،،

هذا ما فعلت ..

FARPROC hook;

struct T6Bytes
	{
  BYTE P;
  FARPROC addr;
  BYTE R;
} OldBytes, NewBytes;

	unsigned long i;

BOOL  NewFun(
	HANDLE  hProcess,		UINT  uExitCode	)
{

if((MessageBox(0,"Are You Sure ??" , "Close",MB_YESNO)== IDYES ))
		{
	WriteProcessMemory(GetCurrentProcess(), &hook, &OldBytes, sizeof(NewBytes), &i);
	TerminateProcess(GetCurrentProcess(),0);  }


/****************************/////////////////////////////////////

هنا في السطر الذي في الاعلى وحسب مثال الاخ محمد ، يتم استدعاء الدالة البديلة وهي hook ، لكن عند استخدامها يظهر error ، هذه الدالة .. الاخ محمد عرفها بطريقة لا اعرف ما يقابلها في لغة سي ،، هذا قوله :

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

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


*/////////////////////////////////////////////////////////////////////////////////////



return TRUE;
}



int WINAPI WinMain(HINSTANCE hInstance  , HINSTANCE  ,	LPSTR  , int  )
{

DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1),
			  0, (DLGPROC) DlgProc );
return 0; 


}


LRESULT CALLBACK DlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HMODULE h = GetModuleHandle("kernel32.dll");
	if(h == NULL) 
	 h = LoadLibrary("kernel32.dll");
	hook = GetProcAddress(h, "TerminateProcess");




	 switch(message)
   {

	case WM_INITDIALOG:

	return TRUE;


	case WM_COMMAND:
		switch(wParam)
		{
		case IDC_HOOK :

	if(ReadProcessMemory(GetCurrentProcess(), hook, &OldBytes, sizeof(OldBytes), &i)) {
	NewBytes.P = 0x68;
	NewBytes.R = 0xC3;
	NewBytes.addr = (FARPROC)NewFun; 
	 WriteProcessMemory(NULL, hook, &NewBytes, sizeof(NewBytes), &i);



	}

	return TRUE;

		case IDC_TERM:

					TerminateProcess(GetCurrentProcess(),0);


				return TRUE;



		}



		return TRUE ; 

	 }



	return FALSE;

}

جزاكم الله خيرا

،،،،،،،،،،،،،،،،

تم تعديل هذه المشاركة بواسطة Xacker في 2 سبتمبر 2006 في 15:40

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#2

:D :D :D

هل علمت أي خطأ يظهر ؟؟

هل عملت Debug للبرنامج وتتبعت أين يحدث الخطأ ؟

لا تقلق سوف نساعدك ولكن اريد أن ارى مجهودك , وطريقة تفكيرك

#3

السلام عليكم

اقتباس
هل علمت أي خطأ يظهر ؟؟

هل عملت Debug للبرنامج وتتبعت أين يحدث الخطأ ؟

بصراحة هاي يومين ما قرأت كثير لأنشغالي في امور هنا

(سوء الوضع الامني وحالات التهديد و التهجير التي تجتاح البلاد ،، فلقد اصابنا منها ما اصاب غيرنا ،، اخواني .. لا تنسونا من صالح دعائكم ،، فنحن ايضا نقول ..

لا اله الا الله .. وحق المسلم على المسلم :( )

المهم ،،

سأقرء ما دام هناك نفس ..

هاليوم ان شاء ربي سأحاول بهذا البرنامج وغدا بعون الله سأعود لأخبرك بما حدث معي ..

اقتباس
لا تقلق سوف نساعدك ولكن اريد أن ارى مجهودك , وطريقة تفكيرك

بارك الله بك على تعاونك وعلى تواصلك معي جعله الله في ميزان حسناتك ..

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#4

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

اخي ِAsm4all

لو نرجع للكود الذي وضعته في مشاركتك في قسم الدالفي ،

هذه الخطوة

int i;
if(ReadProcessMemory(DWORD(-1), hocked, &OldBytes, SizeOf(OldBytes), &i)) {
   NewBytes.P = 0x68;
   NewBytes.R = 0xC3;
   NewBytes.addr = NewOne; // address of our proc
   WriteProcessMemory(DWORD(-1), hocked, &NewBytes, SizeOf(NewBytes), &i);
}

انا يظهر لي خطأ عند هذه الخطوة

   NewBytes.addr = NewOne;

يقول

error C2440: '=' : cannot convert from 'int (__cdecl *)(void *,unsigned int)' to 'int (__stdcall *)(void)'
		This conversion requires a reinterpret_cast, a C-style cast or function-style cast

لذا قمت بوضع FARPROC

قبل اسم الدالة ، والخطأ لم يعد يظهر لي ..

لكن الذي يحدث معي اني حين انفذ البرنامج ،

اذا ضغطت على TerminateProcess يتم انهاء البرنامج بصورة طبيعية ،

وعند الضغط عل الزر Hook

ثم الضغط على الزر TerminateProcess ،

يحصل خطأ ، تظهر مسج تابعة لل system بها خيار close و Debug

عند الضغط على debug مثلا يظهر

The Instruction at “0x7c801e1b” referenced memory at “0xffffffff” . The memory could not be “written”

هذه الخطوة

funhook = (FUNCHOOK)GetProcAddress(h, "TerminateProcess");

هنا نحصل على عنوان الدالة المراد عمل هوك لها ،

تمام

ظهر لي العنوان هو 0x7c801e16

هذه الخطوة

	NewBytes.addr= (FUNCHOOK) NewFun;

عند الوقوف على NewFun يظهر عنوانها 0x00401030

طيب ، بعد هذه الخطوة ، أليس المفروض يكون عنوان ال NewBytes.addr هو عنوان دالتنا الجديدة أي NewFun

ال NewBytes.addr بعد هذه الخطوة يكون كاتالي : 0x00401005

أليس هذا خطأ ام انا الغلطان ؟؟

أ ظن انه هنا الخطأ

لأن بعد عملية الكتابة (اذا كانت صحيحة )

المفروض يتم استدعاء الدالة NewFun عند الضغط على Terminate ، وهذا ما لا يحدث

،،،،

بالنسبة لـِ FUNCHOOK ، عرفته هكذا ،

typedef UINT (CALLBACK* FUNCHOOK) (HANDLE , UINT);

،،

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#5

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

typedef UINT (CALLBACK* FUNCHOOK) (HANDLE , UINT);

بداية سليمة

غير هذا الكود

FARPROC hook;

struct T6Bytes
	{
  BYTE P;
  FARPROC addr;
  BYTE R;
} OldBytes, NewBytes;

الى

FUNCHOOK hook;

struct T6Bytes
	{
  BYTE P;
  FUNCHOOK addr;
  BYTE R;
} OldBytes, NewBytes;

غير

BOOL  NewFun(HANDLE  hProcess, UINT  uExitCode) {
  if((MessageBox(0,"Are You Sure ??" , "Close",MB_YESNO)== IDYES )) {
	WriteProcessMemory(GetCurrentProcess(), &hook, &OldBytes, sizeof(NewBytes), &i);
	TerminateProcess(GetCurrentProcess(),0);

  }
}

الى

BOOL CALLBACK NewFun(HANDLE  hProcess, UINT  uExitCode) {
  if((MessageBox(0,"Are You Sure ??" , "Close",MB_YESNO)== IDYES )) {
	WriteProcessMemory(GetCurrentProcess(), &hook, &OldBytes, sizeof(NewBytes), &i);
	TerminateProcess(GetCurrentProcess(),0);

  }
}

وعند اختبار الكود ضع نقطة توقف عند تنفيذ الدالة TerminateProcess , شغل البرنامج بـ F5 , وعند الوصول لها اضغط Crtl+F11 ولحظ تعليمات الأسمبلي جيدا , وحاول استنتاج المشكلة وسببها , لو جيبت الحل يبقى الدرس انتهى ;)

وضع الكود كله , ونسقه عشان يبقى سهل القراءة :P

#6

السلام عليكم

بالنسبة ل

اقتباس
غير هذا الكود

كودFARPROC hook;

struct T6Bytes
	{
  BYTE P;
  FARPROC addr;
  BYTE R;
} OldBytes, NewBytes;

الى

كودFUNCHOOK hook;

struct T6Bytes
	{
  BYTE P;
  FUNCHOOK addr;
  BYTE R;
} OldBytes, NewBytes;

فعلتها سلفا ،

اما الكود الثاني فلم افعله ،

سأغيره واحاول مجددا ،،

اقتباس
وعند اختبار الكود ضع نقطة توقف عند تنفيذ الدالة TerminateProcess , شغل البرنامج بـ F5 , وعند الوصول لها اضغط Crtl+F11 ولحظ تعليمات الأسمبلي جيدا , وحاول استنتاج المشكلة وسببها , لو جيبت الحل يبقى الدرس انتهى

يعني عندما اغير لن تنحل المشكلة ،،

المشكلة ان معلوماتي ضعيفة بالأسمبلي ،،

الله يسهل ،،

احاول اليوم ،،

وغدا لنا عودة بعون الله ،،

جزاك الله خيرا على صبرك وتعاونك ،،

السلام عليكم

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#7
اقتباس
المشكلة ان معلوماتي ضعيفة بالأسمبلي ،،

اين Assembly ...

ثم لو تريد التعمق اكثر عليك بتعلمه...يفيدك خاصة في التنقيح...

سارفق لك كتاب.... :) ؟

تم تعديل هذه المشاركة بواسطة محمدعبد العزيز في 6 سبتمبر 2006 في 18:13

d4baa0.gif
#8

السلام عليكم ،

انا فعلا بدأت بالتعلم اسمبلي ،

لكني لسه مبتدأ

لدي معلومات لكنها بسيطة ،

لكن مادام هناك ارادة ،، لا صعب ولا مستحيل ،،

بأنتظار كتابك اخي ،،

وجزاك الله كل خير ،،

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#9
اقتباس
اين Assembly ...

ثم لو تريد التعمق اكثر عليك بتعلمه...يفيدك خاصة في التنقيح...

الأسمبلي مطلوب هنا فقط لحظة تنقيح البرنامج , بهدف معرفة نقطة الخلل ;)

#10

السلام عليكم ،

اخي احمد ،،

يؤسفني ان اقول مافي فايدة ،، لقد فشلت في معرفة السبب ،

لقد حاولت ،، ولكن معلوماتي البسيطة لم تسعفني ،

،

انا اتوقع ان الغلط هنا ،

 NewBytes.addr= (FUNCHOOK) NewFun;

هنا لا يتم اعطاء العنوان بصورة صحيحة ،

،

هذا ما ظهر لي عند الدالة Terminate

91:	   TerminateProcess(GetCurrentProcess(),0);
00401297   mov		 esi,esp
00401299   push		0
0040129B   mov		 edi,esp
0040129D   call		dword ptr [__imp__GetCurrentProcess@0 (00425198)]
004012A3   cmp		 edi,esp
004012A5   call		__chkesp (00401360)
004012AA   push		eax
004012AB   call		dword ptr [__imp__TerminateProcess@8 (00425190)]
004012B1   cmp		 esi,esp
004012B3   call		__chkesp (00401360)
92:
93:
94:				   return TRUE;
004012B8   mov		 eax,1
004012BD   jmp		 DlgProc+168h (004012c8)
95:
96:
97:
98:		   }

لم افهم الكثير ،

يعني انا ببساطة كنت متوقع ان اجد ايعاز call اما الى عنوان دالتنا الجديدة (اذا عملنا هوك) او ايعاز call الى عنوان الدالة الاصلية (اذا لم نضغط على زر هوك)

لكن العناوين التي ظهرت جميعها غريبة ،،

هل هذا خطأ ؟؟

بأنتظار ردك اخي ،،

السلام عليكم

تم تعديل هذه المشاركة بواسطة الاخير زمانه في 7 سبتمبر 2006 في 11:08

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#11
اقتباس
وضع الكود كله , ونسقه عشان يبقى سهل القراءة
نفذ الكود خطوة خطوة الى ان تصل الى هذا السطر , بالضغط على F10

 004012AB   call		dword ptr [__imp__TerminateProcess@8 (00425190)]

عند الوقوف على هذا السطر اضغط F11, ستنتقل الى تنفيذ الدالة TerminateProcess , انظر في اول أسطر , يوجد خطأ حاول ان تستنتجه , حااااول

لو قولتلك على التعديل مباشرة لن تفهم ما الخلل

تم تعديل هذه المشاركة بواسطة Asm4all في 7 سبتمبر 2006 في 12:49

#12

السلام عليكم ،،

اقتباس
وضع الكود كله , ونسقه عشان يبقى سهل القراءة

لم افهم قصدك ؟؟ :)

اقتباس
حااااول

سأحاول مجددا ،،

تحياتي لك

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#13

السلام عليكم ،

عدت و الاسئلة تملئ جعبتي :wacko:

اولا ،

بالنسبة لفكرة العمل نفسها ،

هنا

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

Push XXXX
Ret

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

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

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

يعني انا لو لدي برنامج اسمبلي به

Mov
Add
…
…
…
Push address of any fun.
Ret
…
…

عندما يصل التنفيذ الى ايعاز push ، ما الذي سيحدث ؟

سيتم وضع القيمة في ال stack ،

ماذا يحصل بعدها ؟؟

هل سيتم تنفيذ هذا العنوان الذي وضع في ال stack ؟؟ (سؤال اسمبلي ;) )

يعني قصدي الا يجب ان يكون ايعاز call مثلا ؟؟

ثم ايعاز ال ret ، ماذا يفيد ؟؟

الى اين اعود وانا اساسا في البرنامج ؟؟

يعني انا حسب ما اعرف انه عندما نكتب اجرائية نضع في نهايتها ret ليعود الى البرنامج ،

لكن هنا الى اين يعود ؟؟

(عندما جربت طريقتكاخي احمد بتتبع البرنامج ب F11 ، خطرت ببالي هذه الاسئلة :) )

هذا الكود كاملا

#include<windows.h>
#include"resource.h"


LRESULT CALLBACK DlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 



typedef UINT (*FUNCHOOK) (HANDLE , UINT);


FUNCHOOK funhook;

struct T6Bytes
	{
  BYTE P;
  FUNCHOOK addr;
  BYTE R;
} OldBytes, NewBytes;

	unsigned long i;

BOOL   NewFun(HANDLE  hProcess,UINT  uExitCode )

{

if((MessageBox(0,"Are You Sure ??" , "Close",MB_YESNO)== IDYES ))
			{
WriteProcessMemory(GetCurrentProcess(), funhook, &OldBytes, sizeof(OldBytes), &i);
TerminateProcess(GetCurrentProcess(),0);

			}

return TRUE;
}



int WINAPI WinMain(HINSTANCE hInstance  , HINSTANCE  ,	LPSTR  , int  )
{

 DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1),0, (DLGPROC) DlgProc );
return 0; 


}


LRESULT CALLBACK DlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

  HINSTANCE h = GetModuleHandle("kernel32.dll");
	if(h == NULL) 
	 h = LoadLibrary("kernel32.dll");
	funhook = (FUNCHOOK)GetProcAddress(h, "TerminateProcess");




	 switch(message)
   {

	case WM_INITDIALOG:


	return TRUE;



	case WM_COMMAND:
		switch(wParam)
		{

case IDC_HOOK :


if(ReadProcessMemory(GetCurrentProcess(), funhook, &OldBytes, sizeof(OldBytes), &i))
 {
	NewBytes.P = 0x68;
	NewBytes.R = 0xC3;
 	NewBytes.addr= (FUNCHOOK) NewFun; 
	 WriteProcessMemory(GetCurrentProcess(), funhook, &NewBytes, sizeof(NewBytes), &i);




}



return TRUE;


case IDC_TERM:

	TerminateProcess(GetCurrentProcess(),0);



return TRUE;



		}




 return TRUE ; 

	 }



	return FALSE;

}

لقد فعلت ما قلت لي ،

هذا شيء مما ظهر لي

7C801E16   push		14000000h
7C801E1B   adc		 byte ptr [eax],al
7C801E1E   ret

هنا لو حاولت التتبع ، يقف السهم عند السطر الثاني

7C801E1B   adc		 byte ptr [eax],al

و يظهر لي هذا الخطأ

First-chance exception in APIHook1.exe (KERNEL32.DLL): 0xC0000005: Access Violation.

هنا اريد ان اسأل

هذه الدالة ، الان مايظهر لي ، المفروض ان اول 6 bytes هي التي نحن قمنا بكتابتها ، تمام والا انا غلطان ؟؟

اقصد هل هذه

7C801E16   push		14000000h
7C801E1B   adc		 byte ptr [eax],al
7C801E1E   ret

تقابل هذه

68
ْXXXX
C3

حسنا ، نحن نعمل push لعنوان دالتنا ، ما هذا العنوان اذا 14000000h ؟؟

المشكلة انا لسه متلخبط بشغلة في صلب الموضوع ،

نحن نعمل push لعنوان دالتنا ام نعمل push للعنوان الحالي الواقفين عليه لنحتفظ به ؟؟

اخ محمد يقول

اقتباس
Push XXXX

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

-------------

انظر اخي الى هذا الحطأ ايضا الذي يظهر اثناء التتبع

Error symbol "TerminateProcess" not fount

هل المشكلة هنا ؟؟

انا في بادئ الامر ظننت ان المشكلة هنا

	funhook = (FUNCHOOK)GetProcAddress(h, "TerminateProcess");

وان عنوان ال funhook لا يمثل عنوان ال TerminateProcess بعد هذه الخطوة ، أي يحصل خطأ في جلب العنوان

لكني جربت هكذا

	funhook = (FUNCHOOK)GetProcAddress(h, "TerminateProcess1");

وعندما نفذت ، تنفذت دالة ال Terminate مباشرة حتى بعد الضغط على زر هوك (ولم تظهر المسج بوكس .. عادي)

لأن العنوان الذي تمت عملية الكتابة والقراءة عليه هو عنوان خاطئ اساسا ،،

 TerminateProcess1

يعني معناها ان العملية الاولى اتت بالعنوان صحيح وفعلا تمت الكتابة عليه لكن الكتابة تمت بصورة خاطئة ولهذا يظهر لي error ،

لكن المشكلة ان عنوان ال terminate لا يرتبط مع عنوان ال newfun

،

عملت شي ثاني ايضأ

غيرت هذا

	
case IDC_TERM:

	TerminateProcess (GetCurrentProcess(),0);
	return TRUE;

الى هذا

	
case IDC_TERM:

	NewFun(GetCurrentProcess(),0);
	return TRUE;

وهنا تنفذت الدالة NewFun بصورة صحيحة ،

ولأتأكد مما أردت ان احصل عليه

دالة ال NewFun

BOOL   NewFun(HANDLE  hProcess,UINT  uExitCode )

{

if((MessageBox(0,"Are You Sure ??" , "Close",MB_YESNO)== IDYES ))
			{
//WriteProcessMemory(GetCurrentProcess(), funhook, &OldBytes, sizeof(OldBytes), &i);
TerminateProcess(GetCurrentProcess(),0);

			}

return TRUE;
}

قمت بحذف هذا السطر

//WriteProcessMemory(GetCurrentProcess(), funhook, &OldBytes, sizeof(OldBytes), &i);

عندها لن تتنفذ الدالة بصورة صحيحة ،

لأني لم اعد كتابة البيانات الاصلية الى الدالة ،

اذا

هذه الخطوة

ReadProcessMemory(GetCurrentProcess(), funhook, &OldBytes, sizeof(OldBytes), &i)

وهذه

WriteProcessMemory(GetCurrentProcess(), funhook, &OldBytes, sizeof(OldBytes), &i);

صحيحة

،،

المشكلة في هذه الاسطر ،،

NewBytes.P = 0x68;
NewBytes.R = 0xC3;
NewBytes.addr= (FUNCHOOK) NewFun; 
WriteProcessMemory(GetCurrentProcess(), funhook, &NewBytes, sizeof(NewBytes), &i);

لكن اين ؟؟؟؟؟

--------

المشاركة اصبحت طويلة !!

راح ادوخك واتعبك اخي احمد معي ،،

بوركت وجزاك الله كل خير

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#14

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

على عجالة

7C801E16   push		14000000h
7C801E1B   adc		 byte ptr [eax],al
7C801E1E   ret

 Push XXXX
Ret

تلاحظ وجود خطأ

المفروض أن الـ Structure حجمها 6 بايت , اليس كذلك؟

انظر ماذا يعود من

 sizeof(T6Bytes)

المهم المشكلة في الـ Structure

انظر في هذا الموضوع

شغل مخك مع السي ++

فقط أضف هذا السطر في بداية الكود

 #pragma pack(1)

و لي عودة لاجابة تساؤلاتك , و تحليل البرنامج

تم تعديل هذه المشاركة بواسطة Asm4all في 8 سبتمبر 2006 في 14:51

#15

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

address1: call function
address2: mov r, eax
....
....
address3: function:
			   ....
			   ....
			   ....
			   ret

عند تنفيذ السطر الأول عند address1 والذي يحتوي التعليمة call , يتم حفظ العنوان address2 في الـ stack كي نعود لهذا العنوان

ويتم الانتقال الى السطر address3 والتنفي> الى أن تصل للتعليمة ret

يسترجع الامر ret اخر قيمة في الـ stack وتكون هي عنوان الرجوع , هذه القيمة هي نفسها التي تم حفظها عند استدعاء التعليمة call وهي العنوان address2

اذا لو قمنا بعمل push لقيمة قبل التعليمة ret ستأخذها التعليمة على انها عنوان الرجوع

اذا call تحفظ عنوان الرجوع و ret تستخدم عنوان الرجوع

اقتباس
نحن نعمل push لعنوان دالتنا ام نعمل push للعنوان الحالي الواقفين عليه لنحتفظ به ؟؟

لعنوان دالتنا , العنوان الذي نريد الانتقال اليه من هذه النقطة

هي بالحرف تعني :

jmp XXXX

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

#16

السلام عليكم ،

كيف الصحة اخي احمد ؟

جزاك الله خير على الرد ،،

سأقرءه بتمعن في البيت ،،

وسأحاول التنفيذ ،،

ويارب يتنفذ :)

مشكور و تحياتي لك ،،

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#17

السلام عليكم ،

الحمد لله تنفذ البرنامج ،،

والخطأ عجيب ،، :huh:

هنا

if(ReadProcessMemory(GetCurrentProcess(), funhook, &OldBytes, sizeof(OldBytes), &i))

قيمة ال i هي 12

و بعد كتابة السطر الذي ذكرته اصبحت 6

،

الان ،، ماذا ينتظرني :(

انا عايز توجيه منك اخي احمد ،،

ماذا اقرء وكيف ابدء ،،

--

الان هذا البرنامج لو اردت ان اعممه ماذا احتاج ،

و ممكن شوية توضيح عشان اعرف ماذا اقرء ،،

مثلا لدي الاتي ،

الفصلل 22 من الكتاب الذي اعطيتني اياه

مقالة three ways to inject your code into aother process

و هذه ايضا StraceNT

،،

ايها تفيدني في هذه المرحلة

انا الان اقرء StraceNT و استوقفتني ملفات PE

بصراحة لم اكن اعرف عنها شيء ، بحثت في ال msdn وايضا قمت بجولة في الهارد تبعي ووجدت درس للأخ احمد غريب ودروس Iczelions

انا الان اقرء ولله الحمد ماشي ،،

هل لديك شي ثاني او درس او مقالة سهلة ممكن تفيدني ،،

واهم شي ،،

انا عاوز توجيه منك اخي و من كل من سبقني في هذا المجال ،،

------

و بأنتظار درس اخونا محمد عبد العزيز ;)

،،

تحياتي لك

وجزاك الله كل خير

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#18

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

اقتباس
الخطأ عجيب
يعني معرفتش ايه المشكلة

طيب عموما للقرائة في هذا الموضوع , لديك العديد من المصادر

الفصلل 22 من الكتاب ايه

Three Ways to Inject Your Code into Another Process

API hooking revealed

HookAPI source code

Process-wide API spying - an ultimate hack

Hooking

Peering Inside the PE

An In-Depth Look into the Win32 Portable Executable File Format

An In-Depth Look into the Win32 Portable Executable File Format, Part 2

ومتنساش www.google.com :D

CBJ_2004_40.pdf

تم تعديل هذه المشاركة بواسطة Asm4all في 10 سبتمبر 2006 في 14:32

#19

السلام عليكم ،

اقتباس
يعني معرفتش ايه المشكلة

انا مستغرب ان حجم struct خاطئ يعمل كل هذه البلاوي التي كانت تظهر لي في العناوين والتنفيذ ...

--

مشكور اخي الكريم على هذه الروابط ،،

الله يعين ،،

اظني سأتغيب كم يوم وسأقرء ثم اعود لأسأل

(يالا راح تاخذ اخي احمد rest مني و من اسئلتي :lol: )

سأقرء وسأعود ،،

كدت انسى ،،

هذا

اقتباس
أستطيع أن اعطيك مثال بسيط يشرح طريقة الـ API Hook لـ Process اخرى (هوك لـ MessageBoxA )

أظنه جاء دوره ،، بعد ان اقرء سأكون بحاجة الى ان اطلع على مثال .. ;)

يعني اذا امكن اخي حمد ، ممكن ان ترفقه ؟

--------

تحياتي لك

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#20

السلام عليكم ،

ها قد عدتُ ،،

كيف الصحة اخي Asm4all

لم استطع ان اطيل الغيبة كثيرا :)

انا حاليا اقرء ولله الحمد ،،

تواجهني صعوبات في فهم بعض الاشياء ،، وخاصة IAT

لكني لن اسأل الان لأني للأن قرأت الموضوع مرة واحدة ،،

بعد ان اقرء الموضوع للمرة الثالثة سيبدأ النقاش ;)

سأعطي ملخص لما فهمت ،،

احتمال كبير اني فهمت غلط لأن هكذا امور لاتفهم من اول مرة ،،

لكن سأدون هنا ما فهمت لأذكر نفسي

وان كنت فهمت غلط ،،

ممكن توضحو لي الصورة -_-

---------

هناك اكثر من طريقة لعمل ال API hook

مثلا

Import Address Table Hooking

اهم عيب في هذه الطريقة انه الدوال التي تتحمل عن طريق LoadLibrary ثم GetProcAddress تنفذ من عملية الخطف !!!!!!!

الحل ،،

ممكن عمل هوك على الدالتين LoadLibrary و GetProcAddress ،، وبدمجها مع الطريقة الاولى يكون الخطف على جميع الدوال !!!

طريقة ثانية

Inline Function Hooking

اظنها نفس الطريقة المطروحة في مثال الاخ محمد :rolleyes:

لدي اسئلة على هذه الطريقة ولكن كما قلت سلفا ،،

سأضعها فيما بعد ..

و أظن انه هناك طرق اخرى ،،

لم انتهي من القراءة بعد

،،

المهم ..

اهم نقطة بالنسبة لي ،، (هل فهمي صحيح ؟؟)

لتعميم أي نوع من هذه الانواع ،،

نضع عملنا والدوال في dll ثم نقوم بحقن ال dll في البروسيس الاخرى

و ايضا تتم عملية الحقن بأكثر من طريقة ،

اولها الرجستري ،

قديمة :lol:

طريقة ال Windows Hooks

وهنا اريد ان اسأل ،،

هل الكلام التالي صحيح ،

نحن الان نريد تحميل ال dll الى بقية البروسيس ،

لذا نقوم بعمل sys.hook مثلا على الماوس او الكيبورد ،

وعندما يضغط المستخدم على الماوس او الكيبورد يتم تنفيذ الهوك وبالتالي يتحمل ال dll (التي تحوي على ال api-hook اضافة الى sys. hook) الى البروسيس ،

؟؟

الطريقة الثالثة هي عن طريق الدالة

CreateRemoteThread

نقوم بكتابة ثريد في بروسيس اخرى ،

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

لكي تحمل هذه المكتبة الى البروسيس المطلوبة ،،

هنا لدي مشكلة ،

كيف اعرف عدد البروسيس التي تعمل ثم كيف احصل على ال ID لكل منها لكي اقوم بتحميل ال dll الى تلك البروسيس ؟؟

هذه فكرتي الاولية عن الموضوع ،

كما ذكرت ،،،

احتمال كبير وجود اخطاء ،،

و ارجو التصحيح ،،

بصراحة لم اصبر اكثر وحبيت ان اطل عليكم ،،

،،

طبعا انا اخذت بنصيحة اخونا الاستاذ احمد غريب ،، احاول فهم الفكرة العامة حاليا ولا اغوص في الامور الصغيرة ،،

-----

اخواني ..

Asm4all

محمد عبد العزيز

اتمنى ان ارى تعليقكم ،،

وممن كل من لديه معلومات ،،

يومان او ثلاث وسأعود مجددا ،،

تحياتي لكما

وبارك الله بالجميع ،،

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#21
اقتباس
ممكن عمل هوك على الدالتين LoadLibrary و GetProcAddress ،، وبدمجها مع الطريقة الاولى يكون الخطف على جميع الدوال !!!
عمل هوك على GetProcAddress يكفي ;)
اقتباس
كيف اعرف عدد البروسيس التي تعمل ثم كيف احصل على ال ID لكل منها لكي اقوم بتحميل ال dll الى تلك البروسيس ؟؟

 BOOL EnumProcesses(DWORD* pProcessIds, DWORD cb, DWORD* pBytesReturned);

توجد طريقة , تستخدم فيها WriteProcessMemory و CreateRemoteThread , لا تحتاج الى dll

فهمك الى الان جيد للموضوع , اكمل القراءة :)

#22

السلام عليكم ،،

اقتباس
توجد طريقة , تستخدم فيها WriteProcessMemory و CreateRemoteThread , لا تحتاج الى dll

جميل ،،

اظني لم اقرء عنها للأن ،،

اظن ان استخدام ال sys. hook للحقن افضل (اسهل) من استخدام CreateRemoteThread ،

هذا اذا كان فهمي صحيح :lol:

اقتباس
فهمك الى الان جيد للموضوع , اكمل القراءة

جميل ان ترى من يشجعك :rolleyes:

جزاك الله خير الجزاء يا اخي احمد ،،

تقريبا انتهيت من قراءة المصادر التي لدي

ومن اليوم بدأت بمراجعة المواضيع من البداية وبدأت اسجل الملاحظات لأضعها هنا ;)

اريد ان نناقش بعض الامور النظرية

ومن ثم البداية الفعلية في كتابة الاكواد (والله اني خايف حتى في بعض الاحيان اقول لي نفسي ،، ماذا دخلني في هذه المواضيع ؟؟!! لكن المشكلة ان المادة شيقة وممتعة رغم صعوبتها ،، يعني بتحس انك بتعمل حاجة !!)

الله يعين ويسهل ،،

السلام عليكم ،،

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#23

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

بصراحة لا ادري من اين ابدء ،،

حان وقت التطبيق العملي .. اذن حان وقت المشاكل :lol: :lol: :huh:

أظن سيكون عملي كالاتي :

1- سأحاول كتابة مثال بسيط (نفس مثال الاخ محمد عبد العزيز) بطرقة Import Address Table Hooking

2- تطبيق مثال بسيط يستخدم CreateRemoteThread لحقن مكتبة dll في بروسيس اخرى

3- تعميم برنامج الهوك في النقطة رقم واحد ليعمل على كل البروسيس (بالمشمش !!) ..

اخي احمد .. ارجو ان تبقى معي للنهاية :rolleyes:

،،

لنبدأ من البداية ،،

طرق عمل ال api-hook

تقريبا انا استقريت على طريقة Import Address Table Hooking ،

بعد قراءتي لهذا

API Hooking by Overwriting Code
This method was heavily used by 16-bit Windows programmers and worked just fine in that environment. Today, this method has several serious shortcomings, and I strongly discourage its use. First, it is CPU-dependent: JUMP instructions on x86, Alpha, and other CPUs are different, and you must use hand-coded machine instructions to get this technique to work. Second, this method doesn't work at all in a preemptive, multithreaded environment. It takes time for a thread to overwrite the code at the beginning of a function. While the code is being overwritten, another thread might attempt to call the same function. The results are disastrous! So this method works only if you know that no more than one thread will attempt to call a particular function at any given time.

هل توافقون الكاتب الرأي ؟؟!! -_-

بالنسبة لطريقة Import Address Table Hooking

هل بها مساوء ؟؟

لم افهم معنى هذا (بصراحة) من مقالة StraceNT – System Call Tracer for Windows NT

Disadvantages
o Have to deal with issues on how to execute our hook functions in the
context of the target process.

،،

برمجيا ...

من مقالة StraceNT – System Call Tracer for Windows NT

void
PatchModule(
LPVOID moduleBaseAddress)
{
PIMAGE_DOS_HEADER pIDH = (PIMAGE_DOS_HEADER)moduleBaseAd dress;
PIMAGE_NT_HEADERS pINTH =
(PIMAGE_NT_HEADERS)
(moduleBaseAddress + pIDH->e_lfanew);
DWORD dwImportTableOffset =
pINTH->OptionalHeader.DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
PIMAGE_IMPORT_DESCRIPTOR pIID =
(PIMAGE_IMPORT_DESCRIPTOR)
(moduleBaseAddress + dwImportTableOffset);
//
// At this point pIID points to an array of Import Address Table,

هنا الامر واضح ،، حسب بنية ملف ال pe ، الكود السابق يحاول الوصول الى بداية العنوان ،،

اما من الفصل 22

فلقد استغنى عن هذه الخطوات بدالة

 PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
	  ImageDirectoryEntryToData(hmodCaller, TRUE, 
	  IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);

،،

هل كلامي السابق مضبوط ؟؟

بالنظر الى ال msdn يقول

Return Values
If the function succeeds, the return value is a pointer to the directory entry's data.

،،

كلام واضح ..

،، طيب

void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, 
   PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller) {

   ULONG ulSize;
   PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
	  ImageDirectoryEntryToData(hmodCaller, TRUE, 
	  IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);

   if (pImportDesc == NULL)
	  return;  // This module has no import section.

   for (; pImportDesc->Name; pImportDesc++) {
	  PSTR pszModName = (PSTR) 
		 ((PBYTE) hmodCaller + pImportDesc->Name);
	  if (lstrcmpiA(pszModName, pszCalleeModName) == 0) 
		 break;
   }

   if (pImportDesc->Name == 0)
			return; 

   PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) 
	  ((PBYTE) hmodCaller + pImportDesc->FirstThunk);

   for (; pThunk->u1.Function; pThunk++) {

	  PROC* ppfn = (PROC*) &pThunk->u1.Function;

	  BOOL fFound = (*ppfn == pfnCurrent);



	  if (fFound) {
			WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew, 
			sizeof(pfnNew), NULL);
		 return;  // We did it; get out.
	  }
   }

}

الكود السابق ايضا من الفصل 22 ،

المشكلة التي تواجهني ،، هنا

في هذا ال struct

PIMAGE_THUNK_DATA

لم اجد شرحا له حتى في ال msdn

فتحت ملف windows.h فلم اجده ،، لماذا ؟؟

في ملف windows.inc وجدت هذا

MAGE_THUNK_DATA32 STRUCT
	union u1
		ForwarderString dd  ?
		Function dd		 ?
		Ordinal dd		  ?
		AddressOfData dd	?
	ends
IMAGE_THUNK_DATA32 ENDS

لا ادري اهو نفسه ؟

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

typedef struct _IMAGE_THUNK_DATA {
union {
PBYTE ForwarderString;
PDWORD Function;
DWORD Ordinal;
PIMAGE_IMPORT_BY_NAME AddressOfData;
};
} IMAGE_THUNK_DATA,*PIMAGE_THUNK_DATA;

المشكلة اني لا اعرف شرح هذه العناصر وبالتالي خطوة مثل هذه

   for (; pThunk->u1.Function; pThunk++)

او هذه

if (!IMAGE_SNAP_BY_ORDINAL(pIINA->u1.Ordinal))

لا ادري ماذا تعني !!!

،،

شي ثاني

هنا

To patch an IAT entry, we will first make the memory location
of IAT entry writable

اليس المقصود استخدام هذه الدالة

VirtualProtect

متى يتوجب علي استخدام هذه الدالة تحديدا ،،

ففي بعض المقالات تم ذكرها وفي البعض الاخر لا ؟؟

حتى في موضوع الاخ محمد عبد العزيز ،، هناك احد الاعضاء سأل وكان جواب محمد

اقتباس
إن كانت لديك الصلاحية في تغيير ماتريد لا تحتاج ل VirtualProtect

و إن لم يكن لديك تستخدمها،

متى لدي الصلاحية ومتى لا ؟؟ :wacko:

الان مثلا لو اريد عمل تطبيق بسيط على دالة TerminateProcess

كيف ستكون الخطوات ؟؟

اولا اعرف دالة MyTerminateProcess

سؤال .. هل يجب ان يكون لها نفس تعريف الدالة الاصلية ؟؟

وبداخل هذه الدالة اضع ما اريد ..

ثانيا اعرف دالة ReplaceIATEntryInOneMod كما في الفصل 22

وفي داخل ال WinMain

case IDC_TERMINATE :
TerminateProcess (..);
Break;
case IDC_HOOK :
ReplaceIATEntryInOneMod(...);
Break;

هنا في هذه الدالة ReplaceIATEntryInOneMod لم يتم بالأحتفاظ بعنوان الدالة الاصلية قبل كتابة عنوان دالتنا ،

ألسنا بحاجة الى حفظ عنوان الدالة الاصلية اذا اردنا مثلا الرجوع اليها ؟؟

**

اليوم كنت اقرء بمقالة StraceNT

بصراحة لم استطع فهم الكود ووضع الخطوط العريضة له (الظاهر كنت نص نايم :P لاني كنت اقرء بعد صلاة الفجر)

و لا ادري ما سر ايعازات الاسمبلي التي تملء الكود ؟؟!! :o

احمد هل لديك برامج هذه المقالات والبرنامج المذكور في الفصل 22 ،

اذا كان لديك هذه الامثلة فأرجو ان ترفقها ..

جزاك الله خيرا

-------------------

تحياتي ..

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#24

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

كان نفسي اكمل معاك يا اخي , لكن الدراسة بدأت اليوم والسنه دي حاسمة "سنة تخرج", ويجب اعطائها حقها واعطاء اهلي حقهم أيضا , لهذا سوف أتغيب عن المنتدى فتره قصيرة , سنه يا دوب :D

كمل انت مع الشباب في المنتدى , ومتنساش تدعيلي ربنا يوفقني السنه دي

اراك على خير

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

تم تعديل هذه المشاركة بواسطة Asm4all في 17 سبتمبر 2006 في 15:05

#25

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

،،

احمد هل تتكلم جد ؟؟

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

اقتباس
كمل انت مع الشباب في المنتدى

هم فين الشباب دول ؟؟

لا ادري لماذا لا يرد احد غيرك علي ؟؟

اقتباس
ومتنساش تدعيلي ربنا يوفقني السنه دي

والله انت تستاهل كل خير ،،

سأبقى ادعيلك ولن انسى جهدك وتعبك معي ..

اقتباس
ويجب اعطائها حقها واعطاء اهلي حقهم أيضا

كما يقول المصطفى صلى الله عليه وسلم ،، فيما معناه ان الله في عون العبد ما دام العبد في عون اخيه ،، وانت يا اخي ما قصرت معي وكنت خير عون لي ،، الله يسهل امرك ويعينك في جميع الامور

اقتباس
لهذا سوف أتغيب عن المنتدى فتره قصيرة , سنه يا دوب

عن جد سوف نفتقدك ،، وسوف افتقدك انا كثيرا ,,

بس انت هم حاول ان اطل علينا بين الحين والحين ،، :)

يعني لا تسويها من تمام وتختفي سنة كاملة :lol:

بكل تأكيد انا سأكمل المشوار ،،

وبعد عام راح اقلك ماذا حصل معي ;) :lol:

اخي احمد فقط انظر الى هذا

اقتباس
احمد هل لديك برامج هذه المقالات والبرنامج المذكور في الفصل 22 ،

اذا كان لديك هذه الامثلة فأرجو ان ترفقها ..

تحياتي لك ،،

اخوك زيد

;)

تم تعديل هذه المشاركة بواسطة الاخير زمانه في 18 سبتمبر 2006 في 08:14

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

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

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