吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 112002|回复: 457
收起左侧

[Android 原创] 开心消消乐lua脚本解密

    [复制链接]
wmsuper 发表于 2017-5-25 14:00
本帖最后由 wmsuper 于 2017-5-25 15:31 编辑

0x01 定位
开心消消乐lua的解析引擎在libhegame.so中,用IDA分析,发现很多函数并没有符号,包括所使用的OpenSSL和Lua的第三方库,增加了逆向的难度。
不过字符串并没有加密,可以通过查找".lua" "load" 这些字符串找到关键地方,通过字符串可以快速定位到加载lua文件的地方。
[C] 纯文本查看 复制代码
void __fastcall lua_load(int a1)
{
  int v1; // r0@1
  int v2; // r3@1
  int *v3; // r0@3
  int v4; // r0@3
  signed int v5; // r7@3
  int v6; // r0@4
  int v7; // r0@6
  int v8; // r5@6
  int v9; // r6@12
  int v10; // r5@12
  int v11; // r0@15
  int v12; // r4@15
  int v13; // r5@17
  int v14; // r4@18
  int v15; // r5@7
  int v16; // r0@30
  int v17; // r6@30
  int v18; // r0@30
  int v19; // r0@30
  int v20; // r0@30
  int v21; // r0@30
  int v22; // r0@30
  int v23; // r0@30
  int v24; // r0@30
  int v25; // r6@30
  int v26; // r0@30
  int v27; // r0@31
  int v28; // r0@31
  int *v29; // r0@33
  const char *v30; // r1@33
  int v31; // r0@16
  int buf; // [sp+8h] [bp-108h]@4
  int v33; // [sp+Ch] [bp-104h]@3
  int v34; // [sp+10h] [bp-100h]@1
  int v35; // [sp+1Ch] [bp-F4h]@1
  char v36; // [sp+20h] [bp-F0h]@2
  int v37; // [sp+24h] [bp-ECh]@3
  char v38; // [sp+28h] [bp-E8h]@3
  char v39; // [sp+2Ch] [bp-E4h]@3
  char v40; // [sp+30h] [bp-E0h]@3
  int v41; // [sp+34h] [bp-DCh]@3
  unsigned int len; // [sp+38h] [bp-D8h]@6
  int v43; // [sp+3Ch] [bp-D4h]@18
  int out; // [sp+40h] [bp-D0h]@3
  int v45; // [sp+44h] [bp-CCh]@1
  char v46; // [sp+48h] [bp-C8h]@32

  v34 = a1;
  v1 = sub_30E100();
  sub_30D100((int)&v35, v1, (int)&v45);
  v2 = sub_30D6B0(&v35, ".lua", 0);
  if ( v2 == *(_DWORD *)(v35 - 12) - 4 )
  {
    sub_30D610(&v36, &v35, 0, v2);
    sub_30D300(&v35, &v36);
    sub_30D130((int)&v36);
  }
  sub_30D100((int)&v38, (int)".", (int)&out);
  sub_30D100((int)&v39, (int)"/", (int)&v45);
  sub_7011C(&v40, &v35, &v38, &v39);
  v3 = (int *)sub_30D140(&v40, ".lua");
  v37 = *v3;
  *v3 = (int)&unk_3F3A68;
  sub_30D130((int)&v40);
  sub_30D130((int)&v39);
  sub_30D130((int)&v38);
  v4 = sub_74CD8(&v41, "src/", &v37);
  v33 = 2;
  v5 = 0;
  do
  {
    v6 = sub_1219BC(v4);
    buf = (*(int (**)(void))(*(_DWORD *)v6 + 16))();
    if ( buf )
    {
      v7 = sub_656EC();
      v8 = len;
      if ( v7 )
      {
        sub_74CD8(&v45, "@", &v37);
        v15 = sub_30E110(v34, buf, v8, v45);    // 读取lua文件
        sub_30D130((int)&v45);
        if ( v15 )
          v5 = 3;
      }
      else if ( len <= 0x10 )      //这里可以知道这个变量是文件的长度
{
        sub_68908("load_lua", "can not get enough file data of %s", v41);
        v5 = 5;
      }
      else
      {
        if ( !(dword_3E730C & 1) && sub_30D150(&dword_3E730C) )
        {
          byte_3E7310 = 0xE9u;
          byte_3E7311 = 0x74;
          byte_3E7313 = 0x92u;
          byte_3E7314 = 0xCCu;
          byte_3E7315 = 0x32;
          byte_3E7316 = 0x2E;
          byte_3E7319 = 0x2E;
          byte_3E731A = 0x7C;
          byte_3E731B = 0x34;
          byte_3E731C = 0x51;
          byte_3E731D = 0xD7u;
          byte_3E7312 = 0x7D;
          byte_3E7317 = 0x7D;
          byte_3E731E = 0xB3u;
          byte_3E7318 = 0x11;
          byte_3E731F = 0x6A;
          sub_30D160((int)&dword_3E730C);
        }
        v9 = len - 16;
        out = 0;
        v45 = 0;
        v10 = aes_cbc_decrypt((int)&byte_3E7310, buf, buf + 16, len - 16, &out);// 第一个参数为key aes解密 IV为文件开头的16个字节
        if ( v10 || (v10 = aes_cbc_decrypt((int)&byte_3E7310, buf, buf + 16, v9, &out)) != 0 )
        {
          zib_decompress(out, v10, (const void **)&v45);// 解压缩
          v12 = v11;
          if ( v11 || (zib_decompress(out, v10, (const void **)&v45), (v12 = v31) != 0) )
          {
            v13 = v45;
            if ( v12 > 3 && *(_BYTE *)v45 == 0xEF && *(_BYTE *)(v45 + 1) == 0xBB && *(_BYTE *)(v45 + 2) == 0xBF )
            {
              v13 = v45 + 3;
              v12 -= 3;
              sub_688EE("load_lua", "%s with utf-8 bom", v37);
            }
            sub_74CD8(&v43, "@", &v37);
            v14 = sub_30E110(v34, v13, v12, v43);
            sub_30D130((int)&v43);
            if ( v14 )
              v5 = 3;
          }
          else
          {
            v5 = 2;
          }
        }
        else
        {
          v5 = 1;
        }
        if ( v45 )
        {
          sub_30D490(v45);
          return;
        }
        if ( out )
          sub_30D490(out);
      }
      sub_30D490(buf);
      if ( !v5 )
        goto LABEL_44;
    }
    else
    {
      v4 = sub_68908("load_lua", "can not get file data of %s", v41);
      v5 = 4;
    }
    v33 = (v33 - 1) & 0xFF;
  }
  while ( v33 );
  if ( v5 )
  {
    v16 = sub_1219BC(v4);
    (*(void (__fastcall **)(int *, int, int))(*(_DWORD *)v16 + 28))(&v43, v16, v41);
    sub_30D6D0(&v45, 16);
    v17 = sub_30D690(&v45, "error loading module ");
    v18 = sub_30D790(v34, 1, 0);
    v19 = sub_30D690(v17, v18);
    v20 = sub_30D690(v19, " from file ");
    v21 = sub_30D690(v20, v43);
    v22 = sub_30D690(v21, ":\n\t");
    v23 = sub_30D690(v22, "fileSize:");
    v24 = sub_30E120(v23, len);
    v25 = sub_30D690(v24, "\n\tmessage: ");
    v26 = sub_30D790(v34, -1, 0);
    sub_30D690(v25, v26);
    switch ( v5 )
    {
      case 1:
      case 5:
        sub_30D690(&v45, ", decrypt error");
        v27 = sub_6CA3C(v43);
        v28 = sub_B1C10(v27);
        (*(void (**)(void))(*(_DWORD *)v28 + 12))();
        goto LABEL_32;
      case 2:
        v29 = &v45;
        v30 = ", uncompress error";
        break;
      case 3:
        v29 = &v45;
        v30 = ", load buff error";
        break;
      default:
        v29 = &v45;
        v30 = ", unknown error";
        break;
    }
    sub_30D690(v29, v30);
LABEL_32:
    sub_30D590(&out, &v46);
    sub_30E130(v34, out);
  }
LABEL_44:
  sub_30D130((int)&v41);
  sub_30D130((int)&v37);
  sub_30D130((int)&v35);
}


