首页
社区
课程
招聘
[旧帖] 吃药call 求解 0.00雪花
发表于: 2012-7-2 10:10 1765

[旧帖] 吃药call 求解 0.00雪花

2012-7-2 10:10
1765
00CF3AB0      1    push ebp
00CF3AB1      2    mov ebp,esp
00CF3AB3      3    sub esp,0x44
00CF3AB6      4    push ebx
00CF3AB7      5    push esi
00CF3AB8      6    push edi
00CF3AB9      7    mov dword ptr ss:[ebp-0x4],ecx  把ecx的值传给ebp减4,ecx的值游戏每次重新登录都会变
                   不过【ecx】的值是不变的是1  这里ecx的值是指针,把这个指
                   针传给ebp减四。这个指针游戏重新登录会变的不过里面的值是不会变的
00CF3ABC      8    cmp dword ptr ss:[ebp+0x8],0x43   ebp加8的值是1
00CF3AC0      9    jl XTUClient.00CF3AC4
00CF3AC2      10   jmp XTUClient.00CF3AEC
00CF3AC4      11   mov eax,dword ptr ss:[ebp+0x8]  此时eax的值是1
00CF3AC7      12   imul eax,eax,0x28   这里eax的值是28
00CF3ACA      13   mov ecx,dword ptr ss:[ebp-0x4] 把1传给ecx
00CF3ACD      14   mov edx,dword ptr ds:[ecx+eax+0x4]  这里是指针加上ecx里的值1加上eax里的值28加上0x4这里面的值是药的id
00CF3AD1      15   push edx   这是吧药的id号push进去
00CF3AD2      16   mov eax,dword ptr ss:[ebp+0x8]  此时eax的值是1
00CF3AD5      17   imul eax,eax,0x28    这里eax的值是28
00CF3AD8      18   mov ecx,dword ptr ss:[ebp-0x4]   把一1传给ecx
00CF3ADB      19   mov edx,dword ptr ds:[ecx+eax]    这里是指针加上ecx里的值一加上eax里的值28这里面的值是1
00CF3ADE      20   imul edx,edx,0xC  这个不太理解 imul有符号乘法不是只有一个操作数码??隐藏的不是eax吗 这里edx的值是c
00CF3AE1      21   mov eax,dword ptr ds:[edx+0x113D2B4]  这里是吧edx里值c加上0x113D2B4里的值传给eax 这个call的值是不变的
00CF3AE7      22   call eax
00CF3AE9      23   add esp,0x4
00CF3AEC      24   pop edi
00CF3AED      25   pop esi
00CF3AEE      26   pop ebx
00CF3AEF      27   mov esp,ebp
00CF3AF1      28   pop ebp
00CF3AF2      29   retn 0x4

下面是我的疑问 我分析的是8,9句是判断小于等于就跳   
11到15句是计算指针里的值是药品id 然后把药品id压入堆栈
16到21就是计算call的地址所以我把上面的call代码简化换成了
push  0x000028ce  药id
mov   eax,0x007ebbe4  call的地址
call   eax
用注入工具注入
游戏能正常吃药 不过游戏一秒以后就崩溃了
我实在是想不到哪出的问题请老大们帮我决绝下

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 9479
活跃值: (757)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
检查堆栈平衡
2012-7-3 11:00
0
雪    币: 111
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
转http://bbs.pediy.com/showthread.php?p=985028

如果你写过游戏外挂,便会发现经常会遇到2个比较大的问题,一是找游戏关键的call ,二是找这些call 的参数。。。这篇文章我主要是说如何获取游戏call的参数。。

  一般的方法是用ce od 逆向查找。。直到查到游戏基址,然而有些时候你会发现想找到这个数据太难了,而且有时候会发现逆向查找的时候会逆向到一个线程上面,于是你只能下条件断点。。。然而你想再往上跟的时候,你会发现很难再向上了。。。。。虽然数据的基址+便宜肯定能找到的但是可能发费你大量的时间与精力
   下面给大家说一种在某些情况下可以不找游戏基址+便宜照样找出游戏call 的参数
    下面方法是用hook 游戏相关函数从而让游戏自动把参数交出来
    我以加血加蓝给为列吧QUOTE]

我找到了给人物加血加蓝的call

