Android高效調(diào)試技巧02——反編譯

今天要給大家介紹一項(xiàng)調(diào)試技巧——反編譯葫辐。因?yàn)槲覀冇龅降膯栴}有時(shí)會(huì)跟第三方應(yīng)用有關(guān),對(duì)于這些我們沒有代碼的應(yīng)用维贺,如果不進(jìn)行反編譯,很難對(duì)其進(jìn)行分析彬檀。

說(shuō)到apk反編譯不得不說(shuō)代碼混淆帆啃,在簽名打包時(shí)啟動(dòng)代碼混淆可以幫助我們保護(hù)代碼。曾經(jīng)聽說(shuō)有小公司發(fā)布了未做代碼混淆的應(yīng)用窍帝,結(jié)果被別人反編譯后上架努潘,辛辛苦苦做出的應(yīng)用就這樣被別人竊取了,所以保護(hù)好自己的勞動(dòng)成果很重要盯桦。除了代碼混淆慈俯,有些應(yīng)用商店還會(huì)要求開發(fā)者進(jìn)行安裝包加固,以提高安全性拥峦。

反編譯就是把對(duì)代碼做的這些保護(hù)解開贴膘,讓我們了解別人代碼的部分細(xì)節(jié)。比如下面要介紹的例子略号,GoogleSetupWizard 引起的問題刑峡,雖然我們沒有它的源碼,但是通過反編譯我們可以了解內(nèi)部的邏輯玄柠。

反編譯工具

在處理這個(gè)問題之前我用的反編譯工具一直是Dex2Jar+jd-gui突梦,用法簡(jiǎn)單,只要將 apk解壓縮羽利,把解壓出的dex文件用Dex2Jar反編譯宫患,然后用jd-gui工具閱讀即可,對(duì)于沒有混淆的apk这弧,閱讀起來(lái)跟閱讀代碼體驗(yàn)差不多娃闲。但是在反編譯 GoogleSetupWizard 的時(shí)候卻出錯(cuò)(提示notsupport version)。咨詢了別的同事建議試試apktool匾浪,解出smali文件皇帮。關(guān)于smali,這里有一份文檔供大家參考Smali學(xué)習(xí)筆記蛋辈。

apktool的下載和使用: 將apktool.jar和apktool放到/usr/local/bin 目錄(需要root權(quán)限)属拾;運(yùn)行apktool d <apk-file> 進(jìn)行反編譯;

反編譯舉例

問題描述:
  在從Owner賬戶切換到Guest賬戶時(shí)失敗冷溶,自動(dòng)又切回Owner賬戶渐白,并且狀態(tài)欄無(wú)法正常下拉。

問題分析:
  該問題第一個(gè)難點(diǎn)是確認(rèn)誰(shuí)觸發(fā)了切回Owner賬戶的動(dòng)作挂洛。這里我們用android.util.Log類的Log.getStackTraceString(newThrowable()) 方法來(lái)完成礼预。賬戶切換會(huì)調(diào)用ActivityManagerNative類的switchUser方法,我們?cè)谠摲椒ㄖ刑砑尤缦抡Z(yǔ)句:

Log.i(TAG,Log.getStackTraceString(newThrowable()));

這樣調(diào)用關(guān)系就一目了然了虏劲。結(jié)果如下:

ActivityManagerNative:  at android.app.ActivityManagerProxy.switchUser(ActivityManagerNative.java:5866)
ActivityManagerNative:  atcom.google.android.setupwizard.util.UserHelper.removeThisUser(UserHelper.java:43)
ActivityManagerNative:  atcom.google.android.setupwizard.lifecycle.ProvisioningFlagsLifecycleCallback.onExit
(ProvisioningFlagsLifecycleCallback.java:49)
ActivityManagerNative:  at com.google.android.setupwizard.lifecycle.LifecycleManager.notifyExit(LifecycleManager.java:115)
ActivityManagerNative:  atcom.google.android.setupwizard.util.ExitHelper.finishSetup(ExitHelper.java:45)
ActivityManagerNative:  at
**com.google.android.setupwizard.util.SetupWizardUserInitReceiver**
.onReceive (SetupWizardUserInitReceiver.java:33)

