热门标签 | HotTags
当前位置:  开发笔记 > 程序员 > 正文

植物大战僵尸:寻找阳光掉落Call

本次实验内容:本次实验将接触到Call调用这个概念,什么是Call调用?Call相当于你在编程时所编写的函数,而高级语言中的函数最终也是会被编译器转换为汇编格式的Call调用,这些

本次实验内容:本次实验将接触到Call调用这个概念,什么是Call调用? Call相当于你在编程时所编写的函数,而高级语言中的函数最终也是会被编译器转换为汇编格式的Call调用,这些关键Call普遍都会存在各种参数,关于Call的作用,打个比方有些网游外挂可以实现自动寻路,自动吃药,自动打怪,甚至是全屏秒杀,这些功能是通过修改数值也无法做到的,Call就可做到。

其实关键Call就是作者开发过程中写的一个个处理不同事件的独立的处理函数,这些函数包括了各种独立的游戏功能,而我们可以在远程进程中开辟线程,并通过汇编形式动态的调用这些关键Call,从而实现一些变态功能。

本次实验我们将通过查找阳光的掉落的定时器,并通过定时器变量顺藤摸瓜找到生成阳光的关键Call,通过给此Call传递不同参数实现掉落阳光,钻石,零秒通关等,阳光遍历技巧如下:


进入游戏等待阳光出现 -> 当阳光出现后 -> 马上搜索未知初始数值

返回游戏等待时钟发生变化 -> 马上切回CE -> 搜索减少的数值 -> 阳光下落一点搜一点

经过上方步骤反复排查 -> 最终能找到一个值范围(0-700) -> 锁定1即可实现无限掉落


基址与偏移的找法,在文章开头就已经分享了查找的技巧,此处控制阳光掉落公式 [[[006A9F38 + 768] + 5538]]


00413B7C - 83 86 38550000 FF - add dword ptr [esi+00005538],-01 <<

004524F4 - 8B 86 68070000 - mov eax,[esi+00000768] <<

00599F75 - A1 389F6A00 - mov eax,[PlantsVsZombies.exe+2A9F38] <<


我们要找关键Call只需要等待阳光出现,当阳光出现后,CE会检测到一条数据 add dword ptr [esi+00005538],-01 说明此时定时器开始工作了,我们只需要记下这个内存地址00413B7C,然后关闭CE,并打开X64DBG附加到游戏。

打开X64DBG附加到游戏进程,然后按下ctrl+G定位到00413B7C 此时我们需要关注add dword ptr ds:[esi+0x5538],0xFFFFFFFF这条计时器指令下方,就是一个大跳转该跳转跳向了结束,那么我们可以猜测jne 0x413BF1跳过的内容很有可能就是跳过了阳光的生成过程,也就是可能跳过了阳光生成Call。

玩过此游戏的一定知道,游戏屏幕中不止可以掉落出阳光,还可以掉出其他的东西,比如钻石,金钱,奖牌等,那么我们有理由相信,该游戏中调用的Call应该有很多参数传递,比如掉落属性,掉落坐标,掉落类型等,而我们已经找到了阳光计时器每次递减的汇编代码,故猜测调用Call应该就在附近,向下查找发现有很多Call调用,但有一个比较特别的call 0x40CB10,之所以说它特别是因为该Call在调用之前,通过push传递了多了参数,此处很可疑,我们需要具体分析。

此时我们在00413BE4处下断点,然后回到游戏发现每当阳光出现的时候,此处就会断下,那么我们尝试给它传递不同的参数,例如给eax传递一个2,观察效果发现原本应该是出现阳光的地方,现在居然出现了金币。

经过上方的测试,发现我们猜测是合理的,那么这段代码,转换为C语言后应该是这样的:

> push 0 普通掉落 push 2-3 其他掉落方式 push 4 自动收集阳光 push 6 右侧滑出掉落
> eax=2 金钱 eax=3 钻石 eax=4 普通阳光 eax=5 小的阳光 eax=6 大的阳光 eax=8 自动通关神器
sub_00413BE4(push 0= 物品飞出状态,push eax= 掉落物品,push 0x3c,push edi= 对象状态,ecx= 游戏基地址)
{
return 0;
}

到此,我们还没有办法完成外部注入,因为据我观察程序中的edi寄存器与ecx寄存器中的数据是动态的,每次游戏重新运行都会发生变化,如果想要在外部调用这个Call函数,我们需要找到这两个寄存器的基址,或者说找到他们的来源。

我们先来分析第一个地址如何定位,第一个动态地址是EDI寄存器,这个寄存器每次存储一个整数,此处无法直接找基址,我采取的方式是从后向前逆推代码,观察那些指令改写了该寄存器,然后将这些改写寄存器的指令拼凑起来。

这些调用分别是上图中的,赋值1-赋值3外加一个call 0x005AF400,程序中正是通过这种方式计算出动态数据的,我们直接将其提取出来,提取后代码如下:

