Visual Basic内嵌汇编语言解决方案

   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,并非真正的窗口过程地址,而是自己的汇编码地址。

    具体一点,比如,我们要嵌入一段什么也不干的汇编代码:

Dim AsmCode() as byte
redim AsmCode(8)
'生成机器代码
AsmCode(0) = &H58 'POP EAX
AsmCode(1) = &H59 'POP ECX
AsmCode(2) = &H59 'POP ECX
AsmCode(3) = &H59 'POP ECX
AsmCode(4) = &H59 'POP ECX
AsmCode(5) = &H50 'PUSH EAX
'你可以在这里添加你想执行的Asm代码...
'.....如果添加的话,后面的数组偏移需要做相应改动
'你添加的代码在这里结束
'将控制权交还主程序
AsmCode(6) = &HC3 'RET
'.....

    然后:

CallDllFunction = CallWindowProc(VarPtr(AsmCode(0), 0, 0, 0, 0)

    VarPtr函数,用于取变量地址。返回一个long 型值。

    为什么前面要执行几个pop和一个push呢?因为我们是以一段汇编代码首地址,伪装成一个窗口过程的,系统调用CallWindowProc时,实际上除lpPrevWndFunc,我们还传入了4个参数,就是上面的的4个0,而CallWindoProc函数在调用lpPrevWndFunc这段汇编代码程序时,把其余4个参数是压入了堆栈的。相当于执行了以下代码:

xxxx00A4H: push 0
xxxx00A6H: push 0
xxxx00A8H: push 0
xxxx00AAH: push 0
xxxx00ACH: call VarPtr(AsmCode(0))(这段代码我们是看不见的,是CallWindoProc在内部做的处理)
xxxx00AFH: ......

    因为我们根本没有用到这4个参数,所以我们只需要将它弹出。所以,我们执行了4个POP ECX,就是把这4个不用的参数弹出,以保持堆栈指针的正确性。但为什么还要,第一句的:POP EAX,还是因为CallWindowProc把lpPrevWndFunc当成一个窗口过程的原故,因为作为一个正常的窗口过程,在执行Call语句的时候,得把Call语句的下一条指令地址push到堆栈中,用于子程序ret.在上面这段代码就是执行了:push xxxx00afh.事实上,在CallWindowProc中,实际上隐含执行这么几句,我们必须关心的代码:

push 0;参数入栈
push 0
push 0
push 0
push xxxx00afh;(当执行call 时,自动执行)

    为了能让窗口过程执行结束后堆栈指针保持平衡,当然要执行相应的pop指令,第一个pop eax是把子程序返回的地址暂时保存在寄存器eax中,然后弹出4个不用的参数。

    接着把保存在eax中返回地址,压回堆栈。当执行ret时,就能正确返回到CallWindowProc中了。

   Option   Explicit
  
'
   ' This   shows   how   to   incorporate   machine   code   into   VB
   ' ''''''''''''''''''''''''''''''''''''''''''''''''''
   ' The   example   fills   the   array   with   a   few   machine   instructions   and   then   copies
   ' them   to   a   procedure   address.   The   modified   procedure   is   then   called   thru
   ' CallWindowProc.   The   result   of   this   specific   machine   code   is   your   CPU   Vendor   Name.
   '
   ' ##########################################################################
   ' Apparently   it   gets   a   Stack   Pointer   Error,   but   I   don't   know   why;   if   anybody
   ' can   fix   that   please   let   me   know                                                     UMGEDV@AOL.COM
   ' The   Error   is   not   present   in   the   native   compiled   version;   so   I   think   it   got
   ' something   to   do   with   the   P-Code   Calling   Convention   (strange   though)
   ' ##########################################################################
   '
   ' Sub   Dummy   serves   to   reserve   some   space   to   copy   the   machine   instructions   into.
   '
   '
   ' Tested   on   Intel   and   AMD   CPU's   (uncompiled   and   compiled)
   '
   '
   Private  Declare  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
  
Private  Declare  Sub  CopyMemory Lib  " kernel32 "  Alias  " RtlMoveMemory "  (lpvDest  As  Any, lpvSource  As  Any, ByVal cbCopy  As   Long )
  
Private  x      As   Long
    
  
Public   Function  GetCpuName()  As   String
        
      
Dim  MachineCode( 0   To   35 )            As   Byte
      
Dim  VarAddr                                  As   Long
      
Dim  FunctAddr                              As   Long
      
Dim  EAX                                          As   Long
      
Dim  CPUName( 1   To   12 )                    As   Byte
        
      
' set   up   machine   code
            
          MachineCode(
0 =   & H55              ' push   ebp
            
          MachineCode(
1 =   & H8B              ' move   ebp,esp
          MachineCode( 2 =   & HEC
            
          MachineCode(
3 =   & H57              ' push   edi
            
          MachineCode(
4 =   & H52              ' push   edx
            
          MachineCode(
5 =   & H51              ' push   ecx
            
          MachineCode(
6 =   & H53              ' push   ebx
            
          MachineCode(
7 =   & H8B              ' move   eax,dword   ptr   [ebp+8]
          MachineCode( 8 =   & H45
          MachineCode(
9 =   & H8
            
          MachineCode(
10 =   & HF              ' cpuid
          MachineCode( 11 =   & HA2
            
          MachineCode(
12 =   & H8B            ' mov   edi,dword   ptr   [ebp+12]
          MachineCode( 13 =   & H7D
          MachineCode(
14 =   & HC
            
          MachineCode(
15 =   & H89            ' move   dword   ptr   [edi],ebx
          MachineCode( 16 =   & H1F
            
          MachineCode(
17 =   & H8B            ' mov   edi,dword   ptr   [ebp+16]
          MachineCode( 18 =   & H7D
          MachineCode(
19 =   & H10
            
          MachineCode(
20 =   & H89            ' move   dword   ptr   [edi],ecx
          MachineCode( 21 =   & HF
            
          MachineCode(
22 =   & H8B            ' mov   edi,dword   ptr   [ebp+20]
          MachineCode( 23 =   & H7D
          MachineCode(
24 =   & H14
            
          MachineCode(
25 =   & H89            ' move   dword   ptr   [edi],edx
          MachineCode( 26 =   & H17
            
          MachineCode(
27 =   & H58            ' pop   ebx
    
          MachineCode(
28 =   & H59            ' pop   ecx
    
          MachineCode(
29 =   & H5A            ' pop   edx
    
          MachineCode(
30 =   & H55            ' pop   edi
            
          MachineCode(
31 =   & HC9            ' leave
    
          MachineCode(
32 =   & HC2            ' ret   16           I   tried   everything   from   0   to   24
          MachineCode( 33 =   & H10            '                        but   all   produce   the   stack   error
          MachineCode( 34 =   & H0
            
          
' tell   cpuid   what   we   want
          EAX  =   0
            
          
' get   address   of   Machine   Code
          VarAddr  =  VarPtr(MachineCode( 0 ))
            
          
' get   address   of   Sub   Dummy
          FunctAddr  =  GetAddress(AddressOf Dummy)
            
          
' copy   the   Machine   Code   to   where   it   can   be   called
          CopyMemory ByVal FunctAddr, ByVal VarAddr,  35               ' 35   bytes   machine   code
            
          
' call   it
           On   Error   Resume   Next           ' apparently   it   gets   a   stack   pointer   error   when   in   P-Code   but   i   dont   know   why
              CallWindowProc FunctAddr, EAX, VarPtr(CPUName( 1 )), VarPtr(CPUName( 9 )), VarPtr(CPUName( 5 ))
              
' Debug.Print   Err;   Err.Description
               ' MsgBox   Err   &   Err.Description
           On   Error   GoTo   0
            
          GetCpuName 
=  StrConv(CPUName(), vbUnicode)          ' UnicodeName
            
  
End Function
    
  
Private   Function  GetAddress(Address  As   Long As   Long
    
          GetAddress 
=  Address
    
  
End Function
    
  
Private   Sub  Dummy()
    
      
' the   code   below   just   reserves   some   space   to   copy   the   machine   code   into
       ' it   is   never   executed
    
          x 
=   0
          x 
=   1
          x 
=   2
          x 
=   3
          x 
=   4
          x 
=   5
          x 
=   6
          x 
=   7
          x 
=   8
          x 
=   9
          x 
=   10
          x 
=   0
          x 
=   1
          x 
=   2
          x 
=   3
          x 
=   4
          x 
=   5
          x 
=   6
          x 
=   7
          x 
=   8
          x 
=   9
          x 
=   10
          
  
End Sub

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值