吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3449|回复: 5
收起左侧

[Android 原创] 某 xor + xxtea 加密 jsc 解密记录

[复制链接]
omae 发表于 2024-4-13 15:10
本帖最后由 omae 于 2024-4-13 15:14 编辑

某使用 cocos2dx 编写的模拟经营类游戏,使用 apktool 解包后找到一些 .jsc 文件。通过 frIDA hook 的方式得到 xxtea 密钥后,尝试直接解密,但解密失败。

使用 16 进制阅读器打开这些 .jsc 文件,发现文件头有疑似 sign 的特征字符串:

微信截图_20240413144923.png

尝试仿照 xxtea 加密的 .luac 文件解密流程,直接删去 sigh 后解密,但仍失败。

搜索该特征字符串,发现 github 上有一个比较新(建立时间约 5 个月前)的repo,在使用示例中出现了该 sign 字符串:

[Shell] 纯文本查看 复制代码
1
python js_xxtea_decrypt.py -k Za810xwef83lsa0A -xs "$(echo -en 'netease\x01\x01\x01\xef' | xxd -p)" -xk Wa810xwef83lsa0A enshtak_apktool/assets


据此,初步判断 .jsc 文件们使用了 xor + xxtea 的加密方式,目前缺失的信息是 xor_key。

在正式开始逆向前,初步思考了下:

1. 既然例子中的 xxtea_key(Za810xwef83lsa0A) 符合常见的 .jsc 密钥格式(长度为 16 的随机数字字母字符串),xor_sign 内容是真实的,那么 xor_key(Wa810xwef83lsa0A)大概率也是某个 apk 的真实加密密钥。

2. 例子中的 xxtea_key 和 xor_key 格式类似。如果 xxtea_key 是被随机生成的话,如果是懒人如我写代码的话,没道理 xor_key 不被(使用相同的算法)随机生成。

在上述推测的前提下,搜索 libcocos.so 中长度为 16 的字符串,直接暴力破解,成功获得密钥。

获得密钥后虽然开心,但考虑到后续可能遇到使用相同加密方式的 apk,一旦换了密钥生成算法的话之后再解密就束手无策了,于是开始了正经的逆向尝试。

ida 打开 libcocos.so,搜索 xor_key 的交叉引用,发现一构造函数:

[C] 纯文本查看 复制代码
1
2
3
4
5
6
void __fastcall cc::FileUtils::FileUtils(cc::FileUtils *this) {
  // ...
  this->neteaseKey = "XOR_KEY";
  // ...
  cc::FileUtils::sharedFileUtils = (__int64)this;
}


本来思路是获取内存中存放 neteaseKey 的地址,然后下读断点,之后打印函数调用栈。但因为手头没有 root 的安卓手机,动态调试需要远程到队友电脑上十分不方便,遂继续尝试静态分析。

既然存放 xor_key 的变量被命名为 neteaseKey,且通过简单检索没找到 cocos2dx 官方有使用 xor 加密方式的文章,因此推测该加密逻辑由某插件或定制代码提供,且推测提供者为 netease 或者和其有关系。因此在字符串中搜索关键词 netease,找到一个几乎紧挨着 xor_key 的字符串 “netease”。搜索其 xref,找到了如下逻辑:

[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
cc::Data __fastcall cc::FileUtils::getDataFromFile(cc::FileUtils *this, const std::string *filename) {
  const char *neteaseKey; // x20
  Size = (uint8_t *)cc::Data::getSize(v3);
  if ( (unsigned int)Size >= 0xC ) {
    Bytes = cc::Data::getBytes(v3);
    Size = (uint8_t *)memcmp(Bytes, "netease", 7uLL);
    if ( !(_DWORD)Size && Bytes[7] == 1 && Bytes[10] == 239 && Bytes[9] == 1 && Bytes[8] == 1 ) {
      v9 = cc::Data::getSize(v3) - 11;
      v10 = calloc(1uLL, v9);
      memcpy(v10, Bytes + 11, v9);
      if ( (_DWORD)v9 ) {
        neteaseKey = this->neteaseKey;
        v12 = 0;
        v13 = v9;
        v14 = v10;
        do {
          if ( strlen(neteaseKey) <= v12 ) {
            v15 = 0;
          } else {
            v15 = v12;
          }
          --v13;
          v12 = v15 + 1;
          *v14++ ^= neteaseKey[v15];
        }
        while ( v13 );
      }
      cc::Data::fastSet(v3, (unsigned __int8 *)v10, v9);
    }
  }
  result._size = v7;
  result._bytes = Size;
  return result;
}


大体逻辑是检测文件头是否为 xor_sign,是则跳过,后续内容使用 xor_key 进行解密。

修改 frida hook 代码,增加获取 xor_key 部分的逻辑,收工~

免费评分

参与人数 2威望 +1 吾爱币 +21 热心值 +1 收起 理由
Project430 + 1 我很赞同!
qtfreet00 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

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

tkgguter88 发表于 2024-10-4 21:53
能不能作一个相关的工具,有的用KEY就是提示密钥错误,不知道该怎么解了
bfbkj998 发表于 2024-11-30 00:42
activity2150 发表于 2024-11-21 10:51
CocosCreator编译的.jsc能解码吗?

有安卓包 能找到armeabi-v7a\libcocos2djs.so  里面有密钥就可以
jeff2024 发表于 2025-2-25 16:30
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2025-4-23 11:29

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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