IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

ASM + DELPHI ... soucis ... mais top intéressant !


Sujet :

Langage Delphi

  1. #1
    Membre habitué Avatar de - Robby -
    Inscrit en
    Juillet 2003
    Messages
    266
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 266
    Points : 170
    Points
    170
    Par défaut ASM + DELPHI ... soucis ... mais top intéressant !
    bonjour a tous !
    voila, sans faire de blabla:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    var toto : pointer ;
    begin
       toto := @Big ;
       ASM
          nop
    @Big: nop
       End;
    end;
    et bein, nada ... ca fonctionne pas !
    Pas moyen d'avoir l'adresse (offset) de " @Big " dans ma variable toto !
    J'ai essayé avec un " label " aussi ... niet !
    Je cherche le pro qui sait comment faire ? Y'a moyen de faire ca ?
    Tout grand merci a tous ...

    PS: c'est un truc pour Nono40 ca, clair ! Nono, t'es la ? hi

  2. #2
    Expert éminent sénior

    Avatar de Nono40
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2002
    Messages
    8 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 8 640
    Points : 19 101
    Points
    19 101
    Par défaut
    Je ne crois pas que ce soit faisable dans Delphi directement ( dans le code Pascal ). Par contre c'est tout à fait faisable dans le code Asm :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TForm1.Button3Click(Sender: TObject);
    Var i:Integer;
    begin
      Asm
        MOV  I,2
        MOV  EAX,OFFSET @Toto
        JMP  EAX
        MOV  I,1
    @Toto:
      End;
      ShowMessage(IntToStr(i));
    end;
    ( Attention à ne pas faire comme moi au début et de mettre JMP [EAX] qui fait un saut indirect.... plantage )
    Delphi :
    La F.A.Q. , 877 réponses à vos questions !
    264 sources à consulter/télécharger !

  3. #3
    Membre habitué Avatar de - Robby -
    Inscrit en
    Juillet 2003
    Messages
    266
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 266
    Points : 170
    Points
    170
    Par défaut
    Merci d'avoir répondu présent ami Nono !
    Ce que tu me dis la, oui, oui ... ca je sais !
    Dans l'assembleur lui meme, aucun problème ... heureusement !
    Mais de l'extérieur de " notre " ASM/END; ... niet !
    et c'est bien bien dommage ! C'est fou qu'on ne puisse pas le faire, ni directement, ni meme via un label ! Je comprends pas trop que les concepteurs d'un monstre comme Delphi passe a coté d'un truc comme ca ! Pas pouvoir référencer depuis une ligne Pascal, une adresse asm !!!!!
    Le but de mélanger de l'asm et un language évolué, c'est quand meme de pouvoir faire communiquer les deux, non ? ... m'enfin !

    PS: t'inquiète pour jmp [eax] ... on est tous passé par la !
    moi l'premier ... ...

  4. #4
    Expert éminent sénior

    Avatar de Nono40
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2002
    Messages
    8 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 8 640
    Points : 19 101
    Points
    19 101
    Par défaut
    Et bien fait-le en assembleur ! Quel est le problème ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TForm1.Button3Click(Sender: TObject);
    var toto : pointer ; 
    begin
      ASM
        MOV  TOTO,OFFSET @BIG
    @Big:
      End;
    end;
    EDIT : et que vas-tu faire avec ton pointeur ?
    Delphi :
    La F.A.Q. , 877 réponses à vos questions !
    264 sources à consulter/télécharger !

  5. #5
    Membre habitué Avatar de - Robby -
    Inscrit en
    Juillet 2003
    Messages
    266
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 266
    Points : 170
    Points
    170
    Par défaut
    Comment veux tu que je t'explique en deux mots, hi ...
    pas évident ! ...
    Ceci est le " noyeau " d'un appel CallGate .
    Regarde dans le code a : " <=== ICI NONO40 " , je fait référence a
    l'adresse de Gate_Gate (qq lignes asm placées ds une proc extérieure)
    Mais, j'aurais bien voulu inclure ces qq lignes asm DANS le code asm
    repris plus bas ... a l'etiquette @Up ou au label Gate: ...
    J'ai placé plus de code qu'il n'en faut ... des fois qu'un CallGate en Delphi intéresserait ! ... ceci dit, ca fonctionne top ...
    Le code de la proc. ext Gate_Gate est le meme que celui situé à @Up.
    Ce code s'exécute en Ring0 et permet via Call [esp+12] d'exécuter en
    fait ce que tu veux en ring0. En fait, en [esp+12] j'ai l'adresse de
    Ring0_code, le paramètre de départ de la fonction.
    Bon, CallGate, c'est UNE méthode pour toucher Ring0 ... y'en a d'autres !
    voila ... juste pour le plaisir ... de te répondre et d'intéresser qui le veut !

    PS: Memory_access ouvre la mémoire en lecture/écriture.
    Open_Map Mappe une zone demandée de mémoire dans l'espace
    du process utilisateur, le mien.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
     
    TYPE
           MON_STRUCT = packed record
              W_1 : word;
              W_2 : word;
              W_3 : word;
              W_4 : word;
           end;
     
           pMA_STRUCTURE = ^MON_STRUCT ;
           MON_ADDR_RING0_CODE = packed record
              low  : word ;
              high : word ;
           end;
    //------------------- toto8966@hotmail.com --- (it's me !) ------------
    VAR
           GDT : packed record
              size : word;
              Base : Cardinal;
           end;
     
           CgCall : packed record {48 bits}
              A : word ;
              B : word ;
              C : word ;
           end;
     
           Depart, base    : Cardinal ;
           Descript        : pMA_STRUCTURE absolute Depart ; // astuce ici !
           Struct_Save     : MON_STRUCT  ;
           Addr_Ring0_Code : MON_ADDR_RING0_CODE ;
           Adr_Ptr         : pointer absolute Addr_Ring0_Code;
     
    CONST b11111011 = $FFFB   ;
          b00000011 = $0003   ;
     
    //---- pour celui que ca intéresse, c'est Bingo ... cadeaux -------------
     
    FUNCTION Call_Gate (Ring0_code : pointer): cardinal ; stdcall ;
    label Gate;
    var  pas_trouver  : boolean ;
    begin
       asm
          sgdt  GDT
       end;
       Memory_Access(ouvrir);
       base := Open_Map(GDT.Base);
     
       Depart := (gdt.size and $FFF8) + base;
       pas_trouver := true ;
     
                // Recherche d'un decripteur de libre dans la gdt.
     
       While (Depart > base) and (pas_trouver = true) do
          begin    { Descriptor:Pointer ABSOLUTE Depart:Cardinal }
             if (Descript.W_3 and $8000) = $0 then
             begin
                        // construction du descripteur pour passer en Ring0.           
     
                Struct_Save := Descript^ ; {Save "CallGate Descriptor" d'origine}
     
                Adr_Ptr := @Gate_Gate ; <===== ICI NONO40
     
                   { Adr_Ptr:Pointer ABSOLUTE Addr_Ring0_Code:record 2xword }
                Descript.W_1  := Addr_Ring0_Code.low  ;
                Descript.W_2  := $0008 ; {Ring0 Code Sélector}
                                          { $EC01 = 1 11  0 1100   0000   0001    }
                Descript.W_3  := $EC02  ;{P|DPL|S|Type X ----|nb param. }
                Descript.W_4  := Addr_Ring0_Code.high ;
                pas_trouver   := false  ;
             end
             else Depart := Depart - $8 ;
          end;
     
       if pas_trouver = true then
       begin
          res := 1; Error(999);
       end ;
     
       CgCall.A := $0 ;
       CgCall.B := $0 ;
       CgCall.C :=  ((Depart - base) or b00000011 ) and b11111011 ;
       // or --> from Ring3 et and --> GDT, pas IDT. 
       Sleep (0) ;
     
    //---------------------------------
       asm                  { FAR CALL ET PASSAGE EN RING0 }
          pushad
          push  fs
     
          nop
          nop
          //int 3  {debugger mode kernel indispensable pour ce genre de truc}
          nop
     
          push  Ring0_code
          push  00000030h       // fs est a 30h en ring0 !
          mov   eax, offset CgCall
     
          dw 18FFh       // Call [eax] --> call @gate et passage en ring0.
     
          pop   fs
          popad
          jmp   @fin
     
    Gate:
    @Up:  mov   fs, bx   <===== CES QQ LIGNES ASM SONT DANS UNE
          Call [esp+12]         PROC. EXT ... J'AURAIS VOULU 
          retf  4               UTILISER CELLES CI !                          
     
    @fin: 
       end;
    //---------------------------------
     
       Descript^ := Struct_Save ; {restore le "CallGate Descriptor" d'origine}
     
       res := Nt_UnMapView(base);       Error(55);
       Memory_Access(fermer);
     
       result := 0;
    end;

  6. #6
    Expert éminent sénior

    Avatar de Nono40
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2002
    Messages
    8 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 8 640
    Points : 19 101
    Points
    19 101
    Par défaut
    Merci pour ce morceau de code très intéressant

    J'ai un début de piste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    Label Lab; // Définition d'un label global
     
    Var AdrLabGlobal:Pointer;// Et d'un pointeur globale
     
    procedure TForm1.Button3Click(Sender: TObject);
    Var AdrLabLocal:Pointer;
    begin
      Asm
        MOV AdrLabLocal,OFFSET Lab
    Lab:
      End;
      ShowMessage('Toto');
    end;
     
    procedure TForm1.Button4Click(Sender: TObject);
    begin
      Asm
        JMP [AdrLabGlobal]
      End;
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Asm
        MOV AdrLabGlobal,OFFSET Lab
      End
    end;
    Le problème est que la valeur mémorisée dans AdrLabGlobal est fausse ( décalé de quelques octets ). Alors que celle de AdrLabLocal est juste. Si avec Evaluer/Modifier on change la valeur de AdrLabGlobal en mettant la même valeur que AdrLabLocal alors je JMP fonctionne ( mais pas la suite... car le End ne correspond pas au même prototype de pile/ variables locales... plantage assuré dés la sortie du ShowMessage, mais ce n'est pas le but de la démo ). Je n'ai pas encore trouvé la raison de ce décalage.

    Je déconseille d'ailleurs aux débutants de jouer avec les pointeurs et les JMP comme montré dans le code ci-dessus
    Delphi :
    La F.A.Q. , 877 réponses à vos questions !
    264 sources à consulter/télécharger !

  7. #7
    Membre habitué Avatar de - Robby -
    Inscrit en
    Juillet 2003
    Messages
    266
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 266
    Points : 170
    Points
    170
    Par défaut
    Bingo !

    Tu constates un petits soucis de décalage ?
    Oui, mais dans ton exemple tu pousses le bouchon encore plus loin.
    Tu utilises une référence ASM - Delphi entre procédures différentes.
    Moi, mon besoin de référence se situe entre ASM et Delphi, Mais dans
    la meme procédure et .... Bingo Nono !
    regarde:
    au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Adr_Ptr := @Gate_Gate ;
    je place ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    asm
    mov   Adr_Ptr, offset Gate
    end;
    Gate est un label local.
    J'ai vérifié au debugger, top ... et click, ca tourne !
    par contre :
    si j'essaye de faire référence a @Up plutot qu'a Gate ... niet !
    autre curiosité ... indépendemment de cette histoire de référence d'adresse, " mov xxx, offset Gate " passe dans du code asm,
    mais " xxx := @Gate " ne passe pas dans du code Delphi ???
    Pas question de référence non trouvée, juste question de syntaxe.
    Il ne comprends pas " @Gate " dans delphi, alors qu'il comprends
    " offset Gate " dans asm ??? ...
    enfin ... j'ai avancé ... suis content .... Merci O grand Nono !
    et .... saluuuut a tous !

    Ps: Wai .. j'ai mis un peu bcp de code dans mon mess. précédent.
    me suis dit que ca pourrait intéresser certains bidouilleurs.
    Un CallGate en Delphi ... c'est introuvable sur le Net !

    errata:
    au label Gate, il faut placer ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    mov  fs, word ptr [esp + 8] 
    call  [esp + 12]                
    ret  8 {2 paramètres}
    bein oui, j'utilisais pas ce code, maintenant oui ! et le bon code c'est ca !
    Pas oublier la modif de " Adr_Ptr " ci dessus évidemment.
    avant je passais FS par BX, maintenant je passe par la pile, voila ! juste question de sensibilté programmistique.
    (j'aime bien la pile moi, hi !)

  8. #8
    Membre habitué Avatar de - Robby -
    Inscrit en
    Juillet 2003
    Messages
    266
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 266
    Points : 170
    Points
    170
    Par défaut
    J'ai trouvé une facon plus ... élégante de résoudre mon soucis.
    J'utilise une procédure imbriquée.
    Voici ce que devient le début de ma fonction Call_Gate :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    FUNCTION Call_Gate (Ma_Demande : pointer): cardinal ; stdcall ;
    var   pas_trouver : boolean;
    Procedure tremplin;
       asm
          mov  fs, word ptr [esp + 8]   <--------- a partir d'ici on est en Ring0. 
          call  [esp + 12]                
          retf  8                  {2 paramètres}  <-- jusqu'a la fin du retf
       end;                                           et entre les deux, c'est Noel !
    begin
       asm
          sgdt  Gdt
       end;
    etc ......
    avec ceci, on trouvera alors ,
    (voir le code de départ pour comparer ...)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    ...
    Adr_Ptr := @tremplin; ; <===== ICI NONO40 
    ...
    et la fin est encore plus simple dans ce cas :
    ...
          dw    18FFh                     // Call far ptr [eax] ... --> Ring0.
          pop   fs
          popad
      end;
    //---------------------------------
     
       Descript^ := Struct_Save;
       res := Nt_UnMapView(base);       
       Memory_Access(fermer);
       result := 0;
    end;
    et bien entendu, ca tourne top de chez top !

  9. #9
    Expert éminent sénior

    Avatar de Nono40
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2002
    Messages
    8 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 8 640
    Points : 19 101
    Points
    19 101
    Par défaut
    Concernant les labels @Up, c'est normal. Ce type de label à une portée limitée au seul bloc asm...end dans lequel il est défini. Même un simple saut assembleur d'un bloc asm à l'autre est interdit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Asm
    @Loop:
      NOP
    End
    i:=i+1;  
    Asm
      DEC ECX
      JNE @Loop // Saut interdit
    End;
    Il te faudra toujours utiliser des labels définis dans ce cas. Note que ce n'est pas une limitation, la notation @<label> n'étant qu'une méthode issue des assembleurs pour ne pas avoir à définir les symboles. Ce n'est qu'une simplification d'écriture.
    Delphi :
    La F.A.Q. , 877 réponses à vos questions !
    264 sources à consulter/télécharger !

  10. #10
    Membre habitué Avatar de - Robby -
    Inscrit en
    Juillet 2003
    Messages
    266
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 266
    Points : 170
    Points
    170
    Par défaut
    Ok, merci pour ton chaleureux coup d'main Nono !
    Je pense que le sujet est clos ... a+
    Encore merci !

    PS: je fais appel a quiconque aurait implémenté un callgate.
    je suis preneur de toute discussion a ce sujet.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. petit soucis : margin-top après clear:both.
    Par niavlys26 dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 06/11/2009, 04h32
  2. [AIR] Gros soucis mais pas de compilation
    Par Gaaaga dans le forum Flex
    Réponses: 2
    Dernier message: 12/05/2009, 11h00
  3. C++, java, DotNet, Delphi - Ok mais quoi d'autre dans le monde professionel ?
    Par _skip dans le forum Langages de programmation
    Réponses: 9
    Dernier message: 18/02/2008, 14h08
  4. Soucis fenetre Top Most
    Par theMonz31 dans le forum C#
    Réponses: 4
    Dernier message: 03/08/2007, 12h58
  5. Firefox sans souci mais IE problème
    Par Fonzy17 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 27/04/2006, 14h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo