嚴正聲明:php
- 一、相關破解技術僅限於技術研究使用,不得用於非法目的,不然後果自負!
- 二、筆者僅出於對逆向技術的好奇,無惡意破壞APP,尊重原開發者的勞動成果,未用於商業用途。
接着說下筆者經常使用的一些「調試定位技法」,沒有優劣之分,混合使用快速找到 G點(關鍵代碼) 便可~css
最簡單,卻最高效的方法,能夠經過「一行文字」「一張圖片」「一個音視頻」完成定位,「無腦全局搜索!」java
記得先把apktool反編譯後的res和asserts文件夾和jadx反編譯後的代碼丟到一塊兒! (也可使用個人批處理反編譯腳本自動搞定)android
舉個例子:忽然以爲競品的對話框有點好看,可是好懶,不想本身寫:git
Ctrl+Shift+F 全局搜「快去登陸吧」或「登陸後會解鎖更精彩的內容哦」github
打開DialogUtils類,6個參數,不難定位到第三個a方法:web
跟下CommonDialog類:面試
直接定位到了佈局文件:shell
複製粘貼,改點東西,精美對話框get√bash
Activity 和 Fragment 也是很是好的切入點,經過簡單的adb命令便可得到棧頂(當前) Activity的相關信息:
# 獲取當前棧頂Activity的名稱
adb shell dumpsys activity | grep "mFocusedActivity"
# 你能夠經過alias爲上述命名設置一個別名:
alias ada="adb shell dumpsys activity | grep 'mFocusedActivity'"
複製代碼
效果以下圖所示:
你能夠能夠用:adb shell dumpsys activity top > info.txt 把Activity詳細信息打印到文件中。
也能夠安裝「開發者助手」直接獲取到(還能夠看到可能涉及的Fragment):
還能夠經過「反射大師」獲取到:
舊版的as是有這個東西,新版把入口給隱藏了,直接來到「android-sdk/tools」目錄下,找到monitor,運行便可:
左側選擇待調試進程:
以爲跟蹤得差很少了,就點擊②那個按鈕中止,右側會出現以下所述的方法調用流程:
而後你就能夠一步步跟了~
Apktool反編譯apk後,生成的是「Smali」文件,而非「Java」文件,Smali 是一種虛擬機指令語言。
Jadx反編譯dex後雖然生成了Java代碼,看看能夠,是不支持調試的,而Smali是可調試的,在AS中想調試Smali的話,還須要安裝「smalidea」插件,插件的下載,可移步至:bitbucket.org/JesusFreke/…,下載後,AS安裝一波插件,安裝完畢重啓便可。
注意:如今是你想調試別人的APP,那首先,要先把別人的APP變成「可調教狀態(debugable)」
一個看似簡單但卻很繁瑣的方法:
把目標APP的 AndroidManifest.xml 中的 debuggable屬性設置爲true,簽名重打包。
若是逆向的APP有多個,這應該顯得好繁冗,不如直接把「手機上全部應用都變成可調試狀態」,方法以下:
- Android 7.0如下安裝了Xposed的:
下載安裝「BDOpener模塊」:github.com/riusksk/BDO…,啓用插件重啓便可。
- Android 7.0及以上安裝了Magisk的:
Magisk裏下載安裝:「MagiskHide Props Config」和「Busybox for Android NDK」而後重啓。
接着終端 adb shell,輸入 props 進行設置,找到:Edit MagiskHide props的選項,好比這裏是4:
回車,會提示是否設置爲0,輸入y,接着設置完,提示是否重啓,輸入y重啓,接着打開AS 的 Logcat 就能夠看到全部的進程了:
設置完可調教,就能夠把smail導入AS中,導入過程須要注意下哦,不是直接open!打開AS在導入腳本反編譯後的apktool文件夾:
導入後,點擊頂部菜單欄的這個位置,「Edit Configurations」,點「+」選擇「Remote」
隨便填個名字,而後設置一個端口號 (本身定,auto.sh腳本那裏要配合着改哦!)
「命令行啓動進程調試等待模式」比較繁瑣且重複,我直接寫到一個auto.sh文件中:
#!/bin/sh
if [[ $# == 0 ]]; then
echo "./debugTool [package] [activity] "
exit 1
fi
package=$1
activity=$2
adb shell am start -D -n ${package}/${activity}
varId=`adb shell ps | grep package| awk '{print $2}'`
adb forward tcp:4567 jdwp:$varId
複製代碼
接着命令行鍵入:./auto.sh 包名 入口Activity,示例以下:
./auto.sh com.xxx.xxx .MainActivity
複製代碼
APP進入待調試等待模式後,點擊頂部「Attach Debugger To Android Process」,下好斷點,選擇調試進程:
接着等待程序運行至斷點,Debugger就能夠看到相關的變量了:
Smali的語法比較繁雜(感受比我之前學彙編還麻煩),網上的教程不是通常的凌亂,有機會我整理一份吧…
你真的想學Smali得話,建議邊「實操邊學,即用即插(查)」,idea有個插件「intellij-java2smali」
Github地址:github.com/ollide/inte…,支持把「正確項目中的Java」轉換爲smali文件。
注意:正確!和 項目!項目有錯的話,轉換直接報錯,單個獨立的java文件也是不能轉換的!用法很簡單:
打開須要轉換的java文件,依次點擊頂部菜單欄的 run -> Compile to smali
說個bug:
官方說是支持kotlin轉的,可是新版的AS會報錯:Error:Kotlin: Unsupported plugin option: org.jetbrains.kotlin.android:enabled=true,估計是插件的用到的kotlin相關依賴沒升級,目前無解(等官方維護,或者本身改插件源碼);
你能夠選擇建立一個純Java的項目,程序沒報錯,能夠跑,可是轉換的時候,又會出現一個bug:
java: 程序包R不存在 ,R文件找不到,儘管你能夠在build目錄下找到它,猜想是沒有適配新版本AS的R文件路徑,一個治標不治本的方法,把setContentView()一行的代碼註釋掉。
另外,我的感受AS上看 smali並非很爽 !既然以爲不爽,那就換個體位,是吧?舉幾個例子:
- 男的以爲不夠刺激,就用「推磨式」;
- 女的以爲不夠刺激,就用「貓式」;
- 男的想快感加倍,就用「後入式」;
- 女的想自由把控,就用「傳統女上位式」;
- 想豐富彼此情感交流,就用「傳教士體位」;
- 想延長時間,就用「面對面側臥」;
- em…體位有不少,就不一一列舉了,只是想告訴你們:哪一種方式適合本身就用哪一種~
若是你用「VS Code」的話,能夠安裝一個「Smalise」插件:Smali語法高亮 支持變量或者方法名的定位:
除此以外,還能夠直接看「Unicode轉換後的中文」、「變量信息」、「定位到定義處」
目前不會,之後有興趣或者須要學再去學吧,學完了再來補全~
學完調試定位技巧,咱們已經能快速找到G點(核心代碼),再來玩點「刺激」的吧:
看到,有人在上一篇《因一紙設計稿,我把競品APP扒得褲衩不剩(中)》有人在評論區留言對「鄰居的故事」感興趣,我用簡單的幾句詩來歸納下後續劇情吧:
男子加班回家晚,草草了事交公糧。
妹子以爲略失望,慾求不滿暗自嘆。
鄰居首捷心暗爽,惟美畫面反思量。
妹子軟萌待開發,制服跳蛋震動棒。
以爲妹子過於乖巧,鄰居想二次開發妹子(APK),因而用上了三個道具,這些道具怎麼用等等再說。說回這一節,在使用別人APP的時候,你可能會想:若是是個人作的APP,我要…!建議別想,直接動手吧!加點什麼(自定義UI) 或者 改點什麼(付費變免費,開隱藏關卡),固然本身暗爽就行了,可別處處傳播,「破壞計算機信息系統罪警告」。以競品APP關卡付費爲例,講解一波:
問題描述以下:
- 一、首頁課程有鎖,點擊:彈出須要開通完整課程的對話框;
- 二、點擊下一關,沒法切換到下一關,提示:敬請期待;
- 三、50-100節的課程帶鎖,點擊提示:努力建造中…;
- 四、課程等級除了L1外,其餘級別帶鎖,點擊提示:敬請期待;
怎麼動態調試Smali上面已經介紹過了,具體調試技巧可見《逮蝦戶!Android程序調試竟簡單如斯》,來到APP中的以下頁面:
點擊50-100 會出現「努力建造中」的提示語,打開開發者助手:
直接定位到 CourseChangeFragment:
看下this.n是啥,以及裏面的d是什麼:
行吧,這個d就是圖片是否高亮,1爲高亮,接着看下this.n在哪裏完成賦值:
而關卡選擇,直接全局搜「選擇等級對應的課程地圖」定位到ChangeLevelDialog,全局搜,定位回CourseChangeFragment:
一樣,看下this.k是啥,在哪裏完成了賦值:
跟到ChangeLevelDialog,能夠看到,提取的是裏面的CourseLevelInfo
跟過去看看:
行吧,這個c就是關卡的狀態,1爲可用狀態,行吧,找下斷點的時機,搜下控件:
控件id爲0x7f0f0363,回到CourseChangeFragment.smali搜:
直接定位到sswitch_2:
這裏圈住的地方,實際上是中文的Unicode碼,不信,轉換下你就知道了:
定位到下面這段代碼:
接着講解一波這段代碼:
iget-object v0, p0, .../CourseChangeFragment;->n:.../$CourseLevelMapInfo;
# 引用對象,p0爲該變量所在類的實例,即this,把n的值放到v0寄存器中
if-eqz v0, :cond_1
# 判斷v0是否爲0(null),是的話跳到cond_1
iget-object v0, p0, .../CourseChangeFragment;->n:.../$CourseLevelMapInfo
# 同上上一行代碼把n的值放到v0寄存器中
iget v0, v0, ...$CourseLevelMapInfo;->d:I
# 引用v0寄存器中保存的n對象,把n.d的值放到v0寄存器中
if-ne v0, v1, :cond_1
# 判斷v0寄存器和v1寄存器中的值是否相等,不等跳到cond_1
複製代碼
如圖下完斷點,開始調試smail,來到關切頁面,點擊後進入調試模式:
右鍵d,選擇Set Value,把值設置爲1,接着往下執行斷點,能夠看到「隱藏關卡」開啓成功:
嘖嘖,有點意思,其餘幾個破解也是「如法炮製」,不過每次都要這樣調試顯得太麻煩了,有沒有一勞永逸的方法?固然有,寫個Xposed插件耍耍吧~
關於Xposed,以前寫過一個系列,就再也不詳細介紹了:
簡單說經過它,你能夠:
修改變量的值,Hook方法(執行先後作一些修改),顯式去執行一些方法等。
咱們須要先定位到「標誌位的源頭處」(通常是方法),在方法執行前或後,進行一些修改,過程比較瑣碎,直接給出插件代碼吧!先是三、破解課程選擇的鎖:
接着是:四、破解關卡選擇對話框
再接着是:二、破解首頁下一關切換
最後是:一、破解首頁全部關卡
把寫好的Xposed插件安裝到手機上,Xposed Installer勾選,重啓,接着打開APP,看下效果:
行吧,插件編寫完畢,可是畢竟不是每一個人的手機都會Root裝Xposed,索性破解後二次打包吧。
使用apktool二次打包的流程很簡單,難的是改Samli代碼:
改smali => apktool b 重打包 => jarsigner/apksigner 二次簽名
行吧,動手擼smali,定位到 CourseChangeFragment.smali 的 onClick函數 的判斷處代碼:
前面這個數字是「十六進制的資源id」,能夠直接把jadx反編譯出來的id轉換下:
分別對應:7f0f0360 和 7f0f0363,對應跳=> sswitch_3 和 sswitch_2,先去sswitch_2處,能夠看到源碼中作了判斷,若是不知足return,知足的話繼續走,這裏能夠鑽個空子,「直接把判斷相關的代碼刪掉」,只保留下圖圈着的代碼:
接着拖過以下命令把項目二次打包回apk:
apktool b xxx -o xxx.apk
複製代碼
接着用「jadx-gui」打開apk看看代碼:
嘖嘖,能夠,接着須要對APK進行二次簽名才能安裝到手機上,能夠經過「jarsigner」或「apksigner」完成簽名。玩法以下:
# 若是你沒有簽名,可經過下述命令建立,回車後會讓你輸入密碼,輸完無腦回車便可
keytool -genkey -v -keystore 文件名.jks -keyalg RSA -keysize 2048 -validity 10000 -alias 簽名別名
# ====== jarsigner簽名 ======
# 一、輸入下述指令,回車後輸入密碼
jarsigner -verbose -keystore 證書 -signedjar 簽名後.apk 簽名前.apk 證書別名
# 二、報錯的話可能須要最在-keystore前添加下述參數:
-digestalg SHA1 -sigalg MD5withRSA
# 三、Tips:可使用下述命令查看APK是否已簽名
jarsigner -verify xxx.apk
# ====== 使用谷歌提供的簽名及驗證的專用工具:apksigner ======
# 位於:Android SDK/build-tools/SDK版本/apksigner.bat
# 一、對齊
zipalign -v -p 4 xxx.apk xxx_aligned.apk
# 二、簽名
sign --ks 證書 --out release.apk origin_aligned.apk
# 三、驗證是否簽名成功
apksigner verify release.apk
複製代碼
把簽名後的APK安裝到手機上,打開看下效果:
雖然還有鎖的那個圖標,可是卻能夠點擊切換關卡了,能夠,繼續折騰,選擇關卡部分:
點擊時判斷 courseLevelInfo.c == 1,那麼咱們找到初始化courseLevelInfo對象的地方,在這裏直接把c設置爲1便可,不難定位到:
在箭頭所指的代碼後,添加一句:courseLevelInfo.c = 1;,就行了,可是你須要把這個java語句轉換成smali!這個轉換可沒你想象中那麼簡單哦!打開ChangeLevelDialog.smali,定位a方法:
不難定位到以下位置,咱們須要在.line 添加賦值代碼:
賦值操做須要用一個寄存器保存1(0x1),而後用iput進行賦值:
接着apktool b打包,用jadx-gui打開看看:
行吧,轉換後除了行號,沒問題,直接jarsigner二次簽名,adb安裝到手機上驗證下:
能夠,nice,把剩下的首頁下一關和全部關卡也折騰下吧:
刪除賦值語句,對應Smali中:
重打包,jadx-gui打開查看:
每一個關卡鎖定位到:MainHomeworkAdapter$CommonViewHolder類 (美圓符號表明內部類)
在如圖所示的地方插入賦值語句,
重打包,jadx-gui打開查看:
運行下看下效果,結果和xposed大同小異,可是沒裝Xposed的手機也能直接使用~
而後說一點:
不是全部的APK都能直接二次打包簽名!有些會作簽名校驗,打開簽名不對,直接閃退,Java層能夠Hook掉檢驗的方法,Native層的只能去改So;還有些加固的APK,儘管能夠導出dex,可是二次打包的話還須要修復onCreate函數(如360加固寶)。因此大部分時候,咱們都只是能看看代碼而已~因此Xposed仍是香,Smali寫起來是真的繁瑣,複雜邏輯的代碼會寫到想哭,每次看效果都要重打包…
PC端逆向,須要下載一堆反編譯工具(apktool, jadx等),一些更好用的工具(AndroidKiller,smali2java)等還不支持mac,
因此它來了—— MT管理器2:移動端「雙窗口文件管理」和「強大的APK編輯功能」,可在手機上高效地修改安卓軟件,界面以下:
官方文檔中已有詳細的講解,就不嗶嗶了,讀者自行查看文檔把:MT管理器,另外還有個相關的逆向論壇:MT論壇
「Tips:基本上能夠說是付費的,部分功能須要會員才能使用~」
筆者有「記帳」的習慣,用的是「X記帳」,界面粉粉的,挺Gay的,就是每次打開彈出的「廣告閃屏頁」令我非常反感。行吧,就拿它來開刀吧,順帶給你們演示下「MT管理器2」怎麼耍。
點擊左側菜單欄的「跟蹤Activity」,開始跟蹤,接着打開軟件,而後回到MT管理器,能夠看到Activity的啓動記錄:
先進LogoActivity,再進MainActivity,點擊左側菜單「安裝包提取」:
提取後定位到/MT2/apks目錄下,點apk,「查看」,打開AndroidManifest.xml也看到:
行吧,入口是就是LogoActivity,點擊classex.dex打開,兩個dex都選擇:
接着按照包名,打開LogoActivity,點擊右上角,「轉成Java」
轉換後的Java代碼和Jadx的同樣:
見名知意,圈着的就是顯示廣告的View(@BindView祖傳黃油刀),想把廣告禁掉,把相關加載的代碼都刪掉就好啦:
和PC同樣改smali,不過比起PC,改完,直接就能夠轉Java,方便好多,修改完後保存,返回會彈出以下對話框:
可是,打開二次打包後的APP:「廣告內容沒了,可是卻卡在了圖標頁,要點擊右上角才能關閉」
我擦,估計是AdsView裏還有什麼邏輯(好比廣告加載完才跳轉),一不作二不休,直接把這個AdsView給去掉吧,
刪佈局文件裏的,再刪LogoActivity相關的代碼,正當我準備開始這樣作的時候,我看到了這些:
2333,爲了不「空指針異常」,調用adsView相關方法前都作了「判空」能夠,很好的開發習慣!
但也方便了我(內心樂開了花)
我直接在頁面初始化的地方把這個「adsView設置爲null」不就行了!
定位到如圖所示位置,在初始化View的地方把View置空,沒毛病
打開initView函數對應的smali代碼,編寫把adsView置空的smali代碼:
二次打包,覆蓋安裝看看效果:
對比下沒去廣告的效果:
當真是日了狗,點擊跳過的按鈕很小很容易誤觸,並且點了還不是立馬關閉!改完後瞬間舒服了~
對了,學完這裏你能夠出去吹牛逼了:《兩行代碼去掉APP閃屏廣告頁》
其實,原本沒有這一節的,畢竟,APP源碼都被你扒得褲衩不剩「任意蹂躪」了,可是有一點:
她並不屬於你!
若是哪一天,這個APP下架了,服務器撤掉了,你所作的一切就「付之東流」了。
與其在之後的某一天說暗自感嘆
「祝你歲月無波瀾,敬我餘生不悲歡」
不如想辦法讓她真的屬於你:
說到底:APP只是一個資源展現工具,而後臺則是一個資源調度工具,關鍵的仍是「資源」!
把資源搞到手,APP和後臺隨便你折騰,接着抓包分析一波,而後寫個爬蟲把每一關的數據保存起來~
直接經過 Fiddler,Charles等 抓包工具抓取一波數據,移動端如何抓包,可參見我以前寫過的文章:《忘了他吧!我偷別人APP的代碼養你》,此處就再也不復述了,直接開抓:
好幾個接口,篩選出咱們須要的接口:
規則比較簡單,接口沒作用戶校驗,付費資源連接也有返回,只是在APP端作了限制。
直接頂一個一個存儲數據的類,把爬取到的數據塞到MongoDB中:
出於反爬蟲的習慣,使用「代理ip」訪問,關於代理IP如何獲取,之前說過,就不嗶嗶了,這裏用阿布雲的代理隧道,1塊錢1小時,美滋滋,相關配置以下:
除了使用代理ip,「設備名,設備id,版本」都隨機生成:
接着編寫請求和解析數據的方法:
最後開啓一波多進程訪問:
多進程+可用性比較高的代理,一分鐘不到就爬完,美滋滋:
lessonDay的順序有些不對,排序查詢一波:
行吧,數據爬取完畢,剩下的接口就不一一演示了,對了,你還能夠寫個腳本把全部的音視頻資源,圖片爬到本身電腦,或者同步到七牛雲等CDN站點,接着遍歷替換一波基地址。另外,若是抓包分析不出規律,你也能夠從APP入手~
歷經坎坷,終於把最後一章給肝出來了,寫這個系列的初衷是想扒一些競品APP的好看效果,結果活生生寫成了逆向,也算是本身一個階段性學習的總結了,逆向的水挺深的,有機會和閒情再耍耍把,就這樣,接下來,準備寫個「面試準備週報」系列,以督查本身好好準備面試,敬請期待。
本系列最後一次送書,意思意思送「一本本身寫的Python爬蟲入門書」,評論區留言抽,包郵,下週五抽~ (可能延遲,但必定抽,無暗箱~)
謝謝各位一直以來的支持和厚愛,愛大家~
Tips:本你想系列用到的工具,都有給出比較官方的下載連接!!!你也能夠到公號
「摳腚男孩」輸入000,回覆對應序號下載,謝謝~