标题: VB6拾遗:内联汇编与CallWindowProc函数
作者: Demon
链接: https://demon.tw/programming/vb6-repick-inline-assembly-callwindowproc.html
版权: 本博客的所有文章,都遵守“署名-非商业性使用-相同方式共享 2.5 中国大陆”协议条款。
网上大部分VB内联汇编都是用CallWindowProc函数实现的。
不久前lcx还发过一篇《利用vbs优雅的执行shellcode》,引得无数人转载,里面用的也是CallWindowProc函数。
关于VB用CallWindowProc函数实现实现内联汇编的文章很多,原理我就不多说了,简单举一个例子,仍然是移位运算:
Option Explicit Private Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcW" ( _ ByVal lpPrevWndFunc As Long, _ ByVal hwnd As Long, _ ByVal msg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long Private Type LeftShiftASM ASM(3) As Long End Type Private m_LeftShift As LeftShiftASM Public Function LeftShift(ByVal a As Long, ByVal b As Long) As Long If m_LeftShift.ASM(0) = 0 Then With m_LeftShift .ASM(0) = &H424448B .ASM(1) = &H8244C8B .ASM(2) = &H10C2E0D3 .ASM(3) = &HCCCCCC00 '8B4424 04 mov eax, dword ptr [esp+0x4] '8B4C24 08 mov ecx, dword ptr [esp+0x8] 'D3E0 shl eax, cl 'C2 1000 retn 0x10 'CC int3 'CC int3 'CC int3 End With End If LeftShift = CallWindowProc(VarPtr(m_LeftShift), a, b, 0, 0) End Function 'By Demon 'https://demon.tw Sub Main() Debug.Print Hex$(LeftShift(1, 31)) End Sub
是不是比用轻量级对象简单多了?既然用CallWindowProc函数实现内联汇编比较简单,为什么还要用轻量级对象呢?
CallWindowProc函数的优势:
CallWindowProc函数不需要类型库(.tlb文件)的支持,调用起来比较简单;而调用轻量级对象的方法必须在类型库中定义好接口,比较麻烦。
选择轻量级对象的理由:
1、更高的效率:如果你用调试器跟进CallWindowProc函数,会发现它要做许多和窗口消息相关的工作,做这些工作所需要的汇编指令比我们实际编写的汇编指令要多得多,大量的时间就这样浪费了,如果需要频繁调用该函数,效率是很低的;而使用轻量级对象就没有多余的汇编指令,直接VTable绑定跳转到我们编写的汇编代码,效率要高得多。
2、没有参数数量的限制:CallWindowProc函数最多只能传递4个参数,如果需要传递更多的参数,就必须使用数组来实现,汇编代码写起来就要复杂一些;而轻量级对象的函数(方法)原型是在IDL中定义的,没有参数数量的限制。
3、对构造函数和析构函数的支持:轻量级对象支持构造函数和析构函数,可以进行一些初始化和清理工作;而CallWindowProc函数不支持。
如果你不怕麻烦的话,使用轻量级对象几乎总是优于使用CallWindowProc函数的。
赞赏微信赞赏支付宝赞赏
随机文章:
demon果然厉害,学习了
大神,右移的运算应该怎么处理呢。。。。