PJ一个小游戏(js逆向)
PJ一个小游戏
Snipaste_2022-07-03_15-48-11.jpg 最近发现一个PC移植安卓的单机小游戏挺有意思(游戏名称ZTcgYmIgYWYgZTggODkgYjIgZTQgYmYgYWUgZTQgYmIgOTkgZTUgYmQgOTU=),于是试着玩了下,发现还不错,就是人物太穷了买不起漂亮的衣服"https://attach.52pojie.cn/forum/202207/03/164201zbdtna2yath0dwat.jpg" file="https://attach.52pojie.cn/forum/202207/03/164201zbdtna2yath0dwat.jpg" class="zoom" onclick="zoom(this, this.src, 0, 0, 0)" width="542" id="aimg_2534308" inpost="1" />
准备阶段
第一步
当然是下载啦,这游戏还算挺大的
image-20220531130855750.png
拖到jadx里看看
哎哟,木有加固。再仔细看看看,我们好像发现了点什么,这是不是Web组件"https://attach.52pojie.cn/forum/202207/03/152500saa6eecnshz6ndcs.png" file="https://attach.52pojie.cn/forum/202207/03/152500saa6eecnshz6ndcs.png" class="zoom" onclick="zoom(this, this.src, 0, 0, 0)" width="964" id="aimg_2534246" inpost="1" />
image-20220531130949321.png
直接去asset目录下看看
哦豁,发现了一些东东
image-20220531131028216.png
解压出来跑跑
一般遇到这种类型的App,都可以直接解压出来尝试一下在本地直接运行一下试试
image-20220531131749902.png
哦豁,报错了,这种情况下我们进入下一步
启动一个http服务
一般遇到这种类型的App,都可以直接解压出来尝试一下在本地跑一下,或者直接就起一个http服务试试。
此时Python同学飘过并留下一行命令:
python3 -m http.server 8088 # 启动一个简单http服务
image-20220531131324410.png
再次访问
浏览器中输入http://127.0.0.1:8088
,然后就可以发现运行起来了
只要浏览器中运行起来,那就可以开搞了"43130257_分析">分析
经过准备阶段后我们发现这其实算是个网页游戏,而且我们连源码都拿到了,那就先去看一下源码吧
我们要什么
首先需要确定我们需要什么,呐做人呢最重要的就是开心咯,怎么开心呢,有钱人的快乐我想象不到,在游戏里做个富翁体验体验嘛好了。所以在这个游戏里也就是这两个
image-20220531132541217.png
搜索一下关键字
知道了我们要什么,那么这时候就可以去源码中搜索一下看看有木有相关内容
image-20220531132710755.png
emmm,还行,结果不多,我们先找找有没有我们需要的信息
image-20220531132814220.png
找到了配置文件,然后我们拿到了我们需要的某些信息,这个现在暂时先留着
找一个切入点
任何分析都要有个切入点才可以,这个app的切入点我定在了个人信息界面,因为这个界面会展示用户的灵石数量"https://attach.52pojie.cn/forum/202207/03/164323dudkdxghj4mholfu.png" file="https://attach.52pojie.cn/forum/202207/03/164323dudkdxghj4mholfu.png" class="zoom" onclick="zoom(this, this.src, 0, 0, 0)" width="1080" id="aimg_2534310" inpost="1" />
image-20220531151256662.png
调试
经过上面几步操作后,我们已经掌握了不少信息了,此时就需要调试一下看看,验证一下我们的思路是不是正确的
image-20220531134146536.png
运行至断点处
由于我们判断此处是人物信息界面,所以我们打开人物信息界面应该就是在断点处停下
Snipaste_2022-07-03_16-31-29.jpg
此时我们可以看到已经在断点处停下了。注意:此时如果我们只是改变人物信息的展示可以直接修改goldItemNumber但是这可能仅仅是展示出现了变化,实际消费是消费不了的,所以我们要追踪一下更深层次的调用。单步调试
我们点击F11(单步执行下一个函数调用)或者上图的左起第三个按钮,具体是单步进入还是F10(单步跳过)视情况而定,需要跟踪下一个函数就F11,如果不关注下一个函数的执行情况就F10。
此处我们需要了解一下goldItemNumber的值从何而来,所以我们就跟到每一个方法中去看下
image-20220531135456516.png
这一步我们进入了numItems方法中并且看到了此方法返回了几个值,增加断点查看一下,此处我打的三个断点是最开始调试的时候断的,实际上不打断点直接调试也可以正常进行。继续调试
开始调试itemContainer,进入方法后我们发现,传入的参数“item”即为需要获取信息的对象,而方法中的
return this._items;
就是返回的具体值。image-20220531135856808.png
此时我们可以在控制台打印一下“_items”image-20220531140203461.png
发现关键信息
此时我们发现“_items”是个字典,但是此时的key值我们并不清楚具体含义,此时可以通过三种方式来确定
- 基于我们已经知道这个返回的信息中肯定包含灵石数量,所以我们查看自己当前的灵石数量,来猜测哪个key对应灵石
- 查看我们准备阶段发现配置文件中找到的灵石的信息,可以发现灵石的id正好就是“5”
- 继续跟踪代码,找到具体的解析逻辑
我比较推荐前两种,毕竟比较省事,少看点代码少费点脑子"https://attach.52pojie.cn/forum/202207/03/152627gk2xayz1m0lhl222.png" file="https://attach.52pojie.cn/forum/202207/03/152627gk2xayz1m0lhl222.png" class="zoom" onclick="zoom(this, this.src, 0, 0, 0)" width="1080" id="aimg_2534265" inpost="1" />
image-20220531141600299.png
修改之前我们可以看到,我们灵石数量为100不可以购买这个150的丹药。image-20220531141801178.png
修改之后可以看到“_items”的值已经变化image-20220531141926357.png
也可以进行购买了修改源码
// return this._items;let mitem = this._items;for(let key in mitem){ console.log(itmitemem[key]); if(mitem[key]>10 && mitem[key] < 500){ console.log('替换返回值'); mitem[key] = 9999; }}console.log("获取个人物品" + mitem);return mitem;
可以实现自动补充损耗
增加物品
经过以上操作,我们可以增加我们的灵石数量和其他的物品数量,但是却并不能凭空增加物品,即只能修改现有物品的数量,那么怎样才能增加物品呢,我们需要继续分析
此时需要思考一件事情,什么情况下可以增加人物的物品
- 获取物品时
- 保存物品时
此时我们可以考虑分析一下存档时可不可以查找到有保存物品信息的情况,从而去修改
寻找存档方法
可以考虑查看存档时是否有网络请求,所以我们可以在调试界面查看一下
image-20220531144152960.png
分析和跟踪方法
寻找存档方法
存档时,可以发现存在一个名为“Save2.ogg_”的请求,此时我们可以在发起程序标签中看到他的调用栈
image-20220531144600041.png
分析调用栈
此时需要挨个查看一下调用堆栈中的方法,分析一下其保存步骤中是否涉及调用和存储人物信息,选的太靠前跟起来容易跟丢,选的太靠后容易找不到关键信息,我分析的时候看了好几个方法,此处就不一一赘述了,直接进入executeSave方法下几个断点并进行存档操作
image-20220531144949931.png
找到目标方法
可以看到方法已经阻塞了,然后再次进行单步调试,我们可以看到有个“ DataManager.saveGame(savefileId)”方法,跟进去看看
image-20220531145323771.png
调试目标方法
image-20220531145631552.png
这里基本就是我们需要的内容了继续找到我们需要的数据
我们可以把方法走到最后一步,然后打印出cntents来看看内容
image-20220531145831706.png
尝试修改数据
我们发现“_items”中的内容应该就是我们的物品信息,此时尝试增加物品,继续去控制台修改信息
image-20220531150026503.png
恢复运行查看效果
image-20220531150148417.png
修改源码
DataManager.makeSaveContents = function() { // A save data does not contain $gameTemp, $gameMessage, and $gameTroop. const contents = {}; ... contents.actors = $gameActors; // contents.party._items = {4: 1, 5: 9999,8: 8000,9:8000, 20: 500, 22: 300, 55: 1, 83: 1, 84: 500, 86: 999, 87:999, 88:999, 162: 1, 312: 1, 317: 1}; contents.party = $gameParty; return contents;};