VB万能后台模拟按键-含构造扫描码[扫盲帖新手必看] 部分游戏(后台按键失效的原因)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VB万能后台模拟按键-含:构造扫描码[扫盲帖新手必看] 部分游戏(后台按键失效的原因)
其实也不是万能只是比 一般的后台按键要好点,新手请看完此片文章,最后有源代码打包下载的。。。
XX网友写的文章和源码,希望对于新手有一定的启发和帮助。。。。。
“相信大家对QQ系列的游戏都有所了解,防外挂技术更是了得!都有所谓的驱动保护,常规方法读写内存都无效,
因为TX的驱动过滤了很多常规的API,还有什么分析工具都不能用,对于QQ西游这款游戏来说,CE,ME,RE都不能用,
即使能获得目标进程句柄,游戏还会定时检测,一旦发现如上工具就自行了断了!
还有QQ西游实现挂机也遇到了难题呢,一般的发送窗口按键消息通通封杀,于是有人想到了硬件级的模拟按键,
使用WinIo模拟,默认的驱动被TX封杀了,只有自己写,但是也不能实现后台挂机,这样用处也不大!”
[问题一,不能获得窗口句柄]
一般寻找窗口句柄都是直接FindWindow吧,这样是不行的,QQ西游在这些函数上做了一些处理.我来给大家说个万能的方法吧,
对于GetWindowText方法游戏就管不到了,可以配合使用GetWindow来枚举所有的窗口,再判断枚举的窗口里面是否含有游戏窗口标题文字,
最后取其句柄就行了,下面我给段代码,也给还有疑问的朋友一些帮助,唷嘻!
Option Explicit
Private Declare Function GetDesktopWindow Lib "USER32" () As Long
Private Declare Function GetWindow Lib "USER32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Public Declare Function GetWindowText Lib "USER32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2
Public Function GetHandle(Title As String) As Long
Dim tmp As String
Dim hwnd As Long
Dim lngProcID As Long
Dim strTitle As String * 255 '//用来存储窗口的标题
'//取得桌面窗口
hwnd = GetDesktopWindow()
'//取得桌面窗口的第一个子窗口
hwnd = GetWindow(hwnd, GW_CHILD)
'//通过循环来枚举所有的窗口
Do While hwnd <> 0
'//取得下一个窗口的标题,并写入到列表框中
GetWindowText hwnd, strTitle, Len(strTitle)
If left$(strTitle, 1) <> vbNullChar Then
tmp = left$(strTitle, InStr(1, strTitle, vbNullChar))
If left(tmp, Len(Title)) = Title Then
GetHandle=hwnd
End If
End If
'//调用GetWindow函数,来取得下一个窗口
hwnd = GetWindow(hwnd, GW_HWNDNEXT)
Loop
End Function
直接调用GetHandle函数,然后传一个窗口标题进去就可以获得其窗口句柄了.
[问题二,不能后台模拟按键]
一般发送按键消息都是SendMessage吧,也有用PostMessage的,一般人用这两个函数都不成功,于是
就走向硬件级的模拟按键,
其实这是错误的,这样反而离目标越来越远,使用普通的PostMessage就行了,有人问了,不是过滤了么?
呵呵,让我们重新来了解下键盘按键的流程吧。我们一般按下键盘,键盘会发送自身对应的扫描码,然后传递给系统,在系统中由对应的键盘驱动来处理此消息,但是不同的设备扫描码有可能不一样,为了规范统一,于是出现了虚拟码,驱动将扫描码转换成对应的虚拟码后,
插入应用程序的消息队列中,等待应用程序处理,这样一个完整的流程就构成了,现在我们再来看看PostMessage的函数原型吧.
BOOL PostMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam );
一个参数是窗口句柄,第一个问题中,我们已经得到.第二个参数是消息的类型,一般的有按键按下消息WM_KEYDOWN和按键弹起消息WM_KEYUP.
第三个参数和第四个参数的附加的,一般普通的对一个窗口发送按键消息就是:
PostMessage wHandle, WM_KEYDOWN, KeyCode, 0 '按下某键
普通的行,但对于QQ西游来说就不行了,再看看上面的代码有什么被忽略了呢,细心的朋友发现了,缺少扫描码,也就是第四个参数.
正常的按键都会有对应的扫描码,如果没有游戏自然会认为是假的,呵呵,因此我们还要构造一个扫描码,怎么构造呢,下面我给出完整的代码:
Option Explicit
Private Declare Function PostMessage Lib "USER32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function MapVirtualKey Lib "USER32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long
Private Const WM_KEYDOWN = &H100
Private Const WM_KEYUP = &H101
Private Const WM_CHAR = &H102
'//构造扫描码
Private Function MakeKeyLparam(ByVal VirtualKey As Long, ByVal flag As Long) As Long
Dim s As String
Dim Firstbyte As String 'lparam参数的24-31位
If flag = WM_KEYDOWN Then '如果是按下键
Firstbyte = "00"
Else
Firstbyte = "C0" '如果是释放键
End If
Dim Scancode As Long
'获得键的扫描码
Scancode = MapVirtualKey(VirtualKey, 0)
Dim Secondbyte As String 'lparam参数的16-23位,即虚拟键扫描码
Secondbyte = right("00" & Hex(Scancode), 2)
s = Firstbyte & Secondbyte & "0001" '0001为lparam参数的0-15位,即发送次数和其它扩展信息
MakeKeyLparam = Val("&H" & s)
End Function
Public Function PostKey(wHandle As Long, KeyCode As Long) '//发送按键
PostMessage wHandle, WM_KEYDOWN, KeyCode, MakeKeyLparam(KeyCode, WM_KEYDOWN) '按下某键
PostMessage wHandle, WM_KEYUP, KeyCode, MakeKeyLparam(KeyCode, WM_KEYUP) '释放某键
End Function
上面就是一个完整的实现方法了,MakeKeyLparam是构造扫描码,PostKey是发送按键消息,直接调用该函数就行了!
[
问题三,不能读写游戏内存]
一般的读写内存都是先打开游戏进程,然后在使用读写内存的函数就行了,OpenProcess,ReadProcessMemory,WriteProcessMemory,这三个API都被过滤了-直接用 牛盾tp版即可.(注意先开牛盾--最后开游戏)
[问题四:如何后台模拟鼠标点击?]
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Function VB后台鼠标左键按键(游戏窗口名 As String, mX As Long, mY As Long)
Dim hwd As Long
hwd = FindWindow(vbNullString, 游戏窗口名)
PostMessage hwd, &H201, 0, (mX And &HFFFF) + (mY And &HFFFF) * &H10000 '鼠标左键按下
PostMessage hwd, &H202, 0, (mX And &HFFFF) + (mY And &HFFFF) * &H10000 '鼠标左键弹起
End Function
Function VB后台鼠标左键按键(游戏窗口名 As String, mX As Long, mY As Long)
Dim hwd As Long
hwd = FindWindow(vbNullString, 游戏窗口名)
PostMessage hwd, &H204, 0, (mX And &HFFFF) + (mY And &HFFFF) * &H10000 '鼠标右键按下
PostMessage hwd, &H205, 0, (mX And &HFFFF) + (mY And &HFFFF) * &H10000 '鼠标右键弹起
End Function
复制代码以上为模块里面的代码
Form窗体里面的 代码为
Private Sub Command1_Click() '鼠标左键按键
Dim x As Long, y As Long
x = Text1.Text
y = Text2.Text
VB后台鼠标左键按键 "填写游戏窗口名", x, y
End Sub
Private Sub Command2_Click() '鼠标右键键按键
Dim x As Long, y As Long
x = Text1.Text
y = Text2.Text
VB后台鼠标右键键按键 "填写游戏窗口名", x, y
End Sub
复制代码[本文总结]
透过本文,你会发现,其实有很多我们都会用,而且也没用到什么高深的技术,只是有些东西没有灵活运用吧,也容易被疏忽,
我就曾因为不能模拟按键找了好多资料,最后还是无功而返,仔细回想,原来方法就在身边.用上面的方法很容易就实现了一个后台模拟按键了.
现在想想,什么自动+血,自动打怪,支持多开...就很容易实现了,这个我也不贴代码了。