|
Trouver une ressource
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
APPELER UNE API EN ASM AVEC DELPHI
Information sur la source
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.
Sources de la même categorie
Commentaires et avis
|
Comparez les prix Nouvelle version

HTC G1
Entre 449€ et 449€
|