LLDB 还只用到po么, 立刻跟我来篡改Xcode吧! (上篇)


 NSString* s = [SomeObj someMethod];

怎么样看s的值呢,ok,大家一定知道的一种console中输入 po s,有些时候还会用p s,还有时候用print s也可以查看结果。
po,p,print都是LLDB的command,但是区别是什么呢,他们各自代表什么含义呢。
如果有疑问,最好的方式就是LLDB help。 
(lldb) help
...

  p         -- ('expression --')  Evaluate an expression (ObjC++ or Swift) in
               the current program context, using user defined variables and
               variables currently in scope.
  po        -- ('expression -O  -- ')  Evaluate an expression (ObjC++ or Swift)
               in the current program context, using user defined variables and
               variables currently in scope.
  print     -- ('expression --')  Evaluate an expression (ObjC++ or Swift) in
               the current program context, using user defined variables and
               variables currently in scope.

...
实际上p,po,print都是expression command的别名,3个命名所表示都是同样的事情,po这里没有体现区别,接着求助help expression 
(lldb) help expression
...

-O ( --object-description )
            Display using a language-specific description API, if possible.
...
很清楚了,加上 -O 会打印object的description。
在稍加了解打印的命令后,我们尝试做点别的。 
 NSString* s = @“dashi"

(lldb) p s
(__NSCFConstantString *) $1 = 0x000000010fddb300 @"dashi"
(lldb)e s = @“da shi bu shi ren"
(__NSCFString *) $2 = 0x0000608001446570 @"da shi bu shi ren"
(lldb) p s
(__NSCFString *) $3 = 0x0000608001446570 @"da shi bu shi ren"
e 改变了s的值。e不是edit的缩写,是上面expression的缩写,你也可以用expr s,都是一种简写方式,lldb可以聪明的识别。s在被下文使用的时候就会使用新的值,这种可以应用在运行时修改代码流程走向。
12 $3 都可以代表相应的对象,你也可以
(lldb) p $3
(__NSCFString *) $3 = 0x0000608001446570 @"da shi bu shi ren”.
你也可以重新设置变量
(lldb) e NSString* $mm = $3
(lldb)  p $mm
(__NSCFString *) $mm = 0x0000608001446570 @"da shi bu shi ren”

写到这里,我就不想再铺教程了,为了展示lldb的强大功能,我们去做些好玩的,进入今天的主题篡改Xcode。

lldb会在整个过程中扮演探险家的角色。
 
这就是我们熟悉的Xcode,看了一眼,随便找个地方吧,那就修改下图这里吧。


其实这就是xcode 插件开发,先要做的事情 —— 让lldb去探险

首先你要有个插件模型。
建立好模型后, 因为我们全程都是用lldb,所以不需要编写任何额外代码,将插件模型代码整理后如下:

注意我多加了个断点,这个断点会在另外一个xcode实例起来的时候断住。如果你不理解另外一个xcode实例起来可以先把断点去掉,run一下。
build and run, 断点断住,ok,lldb中可以输入了。 
Xcode 官方图解上,这个地方被命名为Debug bar
 
