吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 107475|回复: 158
收起左侧

[Android 原创] 【放置江湖】LUA手游 基于HOOK 解密修改流程

    [复制链接]
unity 发表于 2018-1-3 12:46
本帖最后由 H夜 于 2018-1-12 11:26 编辑

1.下载拿到《放置江湖》 apk 后我们第一步检查游戏框架,直接查看 \lib 目录里面的 so就可以了。
1.png
很明显这也是一款基于cocos2dlua 开发的游戏。接着我们查看,他的lua脚本。
2.png
看来lua 脚本被加密了,解密的话,我还是比较推荐用Hook luaL_loadbuffer 的方法解密,我一般都比较喜欢用cydia substate框架。
[C] 纯文本查看 复制代码
#define LIB "/data/app-lib/com.xhtt.app.fzjh-1/libcocos2dlua.so"

void * (*old_luaL_loadbuffer)(void * L, const char * buff, size_t  size, const char * name);
void * new_luaL_loadbuffer(void * L, const char * buff, size_t  size, const char * name)
{
    // 这里加入保存 buff 到内存卡的代码
    void * ret = old_luaL_loadbuffer(L, buff, size, name);
    return ret;
}

MSInitialize {
    MSImageRef ref = MSGetImageByName(LIB);
    void *sym_luaL_loadbuffer= MSFindSymbol(ref,"luaL_loadbuffer");
    MSHookFunction(sym_luaL_loadbuffer, (void*)&new_luaL_loadbuffer, (void **)&old_luaL_loadbuffer);
};

代码弄好以后,启动运行一次游戏就可以把游戏的全部Lua解密出来;
解密出来的代码 是lua 文件,不是luac的 这样就省去我们 反编译luac 代码的流程。

2.我们拿到了lua脚本代码后怎么用呢?修改了lua的逻辑以后在怎么加载到游戏里面去呢?
由于我也是第一次尝试破解解密lua框架手游,我能想到的还是 luaL_loadbuffer 这个方法,在我们解密的过程中用这个方法拿到了lua明文代码,我们修改后的lua明文代码,还是在这个地方偷梁换柱。

如果采用改包的方式,我们还需要 把明文加密, 替换APK 文件, 签名。这个过程太复杂了。而且频繁的修改就要频繁的重复这个过程;
至于实现的话,为了让没有root的安卓用户也可以使用,我们又要用到 VA 框架了。

3.png

这是一个树林打鸟的任务,我们需要把  经验超过后的打工奖励 修改一下。把 这里我把5改成200 而且还有金币奖励;
接下来我们就该操刀 VA 游戏框架了。
VA HOOK SO 的实现过程 有很多,发一下核心实现过程
java 实现部分:
[Java] 纯文本查看 复制代码
public class Native {
    private final static String TAG = "Plugin-Native";
    static {
        try{
            System.loadLibrary("plugin");
        }catch (Exception ex){
            Log.e(TAG, ex.getMessage(), ex);
        }
    }

    public static native void hook(String p);
}

c++ 实现部分:
[C++] 纯文本查看 复制代码
extern "C" {
JNIEXPORT void JNICALL Java_com_plugin_Native_hook(JNIEnv *env, jclass jclazz, jstring p) {
    const char *path = env->GetStringUTFChars(p, NULL);

    MSHookType _hook;
    _hook = (MSHookType) findSymbol("libva-native.so", "_ZN5Cydia14MSHookFunctionEPvS0_PS0_");
    void *sym_luaL_loadbuffer = findSymbol(
            path,
            "luaL_loadbuffer");

    if (_hook != NULL && sym_luaL_loadbuffer != NULL) {
        _hook(sym_luaL_loadbuffer, (void *) &new_luaL_loadbuffer, (void **) &old_luaL_loadbuffer);
    }

}
}

[C++] 纯文本查看 复制代码
void *(*old_luaL_loadbuffer)(void *L, const char *buff, size_t size, const char *name);

void *new_luaL_loadbuffer(void *L, const char *buff, size_t size, const char *name) {

    std::string s(name);

    if (s.length() < 128) {
        replace_all(s, "/", ".");
        string path("/sdcard/lua/");
        path.append(s);
        FILE *file = fopen(path.c_str(), "r");
        if (file != NULL) {
            fseek(file, 0, SEEK_END);
            size_t new_size = ftell(file);

            fseek(file, 0, SEEK_SET);
            LOGI("[-]file=%s", s.c_str());

            char *new_buff = (char *) alloca(new_size + 1);
            fread(new_buff, new_size, 1, file);
            fclose(file);

            return old_luaL_loadbuffer(L, new_buff, new_size, name);
        }
    }

    void *ret = old_luaL_loadbuffer(L, buff, size, name);
    return ret;
}


