سؤال

تخيل أنني أفعل شيئا مثل هذا:

void *p = malloc (1000);
*((char*)p) = some_opcode;
*((char*)p+1) = another_opcode; // for the sake of the example: the opcodes are ok

....
etc...

كيف يمكنني تحديد مؤشر دالة للاتصال P كما لو كانت وظيفة؟ (أنا أستخدم VC ++ 2008 Express).

شكرا

هل كانت مفيدة؟

المحلول

التعليق لم يكن مساحة كافية. joe_muc هو الصحيح. يجب أن لا تشوه الكود في الذاكرة التي تم الحصول عليها malloc أو new. وبعد ستدير مشاكل إذا قمت بتغيير خصائص الصفحة للصفحات التي تخصص Windows.

هذه ليست مشكلة Becuase باستخدام Virtualalloc () و APIS Win32 ذات الصلة هي كل سهلة: Virtualalloc () وتعيين flProtect ل [PAGE_EXECUTE_READWRITE][2]

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

أيضا التفاف المكالمات إلى التعليمات البرمجية التي تم إنشاؤها معالجة الاستثناء المنظم.

بعد ذلك، لم يتم توثيق Windows X86 ABI (Calling Centrations) بشكل جيد (أعرف، لقد بحثت). هناك بعض المعلومات هنا, هنا, هنا أفضل طريقة لرؤية كيفية عمل الأشياء هي إلقاء نظرة على التعليمات العامة الناتجة عن المترجم. هذا سهل القيام به مع \FA مفاتيح ( هناك أربعة منهم).

يمكنك العثور على اتفاقيات الاتصال 64 بت هنا.

أيضا، لا يزال بإمكانك الحصول على مجمع ماكرو Microsoft MASM هنا. وبعد أوصي بكتابة رمز الجهاز الخاص بك في MASM وانظر إلى إخراجها، ثم هل لديك مولد رمز الجهاز الخاص بك يفعل أشياء مماثلة.

إنتل و AMD كتيبات المعالج مراجع جيدة - احصل عليها إذا لم يكن لديك.

نصائح أخرى

في الواقع، ربما malloc لن يقطعها. على الأرجح، ربما تحتاج إلى استدعاء شيء مثل [Virtualalloc] (http://msdn.microsoft.com/en-us/library/aa366887(VS.85).aspx) من أجل الحصول على صفحة واحدة قابلة للتنفيذ من الذاكرة.

بدءا صغيرا:

void main(void)
{
    char* p = (char*)VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    p[0] = (char)0xC3;  // ret

    typedef void (*functype)();
    functype func = (functype)p;
    (*func)();
}

الخطوة التالية للعب لطيفة مع الكود الخاص بك هي الحفاظ على سجل EBP. يتم ترك هذا بمثابة تمرين. :-)

بعد كتابة هذا، ركضت مع malloc وعملت أيضا. قد يكون ذلك لأنني أقوم بتشغيل حساب مسؤول على Windows 2000 Server. قد تحتاج الإصدارات الأخرى من Windows في الواقع إلى مكالمة Virtualalloc. من تعرف.

إذا كان لديك Opcodes الأيمن في مكانه، فقد تكون الاتصال بسيطة مثل الصب إلى مؤشر دالة واتصل بها.

typedef void (*voidFunc)();

char *p = malloc (1000);
p[0] = some_opcode;
p[1] = another_opcode; // for the sake of the example: the opcodes are ok
p[n] = // return opcode...

((voidFunc)p)();

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

أنا أيضا أبحث حاليا في تنفيذ التعليمات البرمجية التي تم إنشاؤها، وبينما لم تعطني الإجابات هنا بدقة ما أحتاجه، أرسلتني يا رفاق على المسار الصحيح.

إذا كنت بحاجة إلى وضع علامة على صفحة كقابلة للتنفيذ على أنظمة Posix (Linux، BSD وما إلى ذلك)، تحقق من MMP (2) وظيفة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top