03授人以鱼不如授人以渔●(找CALL篇一)

作者:重楼 
时间:2009.08.20 

目标:游戏找CALL练习实例ONE 

:看这篇找CALL文章,并不是说要学会它的操作步骤,而是学会找步骤的原理,只有懂得原理,才算真正会了.不要因为模拟器的简单 而忽略这篇文章,也不要因为曾经写过这个模拟器的挂 而忽略这篇文章.希望这篇文章能给你带来帮助


  

这是一位大牛做的模拟器器,今天就来找这个 模拟器的CALL 

OD 加载 模拟器 

然后按F9 运行 

bp send 断点 


  

P:为什么要下 send 断点

*send 是微软提供的一个API 函数,可以用来发送数据包.  绝大部分游戏都是用这个函数来发包的,其他还有 WSASend  sendto  WSASendto  ==  send对应的收包函数是 recv  WSASend对应的收包函数是 WSARecv 


下段 后 这里按 ALT+B  会显示 已经下段的 地址 


  

*当你暂时不想断下来 而又不想删掉 就可以 按 空格 来禁止. 

断下来后,我们点下  模拟器的 加血 按钮  OD立马就断了下来 


  

*标题显示 模块- ws2_32  表明 我们还在系统领空 
*游戏发送数据包是调用send函数 发送的,掉用以后 程序告诉系统 我要发包了,然后系统就开发发送封包,这个时候断下来后 我们就在 系统发送完封包 后


按 CTRL+F9  返回 

P:为什么要用 CTRL+F9 返回?而不是 前进

*程序是 一层套着一层的,就像一个箱子 里面 包含一个箱子  ,而里面的箱子里又有一个箱子.而我们断的send  就是在最里面的箱子,所以我们需要返回到 我们所需要的代码层




  



我们来看下 堆栈窗口 

这里 第一行是  CALL 
      第二行到第五行 是 CALL的 参数 
写成函数就是 send(soket,data,datasize,flags) 

这个就是 系统send所需要的参数  
DATA 这里存放着 send发送的封包内容 
DATASIZE  表示 封包的大小 


  

MSDN查看一下 函数的参数 我们会 发现 他的参数 跟我们刚刚反汇编的一样. 





  


*按照 __cdecl调用约定  参数 是从 右边 开始压入堆栈  


继续  返回 

这里 我们已经到了 程序领空了  (标题显示 模拟器,而没有显示ws2_32) 
在这里 OD已经 给我们标明了这是调用send 的汇编代码 
因为这个模拟器并没有写接收 返回封包的 代码 所以 我们调用这个send 函数程序也是没有反应的 

继续返回 


  

这里有一个CALL  如果我们第一次找,我们并不能确认这个是否 是我们要找的 

P:如何确认这个是否是我们需要的CALL? 


我们先断下来 再说 

继续返回 



  

这里上面 有一个 retn  

*retn  表示  一段程序的结束. 

这里从  JMP 00403814  开始 到下面的retn  代表 这个是连续的一段代码 


继续返回 



  

这里 我们又发现一个CALL 


先断下来再说 

在返回 一层 



  

这里也有一个CALL  也断下来 

好了  我们现在已经返回了6层 找到了3CALL 

到底哪个是我们需要找的呢 我们先来测试下我们找的 

把 send 断点 删了 暂时没用了 

按下 加血 我们发现 所有断点  都会断,  这个时候 我们发现 第二个CALL 附近有 ""这种文本 

当然一般的除了喊话CALL 以外不会有很明确的数值当做依据 这个时候就要靠 你的经验 去猜了

我们在 点下 吃蓝  发现 只断下 第一个好了,第一个先不要管了.为啥?猜的... 


好了 我们来看看第二个CALL 

mov edx,00453028 
call 00452E98 
retn 


*要写一个CALL,我们就要模拟出他所需要的寄存器,还有堆栈的环境 

P:如果看一个CALL所 需要的 寄存器

我们进入 call 00452E98  的内部 

选中 call 00452E98  那行 按 回车 就会 跳到下面 


00452E98  /$  55            push    ebp 
00452E99  |.  8BEC          mov    ebp, esp 
00452E9B  |.  83C4 F8      add    esp, -8 
00452E9E  |.  53            push    ebx 
00452E9F  |.  8955 FC      mov    dword ptr [ebp-4], edx 
00452EA2  |.  8BD8          mov    ebx, eax 
00452EA4  |.  8B45 FC      mov    eax, dword ptr [ebp-4] 
00452EA7  |.  E8 1414FBFF  call    004042C0 
00452EAC  |.  33C0          xor    eax, eax 
00452EAE  |.  55            push    ebp 
00452EAF  |.  68 7E2F4500  push    00452F7E 
00452EB4  |.  64:FF30      push    dword ptr fs:[eax] 
00452EB7  |.  64:8920      mov    dword ptr fs:[eax], esp 
00452EBA  |.  8B45 FC      mov    eax, dword ptr [ebp-4] 
00452EBD  |.  BA 942F4500  mov    edx, 00452F94 
00452EC2  |.  E8 5513FBFF  call    0040421C 


00452E98  /$  55            push    ebp 
00452E99  |.  8BEC          mov    ebp, esp 
00452E9B  |.  83C4 F8      add    esp, -8 
00452E9E  |.  53            push    ebx 


这里是 保存 堆栈环境  我们先不管他 

00452E9F  |.  8955 FC      mov    dword ptr [ebp-4], edx 


