Android 逆向⼯工程⼼心得
Hsieh, En-Ping
shieh.npin@gmail.com
Agenda
• 抓
• 拆
• 組
• 秀
抓
First move
The Easy way.
• ⽤用APP抓APK

https://play.google.com/store/apps/details?id=com.ext.ui&hl=zh_TW
• 貼網址

https://apps.evozi.com/apk-downloader/
⾝身為宅宅的浪漫!
The Classic way.
• #adb shell pm list package

顯⽰示所有安裝的應⽤用程式之packageName
• #adb shell pm path package.name.here

顯⽰示應⽤用程式之APK路路徑
• #adb pull /path/to/apk/location/base.apk

取出應⽤用程式之APK
拆
Making material
可以把JAR直接放到
Android上跑嗎?
Java Virtual
Machine(JVM)

⼀一種能夠執⾏行行Java bytecode的虛擬機器
Desktop
Java VM
Java
bytecode
Dalvik VM
可以執⾏行行已轉換為「Dalvik
Executable」格式的Java應⽤用程式
Desktop Android
Java VM Dalvik VM
Java
bytecode
Dex
bytecode
JVM ≠ Dalvik VM?
Stacked based Register based
Desktop Mobile
Java VM Dalvik VM
Java
bytecode
Dex code
變換
http://lim.univ-reunion.fr/staff/fred/Doc/Dalvik/Analysis-of-Dalvik-VM.pdf
每次變換都會損失部分資訊。
和最初的原始碼差異異越來來越⼤大
那APK⼜又是如何製作?
APK封裝流程
Source Code

(*.java)
Java
Bytecode

(*.class)
Java Compiler
Compile
APK封裝流程
Java
Bytecode

(*.class)
“dx” tool
Dalvik
Executable

(classes.dex)
Convert

&

Merge
APK封裝流程
Dalvik
Bytecode

(classes.dex)
APK Packager
w/ compiled
resourced
APK

(unsigned)
Assemble
APK封裝流程
APK

(unsigned)
APK

(signed)
APK Packager
w/ key store
Sign
https://developer.android.com/studio/build/index.html
So far…
• 要修改邏輯→Dex下⼿手。
• 要對Dex下⼿手→拆開APK。
• 要拆開APK→簽章失效。
• 也就是說,當修改完後必須重組APK並加簽章。
可以直接解開來來改嗎?
如果你天資過⼈人,是百年年難得⼀一⾒見見的武術奇才
Apktool
https://ibotpeaches.github.io/Apktool/
Apktool
• #java -jar apktool d target.apk -o target

反組譯APK並產⽣生smali與xml

*Smali是⼀一種很接近dex的組合語⾔言
• #java -jar apktool b target -o output.apk

將smali與xml重新組譯成APK



如果試著安裝就會...
[INSTALL_PARSE_FAILED_NO_CERTIFICATES]
Signed
• #jarsigner -verbose -keystore ~/.android/
debug.keystore -storepass android -keypass
android target.apk androiddebugkey



使⽤用debug keystore 去簽重新包裝的apk
先來來試試看!
Smali
https://github.com/JesusFreke/smali
foo(I[[II[Ljava/lang/Object;)Z
boolean foo(int, int[][], int, Object[])
foo(I[[II[Ljava/lang/Object;)Z
boolean foo(int, int[][], int, Object[])
暫存器
.method public d(Ljava/lang/String;J)I


.locals 3
暫存器 v0 v1 v2
型態 ? ? ?
別名 p0 p1 p2 p3
v3
this
v4 v5 v6
String long
v0~v2是可以⾃自由使⽤用的區域暫存器
v3是物件本⾝身,但靜態⽅方法則無。
v4~v6是傳入參參數
參參數p0~p3不受到區域暫存器的影響。
Quick Demo
.method public static d(Ljava/lang/String;Ljava/lang/String;)V
.locals 3
.param p0, "username" # Ljava/lang/String;
.param p1, "password" # Ljava/lang/String;
.prologue
...
invoke-virtual {v1, v0}, Landroid/content/Context;->startService(Landroid/content/Intent;)Land
return-void
.end method
invoke-virtual {v0}, Landroid/content/Intent;->toString()Ljava/lang/String;
move-result-object v0
const-string v3, "LOG"
invoke-static {v3, v0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
調⽤用intent.toString()將輸出存到v0
增加區域暫存器
設定v3
調⽤用Log.d(String,String)
.locals 4
Smali經驗談
• 注意static⽤用invoke-static、public/protected⽤用invoke-
virtual、private⽤用invoke-direct、super⽤用invoke-super
• 確認該區域暫存器沒有被其他指令使⽤用
• 函數簽名要多檢查,例例如Log.d有回傳值
• ⾃自⼰己做APK轉smali學最快
Smali is good, but still
hard to analyze.
We need dex2jar and JDGui
Dex2Jar
https://sourceforge.net/projects/dex2jar/
#sh ./dex2jar/d2j-dex2jar.sh target.apk
JDGui
http://jd.benow.ca/
組
Develop
Analysis
APK
JAR
Dex2jar
Analyze
JDGui
Reversing
APK
Smali
Apktool
Modified
Editor(Sublime Text)
APK(unsign)
Apktool
APK(signed)
Jarsigner
秀
Show, Don’t tell!
分析經驗談
• AndroidManifest.xml is a good start point. Adding
android:debuggable=“true” helps you ALWAYS.
• 耐⼼心、運氣和經驗。
• Use UIAutomator to analyze UI and xml.
• Use shell to view persistence data, such as db.

#adb shell run-as package.name
分析經驗談
• Framework相關的class/method是不會被混淆的。
• Use Activity Manager to analyze Task Stack

#adb shell dumpsys activity activities 

| sed -En -e '/Running activities/,/Run #0/p'
• ⽤用上任何可⽤用的Sniffer Tool,像是Charles Web
Proxy, tcpdump。
分析經驗談
• 善⽤用全域搜尋關鍵詞(Unicode <-> Text/Hex <-> Int)
• 藉由逆向製造Exception來來追蹤執⾏行行路路徑。
• 多看多嘗試,不要太快就看得太深。
逆向經驗談
• Static is better. NO constructor required.
• 建立同樣PackageName的Utility Project,編譯成
APK後再轉Smali並放入要改寫的⽬目錄。
• 少寫少錯,多寫多錯。
• Don’t forget use git.
Anti-Reverse Engineering
• 逆向⼯工程是時間問題,但是可以努⼒力力讓逆向成本⼤大
於價值。
• Proguard 能提供基本的防護。
• 使⽤用JNI與C++處理理核⼼心與加密可提⾼高逆向的⾨門檻。
• 如果有後端,將核⼼心邏輯放在Server side。
• 使⽤用DexGuard、Arxan等商⽤用加密⼯工具。
Appendix
• Smali Syntax Highlight Plugin 

https://github.com/ShaneWilton/sublime-smali
• Jadx

https://github.com/skylot/jadx
• 如果有align問題請記得

#zipalign -f -v 4 unalign.apk align.apk
Reference
https://liuzhichao.com/p/919.html

http://blog.isming.me/2015/01/14/android-decompile-smali/

https://hitcon.org/2015/CMT/download/day2-g-r4.pdf

http://blog.csdn.net/wdaming1986/article/details/8299996

https://www.rsaconference.com/writable/presentations/file_upload/stu-w02b-
beginners-guide-to-reverse-engineering-android-apps.pdf
The End.
Q & A

Android 逆向工程心得分享