在这里讲述的其实是java反编译,主要是因为我是反编译人家的app源码入手的,就自然的挂起了羊头。
众所周知,通过dex2jar能将android app的dex解析为class文件jar包,然后通过jd等反编译工具查看源代码,貌似很容易就能对别人的劳动成果拿来主义,可果真如此理想么? 本着实事求是的原则,自己亲手试了下,结果自然是杯具的。
以下是反编译出的结果,我们简单的以一个方法为例:
public double getCORRLN(double[] paramArrayOfDouble)
{
double d1 = 0.0D;
double d2 = 0.0D;
double d3 = 0.0D;
double d4 = 0.0D;
double[] arrayOfDouble1 = new double[this.grayLevel];
double[] arrayOfDouble2 = new double[this.grayLevel];
int i = 0;
int k;
label42: int m;
if (i >= this.grayLevel)
{
k = 0;
if (k < 32)
break label171;
m = 0;
if (m < 32)
break label201;
}
for (int i1 = 0; ; i1++)
{
if (i1 >= 32)
{
if ((d3 != 0.0D) && (d4 != 0.0D))
this.CORRLN = ((this.CORRLN - d1 * d2) / Math.sqrt(d3 * d4));
return this.CORRLN;
for (int j = 0; ; j++)
{
if (j >= this.grayLevel)
{
d1 += (i + 1) * arrayOfDouble1[i];
i++;
break;
}
arrayOfDouble1[i] += paramArrayOfDouble[(j + i * this.grayLevel)];
}
label171: d3 += Math.pow(k + 1 - d1, 2.0D) * arrayOfDouble1[k];
k++;
break label42;
label201: for (int n = 0; ; n++)
{
if (n >= 32)
{
d2 += (m + 1) * arrayOfDouble2[m];
m++;
break;
}
arrayOfDouble2[m] += paramArrayOfDouble[(m + n * this.grayLevel)];
}
}
d4 += Math.pow(i1 + 1 - d2, 2.0D) * arrayOfDouble2[i1];
}
}
基本每个方法都有错误,基本每个错误都是逻辑混乱,基本没一个方法能用,简单来说,这个文件就是废的。
第一次看到这情况,心里很纳闷,不知道是dex2jar这个过程除了问题还是jd的问题,后来百度了一下(谷歌打不开,懒得折腾,别鄙视,人家度娘一样很敬业),发现这种问题很多,通过jad为核心的反编译工具(jd就是如此)都这副尿性,偏偏jad在java反编译工具中又算最好的,不知道是不是因为太久没更新的缘故,反正就是不给力。
那如何是好呢,嘿 用java开发,就没有不能破解的,工具不给力,那就人工来呗,果断搞起。
首先,找出该类的.class文件,javap隆重登场,在这里 比如该类为xohome.class, 在终端中,切入该文件所在目录,执行命令:
javap -c -private xohome.class
相信学过汇编的对这些都不陌生,如果你看得头晕,那就没辙了,因为这只是窗口大小的代码,一个中等方法大概有这样的代码500行。。。
我们开好工作窗口,将jd反编译的代码、字节码、空白文档(用作写反编译的代码用)依次列开:
这就是简单的工作台了,我本来想截大点的,可oc上传图片200K让人忧伤。。。
OK,开始正式工作,首先 我们得了解下java字节码中方法的构成,在这里,需要明白的是方法内的局部变量表,一个java方法,包含一个局部变量表,里头存储着包含参数在内的变量信息,一个java方法默认有一个参数,则是隐性参数this,也就说该表下标为0的变量为this,其次,根据你参数的数量和顺序,一次对于参数1、参数2、参数3....等等; 其次,是Exception的异常表,该表在反编译过程中不太重要:
编程,无非就是对各种参数的各种加减乘除运算,在了解了变量表之后,在基于堆栈的Java虚拟机,就剩下很简单的重复劳动了,以java字节码指令表为参考,用上述例举的方法为例:
0 > this // 参数0为this
1 > paramArrayOfDouble // 参数1为方法参数,标记为paramArrayOfDouble
2 > d1 // double d1 该变量是通过字节码信息来确定的,下述变量都是如此, 因为double变量占2字节,下一个变量下标就为4
4 > d2
6 > d3
8 > d4
10 > arrayOfDouble1 double[]
11 > arrayOfDouble2 double[]
12 > i
13 > j
public double getDouble(double[]);
Code:
0: dconst_0 // 取常数0入栈
1: dstore_2 // d1 = 0 dstore_2指令为为double类型变量赋值,可得出参数1为double类型,这里命名为d1
2: dconst_0
3: dstore 4 // d2 = 0 同d1
5: dconst_0
6: dstore 6 // d3 = 0 同d2
8: dconst_0
9: dstore 8 // d4 = 0 同d3
11: aload_0 // aload_0指令为加载局部变量0的引用,0为this
12: getfield #48 // Field grayLevel:I // 获取当前类成员变量grayLevel
15: newarray double
17: astore 10 // 上面指令为创建数组 附带信息未double 当前指令为赋值 》array1 = new double[this.grayLevel]
19: aload_0
20: getfield #48 // Field grayLevel:I
23: newarray double
25: astore 11 // 同array1 array2 = new double[this.grayLevel]
27: iconst_0
28: istore 12 // int i = 0 istore指令为int类型赋值
// if i < this.grayLevel goto 110
30: iload 12
32: aload_0
33: getfield #48 // Field grayLevel:I
36: if_icmplt 110 // if_icmplt指令为分支指令,对比当前栈的值value1是否小于value2
// else
39: iconst_0
40: istore 14 // int k = 0
// loop
42: iload 14
44: bipush 32 // byte 32入栈
// if k < 32 goto 171
46: if_icmplt 171
// else
49: iconst_0
50: istore 15 // int m = 0
52: iload 15
54: bipush 32
// if m < 32 goto 201
56: if_icmplt 201
// else
59: iconst_0
60: istore 17 // int i1
62: iload 17
64: bipush 32
// if i1 < 32 goto 262
66: if_icmplt 262
// else
69: dload 6 // 载入d3
71: dconst_0 // 载入0
72: dcmpl
73: ifeq 105 // d3!=0
76: dload 8
78: dconst_0
79: dcmpl
80: ifeq 105 // d4!=0
83: aload_0
84: aload_0
85: getfield #84 // Field CORRLN:D
88: dload_2
89: dload 4
91: dmul
92: dsub
93: dload 6
95: dload 8
97: dmul
98: invokestatic #147 // Method java/lang/Math.sqrt:(D)D
101: ddiv
102: putfield #84 // Field CORRLN:D
105: aload_0
106: getfield #84 // Field CORRLN:D
109: dreturn
// if i < this.grayLevel
110: iconst_0
111: istore 13 // int j=0
113: iload 13
115: aload_0
116: getfield #48 // Field grayLevel:I
// if j < this.grayLevel goto 142
119: if_icmplt 142
// else
122: dload_2 // 载入d2
123: iload 12 // 载入i
125: iconst_1 // 载入1
126: iadd // d2 + 1
127: i2d // int to double
128: aload 10 // arrayOfDouble1
130: iload 12 // 载入i
132: daload // arrayOfDouble1[i]
133: dmul
134: dadd
135: dstore_2 // d1 += (i + 1) * arrayOfDouble1[i];
136: iinc 12, 1 // i++
139: goto 30
// j < this.grayLevel
142: aload 10 // 载入arrayOfDouble1
144: iload 12 // 载入i
146: aload 10
148: iload 12
150: daload // arrayOfDouble1[i]
151: aload_1 // paramArrayOfDouble
152: iload 13 // j
154: iload 12 // i
156: aload_0
157: getfield #48 // Field grayLevel:I
160: imul
161: iadd
162: daload // paramArrayOfDouble[j + i*this.grayLevel]
163: dadd
164: dastore
// arrayOfDouble1[i] += paramArrayOfDouble[(j + i * this.grayLevel)];
165: iinc 13, 1
168: goto 113
// if k < 32 goto
171: dload 6
173: iload 14
175: iconst_1
176: iadd
177: i2d
178: dload_2
179: dsub
180: ldc2_w #148 // double 2.0d
183: invokestatic #153 // Method java/lang/Math.pow:(DD)D
186: aload 10
188: iload 14
190: daload
191: dmul
192: dadd
193: dstore 6
// d3 += Math.pow(k + 1 - d1, 2.0D) * arrayOfDouble1[k];
195: iinc 14, 1
198: goto 42
// if m < 32
201: iconst_0
202: istore 16 // n = 0
204: iload 16
206: bipush 32 // 32
// if n < 32 goto 233
208: if_icmplt 233
// else
211: dload 4 // d2
213: iload 15 // m
215: iconst_1 // 1
216: iadd // m + 1
217: i2d
218: aload 11
220: iload 15
222: daload
223: dmul
224: dadd
225: dstore 4 // d2 += (m + 1) * arrayOfDouble2[m];
227: iinc 15, 1
230: goto 52
if n<32
233: aload 11
235: iload 15
237: aload 11
239: iload 15
241: daload
242: aload_1 // paramArrayOfDouble
243: iload 15
245: iload 16
247: aload_0
248: getfield #48 // Field grayLevel:I
251: imul
252: iadd
253: daload
254: dadd
255: dastore
256: iinc 16, 1
259: goto 204
// i1 < 32
262: dload 8
264: iload 17
266: iconst_1
267: iadd
268: i2d
269: dload 4
271: dsub
272: ldc2_w #148 // double 2.0d
275: invokestatic #153 // Method java/lang/Math.pow:(DD)D
278: aload 11
280: iload 17
282: daload
283: dmul
284: dadd
285: dstore 8
287: iinc 17, 1
290: goto 62
0 > this
1 > paramArrayOfDouble
2 > d1
4 > d2
6 > d3
8 > d4
10 > arrayOfDouble1 double[]
11 > arrayOfDouble2 double[]
12 > i
13 > j
14 > k
15 > m
16 > n
17 > i1
code:
double d1 = 0.0D;
double d2 = 0.0D;
double d3 = 0.0D;
double d4 = 0.0D;
double[] arrayOfDouble1 = new double[this.grayLevel];
double[] arrayOfDouble2 = new double[this.grayLevel];
for(int i=0;
30 i < this.grayLevel; i++) {
110 for(int j=0;
113 j < this.grayLevel; j++) {
142 arrayOfDouble1[i] += paramArrayOfDouble[(j + i * this.grayLevel)];
}
122 d1 += (i + 1) * arrayOfDouble1[i];
}
39 for(int k=0;
42 k < 32;k++) {
171 d3 += Math.pow(k + 1 - d1, 2.0D) * arrayOfDouble1[k];
}
49 for(int m=0;
52 m < 32;m++) {
201 for(int n=0; n<32; n++) {
233 arrayOfDouble2[m] += paramArrayOfDouble[(m + n * this.grayLevel)];
}
d2 += (m + 1) * arrayOfDouble2[m];
}
59 for(int i1=0;
62 i1 < 32; i1++) {
262 d4 += Math.pow(i1 + 1 - d2, 2.0D) * arrayOfDouble2[i1];
}
69 if(d3 != 0 && d4 != 0) {
this.CORRLN = ((this.CORRLN - d1 * d2) / Math.sqrt(d3 * d4));
}
return this.CORRLN;
来源:oschina
链接:https://my.oschina.net/u/137432/blog/279442