iOS 逆向-macho文件和LLDB

一 利用class-dump導(dǎo)出所有頭文件

1. 安裝class-dunmp

可以直接安裝class-dump 或者安裝MonkeyDev
安裝MonkeyDev過(guò)后設(shè)置環(huán)境變量:因?yàn)楸救擞玫膠sh,所以vim ~/.zshrc加上export PATH=/opt/MonkeyDev/bin:$PATH

2. 導(dǎo)出頭文件

把ipa用歸檔實(shí)用工具打開(kāi)淆两,顯示包內(nèi)容刀诬,找到同名macho文件揩懒,進(jìn)入文件目錄昂利,然后class-dump -H QQMusic -o new(新的目錄文件中)

二 拆分和合并macho二進(jìn)制文件

1. 拆分

當(dāng)用多個(gè)架構(gòu)打包后,會(huì)生成一個(gè)fat macho文件济赎,用以下命令拆分:

lipo QQMusic -thin arm64 -output macho_arm64
lipo QQMusic -thin armv7 -output macho_armv7

把QQMusic二進(jìn)制的arm64架構(gòu)拆分并輸出為新的名字為macho_arm64的文件

2. 查看二進(jìn)制文件信息

file QQMusic

3. 合并

lipo -create macho_armv7 macho_arm64 -output newQQMUSIC

三 xcode選擇編譯架構(gòu)

1.png

build active architecture only設(shè)置debug和release版本編譯是塘娶,是否編譯多個(gè)架構(gòu);Architecture和valid Architecctures的交集贵涵,決定編譯時(shí)編譯哪些架構(gòu)

四 LLDB

1. 代碼斷點(diǎn)

  • 設(shè)置斷點(diǎn)
    2.png

    設(shè)置多個(gè)oc方法的斷點(diǎn):breakpoint set -n "-[ViewController save:]" -n "-[ViewController pauseGame:]"
  • 查看斷點(diǎn) breakpoint list
  • 繼續(xù)程序 c
  • 禁用斷點(diǎn) breakpoint disable 2.1禁用第二組的第一個(gè)斷點(diǎn)
  • 啟用斷點(diǎn) breakpoint enable 2.1
  • 刪除斷點(diǎn):只能刪除某組斷點(diǎn)breakpoint delete 3列肢,如果breakpoint delete 3.1起到的是禁用3.1的作用
  • 查看lldb指令:help
help breakpoint
     Commands for operating on breakpoints (see 'help b' for shorthand.)

Syntax: breakpoint

The following subcommands are supported:

      clear   -- Delete or disable breakpoints matching the specified source
                 file and line.
      command -- Commands for adding, removing and listing LLDB commands
                 executed when a breakpoint is hit.
      delete  -- Delete the specified breakpoint(s).  If no breakpoints are
                 specified, delete them all.
      disable -- Disable the specified breakpoint(s) without deleting them.  If
                 none are specified, disable all breakpoints.
      enable  -- Enable the specified disabled breakpoint(s). If no breakpoints
                 are specified, enable all of them.
      list    -- List some or all breakpoints at configurable levels of detail.
      modify  -- Modify the options on a breakpoint or set of breakpoints in
                 the executable.  If no breakpoint is specified, acts on the
                 last created breakpoint.  With the exception of -e, -d and -i,
                 passing an empty argument clears the modification.
      name    -- Commands to manage name tags for breakpoints
      read    -- Read and set the breakpoints previously saved to a file with
                 "breakpoint write".  
      set     -- Sets a breakpoint or set of breakpoints in the executable.
      write   -- Write the breakpoints listed to a file that can be read in
                 with "breakpoint read".  If given no arguments, writes all
                 breakpoints.

For more help on any particular subcommand, type 'help <command> <subcommand>'.
  • 設(shè)置所有的save:方法的斷點(diǎn) breakpoint set --selector save:

  • 設(shè)置某個(gè)文件中的save:方法的斷點(diǎn):breakpoint set --file ViewController.m --selector save:

  • 全局遍歷項(xiàng)目中所有方法名中包含某字段的斷點(diǎn):breakpoint set -r Game:

  • 根據(jù)內(nèi)存地址給方法-[ViewController eatWithObjc:] 下斷點(diǎn):
    image list得到:

[  0] 9DC999FC-3D7D-37A2-A57D-F33622E4FB43 0x0000000101378000 /Users/mac/Library/Developer/Xcode/DerivedData/003--Demo1-euekigzuynuvedgnvqwopomnhaam/Build/Products/Debug-iphoneos/003--Demo1.app/003--Demo1

