指令碼動態執行API函式

2021-04-25 10:43:02 字數 2868 閱讀 1554

本文介紹如何讓你的指令碼解釋程式解釋執行stdcall規範的api函式

你需要有組合語言基礎,在編寫動態呼叫api程式的時候才用得到,

不廢話了開始!

呼叫api的關鍵所在就是介面的整理,比如我們在delphi裡面呼叫api

如:tsendmessage = function(hwnd: hwnd; msg: uint; wparam: wparam; lparam: lparam): lresult; stdcall;

var

smg : tsendmessage;

smg := getprocaddress(...);

然後我們就可以呼叫sendmessage函式了,但是我們想一想,如果我們

要寫自己的解釋程式,難道什麼介面我們都在delphi裡定義好,這顯然

不正確,因此就有了本文的研究。

本文的核心:讓你的程式適應在不需要事先定義任何介面的情況下,根

據使用者自定義的介面呼叫幾乎所有形式的stdcall規範的api函式。

//定義api最多的引數個數,如果換動態陣列就不需要了

const

apiparamamax  = 10;

apiparamasize = 8;

type

//api引數描述

tapiparama = record

paramtype : longword;    //引數型別

address   : pointer;     //引數位址

end;

papiparama = ^tapiparama;

tapiparamlist = array of tapiparama;  //引數列表

papiparamlist = ^tapiparamlist;       //列表指標

一看tapiparama的定義,估計很多朋友就明白了,我們需要分兩步走,

第一步,整理使用者的呼叫資料,第二步根據這個列表呼叫api函式

我們再定義一些常量

補充幾句:api引數呼叫時,如果是var就是傳var的指標,

如果是結構也是傳結構的指標,pchar也是

如果是整數或者smallint那幾個,就是直接傳值

如果是浮點數,var就是傳指標,值的話就直接傳值

[email protected]

下面我們來看看怎麼使用這個函式

下面是呼叫sendmessage的過程

var//引數的值,也可以不要這幾個,因為sendmessage沒有傳指標的引數

intlist    : array [1..4] of integer;

returnint  : integer;

paramlist  : tapiparamlist;

returnpara : tapiparama;

apiproc    : tapiparama;

i : integer;

begin

intlist[1] := handle;

intlist[2] := wm_close;

intlist[3] := 0;

intlist[4] := 0;

setlength(paramlist,4);

for i:=low(paramlist) to high(paramlist) do begin

paramlist[i].paramtype  := atinteger;

paramlist[i].address    := @intlist[i];

end;

apiproc.paramtype     := atprogram;

apiproc.address       := @sendmessage;  //api函式的入口位址

returnpara.paramtype  := atinteger;

returnpara.address    := @returnint;

doapi(@paramlist,@apiproc,@returnpara);

//返回值被儲存到returnint裡了。

end;

不難看出,我們在解釋程式裡面只需要解釋使用者定義的api函式位址,

api的引數型別,api的返回值型別,api引數的值,並整理這些資料,

放到乙個array of integer 或者array of real..裡面,傳給doapi就

可以了。取回結果,並交給直譯器處理

結構呼叫的例子:

varsd : tsystemtime;

paramlist  : tapiparamlist;

apiproc    : tapiparama;

begin

setlength(paramlist,1);

paramlist[0].paramtype := atpointer;

paramtype[0].address   := @sd;

apiproc.paramtype      := atprogram;

apiproc.address        := @getsystemtime;

doapi(@paramlist,@apiproc,nil);

//sd這個結構裡就有當前的日期和時間了

end;

如果引數或者結果是物件

varobj : tobject;

....

paramlist[0].paramtype := atobject;

paramtype[0].address   := @obj;

....

看起來好麻煩,呼叫乙個api需要作這麼複雜的事情,直接呼叫

getsystemtime(sd)不就好了嗎?寫解釋程式好象就這個樣:(

從字串翻譯成程式來執行就這麼回事,如:vb,vf

動態執行函式

引用 呼叫 declare v start runtime date v datefrom varchar2 15 v dateto varchar2 15 v redoflag number 1 v para1 varchar2 100 v para2 varchar2 100 v errcode...

c 動態執行C 指令碼

usingmicrosoft.csharp usingsystem.codedom.compiler usingsystem.reflection private voidbutton1 click objectsender,eventargs e n n compilerresults vcomp...

API函式執行可執行檔案

shellexecute hwnd hwnd,父視窗控制代碼 lpcstr lpoperation,操作型別 lpcstr lpfile,要進行操作的檔案或路徑 lpcstr lpparameters,當lpoperation為 explore 時指定要傳遞的引數,通常設為null lpcstr l...