可以看出調(diào)用者是com.google.android.setupwizard應(yīng)用的SetupWizardUserInitReceiver類托酸,它是一個(gè)Google gms 應(yīng)用。我們用apktool將其反編譯柒巫,SetupWizardUserInitReceiver.smali
文件如下:

.superLandroid/content/BroadcastReceiver;
.source"SetupWizardUserInitReceiver.java"
#direct methods

.methodpublic constructor <init>()V
.locals0
.prologue
.line 28
invoke-direct{p0}, Landroid/content/BroadcastReceiver;-><init>()V
return-void
.endmethod
#virtual methods
.methodpublic onReceive(Landroid/content/Context;Landroid/content/Intent;)V
.locals2
.paramp1, "context" # Landroid/content/Context;
.paramp2, "intent" # Landroid/content/Intent;
.prologue
.line 31

const-string/jumbov0, "android.intent.action.USER_INITIALIZE"
invoke-virtual{p2}, Landroid/content/Intent;->getAction()Ljava/lang/String;
move-result-objectv1
invoke-virtual{v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-resultv0
if-eqzv0, :cond_0
.line 32
invoke-static{p1},Landroid/os/UserManager;->get(Landroid/content/Context;)Landroid/os/UserManager;
move-result-objectv0
invoke-virtual{v0}, Landroid/os/UserManager;->isGuestUser()Z
move-resultv0
.line 31
if-eqzv0, :cond_0
.line 33
invoke-static{p1},Lcom/google/android/setupwizard/util/ExitHelper;->finishSetup(Landroid/content/Context;)V
.line 30
:cond_0
return-void
.endmethod

這是一個(gè)BroadcastReceiver励堡,我們要關(guān)注的是它的onReceive方法。通過網(wǎng)上搜索smali語(yǔ)法堡掏,可以判斷出當(dāng)為Guest用戶時(shí)會(huì)調(diào)用ExitHelper的finishSetup方法应结。我們?cè)倏催@個(gè)方法,

.methodpublic static finishSetup(Landroid/content/Context;)V
.locals2
.paramp0, "context" # Landroid/content/Context;
.prologue
.line 45

invoke-static{},Lcom/google/android/setupwizard/lifecycle/LifecycleManager;->get()Lcom/google/android/setupwizard/lifecycle/LifecycleManager;
move-result-objectv0
invoke-virtual{v0, p0},Lcom/google/android/setupwizard/lifecycle/LifecycleManager;->notifyExit(Landroid/content/Context;)V
.line 49

>new-instancev0, Landroid/content/Intent;
const-string/jumbov1, "com.google.android.setupwizard.SETUP_WIZARD_FINISHED"
invoke-direct{v0, v1}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V
invoke-virtual{p0, v0},Landroid/content/Context;->sendBroadcast(Landroid/content/Intent;)V
.line 42
return-void
.endmethod

上面先拿到了一個(gè)LifecycleManager 實(shí)例泉唁,然后調(diào)用了LifecycleManager的notifyExit方法鹅龄,再發(fā)送了一個(gè)com.google.android.setupwizard.SETUP_WIZARD_FINISHED廣播。最終亭畜,我們跟蹤到調(diào)用用戶切換的代碼如下:

50 const-string/jumbo v3, "device_provisioned"**
51 
52 invoke-static {v0, v3, v6},Landroid/provider/Settings$Global;>putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
53 
54 .line 56 
55 :cond_0 
56 :goto_0 
57 const-string/jumbo v3, "user_setup_complete" 
58 
59 invoke-static {v0, v3, v6},Landroid/provider/Settings$Secure;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
60 
61 .line 34 
62 return-void 
63 
64 .line 45 
65 :cond_1 
66 invoke-static {p1},Lcom/android/setupwizardlib/util/WizardManagerHelper;->isDeviceProvisioned(Landroid/content/Context;)Z
67 
68 move-result v3 
69 
70 if-nez v3, :cond_0 
71 
72 .line 48 
73 invoke-virtual {v2}, Landroid/os/UserManager;->getUserHandle()I 
74 
75 move-result v1 
76 
77 .line 49 
78 .local v1, "user":I 
79 invoke-static {p1},Lcom/google/android/setupwizard/util/UserHelper;->removeThisUser(Landroid/content/Context;)Z

