MessageBoxA в сборке Windows AT & T - PullRequest
       50

MessageBoxA в сборке Windows AT & T

4 голосов
/ 08 сентября 2010

Я пытаюсь вызвать MessageBoxA () непосредственно в сборке, используя gcc inline.Однако мне нужно сделать это двумя способами: сначала используется динамическая адресация, с LoadLibrary () и GetProcAddress () - я нашел об этом учебное пособие, пытаясь следовать ему.Но я также заинтересован в непосредственном вызове адреса MessageBoxA, который в моем Windows SP3 English является 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 просто вызывать syscall для write (), но в Windows я еще не настолько знаком.

Я ожидаю увидеть окно с сообщением "DDDDDDDD".Может ли кто-нибудь помочь мне в этом, пожалуйста?Цени любую помощь, а также с учебными ссылками!

Большое спасибо

Ответы [ 4 ]

2 голосов
/ 18 октября 2010

Я сделал это следующим образом:

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)

2 голосов
/ 08 сентября 2010

Сначала запишите его в C, скомпилируйте и просмотрите список сборки, чтобы увидеть, что сгенерировал компилятор. Это самый простой способ учиться. Если вы видите непонятную инструкцию, поищите ее в справочных файлах Intel Instruction Set.

1 голос
/ 09 сентября 2010

«Прямой» вызов MessageBoxA на самом деле невозможен.Да, вы можете добавить вызов к 0x7e4507ea, но это не имеет значения.Вы должны добавить запись в свою таблицу адресов импорта, в которой говорится, что вы звоните MessageBoxA из user32.dll и откуда.Когда Windows загрузит ваш исполняемый файл, он увидит, что вы звоните MessageBoxA, загрузите user32.dll и исправьте фактический адрес, где MessageBoxA закончился.

1 голос
/ 09 сентября 2010

напрямую позвоните по адресу

Звучит как большой нет-нет.У вызовов API нет фиксированного адреса.Это зависит от того, где в памяти он был загружен.Хотя я уверен, что User32.dll загружается при запуске ОС, я бы не стал рассчитывать, что он когда-либо будет занимать одно и то же место.

Чтобы вызвать подпрограмму API, необходимо импортировать ее, чтобы ОС могла предоставитьВы с правильным адресом для звонка.

...