Script Interpretation Interpretation If dynamically performs API functions

xiaoxiao2021-03-06  32

This article describes how to explain your script interpreter explained that the API function of the STDCALL specification you need to have a assembly language basis. When writing a dynamic calling API program, it is used, not nonsense! The key to calling the API is the integration of the interface. For example, we call the API in Delphi such as: tsendMessage = function (hWnd: hwnd; msg: uint; wparam: wparam; lparam: lparam): LRESULT; stdcall;

Var SMG: TsendMessage;

SMG: = getProcAddress (...);

Then we can call the SendMessage function, but we want to think about it, if we want to write your own interpretation, we are all defined in Delphi, which is obviously incorrect, so there is this study. Core of this article: Let your program adapt to the API function of almost all forms of StdCall specification based on user-defined interfaces without any interfaces that need to be defined in advance.

// Define the number of parameters of the API. If you change an array, const apiparamamax = 10; apiparamasize = 8;

Type // API parameter description Tapiparama = Record ParamType: longword; // Parameter Type Address: Pointer; // Parameter Address End; Papiparama = ^ TapiParama;

TapiParamlist = array of payiparama; // Parameter list PAPIPARAMLIST = ^ tapiParamlist; // list pointer

Look at TapiParama's definition, it is estimated that many friends will understand, we need to walk two steps, first step, organize users' calling data, the second step calls API functions according to this list

We redefine some constant {API param type} atnull = $ 000; / / to discard the return value when the return value type

Atbyte = $ 001; atshortint = $ 002; atsmallint = $ 003; atword = $ 004; atinteger = $ 005; atlongword = $ 006; atlongint = $ 007; atcardinal = $ 008;

Atint64 = $ 009;

Atreal = $ 00a; atsingle = $ 00b; atreal48 = $ 00c; // Abandon ATDOUBLE = $ 00d; atcomp = $ 00E; atcurrency = $ 00F;

Atextended = $ 010;

Atvarpointer = $ 011; atboolean = $ 012; atlongBool = $ 013; atObject = $ 014;

ATPROGRAM = $ 100; // Save is the API function address atpointer = $ 101;

OK, we start the program to call the API's main program process; // a parameter list APIPROC, // save the API address Returnpara: PAPArama); stdcall; // returnpara If the API is a function and requires return value, otherwise Set to NILIMPLEMENTATION

// paramlist parameter finishing process, here is // according to Tapiparama.ParamType to handle the pointer address of parameter // EBX, that is, Paipparama // ECX, EDX is used in the process, before use Protect the value of ECX, EDX, if ECX, EDX value needs to protect procedure initparam; stdcall; asm cmp EBX, $ 0; // Parameter = NIL JZ @Exitthisproc;

CMP DWORD PTR [EBX], ATPOINTER; // Atpointer mode JZ @jppointer; CMP DWORD PTR [EBX], Atinteger; // Atinteger mode JZ @integermode; cmp dword ptr [ebx], atreal; // REAL mode JZ @Realmode CMP DWORD PTR [EBX], Atbyte; // Byte Mode Processing Process and Integer JZ @integerMode; CMP DWORD PTR [EBX], Atshortint; // Shortint mode processing procedure and Integer JZ @integermode; CMP DWORD PTR [EBX ], atsmallint; // smallint mode processing procedure and integer JZ @integermode; cmp dword ptr [ebx], atword; // Word mode processing process and Integer is just JZ @integermode; CMP DWORD PTR [EBX], ATLONGWORD; // The longword mode processing process is just as JZ @Integermode; CMP DWORD PTR [EBX], atcardinal; // cardinal mode processing process and Integer is just JZ @integermode; CMP DWORD PTR [EBX], atint64; // int64 mode processing process and Real JZ @Realmode; CMP DWORD PTR [EBX], atsingle; // Single mode processing process and Integer as jz @integermode; cmp dword ptr [ebx], atdouble; // double mode processing process and REAL JZ @Realmode; CMP DWORD PTR [EBX], Atcomp; // CoMP mode Process and REAL JZ @Realmode; CMP DWORD PTR [EBX], Atcurrency; // Currency mode processing process and REAL JZ @Realmode; CMP DWORD PTR [EBX], atextended; jz @ExtendedMode; CMP DWORD PTR [EBX] , atvarpointer; // varpointer mode processing process and Integer JZ @integermode; cmp dword ptr [ebx], atboolean; // boolean mode processing process and byte as JZ @integermode; cmp dword ptr [EBX], ATLONGBOOL; // longbool The pattern processing process is just as JZ @Integermode; CMP DWORD PTR [EBX], atObject; // Object mode processing procedure, as JZ @integermode; jmp @Exitthisproc;

@INTEGERMODE: // Integer Mode MOV EBX, [EBX $ 4]; //tapiparama.address address Add EBX, - $ 4; // minus 4, because 4 JMP @jppointer; @Realmode: Add EBX, $ 4 The address MOV EBX, [EBX] // of //tapiparama.address // Get the actual floating point number address POP ECX; // Remove the EIP PUSH DWORD PTR [EBX 4] after RET [EBX 4]; // API Parameter Real Entering Push DWORD PTR [EBX]; // API Parameter Real Entering Push ECX; // Rent EIP Revent JMP @ExitThisproc;

@ExtendedMode: Add EBX, $ 4; MOV EBX, [EBX] POP ​​ECX; // Remove the EIP MOV DX after RET, [EBX 6]; Push EDX; // API Parameter Improvement Push Dword PTR [EBX 4] ; // API parameter enables the Push DWORD PTR [EBX]; // API parameter Improve Push ECX; // Retiled EIP Write JMP @EXITTHISPROC;