0x02 分析
调用的算法需要进行分析,原文件中并没有aes_cbc_decrypt和zib_decompress这两个符号,这是需要自己去分析函数功能,这个so调用了大量的第三方库的接口,加密算法也是调用
OpenSSL的,所以只要熟悉下这些库的接口,可以很方便确定加解密函数的功能和参数。
跟进aes_cbc_decrypt这个函数,有很明显的调试字符串,就可以马上确定所调用的是哪一个OpenSSL函数。(注:函数名称是加上去的)
2.png

很快的就能确定函数原型为aes_cbc_decrypt(char*key,char*iv,char*inbuf,int inlen,char**outbuf);
于是可以推出key和iv的来源,很明显key就是上面那一串密钥,注意2和3参数,相差16,于是可以推出来IV就是文件的开头16个字节
1.png

------------------------------------------------------------------------------------------------------------------
跟进zib_decompress这个函数,1.2.8可以确定用了zlib的inflateInit(strm),第一个参数v15就是zib_decompress函数的第一个参数a1,也就是说aes解密完成
就直接开始解压,中间没进行额外的处理。
4.png


5.png
0x03 解密算法编写
从上面的分析可以知道,lua文件经过aes_cbc解密之后再进行解压,解密算法如下:
[Python] 纯文本查看 复制代码
def decdata(c):
    key='\xe9\x74\x7d\x92\xcc\x32\x2e\x7d\x11\x2e\x7c\x34\x51\xd7\xb3\x6a'
    iv=c[0:16]
    main_data=c[16:]
    cryptor = AES.new(key,AES.MODE_CBC,iv) 
    pad_compress_data=cryptor.decrypt(main_data)
    str_len=len(pad_compress_data)
    pad=ord(pad_compress_data[-1])
    compress_data=pad_compress_data[0:str_len-pad]
    plain_text = zlib.decompress(compress_data)
    return plain_text



