Определение байтов в встроенной сборке GCC в Dev-C ++ (. ASCII в AT & T Syntax в 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» в строке сборки, не поддаваясь вручную в стек? Я имею в виду это в НАМС: db 'Hello'
Я знаю, что в синтаксисе AT & T я мог бы сделать .ascii 'Hello'
или .string 'Hello'
Но как насчет встроенного GCC?
Обратите внимание, что я использую Dev-C ++ в Windows XP SP3
Спасибо!
Решение
Да, используя директивы ассемблера внутри вашего встроенного ассемблера. Хитрость заключается в том, чтобы помещать строку в нужном месте (раздел данных), что вы можете сделать, переключившись с помощью .section .data
, а затем снова переключается с .section .text
.
Вы должны дать данным этикетку, чтобы вы могли обратиться к ним; Я бы порекомендовал использовать синтаксис локальной метки здесь (где этикетка - число, например, 1:
, и вы ссылаетесь на это как 1b
во-первых 1:
этикетка назад, или 1f
во-первых 1:
ярлыки вперед - см. Документация GNU Assembler Больше подробностей).
Как это:
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, чтобы проверить это, но она компилирует OK и выглядит так, как будто она должна делать правильные вещи, используя кросс-компилятор Mingw на Linux (я считаю, что Dev-C ++ основан на Mingw).
ПРИМЕЧАНИЕ. Этот метод обычно применим при использовании инструментального оборудования GNU. Если вы строите бинарные файлы эльфов (например, Native Linux), существует более аккуратный способ вернуться в текстовый раздел, который должен использовать .previous
, что означает «какой бы ни был раздел до предыдущего .section
был ". (Приведенный выше пример работает на Linux, если вы измените _puts
к puts
учитывать различные соглашения о префиксе символа.)