金猪脚本(原飞猪脚本)以按键精灵教学为主,涉及UiBot,Python,Lua等脚本编程语言,教学包括全自动办公脚本,游戏辅助脚本,引流脚本,网页脚本,安卓脚本,IOS脚本,注册脚本,点赞脚本,阅读脚本以及网赚脚本等各个领域。想制作脚本和学习按键精灵的朋友可以添加按键精灵学习交流群:554127455 学习路上不再孤单,金猪脚本伴你一同成长.
远程写入内存数据代码,读取和写入原理差不多的,按键官方都开放读取数据插件,我就不多讲内存读取了。我们直接用远程进程的写入作为例子,本程序的指针代码你们可以自己测试下。
我们思考一个问题:
按键精灵能不能直接读取变量的指针,或者直接用系统API函数操控游戏或者软件的内存?
首先我们分析vb指针函数:VarPtr、StrPtr和ObjPtr函数的用法。
在旧版VB中可以直接读取变量的指针,和操控的指针。
Declare Function VarPtr Lib "vbrun100.dll" (Var As Any) As Long
Dim a As Long, b As Long, m As Long
M = VarPtr(a) '获得a的指针
MsgBox m
结果: m=&H01744FA0
但是历史的改变,VB现在已经变样了,现在我在W764位系统下数据库也改变了、我测试过这个应该行不通的。如果有朋友在google里面能找到新版vs2010以上版本的最新答案话可以告诉我。
Never too old to learn
好吧,我们现在正是进入正题:
下面修改后内存API函数写入的代码和注释:
Declare Function OpenProcess Lib "kernel32" Alias "OpenProcess" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Declare Function write Lib "kernel32" Alias "WriteProcessMemory" ( Handle_Game As Long, lpBaseAddress As long,date As long, nSize As Long, lpNumberOfBytesWritten As Long) As Long
Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Long) As Long
hwnd = Plugin.Window.find(0, "
lants vs. Zombies 1.2.0.1073 RELEASE")[/code]
- If hwnd <=0 Then
- MessageBox ("先开始植物大战僵尸")
- EndScript
- End If
- GameId = Plugin.SysEx.GetProcessID(hwnd) //这个代码可以用vb的方法通过获取系统进程管理对象来获取的,当然不是重点我就先不讲这里,直接用插件命令代替
- TracePrint "获取进程的ID=" & GameId//打开进程,这里我还是用系统的,我在另外一个帖子有讲如何直接通API获取进程id
- Handle_Game = OpenProcess(2035711, false, GameId)//获取进程句柄
复制代码
//打开进程的函数原型
//HANDLE OpenProcess(
//DWORD dwDesiredAccess, //渴望得到的访问权限(标志)
//BOOL bInheritHandle, // 是否继承句柄
//DWORD dwProcessId// 进程标示符
//);
// 这里如果非要解释OpenProcess访问权限是什么,告诉你们这是一个宏,理解为常量值,就是2035711 不理解就简单理解为:表示有访问读写权限
- TracePrint "Handle_Game=" & Handle_Game//要写入的地址
- Addr_Game = &H0C32DA08 //要写入的数值
- indate = 65236000 //用这个测试的时候,我们检测下2字节的最大值和4字节的最大值,注意数据溢出
- /*由于写入内存又要传址,所以不能直接以Long型写入,
- 将要写入的数值分割成低字和高字,以Unicode码形式分别存放在两个变量里,
- 一个Uniclde字符能放两字节,两个才是4字节*/
- Addr_Low = chrw(indate mod 65536)
- Addr_High = chrw(int(indate / 65536))
- //读取写入地址原来的值
- var_Check = Plugin.Memory.Read32Bit(hwnd, &H100579C)
- TracePrint "旧值=" & var_Check//低字和高字分两次写入
- Call write(Handle_Game, Addr_Game, Addr_Low, 2, 0)
- Call write(Handle_Game, Addr_Game + 2, Addr_High, 2, 0)//读取写入地址现在的值
- var_Check = Plugin.Memory.Read32Bit(hwnd,Addr_Game) // 这句代码没用的,只是用来检测是否有效的
- TracePrint "现值=" & var_Check
- //关闭进程对象句柄
- //call CloseHandle (Handle_Game)
复制代码
上面的直接用内存API函数读取4字节的整数,2字节的整数就是去掉高低位代码就可以了。
问:如果要写入一个字节应该怎么办呢?
- 答:其实原理一样的,我们可以直接用vb里面的Chr类型ASCII来进行读取,chr类型就只占一个字节。具体可以直接查看vbs命令If hwnd <=0 Then
- MessageBox ("先开始植物大战僵尸")
- EndScript
- End If
- GameId = Plugin.SysEx.GetProcessID(hwnd)
- Addr_Game = &H0C32DA08//要写入的数值
- Addr_Byte=Chr(1)
- Call write(Handle_Game, Addr_Game, Chr(1), 1, 0) //这里Chr(1)1个字节的整数就是1,1个字节最大值为255
复制代码
好的,现在能写入一个字节(八位二进制),十六位FF(10进制最大值255),是不是可以写个类似易语言里面 字节集相关的内容,按键里面也可以自己增加相关的命令库了。字节读写搞定的话后面很多东西基本全部能轻松搞定的了。
机器码例子:FF 15 64 4B E8 02 A4 84 D4 40 00 02 05 D0
机器码例子:64 A10 00 00 00 05 06 48 92 50 00 08 1EC 54 01 00 00 56 57 89 8D C0 FE FF FF
我举个例子吧:
- Call Lib.类人猿内存库.WriteInteger(Handle_Game, Addr_Game, Chr(1), 1, 0)
- Call Lib.类人猿内存库.SearchByte(Handle_Game, Addr_Game, Module_Name,"FF 15 64 4B E8 02 A4 84 D4 40 00 02 05 D0 ", 14)
复制代码
…………………………………………
当然上面的只是冰山一角,朋友们可以测试下一下其他数据类型行不行,比如Cstr等类型的函数,说不定会有新的收获。其实最终目的我们还要想办法存改成汇编代码。
到这里你可以用用你的小聪明了。比如:用你聪明的小脑袋和厉害算法搞内存特征码定位,搞内存防止游戏更新的辅助,又或者杀毒找特征那种功能了,其实用处还很多。呵呵!
其实也不复杂。
好了,我们继续查下申请内存空间的几个函数的使用LocalAlloc,VirtualAlloc,GlobalAlloc能不能实现申请指针,辅助里面就叫内存地址吧,这个使用还是很多的。
- 下面我以LocalAlloc 作为例子:Declare Function LocalAlloc Lib "kernel32" Alias "LocalAlloc" (ByVal wOemChar As Long,ByVal wOmChar As Long) As Long
- Declare Function LocalFree Lib "kernel32" Alias "LocalFree" (ByVal hMem As Long) As Long
- Alloc_Addr = LocalAlloc(0, 4) //申请获取指针
- TracePrint Hex(Alloc_Addr)
- LocalFree RAlloc_Addr//释放申请的空间
复制代码
今天就跟大家分享到这里,上面的代码照抄即可。很多东西其实可以直接用C++或者VB移植到按键精灵。好了,打字很累,有需要加下我共同学习下。
本文暂时没有评论,来添加一个吧(●'◡'●)