none
[C++] Problème avec l'assembleur inline - Visual Studio 2008 RRS feed

  • Question

  • Bonjour,

    Actuellement en master informatique à l'université de Metz, je dispose d'un projet de recherche à réaliser.

    Dans ce dernier, je dois utiliser de l'assembleur inline (en C++), seulement mon code n'a pas le comportement attendu, par faute de manque d'informations sur la syntaxe tolérée et du comportement des variables C++ utilisées en assembleur.

    Explication du problème:

    adresseSMC est une variable déclarée en C++, de type PVOID. Je rempli cette adresse lors de la levée d'une exception provoquée par une violation d'écriture:
    int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
    DWORD OldProtect;
    DWORD InstructionSize = 1;
    PVOID adresseSMC;
    
    	cout << "Fonction filter." << endl;
    
    	if (code == EXCEPTION_ACCESS_VIOLATION)
    	{
    		//Après avoir soulevé l'exception, on sait ou se trouve le code du SMC
    		adresseSMC = ep->ExceptionRecord->ExceptionAddress;
    ....

    Suite à cela, je souhaite modifier le contenu de la case mémoire dont l'adresse est stockée dans adresseSMC, pour la remplacer par un appel de fonction (clearWR). Pour ce faire, j'utilise le code assembleur:

    		__asm{		//PUSH eax
    					XOR eax, eax
    					XOR ebx, ebx
    					MOV eax, [fct]
    					MOV dword ptr ds:[adresseSMC], eax
    					//POP eax
    					JMP end
    			fct:	call clearWR
    			end:
    		}
    Or suite à l'exécution de ce code, je constate grâce à des cout que le contenu de ma variable adresseSMC est modifié, et non le contenu de l'adresse mémoire située à adresseSMC!

    Je tiens à préciser qu'il s'agit d'un projet de recherche indispensable à la validation de mon année, j'espère que vous comprendrez donc que ma question reste assez urgente.

    D'avance merci pour vos réponses :

    vendredi 30 mars 2012 13:26

Réponses

  • En plus de la réponse de Ciprian, je précise aussi que votre approche risque d'être problématique car, si j'ai bien compris votre besoin, vous voulez modifier une zone qui doit être dans un segment de code.

    Les protections mémoire des Windows "récents" interdisant de modifier les segments exécutables devraient vous tacler.

    Et les anti-virus peuvent aussi s'y mettre. ;-)


    Paul Bacelar, Ex - MVP VC++

    mercredi 4 avril 2012 11:21
    Modérateur
  • Bonjour à tous,

    tout d'abord je tiens à vous remercier pour vos réponses. Au final nous avons réussi à passer outre ce problème grâce au langage C++.

    Pour ceux que ça intéresse, j'ai décidé de récupérer au final l'adresse ou se trouve l'instruction qui m'intéresse. J'ai encadré les instructions  avec des NOP pour être sûr que je récupère la bonne adresse:

    __asm{		//PUSH eax
    					XOR eax, eax
    					XOR ebx, ebx
    					MOV eax, fct
    					MOV DWORD PTR [InstrclearWR], eax
    					//POP eax
    					JMP end
    					NOP
    					NOP
    			fct:	call clearWR
    					NOP
    					NOP
    			end:
    		};

    Ensuite, j'ai utilisé un reinterpret cast sur un pointeur, et c'est comme ça que j'ai réussi à modifier le contenu de l'adresse mémoire récupérée au préalable:

    unsigned int puis=255; for (int j = 1 ; j < 25; j++) puis *= 2; char *c = reinterpret_cast<char*>(adresseSMC); cout << "Affichage instructions : "; for (int i = -20; i < 20; i++) { cout << dec << "i : " << i << " = " << hex << int (*(c+i)) << " "; cout << endl; }

            for (int i = 0; i < 9; i++)
            {
                *(c+i) = (char) 144;
            }

            cout << "après : ";
            for (int i = -20; i < 20; i++)
            {
                cout << dec << "i : " << i << " = " << hex << int (*(c+i)) << " ";
                cout << endl;
            }

    Je n'ai donc plus qu'a remplacer ici le code de l'instruction NOP (affectation du 144 dans le for) par les instructions qui m'intéressent.

    En tout cas cette solution est fonctionnel et a été testée :-)

    • Marqué comme réponse Myrkan57 jeudi 5 avril 2012 07:25
    jeudi 5 avril 2012 07:24
  •  

    Bonjour,

    Le comportement est normal : la variable adresseSMC de type PVOID represente un pointer et l’instruction MOV dans votre cas va modifier le pointer adresseSMC avec le contenu d’eax (voir cette discussion et cette question). Je crois que vous avez plus de chances d’obtenir d’aide sur un forum concernant l’ASM, voir http://www.programmersheaven.com/mb/x86_asm/Board.aspx, http://www.asmcommunity.net/board/index.php et http://www.tek-tips.com/threadminder.cfm?pid=272, par exemple. ASM n’est pas une technologie que je maitrise et je ne peux pas vous aider trop. En plus, les questions d’ASM ne sont pas directement liées au développement en utilisant le langage VC++.

    Merci de votre compréhension.

    Bonne journée,

    Cipri


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    lundi 2 avril 2012 08:22

Toutes les réponses