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

سؤال عن تعديل كود البرنامج من داخل البرنامج

بدأه soufianosse في 9 يناير 2010 · 9 رد · 1,360 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

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

لنأخد برنامج بسيط

( خاصية وضع الكود لم تعمل معي )

#include<iostream.h>

void main()

{

char a[]="arabteam";

for (int i=0; i<10; i++)

cout << a << endl;

system ("PAUSE");

// code to change

return 0;

}

لتوضيح المعنى نريد عند فتح البرنامج اول مرة يتم تنفيد ما بداخله وعند الانتهاء يقوم بتعديل متلا عدد مرات التكرار الدي هو 10 بـ 5 متلا

عند فتح البرنامج مرة تانية سيطبع الجملة 5 مرات يعني انه تم التعديل في كود البرنامج من داخل البرنامج وستبقى دائما 5

طبعا هدا الامر يمكن عمله بعمل dissembling تم تعديل القيمة 10 وحفض البرنامج الجديد او عن طريق محرر الهكس او ...

لكن كيف يمكن ان نقوم بهدا من داخل البرنامج ؟ سيكون عبر كود اسمبلي لكن ما هي الطريقة ؟

تم تعديل هذه المشاركة بواسطة soufianosse في 9 يناير 2010 في 21:59

#2

ما تطلبه لن اقول غير ممكن و لكنه غير وارد الحدوث على الإطلاق لأن البرنامج بعد تحويله للصيغه التنفيذيه يصبح لا وجود للكود داخله و اقصد الكود الذى كتبته و ليس الذى انتجه المترجم و بالتالى لإتمام ما تقول تحتاج لإرفاق نسخه نصية من الكود و كذلك وجود المترجم بجميع ادواته مع برنامجك ثم تقوم بعمل التعديل الذى تريده ثم استدعاء المترجم بإستخدام الـ Command line ليحول النص المعدل إلى نسخه تنفيذيه التى بعد ذلك ستقوم انت بإبدالها بالنسخه الحاليه من البرنامج و هكذا.

مدونتي: C++ Tips and Tricks

#3

شكرا لك اخي

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

فمتلا عندما نعدل قفزة او نصفر كود بالكامل ونحفض البرنامج

او تعديل القيمة المقارن بها من 0 الى 1 او العكس

او كان المبرمج عامل امر مقارنة ( if ... ) فادا تحقق الشرط 1 او لم يتحقق 0 فعندما نعدلها الى 1 يصبح الشرط متحققا دائما

الا يعني هدا تعديل كود البرنامج ؟

عدلنا في كود الاسمبلي = تم التعديل في البرامج

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

فمتلا لو اخدنا كود الاسمبلي للحلقة for سنجده كالاتي

for (int i=0; i<10; i++) // C++ line
// equalivant ASM code
	mov dword ptr ,0 // i = 0
	jmp main+54h (411504h) // enter IF loop

	mov eax,dword ptr  // /
	add eax,1 	// | i++
	mov dword ptr ,eax // \

	cmp dword ptr ,0Ah // i < 10?
	jge main+86h (411536h) // if greater/equal > exit IF loop

ما سنغيره هو 0Ah وهي القيمة 10 نغيرها لـ 5h لتبقى دائما

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

تم تعديل هذه المشاركة بواسطة Xacker في 10 يناير 2010 في 03:27 — السبب: وضع تعليقات على الكود

#4
اقتباس
لكن كيف تفسر ما تفعله محرارة الهكس او بالاحرى برامج التنقيح

كل امر فى الأسمبلى يقابل Opcode معين و هو ما يتم حفظه بالملف التنفيذى و عندما يتم تحميل البرنامج فى الذاكره يتم تنفيذ الـ opecodes من قبل البروسسور و ما تفعله انت من داخل محررات الهكس هو تغيير opcode بأخر لتغيير حالة شرط او قيمه معينه. و المترجمات سميت مترجمات لأنها تترجم الكود المقروء إلى الـ opcodes التى يفهمها البروسسور. و حيث ان ادنى مستوى لدينا هو الأسمبلى لذا فتعديلك للـ opcodes فأنت توجهه كلامك مباشرة للبرسسور.

بالنسبه ما تفعله برامج التنقيح فهو مختلف، لا اعرف ان كنت فهمت ما تقصد تماما و لكن ما همته انا من كلامك عن كيفية اظهار برنامج التنقيح لكود مثل السى و المقابل له بالأسمبلى اثناء التنقيح. هذا الأمر يتبع اسلوب كتابة الملفات التنفيذيه بويندوز اكثر مما يرتبط بالكود التنفيذى للبرنامج فكل ما يحدث هو اثناء برمجتك للبرنامج (النسخه التنقيحيه Debug) يتم انشاء ما يسمى بالـ Code views و يتم تخزينها بملفات خارجيه تأخذ الإمتداد PDB او تسمى بـ Program Database و هى تحتوى على رقم السطر و الكود التنفيذى المقابل له و حجمه داخل الملف التنفيذى و من داخل الملف التنفيذى نفسه يتم وضع Link يبرط الملف التنفيذى بالـ Program Database لذا عندما يحدث ان تقوم بعمل تنقيح للبرنامج بعض برامج التنقيح (مثل OllyDbg او MS VS Debugger) يقوم بإظهار سطر الكود و ما يقابله بالأسمبلى.

