游戏数据的捕捉(郁金香学习笔记)
来源:互联网 发布:郭靖黄蓉爱情知乎 编辑:程序博客网 时间:2024/04/30 15:02
目录:
1.得到角色对象属性
2.得到吃药的CALL
3.得到快捷键CALL
4.得到选中怪物的ID地址
5.得到怪物列表
6.得到怪物属性
7.得到显示血条CALL
8.得到普通攻击CALL
9.得到捡物品CALL
10.得到背包列表地址
11.得到喊话CALL
12.坐标相关信息
13.得到综合内存信息
14.得到买卖物品CALL
15.关于OD调试多线程的问题
16.游戏多开实现
17.辅助编程注意事项
最近学习郁金香视频 写下学习笔记以便以后查询.
1.得到角色对象属性
角色属性是一个对象,通过生命值的变化 得到生命值地址 查看附近的内存得到其他属性
角色对象基地址 02EE5B98
02EE5BE8 角色名字
02EE5C68 生命地址 dword
+4 内功 dword
+8 愤怒值 dword 千分比
+C 生命上限 dword
+10 内功上限 dword
+14 3E8
+18 经验值 2dword
+20 下一级经验值 2dword
+28 0A
+2C 历练 dword
+30 心 dword
+34 气 dword
+38 体 dword
+3C 魂 dword
+40 0
+44 0
+48 攻击 dword
+4C 防御 dword
+50 命中 dword
+54 回避 dword
+58 武功命中 dword?
+5C 武功防御 dword?
+60 0
+64 金钱
+68 0
2.得到吃药的CALL
通过数量定位 小量金创药数量地址 2F8DAE24
CE监测访问数量的代码得到
//吃药call地址
push 0 //物品栏ID
push 1 //数量
push 0
call 00757700
提取特征码 A1648110038B8498040400008BB0B80200000BB0BC0200007433
3.得到快捷键CALL
用快捷键吃药 吃药call是在快捷键call中的 跟踪往上一层来到快捷键call
F1-F10快捷键
0065BF07 50 push eax //0-9
0065BF0E E8 BD65FFFF call 00652520
提取特征码为 741F83BCB104040000000F84F40900008B84B10404000083784800 便于更新程序的时候好定位
4.得到选中怪物的ID地址
选中不同的怪物有不同的ID来定位
可以通过CE来监控 变化的值 未变化的值
得到选中怪物ID所在地址 [312DF1C]+1478
5.得到怪物列表
通过监测 改写选中怪物ID的代码 可以看到一个值填充了 选中ID
004AF442 8981 78140000 mov dword ptr [ecx+0x1478], eax ; 指定选中怪的ID
跟踪上下文可以发现
004AF470 - 8B 0C 85 20DF1203 - mov ecx,[eax*4+0312DF20]
eax是怪物ID 也是数组ID 这个数组一般就是怪物列表地址了
6.得到怪物属性
通过怪物列表得到怪物对象 选中不同怪物 以及打死怪物 怪物距离的不同 得到怪物属性
怪物列表地址
0312DF20
{
+ ID*4 怪物对象地址
{
+0 怪物各种功能的函数指针列表
+8 类型 怪2E
+C ID/数组下标
+31C 角色离怪物的距离
+320 怪物的名字
+37C 怪物复活过程
+380 怪物生死状态 0为生 1为死
+1018 怪物坐标X
+1020 怪物坐标Y
}
}
其中的怪物生死状态 可以通过CE来锁定选中的怪ID 打死后它会自动刷出 这样便于观察怪物对象内存中的各种属性
有些属性是浮点型 比如坐标 距离 所以用OD观察数据时要用相应的数据类型来观察
7.得到显示血条CALL
手动改写选中怪物ID时 发现没有鼠标选中时的血条 跟踪选中怪的ID代码
发现在之前有一个call 经测试是显示血条的call
选中怪显示血条call 使用条件最好是没有选中怪 要不然出现多个怪显示血条
mov esi, 0x2B1EBE18
mov eax, dword ptr [esi]
mov edx, dword ptr [eax+0x4]
push 0 //这个push以后经过了一个跳转猜到下一个push的 很容易漏掉
push 0x1
push 0x44F
mov ecx, esi
call edx
mov eax, dword ptr [esi+0xC]
mov ecx, dword ptr [0x312DF1C]
mov dword ptr [ecx+0x1478], eax
提取特征码 83C410EB108B068B50046A01684F0400008BCEFFD2
8.得到普通攻击CALL
监测 访问选中怪物ID的代码 在按下攻击以后出现的代码 这个代码一般是在普通攻击call中的
逐一测试发现 普通攻击call
0064DA3F 8B0D 1CDF1203 mov ecx, dword ptr [0x312DF1C]
0064DA45 E8 D689E5FF call 004A6470
提取特征码 8B88D802000080B9E9290000000F8408020000578BBE7814000039BE9014000075218B8694140000
其中通过普通攻击发现 选中怪物的对象的地址 [312DF1C]
9.得到捡物品CALL
通过丢物品 捡物品发现鼠标选中的对象ID都放在 [312DF1C]+1478 地址里的,怪物 NPC 物品都是通用的
捡丢物品 监测 访问此地址 可以得到一条捡物品call内部的代码 从而得到捡物品call 这种方法比较难跟踪
另一个方法是 因为普攻 和捡物属于同一类 动作 大部分程序员会把它们放到一个case里边
如:
switch(动作号)
{
case 普攻ID:{调用普攻call}
case 捡物ID:{相应的call}
case 打坐ID:{相应的call}
case 走跑ID:{相应的call}
case 逃脱ID:{相应的call}
case 组队ID:{相应的call}
case 交易ID:{相应的call}
...
...
default:
}
恰好前边得到了普攻call的调用地方 用IDA视图查看很轻松可以得到其他几个call
分别是
跑走: 0064DA51 call sub_64CE10
运气: 0064DA71 call sub_64CEA0
普攻: 0064DA95 call sub_4A6470
捡物: 0064DAB9 call sub_4A66C0
其他以此类推...
在跟踪call的参数得到 代码
0076CBB4 8B0D FC2FEA00 mov ecx, dword ptr [0xEA2FFC]
0076CBBA 8B89 74020000 mov ecx, dword ptr [ecx+0x274]
最终call完整调用参数如下:
A.
mov ecx, dword ptr [0xEA2FFC]
mov ecx, dword ptr [ecx+0x274]
call 64CDC0
B.运气call
mov ecx, dword ptr [0xEA2FFC]
mov ecx, dword ptr [ecx+0x274]
call 64CEA0
以此类推...
10.得到背包列表地址
背包数据结构一般为:
物品背包数组(基址1)
+4 物品对象1
+8 物品对象2
+??
+?? 物品数量
+?? 物品名称
+?? 功能说明
每个物品格 对应一个对象 这些对象是连续的数组
从人参数量下手 得到数量地址 监控访问地址的代码 人参所在物品栏的临时基址
0DD97468,搜索此地址得到几个代码 分别监控访问,鼠标移动人参换不同的物品格,可以得到代码:
0076B9D1 - 3B 3D 64811003 - cmp edi,[03108164]
0076B9D7 - 75 2A - jne 0076BA03
0076B9D9 - 8B 84 B7 04040000 - mov eax,[edi+esi*4+00000404]
很明显[edi+esi*4+00000404]这个是关键 edi的值可能背包基地址但是发现其值是19eBA4C0 也是一个临时地址往上看代码
发现cmp edi,[03108164] 可以推测[03108164]就是存放每次游戏背包基地址的地方了
综合上边发现 OD观察内存得到:
物品栏基地址 [03108164]
+404 装备物品第一格基地址 0DD97468(临时)
+5C 物品名字
+AC 使用级别
+F1 说明
+23C 数量
+26c 防御
+290 背包数组下标
+30C 耐久度
+408 第二格
...
...
+?? 如果这格没有物品 则为0
11.得到喊话CALL
喊话功能call寻找过程:
通过在喊话对话框中输入不同的字符串 得到2个地址 分别在CE中改写这2个地址
发现地址A改写后马上更新到喊话对话框中了 但是发送对话显示的是地址B的内容
追踪到B CE监控访问该地址代码 得到一个MEMSET函数内的代码 CE查看访问时 ECX的值
OD下条件断点 断下后放回上一层 用IDA查看地址 结合视图查看 反复跟踪得到喊话call
esi=[312E7E0]=0E278010
00447A9E 8B06 mov eax, dword ptr [esi]
00447AA0 8B50 04 mov edx, dword ptr [eax+0x4]
00447AA3 57 push edi //0xD
00447AA4 53 push ebx //0xD
00447AA5 68 ED030000 push 0x3ED
00447AAA 8BCE mov ecx, esi
00447AAC FFD2 call edx
具体访问代码:
mov esi, dword ptr [312E7E0]
mov edi,0xd
mov ebx,0xd
mov eax, dword ptr [esi]
mov edx, dword ptr [eax+0x4]
push edi
push ebx
push 0x3ED
mov ecx, esi
call edx
函数特征码 8B068B5004575368ED0300008BCEFFD2
内容基地址寻找过程:
监控地址B访问代码
mov cl, [eax]
以此往上跟踪可以得到
mov ebx, dword_E73D1C
lea edi, [ebx+13Ch]
mov eax, edi
由此可得到 喊话基地址为 [0E73D1C]+13c
12.坐标相关信息
需要注意的是3D游戏中 坐标是由X Y Z 其中z是高 如果瞬间转移的时候不注意Z很有可能就会移动到
山体里边或湖水里边 或 地下 或天上 这个时候系统是会监测到的 所以会还原到一个正确的位置
Z坐标的计算 可以一般是以上往下计算的 所以Z都是负数 负得越多海拔越低 负得少海拔高,
想象一下就是把整个3D实地模型放到一个箱子里了 箱子的上顶角就是坐标的0点
通过CE观察鼠标坐标得到
坐标对象基地址 0312DF1C 其中还存放了鼠标选怪ID
+0x1614 当前角色X坐标
+0x1618 当前角色Z坐标
+0x161C 当前角色Y坐标 或者0012762C
+0x15D8 鼠标点击坐标X 或者00E9AB50
+0x15DC 鼠标点击坐标Z
+0x15E0 鼠标点击坐标Y 或者00E9AB58
这组鼠标地址 主要是用来计算发送数据
另外一组组要是画面跑动使用
[[312DF1C]+2C94]+280 当前X //修改后直接跳到相应的坐标 只是本地 服务器数据未变
[[312DF1C]+2C94]+284 当前Z
[[312DF1C]+2C94]+288 当前Y
[312DF1C]+147C 目标X
[312DF1C]+1480 目标Z
[312DF1C]+1484 目标Y
后边还发现一组用于跑动需要
直接通过鼠标改变来跟踪跑步函数比较困难 所以通过动静的状态来判断
CE搜索后得到比较多 通过改写目标地址 然后状态来判断角色移动没 来最终发现
以下2个开关
[312DF1C]+1494 开关1 1
[312DF1C]+1498 开关2 1
但是发现不是每次画面人物都能移动的 观察得到人物摆poss时 开关2会变成1 动作完成后变为0
这个时候在修改 目标地址 及开关就可以移动 推测摆poss 不光是好看 应该有数据更新重置功能
跟踪开关2改写的代码 来到了摆poss的代码处 发现每次改写时 还会改写一个地方 且这个地方很临近
经CE测试得到
[312DF1C]+149C 开关3 为0时更改坐标开关12可以移动
现在可以自由移动 但是发现走的是直线 和平时移动不太一样 这样势必会撞墙 应该有代码判断是否有障碍 定位判断障碍的函数
用CE修改目标地址 让主角跑起来 监测X或Y写入 当撞墙时 X或Y有一个值就不会变了 这时候查看写入代码
地址004B1693 如果遇到墙 执行不到这个地址 地址前边应该有校正 IDA视图浏览很快定位到有3个流程
但是都是 54CEC0 函数的返回值 从而推断 54CEC0 函数是判断障碍物的函数有,进入函数发现有4个返回值
分别是 0 1 2 3 OD断点检测 正常时返回的是1 快速验证 修改函数代码正常返回0时就返回1 再用CE修改
目标地址进行跑动 这下就可以穿越一切了
上边的一切都是画面变动 服务器数据并没有发生变化 定位发送坐标数据的函数
由于鼠标函数比较复杂 且游戏本身有土灵符可以瞬移 这样省去了 鼠标函数调用 但是有发送数据的函数
CE监测 鼠标坐标 使用土灵符 可以得到函数 495AD0 下断函数 发现鼠标点击时也有调用此函数 应该就是
数据发送函数了 但是使用道具和鼠标点击参数不一样 综合一下写入 完整的角色移动call
mov esi, dword ptr [312DF1C]
//设置目标地址
mov dword ptr [esi+147C],44C70000
mov dword ptr [esi+1480],0xC3B621EF
mov dword ptr [esi+1484],4465C000
mov dword ptr [esi+1494],1
mov dword ptr [esi+1498],1
mov dword ptr [esi+149C],0
//发送数据到服务器
mov dword ptr [esi+15D8],44C70000
mov dword ptr [esi+15DC],0xC3B621EF
mov dword ptr [esi+15E0],4465C000
mov edx,dword ptr [esi+15D8]
mov ecx,dword ptr [esi+15DC]
push 2
sub esp, 0c
mov eax, esp
mov [eax], edx
mov edx,[esi+15E0]
mov [eax+4],ecx
mov ecx,esi
mov [eax+8],edx
call 495AD0
13.得到综合内存信息
通过丢物品后 走远点击物品然后点击其他地方来取消捡物品 可以得到选择物品ID和怪物是同一个
观察物品内存块情况 得到
0312DF20
{
+ ID*4 物品对象地址
{
+8 类型 33
+C ID/数组下标
+64 物品的距离
+94 物品的名字
+198 物品坐标X
+19C 物品坐标Z
+1A0 物品坐标Y
}
}
人物角色内存情况
0312DF20
{
+ ID*4 人物对象地址
{
+8 类型 2E
+C ID/数组下标
+18 人物名字
+1D00 人物等级
+147C 人物坐标X
+1480 人物坐标Z
+1484 人物坐标Y
}
}
14.得到买卖物品CALL
通过执行买卖动作 用OD监视得到买卖物品的数据包信息
可以多次检查不同数据来观察
0012A48C 00 00 92 00 80 00 02 00 00 00 19 41 68 F3 68 CA //92 80 02为常量
0012A49C 9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 32 1B //01数量 32为计数ID
0012A4AC 02 00 00 00 00 00 17 39 C2 90 23 A2 E8 0C 68 CA //物品类型
0012A4BC 9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 01 0C //01数量 0C是背包下标
0012A4CC 00 00 01 00 6C F3 00 00 00 00 00 00 00 00 00 00
0012A4DC 00 00 00 00 00 00 00 00 00 00 00 00 00 F3 00 00
0012A4EC 00 00 00 00 00 00 00 00 68 F3 00 00 00 00 00 00
0012A4FC 00 00 00 00 00 00 00 45 65 F3 00 00 00 00 27 44
0012A50C 62 F3 26 42 62 F3 00 00 00 00 00 00 00 00 00 00
0012A48C 00 00 92 00 80 00 02 00 00 00 00 00 00 00 94 CA ..?€........斒
0012A49C 9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 36 1B ?...........6
0012A4AC 02 00 00 00 00 00 F7 57 2F D0 AE A8 E8 0C 94 CA .....鱓/挟ㄨ.斒
0012A4BC 9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 01 00 ?............
0012A4CC 00 14 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
0012A4DC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0012A4EC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
6C6EB130 >00 00 92 00 80 00 02 00 00 00 00 00 00 00 94 CA ..?€........斒
6C6EB140 9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 36 1B ?...........6
6C6EB150 02 00 00 00 00 00 F7 57 2F D0 AE A8 E8 0C 94 CA .....鱓/挟ㄨ.斒
6C6EB160 9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 01 00 ?............
6C6EB170 00 14 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
6C6EB180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
6C6EB190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
6C6EB1A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
6C6EB1B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
3233FDC0 00 00 92 00 80 00 02 00 00 00 00 00 00 00 94 CA ..?€........斒
3233FDD0 9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 36 1B ?...........6
3233FDE0 02 00 00 00 00 00 F7 57 2F D0 AE A8 E8 0C 94 CA .....鱓/挟ㄨ.斒
3233FDF0 9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 01 00 ?............
3233FE00 00 14 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ..............
出售物品数据包结构
struct
{
+0 const0 word 00
+2 const1 word 92
+4 const2 word 80
+6 const3 dword 2
+A ?? dword 可以为0
+E 物品对象+4C dword 物品ID
+12 物品对象+50 dword
+16 数量 23c dword
+1A ?? dword 可以为0
+1E 角色属性[0x2EE5CCC] dword
+22 角色属性[0x2EE5CD0] dword
+26 物品对象+54 dword
+2A 物品对象+58 dword
+2E 物品对象+4c dword
+32 物品对象+50 dword
+36 数量 23c dword
+3A 物品对象+240 dword
+3E 物品对象+1F2 byte
+3F 背包下标 290 byte
+40 物品对象+238 byte
+41 物品对象+244 byte
+42 物品对象+AC byte
+43 物品对象+A4 byte
6C F3 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 F3 00 00
00 00 00 00 00 00 00 00 68 F3 00 00 00 00 00 00
00 00 00 00 00 00 00 45 65 F3 00 00 00 00 27 44
62 F3 26 42 62 F3 00 00 00 00 00 00 00 00 00 00
}
提取特征码 8D853CFFFFFF50B840E94700FFD0
以此类推得到 买物品CALL的数据包 打开NPC买卖对话框CALL的数据包 从而完成自动买卖物品
15.关于OD调试多线程的问题
OD调试多线程会出现这样的问题
"OllyICE无法再断点(可能无效)地址 读取寄存器及更新EIP
通常纠正后继续试不可能的 然后 您可以在自己承担风险的情况下
恢复及继续"
解决方法参照 http://blog.csdn.net/whatday/article/details/9059281
16.游戏多开实现
此游戏多开会有提示框 OD载入去除 发现还是不行 网上搜索发现是client文件夹冲突 想想也是第一个客户端一个文件嘛
复制client文件夹命名为其他名字 复制launcher.exe修改其中路径 多开OK了
17.辅助编程注意事项
1.由于牵涉到内存 所以每个内存读之前 先尝试是否有效 可以使用 IsBadReadPtr 函数
2.各种对象属性最好基于指针 因为数据都是动态变化的 只有在使用前来取得数据还是最正确的数据
3.怪物对象ID不会变 但是对象基地址有可能变 所以应时候ID找对象基地址
- 游戏数据的捕捉(郁金香学习笔记)
- cortex_m3_stm32嵌入式学习笔记(十):输入捕捉实验(定时器的输入捕捉)
- Java线程学习笔记(二) 线程的异常捕捉
- AppleScript学习笔记(三)捕捉错误
- 郁金香驱动笔记
- 008-人物信息数据的封装.基址与偏移管理单元库(郁金香灬老师 2015年游戏外挂视频教程第8课内容)
- struts2学习笔记异常捕捉
- Kinect开发学习笔记之(六)带游戏者ID的深度数据的提取
- Kinect开发学习笔记之(六)带游戏者ID的深度数据的提取
- Kinect开发学习笔记之(七)带游戏者ID的深度数据的提取
- Kinect开发学习笔记之(六)带游戏者ID的深度数据的提取
- Kinect开发学习笔记之(六)带游戏者ID的深度数据的提取
- 【Cocos2d-X开发学习笔记】第29期:游戏中数据的存储(上)
- 【Cocos2d-X开发学习笔记】第30期:游戏中数据的存储(下)
- 网络数据包捕捉工具jNetPcap学习笔记(一)
- 3DS MAX 学习笔记 一(捕捉工具)
- 郁金香
- IDA学习笔记--VS2008按钮事件捕捉
- css和js的浏览器不兼容问题汇总
- I2C总线原理及应用实例
- WPS设置首字母自动大写转换
- c语言要点摘录(21~24 数组与指针-上)
- 64位时间戳实现
- 游戏数据的捕捉(郁金香学习笔记)
- 删除可执行文件的图标
- hdu2767Proving Equivalences(强连通+缩点)
- 最小生成树
- HDU 4354 Missile 树的最大独立集+枚举
- D3D混合纹理
- js 当中的预编译
- 离散化 和多维线段树
- 嵌入式开发基础----register和volatile关键字