mov eax,226
call 0x005AF400
mov edi,eax
add edi,64

再来分析第二个,第二个相对于第一个来说就好找许多了,因为它是一个动态地址,如下图我们记下 13DCE000 这个动态地址,然后直接在X64dbg中脱离游戏,这里不能结束游戏,如果结束了下次该地址又会发生变化。

CE直接附加游戏,然后我们来搜索十六进制数据13DCE000然后,你懂的,就是找基址,前面已经找过很多次了。

通过查找访问代码,就能找到一级偏移是768,继续记下00FE4170然后回到CE继续搜索。

到这里基地址出来了,其公式为[6A9EC0+768],从这里也可以看出,这应该是一个通用对象地址。

最后,我们整合并写出以下汇编代码,然后使用注入器注入到游戏测试。

pushad
mov eax,226
call 0x005AF400
mov edi,eax
add edi,64
mov esi,dword ptr ds:[ 006a9ec0 ]
mov esi,dword ptr ds:[ esi + 768 ]
push 0
push 4
push 3c
push edi
mov ecx,esi
call 0x40cb10
popad

发现每当我们点击注入以后,程序中就会多出一个太阳,说明我们的汇编代码没有问题。

为了能够写出自己的外挂,我们需要实现一个简单的注入器,并能够通过远程的方式调用阳光生成Call,使用C语言编写如下代码即可实现注入效果,需要注意调用约定,此处我在Win10上测试没有问题,在Xp系统上会出现异常退出的情况。

#include
#include
void AddSun()
{
__asm{
pushad
mov eax, 226
mov ebx, 0x005AF400
call ebx
mov edi, eax
add edi, 64
mov esi, dword ptr ds : [0x006a9ec0]
mov esi, dword ptr ds : [esi + 0x768]
push 0h
push 0x4
push 0x3c
push edi
mov ecx, esi
mov edx, 0x40cb10
call edx
popad
}
}
void InjectCode(DWORD dwProcId, LPVOID mFunc)
{
HANDLE hProcess,hThread;
LPVOID mFuncAddr,ParamAddr;
DWORD NumberOfByte;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcId);
mFuncAddr = VirtualAllocEx(hProcess, NULL, 128, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, mFuncAddr, mFunc, 128, &NumberOfByte);
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)mFuncAddr, ParamAddr, 0, &NumberOfByte);
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, mFuncAddr, 128, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
}
int main()
{
for (int i = 0; i <10;i++)
InjectCode(3644, AddSun);
}

至此我们的植物大战僵尸关于阳光的分析就到此结束了,其他的比如植物无敌,植物攻击加速等,就留一个作业,大家开动脑筋看能不能自己实现,回顾前面所讲的外挂制作技巧,你是否已经完全理解了呢?如果你能够吃透这些基础知识,那么相信你可以做出植物无敌,攻击加速等其他变态功能,其实逆向就是一个思路的问题,大家要多去思考,多去尝试,相信你会成功的!

文章出处:https://www.cnblogs.com/LyShark/p/15770671.html

版权声明:本博客文章与代码均为学习时整理的笔记,博客中除去明确标注有参考文献的文章,其他文章 [均为原创] 作品,转载请 [添加出处] ,您添加出处是我创作的动力!

如果您恶意转载本人文章并被本人发现,则您的整站文章,将会变为我的原创作品,请相互尊重 !



推荐阅读
  • 本文比较了eBPF和WebAssembly作为云原生VM的特点和应用领域。eBPF作为运行在Linux内核中的轻量级代码执行沙箱,适用于网络或安全相关的任务;而WebAssembly作为图灵完备的语言,在商业应用中具有优势。同时,介绍了WebAssembly在Linux内核中运行的尝试以及基于LLVM的云原生WebAssembly编译器WasmEdge Runtime的案例,展示了WebAssembly作为原生应用程序的潜力。 ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 作为一名正在读EE专业的研一学生,面临选择一门适合未来职业生涯的编程语言的问题。目前只会使用C++和Matlab,但发现C++的使用率逐渐减少。对于选择哪门语言进行深入学习还没有明确方向,希望选择一门使用广泛且不会被短期淘汰的语言。提到了Phyton的简洁性,但担心从零基础学习起会有困难。同时也担心选择了C++后语言会被淘汰,以及编程效率低的问题。 ... [详细]
  • Final关键字的含义及用法详解
    本文详细介绍了Java中final关键字的含义和用法。final关键字可以修饰非抽象类、非抽象类成员方法和变量。final类不能被继承,final类中的方法默认是final的。final方法不能被子类的方法覆盖,但可以被继承。final成员变量表示常量,只能被赋值一次,赋值后值不再改变。文章还讨论了final类和final方法的应用场景,以及使用final方法的两个原因:锁定方法防止修改和提高执行效率。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
author-avatar
火影魂XJ_710
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有