@Jppointer: Add EBX, $ 4;

@ParamStart: POP ECX; // Remove the EIP PUSH [EBX] // API required to remove the parameters required by the RET, the parameters required for the PUSH ECX; // RET, the EIP will be removed @Exitthisproc: End;

// API calling process

Procedure doapi (paramlist: papiparamlist; apiproc, returnpara: papiparama); stdcall; begin asm push edx; push ebx; push ecx; push eax; // protection site

MOV EBX, paramlist; MOV EBX, [EBX]; // TapiParamlist Mov Eax, [EBX-4]; // High Array Dec Eax; @ loop1: // Cycle from High (paramlist ^) Downto 0 CMP EAX, 1; JZ @paramaover; MOV EBX, paramlist; MOV EBX, [EBX]; MOV ECX, EAX; Imul ECX, APAramasize add EBX, ECX; Call initparam; // finishing parameter DEC EAX; JMP @ Loop1;

@Paramaover: MOV EBX, [APIPROC]; // Get the API's entry address MOV EBX, [EBX $ 4]; Call EBX; // Call the API function

// Handle the function returns the result MOV EBX, RETURNPARA; CMP EBX, $ 0; // is NIL JZ @Exitthisproc;

CMP DWORD [EBX], ATPOINTER; JZ @integermode; cmp dword [ebx], atinteger; jz @integermode; cmp dword [ebx], atreal; jz @RealMode; cmp dword [ebx], atby; jz @bytemode; cmp dword [Ebx], atshortint; // shortint and byte processing method as jz @bytemode; cmp dword; jz @smallintmore; cmp dword [ebx], atword; // Word and Smallint processing method JZ @smallintmode; CMP DWORD [EBX], ATLONGWORD; / / WORD and Smallint processing methods JZ @integermode; cmp dword [ebx], atcardinal; // cardinal and smallint processing method as JZ @integermode; cmp dword [ebx], atint64; jz @ INT64MODE; CMP DWORD [EBX], ATSINGLE; JZ @SINGLEMODE; CMP DWORD [EBX], ATDOUBLE; / / DOUBLE and REAL processing method as jz @realmode; cmp dword [ebx], atcomp; jz @compmode; cmp dword [ebx ], atcurrency; // currency and COMP processing method are just as jz @compmode; cmp dword; // currency and integer processing method as JZ @integermode; cmp dword [ebx], Atboolean; // Boolean and Byte processing method JZ @bytemode; cmp dword [ebx], atlongBool; // longbool and integer processing method is just as JZ @integermode; cmp dword [ebx], atobject; // Object, and Integer processing method JZ @Integermode;

JMP @exitthisproc; // 无效 无 模式

@INTEGERMODE: MOV EBX, [EBX $ 4]; // Integer mode, directly set Tapiparama.Address points to Integer's value MOV [EBX], EBX; JMP @exitthisproc; @Realmode: MOV EBX, [EBX $ 4]; FSTP Qword PTR [EBX]; // Receive floating point wait; jmp @exitthisproc;

@BYTEMODE: MOV EBX, [EBX $ 4]; MOV [EBX], Al; JMP @ExitThisproc;

@Smallintmode: MOV EBX, [EBX $ 4]; MOV [EBX], AX; JMP @Exitthisproc;

@ INT64MODE: MOV EBX, [EBX $ 4]; MOV [EBX], EAX; MOV [EBX 4], EDX; JMP @exitthisproc;

@SingleMode: MOV EBX, [EBX $ 4]; FSTP DWORD PTR [EBX]; Wait; JMP @ExitThisproc;

@Compmode: MOV EBX, [EBX $ 4]; Fistp Qword PTR [EBX]; Wait; JMP @ExitThisproc;

@Exitthisproc: pop eax; // Restore on-site POP ECX; POP EBX; END;

Add a few words: When the API parameter is called, if it is VAR is a pointer of the VAR, if it is a structure, the PCHAR is also an integer or smallint, it is the direct pass value if it is a floating point, VAR is transmitted. The pointer, the value of the value is directly transmitted.

The process of dynamically calling the API is all written. Blue Ray Original, please keep this information. :) Http://www.1285.net/zgf@1285.net

Let's take a look at how to use this function.

Here is the value of the process var // parameter of calling SendMessage, or do not do these, because SendMessage does not have a pointer parameter Intlist: Array [1..4] of integer; returnint: integer; paramlist: 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 (para) DO begin paramlist [i] .paramtype: = atinteger; paramlist [i] .address: = @intlist [i]; end; apiproc.paramtype: = atprogram; apiproc.address = @SendMessage; // API function entry address Returnpara.ParamType: = atinteger; returnpara.address: = @Returnint; doapi (@ paramlist, @ apiproc, @ Returnpara); // The return value is saved to return. End; It is not difficult to see that we only need to explain the user-defined API function address, the API parameter type, the API return value type, the value of the API parameter, and organize these data, put it in an Array of Integer or Array Of real .. is passing to doapi. Retrieve the result, and hand it over to the interpreter processing

Examples of configuration calls: var SD: 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 This structure has the current date and time End;

If the parameter or result is the object var obj: Tobject; .... paramlist [0] .ParamType: = atobject; paramtype [0] .address: = @obj; ....

It looks so troublesome, call an API to make such a complicated thing, call GetSystemTime (SD) directly? Write an explanation seems to be like this: ("From the string to translate into a program to run this, such as: VB, VF

转载请注明原文地址:https://www.9cbs.com/read-78026.html

New Post(0)