找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 20|回复: 1

用机器码注入实现VB6回调函数功能,并支持自定义函数功能。

[复制链接]
发表于 昨天 18:57 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
在编译成native exe 后可实现回调函数的功能,不依赖DLL库。I立即回调,比通常通过callwindowproc实现快多了。
使用场景是需要高速回调的场合,比如模拟cpu指令的高速查表解码。在ide模式不支持,可以用callwindowsproc或我提供的callback.dll代替。
同时支持自定义虚函数,用实现不同功能的机器码自动替换掉,操作简单就一行代码。obj.InjectCode AddressOf 函数名, 机器码串。
form1窗体代码:
Option Explicit
'支持四个long参数的回调函数机器码
Const patchHex = "8B 44 24 04 8B 4C 24 08 8B 54 24 0C 8B 74 24 10 8B 7C 24 14 57 56 52 51 FF D0 C2 14 00"

Private Sub Command1_Click()
Dim Addptr As Long
Dim Mulptr As Long

Dim obj As New ClsInjectCode
'/////注入回调函数代码  ////
obj.InjectCode AddressOf Callback, patchHex
'///// 取范例函数指针                       /////
'///// 遗憾的是vb只能硬编码取得函数入口指针  ////
Addptr = GetAddr(AddressOf FAdd)
Mulptr = GetAddr(AddressOf FMul)
'///// 回调测试  ////////
Callback Addptr, 1, 2, 3, 4  '加法
Callback Mulptr, 1, 2, 3, 4  '乘法
Callback Addptr, 1, 2, 3, 4  '加法
Callback Mulptr, 1, 2, 3, 4  '乘法
Set obj = Nothing

End Sub

公共模块代码
Option Explicit
'//////////////////////////////////////////////////////////////
'//// callback 函数是个虚函数,代码无意义只为分配内存空间  ////
'//// 参数布局 模仿 callwindowproc 的参数格式              ////
'//////////////////////////////////////////////////////////////
Public Function Callback(ByVal addr As Long, ByVal a As Long, ByVal b As Long, _
                         ByVal c As Long, ByVal d As Long) As Long
Dim r As Long
r = a + b + c + d
r = a + b + c + d
r = a + b + c + d
Callback = r
End Function
'/// 测试范例: 加法 /////
Public Function FAdd(ByVal a As Long, ByVal b As Long, _
                         ByVal c As Long, ByVal d As Long) As Long
Dim r As Long
r = a + b + c + d
MsgBox "加法:" & a & " + " & b & " + " & c & " + " & d & " = " & r
FAdd = r
End Function

'/// 测试范例: 乘法 /////
Public Function FMul(ByVal a As Long, ByVal b As Long, _
                         ByVal c As Long, ByVal d As Long) As Long
Dim r As Long
r = a * b * c * d
MsgBox "乘法:" & a & " * " & b & " * " & c & " * " & d & " = " & r
FMul = r

End Function

'////// 返回通过 addressof 传入的函数指针   ////
Public Function GetAddr(ByVal addr As Long) As Long
GetAddr = addr

End Function



类模块ClsInjectCode代码:
Option Explicit
' 修改内存保护属性(使代码段可写)
Private Declare Function VirtualProtect Lib "kernel32" ( _
    ByVal lpAddress As Long, _
    ByVal dwSize As Long, _
    ByVal flNewProtect As Long, _
    lpflOldProtect As Long) As Long

' 拷贝内存(用于写入机器码)
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
    ByVal Destination As Long, _
    ByRef Source As Any, _
    ByVal Length As Long)

' 记录最后一次注入地址和机器码
Private mLastAddress As Long
Private mLastHexCode As String
Private Const PAGE_EXECUTE_READWRITE As Long = &H40

'//// 代码注入接口  //////
Public Sub InjectCode(ByVal addr As Long, ByVal hexStr As String)
    Dim patch() As Byte
    patch = HexStringToBytes(hexStr)
    Call ModifyFun(addr, patch)
    mLastAddress = addr
    mLastHexCode = hexStr
End Sub

'//////// 机器码字符串转成byte数组 /////
Private Function HexStringToBytes(hexStr As String) As Byte()
    Dim parts() As String
    Dim result() As Byte
    Dim i As Long

    parts = Split(Trim$(hexStr))
    ReDim result(0 To UBound(parts))

    For i = 0 To UBound(parts)
        result(i) = CByte("&H" & parts(i))
    Next

    HexStringToBytes = result
End Function

'////// 机器码注入  //////
Private Sub ModifyFun(ByVal addr As Long, patch() As Byte)
    Dim patchLength As Long
    patchLength = UBound(patch) - LBound(patch) + 1

    Dim oldProtect As Long
    Call VirtualProtect(addr, patchLength, &H40, oldProtect)
    Call CopyMemory(ByVal addr, ByVal VarPtr(patch(LBound(patch))), patchLength)
    Call VirtualProtect(addr, patchLength, oldProtect, oldProtect)
End Sub

配合IDE模式下调试的回调函数Dll库C代码,可自己编译:
编译后在VB的声明格式:
Private Declare Sub Callback Lib "Callback.dll" Alias "_Callback@20" _
      (ByVal addr As Long, ByVal a As Long, ByVal b As Long, ByVal c As Long, ByVal d As Long)


#include <windows.h>

// 定义回调函数类型
typedef void (__stdcall *CallbackFunc)(int,int,int,int);

// 设置回调并立即执行
__declspec(dllexport) void __stdcall Callback(CallbackFunc cb, int a, int b,int c,int  d) {
    if (cb) {
        cb(a, b, c, d);  // 立即回调,传入调用者参数
    }
}
回复

使用道具 举报

 楼主| 发表于 昨天 19:01 | 显示全部楼层
这是编译好的Callback.dll回调函数库

callback.rar

7.24 KB, 下载次数: 1

回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2025-9-24 03:01 , Processed in 0.047073 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表