您的位置:首页 > 编程语言 > Java开发

利用javassist修改类的字节码并自动重新打包

2017-08-12 12:33 232 查看
之前写过用javassist破解WAS的base包,但功能还不是很完善,这里增加压缩和解压方法,不用自己再重新打包了
原来破解WAS的base包代码:http://blog.csdn.net/gsls200808/article/details/44116555
注意:本文需要的第三方jar包有commons-logging-1.2.jar、javassist-3.11.0.GA.jar
项目结构如下



//主类
import java.io.IOException;

import com.vvvtimes.Utils.Compressor;
import com.vvvtimes.Utils.CrackClass;
import com.vvvtimes.Utils.Decompression;
import com.vvvtimes.Utils.StrongFileUtil;

public class Test {

// 主函数
public static void main(String[] args) throws Exception {
String oldJarPath = "E:\\Base.jar"; //原jar路径
String outClassPath ="E:\\Base"; //解压临时文件路径
String newJarPath = "E:\\Base_Crack.jar"; //重新压缩后的jar路径

//解压
File jarFile = new File(oldJarPath);
File targetDir = new File(outClassPath);
try {
Decompression.uncompress(jarFile, targetDir);
System.out.println("解压成功");
} catch (IOException e) {
e.printStackTrace();
}

//输出class
CrackClass.crack(oldJarPath, outClassPath);

//压缩
Compressor zc = new Compressor(newJarPath);
zc.compress(outClassPath);
System.out.println("压缩成功");

//删除压缩的文件夹
if(StrongFileUtil.deleteDir(new File(outClassPath))){
System.out.println("删除压缩临时文件夹成功");
}

}

}

//修改字节码的类

package com.vvvtimes.Utils;

import java.io.IOException;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

public class CrackClass
{
public static void crack (String oldJarPath ,String outClassPath) throws NotFoundException , CannotCompileException , IOException
{
// 这个是得到反编译的池
ClassPool pool = ClassPool.getDefault();

// 取得需要反编译的jar文件,设定路径
pool.insertClassPath(oldJarPath);

// 取得需要反编译修改的文件,注意是完整路径
CtClass cc1 = pool
.get("com.xxx.base.BaseLicenseUtility");

try {
// 取得需要修改的方法
CtMethod method = cc1.getDeclaredMethod("checked");
// 修改方法体直接return true;
method.setBody("{return true;}");
// 取得需要修改的方法
CtMethod method2 = cc1.getDeclaredMethod("lock");
// 修改方法体直接return true;
method2.setBody("{return true;}");
// 写入
cc1.writeFile(outClassPath);
System.out.println("写入成功");
} catch (NotFoundException e) {
e.printStackTrace();
}
}

}


//压缩类

package com.vvvtimes.Utils;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Compressor {

private static Log log = LogFactory.getLog(Compressor.class);

private static final int BUFFER = 8192;

private File fileName;

private String originalUrl;

public Compressor(String pathName) {
fileName = new File(pathName);
}

public void compress(String... pathName) {
ZipOutputStream out = null;
try {
FileOutputStream fileOutputStream = new FileOutputStream(fileName);
CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream,
new CRC32());
out = new ZipOutputStream(cos);
String basedir = "";
for (int i = 0; i < pathName.length; i++) {
compress(new File(pathName[i]), out, basedir);
}
out.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public void compress(String srcPathName) {
File file = new File(srcPathName);
if (!file.exists())
throw new RuntimeException(srcPathName + "不存在!");
try {
File[] sourceFiles = file.listFiles();
if(null == sourceFiles || sourceFiles.length<1){
System.out.println("待压缩的文件目录:" + srcPathName + "里面不存在文件,无需压缩.");
}else{
FileOutputStream fileOutputStream = new FileOutputStream(fileName);
CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream,
new CRC32());
ZipOutputStream out = new ZipOutputStream(cos);
String basedir = "";
for(int i=0;i<sourceFiles.length;i++){
compress(sourceFiles[i], out, basedir);
}
out.close();
}

} catch (Exception e) {
throw new RuntimeException(e);
}
}

private void compress(File file, ZipOutputStream out, String basedir) {
/* 判断是目录还是文件 */
if (file.isDirectory()) {
this.compressDirectory(file, out, basedir);
} else {
this.compressFile(file, out, basedir);
}
}

/**
* 压缩目录
* @param dir
* @param out
* @param basedir
*/
private void compressDirectory(File dir, ZipOutputStream out, String basedir) {
if (!dir.exists())
return;

File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
/* 递归 */
compress(files[i], out, basedir + dir.getName() + "/");
}
}