0x04 加密方案评价
1.编写程序的时候由于过多的留下调试字符串导致程序容易被逆向(要利用#define DEBUG控制代码编译,release版的程序不应该包含这些字符串)
2.过多的利用第三方开源加密库。开发者是比较喜欢使用别人造好的轮子,但是也给带来安全性问题。
3.从解密出来的lua来看,消消乐的lua脚本没经过编译,这就导致了源码泄露。
lua解密.zip (872 Bytes, 下载次数: 976)

免费评分

参与人数 99吾爱币 +86 热心值 +93 收起 理由
鑫夜 + 1 + 1 我很赞同!
326253sun + 1 我很赞同!
良辰讵可待 + 1 + 1 一直支持您
ygc12335 + 1 热心回复!
jnez112358 + 1 + 1 谢谢@Thanks!
revenshake + 1 + 1 热心回复!
tian5i + 1 + 1 我很赞同!
NoDocCat + 1 + 1 我很赞同!
有道云笔记 + 1 我很赞同!
别了丶 + 1 + 1 谢谢@Thanks!
zryhb16566 + 1 + 1 用心讨论,共获提升!
sugar小兵 + 1 + 1 我很赞同!
webmarksman + 1 + 1 谢谢@Thanks!
沙漠一滩水 + 1 + 1 谢谢@Thanks!
zxymdaddy + 1 + 1 我很赞同!
843240106 + 1 + 1 热心回复!
心语科技 + 1 + 1 热心回复!
lvzhu111 + 1 + 1 我很赞同!
曹敖铭 + 1 我很赞同!
yaksaf + 1 + 1 我很赞同!
mengliluo + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
superwl + 1 用心讨论,共获提升!
marcokang1314hl + 1 + 1 我很赞同!
aidawei001 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
q74330 + 1 + 1 我很赞同!
1278156309 + 1 + 1 非常不错的 教程 谢谢楼主大人了
Pfc小书生 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
一剑西来 + 1 + 1 我很赞同!
fruitg + 1 用心讨论,共获提升!
laogong300 + 1 + 1 谢谢@Thanks!
jjww5188 + 1 + 1 热心回复!
idea + 1 + 1 用心讨论,共获提升!
道本 + 1 + 1 热心回复!
zhuzaiting + 1 + 1 谢谢@Thanks!
kkpljat + 1 + 1 谢谢@Thanks!
masaike + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
helloword121 + 1 + 1 谢谢@Thanks!
LHQ + 1 + 1 谢谢@Thanks!
GaaraZL + 1 + 1 大侠能给@ 个成品么
hsia_y + 1 + 1 谢谢@Thanks!
王亦棋 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
闪现抱你 + 1 + 1 大神,收下我的膝盖
center + 1 + 1 大神,收下我的膝盖
小枫丶 + 1 + 1 用心讨论,共获提升!
Lullaby. + 1 + 1 谢谢分享呀。
Ravey + 1 谢谢@Thanks!
dajiaozi + 1 已经处理,感谢您对吾爱破解论坛的支持!
kll545012 + 1 热心回复!
feerboyz + 1 谢谢@Thanks!
freelyfly + 1 + 1 热心回复!
woshiwonizaina + 1 + 1 用心讨论,共获提升!
我爱这个论坛 + 1 + 1 用心讨论,共获提升!
us0 + 1 + 1 用心讨论,共获提升!
zjszjsios + 1 用心讨论,共获提升!
52_poj + 1 + 1 我很赞同!
车子开上五环 + 1 + 1 用心讨论,共获提升!
Byelo + 1 + 1 我很赞同!
abcde654321 + 1 + 1 热心回复!
红阳 + 1 + 1 我很赞同!
52破解☆ + 1 + 1 热心回复!
xd1225 + 1 + 1 我还以为是破解程序呢,可惜了
gxxxlxy + 1 + 1 谢谢@Thanks!
wenha2010 + 1 + 1 热心回复!
dingding8208 + 1 + 1 已答复!
palard + 1 + 1 谢谢@Thanks!
896536260 + 1 + 1 我很赞同!
我要装逼 -1 + 1 我想问大神要成品
xiaohao998 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
WoodyC + 1 + 1 热心回复!
w20064360 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
wuhen999 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
wqxk22 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ekanshao + 1 + 1 我很赞同!
吾爱远哥 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
真主之劍 + 1 + 1 用心讨论,共获提升!
adq_cq -1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
zfzzqlx + 1 + 1 热心回复!
初级菜鸟 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
海底总动员 + 1 我很赞同!
qaz003 + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
独行风云 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
h080294 + 1 + 1 热心回复!
ayoma + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
qqzfh138 + 1 + 1 谢谢@Thanks!
树荫底下的太阳 + 1 + 1 热心回复!
sgz2310 + 1 + 1 谢谢@Thanks!
lies2014 + 1 + 1 谢谢@Thanks!
hhntv418 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
yabghu + 1 已经处理,感谢您对吾爱破解论坛的支持!
ai921570595 + 1 + 1 热心回复!
wdg4984 + 1 + 1 我很赞同!
52鱼鱼 + 1 + 1 热心回复!
sxr1284 + 1 + 1 热心回复!
EA7_AY + 1 已答复!
飘零的殇 + 1 + 1 已答复!
a2666392 + 1 + 1 能发成品吗大神
不爱哭 + 1 热心回复!
cc6639581 + 1 + 1 助攻给你升级
erebusx + 1 + 1 太感谢了!解决的正是我现在发愁的问题

查看全部评分

本帖被以下淘专辑推荐:

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

木风 发表于 2017-5-29 11:16
加油,等待作品
h080294 发表于 2017-5-27 18:42
erebusx 发表于 2017-5-25 20:56
在跟进zib_decompress函数之前其实也看不到那些调试信息,实际上是对可疑的函数逐个跟进去看看,然后发现 ...

不太懂这方面,但md5这个跟SignatureUtil:getDefaultCmPayment有关系没?看里面有个操作
[Lua] 纯文本查看 复制代码
local signature = v:toCharsString()
					local md5 = HeMathUtils:md5(signature)
					table.insert(list, md5)

外面的话还有个static_config的xml对应着文件的md5值和size。
能不能私下交流下
头像被屏蔽
Tunny 发表于 2017-5-25 14:20
小辉灰 发表于 2017-5-25 14:22 来自手机
可以呀很牛逼没网到可以了,
dkr0801 发表于 2017-5-25 14:23
厉害   学习了
Ouras 发表于 2017-5-25 14:25
感谢分享
erebusx 发表于 2017-5-25 14:26
太好了,纠结lua脚本解密的问题,ida刚开始用,看着那一对的汇编语言正在头痛呢,一下子思路就清晰了,多谢!
sefiy 发表于 2017-5-25 14:27
厉害厉害
mayl8822 发表于 2017-5-25 14:55
感谢分享, 学习了
underway 发表于 2017-5-25 15:07
哈哈,开启全自动模式
wenbo998 发表于 2017-5-25 15:13
能自己消除吗这个?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-15 13:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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