ملحوظه: الأسمبلى هى الكلمات المقروءة للـ Opcodes ألتى يفهمها البروسسور.

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

اقرء الملاحظه التى كتبتها بالأعلى و ستعرف ان كل ما تفعله المنقحات هو تحويل الـ Opcodes إلى الصيغه المقروءه و قم بالرجوع إلى مراجع Intel او AMD ستجد فيهم الفظ (التعليمه) و الـ opcode و شرح لهم.

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

ليس لدى اكثر مما قلت فإن ابتغيت توضيح اكثر فأنا و كل الأخوه موجودين.

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#5

اولا شكرا لك اخي الكريم على هدا التوضيح لكن ربما لم تفهم ما اقدصده بالضبط

متلا في olly يمكن ان تغير قفزة في البرنامج وتبقى للابد متلا لو عدلت jne الى jmp وحفضت البرنامج فستبقى jmp للابد

تقوم المنقحات بعمل هدا التغيير وحفضه وهدا يعني تعديل الـOpcode

والسؤال هو كيف نعمل هدا التعديل من داخل البرنامج ؟

بشكل اوضح تحديد opcode لهدا السطر cmp dword ptr ,0Ah وتعديل 0Ah الى 5h

#6

*صراحة* لا أعلم إن كانت دوال مثل CreateFile أو CreateFileMapping وخلافها من الدوال لا تستطيع الحصول على صلاحيات كتابة على ملف قيد العمل (البرنامج نفسه الذي توجد فيه) - حتى لو لم تستطع التعديل على البرنامج قيد العمل في أسوأ الحالات، يمكنك تجاوز هذه المشكلة بإنشاء process في الذاكرة وإنهاء البرنامج الأساسي..

بالتالي يصبح بإمكانك قراءة البرنامج, والتعديل على القيم التي تشاء فيه ببساطة (والتي يفترض أنك تعلم إزاحتها بالضبط ضمن البرنامج وهذا ليس بالشئ الصعب معرفته) ومن ثم تقوم بحفظه.

هذا البايت (تجاوزاً) - يمكن الحصول عليه من تلك الإزاحة، وإجراء الحسابات اللازمة عليه شريطة ألا تغير من حجم الـ mnemonics التابعة للـ opcode، أي لو كان بايت فيجب أن يبقى ضمن حدود بايت وإلا سيتغير لديك كل شئ يليه وستتغير مواصفات الـ sections..

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#7

اهلا اخي xacker

هل تقصد التعديل على البنرنامج في الداكرة ؟

يعني استعمال WriteProcessMemory كما نفعل مع Trainer ؟

ام تقصد ان ننشئ برنامج فرعي دوره هو انهاء البرنامج الرئيسي تم اعادة تحميله باستعمال createfile + creatfilemapping

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

تم تعديل هذه المشاركة بواسطة soufianosse في 10 يناير 2010 في 04:01

#8

أقصد الثانية، ولا تحتاج إلى برنامج فرعي (أو بالأحرى مجرّد process يتم إنشاؤها في runtime) إلا في حال لم يكن بالإمكان التعديل على البرنامج أثناء تشغيله من داخل نفسه (جرب اكتب برنامج صغير بالأسمبلي للقيام بالعملية)

أما كيف تحصل على الإزاحة (مثلاً) فالأمر بسيط بالأسمبلي..

label:	cmp	ecx,5
	;
	; loop statement here
	;
	mov	eax,label ; eax holds the absolute addr

العنوان تستطيع أن تمرره كـ command line للـ Process المنشئ في الذاكرة على سبيل المثال.

من العنوان تستطيع حساب الإزاحة على القرص (وليس في الذاكرة) - ستحتاج معلومات عن بنية PE.

والتعديل أمر بسيط.

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#9

مممم شكرا لك اخي xacker وايضا الاخ Muhammad alaa

ساجرب الامر ان شاء الله

#10

السلام عليكم.... لدي طريقة

اولا قم بانشاء متغير حرفي يحمل القيمة التي تريدها في التكرار...مثلا

#include<stdlib.h>
char cntr[3] = "005";
...
for(int i=0; i< atol(cntr); i++)
{
//do somthings
}

بعد ذلك ترجم البرنامج وافتح الملف التنفيذي باي محرر Hex واحصل على عنوان ال 005 في الملف و ليكن مثلا 0x2000

نعود الى الكود و نضيف كود يقوم بتغيير ال 005 في كل مرة يتم فيها تشغيل البرنامج

FILE F = fopen("me.exe", "wb+");
BYTE data[3];
//set in data any new value you want to save
fseek(F, 0x2000);
fwrite(data, sizeof(data), 1, F);
fclose(F);

قم بوضع كود يعطي قيمة جديدة ل data في كل مرة... طبعا تحتاج الى انشاء Processs جديد كي تتمكن من التعديل على الملف...

على كل حال هذه الطريقة تعمل جيدا عي

[سبحان الله و بحمده, سبحان الله العظيم]

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

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…