本文介紹如何讓你的指令碼解釋程式解釋執行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就是傳指標,值的話就直接傳值
下面我們來看看怎麼使用這個函式
下面是呼叫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...