吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 112745|回复: 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] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
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] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
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, 下载次数: 982)

免费评分

参与人数 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] 纯文本查看 复制代码
1
2
3
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, 2025-4-19 02:20

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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