上面會(huì)去讀device_provisioned這個(gè)setting項(xiàng)扮休,當(dāng)為false時(shí)會(huì)退出當(dāng)前賬戶。通過在源碼下搜索拴鸵,果然發(fā)現(xiàn)在packages/apps/Provision模塊下有對(duì)應(yīng)的提交玷坠,這樣就定位到了問題點(diǎn)。

總結(jié)

反編譯作為一項(xiàng)調(diào)試技巧劲藐,在通往高手之路上是不必可少的八堡。雖然反編譯后的代碼比較難懂,但是多加練習(xí)總有一天會(huì)得心應(yīng)手聘芜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末兄渺,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子汰现,更是在濱河造成了極大的恐慌挂谍,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件服鹅,死亡現(xiàn)場(chǎng)離奇詭異凳兵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)企软,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門庐扫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人仗哨,你說(shuō)我怎么就攤上這事形庭。” “怎么了厌漂?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵萨醒,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我苇倡,道長(zhǎng)富纸,這世上最難降的妖魔是什么囤踩? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮晓褪,結(jié)果婚禮上堵漱,老公的妹妹穿的比我還像新娘。我一直安慰自己涣仿,他們只是感情好勤庐,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著好港,像睡著了一般愉镰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钧汹,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天丈探,我揣著相機(jī)與錄音,去河邊找鬼崭孤。 笑死类嗤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辨宠。 我是一名探鬼主播遗锣,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼嗤形!你這毒婦竟也來(lái)了精偿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤赋兵,失蹤者是張志新(化名)和其女友劉穎笔咽,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體霹期,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叶组,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了历造。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甩十。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖吭产,靈堂內(nèi)的尸體忽然破棺而出侣监,到底是詐尸還是另有隱情,我是刑警寧澤臣淤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布橄霉,位于F島的核電站,受9級(jí)特大地震影響邑蒋,放射性物質(zhì)發(fā)生泄漏姓蜂。R本人自食惡果不足惜按厘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望覆糟。 院中可真熱鬧刻剥,春花似錦遮咖、人聲如沸滩字。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)麦箍。三九已至,卻和暖如春陶珠,著一層夾襖步出監(jiān)牢的瞬間挟裂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工揍诽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留诀蓉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓暑脆,卻偏偏與公主長(zhǎng)得像渠啤,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子添吗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一沥曹、前言 今天我們開始apk破解的另外一種方式:動(dòng)態(tài)代碼調(diào)試破解,之前其實(shí)已經(jīng)在一篇文章中說(shuō)到如何破解apk了: ...
    JiangWei_App閱讀 3,670評(píng)論 2 29
  • 大多數(shù)APP都對(duì)API接口進(jìn)行了加密碟联,防止第三方隨意調(diào)用接口妓美,常用的方法是,設(shè)置一個(gè)key鲤孵,在調(diào)用接口來(lái)發(fā)送請(qǐng)求時(shí)...
    vstorm閱讀 8,095評(píng)論 0 2
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,138評(píng)論 25 707
  • 【2015/2/26】 這一把鎖有個(gè)華麗的名字叫命運(yùn)齒輪壶栋。 可惜它的形狀并不是齒輪狀,而是兩片銀色的金屬鉸合在一起...
    下不停的雨閱讀 345評(píng)論 0 0
  • 情緒每個(gè)人都有允許自己的情緒和情緒在一起普监,有情緒不可怕接受情緒不好處理好不逃避不害怕贵试,情緒不可怕可怕自己不接納不理...
    下頁(yè)人氣閱讀 1,959評(píng)論 0 0