没有源代码,如何修改别人的类

原创
2014/08/07 11:23
阅读数 332

作为一个流氓程序猿,打劫放火的时候,经常需要修改别人已经编译的类,在一些,没有源代码,隔离内网,破解注册码,等特殊场景下。

1. 显而易见   

    想办法把源代码弄过来,导入项目,凑齐Jar包,然后。。没有了

2. 祭出神器   

    招式:使用字节码工具,比如 javassist,jbe 直接对class文件进行修改。屠龙宝刀在手,迎刃而解。

    场景:修改hive-jdbc中文乱码问题的时候,当时在隔离内网,没法弄到源代码。

    适用:密界最喜欢用的工具之一了吧,适合各种破解游戏,注册,验证一类的。俗称爆破

    缺点:需要一点内功,要耍的动Java字节码。当然javassist要容易点。

    代码:

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

public class HivePatch {
	/**
	 * DESC :fix about jdbc utf-8
	 * 
	 * @param jarPath hive-jdbc-jar path
	 * 
	 */
	public void patch(String jarPath){
		try{
			 ClassPool pool = ClassPool.getDefault();
			 pool.insertClassPath(jarPath) ;
			 CtClass cc = pool.get("org.apache.hadoop.hive.jdbc.HiveQueryResultSet");                 
			 CtMethod ms=cc.getDeclaredMethod("next");
			 ms.instrument(
			     new ExprEditor() {
			         public void edit(MethodCall m) throws CannotCompileException
			         {
			             if (m.getClassName().equals("java.lang.String")
			                           && m.getMethodName().equals("getBytes")){
			            	 m.replace("{$_=rowStr.getBytes(\"UTF-8\");}");
				             System.out.println("line "+m.getLineNumber()+" change .");
			             }
			         }
			     });
			 cc.writeFile(jarPath);
		 }catch(Exception e){
			 e.printStackTrace();
		 }
	}
	public static void main(String[] args) {
		 new HivePatch().patch("/home/hive-jdbc-0.9.0.jar");
	}
}

3. 返璞归真

    招式:不用神功,手里也没有神器,一片叶子也能破敌,从没见过这么修改类的,颇有返璞归真的境界。

    场景:修改elasticsearch-hadoop-1.3.0.M1 日期类型格式问题的时候,还在隔离内网,没法弄到源代码。

    适用:实在字节码工具没有,源代码也没有的时候,空手套白狼吧。

    缺点:要修改的类的依赖关系复杂的时候,工作量倍增。

    代码:

public class HiveValueReader extends WritableValueReader {

    @Override
    protected Object date(String value) {
        return new TimestampWritable(new Timestamp(DatatypeConverter.parseDateTime(value).getTimeInMillis()));
    }

    @Override
    protected Class<? extends Writable> dateType() {
        return TimestampWritable.class;
    }
}

这里的date方法在格式化 yyyy-MM-dd HH:mm:ss.SSS 的时候会有问题,我们要修改date方法的时候,可以创建个项目,把这个类的依赖都创建空类

然后把所有的依赖方法都,创建空方法,如图

这样,我们就可以修改编译,我们的HiveValueReader类了

展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部