4

gccインラインを使用して、アセンブリで直接MessageBoxA()を呼び出そうとしています。ただし、これを2つの方法で行う必要があります。1つは、LoadLibrary()とGetProcAddress()を使用した動的アドレス指定の使用です。これに関するチュートリアルを見つけて、それに従ってください。しかし、私はMessageBoxAのアドレスを直接呼び出すことにも興味があります。これは私のWindowsSP3英語では0x7e4507eaです。

私はこのコードを実行しようとしています:

/*
 *    eax holds return value
 *    ebx will hold function addresses
 *    ecx will hold string pointers
 *    edx will hold NULL
 *
 */


int main(int argc, char **argv)
{
asm("   xor %eax, %eax          \t\n\
        xor %ebx, %ebx          \t\n\
        xor %ecx, %ecx          \t\n\
        xor %edx, %edx          \t\n\
        push $0x0               \t\n\
        push $0x44444444        \t\n\
        push $0x44444444        \t\n\
        pop %ecx                \t\n\
        mov %dl,0x3(%ecx)       \t\n\
        mov $0x7e4507ea, %ebx   \t\n\
        push   %edx             \t\n\
        push   %ecx             \t\n\
        push   %ecx             \t\n\
        push   %edx             \t\n\
        mov $0x8, %ax           \t\n\
        call *%ebx              \t\n\
        ");
}

Windowsでこれを実行できるかどうかはわかりませんが、ライブラリ(この場合はuser32.dll)を指定せずに、アドレスを直接呼び出します。Linuxではwrite()syscallを呼び出すのは簡単ですが、Windowsではまだあまり馴染みがありません。

「DDDDDDDD」のメッセージボックスが表示されると思います。誰かがそれについて私を助けてくれませんか?チュートリアルリンクもあり、助けに感謝します!

どうもありがとう

4

4 に答える 4

2

最初にCで記述し、コンパイルしてアセンブリリストを表示し、コンパイラが生成したものを確認します。これが最も簡単な学習方法です。理解できない命令を見つけた場合は、Intel命令セットリファレンスPDFでそれを探してください。

于 2010-09-08T19:13:13.207 に答える
2

私はこのようにしました:

int main ()
{
    asm("xorl %eax, %eax        \n"
        "xorl %ebx, %ebx        \n"
        "xorl %ecx, %ecx        \n"
        "xorl %edx, %edx        \n"
        "pushl %ecx             \n"
        "pushl $0x20206c6c      \n"
        "pushl $0x642e3233      \n"
        "pushl $0x72657375      \n"
        "movl %esp, %ecx        \n"
        "movl $0x7c801d7b, %ebx \n"
        "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"
    );
}

関数のアドレスをハードコーディングすることは完全に可能ですが、動的にロードすることを好みました (ただし、kernel32 アドレスをハードコーディングしています)。これにより、どの Windows XP (SP1、2、3) でも動作します。

于 2010-10-18T11:55:14.237 に答える
1

住所に直接電話する

大きなノーノーのように聞こえます。API 呼び出しには固定アドレスがありません。メモリ内のどこにロードされたかによって異なります。OS の起動時に User32.dll が読み込まれることは確かですが、同じスペースを占有することは期待できません。

API ルーチンを呼び出すには、それをインポートして、OS が呼び出しの正しいアドレスを提供できるようにする必要があります。

于 2010-09-09T13:14:31.890 に答える
1

MessageBoxA を「直接」呼び出すことは実際には不可能です。はい、 への呼び出しを追加できますが、0x7e4507ea実際には問題ではありません。インポートアドレス テーブルにエントリを追加する必要MessageBoxAがあります。これは、user32.dll から、どこから呼び出しているかを示しています。Windows が実行可能ファイルをロードすると、あなたが を呼び出していることがわかり、MessageBoxA代わりに user32.dll がロードされ、MessageBoxA終了した実際のアドレスにパッチが適用されます。

于 2010-09-09T15:09:16.693 に答える