用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 + filename size = os.path.getsize(infilename) with open(infilename, 'rb') as inFile: data = inFile.read() inFile.close() try: result=decdata(data) except: print filename break outfilename = 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 一.破解工具预备要破解JAVA软件,必须要反编译用JAVA编写的类文件。由于网上大虾们的支持,许多反编译软件被研制出来
其中,我经常使用的是:
1. cavaj Java Decompile 1.11
2.Java源代码反编译专家(该软件支持目录编译)
3.JAD
这三个软件各有优缺点:前二个软件是GUI界面,使用起来很方便。尤其是"Java源代码反编译专家",支持
目录编译,用起来很得心应手;第三个软件JAD功能最强,由于是字符界面,但是相对初学者比较难一点。
二.破解步骤
1.首先分析批处理文件,找到第一个调用的CLASS。
在分析iavaZIP20软件的iavaZIP2.bat,我把最重要的一句COPY到下行:
com.sfs.app.iavazip20.iavaZIP20 %1 %2 %3 %4 %5 %6 %7 %8 %9
可以知道,在com\sfs\app\iavazip20的目录下的iavaZIP20.CLASS就是被调用的第一个CLASS.
2.反编译第一个CLASS,分析MAIN方法,寻找版本控制的代码段
我用“cavaj Java Decompile 1.11”编译iavaZIP20.class文件,很快就可以得到该软件的JAVA代码,
main方法的全部代码如下:
public static void main(String args[])
{
iavaZIP20 iavazip20 = new iavaZIP20(args)
if(iavazip20.isEXPired())
{
System.out.println("iavaZIP20 trial time has expired. Please purchase and enter licence key.")
for(_cls13 _lcls13 = new _cls13(iavazip20, true)_lcls13.expirationFrame.isShowing())
{
try
{
Thread.sleep(1000L)
}
catch(InterruptedException _ex) { }
}
if(_cls66.isSerialRegcode(((_cls1) (iavazip20)).res.getProperty("user.id")))
{
iavazip20._fld6.remove(iavazip20._fld4)
iavazip20._fld6.add("Right", iavazip20._fld4 = iavazip20._fld0 = new _cls13(iavazip20))
iavazip20._fld6.validate()
} else
{
iavazip20.dispose()
System.exit(0)
}
}
iavazip20.show()
}
很明显,iavazip20.isExpired()就是版本控制的代码。
3.分析版本控制的语句,找到破解的方法
由于isExpired()的方法的代码如下:
public boolean isExpired()
{
return !_cls66.isSerialRegcode(super.res.getProperty("user.id", "0")) &&Long.parseLong(super.res.getProperty("magic")) magicTime <System.currentTimeMillis()
}
看了com\sfs\app\iavazip20的所有文件,由于该文件夹中的文件都是从1-66之间的整数问文件名,“class”为扩展名的类文件,分析“!_cls66.isSerialRegcode”的方法是破解的要害类应该就是66.class文件
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)