那么ALSR偏移量為:0x1378000,在ida中得到-[ViewController eatWithObjc:]的地址為:

_text:0000000100006688 ; void __cdecl -[ViewController eatWithObjc:](ViewController *self, SEL, id)
__text:0000000100006688 __ViewController_eatWithObjc__          ; DATA XREF: __objc_const:0000000100008170↓o

最終得到方法在內(nèi)存中的真實(shí)地址為:0x100006688+0x1378000
下斷點(diǎn):b -a 0x100006688+0x1378000

2. 執(zhí)行代碼進(jìn)行調(diào)試

  • expression 簡(jiǎn)寫(xiě)p
(lldb) expression self.view.subviews
(NSArray *) $0 = 0x0000000159e38920
(lldb) p self.view.backgroundColor = [UIColor yellowColor]
(UIColor *) $1 = 0x0000000159e837f0
(lldb) c
Process 80637 resuming
2018-05-07 16:20:42.198488+0800 001--LLDB[80637:7308534] XPC connection interrupted
2018-05-07 16:21:00.038626+0800 001--LLDB[80637:7308097] Status bar could not find cached time string image. Rendering in-process.

打印對(duì)象:po self.view.subviews

  • 舉個(gè)例子??:

在數(shù)組中加入新的Person對(duì)象

(lldb) p [self.models addObject:[Person new]];
(lldb) p (Person *)self.models.lastObject
(Person *) $3 = 0x0000000101508080
(lldb) p $3.name = @"meryin"
(NSString *) $4 = 0xa006e697972656d6
(lldb) p $3.age = 20
(int) $5 = 20
(lldb) po $3.name
meryin

設(shè)置變量然后再添加:

(lldb) p Person *p4 = [Person new]; //按住control和回車鍵,繼續(xù)代碼
p4.name = @"tom";p4.age = 25;
[self.models addObject:p4];//最后回車

3. 內(nèi)存斷點(diǎn)

  • 給某對(duì)象的某屬性下斷點(diǎn):
    (lldb) watchpoint set variable p1->_name
    或者利用內(nèi)存地址下斷點(diǎn):
(lldb) frame variable
(ViewController *) self = 0x0000000105ec23b0
(SEL) _cmd = "viewDidLoad"
(Person *) p1 = 0x0000000105ea8190
(Person *) p2 = 0x0000000000000010
(Person *) p3 = 0x000000016f3e5528
(lldb) p &p1->_name
(NSString **) $2 = 0x0000000105ea81a0
(lldb) watchpoint set expression 0x0000000105ea81a0
Watchpoint created: Watchpoint 2: addr = 0x105ea81a0 size = 8 state = enabled type = w
    new value: 4305584416
(lldb) watchpoint list
Number of supported hardware watchpoints: 4
Current watchpoints:
Watchpoint 2: addr = 0x105ea81a0 size = 8 state = enabled type = w
    new value: 4305584416
(lldb) 

4. 斷點(diǎn)后執(zhí)行指令

(lldb) break command add 1
Enter your debugger command(s).  Type 'DONE' to end.
> p self //回車
> p self.models //回車
> DONE //回車

在1組處打了斷點(diǎn)宾茂,斷點(diǎn)執(zhí)行到1后會(huì)執(zhí)行p self等指令
breakpoint command list查看斷點(diǎn) 用法和breakpoint一樣

5. 查看堆棧信息

  • 函數(shù)調(diào)用棧:bt
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x000000010092e388 001--LLDB`-[ViewController touchesBegan:withEvent:](self=0x0000000100e69740, _cmd="touchesBegan:withEvent:", touches=0x0000000100fa54d0, event=0x0000000100f644d0) at ViewController.m:85
    frame #1: 0x000000018ea61870 UIKit`forwardTouchMethod + 340
    frame #2: 0x000000018e9077c8 UIKit`-[UIResponder touchesBegan:withEvent:] + 60
    frame #3: 0x000000018e901830 UIKit`-[UIWindow _sendTouchesForEvent:] + 1892
    frame #4: 0x000000018e8f68f8 UIKit`-[UIWindow sendEvent:] + 3160
    frame #5: 0x000000018e8f5238 UIKit`-[UIApplication sendEvent:] + 340
    frame #6: 0x000000018f0d6c0c UIKit`__dispatchPreprocessedEventFromEventQueue + 2340
    frame #7: 0x000000018f0d91b8 UIKit`__handleEventQueueInternal + 4744
    frame #8: 0x000000018f0d2258 UIKit`__handleHIDEventFetcherDrain + 152
    frame #9: 0x0000000184af7404 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
    frame #10: 0x0000000184af6c2c CoreFoundation`__CFRunLoopDoSources0 + 276
    frame #11: 0x0000000184af479c CoreFoundation`__CFRunLoopRun + 1204
    frame #12: 0x0000000184a14da8 CoreFoundation`CFRunLoopRunSpecific + 552
    frame #13: 0x00000001869f7020 GraphicsServices`GSEventRunModal + 100
    frame #14: 0x000000018e9f578c UIKit`UIApplicationMain + 236
    frame #15: 0x000000010092e54c 001--LLDB`main(argc=1, argv=0x000000016f4d79d8) at main.m:14
    frame #16: 0x00000001844a5fc0 libdyld.dylib`start + 4
  • 查看某一個(gè)函數(shù): frame select 1
  • 查看上一個(gè)函數(shù):(lldb) up
  • 查看下一個(gè)函數(shù):(lldb) down
  • 查看參數(shù):
