一 apk反编译
将apk文件解压后有两部分文件需要处理,一种是xml文件,另一种一个dex文件(.dex)
对xml文件进行包的解析,一般有两种方式:apktool(推荐)和AXMLPrinter2.jar;
从dex到class公认dex2jar.bat,实现反编译;公认的强者;
而class到java的方式要更多样化一些,因为只是查看反编译后的代码:jd-gui(推荐),Jodeclipse(Jode的Eclipse插件),JadClipse(Jad的Eclipse插件)。
dex解包
首先把apk文件改名为.zip,然后解压缩其中的class.dex文件,它就是java文件编译再通过dx工具打包成的。
把class.dex拷贝到dex2jar.bat所在目录。运行dex2jar.bat class.dex,生成classes.dex.dex2jar.jar。
运行JD-GUI工具(绿色软件,好用的软件!),打开上面的jar文件,即可看到java源代码。
file-saveall将java源码保存为zip文件
资源文件解包
1 安装apktool,将apk反编译
将smali文件包删除.
2 将上一步保存的源码解压,在此建立一个src目录.将源码放入src下,导入到eclipse中.结构如下- 反编译完成.错误会很多..可以选择不同的工具来反编译,然后交叉对比.我一般使用jd-ui和jad-eclipse插件来编译.
jad-eclipse配置
二 错误代码还原规则
if…else 语句:
反编译代码
1 2 3 4 5 6 7 | if (paramBoolean)
paramTextView.setTextColor(-16727809);
while (true)
{
return;
paramTextView.setTextColor(-1315861);
} |
还原后
1 2 3 4 5 6 7 8 9 |
if (paramBoolean)
{
paramTextView.setTextColor(-16727809);
}
else
{
paramTextView.setTextColor(-1315861);
} |
会把if ..esle 反编译成 if …while(true)结构.
反编译代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | if (paramInt1 != 1)
break label185;
if (this.countChild_1 == null)
{
this.countChild_1 = new PokerCountChild(this.mContext);
this.countChild_1 = new PokerCountChild(this.mContext);
this.countChild_1.setPosition((int)(0.83D * BaseGameActivity.screenWidth
- this.countChild_1.getWidth()), (int)(0.2D * BaseGameActivity.screenHeight));
this.countChild_1.setCount(paramInt2);
addOneChild(this.countChild_1);
if (paramInt2 == 0)
this.countChild_1.setAlpha(0);
}
this.countChild_1.setCount(paramInt2);
}
label185:
do
return;
while (paramInt1 != 2);
if (this.countChild_2 == null)
{
this.countChild_2 = new PokerCountChild(this.mContext);
this.countChild_2 = new PokerCountChild(this.mContext);
this.countChild_2.setPosition((int)(0.17D * BaseGameActivity.screenWidth),
(int)(0.2D * BaseGameActivity.screenHeight));
this.countChild_2.setCount(paramInt2);
addOneChild(this.countChild_2);
if (paramInt2 == 0)
this.countChild_2.setAlpha(0);
}
this.countChild_2.setCount(paramInt2); |
还原
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | if(i == 1)
{
if(countChild_1 == null)
{
countChild_1 = new PokerCountChild(mContext);
countChild_1 = new PokerCountChild(mContext);
countChild_1.setPosition((int)(0.83D *
(double)BaseGameActivity.screenWidth - (double)countChild_1.getWidth()),
(int)(0.2D * (double)BaseGameActivity.screenHeight));
countChild_1.setCount(j);
addOneChild(countChild_1);
if(j == 0)
countChild_1.setAlpha(0);
}
countChild_1.setCount(j);
} else
if(i == 2)
{
if(countChild_2 == null)
{
countChild_2 = new PokerCountChild(mContext);
countChild_2 = new PokerCountChild(mContext);
countChild_2.setPosition((int)(0.17D *
(double)BaseGameActivity.screenWidth), (int)(0.2D *
(double)BaseGameActivity.screenHeight));
countChild_2.setCount(j);
addOneChild(countChild_2);
if(j == 0)
countChild_2.setAlpha(0);
}
countChild_2.setCount(j);
return;
} |
会将语句倒序,出现break label结构
反编译代码
jd-gui有时会将whilei语句翻译成if,此处要将if改成while
switch语句
反编译代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | switch (this.mBand)
{
default:
case 0:
case 1:
case 2:
}
while (true)
{
return;
this.mBand.setText("FM1");
continue;
this.mBand.setText("FM2");
continue;
this.mBand.setText("AM");
} |
还原
1 2 3 4 5 6 7 8 9 10 11 12 13 | switch (mBand)
{
case 0:
mBand.setText("FM1");
break;
case 1:
mBand.setText("FM2");
break;
case 2:
mBand.setText("AM");
break;
default:
} |
switch规则就是一个continue对应一个case.要注意是是要外层的continue才算数,在if里的continue不算
随时随地看视频