我们在打开游戏加载lua的时候,用 name 取比较我们 内存卡根目录的 lua文件夹里面的 lua 代码。如果有就替换 没有就不替换。
这里的话只要注意 lua 文件命名就ok了。
3.最后成功的截图:
4.png

成品视频教程:
视频地址.txt (79 Bytes, 下载次数: 1814)
成品下载微云:
https://share.weiyun.com/c8158569a7deb826ca3905a79d995875


免费评分

参与人数 29吾爱币 +29 热心值 +27 收起 理由
qweqwe52 + 1 + 1 谢谢@Thanks!
kventer + 1 + 1 把每日签到的奖励都修改成元宝
lp997923 + 1 谢谢@Thanks!
haoyi888sdo + 1 谢谢@Thanks!
抽风的宅牛 + 1 + 1 谢谢@Thanks!
puluter + 2 + 1 用心讨论,共获提升!
qaz003 + 2 + 1 谢谢@Thanks!
Charming丶鬼瞳 + 1 + 1 能直接改成APK就更好了 我是没有成功
360573078 + 1 + 1 已下载,希望大神多发一些小白教程!谢谢!
小柒丨STRIFE + 1 + 1 我等程序猿楷模XD
sunnylds7 + 1 + 1 谢谢@Thanks!
鸡儿在学习 + 1 + 1 谢谢@Thanks!
SomnusXZY + 1 + 1 热心回复!
yyhf + 1 用心讨论,共获提升!
oranges + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
cocomail + 1 + 1 我很赞同!
xiefanxiu + 1 + 1 感谢楼主分享,最近正在玩这个游戏
history850 + 1 + 1 试着改元宝 可惜没成功
黯然生 + 1 + 1 可以发一个修改好的APK吗?
zhoujinming + 1 + 1 安卓7.0失败
dryzh + 1 + 1 用心讨论,共获提升!
浅薄不自觉 + 1 + 1 楼主我修改成功了,现在有个疑问,元宝能修改吗
13883202229 + 1 只能安卓5.0和6.0 安卓7.0不能改
白栀 + 1 + 1 谢谢@Thanks!
gm188 + 1 + 1 好东西啊,多谢多交流!!!!
menghun + 1 + 1 我很赞同!
宅宅男 + 1 + 1 谢谢@Thanks!
touhoufans + 1 + 1 谢谢@Thanks!
qiuchuxiong98 + 1 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

wmsuper 发表于 2018-1-4 13:31
其实可以直接解密,而且不用加密回去,代码里面会自动判断是否加密并进行解密,否则就直接进行解析,加密算法为官方使用的xxtea算法,相关解密代码如下:
[C] 纯文本查看 复制代码
int __fastcall cocos2d::LuaStack::luaLoadBuffer(int a1, int a2, int a3, unsigned __int8 *a4, int a5)
{
  unsigned __int8 *v5; // r6
  int v6; // r5
  int v7; // r7
  JM *v8; // r4
  int v9; // r0
  int v10; // r0
  int v11; // r5
  int v12; // r4
  int v14; // [sp+Ch] [bp-24h]
  int v15; // [sp+14h] [bp-1Ch]

  v5 = a4;
  v6 = a1;
  v7 = a2;
  v8 = (JM *)a3;
  if ( *(_BYTE *)(a1 + 28) && (v14 = *(_DWORD *)(a1 + 44), !j_strncmp(a3, *(_DWORD *)(a1 + 40), v14)) )
  {
    v15 = 0;
    v9 = xxtea_decrypt((int)v8 + v14, (int)&v5[-v14], *(_DWORD *)(v6 + 32), *(_DWORD *)(v6 + 36), &v15);
  }
  else
  {
    v15 = 0;
    JM::isEncrypted(v8, v5, a3, 0);
    if ( !v10 )
      return j_luaL_loadbuffer(v7, v8, v5, a5);
    JM::decrypt(v8, v5, (int)&v15);
  }
  v11 = v9;
  v12 = j_luaL_loadbuffer(v7, v9, v15, a5);
  j_free(v11);
  return v12;
}




