使用javassist处理字节码混淆过的class文件

java程序员,有时候为了某种特定目的比如调试或者增强代码,不得不反编译一下代码,然后把内容修改成自己想要的,再从新打包回jar文件里面。
当然,很多时候为了防止这种事情发生,于是代码混淆工具诞生了。一般代码级别的混淆,反编译之后基本无法获得原有的逻辑,不过仍然可以直接修改代码然后再编译打包回去;比较厉害的情况是字节码直接混淆,这种情况有可能反编译出来比较奇特的代码,我最近就遇到这样的问题,反编译出来竟然是这样的结构(忽略了函数体):

private static String a(String[] as);
public static void a();
private static String a();
private static String a(String as);
private static void a(Date paramDate1, Date paramDate2);


这样的代码没法修改,因为根本不可能编译通过,所以只能在字节码级别做文章,尽量简单的解决混淆带来的麻烦。
好在javassist就可以处理这样的问题,除了动态增强之外,javassist也可以把增强过的类,从新写入到文件中。

import java.io.File;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.expr.ExprEditor;
import javassist.expr.MethodCall;

public class Pathcer {
static String tempDir = "c:\\output1";
static String className = "com.company.fQ";

public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get(className);

File f = new File(tempDir);
if (!f.exists())
f.mkdirs();

CtMethod targetM = null;

CtMethod[] methos = cc.getDeclaredMethods();
//找到private staitc void a();
for (CtMethod m : methos) {
if (!m.getName().equals("a"))
continue;
if (m.getReturnType().getName().equals("void"))
continue;
CtClass arg[] = m.getParameterTypes();
if (arg != null && arg.length > 0)
continue;

targetM = m;
break;
}

if (targetM == null) {
System.out.println("not found the target mehtod!exit now.");
System.exit(1);
}
//直接写java代码,可以动态编译进去;好消息是setBody函数里面可以写任何东西。
targetM.setBody("{return \"This is my code.\";}");

//注意因为class已经加载过了,所以必须从新加载一次。
ClassPool.getDefault().get(className).writeFile(f.getAbsolutePath());
}

}




javassist可以增强任何东西,比如给一个类添加接口,添加父类,添加函数,删除函数,总之几乎无所不能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值