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

انشاء دوال بشكل ديناميكى

بدأه C++er في 31 أغسطس 2010 · 2 رد · 741 مشاهدة · في أرشيف قسم الـــ Assembly
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

الفكره تتلخص فى اني صنعت محرك لتحليل العمليات الحسابيه (بلغة السى بلس بلس :ph34r: ) و قمت بتخزين ناتج العمليات الحسابيه داخل Expression Tree، هذه الشجره أحد عناصرها هى متغيرات لذا فى كل مره يريد المستخدم تنفيذ التعبير الموجود داخل الشجره لابد من إعادة حساب قيمه من جديد لهذا فكرت أن أقوم بعمل optimize للشجره عن طريق صنع داله بإستخدام الـProcessor OP Codes و اقوم بعمل مرجعيه على المتغيرات داخل الـ stack و عندما يريد المستخدم تنفيذ محتويات الشجره اقوم بتخزين المتغيرات داخل الـ Stack ثم اقوم بإستدعاء النسخه التنفيذيه لهذه الشجره.

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

فى أبسط الأحوال، فلنفترض أن المعادله التى ادخلها المستخدم شكلها كالتالى mimetex.cgi?x، مع العلم أن mimetex.cgi?x هو متغير و يمثل المعادله، لذا يوجد كودين سيتم إنشائهم، الأول هو كود الداله التى ستقوم بتنفيذ المعادله و الرجوع بالقيمه و كود الأله الذى تم انشائه من خلال الشجره لهذه المعادله هو كالتالى:

\x55\x8B\xEC\x8B\x45\x08\x5D\xC3

و يقابل بالأسمبلى:

push ebp          ; 55
mov  ebp, esp     ; 8BEC

; start equation code
mov  eax, [ebp+8] ; 8B4508
; end equation code

pop  ebp          ; 5D
retn              ; C3

هذه الداله لها نظام استدعاء خاص حيث سيكون absolute و ليس relative لذا لن يتم استخدام E8 للإستدعاء المباشر و لكن لابد من حفظ موقع الإستدعاء داخل مسجل (eax مثلا) و من ثم إستدعاء العنوان الموجود بهذا المسجل. قبل عملية الإستدعاء يتم حجز مساحة من الـ stack للمتغيرات و بعد الإستدعاء يتم تحرير هذه المساحه، كود الأله لهذه العمليه هو:

\x6A\x03\xB8\x0\x0\x0\x0\xFF\xD0\x83\xC4\x04

و يقابل بالأسمبلى:

; push count 3 = (x:1)
push 3           ;  6A03
; call dynamic function
mov  eax, 00000000 ;  B8 address
call eax           ;  FFD0
; free variables
add  esp, 4;       ;  83C404

بالنسبه للأصفار التى يتم وضعها داخل المسجل eax فإنه سيتم إبدال هذه الأصفار بعنوان الداله التى يتم إنشائها.

إذا تم تنفيذ كود الأله السابق من داخل لغة السى سيتم التنفيذه بنجاح، المشكله أنه بعد التنفيذ يحدث خطأ ما، هذا الخطأ يتغير فى كل مره يتم تغيير كود الأله الذى يتم تنفيذه، لاحظ أنه إذا تم إستخدام أى من المسجلات edi, esi, ebp, esp فإنه يتم حفظهم و استرجاعهم دون مشاكل و حيث ان هذا المثال كان بسيط لذا لم يكن الكود كبير.

لمن يريد التجربه ها هو كود السى :

#include <stdio.h>
#include <malloc.h>
#include <string.h>

const char* my_func = "\x55\x8B\xEC\x8B\x45\x08\x5D\xC3";

#define CALL_EXIT "\x6A\x03\xB8\x0\x0\x0\x0\xFF\xD0\x83\xC4\x04"
#define CALL_SIZE sizeof(CALL_EXIT)

int main()
{
	char* call_fn = (char*)malloc(CALL_SIZE);
	memcpy(call_fn,CALL_EXIT, CALL_SIZE);

	for(int i=0; i<4; i++)
		call_fn[i+3]  = char(int(my_func)>>i*8);

	__asm
	{
		push call_fn
		ret
	}
}

إذا اردت الحصول على القيمه المعاده من الداله فعليك بالحصول عليها من eax، الكود الخاص بمشروعى لم يكتمل بعد بسبب المشكلة التى هى محور هذا الموضوع.

هل لديكم أى حلول؟

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

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

#2
 #define CALL_EXIT "\x6A\x03\xB8\x0\x0\x0\x0\xFF\xD0\x83\xC4\x04\xC3"

__asm
{
	push retaddr
	push call_fn
	ret
retaddr:
}

تم تعديل هذه المشاركة بواسطة GamingMasteR في 1 سبتمبر 2010 في 06:05

1

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#3

تمام يا G، دى افضل كتيير من الفكره اللى كنت بحاول اطبقها (نفس الفكره بإستخدام jmp).

بارك الله فيك.

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

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

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

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

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

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

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