安卓應(yīng)用調(diào)試

最近學(xué)習(xí)了一下安卓應(yīng)用的調(diào)試方法薪者,覺(jué)得可能對(duì)于部分初學(xué)者而言會(huì)有一定幫助彩扔,所以在這里把整個(gè)調(diào)試過(guò)程記錄下來(lái)址晕。

調(diào)試環(huán)境

android 7.1(userdebug版本痹愚,可以在不重打包的條件下調(diào)試應(yīng)用憎瘸。ps. 使用sdk下載的鏡像默認(rèn)就是這種版本)
IDA 6.8(沒(méi)有的同學(xué)可以到52pojie上下載)

測(cè)試對(duì)象

whctf2017的安卓逆向題loopcrypto

程序分析

反調(diào)試

在init_array里面定義了一個(gè)函數(shù)sub_83DC


image.png

通過(guò)反編譯不難發(fā)現(xiàn)入篮,這是一個(gè)反調(diào)試函數(shù),需要patch后才能調(diào)試


image.png

PS. 不知道調(diào)用fork函數(shù)算不算一種反調(diào)試方法幌甘,但是總會(huì)遇到fork之后斷開(kāi)調(diào)試的情況潮售。這種反調(diào)試很容易解決,因?yàn)槲覀儾捎玫氖莿?dòng)態(tài)patch锅风,所以直接修改pc到return的指令上就可以了酥诽。解決這個(gè)反調(diào)試后就可以正常的調(diào)試了。
函數(shù)注冊(cè)

IDA在進(jìn)行分析的過(guò)程中并沒(méi)有吧JNI_OnLoad函數(shù)識(shí)別出來(lái)皱埠,但我們可以在export視圖里面找到它肮帐。

image.png
image.png

通過(guò)分析,不難發(fā)現(xiàn)JNI_Onload注冊(cè)的check函數(shù)對(duì)應(yīng)的真實(shí)函數(shù)為sub_87FC(為了方便分析jni函數(shù)調(diào)用边器,我們可以導(dǎo)入jni.h函數(shù)定義训枢,快鍵鍵Ctrl+F9)

image.png

調(diào)試過(guò)程

因?yàn)閼?yīng)用加載so庫(kù)的過(guò)程有反調(diào)試代碼,因此需要在應(yīng)用加載so庫(kù)之前attach到應(yīng)用程序上忘巧,并patch相關(guān)反調(diào)試代碼恒界。這里我們采用實(shí)時(shí)patch的方法,這樣的話可以省去重打包的麻煩砚嘴,同時(shí)也可以不用處理java層的簽名檢測(cè)十酣。

第一步

以調(diào)試模式啟動(dòng)應(yīng)用(調(diào)試模式啟動(dòng)可以使得應(yīng)用程序停止在程序入口點(diǎn))

adb shell am start -D -n com.a.sample.loopcrypto/.MainActivity
第二步

使用IDA attach到目標(biāo)應(yīng)用。在此之前我們可能需要先push一個(gè)android_server(android7.1上需要使用pie編譯的版本)到手機(jī)內(nèi)部

λ file android_server
android_server: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, stripped

λ adb push android_server /data/local/tmp
android_server: 1 file pushed...MB/s (523480 bytes in 0.108s)

λ adb shell chmod 777 /data/local/tmp/android_server

使用root權(quán)限啟動(dòng)android_server

λ adb shell
angler:/ # id
uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc) context=u:r:su:s0
angler:/ # cd /data/local/tmp
/android_server    < IDA Android 32-bit remote debug server(ST) v1.19. Hex-Rays (c) 2004-2015
Listening on port #23946...

開(kāi)啟端口轉(zhuǎn)發(fā)

adb forward tcp:23946 tcp:23946

準(zhǔn)備工作完成之后就可以開(kāi)心的調(diào)試了际长。首先選擇Android debugger


image.png

然后attach目標(biāo)應(yīng)用

image.png
image.png

設(shè)置調(diào)試選項(xiàng)為加載動(dòng)態(tài)庫(kù)時(shí)掛起耸采,然后恢復(fù)運(yùn)行。

image.png

事實(shí)上這個(gè)時(shí)候我們還不能調(diào)試也颤,因?yàn)閖ava層代碼還處于等待調(diào)試狀態(tài)洋幻,需要使用jdb恢復(fù)運(yùn)行,但命令行的方式不是特別好用翅娶,所以我們這里使用Android Studio來(lái)解決這個(gè)問(wèn)題(需要?jiǎng)?chuàng)建一個(gè)應(yīng)用)文留。

image.png

這個(gè)時(shí)候我們就會(huì)發(fā)現(xiàn)IDA停在了加載so庫(kù)的位置好唯,只不過(guò)不是加載libcheck.so。

image.png

恢復(fù)運(yùn)行燥翅,程序再次會(huì)再次斷下來(lái)骑篙,通過(guò)output window可以看到即將加載libcheck.so。

image.png

這個(gè)時(shí)候我們可以給init_array里面定義的函數(shù)下斷點(diǎn)(Ctrl+S查看內(nèi)存map)森书。

image.png
image.png

