Method for moving external functions in VB

zhaozj2021-02-16  46

VB can use the DecLare declaration to call the external function of the standard DLL, but its limitations are also obvious: using Declare we can only load the function pointer specified by the lib and alias words when designing! Instead of specifying a function pointer that is dynamically loaded by our own motion, you cannot use the declare statement to call any function pointer. When we want to dynamically call external functions, we must consider using other auxiliary methods to complete this task.

In the article "VB really can't think of a series of three: VB pointer Sunflower Collection", "Matthew Curland's VB Function Pointer Call", "Dynamic Creating Automation Interface Implement VB" function pointer to call "and other literature, etc. A certain degree of discussion, but the clue is very cumbersome, and the rookie like me is a bit deep. During the data search process, I find this feature by tune the assembler in VB, which is relatively simple to implement this feature. The following is the implementation principle. :

1) Use loadLibrary load DLL; 2) getProcAddress get function pointer;

The pre-load function is obtained above, but the method of using this pointer is not provided in VB. We can complete the call of the function pointer through a compilation language!

3) Press all parameters of the function into the stack by assembly language, and then use the Call to use the function pointer.

The main procedures for implementing the above features: 'Loading Dllibaddr = LoadLibrary (Byval "User32")' Get function pointer procaddr = getProcadDress (libaddr, byval "messageboxa") 'prototype for MessageBox (hwnd, lptext, lpcaption, utype)

'- below assembly section --- Push Utypepush LPCAPTIONPUSH LPTEXTPUSH HWNDPUSH LPTEXTPUSH HWNDCALL PROCADDR' --------------------

Freeelibrary libraddr 'release space

Hey, simple enough! Below is the source code of the MESSAGEBOXA. The above steps are encapsulated into the Rundll32 function, which can be placed in the module (CALLAPIBYNAME.BAS): DIM S1 () AS BYTE, S2 () AS BYTE DIM RET AS Long S1 = STRCONV ( "Hello ~ World", VBFromunicode S2 = STRCONV ("VBNote", VBFromunicode) RET = Rundll32 ("User32", "MessageBoxa", HWnd, Varptr (S1 (0)), Varptr (S2 (0)), 0 &)

Sourcecodes in Callapibyname.bas:

Option expedition

Private Declare Function LoadLibrary Lib "kernel32" Alias ​​"LoadLibraryA" (ByVal lpLibFileName As String) As LongPrivate Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As LongPrivate Declare Function CallWindowProc Lib "User32" Alias ​​"CallWindowProcA "(ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongPrivate Declare Function FreeLibrary Lib" kernel32 "(ByVal hLibModule As Long) As LongPrivate Declare Sub CopyMemory Lib" kernel32 "Alias" RTLMOVEMEMORY "(LPDest As Any, Lpsource As Any, Byval CBYTES As Long) public m_opindex as long 'write position private m_opcode () as byte' askEMBLE OPCODE

Public Function RunDll32 (LibFileName As String, ProcName As String, ParamArray Params ()) As Long Dim hProc As Long Dim hModule As Long ReDim m_OpCode (400 6 * UBound (Params)) 'reserved for write m_OpCode' read API library hModule = LoadLibrary (ByVal LibFileName) If hModule = 0 Then MsgBox "Library read failure!" Exit function End If 'acquired function address hProc = GetProcAddress (hModule, ByVal ProcName) If hProc = 0 Then MsgBox "function reads failed!" , Vbcritical Freelibrary HModule Exit Function End IF 'executing Assembly Code section Rundll32 = CallWindowProc (getCodestart (HProc, params), 0, 1, 2, 3) Freelibrary HModule' release space END FUNCTION

Private function getCodestart (Byval Arrparams as line, byval arrparams as variant) AS long '--- The following is the assembly section -' Role: Press the parameters of the function into the stack DIM LNGINDEX AS Long, LNGCODESTART AS Long 'start address Must be the multiple of the "Varptr function is used to get the address LNGCODESTART = (Varptr (m_opcode (0)) or & HF) 1 m_opIndex = LNGCODESTART - VARPTR (m_opcode (0)) 'program starting element of the element Part of the interrupt point is added to for lngindex = 0 to m_opindex - 1 m_opcode (lngindex) = & HCC 'int 3 next lngindex' ------- The following starts to put the required program ---------- - 'Because the parameter push to stack is to put the stdcall call parameter by the last start to put the stack for lngindex = ubound (arrparams) TO 0 Step -1 AddByTocode & H68' Push machine code is H68 AddlongTocode Clng (Arrparams (LNGIndex)) 'Parameter address Next LNGINDEX' CALL HPROC ADDBYTOCODE & HE8 'CALL machine code is HE8 AddlongTocode LNGPROC - Varptr (m_opcode (m_opIndex)) - 4' function address Address CALL address' --------- End Office Needable program -------------- 'Return Call Functions AddBytetocode & HC2' RET 10h AddByTocode & H10 AddBytetocode & H0 getCodestart = LNGCODESTERTEND FUNCTI OnPrivate Sub AddlongTocode (LDATA As Long) Writes the parameters of the long type to m_opcode CopyMemory M_opcode (M_opIndex), LDATA, 4 m_opIndex = m_opIndex 4END SUB

Private Sub AddintTocode (iData as Byte) 'writes the parameter of the Integer type M_OPCode CopyMemory M_opcode (m_opIndex), Idata, 2 m_opIndex = m_opIndex 2nd Sub

Private sub addbytetocode (bdata as Byte) 'writes the parameter of the Byte type M_opcode (m_opIndex) = bdata m_opIndex = m_opIndex 1END SUB

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

New Post(0)