android 逆向工程
很多人寫文章,喜歡把什麼行業現狀啊,研究現狀啊什麼的寫了一大通,感覺好像在寫畢業論文似的,我這不廢話,先直接上幾個圖,感受一下。
第一張圖是在把程式碼注入到地圖裡面,啟動首頁的時候彈出個浮窗,下載網路的圖片,蒼老師你們不會不認識吧?
第二張圖是微信運動步數作弊,6不6?
ok,那我們從頭說起……
1.反編譯
Android 的反編譯,相信大家都應該有所瞭解,apktool、JEB 等工具。
我們先看一下 Apk 檔案的結構吧,如下圖:
1.META-INF:簽名檔案(這個是如何生成的後面會提到)。
2.res:資原始檔,裡面的 xml 格式檔案在編譯過程中由文字格式轉化為二進位制的 AXML 檔案格式。
3.AndroidManifest.xml:Android 配置檔案,編譯過程依然被轉換為 AXML 格式。
4.classes.dex:java 程式碼編譯後產生的類似位元組碼的檔案(dalvik 位元組碼)。
5.resources.arsc:具有 id 值資源的索引表(asserts 資料夾中的資源不會生成索引)。
6.其他檔案:可由開發者自己新增,諸如 assets 等,或者 lib(native so 程式碼)等目錄。
(Android 編譯打包過程分析參看:
Apk 的核心邏輯主要在 classes.dex 中,破解和二次打包也基本上對這個檔案做手腳,所以對這個檔案的保護也尤為重要。
上圖為一般 Apk 的破解過程(windows 畫圖工具畫的比較搓)。
我們首先用 apktool 工具反編譯:java -jar apktool.jar d -f xxx.apk outDir(PS:outDir 不寫會在當前目錄輸出)。
反編譯後的目錄結構如下:
這裡,res 裡的 xml 和 manifset.xml 都已經是解出後的 xml 了,不是 axml 格式了,res 目錄裡的 values 目錄下的 public.xml 可以看到資源對應的 id。
如果命令 java -jar apktool.jar d -f再加入 -r 代表資原始檔不反編譯,上圖的目錄中將依然有resources.arsc,xml 都是 axml 格式的,也找不到 public.xml。
其實我們主要關注的是 smali 這個目錄,裡面是按照 android 程式編寫的時候 java 檔案的目錄格式生成的,但是裡面的檔案並不是 java 格式的,而是 smali 格式的,類似 MainActivity.smali。
那麼什麼是 smali 檔案呢?
1.Smali 是 Android 的 Dalvik 虛擬機器所使用的一種 dex 格式的中間語言。
2.可以理解為,C 語言和組合語言的編譯與反編譯,把 smali 理解為一種組合語言。
我們可以開啟一個 smali 檔案看看,我們可以使用 notepad++ 開啟,然後定一下 smali 語法的高亮顯示。
將下面內容儲存到 C:\Users\使用者名稱\AppData\Roaming\Notepad++下,檔名為 userDefineLang.xml。
可以參看 http://www.ourunix.org/post/117.html 操作。開啟 MainActivity.smali 檔案,頭三行程式碼大致如下:
[C] 純文字檢視 複製程式碼
?
1
2
3
.class public Lcom/example/hacktest/MainActivity;
.super Landroid/app/Activity;
.source “MainActivity.java”
smali 語法這裡就不介紹了,自己查資料就好 smali 檔案語法參考:
這裡舉個例子,我們寫個程式,一個 edittext 一個 button,當 edit 裡面輸入正確的文字的時候,點選 button 才會彈出正確的 toast。
我們看一下,反編譯後的關鍵程式碼:
可以看到這是一個引數為 string,返回值為 boolean 名叫 check 的函式,當輸入為“11”的時候才返回 true。
我們可以把第一個紅框位置的 if-eqz 改成 if-nez,這樣你輸入除了11的任何字元都會返回 true。
或者把第二個紅框位置的 0x1,改成 0x0,(0代表 true),這樣這個函式不管輸入什麼都返回 true。
OK,這樣我們就改完了,我們重新編譯:java -jar apktool.jar b -f outDir xxx.apk(PS:xxx.apk 可以不寫,會在 outDir 裡生成 dist 目錄,編譯好的 Apk 在這裡面)。
簽名:可以網上下載工具 autoSign,使用方法略…
安裝 Apk 後驗證,通過。
但是事情並不總是如我們所願,有些 Apk 會做一些盜版檢測機制,就是為了防止二次重打包。
以手機XX應用為例,當你按照上述步驟反編譯,重新編譯,簽名之後,進入 APP 會出現這個頁面,無法正常使用。
因為你並沒有這個 APP 的正版簽名檔案(關於簽名相關的東西,在後面我再仔細講)。
那麼這個原理是什麼呢,我們大膽猜測一下,無非就是和上一個例子類似的check函式,兩個值的對比,那麼這個值一定是簽名。
我們先通過方法拿到正版的簽名md5,然後在反編譯後的程式碼中搜索一下這個值。
然而並沒有搜到,再換個思路,我們搜尋獲取簽名的這個函式,從而定位關鍵程式碼,獲取應用簽名的java程式碼類似是:
[Java] 純文字檢視 複製程式碼
?
1
2
3
PackageInfo pi = context.getPackageManager.().getPackageInfo(packname,packageManager.GET_SIGNATURES);
對應的smali程式碼類似是:
Landroid/content/pm/PackageInfo;->signatures:[Landroid/content/pm/Signature
我們再搜用這段程式碼搜尋,在 StormUtils2.smali 裡面找到了,發現在函式 getSignInfo 裡面,繼續跟蹤到 checkPiracy 函式。
看到這個函式發現就和上例中的 check 函式類似了,改一下返回值為 true 就好了。
我們再仔細看看這個函式,發現關鍵的簽名 md5 值被拆開存放了,所以我們才沒有搜到,這也是防範搜尋的一個舉措吧(雖然我覺得並沒什麼用)。
[Java] 純文字檢視 複製程式碼
?
1
2
const-string/jumbo v3, “dbbf****96b326003”
const-string/jumbo v0, “c388a****1578d5”
好的,修改後,我們再重新編譯、簽名,驗證通過。
(PS:關於簽名檢測的除了 java 層的,可能還有再 so 裡面校驗的和伺服器驗證的方式,在 so 裡的用 IDA 開啟 so 跟蹤修改,伺服器驗證的抓包檢視,再模擬發包重放攻擊就好了,這裡就不具體介紹了)
- Android 的簽名保護機制到底是什麼?
Android 系統禁止更新安裝簽名不一致的 Apk,如果我們修改了 Apk 又用別的簽名檔案簽名,肯定是不一致的。
我們從簽名工具 autoSign 分析,看一下 sign.bat 檔案內容:
@ECHO OFF
Echo Auto-sign Created By Dave Da illest 1
Echo Update.zip is now being signed and will be renamed to update_signed.zip
java -jar signapk.jar testkey.x509.pem testkey.pk8 update.apk update_signed.apk
Echo Signing Complete
Pause
EXIT
看一下 java -jar signapk.jar testkey.x509.pem testkey.pk8 update.apk update_signed.apk 這行的意義:
以testkey.x509.pem 這個公鑰檔案和 testkey.pk8 這個私鑰檔案對 update.apk 進行簽名,簽名後儲存為 update_signed.apk。
我們可以看到簽名前和簽名後比較,簽名後的檔案中多了一個資料夾“META-INF”,裡面有三個檔案 MANIFEST.MF 、 CERT.SF 、 CERT.RSA。
我們通過 jd-gui 工具開啟 signapk.jar,找到 main 函式,通過這個函式跟蹤程式碼
- addDigestsToManifest 這個函式,遍歷 Apk 中所有檔案,對非資料夾非簽名檔案的檔案逐個生成 SHA1 數字簽名信息,再 base64 編碼。
然後再寫入 MANIFEST.MF 檔案中,生成檔案如下:
Manifest-Version: 1.0
Created-By: 1.0 (Android)
Name: res/drawable-xhdpi/ic_launcher.png
SHA1-Digest: AfPh3OJoypH966MludSW6f1RHg4=
Name: AndroidManifest.xml
SHA1-Digest: NaPhUBH5WO7uGk/CfRu/SHsCvW0=
Name: res/drawable-mdpi/ic_launcher.png
SHA1-Digest: RRxOSvpmhVfCwiprVV/wZlaqQpw=
Name: res/drawable-hdpi/ic_launcher.png
SHA1-Digest: Nq8q3HeTluE5JNCBpVvNy3BXtJI=
Name: res/layout/activity_main.xml
SHA1-Digest: kxwMyILwF2K+n9ziNhcQqcCGWIU=
Name: resources.arsc
SHA1-Digest: q7Ystu6WoSWih53RGKXtE3LeTdc=
Name: classes.dex
SHA1-Digest: Ao1WOs5PXMxsWTDsjSijS2tfnHo=
Name: res/drawable-xxhdpi/ic_launcher.png
SHA1-Digest: GVIfdEOBv4gEny2T1jDhGGsZOBo=
SHA1 生成的摘要資訊,如果你修改了某個檔案,Apk 安裝校驗時,取到的該檔案的摘要與 MANIFEST.MF 中對應的摘要不同,則安裝不成功。
2. 接下來對之前生成的 manifest 使用 SHA1withRSA 演算法, 用私鑰簽名,writeSignatureFile 這個函式,最後生成 CERT.SF 檔案,如下:
Signature-Version: 1.0
Created-By: 1.0 (Android)
SHA1-Digest-Manifest: pNZ9UXN9GMqTgqAwKD6uEN6aD34=
Name: res/drawable-xhdpi/ic_launcher.png
SHA1-Digest: cIga++hy5wqjHl9IHSfbg8tqCug=
Name: AndroidManifest.xml
SHA1-Digest: oRzzLkwuvxC78suvJcAEvTqcjSA=
Name: res/drawable-mdpi/ic_launcher.png
SHA1-Digest: VY7kOF8E3rn8EUTvQC/DcBEN6kQ=
Name: res/drawable-hdpi/ic_launcher.png
SHA1-Digest: stS7pUucSY0GgAVoESyO3Y7SanU=
Name: res/layout/activity_main.xml
SHA1-Digest: Yr3img6SqiKB+1kwcg/Fga2fwcc=
Name: resources.arsc
SHA1-Digest: j1g8I4fI9dM9hAFKEtS9dHsqo5E=
Name: classes.dex
SHA1-Digest: Sci9MmGXNGnZ1d04rCrEEV7MWn4=
Name: res/drawable-xxhdpi/ic_launcher.png
SHA1-Digest: KKqaLh/DVvFp+v1KoaDw7xETvrI=
用私鑰通過 RSA 演算法對 manifest 裡的摘要資訊進行加密,安裝的時候只能通過公鑰解密,解密之後才能獲得正確的摘要,再對比。
- 最後就是如何生成 CERT.RSA,開啟這個檔案看到的是亂碼,說明整個檔案都被編碼加密了,而且這個檔案和公鑰有關,從原始碼中看出他是通過 PKCS7 將整個檔案加密了。
總結:1.簽名只是對完整性和簽名釋出機構的校驗機制 2.不能阻止 Apk 被修改,只是簽名無法保持一致 3.不同私鑰對應著不同的公鑰,實質上不同的公鑰就代表了不同的簽名。
Android 系統如何獲取簽名
我們從獲取下面一段程式碼開始分析:
[Java] 純文字檢視 複製程式碼
?
1
2
3
4
packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES );
Signature[] signs = packageInfo.signatures;
md5 = getMD5Str(signs[ 0].toByteArray());
context.getPackageManager()其實拿到的是ApplicationPackageManager
看一下 context 的實現類 contextImpl 裡的 getPackageManager()。
[Java] 純文字檢視 複製程式碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
@Override
public PackageManager getPackageManager() {
if (mPackageManager != null) {
return mPackageManager ;
}IPackageManager pm = ActivityThread.getPackageManager ();
if (pm != null) {
// Doesn’t matter if we make more than one instance.
return (mPackageManager = new ApplicationPackageManager(this, pm));
}return null ;
}
可以看到 ActivityThread 中方法 getPackageManager 獲取 IPackageManager。
繼續看 ActivityThread 的程式碼:
[Java] 純文字檢視 複製程式碼
?
01
02
03
04
05
06
07
08
09
10
11
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
//Slog.v(“PackageManager”, “returning cur default = ” + sPackageManager);
return sPackageManager ;
}
IBinder b = ServiceManager.getService(“package”);
//Slog.v(“PackageManager”, “default service binder = ” + b);
sPackageManager = IPackageManager.Stub.asInterface(b);
//Slog.v(“PackageManager”, “default service = ” + sPackageManager);
return sPackageManager;
}
看原始碼知道是通過 ServiceManager.getService(“package”);獲取 PackageManagerService 並得到 IBinder物件,然後通過 asInterface 函式取得介面類 IPackageManager 例項。
然後作為引數構造 ApplicationPackageManager,再看 ApplicationPackageManager 這個類裡的方法:
[Java] 純文字檢視 複製程式碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
@Override
public PackageInfo getPackageInfo(String packageName, int flags)
throws NameNotFoundException {
try {
PackageInfo pi = mPM.getPackageInfo(packageName, flags, mContext.getUserId());
if (pi != null) {
return pi;
}
} catch (RemoteException e) {
throw new RuntimeException( “Package manager has died” , e);
}throw new NameNotFoundException(packageName);
}
這裡的mPM就是上面建構函式傳進來的 IPackageManager,就可以呼叫 PackageManagerService 的方法了。
下圖是 PackagerManager 靜態類結構圖:
ok,看完上圖的結構圖,繼續跟程式碼 ,看到這裡是 mPM 繼續呼叫的getPackageInfo(代理模式),通過程序通訊到 PackageManagerService 中執行響應操作:
[Java] 純文字檢視 複製程式碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
@Override
public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid (), userId, false, “get package info”);
// reader
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (DEBUG_PACKAGE_INFO)
Log.v (TAG, “getPackageInfo ” + packageName + “: ” + p);
if (p != null) {
return generatePackageInfo(p, flags, userId);
}
if((flags & PackageManager. GET_UNINSTALLED_PACKAGES ) != 0) {
return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
}
}
return null ;
}
這裡 mPackages 是 hashMap,其呼叫put方法的時機是在 scanPackageLI 方法中,而 scanPackageLI 的呼叫地方是在程式安裝和替換函式中,還有就是 scanDirLi 中,程式碼略。
scanDirLi 是用來掃描一些系統目錄的的,在 PackageManagerService 的建構函式中呼叫的:
[Java] 純文字檢視 複製程式碼
?
1
2
3
4
5
6
7
File dataDir = Environment. getDataDirectory();
mAppDataDir = new File(dataDir, “data”);
mAppInstallDir = new File(dataDir, “app”);
mAppLibInstallDir = new File(dataDir, “app-lib” );
mAsecInternalPath = new File(dataDir, “app-asec” ).getPath();
mUserAppDataDir = new File(dataDir, “user”);
mDrmAppPrivateInstallDir = new File(dataDir, “app-private” );
上面是掃描的位置↑↑↑↑↑↑↑
PackageManagerService 處理各種應用的安裝、解除安裝、管理等工作,開機時由 systemServer 啟動此服務。就是說之前安裝過的應用或者系統應用資訊都會在開機掃描過程中存到 mPackages 這個 hashMap 中。開機後用戶的安裝操作也會同樣存到這個 hashMap 裡面。
繼續看 getPackageInfo,呼叫的 generatePackageInfo , 裡面呼叫的是 PackageParser 中的 generatePackageInfo,繼續跟。
這個函式的程式碼比較長,只貼出部分關鍵程式碼:
[Java] 純文字檢視 複製程式碼
?
1
2
3
4
5
6
7
8
if ((flags&PackageManager. GET_SIGNATURES ) != 0) {
int N = (p.mSignatures != null) ? p.mSignatures.length : 0;
if (N > 0) {
pi.signatures = new Signature[N];
System.arraycopy (p.mSignatures, 0, pi. signatures, 0 , N);
}
}
return pi;
這段程式碼之前主要是做一些複製的操作,就是 new 一個 PackageInfo,然後把 PackageParser.Package 物件中的一些內容複製到這個 PackageInfo 中。
從這段程式碼可以看出來,最終得到的 signatures 資訊就是中 p(PackageParser.Package )中的成員 mSignatures 中得來的。
好了,現在就是看這個PackageParser.Package是從哪來的了,通過跟蹤程式碼,installPackageLI 和 scanPackageLI 中的:
[Java] 純文字檢視 複製程式碼
?
1
final PackageParser.Package pkg = pp.parsePackag (tmpPackageFile, null, mMetrics, parseFlags);
這行程式碼只是生成了 pkg,並沒有賦值裡面的 mSignatures,繼續跟蹤,找到函式 collectCertificatesLI,找到 pp.collectCertificates(pkg , parseFlags)。
PS:最終又進行了一系列的跟程式碼,找到了 JarVerifier.java 這個類的 readCertificates 這個就是用來讀取.RSA 檔案的,最終我們看到的裡面的程式碼是通過 loadCertificates 取得的 certs 賦值給了 pkg.mSignatures。
至此,獲取簽名的所有邏輯就算是簡單的過一遍了,以下是簡略流程圖:(發現 ppt 畫圖比 Windows 畫圖工具好用多了,哈哈)
在跟程式碼的過程中也找到了簽名對比的函式 compareSignatures ,有空自己看看就好了。
OK,繞了這麼久我們終於找到源頭了,獲取簽名就是在 META-INF 中尋找,並解析。試想一下,如果我們修改了這個函式,讓他解析原來正版的 META-INF 中的 CERT.RSA 檔案,這樣就可以偽造為真正的簽名了。
那麼我們就想到了 HOOK,(很多人都是從看雪論壇上找到的一篇文章看到的 http://bbs.pediy.com/showthread.php?t=186054 hook 的原來簡單來說就是,找到原函式和新函式的指標位置,然後兌換內容,將新函式替代原函式。
下圖就是我用了上面的方法產生的效果,還差點被微信部門的人請去喝茶。
這裡用的是 Xposed 框架,原理就是 hook 了手機的計步感測器的佇列函式,然後把步數的返回值每步乘1000返回,前提是,你的手機硬體本身有計步感測器功能,這裡微信運動裡面列出了支援的手機列表:https://kf.qq.com/touch/sappfaq/151013AvyyeQ151013r63qmq.html?platform=15 好像最高就是98800了,可能是微信做了步數限制吧。
我這裡用的是小米4聯通版,發現雖然是1000基數的加,但是好像隔了很久才變化,估計又是 MIUI 做了一些省電策略,感測器的採集做了對齊吧?
Xposed 框架,很多玩機愛好者,會拿它修改一些主題,字型之類的,或者系統介面,定製自己想要的系統外掛等等。然而,也有缺點,需要手機root,而且這個框架,還有可能讓手機變磚,還有的系統可能對這個框架支援的不好,或者不支援。XDA 論壇裡面也有很多大神把 Xposed 對某些機型做了適配,大神一般都是說,如果手機變磚他們不負責,哈哈。
正式由於這些框架的諸多不便,root 等等的問題,於是就有了一些非 root 的 hook 的黑科技,比如阿里巴巴的開源框架 Dexposed(https://github.com/alibaba/dexposed)其也是根據 Xposed 框架修改而來的,不過看 github 上他們也好久沒更新了。
也有像其他個人寫的和這種比較類似的框架,這裡就不介紹了。但是這類框架的缺點就是,只能在該程序下hook,不能全域性 hook,即只對這個程序的應用起作用,不能對另一個應用起作用,優點是可以 hook 自定義函式也能hook 系統函式,並且不用 root 和重啟。阿里用這個框架來打線上熱補丁。
那對於 App 內部簽名校驗的就不用再搜相應的程式碼了,直接 hook 就一步到位了,android.app.ApplicationPackageManager 這個類的 getPackageInfo 這個方法直接把正確的簽名返回就好了,接下來我們就需要把hook的程式碼注入到某個 App 裡就好了。
- 關於如何注入?
開篇的時候有個圖片就是我在地圖裡面注入了一個蒼老師的圖片其實就是,自己寫了個 imageloader,用來下載網路圖片,再寫個 activity 或者 dialog 來承載這個 imageview,然後編譯,再反編譯,取出相應的smali等檔案,比如貼到已經反編譯好的地圖的裡面,把開啟這個蒼老師圖片下載的啟動程式碼放到合適位置,最後再把地圖重新打包簽名,就ok 了。
hook 程式碼也是同理注入,驗證一下,成功(我這塊寫的比較粗略,程式碼比較多,只說思路了)那麼這種程式碼注入和 hook 相結合的方式能幹什麼呢,我們也不妨搞出點事情來。同樣我們還是進行微信運動作弊的事情,其實很多運動類的軟體都可以把自己的資料同步到微信運動裡,比如小米手環,樂動力,悅動圈等等。
那我們就先拿一個來開刀吧:
經過一系列的跟蹤程式碼定位,最終定位到了這個類 cn.ledongli.ldl.cppwrapper.DailyStats 裡的 f 方法(f 是因為程式碼混淆了)然後我們注入並 hook 方法,讓它返回66666,ok,我們看到了如下效果:
然後我們在應用裡面登陸微信賬號,和對接到微信運動的功能,發現不好用,是因為,微信裡面做了對應用的簽名校驗,應用的簽名已經變了。
所以我們只能破解微信了(悶聲作大死),同樣注入 hook 程式碼,讓微信獲取樂動力的簽名的時候取得正確簽名,關鍵程式碼:
[Java] 純文字檢視 複製程式碼
?
1
2
3
4
5
6
7
if( packageName.equals( “cn.ledongli.ldl”)){
if ( result instanceof PackageInfo) {
PackageInfo info = (PackageInfo) result;
info. signatures[0] = new Signature( myHexLedongli);
param.setResult( info);
}
}
再把這個盜版的微信重新打包簽名,重新進行應用的同步資料操作,再進微信運動看看,是不是已經66666了。至此作弊完成。
♂♂♂♂♂♂♂♂♂♂我是畫風不同的分割線♂♂♂♂♂♂♂♂♂♂♂♂
說了這麼多破解的,也該聊聊防破解的了。
google 最早給的就是程式碼混淆的方案,其實一般的混淆只是降低了程式碼的可讀性,讓你對反編譯出來的函式命名等不知道什麼意思,不過解讀出來只是時間問題。後來還有資源混淆的,但是意義不大。
後來有了核心程式碼用 C 實現,寫成 SO,加花指令的辦法,這個辦法確實會阻止一大部分人的繼續破解,但是對於經常做逆向的工程師來說也不是什麼難題。
其實做這麼多大多數軟體的初衷就是不想軟體被盜版,然後被注入亂七八糟的廣告,或者被盜取資訊等,後來就有了盜版檢測機制。比如:JAVA 層的簽名校驗,NDK 層校驗,分段存放簽名 Hash 串,伺服器校驗等等,但是這些方法我都在上面說了破解方法。
現在國內的一般應用市場都有對 APP 簽名的檢測,在你下載的時候會告訴你這個 APP 是不是盜版的,從而讓使用者區分出來。但是應用市場自己本身又被盜版了怎麼辦呢?
再後來,就有了像360加固保和騰訊的樂固等產品,so 做了加密,真正的 dex 也藏起來了,不過個人覺得,就算真正的 dex 也需要變成 odex 了,root 的手機取到 odex,再轉回 dex,就能拿到真正的 dex(雖然我沒試過,但是我覺得可能是一個思路),所以這個方法就更難破解了。
雖然加固產品很厲害,但是也會有他的缺陷,Android 系統不斷的更新升級,也許就換了某些模式等等,比如 ART 剛出來的時候,加固保加固後的 Apk,在 ART 模式執行下就會 Crash。這些加固產品要不斷的適配各種型號的手機,CPU 型別,執行模式等等,所以很多 APP 為了考慮相容性,他們也不會輕易去加固自己的產品。
♂♂♂♂♂♂♂♂♂♂我是畫風不同的分割線♂♂♂♂♂♂♂♂♂♂♂♂
關於逆向破解 Android 應用,我覺得耐心很重要吧,程式碼跟來跟去確實很枯燥,總結幾點小技巧吧:
1.資訊反饋:通過介面的一些彈出資訊,介面特點尋找突破點。
2.特徵函式:比如搜 Toast,Log,getSignature 等。
3.程式碼注入:把 toast 或者 log 函式注入到程式中,跟蹤位置。
4.列印堆疊:插入 new Exception(“定位”).printStackTrace();
5.網路抓包:通過抓包得到的關鍵欄位,在程式碼中定位。
寫在後面:
這篇文章整理了有一段時間了,覺得還是應該寫出來,也不是什麼高深的技術文章,就是個人總結的一點心得而已。
關於破解應用很多人可能會去破解別人的應用注入廣告來獲取利益,也有可能盜取別人的資訊。
不過我們作為有節操的開發工程師,應該本著瑞雪的精神看待技術,學習技術,而不是亂♂搞。但是我們也應該知道,我們的應用有可能會被別人怎麼搞……
最後推薦一本資料書,大家可以有空看看。
相關推薦
Android逆向工程之apk加固後反編譯AndroidManifest.xml
Android逆向工程之apk加固後反編譯AndroidManifest.xml Android編譯生成的apk經過加固後,AndroidManifest.xml無法直接檢視,直接開啟是一堆亂碼。在一些情況下, 又特別需要知道加固後的包中某個值最終形態,比如多渠道打包中,根據不同配置生成不同
Android逆向工程-破解 哈皮妹-蘿莉
轉載請註明出處:http://blog.csdn.net/singwhatiwanna/article/details/18797493前言新的一年新的開始,除了繼續我的原有課題之外,我還打算研究下Android逆向工程的一些東西,主要包括反編譯、Smali、APK打包、簽名
Android 逆向工程
1. Apk簽名 1). 建立簽名檔案 新建專案 -> build -> Generate Signed Bundle/APK... -> Create new...
Android逆向工程(一)-Apktool使用
當我們辛辛苦苦寫的程式碼被別人抄走的時候一定會讓我們非常的抓狂。要學會防守,我們也需要知道別人進攻的方式,接下來我們學習下如何破解Apk。Apktool是家喻戶曉的逆向工具,我們學習下如何使用它。 安裝 http://ibotpeaches.github.i
Android逆向工程之反編譯註入程式碼
反編譯植入程式碼。 其實思路很簡單: 1、首先我們要反編譯targetapk.apk,得到原始碼對應位元組碼。我們知道,如果我們要植入程式碼到其中,必須加入位元組碼然後重新編譯打包。 2、怎麼寫位元組碼?其實我們只要新建一個Android工程,將我
android 逆向工程
很多人寫文章,喜歡把什麼行業現狀啊,研究現狀啊什麼的寫了一大通,感覺好像在寫畢業論文似的,我這不廢話,先直接上幾個圖,感受一下。 第一張圖是在把程式碼注入到地圖裡面,啟動首頁的時候彈出個浮窗,下載網路的圖片,蒼老師你們不會不認識吧? 第二張圖是微信運動步數作
Android逆向工程
在Root前提下,我們可以使用Hooker方式繫結so庫,通過逆向方式篡改數值,從而達到所謂破解目的。然而,目前無論是軟體加固方式,或是資料處理能力後臺化,還是客戶端資料真實性驗證,都有了一定積累和發展,讓此“懶技術”不再是破解修改的萬金油。再者,閱讀彙編指令,函式指標替換,
Android逆向工程:講解相關逆向工具的配置和使用,帶你快速熟悉逆向操作
有個一週沒有寫部落格了,最近一直都在忙於公司的業務開發,沒有多少時間來和大家分享技術,好不容易逮到一個時間,抽空寫一下部落格,那麼就讓我們趕快開始今天的學習把! 上面的部落格中,我們學習了smali語法的相關知識,以及動態除錯smali程式碼的操作,不知道你是否已經學會了,
Android APK逆向工程/反編譯總結
1概述 本文涉及的內容本質上就是APK的反編譯, 作為一個開發者, 需要正視一下本文所談及的技術, 目的是為了讓你借鑑/學習優秀實踐, 而非讓你去盜用其它開發者得成果。事實是, 通過本文所談及的內容, 如果不付諸實踐和學習,沒有比較好的Android基礎, 實質上也不能
Android Cocos2dx引擎 prv.ccz/plist/so等優化快取檔案,手把手ida教你逆向工程反編譯apk庫等檔案
前段時間在 Android play 上看到一個很牛逼的 3D 動態天氣預報,效果真的很炫,二話不說動手 dex2jar.bat/apktool 發現這並沒 有什麼卵用,在核心的地方看見 native
Android Studio逆向工程——向Eclipse遷移
背景:近期接手一個老專案。用Eclipse構建。由於某中原因,一直沿用的Eclipse。然後需要新增新功能,新功能是一個支付專案,給的程式碼是Android Studio構建。為了把專案匯入Eclipse中,費時費力,終於成功。這裡把過程分享一下。 準備階段 首先拿到了專案
Android 圖解逆向工程中ARM常用匯編指令(一)
我們走得太快,靈魂都跟不上了。 微小的幸福就在身邊,容易滿足就是天堂。 在逆向和爆破中我們經常會在IDA中接觸到彙編,一般做安卓的不會太瞭解VB回編等,不太瞭解的同學可以先檢視上篇文章《Android ARM常用的彙編指令合集》 再來繼續我們
Android逆向分析初體驗
目錄 搜索 比較 .com -1 動態調試 總結 為我 修改 一、 準備知識 1. 懂Java Android開發。 2. 懂NDK ,C 語言 Android 動態鏈接庫.SO開發。 3.
在IDEA中使用MyBatis Generator逆向工程生成代碼
classpath 生成器 targe base time jar包 選項 操作 ava 本文介紹一下用Maven工具如何生成Mybatis的代碼及映射的文件。 一、配置Maven pom.xml 文件 在pom.xml增加以下插件: <build>
IDEA 中生成 MyBatis 逆向工程實踐
工程1.搭建 MyBatis Generator 插件環境 a. 添加插件依賴 pom.xml <!--mybatis 逆向生成插件--> <plugin> <groupId>org.mybatis
iOS逆向工程之App脫殼
工程 脫殼 一、生成dumpdecrypted.dylib動態庫首先我們要生成“砸殼”用的動態庫dumpdecrypted.dylib,我們“砸殼”時主要用到這個動態庫。該動態庫的源碼在github上是開源的(Github地址),要想得到dumpdecrypted.dylib這個動態庫,只需要從git
iOS逆向工程之Hopper中的ARM指令
工程一、Hopper中的ARM指令ARM處理器就不多說了,ARM處理器因為低功耗等原因,所以大部分移動設備上用的基本上都是ARM架構的處理器。當然作為移動設備的Android手機,iPhone也是用的ARM架構的處理器。如果你想對iOS系統以及你的應用進一步的了解,那麽對ARM指令集的了解是必不可少的,ARM
Spring+SpringMVC+MyBatis深入學習及搭建(十)——MyBatis逆向工程
cat springmvc blank 不為 tex llc root from ssi 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/6973266.html 前面講到:Spring+SpringMVC+MyBatis深入學習及
mybatis高級應用四_逆向工程
rgs lec 配置 lean lin 執行 ble r.java cal 1 逆向工程 源碼請參考:雲盤下工程 generatorSqlmapCustom 1.1 什麽是逆向工程 mybaits需要程序員自己編寫sql語句,mybatis官方提供逆向工程 可以針對
android 逆向
gui 使用 jd-gui nag .apk oid .exe con 逆向 用到兩個工具 :dex2jar和jd-gui 1,重命名ContactManager.apk為ContactManager.zip並解壓得到文件classes.dex; 2,解壓dex2jar