使用image lookup 去做第一次侦查。
(lldb) image lookup -rn DebugBar
140 matches found in /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/IDEKit:
        Address: IDEKit[0x00000000000444d2] (IDEKit.__TEXT.__text + 272834)
        Summary: IDEKit`-[IDEDebugBar loadView]        Address: IDEKit[0x000000000004483b] (IDEKit.__TEXT.__text + 273707)
        Summary: IDEKit`-[IDEDebugBar tile]        Address: IDEKit[0x000000000004559d] (IDEKit.__TEXT.__text + 277133)
        Summary: IDEKit`+[IDEDebugBar standardDebugBarButtonWithImage:alternateImage:toolTip:accessibilityDescription:]        Address: IDEKit[0x000000000004571a] (IDEKit.__TEXT.__text + 277514)
        Summary: IDEKit`+[IDEDebugBar standardDebugBarButtonSize]        Address: IDEKit[0x000000000004577b] (IDEKit.__TEXT.__text + 277611)
        Summary: IDEKit`-[IDEDebugBar editorInfoProvider]        Address: IDEKit[0x0000000000045791] (IDEKit.__TEXT.__text + 277633)
        Summary: IDEKit`-[IDEDebugBar setEditorInfoProvider:]        Address: IDEKit[0x000000000004c24c] (IDEKit.__TEXT.__text + 304956)
        Summary: IDEKit`-[IDEDebugBar viewDidInstall]        Address: IDEKit[0x000000000004c512] (IDEKit.__TEXT.__text + 305666)
        Summary: IDEKit`-[IDEStackFrameDebugBarContentProvider init]        Address: IDEKit[0x000000000004c70f] (IDEKit.__TEXT.__text + 306175)
        Summary: IDEKit`+[IDEStackFrameDebugBarContentProvider keyPathsForValuesAffectingNavigableDebugItems]        Address: IDEKit[0x000000000004c733] (IDEKit.__TEXT.__text + 306211)
        Summary: IDEKit`-[IDEStackFrameDebugBarContentProvider
………
image lookup 会帮助我们查找内存当中对象所调用的方法。
看到了一个IDEDebugBar,这个或许就是我们在寻找DebugBar的类。
再进一步
(lldb) image lookup -rn IDEDebugBar
52 matches found in /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/IDEKit:
        Address: IDEKit[0x00000000000444d2] (IDEKit.__TEXT.__text + 272834)
        Summary: IDEKit`-[IDEDebugBar loadView]        Address: IDEKit[0x000000000004483b] (IDEKit.__TEXT.__text + 273707)
        Summary: IDEKit`-[IDEDebugBar tile]        Address: IDEKit[0x000000000004559d] (IDEKit.__TEXT.__text + 277133)
        Summary: IDEKit`+[IDEDebugBar standardDebugBarButtonWithImage:alternateImage:toolTip:accessibilityDescription:]        Address: IDEKit[0x000000000004571a] (IDEKit.__TEXT.__text + 277514)
        Summary: IDEKit`+[IDEDebugBar standardDebugBarButtonSize]        Address: IDEKit[0x000000000004577b] (IDEKit.__TEXT.__text + 277611)
        Summary: IDEKit`-[IDEDebugBar editorInfoProvider]        Address: IDEKit[0x0000000000045791] (IDEKit.__TEXT.__text + 277633)
        Summary: IDEKit`-[IDEDebugBar setEditorInfoProvider:]        Address: IDEKit[0x000000000004c24c] (IDEKit.__TEXT.__text + 304956)
        Summary: IDEKit`-[IDEDebugBar viewDidInstall]        Address: IDEKit[0x000000000004c74c] (IDEKit.__TEXT.__text + 306236)
        Summary: IDEKit`-[IDEDebugBar setContentProviders:]        Address: IDEKit[0x000000000004d1b5] (IDEKit.__TEXT.__text + 308901)
        Summary: IDEKit`-[IDEDebugBarContentProvider wasAttachedToDebugBar:]        Address: IDEKit[0x000000000004d467] (IDEKit.__TEXT.__text + 309591)       Summary: IDEKit`-[IDEDebugBarContentProvider setDebugBar:]        Address: IDEKit[0x000000000004d478] (IDEKit.__TEXT.__text + 309608)
        Summary: IDEKit`-[IDEDebugBarContentProvider debugBar]        Address: IDEKit[0x000000000004d48e] (IDEKit.__TEXT.__text + 309630)
        Summary: IDEKit`-[IDEDebugBarContentProvider currentDebugSession]        Address: IDEKit[0x000000000004d4de] (IDEKit.__TEXT.__text + 309710)
        Summary: IDEKit`-[IDEDebugBarContentProvider currentLaunchSession]        Address: IDEKit[0x000000000004d576] (IDEKit.__TEXT.__text + 309862)
        Summary: IDEKit`-[IDEDebugBar hideStandardControls]        Address: IDEKit[0x000000000004d589] (IDEKit.__TEXT.__text + 309881)
        Summary: IDEKit`-[IDEDebugBarContentProvider setDebugBarControlViews:]        Address: IDEKit[0x000000000004d79c] (IDEKit.__TEXT.__text + 310412)
        Summary: IDEKit`-[IDEDebugBarContentProvider debugBarControlViews]        Address: IDEKit[0x000000000004d7b2] (IDEKit.__TEXT.__text + 310434)
        Summary: IDEKit`-[IDEDebugBarContentProvider currentDebugSessionDidChange]        Address: IDEKit[0x000000000004de96] (IDEKit.__TEXT.__text + 312198)
        Summary: IDEKit`-[IDEDebugBar setSelectedModelObject:]        Address: IDEKit[0x000000000004e0c1] (IDEKit.__TEXT.__text + 312753)
        Summary: IDEKit`-[IDEDebugBar selectedModelObject]        Address: IDEKit[0x000000000004e354] (IDEKit.__TEXT.__text + 313412)
        Summary: IDEKit`-[IDEDebugBarContentProvider currentDebugSessionStateDidChange]        Address: IDEKit[0x000000000004e35a] (IDEKit.__TEXT.__text + 313418)
        Summary: IDEKit`-[IDEDebugBar _doToolTipWorkaround]        Address: IDEKit[0x0000000000098c46] (IDEKit.__TEXT.__text + 618806)
        Summary: IDEKit`-[IDEDebugBarContentProvider workspaceDidFinishLoading]        Address: IDEKit[0x00000000000d9bb9] (IDEKit.__TEXT.__text + 884905)
        Summary: IDEKit`-[IDEDebugBar viewWillUninstall]        Address: IDEKit[0x00000000000d9c9c] (IDEKit.__TEXT.__text + 885132)
        Summary: IDEKit`-[IDEDebugBarContentProvider willBeDetachedFromDebugBar:]        Address: IDEKit[0x0000000000112dfc] (IDEKit.__TEXT.__text + 1118956)
        Summary: IDEKit`-[IDEDebugBar additionalGrabRectInTermsOfView:]        Address: IDEKit[0x000000000019fee5] (IDEKit.__TEXT.__text + 1696725)
        Summary: IDEKit`__23-[IDEDebugBar loadView]_block_invoke        Address: IDEKit[0x000000000019ff19] (IDEKit.__TEXT.__text + 1696777)
        Summary: IDEKit`-[IDEDebugBar _createShowHideDebugAreaButton]        Address: IDEKit[0x00000000001a0017] (IDEKit.__TEXT.__text + 1697031)
        Summary: IDEKit`-[IDEDebugBar installContentProvidersForDefaultCategory]        Address: IDEKit[0x00000000001a0034] (IDEKit.__TEXT.__text + 1697060)
        Summary: IDEKit`-[IDEDebugBar installContentProvidersForCategory:]        Address: IDEKit[0x00000000001a014e] (IDEKit.__TEXT.__text + 1697342)
        Summary: IDEKit`-[IDEDebugBar installContentProvidersForNewDefaultCategory:]        Address: IDEKit[0x00000000001a01ae] (IDEKit.__TEXT.__text + 1697438)
        Summary: IDEKit`__35-[IDEDebugBar setContentProviders:]_block_invoke        Address: IDEKit[0x00000000001a054b] (IDEKit.__TEXT.__text + 1698363)
        Summary: IDEKit`__35-[IDEDebugBar setContentProviders:]_block_invoke151        Address: IDEKit[0x00000000001a05b2] (IDEKit.__TEXT.__text + 1698466)
        Summary: IDEKit`-[IDEDebugBar _prefersDebugBarToBeShownDidChangeForCotentProvider:]        Address: IDEKit[0x00000000001a0681] (IDEKit.__TEXT.__text + 1698673)
        Summary: IDEKit`-[IDEDebugBar _updatePrefersToAlwaysBeShown]        Address: IDEKit[0x00000000001a0704] (IDEKit.__TEXT.__text + 1698804)
        Summary: IDEKit`-[IDEDebugBar _updateShowDebugAreaButtonToolTipAndAccessibilityLabel]        Address: IDEKit[0x00000000001a088d] (IDEKit.__TEXT.__text + 1699197)
        Summary: IDEKit`__29-[IDEDebugBar viewDidInstall]_block_invoke        Address: IDEKit[0x00000000001a08c1] (IDEKit.__TEXT.__text + 1699249)
        Summary: IDEKit`-[IDEDebugBar _contentProvidersForCategory:]        Address: IDEKit[0x00000000001a0b8a] (IDEKit.__TEXT.__text + 1699962)
        Summary: IDEKit`__44-[IDEDebugBar _contentProvidersForCategory:]_block_invoke        Address: IDEKit[0x00000000001a0cc4] (IDEKit.__TEXT.__text + 1700276)
        Summary: IDEKit`-[IDEDebugBar _sharedLibrariesPopUpXOffset]        Address: IDEKit[0x00000000001a0ce7] (IDEKit.__TEXT.__text + 1700311)
        Summary: IDEKit`-[IDEDebugBar showSharedLibrariesPopUp]        Address: IDEKit[0x00000000001a0eee] (IDEKit.__TEXT.__text + 1700830)
        Summary: IDEKit`-[IDEDebugBar primitiveInvalidate]        Address: IDEKit[0x00000000001a0fbb] (IDEKit.__TEXT.__text + 1701035)
        Summary: IDEKit`-[IDEDebugBar setHideStandardControls:]        Address:
...
      
      
好多方法,感觉可以做很多手脚。找个简单的先试试,-[IDEDebugBar _createShowHideDebugAreaButton]。
看名字,我猜测可能就是这个按钮嗯,去尝试改一下。
为了解除疑虑,看看这个方法系统有没有调用过。
(lldb) breakpoint set -F "-[IDEDebugBar _createShowHideDebugAreaButton]"
Breakpoint 3: where = IDEKit`-[IDEDebugBar _createShowHideDebugAreaButton], address = 0x0000000101611f19
(lldb)c



网易云新用户大礼包:https://www.163yun.com/gift

本文来自网易实践者社区,经作者范飞授权发布。