dex2jar 下载地址,百度下载(http://code.google.com/p/dex2jar/downloads/list)
APK tool,百度下载(https://bitbucket.org/iBotPeaches/apktool/downloads/ ,https://ibotpeaches.github.io/Apktool/install/ )
jd gui
http://code.google.com/p/innlab/downloads/list
http://java.decompiler.free.fr/?q=jdgui
jadx (用法:https://segmentfault.com/a/1190000012180752#articleHeader7)
(下载地址: https://github.com/skylot/jadx/tags )
直接运行bin目录中的jadx-gui.bat,选择apk文件即可。
有些apk的体积比较大的时候,反编译的时候会卡住或者假死。
解决方案:
使用记事本或者notpad++打开jadx-gui.bat
更改应用运行内存
变更前:
set DEFAULT_JVM_OPTS=
变更后:
set DEFAULT_JVM_OPTS=-Xmx1024M
请注意这里面有个减号”-“
例如:编译新版本的微信的时候,建议将该值更改为5GB,也就是-Xmx5120M
请根据自己电脑的实际配置进行变更
Android 反编译资料整理 http://rayleeya.iteye.com/blog/841076
Android反编译后代码阅读 https://www.cnblogs.com/zjzyh/p/6601204.html
android 反编译 代码 和源码对应关系 http://www.codes51.com/itwd/748452.html
用JD-GUI反编译出来的Andorid代码,里面指向的xml都是数字了,
SetContectView(2130903066)
这个2130903066这个View是指向的哪个XML
在JD-GUI哪里能够找到,我每个类都看遍了
感觉他这里指向的数字是相应的资源地址
但是我怎么看XML对应成哪些资源地址
解决方案
2130903066的十六进制是7F03001A,在res/values/public.xml里搜索7F03001A就知道对应的哪个id了
Android应用逆向——分析反编译代码之大神器 https://blog.csdn.net/charlessimonyi/article/details/52027563
关于apk的反编译修改,你不知道的事,尤其是官方Rom https://blog.csdn.net/bingo1991/article/details/7768889
一、 获取apk资源
先cd 到 apktool.bat 的文件夹下面
apktool.bat d -f [apk文件 ] -o [输出文件夹]
例子: java -jar apktool.jar d -f SetupWizard.apk -o setup
反编译出来的资源随后会在 setup 文件夹下
二、 获取apk代码
(1) 将 apk 变成 zip 取出其中的 class.dex
(2) 想要查看的话 用,首先将 class.dex 放到,dex2jar 工具的目录下
执行 dex2jar.bat classes.dex
或者 d2j-dex2jar.bat classes.dex
(主要还是看你的下面有哪个)
然后生成 classes_dex2jar.jar
(3) 然后用工具 jd-gui.exe 打开 jar 文件查看
(4) 代码中的id 对应 public.xml 10进制在计算器中转换到 16进制,public.xml查找
三、 baksmali
java -jar baksmali-1.4.2.jar -o classout/ classes.dex
会生成 out目录,里面是 smail文件
(2) 修改后重新打包 out 成 classes.dex
java -jar smali-1.4.2.jar -o classes.dex classout
四、问题:
1、 反编译出来的类,用 jd-gui查看,有些文件显示INTERNAL ERROR 解决办法(http://www.cnblogs.com/langtianya/p/5140226.html)
下载其他的代码查看工具,如:
https://github.com/deathmarine/Luyten
https://github.com/skylot/jadx
(1) 保存反编译出来的代码----> 文件
把需要反编译的文件用JD-GUI打开点击->File->Save JAR soureces
选择后导出一个zip压缩包!里面就是所有的源代码了
java -jar xxx.exe 执行
2、Android:逆向工程之资源ID还原小工具 https://blog.csdn.net/annkie/article/details/7790026
五、 错误代码还原规则
反编译中颜色值 -16777216 ---- 对应的是 Color里面的
System.out.println(String.format("%08x",-16777216));
android的颜色值16进制范围是00000000-ffffffff
int | BLACK | -16777216 | 0xff000000 |
int | BLUE | -16776961 | 0xff0000ff |
int | CYAN | -16711681 | 0xff00ffff |
int | DKGRAY | -12303292 | 0xff444444 |
int | GRAY | -7829368 | 0xff888888 |
int | GREEN | -16711936 | 0xff00ff00 |
int | LTGRAY | -3355444 | 0xffcccccc |
int | MAGENTA | -65281 | 0xffff00ff |
int | RED | -65536 | 0xffff0000 |
int | TRANSPARENT | 0 | 0x00000000 |
int | WHITE | -1 | 0xffffffff |
int | YELLOW | -256 | 0xffffff00 |
(1)if…else 语句: 会把if ..esle 反编译成 if …while(true)结构.
反编译代码
if (paramBoolean)
paramTextView.setTextColor(-16727809);
while (true)
{
return;
paramTextView.setTextColor(-1315861);
}
还原后
if (paramBoolean)
{
paramTextView.setTextColor(-16727809);
}
else
{
paramTextView.setTextColor(-1315861);
}
(2) 会将语句倒序,出现break label结构
反编译代码
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);
还原
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) ----------------------return while 替换成 else if
{
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;
}
(3) switch语句
反编译代码
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");
}
还原
switch (mBand)
{
case 0:
mBand.setText("FM1");
break;
case 1:
mBand.setText("FM2");
break;
case 2:
mBand.setText("AM");
break;
default:
}
(4)
if(rt != 0)
break MISSING_BLOCK_LABEL_369;/为什么这里会有这段东西的~?
filepath = fc.getSelectedFile();
替换成 return