(lldb) frame variable
(ViewController *) self = 0x0000000100e69740
(SEL) _cmd = "touchesBegan:withEvent:"
(NSSet *) touches = 0x0000000100fa54d0
(UIEvent *) event = 0x0000000100f644d0
(NSString *) str = 0x0000000100e96820
(Person *) p1 = 0x0000000100faa7b0
(lldb) p str = @"xxx";
(lldb) po str
xxx
  • 回滾上一個(gè)函數(shù)并不再執(zhí)行:thread return

6. stop-hook

在每次斷住程序的時(shí)候去執(zhí)行一些命令,只對(duì)breadpoint,watchpoint生效

(lldb) target stop-hook add -o "frame variable"
Stop hook #1 added.
(lldb) target stop-hook list
Hook: 1
  State: enabled
  Commands: 
    frame variable

當(dāng)某個(gè)斷點(diǎn)觸發(fā)后瓷马,會(huì)執(zhí)行"frame variable"指令
target stop-hook用法和breakpoint 一樣,list查看跨晴,delete刪除 刪除某組還可以用(lldb) undisplay 1
還可以用配置文件欧聘,不用每次運(yùn)行Xcode都要寫(xiě)指令:
找到.lldbinit或者touch .lldbinit在此文件中配置自己的指令。

4.png

vim .lldbinit然后target stop-hook add -o "frame variable"保存退出端盆,用cat .lldbinit可以看到target stop-hook add -o "frame variable"

7. image lookup查看庫(kù)怀骤,類和崩潰等信息

(lldb) help image lookup
     Look up information within executable and dependent shared library images.

Syntax: 

Command Options Usage:
  target modules lookup [-Av] -a <address-expression> [-o <offset>] [<filename> [<filename> [...]]]
  target modules lookup [-Arv] -s <symbol> [<filename> [<filename> [...]]]
  target modules lookup [-Aiv] -f <filename> [-l <linenum>] [<filename> [<filename> [...]]]
  target modules lookup [-Airv] -F <function-name> [<filename> [<filename> [...]]]
  target modules lookup [-Airv] -n <function-or-symbol> [<filename> [<filename> [...]]]
  target modules lookup [-Av] -t <name> [<filename> [<filename> [...]]]

       -A ( --all )
            Print all matches, not just the best match, if a best match is
            available.

       -F <function-name> ( --function <function-name> )
            Lookup a function by name in the debug symbols in one or more
            target modules.

       -a <address-expression> ( --address <address-expression> )
            Lookup an address in one or more target modules.

       -f <filename> ( --file <filename> )
            Lookup a file by fullpath or basename in one or more target
            modules.

       -i ( --no-inlines )
            Ignore inline entries (must be used in conjunction with --file or
            --function).

       -l <linenum> ( --line <linenum> )
            Lookup a line number in a file (must be used in conjunction with
            --file).

       -n <function-or-symbol> ( --name <function-or-symbol> )
            Lookup a function or symbol by name in one or more target modules.

       -o <offset> ( --offset <offset> )
            When looking up an address subtract <offset> from any addresses
            before doing the lookup.

       -r ( --regex )
            The <name> argument for name lookups are regular expressions.

       -s <symbol> ( --symbol <symbol> )
            Lookup a symbol by name in the symbol tables in one or more target
            modules.

       -t <name> ( --type <name> )
            Lookup a type by name in the debug symbols in one or more target
            modules.

       -v ( --verbose )
            Enable verbose lookup information.
     
     This command takes options and free-form arguments.  If your arguments
     resemble option specifiers (i.e., they start with a - or --), you must use
     ' -- ' between the end of the command options and the beginning of the
     arguments.

