繁体   English   中英

Windows AT&T程序集中的MessageBoxA

[英]MessageBoxA in Windows AT&T Assembly

我正在尝试使用gcc内联直接在程序集中调用MessageBoxA()。 但是我需要以两种方式执行此操作:首先使用动态寻址,使用LoadLibrary()和GetProcAddress() - 我找到了关于此的教程,尝试遵循它。 但我也有兴趣直接调用MessageBoxA的地址,在我的Windows SP3英语中是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()系统调用很简单,但在Windows中我还不太熟悉..

我希望看到一个带有“DDDDDDDD”的消息框。 有人可以帮我吗? 感谢任何帮助,还有教程链接!

非常感谢

首先在C中编写它,编译并查看程序集列表以查看编译器生成的内容。 这是最简单的学习方式。 如果您在英特尔指令集参考PDF中看到一条您不理解的指令。

我这样做了:

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)

直接拨打地址

听起来像一个大禁忌。 API调用没有固定的地址。 这取决于它加载的内存在哪里。 虽然我确信在操作系统启动时加载了User32.dll,但我不会指望它占用相同的空间。

要调用API例程,必须将其导入,以便操作系统为您提供正确的呼叫地址。

“直接”调用MessageBoxA实际上是不可能的。 是的,您可以添加对0x7e4507ea的调用,但这并不重要。 必须在导入地址表中添加一个条目,该条目表示您正在从user32.dll调用MessageBoxA ,并从那里调用。 当Windows加载您的可执行文件时,它会看到您正在调用MessageBoxA ,为您加载user32.dll,并修补MessageBoxA结束的实际地址。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM