反編譯相關工具
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
(1) 如果需要修改的話 用 baksmali 執行,將 classes.dex 轉化變成 smail檔案,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