在VB中使用嵌入asm和API指针 Form1.frmVERSION 5.00 Begin VB.Form Form1 Caption = "Form1" ClientHeight = 3195 ClientLeft = 60 ClientTop = 345 ClientWidth = 4680 LinkTopic = "Form1" ScaleHeight = 3195 ScaleWidth = 4680 StartUpPosition = 3 'Windows Default Begin VB.CommandButton Command1 Caption = "Command1" Height = 495 Left = 1740 TabIndex = 0 Top = 1350 Width = 1215 End End Attribute VB_Name = "Form1" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False '主 题:在VB中使用嵌入asm和API指针,去它的DECLARE吧!绝对的好消息。高手请进。 '作 者: thriller '所属论坛: Visual Basic '问题点数:0 '回复次数:0 '发表时间:2001-2-1 22:42:00 ' '看看下面的代码。 '在VB中使用嵌入asm和API指针,去它的DECLARE吧! '在DELPHI和VC中可以做到的,VB一样可以了。虽然稍微麻烦,但的确有效。 '还有什么是VB不能做的?! '好东西不敢独享,大家LOOK:'form Private Declare Function GetDC& Lib "user32" (ByVal hwnd As Long) Private Declare Function ReleaseDC& Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long)Private Sub Command1_Click() Dim a As Long, b As Long Dim s() As Byte, x As Long, y As Long s = StrConv("Hello !", vbFromUnicode) b = 15 x = CallApiByName("user32", "SetWindowTextA", hwnd, VarPtr(s(0))) Debug.Print "x= ", x x = CallApiByName("kernel32", "RtlMoveMemory", VarPtr(a), VarPtr(b), 4&) Debug.Print "a= ", a x = CallApiByName("user32", "FlashWindow", hwnd, 1&) Debug.Print "x= ", x dc1 = GetDC(hwnd) x = CallApiByName("user32", "GetDC", hwnd) Debug.Print "x= ", x, "dc= ", dc1 x = ReleaseDC(hwnd, dc1) End Sub Module1.bas Attribute VB_Name = "Module1" 'basOption Explicit '*********************************************** '* This module use excelent solution from '* http://www.vbdotcom.com/FreeCode.htm '* how to implement assembly calls directly '* into VB code. '*********************************************** Private Declare Function LoadLibrary Lib "Kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long Private Declare Function GetProcAddress Lib "Kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long 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 Function FreeLibrary Lib "Kernel32" (ByVal hLibModule As Long) As Long Private Declare Sub CopyMemory Lib "Kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long) Private mlngParameters() As Long 'list of parameters Private mlngAddress As Long 'address of function to call Private mbytCode() As Byte 'buffer for assembly code Private mlngCP As Long 'used to keep track of latest byte added to codePublic Function CallApiByName(libName As String, funcName As String, ParamArray FuncParams()) As Long Dim lb As Long, i As Integer ReDim mlngParameters(0) ReDim mbytCode(0) mlngAddress = 0 lb = LoadLibrary(ByVal libName) If lb = 0 Then MsgBox "DLL not found", vbCritical Exit Function End If mlngAddress = GetProcAddress(lb, ByVal funcName) If mlngAddress = 0 Then MsgBox "Function entry not found", vbCritical FreeLibrary lb Exit Function End If ReDim mlngParameters(UBound(FuncParams) + 1) For i = 1 To UBound(mlngParameters) mlngParameters(i) = CLng(FuncParams(i - 1)) Next i CallApiByName = CallWindowProc(PrepareCode, 0, 0, 0, 0) FreeLibrary lb End FunctionPrivate Function PrepareCode() As Long Dim lngX As Long, codeStart As Long ReDim mbytCode(18 + 32 + 6 * UBound(mlngParameters)) codeStart = GetAlignedCodeStart(VarPtr(mbytCode(0))) mlngCP = codeStart - VarPtr(mbytCode(0)) For lngX = 0 To mlngCP - 1 mbytCode(lngX) = &HCC Next AddByteToCode &H58 'pop eax AddByteToCode &H59 'pop ecx AddByteToCode &H59 'pop ecx AddByteToCode &H59 'pop ecx AddByteToCode &H59 'pop ecx AddByteToCode &H50 'push eax For lngX = UBound(mlngParameters) To 1 Step -1 AddByteToCode &H68 'push wwxxyyzz AddLongToCode mlngParameters(lngX) Next AddCallToCode mlngAddress AddByteToCode &HC3 AddByteToCode &HCC PrepareCode = codeStart End FunctionPrivate Sub AddCallToCode(lngAddress As Long) AddByteToCode &HE8 AddLongToCode lngAddress - VarPtr(mbytCode(mlngCP)) - 4 End SubPrivate Sub AddLongToCode(lng As Long) Dim intX As Integer Dim byt(3) As Byte CopyMemory byt(0), lng, 4 For intX = 0 To 3 AddByteToCode byt(intX) Next End SubPrivate Sub AddByteToCode(byt As Byte) mbytCode(mlngCP) = byt mlngCP = mlngCP + 1 End SubPrivate Function GetAlignedCodeStart(lngAddress As Long) As Long GetAlignedCodeStart = lngAddress + (15 - (lngAddress - 1) Mod 16) If (15 - (lngAddress - 1) Mod 16) = 0 Then GetAlignedCodeStart = GetAlignedCodeStart + 16 End Function
用delphi写一个吧,那样方便多了
可以.比如下面这个程序,可以判断你的CPU的类型: Attribute VB_Name = "Module1" 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... [email protected] '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 LongPublic Function GetCpuName() As StringDim 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 codeMachineCode(0) = &H55 'push ebpMachineCode(1) = &H8B 'move ebp,esp MachineCode(2) = &HECMachineCode(3) = &H57 'push ediMachineCode(4) = &H52 'push edxMachineCode(5) = &H51 'push ecxMachineCode(6) = &H53 'push ebxMachineCode(7) = &H8B 'move eax,dword ptr [ebp+8] MachineCode(8) = &H45 MachineCode(9) = &H8MachineCode(10) = &HF 'cpuid MachineCode(11) = &HA2MachineCode(12) = &H8B 'mov edi,dword ptr [ebp+12] MachineCode(13) = &H7D MachineCode(14) = &HCMachineCode(15) = &H89 'move dword ptr [edi],ebx MachineCode(16) = &H1FMachineCode(17) = &H8B 'mov edi,dword ptr [ebp+16] MachineCode(18) = &H7D MachineCode(19) = &H10MachineCode(20) = &H89 'move dword ptr [edi],ecx MachineCode(21) = &HFMachineCode(22) = &H8B 'mov edi,dword ptr [ebp+20] MachineCode(23) = &H7D MachineCode(24) = &H14MachineCode(25) = &H89 'move dword ptr [edi],edx MachineCode(26) = &H17MachineCode(27) = &H58 'pop ebxMachineCode(28) = &H59 'pop ecxMachineCode(29) = &H5A 'pop edxMachineCode(30) = &H55 'pop ediMachineCode(31) = &HC9 'leaveMachineCode(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 0GetCpuName = StrConv(CPUName(), vbUnicode) 'UnicodeNameEnd FunctionPrivate Function GetAddress(Address As Long) As LongGetAddress = AddressEnd FunctionPrivate Sub Dummy()'the code below just reserves some space to copy the machine code into 'it is never executedx = 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 = 10End Sub
http://www.csdn.net/expert/topic/460/460269.xml?temp=.3568079
http://www.china-askpro.com/msg46/qa49.shtml
http://www.china-askpro.com/msg27/qa86.shtml一个例程:
http://www.dapha.net/soure/stan/ASM+VB%20=%20VB%20Hardcore.%20REALTIME%20Picture%20Fade.zip
Form1.frmVERSION 5.00
Begin VB.Form Form1
Caption = "Form1"
ClientHeight = 3195
ClientLeft = 60
ClientTop = 345
ClientWidth = 4680
LinkTopic = "Form1"
ScaleHeight = 3195
ScaleWidth = 4680
StartUpPosition = 3 'Windows Default
Begin VB.CommandButton Command1
Caption = "Command1"
Height = 495
Left = 1740
TabIndex = 0
Top = 1350
Width = 1215
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
'主 题:在VB中使用嵌入asm和API指针,去它的DECLARE吧!绝对的好消息。高手请进。
'作 者: thriller
'所属论坛: Visual Basic
'问题点数:0
'回复次数:0
'发表时间:2001-2-1 22:42:00
'
'看看下面的代码。
'在VB中使用嵌入asm和API指针,去它的DECLARE吧!
'在DELPHI和VC中可以做到的,VB一样可以了。虽然稍微麻烦,但的确有效。
'还有什么是VB不能做的?!
'好东西不敢独享,大家LOOK:'form
Private Declare Function GetDC& Lib "user32" (ByVal hwnd As Long)
Private Declare Function ReleaseDC& Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long)Private Sub Command1_Click()
Dim a As Long, b As Long
Dim s() As Byte, x As Long, y As Long
s = StrConv("Hello !", vbFromUnicode)
b = 15
x = CallApiByName("user32", "SetWindowTextA", hwnd, VarPtr(s(0)))
Debug.Print "x= ", x
x = CallApiByName("kernel32", "RtlMoveMemory", VarPtr(a), VarPtr(b), 4&)
Debug.Print "a= ", a
x = CallApiByName("user32", "FlashWindow", hwnd, 1&)
Debug.Print "x= ", x
dc1 = GetDC(hwnd)
x = CallApiByName("user32", "GetDC", hwnd)
Debug.Print "x= ", x, "dc= ", dc1
x = ReleaseDC(hwnd, dc1)
End Sub
Module1.bas
Attribute VB_Name = "Module1"
'basOption Explicit
'***********************************************
'* This module use excelent solution from
'* http://www.vbdotcom.com/FreeCode.htm
'* how to implement assembly calls directly
'* into VB code.
'***********************************************
Private Declare Function LoadLibrary Lib "Kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function GetProcAddress Lib "Kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
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 Function FreeLibrary Lib "Kernel32" (ByVal hLibModule As Long) As Long
Private Declare Sub CopyMemory Lib "Kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)
Private mlngParameters() As Long 'list of parameters
Private mlngAddress As Long 'address of function to call
Private mbytCode() As Byte 'buffer for assembly code
Private mlngCP As Long 'used to keep track of latest byte added to codePublic Function CallApiByName(libName As String, funcName As String, ParamArray FuncParams()) As Long
Dim lb As Long, i As Integer
ReDim mlngParameters(0)
ReDim mbytCode(0)
mlngAddress = 0
lb = LoadLibrary(ByVal libName)
If lb = 0 Then
MsgBox "DLL not found", vbCritical
Exit Function
End If
mlngAddress = GetProcAddress(lb, ByVal funcName)
If mlngAddress = 0 Then
MsgBox "Function entry not found", vbCritical
FreeLibrary lb
Exit Function
End If
ReDim mlngParameters(UBound(FuncParams) + 1)
For i = 1 To UBound(mlngParameters)
mlngParameters(i) = CLng(FuncParams(i - 1))
Next i
CallApiByName = CallWindowProc(PrepareCode, 0, 0, 0, 0)
FreeLibrary lb
End FunctionPrivate Function PrepareCode() As Long
Dim lngX As Long, codeStart As Long
ReDim mbytCode(18 + 32 + 6 * UBound(mlngParameters))
codeStart = GetAlignedCodeStart(VarPtr(mbytCode(0)))
mlngCP = codeStart - VarPtr(mbytCode(0))
For lngX = 0 To mlngCP - 1
mbytCode(lngX) = &HCC
Next
AddByteToCode &H58 'pop eax
AddByteToCode &H59 'pop ecx
AddByteToCode &H59 'pop ecx
AddByteToCode &H59 'pop ecx
AddByteToCode &H59 'pop ecx
AddByteToCode &H50 'push eax
For lngX = UBound(mlngParameters) To 1 Step -1
AddByteToCode &H68 'push wwxxyyzz
AddLongToCode mlngParameters(lngX)
Next
AddCallToCode mlngAddress
AddByteToCode &HC3
AddByteToCode &HCC
PrepareCode = codeStart
End FunctionPrivate Sub AddCallToCode(lngAddress As Long)
AddByteToCode &HE8
AddLongToCode lngAddress - VarPtr(mbytCode(mlngCP)) - 4
End SubPrivate Sub AddLongToCode(lng As Long)
Dim intX As Integer
Dim byt(3) As Byte
CopyMemory byt(0), lng, 4
For intX = 0 To 3
AddByteToCode byt(intX)
Next
End SubPrivate Sub AddByteToCode(byt As Byte)
mbytCode(mlngCP) = byt
mlngCP = mlngCP + 1
End SubPrivate Function GetAlignedCodeStart(lngAddress As Long) As Long
GetAlignedCodeStart = lngAddress + (15 - (lngAddress - 1) Mod 16)
If (15 - (lngAddress - 1) Mod 16) = 0 Then GetAlignedCodeStart = GetAlignedCodeStart + 16
End Function
Attribute VB_Name = "Module1"
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... [email protected]
'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 LongPublic Function GetCpuName() As StringDim 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 codeMachineCode(0) = &H55 'push ebpMachineCode(1) = &H8B 'move ebp,esp
MachineCode(2) = &HECMachineCode(3) = &H57 'push ediMachineCode(4) = &H52 'push edxMachineCode(5) = &H51 'push ecxMachineCode(6) = &H53 'push ebxMachineCode(7) = &H8B 'move eax,dword ptr [ebp+8]
MachineCode(8) = &H45
MachineCode(9) = &H8MachineCode(10) = &HF 'cpuid
MachineCode(11) = &HA2MachineCode(12) = &H8B 'mov edi,dword ptr [ebp+12]
MachineCode(13) = &H7D
MachineCode(14) = &HCMachineCode(15) = &H89 'move dword ptr [edi],ebx
MachineCode(16) = &H1FMachineCode(17) = &H8B 'mov edi,dword ptr [ebp+16]
MachineCode(18) = &H7D
MachineCode(19) = &H10MachineCode(20) = &H89 'move dword ptr [edi],ecx
MachineCode(21) = &HFMachineCode(22) = &H8B 'mov edi,dword ptr [ebp+20]
MachineCode(23) = &H7D
MachineCode(24) = &H14MachineCode(25) = &H89 'move dword ptr [edi],edx
MachineCode(26) = &H17MachineCode(27) = &H58 'pop ebxMachineCode(28) = &H59 'pop ecxMachineCode(29) = &H5A 'pop edxMachineCode(30) = &H55 'pop ediMachineCode(31) = &HC9 'leaveMachineCode(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 0GetCpuName = StrConv(CPUName(), vbUnicode) 'UnicodeNameEnd FunctionPrivate Function GetAddress(Address As Long) As LongGetAddress = AddressEnd FunctionPrivate Sub Dummy()'the code below just reserves some space to copy the machine code into
'it is never executedx = 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 = 10End Sub