谁有调用游戏主线程调用callCALL插件.发一个上来

6251人阅读
win32编程(35)
杂谈(38)
一般情况下 按照以下处理方式就可以避免了
例如 龙OL &这样处理就不会被检测到非法调用call了
在游戏地址空间找到一处空位置 &写入如下机器码
& & &58 & & & & & & & & pop eax & & & & & & & & & & & & & & & & &
; &弹出返回地址
004014DA & & &A3 E8144000 & & & &mov dword ptr ds:[4014E8],eax & & & ; &保存返回地址
004014DF & & &58 & & & & & & & & pop eax & & & & & & & & & & & & & & & & &
; &弹出选怪call地址
& & &FFD0 & & & & & & & call eax & & & & & & & & & & & & & & & &
; 在游戏空间内调用了选怪call
& &- FF25 E8144000 & & &jmp dword ptr ds:[4014E8] & & & & & ; &返回调用处
& & &90 & & & & & & & & nop & & & & & & & & & & & & & & & & & & &
; &下面4个字节用来保存返回地址
& & &90 & & & & & & & & nop
004014EA & & &90 & & & & & & & & nop
004014EB & & &90 & & & & & & & & nop
004014EC & & &90 & & & & & & & & nop
004014ED & & &90 & & & & & & & & nop
004014EE & & &90 & & & & & & & & nop
下来我们看看 怎么调用他 () & & &
& & &90 & & & & & & & & nop
& & &C2 0400 & & & & & &ret 4 & & & & & & & & & & & & & & & & & &; &比如这里是有一个参数的选怪call & &所以是 ret 4
& & &90 & & & & & & & & nop
push 1 & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &;压入选怪参数&
push Spy4Win. & & & & & & & & & &; 压入选怪call地址 &比如这个地址是选怪call
mov eax,Spy4Win. & & & & & & & & ; &这里是我们在exe地址空间内找到的可用地址
这样 到选怪call以后 &调用选怪call的就是游戏自己了&
另外还有一种检测方式就是游戏检测是否是游戏窗口主线程在调用游戏的call
这种方式就通过hook游戏窗口过程 &也就是窗口子类化
子类化以后通过发送自定义消息给游戏窗口来实现在游戏窗口主线程中调用游戏call
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:416556次
积分:4793
积分:4793
排名:第4703名
原创:118篇
转载:17篇
评论:63条
(2)(1)(1)(2)(1)(3)(5)(1)(1)(4)(1)(1)(3)(3)(1)(5)(2)(4)(1)(3)(2)(4)(3)(1)(3)(17)(10)(3)(2)(19)(12)(2)(1)(2)(5)(2)【讨论】有谁研究过64位游戏CALL如何调用,一起来研究下 - 看雪安全论坛
『软件调试逆向』 [综合性论坛]本版讨论的主题包括:调试逆向、系统底层、商业保护、虚拟机保护、.NET平台等安全相关的话题。
注册日期: May 2014
现金: 21 Kx
获感谢文章数:0获会员感谢数:0
, 19:26:52
【讨论】有谁研究过64位游戏CALL如何调用,一起来研究下
游戏是剑网3,系统Win7&64位,游戏当然也是64位,用x64dbg找到喊话CALL,下在是这个CALL的原型:&
FC74E&|&4C&63&C8&&&&&&&&&&&&&&&&&|&movsxd&r9,rax&&&&&&&&&&&&&&&&&&&&&&&&&&&|&;eax=8&喊话内容长度+2&
FC751&|&48&8D&44&24&40&&&&&&&&&&&|&lea&rax,qword&ptr&ss:[rsp+40]&&&&&&&&&&&|&;喊话内容&
FC756&|&48&8D&0D&C3&D1&1D&00&&&&&|&lea&rcx,qword&ptr&ds:[13F4D9920]&&&&&&&&|&
FC75D&|&4C&8B&C5&&&&&&&&&&&&&&&&&|&mov&r8,rbp&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&|&;rbp=2632AED8&//这个值要找来源&
FC760&|&8B&D3&&&&&&&&&&&&&&&&&&&&|&mov&edx,ebx&&&&&&&&&&&&&&&&&&&&&&&&&&&&&|&;ebx=1&频道&
FC762&|&48&89&44&24&20&&&&&&&&&&&|&mov&qword&ptr&ss:[rsp+20],rax&&&&&&&&&&&|&
FC767&|&E8&84&76&E7&FF&&&&&&&&&&&|&call&jx3clientx64.13F173DF0&&&&&&&&&&&&&|&;喊话CALL&
VC++用代码调用(64位&):&
void&RoleTalk()&
&&&&__try&
&&&&&&&&__asm&
&&&&&&&&{&&&&&&&&&&&&&
&&&&&&&&&&&&mov&r9,0x8&//0x8为喊话长度+2&
&&&&&&&&&&&&lea&rax,qword&ptr&ds:[0x]&//0x为喊话内容地址&&&&&&&&&
&&&&&&&&&&&&lea&rcx,qword&ptr&ds:[0x13F4D9920]&&&&&&&&&&&&&
&&&&&&&&&&&&mov&r8,0x2632AED8&//这个值会变化,暂时没去找来源&
&&&&&&&&&&&&mov&edx,0x1&//0x1为频道&
&&&&&&&&&&&&mov&rbx,0x13F173DF0&
&&&&&&&&&&&&call&rbx&&&&&&&&&&&&&
&&&&&&&&}&&&&&
&&&&__except(1)&
&&&&&&&&AfxMessageBox(L&11111&);&&&&&
经过VS附加游戏调试DLL,问题出在CALL的调用,不是调用出异常就是调用没反应,不知道谁研究过。&
注:mov&rbx,0x13F173DF0&
&&&&call&rbx&
这个地方试过改为mov&r9,0x13F173DF0&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&call&r9&
但是还是无效
注册日期: Mar 2011
现金: 60 Kx
获感谢文章数:1获会员感谢数:1
, 20:21:55
我想问下x64下怎么使用-__asm&内联汇编
注册日期: Nov 2005
现金: 93 Kx
获感谢文章数:0获会员感谢数:0
, 20:49:11
x64的call只能是near&call。我估计你这个call的范围是far&call,所以出错。你可以研究一下x64的far&call
还有R8一般是第一个参数,“//这个值会变化,暂时没去找来源”估计也不太可行吧。。。
注册日期: May 2014
现金: 21 Kx
获感谢文章数:0获会员感谢数:0
, 21:46:30
mov&rbx,0x13F173DF0&
call&far&rbx&
mov&rbx,0x13F173DF0&
call&near&rbx&
都试了,没用。
“这个值会变化,暂时没去找来源”,游戏不关不会变,重新上这个值才会变
注册日期: Feb 2016
现金: 51 Kx
获感谢文章数:0获会员感谢数:0
, 09:57:19
路过,学习一下!!!!!!
注册日期: Nov 2005
现金: 93 Kx
获感谢文章数:0获会员感谢数:0
, 10:10:55
最初由 东阳不列山发布
mov&rbx,0x13F173DF0&
call&far&rbx&
mov&rbx,0x13F173DF0&
call&near&rbx&
都试了,没用。
“这个值会变化,暂时没去找来源”,游戏不关不会变,重新上这个值才会变
不是让你写call&far啊。。x64下没有call&far了,要自己实现。
/showthread.php?t=207393
这个也许对你有帮助
注册日期: Aug 2010
现金: 114 Kx
获感谢文章数:0获会员感谢数:0
, 17:08:40
参数都变了&写CALL还有什么用?&
你OD断了之后获取到参数&再编译&然后再写再注入测试吗?
您不可以发表主题
您不可以回复帖子
您不可以上传附件
您不可以编辑自己的帖子
论坛论坛启用
用户控制面板
会员在线状态
『看雪众测/众包』
『Android 安全』
『iOS安全』
『求助问答』
『经典问答』
『资料导航』
『软件调试逆向』
『编程技术』
『加壳与脱壳』
『资源下载』
『WEB安全』
『漏洞分析』
『密码学』
『外文翻译』
『CrackMe&ReverseMe』
『招聘专区』
『职业生涯』
『15PB培训』
『麦洛克菲培训』
『茶余饭后』
『安全资讯』
『论坛活动』
6)PEDIY Crackme竞赛2009
7)看雪十周年专版
8)腾讯公司2010软件安全竞赛
9)2011 Exploit Me竞赛
『图书项目版』
《加密与解密(第三版)》
《C++反汇编与逆向分析技术揭秘》
《Android软件安全与逆向分析》
『论坛版务』
所有时间均为北京时间, 现在的时间是 .
&&& 看雪学院()
| 提供带宽资源
|&微信公众帐号:找游戏CALL
先用CE找到鼠标点击点的坐标的内存地址 再查找what
write...,得到一个代码地址,根据这个代码地址,调用OD,在该地址下断,断下后几个ctrl+f9就能到达我们要找的走路CALL地址
OD,bp send,鼠标选怪,断下后,几个ctrl+f9,找一个鼠标点击的函数
类似TAB的CALL,push eax ,call
XXXXX,进入到XXXXXX地址,这里就是鼠标点击的函数头,在这里下断,你走路吧,步步过,一直跟到函数尾,就能找到我们要找的走路CALL
1、首先要明白你要找什么?先举例,比如你开枪射击,你扣动扳机后,枪会产生N个动作:撞针会后退、前进、子弹的火药要燃烧。。。。。。这些都不要管它。
&&你扣动扳机的那个动作,就相当于你要找的关键CALL。
&&这个概念一定要明确。下断要找准地方。比如上面的例子,你在撞针撞击子弹的地方下断,断是会断下,但断错了地方。个人觉得,一直向上找,直到你F2下断后,不做游戏动作也会被断下为止。
2、多练、多想,再来一点点的运气,才能找到关键CALL。不然武林诛仙不玩了,再玩其它游戏就菜了。
关键Call的找法一直都是个不大不小让人头痛的问题,需要大量的汇编代码分析,还需要很多测试工作,当然还有一种变态的方法,那就是用OD断下后,把前前后后所有的call都测试一边,也能找到关键call,不过面对大量的call和无数次挂游戏,恐怕这个方法只能在理论上实现了。
那么是否有既不需要看大量的汇编代码,有能够经过有限的几个测试找到关键call的方法呢,下面我就把一种另类的找法送给和我一样的懒人和新手吧。
& 以50打坐和普通攻击的call查找为例。
& 启动OD加载50,进入游戏后,和传统方法一样,bp
send下断,然后等待游戏断一次,按F9直到游戏正常运行(这里等待断一次主要是为了去掉游戏定时与服务器信息和其它信息的干扰),然后马上回到游戏,按0(默认0是打坐),游戏被断下,连续按4次ctrl+F9(通常游戏的前3层都是信息函数等东西,所以直接到第4层啦),然后按F8,此时按alt+k打开堆栈窗口,如下:
&& & 函数例程 /
&&&调用来自&
&004542DB&
&ElementC.&
&ElementC.
&0049959B&
&ElementC.&
&ElementC.
ElementC.0049959B&
&00540E87&
&ElementC.00540ED0&
&ElementC.00540E82
1、有很多行,不过我们只需要关系第一行就可以了,其它的不用管,记录下,如果已经知道打坐的call地址,一看就知道我们已经找到了,不过现在我们架设是第一次找不知道关键call的地址,所以把记录下来,继续ctrl+F9,F8再进入一层,仍然是按alt+k,查看堆栈窗口,仍然只记录第一行得到,还是ctrl+F9,F8,alt+k再记录一个0049959B,一般来说游戏的call多在4-6层中,很少有再深的,而且还有另外的判断方法,因为单你再使用ctrl+F9进入下一层时,出现的call就不是单纯的地址了,而是类似call
[xxxx+xxx]这样的形式,那么也就说明走过了,所以记录3层就够了。
2、第一步完成了,此时按F9让游戏继续,又断下来了,不过这个时候不用急着按ctrl+f9进入,直接按一个alt+k看看,
&& & 函数例程 /
&&&调用来自&
035CFEC8& &&
&00568A60&
&WS2_32.send&
&ElementC.00568A5A
035CFECC& &&
&&&Socket =
035CFED0& &&
&0C622008&
035CFED4& &&
&0000000D&
&&&DataSize = D
035CFED8& &&
&&&Flags =
035CFEE8& &&
&0056DE37&
ElementC.00568A60&
ElementC.0056DE34
第一行显示的是
ws2_32.send,原来是发送函数,所以不用再进入了,看一下CPU窗口的标题,显示的是CPU-t线程&
&0000000xxxx,记一下那个xxxx的数字,直接按F9运行游戏,又断下来了,此时看一下CPU窗口的标题,如果xxxx数字一样,说明还是发送函数一类的东西不用进入(你可以都打开堆栈窗口看看验证下),继续按f9运行游戏,如果游戏断下来了而且不是发送函数一类的就都进入看一下,和上面的一样记录下地址,最后直到不再连续断,删除断点,回到游戏,人物已经进入打坐状态,一般简单的操作只会有1到2个需要跟进的断,而复杂的操作可能多一些,不过如果你从简单的call入手,注意观察,复杂操作的call还可以通过总结再去除掉很多无关的断。
3、第三步,好了只有三个地址,而且都没有参数,直接调用测试吧,运气不错第一个就是了。呵呵,没有分析汇编代码找到了打坐的call
顺便找找取消打坐的call吧,仍然bp
send,然后等游戏断一次,按F9直到游戏正常,然后进入游戏,用鼠标在其它地方点一下,游戏断了下来,4次ctrl+f9后按f8,alt+k,直接记录第一行,
&& & 函数例程 /
&&&调用来自&
0F19FD88& &&
&00466D4C&
&ElementC.&
&ElementC.00466D47
0F19FE2C& &&
&00455D8E&
&ElementC.&
&ElementC.00455D89
0F19FE30& &&
&0F19FE7C&
0F19FE38& &&
ElementC.00455D8E&
有了经验就不再继续了,直接测试,果然就是取消打坐。
顺便说一下,注意上面的
0F19FE2C& &&
&00455D8E&
&ElementC.&
&ElementC.00455D89
0F19FE30& &&
&0F19FE7C&
这两行,如果是有参数的call,就是这样的形态,这里也就是call 含有一个参数。
普通攻击call的找法,和上面的类似,先选择一个怪,然后切换到OD,bp
send,等游戏断一次,按F9直到恢复,然后按数字1(普通攻击默认在1),游戏断下,然后同样的方法,你可以找到
&& & 函数例程 /
&&&调用来自&
0F19FDCC& &&
&00475F71&
&ElementC.0059DC30&
&ElementC.00475F6C
0F19FDEC& &&
&00475B8E&
&ElementC.00475CE0&
&ElementC.00475B89
0F19FDF0& &&
&10B2A500&
0F19FE20& &&
&004639EC&
ElementC.00475B8E&
0F19FE98& &&
ElementC.004639EC&
ElementC.0043A56F
还是在第一行看到了吗?0059DC30,直接就找到了普通攻击的call。带参数的call的找法,和普通攻击的相似,无非就是记录下来的地址可能会多一些,需要测试的也多一些,不过如果你能够对找出来的地址处的汇编代码进行简单的分析,那么也就还可以再排除大部分地址,减少测试量。
这就是利用堆栈进行关键call的另类找法。本来打算弄点图上去的,不过因为我很懒,也就算了,大家多动手测试下,相信很快就能够掌握一些东西,然后我们多交流共同提高。
比如找怪的CALL,BP
SEND,等游戏断了一下,然后F9恢复运行,切换到游戏,用鼠标点任何一个怪,OD断下来然后按照上面的方法,马上就可以在堆栈中找到.
ElementC.在第一行,而且这行的下面就在堆栈中显示这个call的参数,类似Arg1=XXXXXXXX
Arg2=XXXXXXXX
眼睛尖的马上就会发现,其中的一个参数不就是怪的ID嘛,另外一个就是相关的偏移,马上就可以确定这个就是call了.
拣物品和使用物品等也是类似的,全都是在第一行出现,其实原理很简单,因为是在堆栈里面,必须满足堆栈的处理原则,所以么先入后出,后入先出,呵呵.如果是一个新游戏可能一开始会觉得不太好弄,不过因为大多数程序员都有共同的毛病就是只要功能类似肯定就会选择对某一类动作调用共同的函数进行操作,只是传入的参数不同,所以看多了,很快就可以对那个才识我们需要的真正的call地址作出判断,有时候还有额外的收获,比如说查找使用技能的call.由于距离怪还有一定的距离.所以要先移动.然后才打.于是会断下很多,其中大部分是w32_send,这个直接判断标题栏就剔除了.而剩下的断中,就包含移动.和使用技能的.注意观察堆栈中调用的参数,只用看第一个调用,很意外的还顺便把移动的call找到了。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。查看: 12316|回复: 19
CALL是如何炼成的~~
阅读权限20
遇到一个CALL应该如何写?
这个是写一个内挂不可避免的问题.刚初学的朋友可能会不知道如何入手.想起刚学这方面的时候,绕过很多弯路,现在把一些经验写出来给大家参考参考吧,不是很高深的东西,但我觉得对某些人很有帮助.
CALL是什么?
CALL是汇编中的一个指令,CPU执行这条指令会执行2个动作 一:压入EIP入栈 二:跳转到后面的地址.&&跟RETN指令配合就实现了汇编中子程序的作用,通常我们常说的写CALL就是 调用游戏中已经存在的功能子程序.
viod myadd (int a, int b)
int c=a+b;
这是一个简单的子程序,当我们用程序语言调用那么就是&&myadd(5,4);
而在汇编里则是
call myadd
编译好的程序不会存在什么函数变量和子程序. 只有1和0 . 所以编译器会给myadd 分配一个地址.在反汇编里就是&&
call ********&&
CALL ******* 并不单单就是子程序的调用,他还可以调用 函数 API.
如函数&&send
在汇编里调用就是
push flags
push socket
参数在反汇编里表现形式.
在汇编或反汇编里参数都是压入堆栈来供CALL调用的.而CALL以[ESP+*]的形式读取参数.
viod myadd(int a,int b)
myadd(4,5);
在反汇编参数 4 和参数 5 在反汇编里的实现形式是
call ********
写CALL的时候有时候会给EAX赋值而有些时候却要给ECX赋值,如何知道要给某个寄存器赋值呢?
一般学过智辅方面的知识的朋友大概都是 汇编指令 mov 的 实现的功能.&&
mov 操作数1 操作数2
将操作数2 的值放入到操作数1 里.
mov eax,ebx
将 ebx的值放入到eax里
寄存器的作用大家都知道是用来存放数据供CPU调用.所以寄存器本身是空的.
在调用一个CALL的时候 所有的寄存器都是空的或者是调用上一个CALL遗留下来的残留数据.
当这个CALL需要一个200的值,通过ebx 储存.
那么我们调用CALL而不给ebx赋值 ,调用的时候CALL还是会读取当前ebx的值,而这个时候寄存器的值则是0或者上一个CALL调用后残留数据.而不是CALL想要的200数据.
调用CALL之所以需要寄存器,是因为CALL通过调用相关的寄存器获取到特定的数值.
而CALL调用寄存器的语句常用则有&&PUSH&&寄存器,& & mov 寄存器,寄存器&&lea 寄存器,寄存器 等等.
这里我们要提一下寄存器环境保护,众所周知,CPU的寄存器只有一个EAX ,EBX,ECX,EDX......&&如果一个寄存器EAX里存放着一些资料供后面使用,但当前CALL却需要EAX储存一些临时的数值这个时候要怎么办?
这个时候我们则需要把寄存器EAX里的数值保存到一个地方,然后把EAX给CALL使用 用完后在把那个值放
回到寄存器EAX里去.&&这个过程则是寄存器的环境保护. 在反汇编里保存寄存器的地方就是堆栈.
当你在一个子程序头部看到一些 push eax&&而又在尾部看到 pop eax 的时候 这里的eax 就是寄存器数值保护,push eax&&则是保存eax储存的数值,&&pop eax则是放回去.
堆栈如何平衡?
如何理解堆栈的平衡呢?当push 压入了一个堆栈, esp的值就会-4 来存放数值. CALL完后就需要+4来把esp的值恢复回去.如何知道一个CALL是否需要堆栈平衡呢?看CALL内部的尾部就可以了, 如果CALL尾部有RETN **&&或者add esp,*之类的,则是CALL自动平衡了一些堆栈,至于恢复了多少则要看指令后面带的数字.
如何写一个CALL?
其实写CALL很简单,先处理堆栈和寄存器,在处理堆栈和寄存器中的数值,最后处理堆栈平衡就可以了,
写CALL之前你要明白几个东西.
viod myadd(int a,int b)
myadd(4,5);&&//程序的调用代码
在反汇编里程序的调用代码为
call 5e0000&&//假设 CALL的地址为5e0000
你会如何写这个CALL呢?
写CALL最重要的一点就是把CALL需要的寄存器参数写出来.
如 这个CALL则需要2个参数.
我们的调用代码则可以这样写
call 5e0000
而不需要把5放入eax里 把4放入ebx里.
为何?因为CALL并没有读取eax 和ebx里的数据.
这里我们写的代码和反汇编里的代码有什么共同点呢?2者之间有和关联?
其实共同点只有三个,那就是调用了同一个地址和提供了CALL所需要的参数,还有处理了堆栈的平衡
而两者之间是没有任何关联的.
有些人认为写CALL一定要按照游戏调用CALL的代码来写.其实,不是的.游戏调用CALL的代码只是用来参考的.我们只需要写出CALL所需要的寄存器即可.&&这个是很多人存在的一个误区.只要你能理解这个概念那么CALL就会变的简单明了.
所以上面我们没有按照调用代码把数值放入寄存器里而是直接压入堆栈供CALL调用.
所以说直接靠一个CALL地址(并非调用代码地址),分析代码,来写出调用代码,也并不是不可能的事情,我也可以做到一些不是很复杂的CALL代码分析,当然如果太复杂的话那就是找不自在.
记住~游戏中调用CALL的代码只是一个参考的依据.
寄存器中的值.
我认为寄存器中的值可以分为3种,
一是常量 也就是固定的值,比如说push 23123,push 0 等等
二是基址 这类一般是控件或者类的基址,或者游戏的基址,人物的基址,一般由ECX储存
三是可以自定义的值 如 坐标, 喊话频道, 喊话内容地址等等.这些都是可以自定义的.
寄存器eax值的跟踪!
在调用约定里 所有CALL的返回值都是靠EAX返回的,如果EAX放不下就放在EDX里。如果返回的结果是文本类型的话就会返回一个指针地址。在游戏里,一般的功能CALL返回值很少有。
int myadd(int a, int b)
int c=a+b;
在反汇编的表现形式大概就是
push ebp& && && && && && && && &//寄存器环境保护
mov&&ebp,esp& && && && &&&//将堆栈指针的值传给EBP用于开辟临时变量
sub esp,4& && && && && && &//开辟一个临时空间 也就是我们定义的临时变量C
mov [esp-4],0& && && && &//将 c 初始化 也就是C=0 尽管我们没有写不过编译器会自动完成
mov eax,a& && && && && & //将A放入寄存器EAX里&&
add eax,b& && && && &&&//将EAX加上B
mov [esp-4],eax& && && && &&&// 将计算结果保存到临时变量C
mov eax,[esp-4]& & //将保存结果的变量C传递到EAX
mov esp,ebp& && &&&//将堆栈指针恢复到调用CALL之前。
pop ebp& && && && &&&//将寄存器保存的值取出来。
这个就是一个简单加法子程序的运行过程。所以很多时候我们跟踪一下自己写的程序,看看机器是如何运行你的代码的,这个是一件很有趣的事情,也会增加你对编程和汇编的了解。这里的反汇编代码是我手动写的可能和真正的有误差,但大概的过程是应该没有错的。
所以很多人在跟踪寄存器EAX的时候往往会放过挨着的CALL指令,直接找上面的汇编代码。要看看EAX是否是一个CALL的返回值其实很简单,看看运行CALL指令后EAX的值是否有变化就可以了。
CALL参数的构造。
CALL的有些参数需要自己定义,比如说常见的有,坐标,喊话频道,怪物ID等等。这些就不说了,还有一些不太明显的。比如说喊话内容。
游戏里的喊话内容是以文本指针地址存放的。有些朋友就把这个指针的基址找出来了。其实没有必要,因为对于CALL来说,他需要的只是一个喊话内容而已。而不是需要游戏里的喊话指针地址。
所以写一个CALL重要的是知道CALL需要什么,只要你能知道他需要什么你也就能够调用它了,就像机器一样你需要提供给它需要的动力才能启动。
游戏调用CALL时,值的内存传递方式。
除了堆栈和寄存器以外,游戏可能会用其他的方法传递数值,最常见的就是内存。写过游戏聊天CALL的朋友可能会遇到过频道信息放在内存里供CALL调用的。一般是在喊话CALL内部调用,用CE找到频道信息的地址吧。 当然这里既然在CALL内部调用了频道在内存里的值,也可以通过频道信息来找到喊话CALL的地址。
================================================
CALL参数的传递!
总所周知,寄存器是用来传递参数的,但本身并没有值,他只是一个存放值的空间,存放用来传递的参数.CPU执行一个CALL的时候,我们可以把几个寄存器看成是一个空的空间.那么我们就可以理解,并不是所有的寄存器都会拿来存放数据的.看CALL需要传递几个参数了.&&
寄存器除了传递参数外,另外一个功能就是存放临时数据,如何判断一个CALL调用了那么寄存器的参数.你要会判断这个寄存器是用来传递的还是用来临时存放数据的.
在分析CALL之前我们应该把寄存器都看成空的 除了ESP EIP2个特殊的寄存器外.
当你发现 mov eax,ebx的时候 EBX是否是CALL要调用的寄存器呢?我觉得这个要看寄存器是否有值(在假设寄存器都为空的情况下).&&如果mov eax,ebx 前面没有给EBX赋值的指令的话那么 这个ebx就是CALL需要调用的寄存器.&&也就是用来传递参数的寄存器. 那么EAX呢?
这里的EAX就是一个临时存放的寄存器.用来存放ebx里的数据.
如果mov eax,ebx&&指令前面有给ebx赋值的话,&&比如说mov ebx,123123&&那么ebx也可以排除了 因为他用来存放临时数据了 .并不是用来传递数据的.
当然,在调试的情况下,调用一个CALL之前寄存器不可能为空,大部分都有之前CALL遗留下来的残留数据.
还有一种是堆栈传递.这个就不相信说了,只要看下调用CALL前的PUSH指令就能很好的得到.
寄存器esp,ebp值的跟踪!
上面说到 堆栈参数的传递,当参数压入到堆栈CALL的内部是如何读取的呢?
很多朋友都看见过这样的寻址指令 mov ebx,[esp+1c]&&这个时候很多朋友都去寻找赋值 ESP 相关的指令去了,但找了半天都没找到.其实这里直接指向了堆栈. ESP是一个特殊的寄存器,他永远指向了堆栈顶部.
所以一般轻易不会去变动这个值.&&当 CPU 执行 PUSH指令时 ,ESP就会-4 然后把数据存放到当前ESP的地址里.这个时候如果读取刚刚压入的参数 就是 mov ,eax,[esp]&&这样堆栈顶部的数据就会被读取.
但是这个时候又压入一个数据呢?&&压入的时候ESP会-4&&那么 指向刚刚那个参数就是 mov ebx,[esp+4]
如果压入了5个 要指向第一个参数 就是 [esp+10]&&没错就是10&&一个堆栈是4字节 4个就是16字节 16在16进制里就是10
这里要说明的一下是 CALL指令也会压入一个数值.所以
CALL ********
在CALL内部指向 EAX 就是 [ESP+4]&&这里其实压入了2个堆栈 ,一个是PUSH EAX&&还有一个是CALL.
临时参数的表达方式是 [ebp-*]&&一般是在CALL头部把ESP的数值赋值到EBP&&那么 EBP永远指向CALL头部时的堆栈指针,对于下面新增的堆栈就是 以减法表示 因为 压入一个堆栈ESP就会-4&&.故[EBP-*]在反汇编里代表临时变量.
游戏CALL分析的四种常用方法!
一般来说常见的有
发包函数下段返回:这个是比较常见的方法,代表作是完美国际的游戏.常用发包函数有send&&和 WSASend 按CTRL+F9就可以返回到调用功能代码处.
功能信息跟踪:当断下发包函数返回无法找到功能CALL的话那么就需要用到这种方法了,也是比较常见的方法.比如说,自动寻路的目标坐标点. 喊话功能的喊话内容存放地址,攻击怪物的怪物ID信息,等等的一切都是.即使能靠下发包断点返回就能找到游戏功能CALL的游戏里 有些功能也需要用这种方法跟踪 最常见的是自动寻路和TAB 选怪功能.
发包BUF区下内存写入:我没用过这种方法,是听群里人说的,他在天龙里用过.断封包函数,然后在封包临时存放地址下内存写入.然后返回即可.
游戏结构分析:比较常见的是完美国际的和热血江湖,其他的也见过一些,首先找到一个CALL的地址,然后返回到他的结构点,一般是游戏的检测玩家动作的函数层, 接收到后然后对比执行相关CALL这里几乎能找到所有的动作,不过因为是最高层所以分析的东西比较多.
当然了,可能还有其他的方法,比如说下鼠标点击函数等等.
寄存器值的跟踪与分析!
有时候有的参数会经常变化 所以需要找到他存放的基址才能获取每次变化的值.这个时候就要对参数进行跟踪找到他的基址.一般是用CE 或者用OD分析代码取到.
对于这类值的跟踪我建议使用CE.最后说明一下,基址的公式并不只有一种,用最短的那个公式即可
如果某些需要用OD来跟踪的话,最好学下汇编的基础.
寄存器值的来源!
很多参数都是有来源的,比如说,喊话内容 来自于 你输入的喊话框地址,&&压入的频道信息来自于你选择的频道,买卖的数量来自你选择的买卖窗口, 坐标的值来自于你点击地图生成的反馈,等等的一切都是.
看似很简单的东西,大部分人都明白.其实还有一些参数也是由一些
写CALL时常见的错误!
一般写CALL的时候常见的2种错误是,一个是无法读取一个内存地址,或者是无法写入一个内存地址,这个代码的地址一般在CALL的内部.一般由寄存器的参数赋值错误或未对需要的寄存器赋值造成的.
还有一种常见的是堆栈不平衡所造成的错误.
这2种是比较常见的错误,也非常好解决,只要对照一下正确的寄存器参数就可以了
找CALL的思路!
找CALL时,思路很重要,如果一个打坐的CALL无法用bp send返回找到, 那么该如何找呢?思路就是打坐的状态~游戏里 人物的每个动作必定有些内存值会不一样.也许这些值代表人物是在打坐状态,那么我们跟踪这个
值就很容易找到CALL了.或者说征途的买卖功能, 他的游戏是这样实现买卖的首先打开买卖窗口是不会发包
的,最后会弹出一个确认框,这个时候点确定便会发一个买卖封包.CALL内部压入了一个确认框的基址.
如果你找到这个最后确认的CALL那么之前的窗口如何寻找呢? 我觉得既然是买卖窗口最后产生的确认框地址,我们也可以通过这个地址来寻找到买卖的窗口.
一个喊话功能寻找的话并非只有查找访问喊话地址的代码,你也可以查找频道信息,密人信息等聊天有关的.所以依照这个思路,查找怪物ID也可以通过找攻击CALL来寻找.
只要你找对了正确的思路,你便可以通往一条成功的道路.
CALL的本质!
所谓的call,其实本质上来说就是一条汇编指令.只要找到了关键代码的地址,传入适当参数,就可以借用游戏中已有功能来完成内挂的功能。
写CALL其实就2个步骤,第一找到关键代码的地址,第二传入适当的参数。
刚刚逛光海的时候,看到这样一个返汇编原型
004CA355& & C745 E1 0000000&MOV DWORD PTR SS:[EBP-1F],0
004CA35C& & C745 DD 0000000&MOV DWORD PTR SS:[EBP-23],0
004CA363& & C745 D9 0000000&MOV DWORD PTR SS:[EBP-27],0
004CA36A& & C745 D5 0000000&MOV DWORD PTR SS:[EBP-2B],0
004CA371& & 8B4D FC& && &&&MOV ECX,DWORD PTR SS:[EBP-4]& &&&
004CA374& & 894D D5& && &&&MOV DWORD PTR SS:[EBP-2B],ECX
004CA377& & 6A 00& && && & PUSH 0
004CA379& & 8D55 D4& && &&&LEA EDX,DWORD PTR SS:[EBP-2C]
004CA37C& & 52& && && && &&&PUSH EDX
004CA37D& & 8B45 CC& && &&&MOV EAX,DWORD PTR SS:[EBP-34]
004CA380& & 8B48 04& && &&&MOV ECX,DWORD PTR DS:[EAX+4]
004CA383& & E8 F8B90B00& & CALL game.00585D80
004CA388& & 33C0& && && && &XOR EAX,EAX
004CA38A& & 8BE5& && && && &MOV ESP,EBP
004CA38C& & 5D& && && && &&&POP EBP
这里用到的指令不外乎那几种,汇编的初学者都可以正确的说出来。很多人能理解这个指令的功能,却不懂这个指令所代表的含义。
004CA355& & C745 E1 0000000&MOV DWORD PTR SS:[EBP-1F],0
004CA35C& & C745 DD 0000000&MOV DWORD PTR SS:[EBP-23],0
004CA363& & C745 D9 0000000&MOV DWORD PTR SS:[EBP-27],0
004CA36A& & C745 D5 0000000&MOV DWORD PTR SS:[EBP-2B],0
如,如果光看指令的话,谁都知道这个指令是代表 将0 赋值给[ebp-*] 这个地址。但[ebp-*]又代表什么呢?这个其实是一个很简单的指令,相信很多人都知道[ebp-*] 代表临时变量.
很多汇编指令都有一定的含义所在.所以理解这些东西你将会更清楚的从反汇编原型中看到更多的东西出来.
汇编很重要,反汇编对于逆向来说更重要.
写一个CALL我们首先要处理堆栈.这里压入了2个堆栈.也就是说这个子程序有2个参数.
004CA377& & 6A 00& && && & PUSH 0& && && && && && && && && && && && && && && && &'第一个堆栈
004CA379& & 8D55 D4& && &&&LEA EDX,DWORD PTR SS:[EBP-2C]
004CA37C& & 52& && && && &&&PUSH EDX& && && && && && && && && && && && && && && & '第二个堆栈
004CA37D& & 8B45 CC& && &&&MOV EAX,DWORD PTR SS:[EBP-34]
004CA380& & 8B48 04& && &&&MOV ECX,DWORD PTR DS:[EAX+4]
004CA383& & E8 F8B90B00& & CALL game.00585D80
第一个堆栈属于常量不会变化的那种.所以直接写上去就可以了.
第二个是压入了EDX 而EDX 则是 [ebp-2C]&&的地址.也就是说EDX=EBP-2C&&.LEA是传址的命令.
我们知道[ebp-2c] 是一个临时变量,而压入了这个地址其实是充当着一个指针的作用.当然这些因为没有看过反汇编内部所以一切只是猜测.& & 假设[ebp-2c]=1c& &&&
他压入的就是1c5000
push 1c5000
我们如何跟踪这个值呢?
首先ebp的来源是从esp传过来的.而esp 则是不固定是变化的.所以我们这里每次断下来的值不一定是一样的.
我们上面提到 要写一个CALL首先要知道子程序所需要的.这里压入了一个地址,我们可以猜测子程序需要的是一个存放着一定数值的指针地址.
所以我们可以在写CALL的时候模拟出一个来,只要CALL需要的时候能正确指向这个数值就可以了.
堆栈我们先放下一边,我们再来看看寄存器.
004CA371& & 8B4D FC& && &&&MOV ECX,DWORD PTR SS:[EBP-4]& &&&
004CA374& & 894D D5& && &&&MOV DWORD PTR SS:[EBP-2B],ECX
004CA379& & 8D55 D4& && &&&LEA EDX,DWORD PTR SS:[EBP-2C]
004CA37D& & 8B45 CC& && &&&MOV EAX,DWORD PTR SS:[EBP-34]
004CA380& & 8B48 04& && &&&MOV ECX,DWORD PTR DS:[EAX+4]
因为没有CALL内部的反汇编原型,所以下面的分析会存在一些错误.
004CA379& & 8D55 D4& && &&&LEA EDX,DWORD PTR SS:[EBP-2C]
从这些指令上来看,调用CALL的时候分别使用了 ECX EAX EDX.首先EDX可以排除,他被调用时为了压入堆栈的时候临时存放的.当然他可以存放到EBX 或者EAX都可以.
004CA371& & 8B4D FC& && &&&MOV ECX,DWORD PTR SS:[EBP-4]& &&&
004CA380& & 8B48 04& && &&&MOV ECX,DWORD PTR DS:[EAX+4]
这里2个指令都调用了 ECX, 但真正用来存放数据的只是下面那行. 因为在执行第二个指令的时候原有的ECX值被覆盖了.调用CALL的时候只会存在最后一个指令赋值的数据.
004CA371& & 8B4D FC& && &&&MOV ECX,DWORD PTR SS:[EBP-4]& &&&
004CA374& & 894D D5& && &&&MOV DWORD PTR SS:[EBP-2B],ECX
从这里可以看出,一开始的ECX只是作为一个临时存放的寄存器.赋值给[ebp-2b]的数据还是由[ebp-4]传递过来的.
这2句如果翻译成编程语言也很简单
临时变量y;
临时变量x;
004CA37D& & 8B45 CC& && &&&MOV EAX,DWORD PTR SS:[EBP-34]
004CA380& & 8B48 04& && &&&MOV ECX,DWORD PTR DS:[EAX+4]
这里ECX的来源是EAX&&也就是 [ebp-34] 指针里的值 在加上4 指针地址里的值.&&很绕口,我们可以分开来写.
这里我们要看传入ECX的数据是什么样的类型,如果是数据的话 那么我们可以直接构造,如果是基址一类的话那么就需要跟踪处理了.
假设,[ebp-34]的来源如下
mov ecx,[5c2000]
mov [ebp-34],ecx
MOV EAX,DWORD PTR SS:[EBP-34]
MOV ECX,DWORD PTR DS:[EAX+4]
这样的话我们要如何写这个CALL呢?
其实很简单,[5c2000] 一直到EAX的时候也没变化所以我们这里不需要处理了,然后加4 写成公式就是,[[5c2000]+4]&&写成调用代码就是&&
mov ebx,[5C2000]
mov ecx,[ebx+4]
就是那么简单。这里有人可能要问了,为何不用EAX?
其实答案很简单,就是CALL没有调用EAX里的数据。作为临时存放的地方,我们可以调用任何一个寄存器来作为临时存放的地点。当然一些特殊的寄存器除外。
所以写成ECX也是一样的
mov ecx,[5C2000]
mov ecx,[ecx+4]
反正最后调用的是ECX的值,只要ECX的值正确就可以了。
所以这里CALL调用的寄存器就是 ECX了, 而ECX通常是作为一些基址传递专用的寄存器,所以用ECX传递的数据一般都是基址类的数据,很少直接存放数据。
好了我们来整理一下。
LEA EDX,[EBP-2C]的地址
MOV EAX,[EBP-34]的地址
MOV ECX,[EAX+4]
CALL 00585D80
这个就是调用代码了。
对于这个CALL来说 ,他所需要的参数环境就是 2个堆栈 一个ECX。
004CA371& & 8B4D FC& && &&&MOV ECX,DWORD PTR SS:[EBP-4]&&
004CA374& & 894D D5& && &&&MOV DWORD PTR SS:[EBP-2B],ECX
上面代码中给临时变量赋值为何这里不写?
编过程序的人都知道,临时变量只能在子程序内部使用。其他子程序是无法调用的。所以不会用临时变量来传递CALL所需要的参数。当然全局变量是可以的。
因为只有一段小小的代码,很多东西都没有,所以在很多方面我们都只能猜测.具体的情况请自己分析反汇编代码吧。
帮助很大,对汇编的理解又加深了
我很赞同!
感谢分享,很细致
我很赞同!
支持楼主!!
我很赞同!
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
楼主解释的好清楚&&学习了&&
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
回复一下做个记号慢慢研究CALL是如何炼成的
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
楼主解释的好清楚&&学习了&&
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限40
这个应该是在破解版块吧
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限20
好文章。 强烈支持~
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
汇编代码&&反汇编代码& &云里雾里的
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
本帖最后由 joson 于
10:51 编辑
这个非常感谢楼主。我只能看懂一部分呢,先收藏
这得让我们这些新手少走很多弯路啊。
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
虽然只能看懂一部分,还是很感谢楼主的无私精神,顶,同时搜藏慢慢研究
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限20
大家一起学习
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限20
写的很不错,受益匪浅,刚学破解和汇编
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
虽然看不懂但是赞一个
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
免责声明:吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
( 京ICP备号 | 京公网安备 87号 )
Powered by Discuz!
Comsenz Inc.}

我要回帖

更多关于 游戏主线程调用call 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信