作为一个流氓程序猿,打劫放火的时候,经常需要修改别人已经编译的类,在一些,没有源代码,隔离内网,破解注册码,等特殊场景下。
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类了
本文介绍了在隔离网络环境中修改已编译类的方法,包括直接获取源代码、使用javassist等字节码工具修改class文件及创建独立项目来实现类的修改。
1925

被折叠的 条评论
为什么被折叠?



