Delphi动态调用API函数Demo:
procedure TForm1.formcreate(Sender: TObject); //当窗口被创建时
type //首先用type定义一个函数,参数跟MessageBoxA一样,用stdcall调用约定
MyMessageBox = function(hWnd:Cardinal;lpText, lpCaption: AnsiString ;uType: Cardinal): Integer; stdcall; //定义的函数名为MyMessageBox,这里跟静态调用不同的是,静态调用是 function 函数名(参数),这里是 函数名=函数(参数)
var
MyMessage:MyMessageBox; //定义一个变量,名为MyMessage,类型是MyMessageBox,也就是这个变量等于函数
Apiaddr:Integer; //保存获取到的api函数地址
Test:Integer; //用来做调试输出用
begin
Apiaddr:=Integer(GetProcAddress(LoadLibrary('user32.dll'), 'MessageBoxA'))+2; //这里+2是为了测试7字节热补丁,实际上api函数的mov edi,edi是没有意义的,这句代码占2个字节,故我们可以直接用push开始执行,所以这里+2,也可以不+2,因为getprocessaddress返回的是pointer类型,所以用integer转整数再+2
@MyMessage:=Pointer(apiaddr); //这里就将这个+2以后的地址转成pointer类型,加@是为了取MyMessage的实际地址,但是这里好像不加@也可以,但是为了保险还是加@
Test:=Integer(@MyMessage); //这里拿来做调试输出,可不用这句代码
MyMessage(0,'动态调用','动态调用',0); //这里我们声明的一个局部变量,他的类型是函数类型,所以这里这个局部变量就等于我们的函数了,所以直接调用,注意Delphi下,MessageBoxA的标题和内容参数是ansistring类型,如果我们定义的函数是string类型,那么就应该调用MessageBoxW,否则会乱码
end;
注:
所谓的动态调用,是指我们不声明API函数,但是我们通过动态获取API指针调用这个API函数
静态调用:
function
MyMessageBoxA(hwnd:integer;text,caption:Ansistring;uType:integer):Integer;stdcall;external 'user32.dll' name 'MessageBoxA'
某些APi函数的头2给字节是mov edi,edi,+2就是跳过这句代码开始执行API,不影响API函数的执行结果,当然不+2就是正常的API调用执行(就是将入口地址+2,再转换为指针输出指向调用)