Bonjour,
J’utilise mes longue vacances pour me mettre à l’assembleur, et plus particulièrement la création d’exécutable assembleur pour Windows (donc API Win32 et mode protégé).
J’ai décidé d’utiliser NASM pour ma programmation Windows mais de multiples questions me viennent à l’esprit et mes recherches sur internet n’ont rien données!
Voilà quatre questions, sans doute idiotes pour la majorité de personne sur ce forum, mais je le répète encore, je n’ai rien trouvé me donnant une piste pour continuer à chercher.
1 ère question
Es-ce qu’un exécutable Win32 doit créer une pile lui-même comme il le fait en mode réel? (même si en mode réel on peut laisser par défaut et utiliser la fin de l’unique segment).
Je n’en ai pas trouvé avec Ollydbg dans les programmes normaux. La pile serait à l’“extérieur” du programme et créée par Windows?
2 ème question
J’ai compris l’utilisation du CALL NEAR/FAR et RETN et RETF. Ceci permet de savoir si il faut empiler le registre CS (pour le retour).
J’ai remarqué que en mode protégé pour sauter d’un segment à un autre à l’intérieur d’un programme il fallait utiliser que “CALL NEAR” sinon le compilateur faisait une erreur. Mais comment expliquer ceci?
Il existe toujours un registre CS! (sélecteur de segment OK, mais registre quand même…)
3 ème question
J’utilise Ollydbg (un débugger) pour voir ce que produit un changement dans le code source sur mon exécutable. Et j’ai remarqué que dans le PE Header un champs notifiait si l’accès aux données était: lecture / écriture / données initialisées / données non-initialisées / exécutable.
Mais je n’arrive pas à modifier ces champs depuis mon code ASM! Je n’arrive pas à dire à NASM que un segment est un segment de données et un autre du code.
Pour vous donner un exemple voici un de mes codes extrêmement simple.
[BITS 32]
extern MessageBoxA
import MessageBoxA user32.dll
segment codeasm USE32 PRIVATE
..start:
push 0
push caption
push msg
push 0
call [MessageBoxA]
ret
segment donnee USE32
msg: db "Le text", 0
caption: db "Le titre", 0
Après vérification (avec OllyDbg) le segment donnee et codeasm sont les deux en READ|WRITE|INITIALIZED_DATA, je ne peux pas changer ces attributs alors que le compilateur Visual Studio 2005 (C++) modifie ces attributs pour rendre le code “EXECUTABLE” et le segment qui accueil les constantes (rdata) n’a pas l’accès : WRITE
http://img201.imageshack.us/img201/7731/segyu3.jpg
A droite les droits sur un exécutable "normal" fais par un compilateur C++ et à gauche, mon code assembleur, sans droit modifié…
Savez-vous comment modifier ces attributs indépendamment pour chaque sections?
Es-ce que le faite que je compile via un fichier objet plutôt que en format "win32" comme le propose NASM pourrait expliquer cette impossibilité de modification?
4 ème et dernière question (je vous promet :p)
Cette question concerne les accès à plusieurs segment avec le même registre de base. Si je compile ce code il marche! :
[BITS 32]
extern MessageBoxA
import MessageBoxA user32.dll
segment codeasm USE32 PRIVATE
..start:
push 0
push caption
push msg
push 0
call [MessageBoxA]
ret
segment donnee1 USE32
caption: db "Le titre", 0
segment donnee2 USE32
msg: db "Le text", 0
Mais pourtant je vais piocher dans deux segments différents! Si j’ai bien compris le tas de documentation que j’ai lu le segment de base devrait être celui que je pointe avec DS (sauf avec EBP). Mais ici comme je vais chercher dans deux segment différent je devrais lire au moins une variable à la mauvaise case mémoire non?
Rien qu’un tout petit indice me permettrait d’amorcer de nouvelles recherches sans doute plus concluantes.
Merci d’avance