分享vb内嵌汇编学习心得
经过一段时间的学习,总算把vb的函数调用,以及类方法的压栈方式弄懂了。
虽然vb可以通过类型库定义接口方法,更方便,但是直接用vb的类的方式,调用函数指针也是可以的。网上有很多方法是通过callwindowproc那个回调函来实现vb使用函数指针。不过我实现了用vb嵌汇编来实现调用函数指针。
'IVBoost类模块
Public Function UAdd(ByVal x As Long, ByVal y As Long) As Long
'0
End Function
Public Function UDif(ByVal x As Long, ByVal y As Long) As Long
'1
End Function
Public Function CallLongReturnLong(ByVal pFn As Long, ByVal x As Long) As Long
'2 还可以加入更多的调用方式
End Function
‘--------------------------
'VBoostImp.cls
Private mVBoost As IVBoost
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
ByRef Destination As Any, _
ByRef Source As Any, _
ByVal Length As Long)
Private ASM(300) As Long
Dim pTVable As Long
Private Sub Class_Initialize()
Set mVBoost = New IVBoost
Dim pObj As Long
pObj = ObjPtr(mVBoost)
CopyMemory pTVable, ByVal pObj, 4
'-------------------
'UAdd
ASM(0) = &H824448B
ASM(1) = &HC244403
ASM(2) = &H10245C8B
ASM(3) = &HC0330389
ASM(4) = &H900010C2
SetVTable VarPtr(ASM(0)), 0
' mov eax, [esp+8]
' Add eax, [esp+12]
' mov ebx, [esp+16]
' mov [ebx], eax
' xor eax,eax
' ret 16
'------------------------
' UDif
ASM(5) = &H824448B
ASM(6) = &HC24442B
ASM(7) = &H10245C8B
ASM(8) = &HC0330389
ASM(9) = &H900010C2
SetVTable VarPtr(ASM(5)), 1
' mov eax, [esp+8]
' sub eax,[esp+12]
' mov ebx, [esp+16]
' mov [ebx], eax
' xor eax,eax
' ret 16
'-----------------------------
'
' CallLongReturnLong
ASM(10) = &H824448B
ASM(11) = &HC2474FF
ASM(12) = &H5C8BD0FF
ASM(13) = &H3891024
ASM(14) = &H10C2C033
ASM(15) = &H90909000
SetVTable VarPtr(ASM(10)), 2
' mov eax,[esp+8] ; 把调用地址先保存到eax
' push [esp+12] ; 再压入参数 x
' Call eax
' mov ebx, [esp+16]
' mov [ebx], eax ; 返回值
' xor eax,eax
' ret 16
'--------------------------
End Sub
Public Property Get VBoost() As IVBoost
Set VBoost = mVBoost
End Property
Private Sub SetVTable(ByVal fn As Long, ByVal iOrder As Long)
CopyMemory ByVal (pTVable + (7 + iOrder) * 4), fn, 4
End Sub
Private Function pFn(ByVal x As Long) As Long
pFn = x
End Function
'---------------------------
'使用
Dim VBoost As IVBoost
Dim VBoostImp As VBoostImp
Sub Main()
Set VBoostImp = New VBoostImp
Set VBoost = VBoostImp.VBoost
With VBoost
MsgBox .UAdd(3, 5)
MsgBox .UDif(5, 3)
MsgBox .CallLongReturnLong(AddressOf Test, 5)
End With
End Sub
Private Function Test(ByVal x As Long) As Long
MsgBox "ss"
Test = x * 3
End Function
[解决办法]
该年没搞明白。
这个不叫“嵌入汇编”,叫 Thunk,没有对应的中文,中文描述为:往内存里面写入机器码数据,并且将数据当成指令运行的技术。
嵌入汇编是指,在高级语言里嵌入汇编助记符,由汇编程序在编译阶段翻译成机器码,并由链接器或者高级语言的编译器的代码生成器融合到目标文件的过程。
------解决方案--------------------
支持楼主研究:)
同意2楼,中文不妨称呼为内嵌机器码吧。
建议把这个帖里说的“内存块设置可执行的代码”加进去
http://topic.csdn.net/u/20100331/16/d42631a8-e14e-41bd-be3e-2b0ca9b12ae4.html
【200分】征给内嵌机器指令的内存块设置可执行的代码