admin管理员组文章数量:1533122
2023年12月13日发(作者:)
love2d引擎手游修改一例
love 2d 介绍
LÖVE是一个使用 Lua 作为编程语言的 2D 游戏框架,网络上关于此引擎的修改教程还是相对较少。此次下手的目标为王国保卫战,这个手游已
经有很多破解版本。这里还是记录一下我自己的摸索过程,从定位关键代码到修改。
1. 定位资源文件
一般手游的程序逻辑都是以脚本的形式存储在apk的资源文件中,这次目标apk是从 google play 下载,从 /data/app 目录中pull出apk,得到
apk的解压结果如下:
├──
├── META-INF
├── assets
├──
├── error_prone
├── fabric
├── jsr305_annotations
├── lib
├── res
├──
└── third_party
看了一下大小,才9.5m大小,zip包中没发现资源文件:
ls -l
-rw-r--r--@ 1 max admin 9469378
这就很奇怪了,看了一下空间占用了近 200m ,而且 /data/data 目录下也没有找到关键资源文件:
不过还是在一个名为 DownloadsDB 数据库文件中发现了一个下载链接
看到google的url,我怀疑是Play Store的特殊机制,因此在国内的应用中较为少见。网上查了一下,果不其然,这应该就是 obb 文件了,用于
资源文件分发,减小apk体积。
这样应用更新的时候就不必重新下载整个apk, 同时,google 的服务器在国外的稳定性与速度都不差,也可以为开发者节省部分cdn费用。打开
压缩包,果不其然,里面存放着游戏脚本,大小也有100m多,这就正好可以对上号了:
2. 定位关键代码
根据上一步资源文件的解压结果来看,这些 lua 脚本应该就是程序逻辑了。打开一个lua文件,先看看hex,为 luajit 文件:
使用 luajit-decompiler (/znixian/luajit-decompiler) 把 luajit 文件反编译成明文,使用方法如下:
python3 ./ --recursive ./ --dir_out ./
这样就可以得到明文 lua 脚本:
main_
手游里,想要定位钻石有关代码,一般都是搜索 gem 关键字,搜索到一个可疑文件 platform_services_ ,代码如下:
--- 观看广告时会调用
function ads:show_video_ad(provider, reward_amount)
local function cb_show_video_ad(status, req)
local success = status == 0
if success then
("ad complete: rewarding %s gems", reward_amount)
--- 获取存档中的物品
local slot = storage:load_slot()
if slot then
--- 观看广告后所得钻石增加 reward_amount 个
= + reward_amount
--- 把增加后的钻石再保存到存档中
storage:save_slot(slot, nil, true)
else
("error giving gems reward. slot could not be loaded")
end
end
(SGN_PS_AD_SHOW_VIDEO_FINISHED, "ads", success, reward_amount)
end
......
上面那段代码,在每次观看广告获取钻石时被调用,这样我们的修改思路就很明确了,只要让
storage:load_slot()
函数每次返回的钻石数为我们指
定的,就可以达到目的了。
3. 修改脚本
在 /all/ 中直接定位到
storage:load_slot()
的实现:
function storage:load_slot(idx, force)
... 参数检查
local input = self:load_lua((_FILE_FMT, idx), force)
... 参数检查
--- 读取 SLOT_ADDITIONAL_DATA 到 result,并返回
for k, v in pairs(SLOT_ADDITIONAL_DATA) do
if not input[k] then
input[k] = v
end
end
return input
end
再看一眼 SLOT_ADDITIONAL_DATA, gems 就是我们要动手的目标了:
local SLOT_ADDITIONAL_DATA = {
gems = 0,
bag = {}
}
直接 patch
storage:load_slot()
函数,添加两行代码,改的时候可以多尝试一下,改错了会导致游戏蓝屏或闪退:
function storage:load_slot(idx, force)
...
for k, v in pairs(SLOT_ADDITIONAL_DATA) do
if not input[k] then
input[k] = v
end
end
input["gems"] = 88888
print("[MaxLog]", input["gems"])
return input
使用 luajit 编译修改好的文件
luajit-2.1.0-beta3 -bg ./all/ ./
4. 测试运行
obb 文件是通过使用时 mount 到应用沙盒 /data/data 目录下,我在文件管理器中未找到真实文件,具体原理还没有研究 obb 机制。我的解
决方案是 Hook
open()
函数,把原脚本文件替换为我们修改过的的文件。
1. 把修改过的脚本文件放入 /data/local/tmp 中:
adb push /data/local/tmp
2. Hook libc 的
open()
函数:
int new_open(const char *name, int flags, ...) {
mode_t mode = 0;
if ((flags & O_CREAT) != 0) {
va_list args;
va_start(args, flags);
mode = static_cast
va_end(args);
}
LOGD("Tag", "open("%s", %d)", name, flags);
if (strstr(name, "all/")) {
// LOGD("Tag", "open("%s", %d)", name, flags);
return old_open("/data/local/tmp/", O_RDONLY);
}
return old_open(name, flags, mode);
}
3. 运行游戏,在 Lua 脚本中打的 Log ,也可以查看到:
4. 游戏里的钻石也成为指定的数额:
总结
其实破解修改手游大致都可以总结以下几个套路:
1. 解密脚本
常见的几个游戏引擎u3d、cocos2dx,都可以解出游戏逻辑脚本,这些脚本也是我们主要关注的目标。需要注意的是可能存在jit、aot等情
况,这时候就需要进行加密解密操作。
2. 定位代码
通过搜索可以关键字,分析代码逻辑,找到需要修改的地方。
3. 修改测试
明文脚本可以直接修改,密文脚本注意还原,还可以使用Hook等手段直接动态修改内存。
版权声明:本文标题:love2d引擎手游修改一例 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1702473430a8728.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论