将 EDX 保存到 [EBP-4] 
我们来找下 EDX的值 


这段汇编代码 前面 没有给 EDX赋值  我们返回上一层  按小键盘  - 

上一层  

mov edx,00453028 

这句代码的意思是  将 453028赋值给EDX 
也就是说EDX=00453028 

找到EDX 的值后 继续往下面找 


00452EA2  |.  8BD8          mov    ebx, eax 

这里需要EAX的值,但是 我们找了这一层和上一层 并没有发现有给EAX赋值的代码 

我们这里 先直接给EAX赋值 

其他没有了 

好了 我们现在可以确认了  这个CALL 调用了 EDX EAX的寄存器的值 


  

这个CALL的写法就是  


mov edx,00453028 
mov eax,00991FA8 
call 00452E98 


我们来测试下 


  


CALL成功了 

但是,我们拿到另外一台电脑  发现 居然不能用了?  调试了下 发现 EAX的值 跟刚刚的不一样


P:如何取到 EAX的固定值呢? 

答案很简单 用CE搜 


  


看到那个绿色的值了么 那个就是 EAX的基址 ,无论 EAX的值 怎么变 都可以在这个地址读取到真正的值 

代码如下 

mov edx,00453028 
mov eax,456d68 
mov eax,[eax] 
call 00452E98 

好了  现在 可以再任意一台电脑上运行了 



======================================================= 



好了  先不管这个CALL 


我们现在来找下 EAX的值。 

  call 00452E98  下断  按下 加血 OD 断下来了 

然后我们按 CTRL+F9 返回 

好了 到了这里 



  


mov edx,ebx 
mov eax,[ebx+124] 
call [ebx+120] 

这个时候 我们发现  EAX的值 

EAX=[ebx+124] 


我们发现 CALL地址 并不是 是直接的地址。 



在这个CALL 下断  点下 加血 按钮 

我们发现  [EBX+124]=[0099493C]=00991FA8 
EAX=991FA8 
刚刚 我们找过 EAX的基址了  

[ebx+120]=[00994938]=00453014 

这里的CALL地址 写成代码是 

mov eax,456d68 
mov eax,[eax] 
call 453014 



  

CALL成功了

P:为什么2个不同地址的CALL都会成功呢? 




经过不断测试(如何测试?点击不同的按钮 看看CALL的地址) 

发现 不同按钮断下来的地址 都是不同的。 



  

补魔的地址 



  

冰系的地址 




========== 


我们来测试下第三个CALL 




  


mov edx,[ebx+214] 
mov [eax+24c],edx 
mov eax,ebx 
call 4324d8 


调试过程中  
[EBX+214]=0  那么 edx的值 =0 

[EAX+24C]=EDX=0 
EAX=00991FA8 

EAX=EBX=994818 
CALL 4324d8 


寄存器的值都搞清楚了 然后 我们看看 CALL还调用了哪个寄存器 

跟进CALL  (按 F7 进入CALL ) 


004324D8  /$  53            push    ebx 
004324D9  |.  8BD8          mov    ebx, eax 
004324DB  |.  66:83BB 22010>cmp    word ptr [ebx+122], 0 
004324E3  |.  74 2D        je      short 00432512 
004324E5  |.  8BC3          mov    eax, ebx 
004324E7  |.  8B10          mov    edx, dword ptr [eax] 
004324E9  |.  FF52 3C      call    dword ptr [edx+3C] 
004324EC  |.  85C0          test    eax, eax 
004324EE  |.  74 22        je      short 00432512 
004324F0  |.  8BC3          mov    eax, ebx 
004324F2  |.  8B10          mov    edx, dword ptr [eax] 


004324E5  |.  8BC3          mov    eax, ebx 
这里有一行 调用了 EBX  我们往上找找 发现 有给EBX 赋值的代码  那么 我们就不必理会了 

004324E7  |.  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=00991FA8 
那么 第二句 就是 MOV [EAX+24C],0  但是 注入器不通过 这个时候 我们换一种写法 
首先给 EAX赋值  mov eax,991FA8  这里 我们刚刚找过 这个基址 456d68 EAX的基址 

首先放入 基址的值 mov eax,456d68 
然后在读取 基址  mov eax,[eax] 
然后 加上偏移 24C  add [eax],24c    

地址写好后 我们把 EDX放到 地址里去 mov [eax],edx  

mov eax,ebx第三句  EBX=994818 
因为 CALL没有调用EBX 所以我们不必给ebx  赋值 
mov eax,994818 


call 4324d8 

放到一起 那么就是 

mov edx,0 
mov eax,456d68 
mov eax,[eax] 
add eax,24c 
mov [eax],edx 
mov eax,994818 
call 4324d8 



  


好了 CALL成功了

经过调试 发现 不同的 按钮  他的EBX里的值也不一样 


好了  我们发现这也可以调用 



提问

P:为什么3个不同地址的CALL都会成功呢

总结 

*retn  表示  一段程序的结束 
*send 是微软提供的一个API 函数,可以用来发送数据包.  绝大部分游戏都是用这个函数来发包的,其他还有 WSASend  sendto  WSASendto  ==  send对应的收包函数是 recv  WSASend对应的收包函数是 WSARecv 
*要写一个CALL,我们就要模拟出他所需要的寄存器,还有堆栈的环境

转载于:https://www.cnblogs.com/keyvip/archive/2011/10/17/2215225.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值