2010-09-08 4 views
4

J'essaie d'appeler MessageBoxA() directement dans l'assembly, en utilisant gcc inline. Cependant, je dois le faire de deux façons: d'abord en utilisant l'adressage dynamique, avec LoadLibrary() et GetProcAddress() - J'ai trouvé un tutoriel à ce sujet, en essayant de le suivre. Mais je suis également intéressé à appeler directement l'adresse de MessageBoxA, qui est 0x7e4507ea dans mon Windows SP3 anglais.MessageBoxA dans Windows AT & T Assembly

Je suis en train d'exécuter ce code:

/* 
* 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\ 
     "); 
} 

Je ne sais pas si dans Windows est encore possible de le faire, appelez directement l'adresse, sans préciser la bibliothèque (dans ce user32.dll Cas). Je sais sous Linux, il est simple d'appeler write() syscall, mais dans Windows, je ne suis pas encore familier ..

Je m'attends à voir une boîte de message avec "DDDDDDDD". Quelqu'un pourrait-il m'aider s'il vous plaît? Appréciez toute aide, avec des liens tutoriels aussi!

Merci beaucoup

+0

Hey comme vous l'avez mentionné dans un commentaire, vous l'avez fait. Pourriez-vous me décrire comment vous vous entendez avec IAT? dans l'exemple ci-dessus –

Répondre

2

écrire en C d'abord, compiler et consulter la liste de l'ensemble pour voir ce que le compilateur généré. C'est la façon la plus facile d'apprendre. Si vous voyez une instruction que vous ne comprenez pas, recherchez-la dans les fichiers PDF de référence du jeu d'instructions Intel.

+0

J'ai essayé de le faire, mais ce n'est pas si simple. J'ai compilé de cette façon: gcc -c msgbox3.c -static -mpreferred-stack-boundary = 2. Mais le fichier objet que j'ai contient contient quelques instructions d'assemblage qui n'ont pas beaucoup aidé ... de toute façon merci de poster. – jyz

+0

@jyzuz: il y a une bonne raison pour laquelle vous avez appris à lire à l'école avant d'apprendre à écrire. Pour les langages informatiques, la même chose vaut. Si vous ne pouvez pas lire l'assemblage, vous ne devez pas essayer de l'écrire. – MSalters

+0

@MSalters: J'apprends à lire/écrire en assembleur avec Richard Blum book (pour Linux). Et aussi apprendre l'assemblage de Windows en lisant quelques articles sur Internet. Je pense que la meilleure façon d'apprendre est de lire et de pratiquer. Je ne peux pas enregistrer quand je suis un enfant si je suis devenu un expert en lecture avant d'écrire un mot ..mais je pense que vous n'apprendrez jamais la programmation sans essayer et faire des erreurs. Peut-être que j'essaie de courir "plus vite que mes jambes peuvent" ... eh bien ... je suis très curieux hehe;) – jyz

1

appeler directement l'adresse

On dirait un gros no-no. Les appels d'API n'ont pas d'adresse fixe. Cela dépend de l'endroit où la mémoire a été chargée. Bien que je suis sûr que User32.dll est chargé au démarrage de l'OS, je ne compterais pas qu'il occupait jamais le même espace.

Pour appeler une routine API, vous devez l'importer afin que le système d'exploitation puisse vous fournir une adresse correcte pour l'appel.

+0

mais c'est assez étrange, parce que je fais des tests ici depuis quelques semaines, et à chaque fois Je cherche l'adresse de MessageBoxA dans user32.dll il renvoie 0x7e4507ea. Cela signifie-t-il que c'est l'adresse de MessageBoxA à l'intérieur de user32.dll ou en mémoire? – jyz

+0

'0x7e4507ea' est l'adresse dans votre espace de traitement. Il est raisonnable stable pour deux raisons: Premièrement, user32.dll se charge très tôt. Par conséquent, il a tendance à charger au même endroit à chaque fois. Les DLL qui se chargent plus tard devront prendre n'importe quelle adresse si elle est laissée. Deuxièmement, user32.dll ne change généralement que lorsque Microsoft y corrige un bug, ce qui n'est pas le cas chaque semaine - certainement pas pour XP SP3, où seuls les bogues de sécurité sont corrigés. – MSalters

+0

Encore une mauvaise idée, un peu comme appeler par ordinal. –

1

L'appel "Directement" MessageBoxA n'est pas vraiment possible. Oui, vous pouvez ajouter un appel à 0x7e4507ea, mais cela n'a pas vraiment d'importance. Vous devez ajouter une entrée à votre table d'adresses d'importation, qui indique que vous appelez MessageBoxA à partir de user32.dll et d'où. Lorsque Windows chargera votre exécutable, il verra que vous appelez MessageBoxA, chargera user32.dll pour vous, et corrigera l'adresse réelle où MessageBoxA s'est terminée.

+0

OK Je pense que je l'ai eu. Je sais que Windows Executable est complètement différent des fichiers Linux ELF. Ce "Import Address Table" est une session dans le fichier Windows exécutable, non? Je vais en lire plus à ce sujet .. merci d'avoir répondu – jyz

+0

Oui, et aussi connu comme la section "IAT" – MSalters

+0

En fait, c'est possible. Et maintenant je suis en mesure de le faire :) – jyz

2

Je l'ai fait ainsi:

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" 
    ); 
} 

Même dur est parfaitement possible de coder les adresses des fonctions, je préfère charger dynamiquement (bien que je hardcoding adresse kernel32), de sorte que cela fonctionne sur n'importe quel Windows XP (SP1, 2, 3)

+0

[Randomisation de disposition de l'espace d'adresse] (http://blogs.msdn.com/b/michael_howard/archive/2006/05/26/address-space-layout-randomization-in -windows-vista.aspx) modifie à peu près cette image. * Les adresses hardcoding * et * failure * sont devenues synonymes. – IInspectable

Questions connexes