APK反編譯後程式碼分析(一)
http://blog.csdn.net/ordinaryjoe/article/details/8626010#comments
一,用jd-gui.exe等工具檢視原始碼。如何你不會,可以參看此文章:
http://blog.csdn.net/hp_2008/article/details/8207879
可以到以下連線下載視覺化反編譯工具:
http://download.csdn.net/detail/hp_2008/5099046
二,反編譯後的原始碼,是亂的,看不太懂。這是因為開發者在釋出APK時,一般都會用程式碼混淆器將原始的原始碼打亂,
這也是防盜的一種方法。但是再怎樣防,道高一尺,魔高一丈,用反編譯工具很輕鬆的就可反編譯成原始碼。要想做到反編譯成一點也看不懂的程式碼,這很難,
在Android Java開源的世界裡就更難做到了。當然你可以把核心的放到中間層,用C/C++封裝成庫,通過JNI呼叫,這樣要想反編譯庫就有難度了。
用混淆器打亂的程式碼,反編譯後,要想看懂也不是一件容易的事。因為大部人都會用免費的混淆器來混淆原始碼,大部份反編譯過來的程式碼就有一定的規則可尋:
(本人水平有限,如有什麼不對的地方,還請指教,非常非感)
反編譯後的程式碼一般會產生以下結構的程式碼,(程式碼結構是個人總結的,如有雷同,純屬巧合)比較難看懂,本文章根據實現情況對這幾種結構做個簡單說明。
1,反編譯後的程式碼:if while結構
if (BTActivity.access$2300(this.this$0))
{
int i = BTActivity.access$700(this.this$0).sendCommand(1028, 4, paramInt);
BTActivity.access$2500(this.this$0).notifyDataSetChanged();
}
while (true)
{
return;
Bluetooth localBt = BTActivity.access$700(this.this$0);
int k = BTActivity.access$600(this.this$0);
int l = localBt.sendCommand(1026, paramInt, k);
}
(1)只分析邏輯
很顯然上面的程式碼也不是原始的原始碼,但是很接近了,如果要想完成還原,還得自己改。
分析上面的程式碼:這裡應該有一個if else的邏輯。從上面的程式碼分析,return下的程式碼
應該是永遠不會被執行,但這是不可能的。所以上面的程式碼邏輯(我們先不看語句)應該是這樣的,
去掉while和return,加上else,修改後如下:
if (BTActivity.access$2300(this.this$0))
{
int i = BTActivity.access$700(this.this$0).sendCommand(1028, 4, paramInt);
BTActivity.access$2500(this.this$0).notifyDataSetChanged();
}
else
{
Bluetooth localBt = BTActivity.access$700(this.this$0);
int k = BTActivity.access$600(this.this$0);
int l = localBt.sendCommand(1026, paramInt, k);
}
這樣的邏輯才是作者的本意。
(2)邏輯分析完了,應該分析語句.
A,這個真的很難看懂。像這句:int i = BTActivity.access$700(this.this$0).sendCommand(1028, 4, paramInt);
很顯然,這個是引用外部的一個類中的一個方法。然後返回整類,從下面的語句可以得知,這個返回值是用不到的。所以這句可去掉int i
還原上面的語句應該是這樣的:
BTActivity.access$700(this.this$0).sendCommand(1028, 4, paramInt);
B,access$700是什麼意思呢。這個應該是BTActivity類中的一個對像,然後這個物件有sendCommand方法。這樣你就可以去查這個BTActivity類定義的哪個物件
有這樣一個方法了,這好理解。
不好理解的是這句:int k = BTActivity.access$600(this.this$0); 這句初步還原就是去掉int k。
然後是這個access$600,它對應的是BTActivity中的哪個方法呢。這很難確定,所以我說要猜,那有沒有方法呢。當然有:
1,看這個類中有多少個方法,如果只有一個,那指定就是它了。
2,如果有多個,那就要看引數。如果只有一個方法的引數與之相對應,那一定是它。
3,如果引數一樣的也有多個。那看邏輯。如果看不出來,只有猜:)。或參加自己的邏輯。
(3)為什麼會出現像access$700(方法不一樣,後面的數字也不一樣)這樣的方法名呢,原因是,呼叫者和被調者不在同一個類中。內部類也不行,如果
兩者在同一個類中,比如同類的方法呼叫,那反編譯後的名字一定是可看懂的。不會是有數字的名字。
(4) 再舉一個更簡單的if else例
反編譯後的程式碼:
if (paramBoolean)
paramTextView.setTextColor(-16727809);
while (true)
{
return;
paramTextView.setTextColor(-1315861);
}
還原成真正的原始程式碼,按我上面說的應該是:
if (paramBoolean)
{
paramTextView.setTextColor(-16727809);
}
else
{
paramTextView.setTextColor(-1315861);
}
以後碰到這樣的if while還原就應該是上面的樣子。
2, 反編譯後的程式碼:switch case while結構
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)分析邏輯:根據mBand的不同值,設定文字的顯示內容。
這個很好看懂,不再多說,還原成原始程式碼:
switch (mBand)
{
case 0:
mBand.setText("FM1");
break;
case 1:
mBand.setText("FM2");
break;
case 2:
mBand.setText("AM");
break;
default:
}
(2)這裡關鍵的地方是:一個continue對你應著一個case的結束;。
3,反編譯後程式碼如下:if for while結構
int i15 = this.freq;
int i16 = this.rmin;
if (i15 < i16)
i17 = this.min;
int i29;
for (this.freq = i17; ; this.freq = i29)
{
int i27;
int i28;
do
{
this.x = getWidth();
this.y = -1;
break label32:
i27 = this.freq;
i28 = this.max;
}
while (i27 <= i28);
i29 = this.max;
}
this.y = 0;
invalidate();
(1)程式碼邏輯分析:保證freq的值在min和max之間。
分析後得到的原始原始碼:
if (freq < min)
{
freq = min;
}
if (freq <= max)
{
x = getWidth();
y = -1;
}
else
{
freq = max;
y = 0;
invalidate();
}
(2)得到上面的原始碼關鍵在於,按反編譯後的程式碼走一遍。
4, 解析switch for while結構程式碼
PowerManager localPowerManager = (PowerManager)getSystemService("power");
switch (paramInt)
{
default:
case 0:
case 1:
}
for (String str = "on"; ; str = "other")
while (true)
{
PowerManager.WakeLock localWakeLock = localPowerManager.newWakeLock(6, str);
localWakeLock.acquire();
localWakeLock.release();
return;
str = "off";
}
還原原始原始碼:
PowerManager localPowerManager = (PowerManager)getSystemService("power");
String str = null;
switch (paramInt)
{
case 0:
str = "on";
break;
case 1:
str = "off";
break;
default:
str = "other";
break;
}
PowerManager.WakeLock localWakeLock = localPowerManager.newWakeLock(6, str);
localWakeLock.acquire();
localWakeLock.release();
5, 分析返編譯後的程式碼(if while結構)
例1:
if (paramInt1 == 0)
this.mMessage.setText("");
while (true)
{
this.mAdditionalMessage.setVisibility(8);
int i = this.mLevel.getMax();
if (paramInt2 != i)
this.mLevel.setMax(paramInt2);
Toast localToast = this.mToast;
......
return;
TextView localTextView = this.mMessage;
String str = "" + paramInt1;
localTextView.setText(str);
}
分析:1,先去掉“this"
2,看返編譯後的按順序邏輯走一遍。可以看出while到return這段程式碼,不管怎麼樣都會執行的。所以原始程式碼應該是這樣的:
setSmallIcon(paramInt1);
paramInt1 &= 2147483647;
if (paramInt1 == 0)
{
mMessage.setText("");
}
else
{
String str = "" + paramInt1;
mMessage.setText(str);
}
mAdditionalMessage.setVisibility(8);
if (paramInt2 != mLevel.getMax())
{
mLevel.setMax(paramInt2);
}
mToast.setView(mView);
......
不斷更新中.....
相關文章
- Android Apk反編譯系列教程(一)如何反編譯APKAndroidAPK編譯
- 反編譯apk編譯APK
- android 反編譯APK取原始碼。Android編譯APK原始碼
- 反編譯Apk後 找到對應的佈局編譯APK
- Android Apk反編譯得到Java原始碼AndroidAPK編譯Java原始碼
- 反編譯APK資原始檔與原始碼編譯APK原始碼
- 安卓apk檔案反編譯安卓APK編譯
- apk 包的破解與反編譯APK編譯
- 關於Android APK反編譯AndroidAPK編譯
- Mac平臺反編譯Unity編譯的安卓apkMac編譯Unity安卓APK
- Android Apk反編譯系列教程(二)APK重打包AndroidAPK編譯
- 使用AndroidKiller進行APK反編譯AndroidAPK編譯
- Android開發:APK的反編譯(獲取程式碼和資原始檔)AndroidAPK編譯
- 練習向:一次簡單的APK反編譯後二次打包APK編譯
- 反編譯之JD-GUI程式碼邏輯分析編譯GUI
- Android APK反編譯技巧全講解AndroidAPK編譯
- apkTool反編譯apk碰到的問題APK編譯
- Android Apk 檔案反編譯和重新打包的過程分析AndroidAPK編譯
- [轉]andriod的apk檔案相關的編譯反編譯工具APK編譯
- Android Apk反編譯系列教程(三)Android Studio除錯smali程式碼AndroidAPK編譯除錯
- MAC使用APKTool反編譯apk修改版本號後重新打包MacAPK編譯
- apkTool---一個簡單好用的apk反編譯工具APK編譯
- 爬蟲app資訊抓取之apk反編譯抓取爬蟲APPAPK編譯
- MacOS X APK 最新版本 反編譯MacAPK編譯
- 常見 APK 反編譯工具安裝與使用APK編譯
- Java程式碼的編譯與反編譯那些事兒Java編譯
- Android反編譯和程式碼混淆Android編譯
- mac上Apk反編譯工具合集整理與資源MacAPK編譯
- Android 安全之如何反編譯與加密apk包Android編譯加密APK
- Android安全之如何反編譯與加密apk包Android編譯加密APK
- 一些防止java程式碼被反編譯的方法Java編譯
- apk反編譯生成程式的原始碼和圖片、XML配置、語言資源等檔案APK編譯原始碼XML
- 程式碼混淆防止APP被反編譯指南APP編譯
- apk decompile 線上反編譯工具-toolfk程式設計師線上工具網APKCompile編譯程式設計師
- 小程式反編譯教程編譯
- c#程式反編譯C#編譯
- 從編譯後的程式碼,分析 Angular @Injectable 的工作原理編譯Angular
- 微信小程式“反編譯”實戰(一):解包微信小程式編譯