008C19ED    C78424 38030000>mov dword ptr ss:[esp+0x338],0x8
008C19F8    E8 C3D5C2FF     call client.004EEFC0
008C19FD    83C4 0C         add esp,0xC
008C1A00    8D8C24 7C010000 lea ecx,dword ptr ss:[esp+0x17C]
008C1A07    E8 5436B4FF     call client.00405060
008C1A0C    E9 D9030000     jmp client.008C1DEA

//加血加蓝的call
008C1A11    56              push esi                                 ; esi=11F9C470   //参数一
008C1A12    8BCB            mov ecx,ebx                    ; ecx=02A45FB0  // ecx 的值
008C1A14 E8 37A9FFFF      call client.008BC350008C1A19
008C1A19   E9 CC030000     jmp client.008C1DEA
008C1A1E    8B96 E8000000   mov edx,dword ptr ds:[esi+0xE8]
008C1A24    57              push edi
008C1A25    52              push edx
008C1A26    6A 10           push 0x10
008C1A28    B9 B0A7DF00     mov ecx,client.00DFA7B0
008C1A2D    E8 0E0BDFFF     call client.006B2540

上面就是我找到的加血加蓝的call
  push esi                                 
  mov ecx,ebx
  call client.008BC350

这个就是关键的call 这里我主要讲解如何获取call 的参数  大家能看到 参数就2个 一个是ecx  的值 一个是 esi的值................
然而当我查找esi 的数据 来源的时候发现这个数据很难找到。。、、、(不排除自己的技术问题)
于是我就想自己写call 把这个函数hook 了后。。让游戏自动把参数给我送来怎么样
   于是自己写了个函数。。。

   function lanje_xue():bool;stdcall ;// 拦截加血 加蓝的参数
begin

asm
cmp eax,$1e  //加血
jnz @@1
mov c_xue,esi   //c_xue  是加血的时候 push 的参数
mov c_ecx,ecx   //ecx 的参数
@@1:
cmp eax,$1f   //加蓝
jnz @@2
mov c_lan,esi     //c_lan  就是当加蓝的时候push 的参数
mov c_ecx,ecx   //ecx 的参数
@@2:
mov j,$008BC350
call j
jmp jmpcode_xue  ///这个是跳回到原来call  的下一句的地址  jmpcode_xue=$008C1DEA

end;

end;

由于本来想  接hook 掉那个call  但是调试的时候发现有点问题。。所以采用的是jmp 实现的

上面就是我拦截游戏参数的函数
下面我就说一下怎么把原来的函数hook 掉

由于我只是讲解原理。。。所以有些函数的参数是全局变量就没给定义了

首先现讲解一下 jmp 和 call  的指令如何写

procedure  hook
var
addr:integer;
old_byte1:string;
begin
//取得  lanje_xue 的地址
   asm
   lea eax,lanje_xue
   mov addr,eax
  end;
//保持 '008C1A14' 的地址  这里用了大漠插件。。由于有内存方面的功能用起来也方便我就不改了。。。
  old_byte1:=dm.ReadData(self.Handle,'008C1A14',10);//   old_byte1:用来保持原来这个地址数据以便恢复
  addr:=addr-$008C1A14-5;  //这个就是上面图片中的公式( 目标地址-原来地址-5)就是写入的值

dm.WriteData(self.Handle,'008C1A14','E9 '); //   向【'008C1A14'】写入   E9 ----->jmp
  dm.WriteInt(self.Handle,'008C1A15',0,addr) ;  / 向【'008C1A15'】写入跳转的地址 end;

///////////////////////////////////////////////

const
xue_call:integer=$008BC350;  //加血加蓝的call 地址;
function add_boold():bool;stdcall;//加血的call
begin
asm
push c_xue
mov ecx, c_ecx
call  xue_call
end;
end;
function add_bule():bool;stdcall;//加蓝的call
begin
asm
push c_lan
mov ecx, c_ecx
call  xue_call     ///
end;
end;

于是我的函数就写完了。。。当把程序附加大游戏中的时候。。。当这个游戏call 调用的时候便会自动把参数放入到你自己定义的变量中去。。。。关键要保证这个call 执行过
因此这种方法适用于放到线程的call 里面程序运行的时候就自动截取数据
还有一种是容易触发的call 中比如这个列子中的call,由于可以把加血的放到快捷栏里面所以当游戏启动时候发送一个模拟按键消息便会自动触发这个call 所以这种方法还是可用的。。
2012-7-3 11:53
0
游客
登录 | 注册 方可回帖
返回
//