java反编译心得

现在的JDK都是1.4/1.5用比较老的JAD和ECLIPSE的JODE进行反编译,出来的代码的可读性比较差,而且比较多错误.

以下是同一CLASS文件反编译出来的代码:

可以看出:

1、JODE出来的代码的可读性最好,不过有CLASS文件代码用JODE是反编译不出来出现异常;

2、JAD出来的代码经常要进行大量整理;

3、JODE和JAD对混混淆过的代码,变量的顺序可能会不一样,自变量的命名,JODE会好一些。

4、对于PUSH和POP,左修整时候,可以自己加自变量,临时存储;

5、JAVA对于表达式或函数参数,是从右到左进行解释的。函数参数,最后PUSH的,是最右边的参数;对于

等号赋值也是先右后左进行出栈。

/**
* jode
* @param i
* @param i_1_
* @param graphics
*/
private void b(int i, int i_1_, Graphics graphics) {
graphics.setColor(0);
if (((h) this).e.f == null)
graphics.setColor(6710886);
else {
int tmp=0;
if (((h) this).e.f.size() == 1) {
PUSH g.c;
PUSH = 64;
} else {
PUSH g.c;
PUSH = 80;
}
g.a(POP, POP, 0, 16, 16, i, i_1_, graphics);
}
StringBuffer stringbuffer = new StringBuffer();
if (((h) this).e.e > 0) {
graphics.setColor(16711680);
stringbuffer.append('[');
stringbuffer.append(((h) this).e.e);
stringbuffer.append("\u65b0\u6d88\u606f"); //新消息
stringbuffer.append(']');
}
if (((h) this).f)
graphics.setColor(16777215);
stringbuffer.append(((h) this).e.a());
graphics.drawString(a(stringbuffer.toString(), 158), i + 16 + 1,
i_1_ + 1, 20);
}

/**
* jad
* @param i
* @param j
* @param g1
*/
private void b(int i, int j, Graphics g1)
{
g1.setColor(0);
if(e.f != null) goto _L2; else goto _L1
_L1:
g1.setColor(0x666666);
goto _L3
_L2:
if(e.f.size() != 1) goto _L5; else goto _L4
_L4:
g.c;
76;
goto _L6
_L5:
g.c;
95;
_L6:
0;
19;
19;
i;
j;
g1;
g.a();
_L3:
StringBuffer stringbuffer = new StringBuffer();
if(e.e > 0)
{
g1.setColor(0xff0000);
stringbuffer.append('[');
stringbuffer.append(e.e);
stringbuffer.append("\u65B0\u6D88\u606F");
stringbuffer.append(']');
}
if(f)
g1.setColor(0xffffff);
stringbuffer.append(e.a());
g1.drawString(a(stringbuffer.toString(), 219), i + 19 + 1, j + 1, 20);
return;
}

// public final void a(boolean bool) {
// if (bool) {
// PUSH this;
// PUSH "BD";
// } else {
// PUSH this;
// PUSH "AA";
// }
// ((n) POP).d = POP;
// }
//
public final void a(boolean flag)
{
if(!flag){
this.d="AA";
}else{
this.d="BD";
}

// if(!flag) goto _L2; else goto _L1
//_L1:
// this;
// "BD";
// goto _L3
//_L2:
// this;
// "AA";
//_L3:
// d;
}
再加几个用例:
一般情况下Java应用的开发者为了保护代码不被别人抄袭,在生成class文件的时候都java文件进行了混淆,这种class文件用反编译工具得到的结果很难看懂,并且不能进行编译。本文从研究的角度,浅析如何读懂这种反编译过来的文件。

例子一:赋值
反编译过来的代码如下:
Node node;
Node node1 = _$3.getChildNodes().item(0);
node1;
node1;
JVM INSTR swap ;
node;
getChildNodes();
0;
item();
getChildNodes();
0;
item();
getNodeValue();
String s;
s;
原始语句:
Node node;
Node node1 = currDocument.getChildNodes().item(0);
node = node1;
String s = node.getChildNodes().item(0).getChildNodes().item(0).getNodeValue();
注解:
JVM INSTR swap ; //赋值语句
练习:
String s1;
String s8 = node.getChildNodes().item(1).getChildNodes().item(0).getNodeValue();
s8;
s8;
JVM INSTR swap ;
s1;
10;
Integer.parseInt();
int i;
i;


例子二:不带参数创建对象
反编译过来的代码如下:
JVM INSTR new #244 <Class CrossTable>;
JVM INSTR dup ;
JVM INSTR swap ;
CrossTable();
CrossTable crosstable;
crosstable;

原始语句:
CrossTable crosstable = new CrossTable();
注解:
练习:
JVM INSTR new #246 <Class Database>;
JVM INSTR dup ;
JVM INSTR swap ;
Database();
Object obj;
obj;

例子三:带参数创建对象
反编译过来的代码如下:
JVM INSTR new #262 <Class StringBuffer>;
JVM INSTR dup ;
JVM INSTR swap ;
String.valueOf(s2);
StringBuffer();
s.substring(j, i);
append();
s6;
append();
toString();
s2;

原始语句:
s2 = (new StringBuffer(String.valueOf(s2))).append(s.substring(j, i)).append(s6).toString();
注解:
此语句实际上是:s2 += s.substring(j, i) + s6;
练习:

例子四:for循环
反编译过来的代码如下:
int k = 0;
goto _L4
_L8:
...
k++;
_L4:
if(k < as.length) goto _L8; else goto _L7

原始语句:
for(int k=0;k < as.length;k++)
{
...
}
注解:

例子五:while循环
反编译过来的代码如下:
String s1 = "";
goto _L1
_L3:
JVM INSTR new #262 <Class StringBuffer>;
JVM INSTR dup ;
JVM INSTR swap ;
String.valueOf(s1);
StringBuffer();
_$2(resultset, s, l);
append();
toString();
s1;
_L1:
if(resultset.next()) goto _L3; else goto _L2

原始语句:
String s1 = "";
while(resultset.next())
{
s1 = s1 + resultSetToString(resultset, s, l);

}
注解:


欢迎有此兴趣的朋友和我交流。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值