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

الحصول على قيمة Eip

بدأه zirek99i في 4 ديسمبر 2013 · 9 رد · 2,340 مشاهدة · في اختبر قداراتك
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

كيف حالكم أصحاب، 

أتمنى تكونوآ في ألف خير

 

جلبت لكم اليوم تحدي سهل بسيط وممتع في نفس الوقت.

 

الهدف من التحدي هو الحصول على قيمة Eip للتعليمة التي سيتم تنفيذها حالياً.

 

الشروط

عدم إستخدام أي دالة من دوال الـ API كـ GetThreadContext أو RtlCaptureContext

يجب أن يكون البرنامج Cross platform

الـ inline assembly كود غير متاح، يمكنك أن تستخدمه لكن الحل لن يقبل كحل نهائي.

 

مدة التحدي 24 ساعة

الجواب سأضعه غداً إن شاء الله.

 

أتمنى أن تستمتعوآ

دمتم في رعاية الله وحفظه.

1
#2

هل ينفع شيء كهذا |:

#include<cstdio>
int main()
{
    printf("0x%x\n",(int)(main)+0x31);
        return 0;
}
#3
مصطفى 36a2 كتب:

 

هل ينفع شيء كهذا |:

#include<cstdio>
int main()
{
    printf("0x%x\n",(int)(main)+0x31);
        return 0;
}

 

بالتأكيد ينفع لكن في هذه الحالة فقط  :P

 

لقد آقتربت من الحل، ماينقصك هو بعض التعديل فقط، لكي يصبح عام،

على العموم تذكر بأن قيمة EIP يتم تخزينها، في حالة خاصة، مما يعرضها لخطر السرقة  :D

 

سأضع الحل في المساء إن لم يجب أحد ..

تم تعديل هذه المشاركة بواسطة zirek99i في 5 ديسمبر 2013 في 17:46

#4

:D

#include<cstdio>
void PrintEIP(int x=0){
    printf("0x%x\n",*(int *)(&x-1)-9);
}
int main(){
    PrintEIP();
    return 0;
}
1
#5

تمام مصطفي  :D

 

وهذا حلي

#include <cstdio>

unsigned int __stdcall my_GetEip (int magic)
{
	return (*((unsigned int *) &magic - 1)) + 0x3;
}

int main (void)
{	
	{
		unsigned int eip;
		eip = my_GetEip (18);
	}

	printf("am the target address!");

	getchar ();
	return 0;
}

بالتوفيق

1
#6

الحمد لله أن الحل خطرلي قبل ما كنت مستمر في الفكرة الغبية التالية

#include<cstdio>
void o(){
    char x[120];
    sprintf(x,"%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x0x%x");
    printf("%s\n",&x[95]);
}
int main(){
o();
return 0;
}

طبعاً الكود غير منته بعد

 

شكراً للسؤال , جميل جداً :)

وفقك الله

#7

@مصطفى

void PrintEIP(int x=0){
    printf("0x%x\n",*(int *)(&x-1)-9);
}

لماذا انقصت 9  في الاخير

اليس eip محفوظ في ebp+4  مؤقتا الى غاية التعليمة ret ؟

تم تعديل هذه المشاركة بواسطة fouad2008 في 7 ديسمبر 2013 في 10:43

#8

أهلا أخي فؤاد :)

eip يتم حفظه في ebp  .. ولكن ebp يتم تغييره .. هذه واحده

افترض أن لدي تعليمة ما X أستدعي بعدها الدالة printEip

والآن :

التعليمة X
00401098   push        0
0040109A   call        @ILT+5(PrintEIP) (0040100a)

الاستدعاء call يدفع eip في المكدس كما تعلم ..

بالتالي

*(int *)(&x-1)

لاحظ أن هذا هو الطرح ( الذي أظن أنك تقصده) طرحت واحد فقط فوصلت إلى eip

(انس الــ9 التي في الآخر سأتكلم عنها الآن )

المهم أن العملية هي هذه فقط

*(int *)(&x-1)

ولكن الـ eip المحفوظ هو الخاص بالتعليمة التي تلي الـ call

مثال :

00401096   rep stos    dword ptr [edi]
6:        PrintEIP();
00401098   push        0
0040109A   call        @ILT+5(PrintEIP) (0040100a)
0040109F   add         esp,4

لاحظ أن البرنامج بدون الـ -9 سيطبع 0040109F 

وهذا غير صحيح ( لا أظن أن zirek  انتبه لها ;))

الفكرة أنني محتاج لطرح 5 للتعليمة call ثم 2 للتعليمة push ثم يجب طرح حجم التعليمة المطلوب إيجاد eip لها .. وفي مثالنا هو 2 للتعليمة

rep stos    dword ptr [edi]

طبعاً هذا ينقص جودة الكود , فهو ليس عامّاً :p

(ملاحظة : لا تظن أني حافظ حجم التعليمات , كله من ال visual studio  :p )

 

بالتوفيق

#9

شكرا على التوضيح .

#10

الطريقة بي  inline assembly  مع انه ليست مسموحة لي :)
p_218000e1.jpg
بالتوفيق 

1

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