------------------------------------------------------------------------------
解密算法如下:
[C] 纯文本查看 复制代码
void __fastcall JM::decrypt(JM *a1, unsigned __int8 *a2, int a3)
{
  unsigned __int8 *v3; // r5
  unsigned __int8 *v4; // r4
  unsigned __int8 **v5; // r7
  int v6; // r0
  void *v7; // r6
  int outlen; // [sp+10h] [bp-A0h]
  char v9; // [sp+14h] [bp-9Ch]

  v3 = (unsigned __int8 *)a1;
  v4 = a2;
  v5 = (unsigned __int8 **)a3;
  JM::isEncrypted(a1, a2, a3, _stack_chk_guard);// 判断是否加密
  if ( v6 )
  {
    JM::gdk(v3, (int)v4, (int)&v9, &outlen);    // 判断加密方式获取对应的秘钥
    xxtea_decrypt((int)&v3[outlen], (int)&v4[-outlen], (int)&v9, 128u, v5);
  }
  else
  {
    v7 = j_malloc((int)v4);
    j_memcpy((int)v7, (int)v3, (int)v4);
    *v5 = v4;
  }
}

获取秘钥的算法
[C] 纯文本查看 复制代码
void __fastcall JM::gdk(unsigned __int8 *inbuf, int inlen, int outkey, _DWORD *outlen)
{
  int keybuf; // r4
  int p; // r2
  int t; // r0
  char tmpbuf; // [sp+4h] [bp-5Ch]

  keybuf = outkey;
  if ( inbuf )
  {
    p = *inbuf;
    if ( p == 'A' )
    {
      if ( inbuf[1] == 'B' && inbuf[2] == 'C' && inbuf[3] == 'T' && inbuf[4] == 'J' && inbuf[5] == 'M' && keybuf )// 判断前缀ABCTJMT
      {
        *outlen = 6;
        j_memcpy((int)&tmpbuf, (int)&unk_BB9384, 64);
        j_memcpy(keybuf, (int)&unk_BB93C4, 64);
        t = keybuf + 64;
LABEL_15:
        j_memcpy(t, (int)&tmpbuf, 64);
        return;
      }
    }
    else if ( p == 'T' && inbuf[1] == 'J' && inbuf[2] == 'M' && keybuf )// 判断前缀 TJM
    {
      *outlen = 3;
      j_memcpy((int)&tmpbuf, (int)&unk_BB9404, 64);
      j_memcpy(keybuf, (int)&unk_BB9444, 64);
      t = keybuf + 64;
      goto LABEL_15;
    }
  }
}

免费评分

参与人数 6吾爱币 +6 热心值 +5 收起 理由
Python大法好 + 1 + 1 我很赞同!
Dem丶鲲鹏 + 1 + 1 谢谢@Thanks!
lou7878 + 1 我很赞同!
qaz003 + 1 + 1 用心讨论,共获提升!
zycode + 1 + 1 我很赞同!
海盗小K + 1 + 1 这么6?

查看全部评分

dfdslysz 发表于 2018-1-6 00:06 来自手机
wsnbbdemm 发表于 2018-1-3 18:16
楼主,按照你视频的教程解压的目录也是一样,但是就是修改无效啊,经验和潜能什么的,一直都是5.

我也是啊  不起作用   
wg871226 发表于 2018-2-23 02:06
aiguozhemini 发表于 2018-2-23 18:37 来自手机
楼主,不能用啊完全按照视频教程
wsnbbdemm 发表于 2018-1-3 18:16
楼主,按照你视频的教程解压的目录也是一样,但是就是修改无效啊,经验和潜能什么的,一直都是5.
kof8855 发表于 2018-1-3 17:45
有IOS的修改版就好了
ikeeki 发表于 2018-1-3 13:05
感谢楼主分享
qiuchuxiong98 发表于 2018-1-3 13:06
谢谢大佬
宅宅男 发表于 2018-1-3 13:34
大佬能不能搞个IOS的
love66804 发表于 2018-1-3 13:41
感谢分享。支持大佬
倦收天 发表于 2018-1-3 15:28
就只能加金币金钱潜能吗。。
丁宝振 发表于 2018-1-3 17:05
这文件到底怎么用?
浅薄不自觉 发表于 2018-1-3 17:07
楼主能不能告诉下,这个怎么用啊,安装了之后不是游戏
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-30 23:19

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表