VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
查看: 7718|回复: 7

[原创] [原创代码]通过Win32汇编做的DLL动态调用API

[复制链接]
 楼主| 发表于 2012-5-19 05:24:04 | 显示全部楼层 |阅读模式
经过一个通宵的研究,我终于成功了....

用Win32汇编,写了一个DLL.
在VB里面调用它的2个函数,就能动态调用DLL了.

附上Win32DLL和实例工程的源代码:
VB动态调用DLL.rar (16.05 KB, 下载次数: 1031)

点评

我觉得CallWindowProc+ASM比黑vTable方便来着...  发表于 2012-5-21 09:33
其实不用写DLL也行的,只要把机器码拷到VB的数组里面,然后把类模块的虚拟函数表黑掉就行了  发表于 2012-5-19 11:47
 楼主| 发表于 2012-5-21 00:59:27 | 显示全部楼层
为啥这么冷啊...来个回复的啊啊啊啊啊

- -所以说..点评什么的....
回复 支持 反对

使用道具 举报

发表于 2012-5-21 02:06:33 | 显示全部楼层
呃,貌似动态调用API的方法也不少呢。。。lz你这个帖子的意思是使用WIN32编写了一个可以动态调用API的DLL然后在VB里再调用该DLL实现动态调用API么?呃。。。我觉得嘛,还是CallWindowProc+机器码,又或者改某表实现比较有劲头点,呵呵
回复 支持 反对

使用道具 举报

发表于 2012-5-21 10:44:18 | 显示全部楼层
CallWindowProc再加上汇编....不就可以达成一样的功能?而且还不用其他DLL
回复 支持 反对

使用道具 举报

发表于 2020-1-13 18:55:57 | 显示全部楼层
如何动态调用CDECL函数?比如SQLIT?最好每个API都做个虚拟函数,如FUNCTION1,FUNCTION2,参数一样,就是用汇编把DLL中的函数和虚拟函数绑定一起。
回复 支持 反对

使用道具 举报

发表于 2020-1-13 18:56:22 | 显示全部楼层
如何动态调用CDECL函数?比如SQLIT?最好每个API都做个虚拟函数,如FUNCTION1,FUNCTION2,参数一样,就是用汇编把DLL中的函数和虚拟函数绑定一起。
回复 支持 反对

使用道具 举报

发表于 2022-6-17 00:23:47 | 显示全部楼层
新建类模块

Option Explicit

Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long) As Long
Private Declare Function VirtualProtect Lib "kernel32 " (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flNewProtect As Long, ByRef lpflOldProtect As Long) As Long
Private Declare Function W32Call Lib "ntdll.dll" Alias "_itoa" (ByVal pfn As Long, Params() As Long) As Long
Private Declare Sub GetMem4 Lib "msvbvm60.dll" (Ptr As Any, Src As Any)

Function vBytes(ParamArray arr() As Variant) As Byte()
     ReDim result(UBound(arr) + 1) As Byte
     Dim i As Long
     For i = 0 To UBound(arr)
         result(i) = CByte(arr(i))
     Next
     vBytes = result
End Function

Private Sub Class_Initialize()
    Dim Codes() As Byte
    Dim Procedure As Long
    Dim old As Long
    Codes = vBytes(85, 139, 236, 139, 69, 12, 139, 0, &H85, &HC0, &H74, &H12, 139, 80, 12, 139, 64, 16, 133, 192, 116, 8, 131, 232, 1, 255, 52, 130, 235, 244, 255, 85, 8, 201, 194, 8, 0)
    Procedure = GetProcAddress(GetModuleHandle("ntdll.dll"), "_itoa")
    Call VirtualProtect(Procedure, 100, &H40, old)
    Call CopyMemory(ByVal Procedure, Codes(0), UBound(Codes) + 1)
    Call VirtualProtect(Procedure, 100, old, old)
End Sub

Public Function ApiCall(ByVal pfn As Long, ParamArray args() As Variant) As Long
    Dim Params() As Long
    Dim i As Long
    Dim k As Long
    k = UBound(args)
    If k >= 0 Then
        ReDim Params(k) As Long
        For i = 0 To k
            Call GetMem4(ByVal VarPtr(args(i)) + 8, Params(i))
        Next
    End If
    ApiCall = W32Call(pfn, Params)
End Function

Public Function GetProcedure(ByVal lmodule As String, ByVal lprocedure As String) As Long
    GetProcedure = GetProcAddress(GetModuleHandle(lmodule), lprocedure)
End Function


写入的代码cdecl stdcall 调用约定通吃

