11

以下のコードは、画面にメッセージボックスを表示しているだけです。
アドレスは、次のことを容易にするためにハードコーディングされています。

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構文で実行できることは知っていますが、gccインラインではどうでしょうか.ascii 'Hello'.string 'Hello'

WindowsXPSP3でDev-C++を使用していることに注意してください

ありがとう!

4

1 に答える 1

10

はい、インラインアセンブラ内でアセンブラディレクティブを利用します。秘訣は、文字列を適切な場所(データセクション)に配置することです。これは、を使用して切り替えてから、を使用し.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ツールチェーンを使用する場合に一般的に適用できます。ELFバイナリ(ネイティブLinuxなど)を構築している場合は、テキストセクションに戻るためのより適切な方法があります。これは、.previous「前のセクションが何であれ」を意味するを使用すること.sectionです。(上記の例は、異なる記号の接頭辞規則を考慮してに変更_putsした場合、Linuxで機能します。)puts

于 2010-09-14T19:36:53.853 に答える