这就是博客作者的入门方式。 原理是一样的,所以我贴出来。 图文并茂的文章已经不多了。
目标:游戏CALL练习示例ONE 注:阅读这篇CALL文章并不是学习其操作步骤,而是学习求步骤的原理。 只有明白了原理,你才能真正知道怎么做。 不要被模拟器愚弄了。 干脆忽略这篇文章,不要因为你写了关于这个模拟器的问题而忽略这篇文章。 我希望这篇文章可以帮助你。
这是一个伟大的人制作的模拟器。 今天调用这个模拟器。
使用 OD 加载模拟器
然后按F9运行
下一个 bp 发送断点
P:为什么要设置发送断点?
*send是微软提供的API函数,可以用来发送数据包。 大多数游戏都使用这个函数来发送数据包。 其他包括==发送。 对应的数据包接收函数是recv。 对应的数据包接收函数为
下载完段落后,在这里按ALT+B,就会显示已经下载的段落的地址。
*当您不想停止、暂时不想删除时,可以按空格键禁用。
断开连接后,我们点击模拟器的健康按钮,OD立即断开连接。
*标题显示模块-表明我们还在系统空域*游戏通过调用send函数发送数据包。 停用后,程序告诉系统我要发送数据包,然后系统开发并发送数据包。 经过这个时间,我们就在系统中发送了数据包。
按 CTRL+F9 返回
P:为什么要用CTRL+F9返回? 而不是继续前进?
*程序是一层一层一层的,就像一个盒子里有一个盒子,盒子里面还有一个盒子。 而我们破坏的发送是在最里面的盒子里,所以我们需要返回到我们需要的代码层。
我们来看看堆栈窗口
这里的第一行是 CALL。 第二到第五行是CALL的参数。 写成函数的函数是send(soket,data,,flags)。
这是系统发送所需的参数DATA。 这里存储的是send发送的数据包的内容,表示数据包的大小。
如果我们从MSDN上查看该函数的参数,会发现它的参数和我们刚才反汇编的参数是一样的。
*按照调用约定,参数从右侧开始入栈
继续返回
这里我们已经到达了程序空域(标题显示了模拟器,但没有显示)。 这里OD已经帮我们标记好了。 这是调用 send 的汇编代码。 因为模拟器还没有写接收返回包的代码,所以我们称这个为send。 函数程序也无响应
继续返回
这里有一个呼叫。 如果我们第一次搜索它,我们无法确认这是否是我们正在寻找的东西。
P:如何确认这是否是我们需要的CALL?
我们先断了再说吧
继续返回
这里有一个retn
*retn 表示程序结束。
这里从JMP开始到下面的retn就代表这是一段连续的代码。
继续返回
这里我们发现另一个CALL
先停下来再说吧
回到一级
这里还有一个CALL也断开了。
好的,我们现在回到了 6 楼,发现了 3 个 CALL。
我们要找哪一个? 让我们先测试一下我们正在寻找什么。
删除了发送断点,暂时没用。
当我们按下加血时,发现所有断点都会被打破。 这时我们发现第二个CALL附近有一个类似“血”的文字。
当然,除了喊CALL之外,一般不会有一个非常明确的数值作为依据。 在这种情况下,你就必须依靠你的经验来猜测。
当我们点击吃蓝的时候,发现只砍掉了第一个。 好吧,我们忽略第一个。 为什么? 你可以猜猜...
好的,我们来看看第二个CALL
mov edx,调用 retn
*为了编写CALL,我们需要模拟它需要的寄存器和堆栈环境
P:如何查看CALL所需的寄存器?
我们进入调用里面
选择呼叫线路并按 Enter 键跳转到底部。
/$ 55 推 ebp |. 8BEC mov ebp, esp |. 83C4 F8 添加 esp,-8 |。 53 推 ebx |。 第8955章 8BD8 mov ebx, eax |. 8B45 FC mov eax,dword ptr [ebp-4] |。 E8 呼叫|。 33C0 双字指针 fs:[eax], esp |。 8B45 FC mov eax,dword ptr [ebp-4] |。 BA mov edx,|。 E8呼叫
/$ 55 推 ebp |. 8BEC mov ebp, esp |. 83C4 F8 添加 esp,-8 |。 53 推 ebx
这里是保存堆栈环境。 我们暂时忽略它。
|。 第8955章
将EDX保存到[EBP-4]我们来求一下EDX的值
在此汇编代码之前没有为 EDX 分配任何值。 我们返回到上一级并按下键盘 -
上一级
移动edx,
这段代码的意思是给EDX赋值,即EDX=
找到EDX的值后,下面继续查找。
|。 8BD8 mov ebx, eax
这里需要EAX的值,但是我们搜遍了这一层和上一层,没有找到给EAX赋值的代码。
这里我们先直接给EAX赋值
没有其他的
好了,我们现在可以确认这个CALL调用了EDX和EAX寄存器的值。
这个CALL的写法是
mov edx, mov eax, 调用
我们来测试一下
呼叫成功
然而,我们换了一台电脑却发现无法使用? 经过调试,我们发现EAX的值和之前不一样了~
P:如何获取EAX的固定值?
答案很简单,使用CE搜索
你看到绿色价值了吗? 这是EAX的基地址。 无论EAX的值如何变化,都可以在这个地址读取到真正的值。
代码如下所示
mov edx, mov eax, mov eax,[eax] 调用
好的,现在您可以在任何计算机上运行它。
=================================================== =====
好吧,我们暂时忽略这个 CALL。
现在让我们找出 EAX 的值。
呼叫时,按下增加血OD的按钮,即停止。
然后我们按CTRL+F9返回
好的,我们到了
mov edx,ebx mov eax,[ebx+124] 调用 [ebx+120]
这时我们找到EAX的值
EAX=[ebx+124]
我们发现CALL地址不是直接地址。
在这个CALL断点下添加血液按钮
我们发现 [EBX+124]=[]= EAX= 我们刚刚找到了 EAX 的基址
[ebx+120]=[]=
这里写成代码的CALL地址是
mov eax, mov eax,[eax] 调用
呼叫成功`
P:为什么两个不同地址的CALL都会成功?
不断测试后(如何测试?点击不同按钮可以看到CALL地址)
发现不同的按钮所划分的地址是不同的。
魔术师的地址
制冰系统地址
=========
我们来测试第三个CALL
mov edx,[ebx+214] mov [eax+24c],edx mov eax,ebx 调用
调试时,[EBX+214]=0则edx的值=0
[EAX+24C]=EDX=0 EAX=
EAX=EBX=调用
现在寄存器值都清楚了,我们看看CALL还调用了哪个寄存器。
跟进CALL(按F7进入CALL)
/$ 53 推 ebx |. 8BD8 mov ebx, eax |. 66:83BB 22010>cmp 字 ptr [ebx+122], 0 |。 74 2D je 短024E5|。 8BC3 mov eax, ebx |. 8B10 mov edx,dword ptr [eax] |。 FF52 3C 调用双字 ptr [edx+3C] |。 85C0 测试 eax、eax|。 74 22 je 短024F0|。 8BC3 mov eax, ebx |. 8B10 mov edx, 双字 ptr [eax]
|。 8BC3 mov eax, ebx 这里有一行调用 EBX。 我们查了一下,发现有代码给EBX赋值,所以我们不用管它。
|。 8B10 mov edx, dword ptr [eax] 这里调用了EAX。 上一层有给EAX赋值的代码。
下面已经没了
好了,使用代码注入器来写CALL
mov edx,[ebx+214] ,[ebx+214]=0
那么第一句就是mov edx,0
mov [eax+24c],edx,edx的值=0 EAX= 那么第二句是MOV[EAX+24C],0但是注入器不通过。 这时我们改变写法,先给EAX赋值。 mov eax,这里我们刚刚发现这个基地址就是EAX的基地址。
先放入基地址mov eax的值,然后读取基地址mov eax,[eax]然后加上偏移量24C add [eax],24c
地址写入后,我们将EDX放入地址中,mov [eax],edx
mov eax,ebx 第三句 EBX= 因为CALL没有调用EBX,所以我们不用给ebx赋值 mov eax,
称呼
把它们放在一起就这样了
mov edx,0 mov eax, mov eax,[eax] 添加 eax,24c mov [eax],edx mov eax, 调用
好了,CALL成功了~
经过调试,发现EBX中不同的按钮有不同的值。
好吧,我们发现这也可以称为
问题:
P:为什么三个不同地址的CALL都能成功?
总结
*retn表示程序结束 *send是微软提供的API函数,可用于发送数据包。 大多数游戏都使用这个函数来发送数据包。 其他包括==发送。 对应的收包函数是recv 对应的收包函数是 *要写一个CALL,我们需要模拟它需要的寄存器和堆栈环境
本文链接: