使用Python脚本强化LLDB调试器

LLDB是Xcode自带的调试器,作为一个iOS应用开发程序员,平时我在开发应用时会使用LLDB来调试代码。在逆向应用时,也会用到LLDB来跟踪应用的执行过程。

LLDB还内置了一个Python解析器,使用Python脚本可以方便LLDB的调试,比如自动化执行一些命令,或者自动化处理数据之类的,具体说明可以参考官方的文档:LLDB Python Reference

以下就以一个具体的例子来演示一个Python脚本的编写过程:

一、获取方法的偏移地址

运行系统自带的计算器Calculator.app

可以看到计算器的菜单里有一个“关于计算器”的选项:

如果我们要在点击“关于计算器”事件断下来的话,就要给这个方法设置一个断点。

先找到计算器的可执行文件的路径,路径为:/Applications/Calculator.app/Contents/MacOS/Calculator
打开Hopper Disassembler反汇编调试器,将可执行文件拖进去,等待Hopper分析完成。

在左侧的搜索框输入"showabout",会搜索到一个结果:

点击这个结果,会跳转到该方法的汇编代码处:

                     -[CalculatorController showAbout:]:
00000001000093dd         push       rbp                                         ; Objective C Implementation defined at 0x1000188d0 (instance)
00000001000093de         mov        rbp, rsp
00000001000093e1         mov        rdi, qword [ds:objc_cls_ref_NSDictionary]   ; objc_cls_ref_NSDictionary, argument "instance" for method imp___got__objc_msgSend
00000001000093e8         mov        rsi, qword [ds:0x10001b6f0]                 ; @selector(dictionaryWithObject:forKey:), argument 'selector' for method imp___got__objc_msgSend
00000001000093ef         lea        rdx, qword [ds:cfstring_2000]               ; @"2000"
00000001000093f6         lea        rcx, qword [ds:cfstring_CopyrightStartYear] ; @"CopyrightStartYear"
00000001000093fd         call       qword [ds:imp___got__objc_msgSend]
0000000100009403         mov        rdi, rax
0000000100009406         pop        rbp
0000000100009407         jmp        imp___stubs__NSShowSystemInfoPanel
                        ; endp

由汇编代码可知[CalculatorController showAbout:]方法在文件中的偏移地址为0x00000001000093dd

二、使用LLDB调试器设置断点

接下来运行终端,执行以下命令,让LLDB调试器依附计算器的进程:

Jobs: ~$ ps aux | grep Calculator
Jobs            79888   0.0  0.1  2781792  11620   ??  S     6:21下午   0:01.07 /Applications/Calculator.app/Contents/MacOS/Calculator
Jobs            80204   0.0  0.0  2432772    568 s002  R+    6:26下午   0:00.00 grep Calculator
Jobs: ~$ lldb -p 79888
(lldb) process attach --pid 79888
Process 79888 stopped
* thread #1: tid = 0x6030af, 0x00007fff912d34de libsystem_kernel.dylib`mach_msg_trap + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x00007fff912d34de libsystem_kernel.dylib`mach_msg_trap + 10
libsystem_kernel.dylib`mach_msg_trap:
->  0x7fff912d34de <+10>: retq
    0x7fff912d34df <+11>: nop

libsystem_kernel.dylib`mach_msg_overwrite_trap:
    0x7fff912d34e0 <+0>:  movq   %rcx, %r10
    0x7fff912d34e3 <+3>:  movl   $0x1000020, %eax

Executable module set to "/Applications/Calculator.app/Contents/MacOS/Calculator".
Architecture set to: x86_64h-apple-macosx.
(lldb) continue
Process 79888 resuming
(lldb)

接着执行以下命令获取应用的ASLR偏移地址:

(lldb) image list -o
[  0] 0x000000000cafa000
[  1] 0x00007fff93d51000
[  2] 0x000000010cb1e000
......
(lldb)

第一行数据的16进制地址0x000000000cafa000就是应用的ASLR偏移地址,之前我们已经找到了[CalculatorController showAbout:]方法的偏移地址是0x00000001000093dd,那么该方法在内存中的地址就是0x000000000cafa000 + 0x00000001000093dd

所以我们可以执行下面的命令来给这个方法设置断点,注意加号两边不要有空格:

(lldb) br set -a "0x000000000cafa000+0x00000001000093dd"
Breakpoint 1: where = Calculator`___lldb_unnamed_function161$$Calculator, address = 0x000000010cb033dd
(lldb)

这时点击菜单的“关于计算器”选项,程序就会断下来:

Process 79888 stopped
* thread #1: tid = 0x6709de, 0x000000010cb033dd Calculator`___lldb_unnamed_function161$$Calculator, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
    frame #0: 0x000000010cb033dd Calculator`___lldb_unnamed_function161$$Calculator
Calculator`___lldb_unnamed_function161$$Calculator:
->  0x10cb033dd <+0>:  pushq  %rbp
    0x10cb033de <+1>:  movq   %rsp, %rbp
    0x10cb033e1 <+4>:  movq   0x12b98(%rip), %rdi       ; (void *)0x00007fff78684488: NSDictionary
    0x10cb033e8 <+11>: movq   0x12301(%rip), %rsi       ; "dictionaryWithObject:forKey:"
(lldb)

三、编写Python脚本

那么问题来了,我们每次调试应用都要先手动获取ASLR偏移地址,如果要给多个地址打断点的话,就要写很多遍"ASLR偏移地址+方法偏移地址",操作比较繁琐。如果这些重复性的操作可以自动完成的话,在平时的使用过程中应该能节省不少时间。

用Python就可以很方便地实现这个功能,接下来我们就来写一个简单的脚本,以简化设置断点的操作。脚本的主要功能是自动获取应用的ASLR地址,用户设置断点时只需输入方法在文件中的的偏移地址,脚本会自动把ASLR偏移地址和方法偏移地址相加,再设置断点。

新建一个Python文件,保存至~/sbr.py,代码如下:

#!/usr/bin/python
#coding:utf-8

import lldb
import commands
import optparse
import shlex
import re


# 获取ASLR偏移地址
def get_ASLR():
    # 获取'image list -o'命令的返回结果
    interpreter = lldb.debugger.GetCommandInterpreter()
    returnObject = lldb.SBCommandReturnObject()
    interpreter.HandleCommand('image list -o', returnObject)
    output = returnObject.GetOutput();
    # 正则匹配出第一个0x开头的16进制地址
    match = re.match(r'.+(0x[0-9a-fA-F]+)', output)
    if match:
        return match.group(1)
    else:
        return None

# Super breakpoint
def sbr(debugger, command, result, internal_dict):

    #用户是否输入了地址参数
    if not command:
        print >>result, 'Please input the address!'
        return

    ASLR = get_ASLR()
    if ASLR:
        #如果找到了ASLR偏移,就设置断点
        debugger.HandleCommand('br set -a "%s+%s"' % (ASLR, command))
    else:
        print >>result, 'ASLR not found!'

# And the initialization code to add your commands 
def __lldb_init_module(debugger, internal_dict):
    # 'command script add sbr' : 给lldb增加一个'sbr'命令
    # '-f sbr.sbr' : 该命令调用了sbr文件的sbr函数
    debugger.HandleCommand('command script add sbr -f sbr.sbr')
    print 'The "sbr" python command has been installed and is ready for use.'

然后在LLDB中执行下面的语句就可以把脚本导入到LLDB:

(lldb) command script import ~/sbr.py
The "sbr" python command has been installed and is ready for use.
(lldb)

输出结果表示名为sbr的Python命令已经装载好并可以使用了。
sbrSuper breakpoint的意思,只需接收一个方法偏移地址作为参数。
接下来验证一下效果,先清除断点列表,再用sbr命令来设置断点。

(lldb) br delete
About to delete all breakpoints, do you want to do that?: [Y/n] y
All breakpoints removed. (1 breakpoint)
(lldb) sbr 0x00000001000093dd
Breakpoint 2: where = Calculator`___lldb_unnamed_function161$$Calculator, address = 0x000000010cb033dd
(lldb)

这时点击菜单的“关于计算器”选项,方法也成功断下来了。

四、启动LLDB时自动加载Python脚本

对于经常要使用到的脚本,可以在LLDB的初始化文件里添加命令加载脚本,这样LLDB启动后就能使用自定义的命令了。
修改~/.lldbinit文件,在文件里加入一行:

command script import ~/sbr.py

重新进入LLDB,可以看到脚本已经自动加载了:

Jobs: ~$ lldb
The "sbr" python command has been installed and is ready for use.
(lldb) command source -s 1 '/Users/Jobs/./.lldbinit'
The "sbr" python command has been installed and is ready for use.
(lldb)
11 个赞

很好的分享,但是帖中的sbr,只能自动输入第一个模块的ASLR吧?如果能默认识别断点地址所在的模块,然后自动把这个模块的ASLR加到断点的地址上去,那就牛了比了!

1 个赞

这真是一个不错的主意

1 个赞

cannot attach to process due to System Integrity Protection

With the release of OS X El Capitan, Apple has bundled with their operating system a new security feature named System Integrity Protection (also known as SIP and Rootless) and designed to block access to a number of system locations, as well as to restrict access to system processes as a measure against the core of OS X being tampered with.

不错,谢谢分享

10.11上Apple引入了SIP机制,即使有root权限,也无法attach系统进程或者修改系统文件,需要进恢复模式关闭SIP。
或者也可以使用rootfool来动态地开关SIP:

前提条件是需要一个开发者证书,因为需要签名一个kext,再在用户态中与该kext通信来实现开关。

1 个赞

恩。感谢。你在segmentfault和这里的回答。

:joy:我都没注意名字。。那个也是你啊

我把系统升级到10.11,遇到了这个问题,可以参考这篇帖子:
http://bbs.feng.com/read-htm-tid-9931290-page-1.html
使用csrutil enable --without debug来允许task_for_pid()调用

分分钟学会了python扩展LLDB,感谢分享。

error: module importing failed: /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/_collections.so: no appropriate 64-bit architecture (see “man python” for running in 32-bit mode)

出现这个怎么解决?

他怎么判断是系统应用的呢?自己安装到/Applications目录下应用是可以hook的,但是系统自带的应用就不行

在我的系统中,第一个不是应用的 ASLR 偏移地址,而是 dyld 的。第二个才是应用的 ASLR。
所以如果可以判断地址所在模块来获取 ASLR 的话,那就牛叉大了。

或者可以第一次使用时设定调试的模块的 ASLR,然后后面 下断点时自动加 ASLR,这样应该会更方便吧?

比如 set ASLR = 0x0000000114f9a000,后面用 brs 的都自动加这个。


自己动手稍微改了一下

改写和增加

def set_ASLR(debugger, command, result, internal_dict):
ASLR_cfg = open("./Code/Tools/.ASLR.cfg", “w”)
ASLR_cfg.write(command)
ASLR_cfg.close()
print >>result, 'ASLR has been set to ’ + command +"!"

def get_ASLR():
ASLR_cfg = open("./Code/Tools/.ASLR.cfg", “r”)
ASLR = ASLR_cfg.read();
ASLR_cfg.close()
return ASLR

在最下面加一行:

debugger.HandleCommand('command script add aslr -f sbr.set_ASLR')

这样就可以用 aslr 0x00000000037c0000 这样的命令设置一个 ASLR,然后后面就可以直接用 sbr 下断点了

今天刚测试的,发现完全不需要这么做。
br s --func-regex 函数关键字
上面这条命令在模块加载下执行,会提示没有找到对应的地址。不过没关系,只要任意一个模块加载进去,符合上面关键字的所有函数都会下断点,太TMD好用了。

2 个赞

看起来好厉害的样子,可是没看明白,求实例讲解。
按我的理解,要想从函数下断点,要么是 debug 版的程序,要么就是恢复符号表之后吧?

比如说你想对 a.dylib 里面的func001 下断点,可以在a.dylib加载之前就执行
br s --func-regex func001
(执行完之后会提示找不到位置,不过没关系继续继续其他命令就好了)
那么在a.dylib加载的时候lldb会自动在加载的时候下好断点(这个时候会提示在哪个位置下了断点)。不过没有试constructor能不能下好断点,其他方法都是可以的。

这得有符号表才行吧?晚上回去试试。

10.11中系统自带的应用hook不了,可以把计算器复制到桌面再运行,就可以hook了

这个方法不错,不过这篇文章主要是用来抛砖引玉的,希望大家能发挥自己的创意写一些比较实用的脚本,这也是文章标题这么命名的原因。

我试了一下,貌似只会在dylib上下断,不会在可执行文件上下断?下面是我在QQi中的试验(执行了br s --func-regex didSelectRow):

(lldb) br li
Current breakpoints:
1: regex = 'didSelectRow', locations = 124, resolved = 124, hit count = 0
  1.1: where = Social`-[SLFacebookAlbumChooserViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d3ec7a8, resolved, hit count = 0 
  1.2: where = Social`__74-[SLFacebookAlbumChooserViewController tableView:didSelectRowAtIndexPath:]_block_invoke, address = 0x000000018d3ecab8, resolved, hit count = 0 
  1.3: where = Social`-[SLFacebookVideoOptionsViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d3f2d80, resolved, hit count = 0 
  1.4: where = Social`__74-[SLFacebookVideoOptionsViewController tableView:didSelectRowAtIndexPath:]_block_invoke, address = 0x000000018d3f3010, resolved, hit count = 0 
  1.5: where = Social`-[SLSheetPlaceViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d3faa78, resolved, hit count = 0 
  1.6: where = Social`__64-[SLSheetPlaceViewController tableView:didSelectRowAtIndexPath:]_block_invoke, address = 0x000000018d3fae48, resolved, hit count = 0 
  1.7: where = Social`-[SLFacebookAudienceTableViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d3fd5f4, resolved, hit count = 0 
  1.8: where = Social`__75-[SLFacebookAudienceTableViewController tableView:didSelectRowAtIndexPath:]_block_invoke, address = 0x000000018d3fd8b0, resolved, hit count = 0 
  1.9: where = Social`-[SLSheetRootViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d42192c, resolved, hit count = 0 
  1.10: where = Social`-[SLMicroBlogAccountsTableViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d422978, resolved, hit count = 0 
  1.11: where = Social`__76-[SLMicroBlogAccountsTableViewController tableView:didSelectRowAtIndexPath:]_block_invoke, address = 0x000000018d422c34, resolved, hit count = 0 
  1.12: where = Social`-[SLFacebookLoginInfoViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d424b7c, resolved, hit count = 0 
  1.13: where = Social`-[SLMicroBlogMentionsViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d4482c0, resolved, hit count = 0 
  1.14: where = UIKit`-[_UIModalItemAlertContentView tableView:didSelectRowAtIndexPath:], address = 0x0000000187d0039c, resolved, hit count = 0 
  1.15: where = UIKit`-[UIMoreListController tableView:didSelectRowAtIndexPath:], address = 0x0000000187d2e59c, resolved, hit count = 0 
  1.16: where = UIKit`-[_UIModalItemContentView tableView:didSelectRowAtIndexPath:], address = 0x0000000187e3e7c0, resolved, hit count = 0 
  1.17: where = UIKit`-[UICompletionTable tableView:didSelectRowAtIndexPath:], address = 0x0000000187ed2858, resolved, hit count = 0 
  1.18: where = UIKit`-[UIWebSelectSinglePicker pickerView:didSelectRow:inComponent:], address = 0x000000018801fae0, resolved, hit count = 0 
  1.19: where = UIKit`-[UIWebSelectTableViewController tableView:didSelectRowAtIndexPath:], address = 0x00000001880212ac, resolved, hit count = 0 
  1.20: where = UIKit`-[UIKeyboardEmojiSplitCategoryPicker tableView:didSelectRowAtIndexPath:], address = 0x0000000188026040, resolved, hit count = 0 
  1.21: where = UIKit`-[UIPrinterUtilityTableViewController tableView:didSelectRowAtIndexPath:], address = 0x0000000188157dc4, resolved, hit count = 0 
  1.22: where = UIKit`-[_UIOpenInTableViewController tableView:didSelectRowAtIndexPath:], address = 0x00000001881704d8, resolved, hit count = 0 
  1.23: where = UIKit`-[UIPrinterBrowserViewController tableView:didSelectRowAtIndexPath:], address = 0x00000001881b9f60, resolved, hit count = 0 
  1.24: where = UIKit`__68-[UIPrinterBrowserViewController tableView:didSelectRowAtIndexPath:]_block_invoke, address = 0x00000001881ba2d0, resolved, hit count = 0 
  1.25: where = UIKit`-[UIPrintPanelTableViewController tableView:didSelectRowAtIndexPath:], address = 0x00000001881c27f4, resolved, hit count = 0 
  1.26: where = UIKit`-[UIRecentsInputViewController tableView:didSelectRowAtIndexPath:], address = 0x00000001881e5bb4, resolved, hit count = 0 
  1.27: where = UIKit`-[UIPrintRangeViewController tableView:didSelectRowAtIndexPath:], address = 0x00000001881ee6e4, resolved, hit count = 0 
  1.28: where = UIKit`-[UIPrintRangeViewController pickerView:didSelectRow:inComponent:], address = 0x00000001881eeaa0, resolved, hit count = 0 
  1.29: where = UIKit`-[UIPickerTableView tableView:didSelectRowAtIndexPath:], address = 0x00000001881ff718, resolved, hit count = 0 
  1.30: where = UIKit`-[_UIDocumentPickerOverviewViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018823ddf4, resolved, hit count = 0 
  1.31: where = UIKit`-[UIPrintPaperViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018823f8b8, resolved, hit count = 0 
  1.32: where = UIKit`-[UIDebuggingInformationRootTableViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018824aabc, resolved, hit count = 0 
  1.33: where = UIKit`-[UIKeyboardMenuView tableView:didSelectRowAtIndexPath:], address = 0x00000001882a9390, resolved, hit count = 0 
  1.34: where = UIKit`-[_UIDatePickerView pickerView:didSelectRow:inComponent:], address = 0x000000018833910c, resolved, hit count = 0 
  1.35: where = UIKit`-[_UIDocumentPickerDocumentTableViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018833d678, resolved, hit count = 0 
  1.36: where = MapKit`-[MKTransitReroutingViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018cfd9750, resolved, hit count = 0 
  1.37: where = MapKit`-[MKSharedAttributionViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018cfda688, resolved, hit count = 0 
  1.38: where = MapKit`-[MKTransitDeparturesViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018cff6810, resolved, hit count = 0 
  1.39: where = MapKit`-[MKPlaceInfoViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018cffe0a8, resolved, hit count = 0 
  1.40: where = MapKit`-[MKPlacePhotosViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d00b6a4, resolved, hit count = 0 
  1.41: where = MapKit`-[MKPlaceActionsViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d037ae8, resolved, hit count = 0 
  1.42: where = MapKit`-[MKPlaceReviewsViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d05d95c, resolved, hit count = 0 
  1.43: where = AddressBookUI`-[ABMembersDataSource tableView:didSelectRowAtIndexPath:], address = 0x000000018b2b7f5c, resolved, hit count = 0 
  1.44: where = AddressBookUI`-[ABAccountsAndGroupDataSource tableView:didSelectRowAtIndexPath:], address = 0x000000018b2c0d98, resolved, hit count = 0 
  1.45: where = AddressBookUI`-[ABAccountsAndGroupsViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018b2c1b38, resolved, hit count = 0 
  1.46: where = AddressBookUI`-[ABCardPropertyPicker tableView:didSelectRowAtIndexPath:], address = 0x000000018b2c4a1c, resolved, hit count = 0 
  1.47: where = AddressBookUI`-[ABCountryPickerViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018b2c9bec, resolved, hit count = 0 
  1.48: where = AddressBookUI`-[ABItemLabelPicker tableView:didSelectRowAtIndexPath:], address = 0x000000018b2d8fd4, resolved, hit count = 0 
  1.49: where = AddressBookUI`-[ABMembersFilteredDataSource tableView:didSelectRowAtIndexPath:], address = 0x000000018b2dddcc, resolved, hit count = 0 
  1.50: where = AddressBookUI`-[ABMultipleImagePickerViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018b2ecaf0, resolved, hit count = 0 
  1.51: where = AddressBookUI`-[ABPersonTableViewDataSource tableView:didSelectRowAtIndexPath:], address = 0x000000018b31c6e4, resolved, hit count = 0 
  1.52: where = AddressBookUI`-[ABServicePickerViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018b342f64, resolved, hit count = 0 
  1.53: where = AddressBookUI`-[ABUnknownPersonViewController_Modern tableView:didSelectRowAtIndexPath:], address = 0x000000018b349224, resolved, hit count = 0 
  1.54: where = AddressBookUI`__74-[ABUnknownPersonViewController_Modern tableView:didSelectRowAtIndexPath:]_block_invoke, address = 0x000000018b349510, resolved, hit count = 0 
  1.55: where = AddressBookUI`__74-[ABUnknownPersonViewController_Modern tableView:didSelectRowAtIndexPath:]_block_invoke193, address = 0x000000018b34953c, resolved, hit count = 0 
  1.56: where = AddressBookUI`-[ABUnknownPersonViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018b34debc, resolved, hit count = 0 
  1.57: where = AddressBookUI`-[ABUnknownPersonViewDelegateForwarder tableView:didSelectRowAtIndexPath:], address = 0x000000018b34e218, resolved, hit count = 0 
  1.58: where = MessageUI`-[_MFQuoteLevelPopoverViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d2e8e84, resolved, hit count = 0 
  1.59: where = MessageUI`-[MFMailComposeController pickerView:didSelectRow:inComponent:], address = 0x000000018d2fef14, resolved, hit count = 0 
  1.60: where = MessageUI`-[MFMailComposeController tableView:didSelectRowAtIndexPath:], address = 0x000000018d2ff310, resolved, hit count = 0 
  1.61: where = MessageUI`-[MFGroupDetailViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d30c5b8, resolved, hit count = 0 
  1.62: where = MessageUI`-[MFAutocompleteResultsTableViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d31a178, resolved, hit count = 0 
  1.63: where = MessageUI`-[MFMailComposeCorecipientViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018d352460, resolved, hit count = 0 
  1.64: where = MediaPlayer`-[MPAlternateTracksViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018b86571c, resolved, hit count = 0 
  1.65: where = MediaPlayer`-[MPAudioRoutingPicker tableView:didSelectRowAtIndexPath:], address = 0x000000018b8dfac8, resolved, hit count = 0 
  1.66: where = MediaPlayer`__58-[MPAudioRoutingPicker tableView:didSelectRowAtIndexPath:]_block_invoke, address = 0x000000018b8dfd94, resolved, hit count = 0 
  1.67: where = MediaPlayer`__58-[MPAudioRoutingPicker tableView:didSelectRowAtIndexPath:]_block_invoke120, address = 0x000000018b8dfdb8, resolved, hit count = 0 
  1.68: where = MediaPlayer`-[MPAVRoutingViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018b8ea4dc, resolved, hit count = 0 
  1.69: where = MediaPlayer`__63-[MPAVRoutingViewController tableView:didSelectRowAtIndexPath:]_block_invoke, address = 0x000000018b8ea980, resolved, hit count = 0 
  1.70: where = MediaPlayer`-[_MPAudioAndSubtitlesController tableView:didSelectRowAtIndexPath:], address = 0x000000018b961494, resolved, hit count = 0 
  1.71: where = MediaPlayer`-[MPAudioVideoRoutingTableViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018b9635ec, resolved, hit count = 0 
  1.72: where = MediaPlayer`__76-[MPAudioVideoRoutingTableViewController tableView:didSelectRowAtIndexPath:]_block_invoke, address = 0x000000018b963ff8, resolved, hit count = 0 
  1.73: where = MediaPlayer`__76-[MPAudioVideoRoutingTableViewController tableView:didSelectRowAtIndexPath:]_block_invoke249, address = 0x000000018b964110, resolved, hit count = 0 
  1.74: where = WebKit`-[WKSelectSinglePicker pickerView:didSelectRow:inComponent:], address = 0x000000018a92e250, resolved, hit count = 0 
  1.75: where = WebKit`-[WKSelectTableViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018a92ef24, resolved, hit count = 0 
  1.76: where = AccountsUI`-[ACUIIdentityPickerViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018c33dbf4, resolved, hit count = 0 
  1.77: where = CertInfo`-[CertificateViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018c269eac, resolved, hit count = 0 
  1.78: where = CertInfo`-[CertInfoCertificateSummaryView tableView:didSelectRowAtIndexPath:], address = 0x000000018c27098c, resolved, hit count = 0 
  1.79: where = CertInfo`-[CertInfoCertificateDetailsController tableView:didSelectRowAtIndexPath:], address = 0x000000018c274e68, resolved, hit count = 0 
  1.80: where = CertInfo`-[CertInfoTrustSummaryController tableView:didSelectRowAtIndexPath:], address = 0x000000018c278618, resolved, hit count = 0 
  1.81: where = CertInfo`-[CertInfoCertificateListController tableView:didSelectRowAtIndexPath:], address = 0x000000018c27abe0, resolved, hit count = 0 
  1.82: where = Preferences`-[PSListController tableView:didSelectRowAtIndexPath:], address = 0x000000018a4c7a10, resolved, hit count = 0 
  1.83: where = Preferences`-[PSListItemsController tableView:didSelectRowAtIndexPath:], address = 0x000000018a4daff4, resolved, hit count = 0 
  1.84: where = Preferences`-[PSAppListController tableView:didSelectRowAtIndexPath:], address = 0x000000018a52145c, resolved, hit count = 0 
  1.85: where = Preferences`-[PSInternationalLanguageController tableView:didSelectRowAtIndexPath:], address = 0x000000018a526534, resolved, hit count = 0 
  1.86: where = Preferences`-[PSLocaleController tableView:didSelectRowAtIndexPath:], address = 0x000000018a52cb88, resolved, hit count = 0 
  1.87: where = Preferences`-[KeychainSyncAdvancedSecurityCodeController tableView:didSelectRowAtIndexPath:], address = 0x000000018a538210, resolved, hit count = 0 
  1.88: where = Preferences`-[PSPowerlogListController tableView:didSelectRowAtIndexPath:], address = 0x000000018a538ab8, resolved, hit count = 0 
  1.89: where = Preferences`-[ProblemReportingController tableView:didSelectRowAtIndexPath:], address = 0x000000018a53ce20, resolved, hit count = 0 
  1.90: where = Preferences`-[PSSearchResultsController tableView:didSelectRowAtIndexPath:], address = 0x000000018a54ce4c, resolved, hit count = 0 
  1.91: where = CoreBluetooth`-[BTDevicePicker tableView:didSelectRowAtIndexPath:], address = 0x00000001886f3664, resolved, hit count = 0 
  1.92: where = ContactsUI`-[CNContactGroupPickerViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018aa2efdc, resolved, hit count = 0 
  1.93: where = ContactsUI`-[CNContactContentViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018aa4802c, resolved, hit count = 0 
  1.94: where = ContactsUI`-[CNCountryPickerController tableView:didSelectRowAtIndexPath:], address = 0x000000018aa5bcd0, resolved, hit count = 0 
  1.95: where = ContactsUI`-[CNAccountsAndGroupsViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018aa5d834, resolved, hit count = 0 
  1.96: where = ContactsUI`-[CNPickerController tableView:didSelectRowAtIndexPath:], address = 0x000000018aa79384, resolved, hit count = 0 
  1.97: where = ContactsUI`-[CNContactListViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018aa81538, resolved, hit count = 0 
  1.98: where = ContactsUI`-[CNContactSuggestionViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018aa8fd1c, resolved, hit count = 0 
  1.99: where = QuickLook`-[QLArchiveViewer tableView:didSelectRowAtIndexPath:], address = 0x000000018d203358, resolved, hit count = 0 
  1.100: where = SafariServices`-[_SFBookmarkInfoViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018ed8654c, resolved, hit count = 0 
  1.101: where = SafariServices`-[SFReaderAppearanceMainViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018ed8b4fc, resolved, hit count = 0 
  1.102: where = EventKitUI`-[EKRecurrenceTypeEditItemViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018db110a0, resolved, hit count = 0 
  1.103: where = EventKitUI`__76-[EKRecurrenceTypeEditItemViewController tableView:didSelectRowAtIndexPath:]_block_invoke, address = 0x000000018db11584, resolved, hit count = 0 
  1.104: where = EventKitUI`-[EKRecurrenceEndEditItemViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018db219fc, resolved, hit count = 0 
  1.105: where = EventKitUI`-[EKUIEventInviteesViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018db2be60, resolved, hit count = 0 
  1.106: where = EventKitUI`-[EKICSPreviewListController tableView:didSelectRowAtIndexPath:], address = 0x000000018db41260, resolved, hit count = 0 
  1.107: where = EventKitUI`-[EKEventAttachmentEditViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018db4a4bc, resolved, hit count = 0 
  1.108: where = EventKitUI`-[EKCalendarEditor tableView:didSelectRowAtIndexPath:], address = 0x000000018db65a9c, resolved, hit count = 0 
  1.109: where = EventKitUI`-[EKLocationEditItemViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018db7eee0, resolved, hit count = 0 
  1.110: where = EventKitUI`-[EKRecurrenceOrdinalPickerViewController pickerView:didSelectRow:inComponent:], address = 0x000000018db92ef0, resolved, hit count = 0 
  1.111: where = EventKitUI`-[EKShareeViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018db9ac98, resolved, hit count = 0 
  1.112: where = EventKitUI`-[EKEventTravelTimeEditViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018dbae650, resolved, hit count = 0 
  1.113: where = EventKitUI`-[CalendarEventAlarmTable tableView:didSelectRowAtIndexPath:], address = 0x000000018dbb3c64, resolved, hit count = 0 
  1.114: where = EventKitUI`-[EKTimeZoneViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018dbc8f08, resolved, hit count = 0 
  1.115: where = EventKitUI`-[EKCalendarItemEditor tableView:didSelectRowAtIndexPath:], address = 0x000000018dbeb34c, resolved, hit count = 0 
  1.116: where = EventKitUI`-[EKEventAvailabilityEditViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018dbeeed0, resolved, hit count = 0 
  1.117: where = EventKitUI`-[EKUICustomRecurrenceIntervalViewController pickerView:didSelectRow:inComponent:], address = 0x000000018dbefb1c, resolved, hit count = 0 
  1.118: where = EventKitUI`-[EKEventViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018dbf9630, resolved, hit count = 0 
  1.119: where = EventKitUI`-[EKCalendarChooser tableView:didSelectRowAtIndexPath:], address = 0x000000018dc0e37c, resolved, hit count = 0 
  1.120: where = EventKitUI`-[EKUICustomRecurrenceViewController tableView:didSelectRowAtIndexPath:], address = 0x000000018dc1e848, resolved, hit count = 0 
  1.121: where = EventKitUI`-[EKUICustomRecurrenceViewController pickerView:didSelectRow:inComponent:], address = 0x000000018dc1eaf0, resolved, hit count = 0 
  1.122: where = WebUI`-[WBUSheetController tableView:didSelectRowAtIndexPath:], address = 0x000000018e8c460c, resolved, hit count = 0 
  1.123: where = WebUI`__56-[WBUSheetController tableView:didSelectRowAtIndexPath:]_block_invoke, address = 0x000000018e8c4738, resolved, hit count = 0 
  1.124: where = WebUI`-[_WBUPasswordPicker tableView:didSelectRowAtIndexPath:], address = 0x000000018e8d3d9c, resolved, hit count = 0 

(lldb)