dev-c ++のgccインラインアセンブリのバイトを定義する(。
-
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'
しかし、GCCインラインではどうですか?
Windows XP SP3でdev-c ++を使用していることに注意してください
ありがとう!
解決
はい、インラインアセンブラー内のアセンブラーディレクティブを使用します。トリックは、文字列を適切な場所(データセクション)に配置することです。 .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システムはありませんが、LinuxでMINGWクロスコンパイラを使用して正しいことをしているはずです(DEV-C ++はMINGWに基づいていると思います)。
注:この手法は、GNUツールチェーンを使用する場合に一般的に適用できます。エルフのバイナリ(ネイティブLinuxなど)を構築している場合、テキストセクションに戻るためのよりきちんとした方法があります。 .previous
, 、それは「前のセクションが何であれ .section
」(上記の例は、変更するとLinuxで動作します _puts
に puts
さまざまなシンボルのプレフィックスコンベンションを説明する。)