- 浏览: 290160 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (155)
- Liferay portal研究 (23)
- spring研究 (7)
- Displaytag (2)
- Flash Builder (0)
- 搜索引擎 (12)
- 杂项 (17)
- SCM管理 (7)
- Jquery (5)
- Linux (7)
- Oracle (10)
- httpd集成 (3)
- Maven2 (5)
- 企业管理 (1)
- tomcat高级 (4)
- dos命令 (1)
- ldap (2)
- Java (8)
- webservice (1)
- jetty代码研究 (3)
- OpenCMS (1)
- JMX (2)
- hibernate (5)
- Ant (1)
- js tree (4)
- Quartz (0)
- CMS (1)
- springside (1)
- proxool (1)
- freemarker (1)
- Cookie (1)
- CAS SSO (4)
- mysql (1)
- php (1)
- js (2)
- Asset (1)
- openmeeting (1)
- h2数据库 (2)
- wcf vs java ws (1)
最新评论
-
22199143:
...
当在重启Tomcat容器时 Exception in Thread "HouseKeeper" java.lang.NullPointerException -
liuqq:
一直用Oracle开发,几乎没有接触过其他数据库。使用Mysq ...
The Nested Set Model -
yjsxxgm:
yjsxxgm 写道FFFFFFFFFFFFFFFWWW
java 访问wcf -
yjsxxgm:
FFFFFFFFFFFFFFF
java 访问wcf -
hjp222:
scanIntervalSeconds 是重新启动,并非真正的 ...
Jetty 热部署
现在的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);
}
注解:
欢迎有此兴趣的朋友和我交流。
以下是同一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);
}
注解:
欢迎有此兴趣的朋友和我交流。
发表评论
-
Eclipse
2010-05-26 08:39 1201Eclipse 快捷键(1) Ctrl+1 快 ... -
A bridge method
2010-04-08 21:37 177413 A bridge method ... -
struts2原理分析
2010-04-01 10:23 5748读者如果曾经学习过Struts1.x或者有过Struts1.x ... -
1,失血模型2,贫血模型3,充血模型4,胀血模型
2010-03-25 20:34 3191为了补大家的遗憾,在此总结下ROBBIN的领域模型的一些观点和 ... -
myeclipse 启动优化
2010-01-25 21:10 1796解决MyEclipse吃内存,让MyE ... -
ca 证书
2010-01-21 12:21 884http://jeffyyko.blog.51cto.com/ ... -
jpolite2
2010-01-19 20:15 1818http://www.trilancer.com/jpolit ... -
p3p iframe session共享及其它
2009-12-22 08:27 3429IE浏览器iframe跨域丢失Session问题 在开发中, ... -
摩斯密码
2009-12-11 21:45 1303突然对密斯密码很感兴趣,所以在网上找了一些有关的资料,供大家参 ... -
Win2003环境下用Apache整合Tomcat6和IIS服务器共用80端口
2009-12-03 10:15 3845Win2003环境下用Apache整合Tomcat6和I ... -
好的网址wiget
2009-09-30 10:47 863tree outlook style webfxtree:ht ... -
比较好的博客
2009-09-29 22:03 808一些通用模块:www.faqee.com 一些通用模块的作者: ... -
vm 修改磁盘大小
2009-09-26 09:33 1322成功检核过的: vmware-vdiskmanager -x ... -
vmtools 安装
2009-09-19 21:42 1538、VMware Tools安装手记(For Linux Gue ... -
vm被打开问题
2009-09-19 21:09 777启动系统报告This virtual machine appe ... -
搭手架项目
2009-09-16 21:50 9841.Appfuse[java] 2.rapid-framewo ...
相关推荐
JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA...
java反编译 java 反编译 java反编译 java 反编译 java反编译 java 反编译 java反编译 java 反编译 java反编译 java 反编译
1.java反编译工具 2.绿色版占用内存少 3.好用,值得下载
JAVA反编译插件文件
java反编译的工具,非常好用 java反编译的工具,非常好用 java反编译的工具,非常好用 java反编译的工具,非常好用 java反编译的工具,非常好用 java反编译的工具,非常好用 java反编译的工具,非常好用 java反编译...
JAVA反编译 JAVA反编译JAVA反编译
可以将java编译后的class文件或者jar包反编译出来,看到编译前的代码
java反编译软件java反编译软件java反编译软件
.class文件反编译成java文件 支持类名索引 方法名索引 字段名索引 此软件仅用于学习使用
JAVA反编译文件解决中文乱码问题
JAVA反编译软件(可将class文件反编译为java文件)
java反编译工具,java反编译工具,java反编译工具 一款很好的java反编译工具 一款很好的java反编译工具一款很好的java反编译工具
jd-gui ,java Class反编译工具 ,java jar反编译工具。经济实惠只要1分。这个是在凑字数。这个是在凑字数。这个是在凑字数。
安卓、Java反编译工具的工具 可以把一编译过的文件反编译成java'文件
java反编译java反编译java反编译java反编译java反编译java反编译java反编译java反编译java反编译java反编译
java 反编译,jd-gui.exe打开class文件即可
jad-java反编译工具eclipse插件,jad-java反编译工具eclipse插件
java反编译java反编译java反编译java反编译java反编译java反编译
java反编译jd-gui-1.6.6.jar
该软件用于java的class文件反编译,实测好用,欢迎大家下载,有问题可以留言。。。。。