• 新浪微博:
  • 微信 :
按键精灵电脑版
立即下载

软件版本:2014.06
软件大小:22.9M
更新时间:03-18

按键精灵安卓版
立即下载

软件版本:3.3.6
软件大小:62.5M
更新时间:01-16

按键精灵iOS版
立即下载

软件版本:1.3.8
软件大小:29.2M
更新时间:06-14

最新企业版UiBot
立即下载

软件版本:3.3
软件大小:282M
更新时间:08-06

快捷导航

登录 后使用快捷导航
没有帐号? 注册

登录 注册
发新话题 回复该主题

【VB源码】内嵌汇编(转) [复制链接]

1#
vb简单易用,但功能有时候受限制。VC,Delphi可以直接在程序中写汇编代码,可恼的是,VB不行。我看过网上也有关于VB嵌入汇编的,不过有些方法,过于复杂,而且也没相应 的介绍。我这里提供一种方法,也许大家以后可能有用!
基本思路:汇编代码,可以存在一个byte类型的数组中,然后,通过某种手段,把系统控制权,转交给这段汇编代码,我们的汇编代码段,就得到了执行。
但如何,让这段汇编代码,获得系统的控制权限呢?查查WIN API手册,可以知道有CallWindowProc这个函数。这个函数本是,用于调用用户自己定义的窗口过程的,其原形如下:
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 Long

它有5个参数。lpPrevWnFunc是一个long型,等于用户自己窗口过程的地址,其余3个都是窗口过程所必须的参数,详见MSDN。我们只需要关心第一个参数:lpPrevWndFunc,窗口过程地址。如果,我们把自己的汇编代码地址,传进去会怎么样?当然,CallWindowProc就把这个地址,当成窗口过程地址,然后,调用这段汇编代码了。我们的汇编代码便得到执。。
当然,也得装摸做样的吧,将其余4个参数传进去,就传4个0算了,因为这4个参数,我们更本不用,但又是CallWindowProc必须的,不要忘了,我们传进去的lpPrevWndFunc,并非真正的窗口过程地址,而是自己的汇编码地址。

具体一点,比如,我们要嵌入一段什么也不干的汇编代码:先
  1. Dim AsmCode() as byte
  2. redim AsmCode(8)
  3. ’生成机器代码
  4. AsmCode(0) = &H58 ’POP EAX
  5. AsmCode(1) = &H59 ’POP ECX
  6. AsmCode(2) = &H59 ’POP ECX
  7. AsmCode(3) = &H59 ’POP ECX
  8. AsmCode(4) = &H59 ’POP ECX
  9. AsmCode(5) = &H50 ’PUSH EAX
  10. ’你可以在这里添加你想执行的Asm代码...
  11. ’.....如果添加的话,后面的数组偏移需要做相应改动
  12. ’你添加的代码在这里结束
  13. ’将控制权交还主程序
  14. AsmCode(6) = &HC3 ’RET
  15. ’.....
  16. 然后:
  17. CallDllFunction = CallWindowProc(VarPtr(AsmCode(0), 0, 0, 0, 0)VarPtr函数,用于取变量地址。返回一个long 型值。
复制代码
为什么前面要执行几个pop和一个push呢?因为我们是以一段汇编代码首地址,伪装成一个窗口过程的,系统调用CallWindowProc时,实际上除lpPrevWndFunc,我们还传入了4个参数,就是上面的的4个0.而CallWindoProc函数在调用lpPrevWndFunc这段汇编代码程序时,把其余4个参数是压入了堆栈的。相当于执行了以下代码:
  1. xxxx00A4H: push 0
  2. xxxx00A6H: push 0
  3. xxxx00A8H: push 0
  4. xxxx00AAH: push 0
  5. xxxx00ACH: call VarPtr(AsmCode(0))(这段代码我们是看不见的,是CallWindoProc在内部做的处理)
  6. xxxx00AFH: ......
复制代码
因为我们根本没有用到这4个参数,所以我们只需要将它弹出。所以,我们执行了4个POP ECX,就是把这4个不用的参数弹出,以保持堆栈指针的正确性。但为什么还要,第一句的OP EAX,还是因为CallWindowProc把lpPrevWndFunc当成一个窗口过程的原故,因为作为一个正常的窗口过程,在执行Call语句的时候,得把Call语句的下一条指令地址push到堆栈中,用于子程序ret。在上面这段代码就是执行了:
push xxxx00afh。事实上,在CallWindowProc中,
实际上隐含执行这么几句,我们必须关心的代码:
  1. push 0;参数入栈
  2. push 0
  3. push 0
  4. push 0
  5. push xxxx00afh;(当执行call 时,自动执行)
复制代码
为了能让窗口过程执行结束后堆栈指针保持平衡,当然要执行相应的pop指令,第一个pop eax是把子程序返回的地址暂时保存在寄存器eax中,然后弹出4个不用的参数。接着把保存在eax中返回地址,压回堆栈。当执行ret时,就能正确返回到CallWindowProc中了。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fu0212/archive/2005/11/04/522425.aspx

2#

早期的帖子,也要定下。vb伪指令汇编。效率底。

发新话题 回复该主题