begin process at 2010 02 09 19:20:30
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Delphi et asm

 > APPELER UNE API EN ASM AVEC DELPHI

APPELER UNE API EN ASM AVEC DELPHI


 Information sur la source

Note :
8 / 10 - par 1 personne
8,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Delphi et asm Niveau :Débutant Date de création :03/05/2005 Vu / téléchargé :3 290 / 229

Auteur : DeadlyPredator

Ecrire un message privé
Site perso
Commentaire sur cette source (2)
Ajouter un commentaire et/ou une note

 Description

Ce code permet d'appeler n'importe quelle api (stdCall) sans avoir à connaitre ses paramètres. Il n'est pas si compliqué. Il y a encore quelques problèmes à résoudre comme comment faire fonctionner iFlags pour la msgbox ... mais c ma première source en ASM.

Source

  • //FAIT PAR DEADLYPREDATOR LE 3 MAI 2005 - À UTILISER À VOS RISQUES
  • unit frmMain;
  • interface
  • uses
  • Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  • Dialogs, StdCtrls;
  • type
  • TForm1 = class(TForm)
  • txtGetTickCount: TEdit;
  • btnGetTickCount: TButton;
  • Label1: TLabel;
  • GroupBox1: TGroupBox;
  • btnMsgBox: TButton;
  • Label2: TLabel;
  • txtMsg: TEdit;
  • Label3: TLabel;
  • txtTitle: TEdit;
  • optMsgInfo: TRadioButton;
  • optMsgAlerte: TRadioButton;
  • chkMsgYesNo: TCheckBox;
  • lMsgRep: TLabel;
  • optMsgCritique: TRadioButton;
  • optMsgNormal: TRadioButton;
  • procedure FormCreate(Sender: TObject);
  • procedure FormDestroy(Sender: TObject);
  • procedure btnGetTickCountClick(Sender: TObject);
  • procedure btnMsgBoxClick(Sender: TObject);
  • private
  • { Private declarations }
  • public
  • { Public declarations }
  • end;
  • var
  • Form1: TForm1;
  • // Variables qui vont contenir le handle des DLLs, jusqu'à leur déchargement
  • iKernel32,iUser32: Cardinal;
  • // -----
  • // Variables qui vont contenir l'adresse des APIs, jusqu'au déchargement des DLLs
  • pGetTickCount,pMessageBox: Pointer;
  • // -----
  • implementation
  • {$R *.dfm}
  • procedure TForm1.FormCreate(Sender: TObject);
  • begin
  • //Chargement des DLLs
  • iKernel32:=LoadLibrary('Kernel32.dll');// La variable stoke le handle de la DLL, on va en avoir besoin
  • iUser32:=LoadLibrary('User32.dll'); // ^^^^
  • //Recherche de l'adresse des APIs
  • pGetTickCount:=GetProcAddress(iKernel32,'GetTickCount');// Voilà à quoi sert le handle. Si l'API n'est pas trouvée, le pointer est nul (=nil)
  • pMessageBox:=GetProcAddress(iUser32,'MessageBoxA'); // ^^^^
  • end;
  • procedure TForm1.FormDestroy(Sender: TObject);
  • begin
  • //Déchargement des DLLs
  • FreeLibrary(iKernel32);// Libération de la dll
  • FreeLibrary(iUser32); // ^^^^
  • end;
  • procedure TForm1.btnGetTickCountClick(Sender: TObject);
  • var
  • iRetVal: Cardinal;//Pour plus tard
  • begin
  • {Appel de GetTickCount
  • Dans delphi : function GetTickCount () : Integer; stdcall; external 'kernel32' name 'GetTickCount'
  • Bon, on a la DLL chargée et l'adresse de l'API voulue, le plus difficile reste à venir ...
  • Je ne vous ferez pas un cours ASM 101 car moi même je n'y connait RIEN presque
  • Vous ne comprenez ce que vous écrivez, pas grave.
  • }
  • asm//Dit à Delphi qu'on commence un bloc d'instructions ASM
  • CALL pGetTickCount //On appel le pointeur de l'API, obtenu par GetProcAddress
  • MOV iRetVal,EAX //En gros, on met le résultat de l'API dans la variable Delphi "iRetVal", pour des types complexes, cela sera peut-être un pointeur
  • end;//Dit à Delphi que le bloc d'instructions ASM est fini
  • //Maintenant, on a le résultat de GetTickCount. Sauf que c'était trop facile.
  • //GetTickCount ne requiert aucun paramètre. Donc pas vraiment de problèmes
  • txtGetTickCount.Text:=IntToStr(iRetVal);//Conversion en string et affichage dans la textbox
  • end;
  • procedure TForm1.btnMsgBoxClick(Sender: TObject);
  • var
  • iRetVal: Cardinal;//Pour plus tard
  • iFlags: Cardinal;//Options d'apparence de la msgbox
  • sTexte, sTitre:PChar;//Pour plus tard
  • begin
  • lMsgRep.Caption:='';//on efface la réponse ...
  • if(optMsgAlerte.Checked=true) then iFlags:=MB_ICONEXCLAMATION;//préparation des paramètres de l'apparence de la msgbox
  • if(optMsgCritique.Checked=true) then iFlags:=MB_ICONASTERISK; //^^^^
  • if(optMsgInfo.Checked=true) then iFlags:=MB_ICONQUESTION; //^^^^
  • if(chkMsgYesNo.Checked=true) then iFlags:=+MB_YESNO; //^^^^
  • sTexte:=PChar(txtMsg.Text); //Il faut convertir le texte en pchar avant
  • sTitre:=PChar(txtTitle.Text); //^^^^
  • {Appel de MessageBoxA
  • Dans delphi : function GetTickCount () : Integer; stdcall; external 'kernel32' name 'GetTickCount'
  • Maintenant, c'est une fonction plus complexe avec des paramètres.
  • On place chaque paramètre avec PUSH
  • ATTENTION!!!! LES PARAMÈTRES DOIVENT ÊTRE DONNÉ À L'INVERSE, DE DROITE À GAUCHE!!!
  • SI PAR EXEMPLE function x(a;b;c;d)
  • on push dans cette ordre d, c, b, a
  • Cette méthode ne permet que de fonctionner avec les api qui utilise la convention d'appel appelée stdcall, soit toutes les APIs de windows et la grande majoritée des autres
  • }
  • asm//Dit à Delphi qu'on commence un bloc d'instructions ASM
  • PUSH 0//Tout les paramètres pusher dans l'ordre inverse
  • PUSH sTitre//^^^^
  • PUSH sTexte//^^^^
  • PUSH 0//iFlags//^^^^ --> iFlags ne fonctionne pas encore, je ne sais pas pourquoi mais la valeur doit être convertie avant mais en quoi?
  • CALL pMessageBox //On appel le pointeur de l'API, obtenu par GetProcAddress
  • MOV iRetVal,EAX //En gros, on met le résultat de l'API dans la variable Delphi "iRetVal", pour des types complexes, cela sera peut-être un pointeur
  • end;//Dit à Delphi que le bloc d'instructions ASM est fini
  • if(iRetVal=7) then lMsgRep.Caption:='vous avez répondu non';//^va fonctionner quand iFlag va fonctionner
  • if(iRetVal=6) then lMsgRep.Caption:='vous avez répondu oui';//^^^^
  • end;
  • end.