恢復(fù)運(yùn)行靶端,程序會(huì)在剛下斷點(diǎn)的地方停下來(lái)。因?yàn)檎麄€(gè)函數(shù)除了反調(diào)之外沒(méi)有實(shí)際功能凛膏,所以我們可以修改pc讓其直接返回(為了保證棧平衡杨名,我們需要完整的執(zhí)行一對(duì)push和pop指令,所以執(zhí)行完13DC處的push指令后再修改pc使其指向下圖中標(biāo)識(shí)的指令)

image.png
image.png

到這兒猖毫,關(guān)于這個(gè)函數(shù)的反調(diào)試就已經(jīng)結(jié)束了台谍。這個(gè)時(shí)候我們就可以給check函數(shù)下斷點(diǎn)了

image.png

恢復(fù)運(yùn)行,在手機(jī)上隨便輸入一個(gè)flag吁断,程序就是停在check函數(shù)入口處

image.png

到這里的話安卓應(yīng)用調(diào)試方法就已經(jīng)介紹完了趁蕊,如果大家對(duì)于調(diào)試java代碼感興趣的話可以參考這篇文章。對(duì)于這道題后續(xù)的分析的話就沒(méi)有什么難度了仔役,所以不再贅述掷伙。

總結(jié)

本文簡(jiǎn)要地介紹了安卓應(yīng)用調(diào)試方法,但為了方便大家分析又兵,整個(gè)操作過(guò)程采用手動(dòng)完成任柜。事實(shí)上,IDAPython提供了豐富的調(diào)試接口寒波,這部分工作完全可以放到腳本里面自動(dòng)化完成乘盼。

補(bǔ)充

室友寫(xiě)的IDAPython腳本,懶得重寫(xiě)俄烁,直接粘過(guò)來(lái)了

from idaapi import *
from idc import *
from idautils import *


class DbgHook(DBG_Hooks):
    def dbg_library_load(self, pid, tid, ea, modinfo_name, modinfo_base, modinfo_size):
        print "%#x %s %#x" %(ea, modinfo_name, modinfo_base)
        if "libcheck.so" in modinfo_name:
            self.libcheck = modinfo_base
            print "libcheck addr is 0x%08x" % self.libcheck

            self.init_pop = self.libcheck + 0x8440
            self.init_addr = self.libcheck + 0x83e0
            add_bpt(self.init_addr,0,BPT_SOFT)
            #enable_bpt(self.init_addr,True)
            SetBptAttr( self.init_addr, BPTATTR_FLAGS, BPT_ENABLED|BPT_TRACE)

            self.check_ptrace = self.libcheck + 0x86f6
            self.check_fork = self.libcheck + 0x86b0
            add_bpt(self.check_fork,0,BPT_SOFT)
            #enable_bpt(self.check_fork,True)
            SetBptAttr( self.check_fork, BPTATTR_FLAGS, BPT_ENABLED|BPT_TRACE)

            self.key_addr = self.libcheck + 0x8728
            add_bpt(self.key_addr,0,BPT_SOFT)
            enable_bpt(self.key_addr,True)

        return


    def dbg_bpt(self, tid, bptea):
        print "[*] Hit: 0x%08x" % bptea
        
        if bptea == self.init_addr:
            print "Set Reg Value:"
            SetRegValue(self.init_pop,"PC")
        elif bptea == self.check_fork:
            print "Set Reg Value:"
            SetRegValue(self.check_ptrace,"PC")
        return

    def dbg_step_over(self):
        eip = GetRegValue("PC")
        print("MyDbgHook : 0x%x %s" % (eip, GetDisasm(eip)))
        return


num_breakpoints = GetBptQty()    
print "[*] Set %d breakpoints." % num_breakpoints  

debugger = DbgHook()
debugger.hook()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绸栅,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子页屠,更是在濱河造成了極大的恐慌粹胯,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辰企,死亡現(xiàn)場(chǎng)離奇詭異风纠,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)牢贸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)竹观,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事臭增《矗” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵誊抛,是天一觀的道長(zhǎng)列牺。 經(jīng)常有香客問(wèn)我,道長(zhǎng)拗窃,這世上最難降的妖魔是什么瞎领? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮随夸,結(jié)果婚禮上九默,老公的妹妹穿的比我還像新娘。我一直安慰自己逃魄,他們只是感情好荤西,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著伍俘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪勉躺。 梳的紋絲不亂的頭發(fā)上癌瘾,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音饵溅,去河邊找鬼妨退。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蜕企,可吹牛的內(nèi)容都是我干的咬荷。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼轻掩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼幸乒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起唇牧,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤罕扎,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后丐重,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體腔召,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年扮惦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了臀蛛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖浊仆,靈堂內(nèi)的尸體忽然破棺而出客峭,到底是詐尸還是另有隱情,我是刑警寧澤氧卧,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布桃笙,位于F島的核電站,受9級(jí)特大地震影響沙绝,放射性物質(zhì)發(fā)生泄漏搏明。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一闪檬、第九天 我趴在偏房一處隱蔽的房頂上張望星著。 院中可真熱鬧,春花似錦粗悯、人聲如沸虚循。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)横缔。三九已至,卻和暖如春衫哥,著一層夾襖步出監(jiān)牢的瞬間茎刚,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工撤逢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留膛锭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓蚊荣,卻偏偏與公主長(zhǎng)得像初狰,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子互例,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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