用OD載入該軟件,搜索下字符串,可以很快知道這個軟件是java寫的,並且用exe4j打包的。
exe4j打包的jar會解包到臨時文件下,我們到臨時文件看壹看,可以看到,jar被釋放出來了。目測可以直接反編譯。
但是事情並不是盡如人意,class文件被加密了。通過簡單的Google壹下,classguard用了AES加密,前人采用的破解方法是直接DUMP下來。
0x01 靜態分析
簡單瀏覽下這個類的實現,發現和傳統的殼沒啥不同,都是自己實現了classloader,但是解密算法在dll中。
通過瀏覽lib文件夾,可以看到不同平臺下的庫文件,這裏主要分析windows下的動態鏈接庫。
IDA載入該dll,查看其導出函數定位到解密class的地方。
這個dll靜態鏈接了OpenSSL的靜態庫。通過ida對應的FLIRT文件來快速識別OpenSSL的庫函數。
可以看到,解密的主要算法是通過構造壹個RSA私鑰,用該私鑰解密內置AES算法的秘鑰,最後通過解密出來的key來解密class。
所以為了獲得解密後的class,可以跑OD腳本直接dump下來,也可以直接批量解密,這裏我采用的是批量解密的方法,首先得動態獲取解密後的AES秘鑰。
0x02 動態分析
通過勾選OD的“中斷於新模塊"可以在載入該dll的時候斷下來,轉到對應的地方下斷點,可以獲取AES的秘鑰。即下圖框起來的那壹部分。
可以看到class在經過該EVP_DecryptUpdate函數的時候內容已經被解開了(部分解開,寫OD腳本的時候可以考慮在EVP_DecryptUpdate和EVP_DecryptFinal下斷點獲取相關內容及長度)
0x03 編寫解密腳本
知道了AES的秘鑰可以編寫腳本來批量解密,腳本如下:
[Python]?純文本查看?復制代碼
#coding=UTF-8import ioimport osimport base64import binasciiimport sysimport cryptosys.modules['Crypto']=cryptofrom? crypto.Cipher import AES?def decdata(c):key=binascii.a2b_hex('2CAE9F73999AF1E51AA4547C6B57BB22')iv=16*'\x00'cryptor=AES.new(key,AES.MODE_ECB,iv)data=cryptor.decrypt(c)pad=ord(data[-1])plain_text=data[0:len(data)-pad]return plain_text?if __name__ == '__main__':indir = r'trader'? #輸入文件夾outdir= r'output'#輸出文件夾exstr='.classx' #輸入文件的擴展名for path, subdirs, files in os.walk(indir):for filename in files:if filename.endswith(exstr):infilename = path + os.sep + filenamesize = os.path.getsize(infilename)?with open(infilename, 'rb') as inFile:data = inFile.read()inFile.close()try:result=decdata(data)except:print filenamebreakoutfilename = outdir + infilename.replace(indir, '', 1).replace('classx','class')print outfilename?outPath,outFilename = os.path.split(outfilename)if not os.path.exists(outPath):os.makedirs(outPath)'''解密class'''with open(outfilename, 'wb') as outFile:outFile.write(result)outFile.close()0x04 結果
可以看到class文件已經被解密出來了,並且能正確反編譯。
替換解密出來的文件後,通過修改jar的入口即可脫殼完成。
改成
[XML]?純文本查看?復制代碼
Manifest-Version: 1.0Ant-Version: Apache Ant 1.9.4Created-By: 1.6.0_45-b06 (Sun Microsystems Inc.)Main-Class: com.fx24k.fxtrader.trader.FxClient