//FAIT PAR DEADLYPREDATOR LE 3 MAI 2005 - À UTILISER À VOS RISQUES
unit frmMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    txtGetTickCount: TEdit;
    btnGetTickCount: TButton;
    Label1: TLabel;
    GroupBox1: TGroupBox;
    btnMsgBox: TButton;
    Label2: TLabel;
    txtMsg: TEdit;
    Label3: TLabel;
    txtTitle: TEdit;
    optMsgInfo: TRadioButton;
    optMsgAlerte: TRadioButton;
    chkMsgYesNo: TCheckBox;
    lMsgRep: TLabel;
    optMsgCritique: TRadioButton;
    optMsgNormal: TRadioButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnGetTickCountClick(Sender: TObject);
    procedure btnMsgBoxClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

// Variables qui vont contenir le handle des DLLs, jusqu'à leur déchargement
iKernel32,iUser32: Cardinal;
// -----

// Variables qui vont contenir l'adresse des APIs, jusqu'au déchargement des DLLs
pGetTickCount,pMessageBox: Pointer;
// -----

implementation

{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
begin
//Chargement des DLLs
iKernel32:=LoadLibrary('Kernel32.dll');// La variable stoke le handle de la DLL, on va en avoir besoin
iUser32:=LoadLibrary('User32.dll');    // ^^^^
//Recherche de l'adresse des APIs
pGetTickCount:=GetProcAddress(iKernel32,'GetTickCount');// Voilà à quoi sert le handle. Si l'API n'est pas trouvée, le pointer est nul (=nil)
pMessageBox:=GetProcAddress(iUser32,'MessageBoxA');     // ^^^^
end;


procedure TForm1.FormDestroy(Sender: TObject);
begin
//Déchargement des DLLs
FreeLibrary(iKernel32);// Libération de la dll
FreeLibrary(iUser32);  // ^^^^
end;

procedure TForm1.btnGetTickCountClick(Sender: TObject);
var
iRetVal: Cardinal;//Pour plus tard
begin
{Appel de GetTickCount

Dans delphi : function GetTickCount () : Integer; stdcall; external 'kernel32' name 'GetTickCount'

Bon, on a la DLL chargée et l'adresse de l'API voulue, le plus difficile reste à venir ...
Je ne vous ferez pas un cours ASM 101 car moi même je n'y connait RIEN presque
Vous ne comprenez ce que vous écrivez, pas grave.
}
  asm//Dit à Delphi qu'on commence un bloc d'instructions ASM

  CALL pGetTickCount //On appel le pointeur de l'API, obtenu par GetProcAddress
  MOV iRetVal,EAX //En gros, on met le résultat de l'API dans la variable Delphi "iRetVal", pour des types complexes, cela sera peut-être un pointeur

  end;//Dit à Delphi que le bloc d'instructions ASM est fini

//Maintenant, on a le résultat de GetTickCount. Sauf que c'était trop facile.
//GetTickCount ne requiert aucun paramètre. Donc pas vraiment de problèmes
txtGetTickCount.Text:=IntToStr(iRetVal);//Conversion en string et affichage dans la textbox

end;

procedure TForm1.btnMsgBoxClick(Sender: TObject);
var
iRetVal: Cardinal;//Pour plus tard
iFlags: Cardinal;//Options d'apparence de la msgbox
sTexte, sTitre:PChar;//Pour plus tard
begin
lMsgRep.Caption:='';//on efface la réponse ...
if(optMsgAlerte.Checked=true) then iFlags:=MB_ICONEXCLAMATION;//préparation des paramètres de l'apparence de la msgbox
if(optMsgCritique.Checked=true) then iFlags:=MB_ICONASTERISK; //^^^^
if(optMsgInfo.Checked=true) then iFlags:=MB_ICONQUESTION;     //^^^^
if(chkMsgYesNo.Checked=true) then iFlags:=+MB_YESNO;          //^^^^

sTexte:=PChar(txtMsg.Text);    //Il faut convertir le texte en pchar avant
sTitre:=PChar(txtTitle.Text);  //^^^^

{Appel de MessageBoxA

Dans delphi : function GetTickCount () : Integer; stdcall; external 'kernel32' name 'GetTickCount'

Maintenant, c'est une fonction plus complexe avec des paramètres.
On place chaque paramètre avec PUSH
ATTENTION!!!! LES PARAMÈTRES DOIVENT ÊTRE DONNÉ À L'INVERSE, DE DROITE À GAUCHE!!!
SI PAR EXEMPLE function x(a;b;c;d)
on push dans cette ordre d, c, b, a
Cette méthode ne permet que de fonctionner avec les api qui utilise la convention d'appel appelée stdcall, soit toutes les APIs de windows et la grande majoritée des autres
}
  asm//Dit à Delphi qu'on commence un bloc d'instructions ASM

  PUSH 0//Tout les paramètres pusher dans l'ordre inverse
  PUSH sTitre//^^^^
  PUSH sTexte//^^^^
  PUSH 0//iFlags//^^^^ --> iFlags ne fonctionne pas encore, je ne sais pas pourquoi mais la valeur doit être convertie avant mais en quoi?

  CALL pMessageBox //On appel le pointeur de l'API, obtenu par GetProcAddress
  MOV iRetVal,EAX //En gros, on met le résultat de l'API dans la variable Delphi "iRetVal", pour des types complexes, cela sera peut-être un pointeur

  end;//Dit à Delphi que le bloc d'instructions ASM est fini

if(iRetVal=7) then lMsgRep.Caption:='vous avez répondu non';//^va fonctionner quand iFlag va fonctionner
if(iRetVal=6) then lMsgRep.Caption:='vous avez répondu oui';//^^^^
end;

end.

 Conclusion

Merci. J'aimerais en faire une API qu'on pourrais utiliser pour appeler d'autres API. Ça pourrait servir.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !
  •   asm api
    • frmMain.~ddpTélécharger ce fichier [Réservé aux membres club]51 octets
    • frmMain.~dfmTélécharger ce fichier [Réservé aux membres club]2 804 octets
    • frmMain.~pasTélécharger ce fichier [Réservé aux membres club]5 004 octets
    • frmMain.dcuTélécharger ce fichier [Réservé aux membres club]5 943 octets
    • frmMain.ddpTélécharger ce fichier [Réservé aux membres club]51 octets
    • frmMain.dfmTélécharger ce fichier [Réservé aux membres club]2 804 octets
    • frmMain.pasTélécharger ce fichier [Réservé aux membres club]Voir ce fichier5 004 octets
    • prjAPI.cfgTélécharger ce fichier [Réservé aux membres club]Voir ce fichier444 octets
    • prjAPI.dofTélécharger ce fichier [Réservé aux membres club]Voir ce fichier2 015 octets
    • prjAPI.dprTélécharger ce fichier [Réservé aux membres club]Voir ce fichier190 octets
    • prjAPI.exeTélécharger ce fichier [Réservé aux membres club]397 312 octets
    • prjAPI.resTélécharger ce fichier [Réservé aux membres club]876 octets

Télécharger le zip


 Sources de la même categorie

RENVOIT UNE CHAINE DE X FOIS LE CARACTÈRE DEMANDÉ par cutmaster
PETIT ÉQUIVALENT DU ?: DU C EN DELPHI POUR LES CHAINES, LONG... par cutmaster
AVOIR LE NOM DU JOUR DE LA SEMAINE DÉSIGNÉ par cutmaster
REMPLISSAGE FORMATÉ D'UN SHORTSTRING par cutmaster
3 FONCTIONS GRAPHIQUES PLUS RAPIDES QUE LES FONCTIONS DE BAS... par balgrim

Commentaires et avis

Commentaire de grandvizir le 31/08/2006 10:09:24

Salut DeadlyPredator. J'ai une petite remarque.

Sachant que Kernel et compagnie sont déjà chargés automatiquement par l'application, je ne pense pas qu'il soit nécessaire de les recharger. Autant utiliser directement l'opérateur Arobase pour récupérer l'adresse de la procédure désirée.

Exemple:

program Project1;
uses Windows, SysUtils, Dialogs;
{$R *.res}

var TickAsm, TickPascal : integer;
    Address             : Pointer;
begin
//APPEL EN ASSEMBLEUR
  Address:=@GetTickCount;
  asm
    CALL  Address
    MOV   TickAsm, EAX
  end;

//APPEL EN PASCAL
  TickPascal:=GetTickCount;

//LES DEUX RESULTATS SONT PAREILS
  ShowMessage(Format('%d = %d',[TickAsm, TickPascal]));
end.

Cela dit le code est bon. C'est juste une autre manière de faire.

Commentaire de sarko le 14/09/2007 14:31:48

Bonjour ,
a propos du non fonctionnement de iflags ,cette
variable doit etre sur le premier push.
Le 4eme push serait le numero de fenetre /??
N'oublie pas le probleme des icones et attention aux codes
interdits .
Bon courage

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,593 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales