我曾经使用 dex2jar 反编译了某一个Android 应用.
然后,导入 Jar,然后一些类可以正常使用,OK
但是,仔细检查发现了问题:
就是反编译后的结果与应用之前计算的结果不同.
比如如下反编译后的EncryptUtil 类中方法:
public static String toParam(String var0, String var1) {
try {
String var3 = "param=" + of_encrypt(var0, var1) + "¶m2=" + getMd5_2(var0);
return var3;
} catch (Exception var4) {
return "param=error¶m2=error";
}
}
对于以下代码:
System.out.println("myAllParams="+EncryptUtil.toParam(originalParam1,xxdm));
System.out.println("myAllParams2="+EncryptUtil.toParam(originalParam1,xxdm));
System.out.println("myParam2_1="+EncryptUtil.getMd5_2(param));
System.out.println("myParam2_2="+EncryptUtil.getMd5_2(param));
按道理,也就是 toParam 方法调用之后的 param2的结果, 应该与 直接调用 getMd5_2的结果一样,
可以结果确不是一样的.
上面代码输出如下:
myAllParams=param=2tb3nq2qay2o2s45ch2mqawf2twpf52pqe5m1vc4lm1ltd391o6vsm1oseh62ojcs92ridda1tjxn41r68rl1pz0hl2qbqoo2s4j8q2hdhkv291ui72il9zc003erq¶m2=6d749a8bf841a5d3d772832367d5c0e6
myAllParams2=param=2tb3nq2qay2o2s45ch2mqawf2twpf52pqe5m1vc4lm1ltd391o6vsm1oseh62ojcs92ridda1tjxn41r68rl1pz0hl2qbqoo2s4j8q2hdhkv291ui72il9zc003erq¶m2=6d749a8bf841a5d3d772832367d5c0e6
myParam2_1=7aac8cb9cdf9898077a262d324dd86b5
myParam2_2=7aac8cb9cdf9898077a262d324dd86b5
但是其实上面对于 param2的计算都是错误的
正确的计算结果 ,也就是原来应用的计算结果是:
param2=338f3b6b250342cc5b1117a6346b0c89
直接从反编译出来的代码看不出是什么导致了问题:
但是感觉 调用toParam 跟直接调用 getMd5_2有差别
于是尝试分析最原始的 toParam 的 smali 代码
如下:
.method public static toParam(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
.locals 3
.param p0, "as_str" # Ljava/lang/String;
.param p1, "as_key" # Ljava/lang/String;
.prologue
.line 34
:try_start_0
new-instance v1, Ljava/lang/StringBuilder;
const-string v2, "param="
invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
invoke-static {p0, p1}, LEncryptUtil;->of_encrypt(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
const-string v2, "¶m2="
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
invoke-static {p0}, LEncryptUtil;->getMd5_2(Ljava/lang/String;)Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
:try_end_0
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0
move-result-object v1
.line 37
:goto_0
return-object v1
.line 36
:catch_0
move-exception v1
move-object v0, v1
.line 37
.local v0, "e":Ljava/lang/Exception;
const-string v1, "param=error¶m2=error"
goto :goto_0
.end method
还是没有发现可疑的地方
欢迎任何线索,指点
1
exch4nge 2015-03-03 11:37:44 +08:00 1
看了半天没明天楼主的意思……是我理解能力差么……
|
2
clino 2015-03-03 11:46:24 +08:00 1
要么是偷别人的东西要么是黑别人的东西?
|
3
Sinute 2015-03-03 11:55:07 +08:00 1
反编译的逻辑不一定就是正确的
我以前就踩过一个坑 反编译结果类似 ``` v0 += "0"; ``` 实际应该是 ``` v0 = "0" + v0; ``` 一层一层进去慢慢调吧 |
4
yangff 2015-03-03 12:00:33 +08:00 via Android 1
你一个用的originalParam1一个用的param。。
|
5
banxi1988 OP |
6
banxi1988 OP |
7
invite 2015-03-03 13:19:57 +08:00
把jar包拿出来大家一起看看。
|
8
kaizixyz 2015-03-03 15:02:27 +08:00 1
EncryptUtil类名都有。为何要用反编译的。Google之啦~
|
9
banxi1988 OP @kaizixyz 这个 Google 过没有相同对应的,
再说在 明显是自己写的 EncryptUtil, 写 Java 的,估计很多都有自己的 StringUtil 或者,EncryptUtil, 类名相同而已,也不是某一个开源库的类. 不过,还是谢谢指点. |
10
sinsin 2015-03-03 18:51:41 +08:00
这个反编译的Md5_2真没看懂吔。。。
* getMd5(var0).split(""),这里用空白RegExp("")来split,得到的是一个包含var0每个字符的数组,而且最前面还多送个空白元素? |
11
RecursiveG 2015-03-03 21:33:09 +08:00
有没有原版getMd5_2的输入输出?
|
12
durrrr 2015-03-04 10:50:47 +08:00 via iPad
of_encrypt 是不是做了什么全局操作?比如改变字符编码什么的。
我觉得最该贴出来的代码是这个。 |
13
banxi1988 OP @durrrr 这个 of_encrypt 没有改变全局的操作.
或者说 getMd5_2 也没有读取全局变量的操作. getMd5_2引用的其他自定义函数也只是 生成标准 MD5字符串的操作. 昨天我自己尝试解析了下 smali 代码,然后调用生成的结果 ,跟 dex2jar 生成的代码,调用产生的结果是一样的. @RecursiveG getMd5_2方法的 一个原版的输入: "nj=2014&yxid=01" 输出:"7bbc20a3bad140e7fcdc52442d3c7b9d" |
14
RecursiveG 2015-03-04 18:57:27 +08:00
这是个结果正确的代码,但是原因还是不明。。。
感觉像是 @sinsin 说的,`split("")` 的时候前面多送了个空白元素。 但是我实际测试的时候没有多送啊。。。。。 难道是行为不一样? ``` java public static String getMd5_2(String originStr){ String mystr=Standard_MD5_lowercase(originStr); String result=""; for(int i=0;i<mystr.length();i++){ if(i==2||i==9||i==16|i==24)continue; result+=mystr.charAt(i); } return Standard_MD5_lowercase(result); } ``` |