/**
* 压缩文件
* @param file
* @param out
* @param basedir
*/
private void compressFile(File file, ZipOutputStream out, String basedir) {
if (!file.exists()) {
return;
}
try {
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(file));
String filePath = (basedir + file.getName())
.replaceAll(getOriginalUrl() + "/", "");
//log.info("basedir::" + basedir);
log.info("压缩文件:" + filePath);
ZipEntry entry = new ZipEntry(filePath);
out.putNextEntry(entry);
int count;
byte data[] = new byte[BUFFER];
while ((count = bis.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
bis.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static void main(String[] args) {
Compressor zc = new Compressor("E:\\Base_Crack.jar");
zc.compress("E:\\Base\\");
System.out.println("压缩成功");
}

public String getOriginalUrl() {
return originalUrl;
}

public void setOriginalUrl(String originalUrl) {
this.originalUrl = originalUrl;
}

}

//解压类

package com.vvvtimes.Utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

//解压
public class Decompression {

protected static Log log = LogFactory.getLog(Decompression.class);

@SuppressWarnings("resource")
public static void uncompress(File jarFile, File tarDir) throws IOException {
JarFile jfInst = new JarFile(jarFile);
Enumeration<JarEntry> enumEntry = jfInst.entries();
while (enumEntry.hasMoreElements()) {
JarEntry jarEntry = enumEntry.nextElement();
File tarFile = new File(tarDir, jarEntry.getName());
if(jarEntry.getName().contains("META-INF")){
File miFile = new File(tarDir, "META-INF");
if(!miFile.exists()){
miFile.mkdirs();
}

}
makeFile(jarEntry, tarFile);
if (jarEntry.isDirectory()) {
continue;
}
FileChannel fileChannel = new FileOutputStream(tarFile).getChannel();
InputStream ins = jfInst.getInputStream(jarEntry);
transferStream(ins, fileChannel);
}
}

/**
* 流交换操作
* @param ins 输入流
* @param channel 输出流
*/
private static void transferStream(InputStream ins, FileChannel channel) {
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 10);
ReadableByteChannel rbcInst = Channels.newChannel(ins);
try {
while (-1 != (rbcInst.read(byteBuffer))) {
byteBuffer.flip();
channel.write(byteBuffer);
byteBuffer.clear();
}
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if (null != rbcInst) {
try {
rbcInst.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != channel) {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

/**
* 打印jar文件内容信息
* @param file jar文件
*/
public static void printJarEntry(File file) {
JarFile jfInst = null;;
try {
jfInst = new JarFile(file);
} catch (IOException e) {
e.printStackTrace();
}
Enumeration enumEntry = jfInst.entries();
while (enumEntry.hasMoreElements()) {
log.info((enumEntry.nextElement()));
}
}

/**
* 创建文件
* @param jarEntry jar实体
* @param fileInst 文件实体
* @throws IOException 抛出异常
*/
public static void makeFile(JarEntry jarEntry, File fileInst) {
if (!fileInst.exists()) {
if (jarEntry.isDirectory()) {
fileInst.mkdirs();
} else {
try {
fileInst.createNewFile();
log.info("解压文件:".concat(fileInst.getPath()));
} catch (IOException e) {
log.error("创建文件失败>>>".concat(fileInst.getPath()));
}
}
}
}

public static void main(String[] args) {
File jarFile = new File("E:\\Base.jar");
File targetDir = new File("E:\\Base");
try {
Decompression.uncompress(jarFile, targetDir);
System.out.println("解压成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}
//增强文件操作工具类,主要是递归删除文件夹 
package com.vvvtimes.Utils;

import java.io.File;

public class StrongFileUtil
{
public static boolean deleteDir(File someFile) {
if (!someFile.exists()) {
System.out.println("[deleteDir]File " + someFile.getAbsolutePath()
+ " does not exist.");
return false;
}
if (someFile.isDirectory()) {// is a folder
File[] files = someFile.listFiles();
for (File subFile : files) {
boolean isSuccess = deleteDir(subFile);
if (!isSuccess) {
return isSuccess;
}
}
} else {// is a regular file
boolean isSuccess = someFile.delete();
if (!isSuccess) {
return isSuccess;
}
}
if (someFile.isDirectory()) {
return someFile.delete();
} else {
return true;
}
}

}


update2018-03-09:完整代码项目地址:https://gitee.com/gsls200808/CrackBaseJar


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