錦州市廣廈電腦維修|上門維修電腦|上門做系統(tǒng)|0416-3905144熱誠服務(wù),錦州廣廈維修電腦,公司IT外包服務(wù)
topFlag1 設(shè)為首頁
topFlag3 收藏本站
 
maojin003 首 頁 公司介紹 服務(wù)項目 服務(wù)報價 維修流程 IT外包服務(wù) 服務(wù)器維護(hù) 技術(shù)文章 常見故障
錦州市廣廈電腦維修|上門維修電腦|上門做系統(tǒng)|0416-3905144熱誠服務(wù)技術(shù)文章
開心消消樂lua腳本解密

作者: wmsuper  日期:2017-05-25 16:07:33   來源: 本站整理

本帖最后由 wmsuper 于 2017-5-25 15:31 編輯

0x01 定位
開心消消樂lua的解析引擎在libhegame.so中,用IDA分析,發(fā)現(xiàn)很多函數(shù)并沒有符號,包括所使用的OpenSSL和Lua的第三方庫,增加了逆向的難度。
不過字符串并沒有加密,可以通過查找".lua" "load" 這些字符串找到關(guān)鍵地方,通過字符串可以快速定位到加載lua文件的地方。
[C] 純文本查看 復(fù)制代碼
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);// 第一個參數(shù)為key aes解密 IV為文件開頭的16個字節(jié)
        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 分析
調(diào)用的算法需要進(jìn)行分析,原文件中并沒有aes_cbc_decrypt和zib_decompress這兩個符號,這是需要自己去分析函數(shù)功能,這個so調(diào)用了大量的第三方庫的接口,加密算法也是調(diào)用
OpenSSL的,所以只要熟悉下這些庫的接口,可以很方便確定加解密函數(shù)的功能和參數(shù)。
跟進(jìn)aes_cbc_decrypt這個函數(shù),有很明顯的調(diào)試字符串,就可以馬上確定所調(diào)用的是哪一個OpenSSL函數(shù)。(注:函數(shù)名稱是加上去的)
 

很快的就能確定函數(shù)原型為aes_cbc_decrypt(char*key,char*iv,char*inbuf,int inlen,char**outbuf);
于是可以推出key和iv的來源,很明顯key就是上面那一串密鑰,注意2和3參數(shù),相差16,于是可以推出來IV就是文件的開頭16個字節(jié)
 

------------------------------------------------------------------------------------------------------------------
跟進(jìn)zib_decompress這個函數(shù),1.2.8可以確定用了zlib的inflateInit(strm),第一個參數(shù)v15就是zib_decompress函數(shù)的第一個參數(shù)a1,也就是說aes解密完成
就直接開始解壓,中間沒進(jìn)行額外的處理。
 


 
0x03 解密算法編寫
從上面的分析可以知道,lua文件經(jīng)過aes_cbc解密之后再進(jìn)行解壓,解密算法如下:
[Python] 純文本查看 復(fù)制代碼
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.編寫程序的時候由于過多的留下調(diào)試字符串導(dǎo)致程序容易被逆向(要利用#define DEBUG控制代碼編譯,release版的程序不應(yīng)該包含這些字符串)
2.過多的利用第三方開源加密庫。開發(fā)者是比較喜歡使用別人造好的輪子,但是也給帶來安全性問題。
3.從解密出來的lua來看,消消樂的lua腳本沒經(jīng)過編譯,這就導(dǎo)致了源碼泄露。


熱門文章
  • 機(jī)械革命S1 PRO-02 開機(jī)不顯示 黑...
  • 聯(lián)想ThinkPad NM-C641上電掉電點不...
  • 三星一體激光打印機(jī)SCX-4521F維修...
  • 通過串口命令查看EMMC擦寫次數(shù)和判...
  • IIS 8 開啟 GZIP壓縮來減少網(wǎng)絡(luò)請求...
  • 索尼kd-49x7500e背光一半暗且閃爍 ...
  • 樓宇對講門禁讀卡異常維修,讀卡芯...
  • 新款海信電視機(jī)始終停留在開機(jī)界面...
  • 常見打印機(jī)清零步驟
  • 安裝驅(qū)動時提示不包含數(shù)字簽名的解...
  • 共享打印機(jī)需要密碼的解決方法
  • 圖解Windows 7系統(tǒng)快速共享打印機(jī)的...
  • 錦州廣廈電腦上門維修

    報修電話:13840665804  QQ:174984393 (聯(lián)系人:毛先生)   
    E-Mail:174984393@qq.com
    維修中心地址:錦州廣廈電腦城
    ICP備案/許可證號:遼ICP備2023002984號-1
    上門服務(wù)區(qū)域: 遼寧錦州市區(qū)
    主要業(yè)務(wù): 修電腦,電腦修理,電腦維護(hù),上門維修電腦,黑屏藍(lán)屏死機(jī)故障排除,無線上網(wǎng)設(shè)置,IT服務(wù)外包,局域網(wǎng)組建,ADSL共享上網(wǎng),路由器設(shè)置,數(shù)據(jù)恢復(fù),密碼破解,光盤刻錄制作等服務(wù)

    技術(shù)支持:微軟等
    主站蜘蛛池模板: 亚洲国产精品无码成人片久久| 国产精品无码一二区免费| 少妇极品熟妇人妻无码| 亚洲精品无码久久久| 亚洲AV无码一区二区大桥未久| 日本无码色情三级播放| 东京热加勒比无码视频| 久久精品无码专区免费东京热 | 亚洲精品无码高潮喷水在线| 精品久久久无码人妻字幂| 亚洲AV无码精品无码麻豆| 国产在线无码一区二区三区视频| 中文字幕人成无码免费视频| AV大片在线无码永久免费| 亚洲中文字幕无码久久2017| 无码人妻aⅴ一区二区三区| 精品人妻系列无码人妻漫画| 无码GOGO大胆啪啪艺术| 中字无码av电影在线观看网站 | 亚洲av日韩av无码av| 久久精品无码一区二区无码| 国产精品无码永久免费888| 国模吧无码一区二区三区| 久久久久久亚洲精品无码| 亚洲一区无码中文字幕乱码| 无码一区二区三区| 国产精品无码一区二区三区电影| 国产午夜无码福利在线看网站| 亚洲AV无码一区二区一二区| 亚洲中文字幕无码av在线| 99久久人妻无码精品系列蜜桃| 色综合久久久久无码专区| 无码超乳爆乳中文字幕久久| 久久久久久国产精品无码超碰| 国产精品视频一区二区三区无码| 免费无码又爽又刺激一高潮| 国产日韩精品无码区免费专区国产| 人妻少妇伦在线无码| 中文字幕无码久久精品青草| 在线播放无码高潮的视频| 亚洲精品久久无码av片俺去也|