上一节我们找到了二叉树遍历的地方
这节我们详细来分析下这个二叉树
我们可以在头部下断 然后单步调试 一步步走 分析
0155BD87 8B71 48 mov esi,dword ptr ds:[ecx+0x48] ; ecx=[0x1BF8C28]
0155BD8A 8BCE mov ecx,esi
0155BD8C 8B46 04 mov eax,dword ptr ds:[esi+0x4]
0155BD8F 8078 0D 00 cmp byte ptr ds:[eax+0xD],0x0 这边把[eax+d]和0比较 其实这里是判断是否遍历完了
0155BD93 75 14 jnz short Game.0155BDA9 如果不相等就跳到0155BDA9
0155BD95 3950 10 cmp dword ptr ds:[eax+0x10],edx 这个是edx是对象ID 是push进来的第二个参数 这个不懂可以先放 我们主要分析二叉树结构 如果我们是通过遍历我们自己人物的信息 如血 跟进来的 那这个edx就是我们人物的ID
0155BD98 7D 05 jge short Game.0155BD9F 如果[eax+0x10]>=edx 就跳 否则就继续往下执行 也就是遍历右树 为什么?
我们发现 他是在和我们传的参数 对象ID比较 最终这个函数是要返回我们传的这个ID的对象出去的 这个eax+10本身也是一个对象的ID eax即表示某个对象
也就是说 他在这个树里面 找我们的传进来的对象是否存在 如果存在 最终会返回出去 否则就返回0
我们再分析 为什么当前对象ID大于我们传进来的ID就不跳 继续往下执行 遍历右树
我们可以这样猜想 说明这个树存放数据是有一定规律的
我简单画了一张草图 将就看吧 哈哈
假设我们根节点5 这时候来了第二个对象他是2 发现比5小因此存放在左树
这时候 又来了第三个对象要存放 他是10 发现比5打 因此存右边
这时候又来了第四个对象要存放 他是1 发现比5小 然后又和2比较 发现比2小 因此放在2的左子
以此类推 也就是说 他是这样一个规律 ID小的放左树 ID大的 放右树
0155BD9A 8B40 08 mov eax,dword ptr ds:[eax+0x8] 这边是遍历右树
0155BD9D EB 04 jmp short Game.0155BDA3 无条件跳转 这边直接跳到0155BDA3 再次循环
0155BD9F 8BC8 mov ecx,eax
0155BDA1 8B00 mov eax,dword ptr ds:[eax]
0155BDA3 8078 0D 00 cmp byte ptr ds:[eax+0xD],0x0 这边把[eax+d]和0比较 其实这里是判断是否遍历完了 上面有一句一样的判断
0155BDA7 ^ 74 EC je short Game.0155BD95
0155BDA9 3BCE cmp ecx,esi
最终把对象返回出去
还记得我们上一节说的血地址吗 [[eax+0x1B4]+0x4]+0x2CF0 eax即对象 也就是说 对象 +0x1B4]+0x4]+0x2CF0
最终往这个地址里面写入了我们人物的血值
其实大家 如果遍历当前对象地址 可以看到很多相关信息 比如坐标 蓝 经验 名字 等等
我简单用c#还原了 他这个遍历 发现了么有 其实和百度的例子 几乎一样
这其实实在遍历周围对象 怪物 NPC 采集物 也包括我们自己 等等 所以我们找血值的时候会跟到这里
我简单做了一个显示
这节就到这里吧 下次心情好了 再继续
网友评论