تحديد البايتات في التجميع المضمّن في مجلس التعاون الخليجي في Dev-C ++ (. ASCII في بناء جملة AT&T على Windows)
-
02-10-2019 - |
سؤال
الكود أدناه هو مجرد عرض مربع رسالة على الشاشة.
العناوين متشددين لتسهيل:
int main ()
{
asm("xorl %eax, %eax \n"
"xorl %ebx, %ebx \n"
"xorl %ecx, %ecx \n"
"xorl %edx, %edx \n"
"pushl %ecx \n" //$0x0
"pushl $0x20206c6c \n" //" ll"
"pushl $0x642e3233 \n" //"d.23"
"pushl $0x72657375 \n" //"resu"
"movl %esp, %ecx \n" //store "user32.dll" address in %ecx
"movl $0x7c801d7b, %ebx \n" //store address of LoadLibraryA in %ebx
"pushl %ecx \n"
"call *%ebx \n"
"movl $0xef30675e, %ecx \n"
"addl $0x11111111, %ecx \n"
"pushl %ecx \n"
"pushl $0x42656761 \n"
"pushl $0x7373654d \n"
"movl %esp, %ecx \n"
"pushl %ecx \n"
"pushl %eax \n"
"movl $0x7c80ae40, %ebx \n"
"call *%ebx \n"
"movl %esp, %ecx \n"
"xorl %edx, %edx \n"
"pushl %edx \n"
"pushl %ecx \n"
"pushl %ecx \n"
"pushl %edx \n"
"call *%eax \n"
"xorl %eax, %eax \n"
"pushl %eax \n"
"movl $0x7c81cb12, %eax \n"
"call *%eax \n"
);
}
(لم أعلق على كل الرمز لأن سؤالي لا يتعلق حقًا بالرمز)
سؤالي هو: هل هناك طريقة لكتابة السلسلة "user32.dll" في التجميع المضمّن دون الدفع يدويًا إلى المكدس؟ أعني مثل هذا في Nasm: db 'Hello'
أعلم أنه في بناء الجملة AT&T يمكنني القيام به .ascii 'Hello'
أو .string 'Hello'
ولكن ماذا عن في مجلس التعاون الخليجي المضمّن؟
يرجى ملاحظة أنني أستخدم Dev-C ++ على Windows XP SP3
شكرًا!
المحلول
نعم ، من خلال الاستفادة من توجيهات التجميع داخل المجمع المضمن. الخدعة في وضع السلسلة في المكان الصحيح (قسم البيانات) ، والتي يمكنك القيام بها عن طريق التبديل باستخدام .section .data
, ثم العودة مرة أخرى مع .section .text
.
يجب أن تعطي البيانات تسمية حتى تتمكن من الرجوع إليها ؛ أوصي باستخدام بناء جملة الملصقات المحلي هنا (حيث تكون التسمية رقمًا ، على سبيل المثال 1:
, ، وأنت تشير إليها على أنها إما 1b
لأول 1:
تسمية للخلف ، أو 1f
لأول 1:
تسمية إلى الأمام - انظر وثائق تجميع GNU لمزيد من التفاصيل).
مثله:
int main(void)
{
asm(".section .data \n"
"1: .asciz \"Hello\" \n"
".section .text \n"
"pushl $1b \n"
"call _puts \n"
"add $4, %esp \n"
);
return 0;
}
ليس لدي نظام Windows مفيد لاختبار ذلك ، لكنه يجمع بشكل جيد ويبدو أنه يجب أن يفعل الشيء الصحيح باستخدام mingw cross-compiler على Linux (أعتقد أن Dev-C ++ يعتمد على mingw).
ملاحظة: تنطبق هذه التقنية بشكل عام عند استخدام مجموعة أدوات GNU. إذا كنت تقوم ببناء ثنائيات Elf (مثل Linux الأصلي) ، فهناك طريقة أكثر إمتاعًا للعودة إلى قسم النص ، والتي تتمثل في الاستخدام .previous
, ، وهو ما يعني "مهما كان القسم قبل السابق .section
كان ". (المثال أعلاه يعمل على Linux إذا قمت بتغيير _puts
إلى puts
لحساب اتفاقيات البادئة المختلفة.)