ntdll.itoa - 55                            - push ebp
ntdll.itoa+1- 8B EC                   - mov ebp,esp
ntdll.itoa+3- 8B 45 0C              - mov eax,[ebp+0C]
ntdll.itoa+6- 8B 00                   - mov eax,[eax]
ntdll.itoa+8- 85 C0                   - test eax,eax
ntdll.itoa+A- 74 12                   - je ntdll.itoa+1E
ntdll.itoa+C- 8B 50 0C              - mov edx,[eax+0C]
ntdll.itoa+F- 8B 40 10               - mov eax,[eax+10]
ntdll.itoa+12- 85 C0                 - test eax,eax
ntdll.itoa+14- 74 08                  - je ntdll.itoa+1E
ntdll.itoa+16- 83 E8 01             - sub eax,01
ntdll.itoa+19- FF 34 82             - push [edx+eax*4]
ntdll.itoa+1C- EB F4                 - jmp ntdll.itoa+12
ntdll.itoa+1E- FF 55 08             - call dword ptr [ebp+08]
ntdll.itoa+21- C9                       - leave
ntdll.itoa+22- C2 0800              - ret 0008


调用例子

Dim obj As New Class1

Private Sub Command1_Click()
    Dim pfn As Long
    Dim Hwnd As Long
    pfn = obj.GetProcedure("user32", "FindWindowW")
    Hwnd = obj.ApiCall(pfn, 0, "Form1")
    MsgBox Hwnd & "   " & Me.Hwnd
End Sub

经过  Public Function ApiCall(ByVal pfn As Long, ParamArray args() As Variant) As Long 封装后效率有一点低,一般这种情况是封装给脚本调用的







回复 支持 反对

使用道具 举报

发表于 2022-6-17 00:25:16 | 显示全部楼层
新建类模块

Option Explicit

Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long) As Long
Private Declare Function VirtualProtect Lib "kernel32 " (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flNewProtect As Long, ByRef lpflOldProtect As Long) As Long
Private Declare Function W32Call Lib "ntdll.dll" Alias "_itoa" (ByVal pfn As Long, Params() As Long) As Long
Private Declare Sub GetMem4 Lib "msvbvm60.dll" (Ptr As Any, Src As Any)

Function vBytes(ParamArray arr() As Variant) As Byte()
     ReDim result(UBound(arr) + 1) As Byte
     Dim i As Long
     For i = 0 To UBound(arr)
         result(i) = CByte(arr(i))
     Next
     vBytes = result
End Function

Private Sub Class_Initialize()
    Dim Codes() As Byte
    Dim Procedure As Long
    Dim old As Long
    Codes = vBytes(85, 139, 236, 139, 69, 12, 139, 0, &H85, &HC0, &H74, &H12, 139, 80, 12, 139, 64, 16, 133, 192, 116, 8, 131, 232, 1, 255, 52, 130, 235, 244, 255, 85, 8, 201, 194, 8, 0)
    Procedure = GetProcAddress(GetModuleHandle("ntdll.dll"), "_itoa")
    Call VirtualProtect(Procedure, 100, &H40, old)
    Call CopyMemory(ByVal Procedure, Codes(0), UBound(Codes) + 1)
    Call VirtualProtect(Procedure, 100, old, old)
End Sub

Public Function ApiCall(ByVal pfn As Long, ParamArray args() As Variant) As Long
    Dim Params() As Long
    Dim i As Long
    Dim k As Long
    k = UBound(args)
    If k >= 0 Then
        ReDim Params(k) As Long
        For i = 0 To k
            Call GetMem4(ByVal VarPtr(args(i)) + 8, Params(i))
        Next
    End If
    ApiCall = W32Call(pfn, Params)
End Function

Public Function GetProcedure(ByVal lmodule As String, ByVal lprocedure As String) As Long
    GetProcedure = GetProcAddress(GetModuleHandle(lmodule), lprocedure)
End Function


写入的代码cdecl stdcall 调用约定通吃

ntdll.itoa - 55                            - push ebp
ntdll.itoa+1- 8B EC                   - mov ebp,esp
ntdll.itoa+3- 8B 45 0C              - mov eax,[ebp+0C]
ntdll.itoa+6- 8B 00                   - mov eax,[eax]
ntdll.itoa+8- 85 C0                   - test eax,eax
ntdll.itoa+A- 74 12                   - je ntdll.itoa+1E
ntdll.itoa+C- 8B 50 0C              - mov edx,[eax+0C]
ntdll.itoa+F- 8B 40 10               - mov eax,[eax+10]
ntdll.itoa+12- 85 C0                 - test eax,eax
ntdll.itoa+14- 74 08                  - je ntdll.itoa+1E
ntdll.itoa+16- 83 E8 01             - sub eax,01
ntdll.itoa+19- FF 34 82             - push [edx+eax*4]
ntdll.itoa+1C- EB F4                 - jmp ntdll.itoa+12
ntdll.itoa+1E- FF 55 08             - call dword ptr [ebp+08]
ntdll.itoa+21- C9                       - leave
ntdll.itoa+22- C2 0800              - ret 0008


调用例子

Dim obj As New Class1

Private Sub Command1_Click()
    Dim pfn As Long
    Dim Hwnd As Long
    pfn = obj.GetProcedure("user32", "FindWindowW")
    Hwnd = obj.ApiCall(pfn, 0, "Form1")
    MsgBox Hwnd & "   " & Me.Hwnd
End Sub

经过  Public Function ApiCall(ByVal pfn As Long, ParamArray args() As Variant) As Long 封装后效率有一点低,一般这种情况是封装给脚本调用的







回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2022-7-4 05:55

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表