[ASM] Questions sur Windows et son mode protégé

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

Début de réponse à ma troisième question: il semble que la sortie en obj ne permette pas de définir les droits d’accès. Il faut compiler avec le format “win32” avec NASM.

2ème et 4ème questions : Les ret far sont interdits en “mode user” parceque le registre cs contient le niveau de privilège de l’application.

De plus windows utilise un modèle de mémoire se rapprochant du “flat” c’est à a dire ou chaque application dispose de son propre espace virtuel d’un seul segment.

C’est pour ça que les variables sont adressable sans changer les registres…