'image' is an abbreviation for 'target modules'
  • 查看崩潰信息
    比如數(shù)組越界的崩潰信息:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndexedSubscript:]: index 4 beyond bounds [0 .. 2]'
*** First throw call stack:
(0x184b4ed8c 0x183d085ec 0x184ae7750 0x184ad48cc 0x1007ae328 0x18ea61870 0x18e9077c8 0x18e901830 0x18e8f68f8 0x18e8f5238 0x18f0d6c0c 0x18f0d91b8 0x18f0d2258 0x184af7404 0x184af6c2c 0x184af479c 0x184a14da8 0x1869f7020 0x18e9f578c 0x1007ae52c 0x1844a5fc0)
libc++abi.dylib: terminating with uncaught exception of type NSException

用image lookup -a查看信息,找到崩潰的方法-[ViewController touchesBegan:withEvent:]

(lldb) image lookup -a 0x184b4ed8c
      Address: CoreFoundation[0x0000000180ef6d8c] (CoreFoundation.__TEXT.__text + 1313804)
      Summary: CoreFoundation`__exceptionPreprocess + 228
(lldb) image lookup -a 0x1007ae328 
      Address: 001--LLDB[0x0000000100006328] (001--LLDB.__TEXT.__text + 1796)
      Summary: 001--LLDB`-[ViewController touchesBegan:withEvent:] + 160 at ViewController.m:86
(lldb) image lookup -a 0x18ea61870
      Address: UIKit[0x000000018ae09870] (UIKit.__TEXT.__text + 3699592)
      Summary: UIKit`forwardTouchMethod + 340
  • 查看類信息
    image lookup -t Person
  • image list查看當(dāng)前用到的庫(kù)

8. 其他指令

  • 單步運(yùn)行(子函數(shù)當(dāng)成整體):n
  • 單步運(yùn)行(進(jìn)入子函數(shù)):s
  • 匯編的單步(子函數(shù)當(dāng)成整體):ni
  • 匯編的單步(進(jìn)入子函數(shù)):si


    3.png
最后編輯于
?著作權(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)離奇詭異,居然都是意外死亡末患,警方通過(guò)查閱死者的電腦和手機(jī)研叫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)璧针,“玉大人嚷炉,你說(shuō)我怎么就攤上這事√匠鳎” “怎么了申屹?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)隧膏。 經(jīng)常有香客問(wèn)我独柑,道長(zhǎng),這世上最難降的妖魔是什么私植? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任忌栅,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘索绪。我一直安慰自己湖员,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布瑞驱。 她就那樣靜靜地躺著娘摔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪唤反。 梳的紋絲不亂的頭發(fā)上凳寺,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音彤侍,去河邊找鬼肠缨。 笑死海蔽,一個(gè)胖子當(dāng)著我的面吹牛鸵熟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播唆鸡,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼名斟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼脑慧!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起砰盐,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤闷袒,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后岩梳,有當(dāng)?shù)厝嗽跇?shù)林里發(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
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望洛波。 院中可真熱鬧胰舆,春花似錦骚露、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至倦零,卻和暖如春误续,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扫茅。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工蹋嵌, 沒(méi)想到剛下飛機(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)容

  • Xcode Debugging 你的代碼,或者任何人的代碼中總會(huì)有bug存在慧起,你可以把調(diào)試看做是更好地理解代碼的一...
    吃蘑菇De大灰狼閱讀 2,448評(píng)論 0 2
  • 轉(zhuǎn)載 與調(diào)試器共舞 - LLDB 的華爾茲: https://objccn.io/issue-19-2/ 推薦:i...
    F麥子閱讀 3,332評(píng)論 0 10
  • 你是否曾經(jīng)苦惱于理解你的代碼菇晃,而去嘗試打印一個(gè)變量的值? NSLog(@"%@", whatIsInsideThi...
    paraneaeee閱讀 1,192評(píng)論 0 7
  • LLDB的Xcode默認(rèn)的調(diào)試器蚓挤,它與LLVM編譯器一起磺送,帶給我們更豐富的流程控制和數(shù)據(jù)檢測(cè)的調(diào)試功能。平時(shí)用Xc...
    CoderSC閱讀 1,360評(píng)論 0 2
  • iOS調(diào)試之LLDB Xcode內(nèi)嵌了LLDB控制臺(tái)灿意,在Xcode代碼編輯區(qū)的下方估灿。shift + cmd + y...
    comst閱讀 1,478評(píng)論 0 3