一些用于调试iOS应用的lldb命令。Some very useful lldb commands for iOS debugging and reverse engineering.
Breakpoint:
* baf - break all functions in module
* bdc - breakpoint disable current
* bda - breakpoint disable at class
* bdr - breakpoint disable in range
* bblocks - break blocks (arm64 only)
* binitfunc - break init func
* bmain - break main function
Search:
* fblock - find block (arm64 only)
* blocks - find blocks (arm64 only)
Trace:
* rtrace
* notifier
Patch:
* patch (private)
Dump:
* dmodule - dump module (private)
Shell command
* addcmd
* delcmd
* pwd
* cd
* ls
File:
* commads to get common directory
* ils
* ufile - upload local file to device
Module:
* image_list
* info_plist
* executable - print main executable name
* appdelegate
* main
* initfunc - print init func
* func_starts - function starts
* lazy_sym - print __la_symbol_ptr section
* entitlements - dump entitlements
Objc
* classes - print class names
* dmethods
* divars
* duplicate_class
Assembly:
* inst2bytes
* bytes2inst
Memory:
* read_mem_as_addr
* read_cstring - read memory as c style string
Symbolize
* load_dSYM
* symbolize
DebugKit
* vmmap
Others:
* find_el - find endless loop
* thread_eb - extended backtrace of thread
- Clone this repo
- Open up (or create) ~/.lldbinit
- Add the following command to your ~/.lldbinit file:
command script import /path/to/YJLLDB/src/yjlldb.py
Set breakpoints at the specified bytes in user modules.
// for example, break at ret
(lldb) bab c0 03 5f d6
Breakpoint 1: where = LLDBCode`-[ViewController viewDidLoad] + 240 at ViewController.m:29:1, address = 0x1029b3008
...
set 728 breakpoints
(lldb) x 0x1029b3008
0x1029b3008: c0 03 5f d6 ff 03 03 d1 fd 7b 0b a9 fd c3 02 91 .._......{......
0x1029b3018: e8 03 01 aa e1 03 02 aa e3 0f 00 f9 a0 83 1f f8 ................
(lldb) dis -s 0x1029b3008 -c 1
LLDBCode`-[ViewController viewDidLoad]:
0x1029b3008 <+240>: ret
Break all functions and methods in the specified module.
For example,break Foundation:
(lldb) baf Foundation
-----break functions in Foundation-----
will set breakpoint for 13880 names
Breakpoint 4: 13961 locations
Disable current breakpoint and continue.
(lldb) thread info
thread #1: tid = 0x2cb739, 0x000000018354f950 libsystem_kernel.dylib`open, queue = 'com.apple.main-thread', stop reason = breakpoint 5.13
(lldb) bdc
disable breakpoint 5.13 [0x18354f950]libsystem_kernel.dylib`open
and continue
Disable breakpoint(s) at the specified class.
(lldb) bda -i ViewController
disable breakpoint 1.8: where = LLDBCode`__41-[ViewController touchesBegan:withEvent:]_block_invoke_4 at ViewController.m:57, address = 0x00000001040e32f8, unresolved, hit count = 1 Options: disabled
...
disable breakpoint 1.27: where = LLDBCode`__41-[ViewController touchesBegan:withEvent:]_block_invoke at ViewController.m:45, address = 0x00000001040e318c, unresolved, hit count = 1 Options: disabled
(lldb) bda -i ViewController(extension)
disable breakpoint 1.23: where = LLDBCode`-[ViewController(extension) test] at ViewController.m:20, address = 0x0000000102ec2e7c, unresolved, hit count = 0 Options: disabled
Disable breakpoint(s) in the specified range.
(lldb) bdr 980~992
disable breakpoint 980.1: where = LLDBCode`-[Test .cxx_destruct] at Test.m:22, address = 0x00000001049fa1b0, unresolved, hit count = 0 Options: disabled
...
disable breakpoint 991.1: where = LLDBCode`func1 at Test.m:42, address = 0x00000001049faaf8, unresolved, hit count = 0 Options: disabled
Break all blocks in user modules
(lldb) bblocks
-----try to lookup block in JITDemo-----
break block: 0x104a78150 with Breakpoint 4: JITDemo`globalBlock_block_invoke at ViewController.m:16:0, address = 0x104a74990
...
break stack block with Breakpoint 9: JITDemo`__41-[ViewController touchesBegan:withEvent:]_block_invoke_4 at ViewController.m:75:0, address = 0x104a74f08
...
-----try to lookup block in LLDBJIT-----
break block: 0x104b341c0 with Breakpoint 82: LLDBJIT`__22+[MachoTool findMacho]_block_invoke at MachoTool.m:110:0, address = 0x104b2b130
...
find a stack block @0x104b32080 in LLDBJIT`+[Image getBlocksInfo:] at Image.m:0:0
break stack block with Breakpoint 88: LLDBJIT`None, address = 0x104b34d40
set 85 breakpoints
(lldb)
or
(lldb) bblocks JITDemo
-----try to lookup block in JITDemo-----
break block: 0x1026ac140 with Breakpoint 87: JITDemo`___lldb_unnamed_symbol75, address = 0x1026a92f4
...
find a stack block @0x1026a9694 in JITDemo`___lldb_unnamed_symbol82
break stack block with Breakpoint 93: JITDemo`___lldb_unnamed_symbol83, address = 0x1026a9700
set 7 breakpoints
Break module init function(s) of specified module.
(lldb) binitfunc
-----try to lookup init function in JITDemo-----
mod init func pointers found: __DATA,__mod_init_func
Breakpoint 6: JITDemo`entry1 at main.m:708:0, address = 0x100e08cb0
Breakpoint 7: JITDemo`entry2 at main.m:740:0, address = 0x100e0960c
Break the specified method(s) in user modules
(lldb) bmethod load
-----try to method in JITDemo-----
Breakpoint 3: JITDemo`+[ViewController load] at ViewController.m:26:0, address = 0x1024f89bc
Breakpoint 4: JITDemo`+[AppDelegate load] at AppDelegate.m:16:0, address = 0x1024f96a4
-----try to method in LLDBJIT-----
set 2 breakpoints
(lldb) bmain
Breakpoint 9: BasicSyntax`___lldb_unnamed_symbol266, address = 0x10017c3fc
Lookup the specified string, between start addr and end addr.
(lldb) image_list -c 8
index load addr(slide) vmsize path
--------------------------------------------------------
[ 0] 0x1022e4000(0x0022e4000) 81.9K /var/containers/Bundle/Application/C134E909-CC52-4A93-9557-37BA808854D3/LLDBCode.app/LLDBCode
...
[ 6] 0x18406f000(0x004044000) 8.7K /usr/lib/libSystem.B.dylib
[ 7] 0x184071000(0x004044000) 394.1K /usr/lib/libc++.1.dylib
(lldb) slookup PROGRAM 0x18406f000 0x184071000
found at 0x184070f7c where = [0x000000018002cf78-0x000000018002cfb8) libSystem.B.dylib.__TEXT.__const
1 locations found
(lldb) x 0x184070f7c -c 64
0x184070f7c: 50 52 4f 47 52 41 4d 3a 53 79 73 74 65 6d 2e 42 PROGRAM:System.B
0x184070f8c: 20 20 50 52 4f 4a 45 43 54 3a 4c 69 62 73 79 73 PROJECT:Libsys
0x184070f9c: 74 65 6d 2d 31 32 35 32 2e 35 30 2e 34 0a 00 00 tem-1252.50.4...
0x184070fac: 00 00 00 00 00 00 00 00 00 92 93 40 01 00 00 00 ...........@....
Lookup the specified bytes in user modules.
(lldb) blookup c0 03 5f d6
-----try to lookup bytes in LLDBCode-----
0x104961018
...
0x104969ab8
32 locations found
Find the specified block(s) in user modules.
(lldb) po $x0
<__NSGlobalBlock__: 0x100f18210>
(lldb) x/4g 0x100f18210
0x100f18210: 0x00000001b57df288 0x0000000050000000
0x100f18220: 0x00000001043b9724 0x00000001043bc1f0
(lldb) info 0x00000001043b9724
0x00000001043b9724, ___lldb_unnamed_symbol77 <+0> `JITDemo`__TEXT.__text + 0x290
(lldb) fblock 0x100f18210
-----try to lookup block in JITDemo-----
find a block: 0x100f18210 in JITDemo`-[ViewController touchesBegan:withEvent:]
1 block(s) resolved
Find blocks in user modules and save block symbols to block_symbol.json
(lldb) blocks
-----try to lookup block in JITDemo-----
* using global block var: 0x104a78150 in JITDemo`-[ViewController viewDidLoad] at ViewController.m:39:5
find a block: 0x104a78190 in JITDemo`-[ViewController viewDidLoad] at ViewController.m:0:0
...
find a stack block @0x104a74e7c in JITDemo`__41-[ViewController touchesBegan:withEvent:]_block_invoke_3 at ViewController.m:0:0
stack block func addr 0x104a74f08 JITDemo`__41-[ViewController touchesBegan:withEvent:]_block_invoke_4 at ViewController.m:75:0
...
-----try to lookup block in LLDBJIT-----
find a block: 0x104b341c0 in LLDBJIT`+[MachoTool findMacho] at MachoTool.m:0:0
...
find a stack block @0x104b32080 in LLDBJIT`+[Image getBlocksInfo:] at Image.m:0:0
stack block func addr 0x104b34d40 LLDBJIT`None
85 block(s) resolved
find function by callee function name
(lldb) ffunc -n open -i 5900
-----parsing module Demo-----
function call found at: 0x1057c09b0, where = Demo`___lldb_unnamed_symbol255344 + 88
find function by callee funcation address
(lldb) ffunc -a 0x1005106a0 -i 5000
-----parsing module Demo-----
function call found at: 0x10050dcd8, where = Demo`test_func + 2360
find function by c string
(lldb) ffunc -k test -i 700 -x 800
-----parsing module Demo-----
keyword test found at 0x105bb5227
(lldb) overridden_method
Trace all functions in the specified module. By default, only OC methods are traced. To trace swift module, you need to add the -a option.
// begin trace
(lldb) mtrace LLDBCode
-----trace functions in LLDBCode-----
will trace 35 names
begin trace with Breakpoint 1: 35 locations
(lldb) c
// trace log
frame #0: 0x0000000102dd2fb8 LLDBCode`-[ViewController touchesBegan:withEvent:](self=0x00000001d4108040, _cmd="touchesBegan:withEvent:", touches=0x000000015fd0fff0, event=1 element) at ViewController.m:35
...
frame #0: 0x0000000102dd318c LLDBCode`__41-[ViewController touchesBegan:withEvent:]_block_invoke(.block_descriptor=0x0000000102ec1500) at ViewController.m:45
trace functions using regular expressions
(lldb) rtrace -i GetDeviceInfo
begin trace with Breakpoint 4: where = CoreTelephony`_CTServerConnectionPhoneServicesGetDeviceInfo, address = 0x1bab0f6a0
...
begin trace with Breakpoint 8: where = MediaRemote`MRMediaRemoteGetDeviceInfo, address = 0x1c85b4c84
begin trace with 5 breakpoint(s)
trace notificaton posting action
(lldb) notifier
begin trace -[NSNotificationCenter postNotification:] with Breakpoint 8
begin trace -[NSNotificationCenter postNotificationName:object:userInfo:] with Breakpoint 9
begin trace CFNotificationCenterPostNotificationWithOptions with Breakpoint 10
Patch bytes in user modules.
(lldb) patch c0 03 5f d6
-----try to patch bytes in LLDBCode-----
patch 32 locations
Dump the specified module from memory.
(lldb) dmodule UIKit
dumping UIKit, this may take a while
ignore __DATA.__bss
ignore __DATA.__common
ignore __DATA_DIRTY.__bss
ignore __DATA_DIRTY.__common
924057600 bytes dump to ~/lldb_dump_macho/UIKit/macho_UIKit
注意:加载时被修改的数据未恢复
Dump current iOS App (arm64 only). Typically, dump decrypted ipa from jailbreak device.
(lldb) dapp
dumping JITDemo, this may take a while
copy file JITDemo.app/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
...
copy file JITDemo.app/embedded.mobileprovision
no file need patch
Generating "JITDemo.ipa"
dump success, ipa path: /Users/xxx/lldb_dump_macho/JITDemo/JITDemo.ipa
Add a lldb command for mac command line tool.
(lldb) addcmd which
Add command script successfully, try using it
(lldb) which
usage: which [-as] program ...
(lldb) which ls
/bin/ls
Delete lldb command added by addcmd.
(lldb) delcmd which
command "which" has been deleted
(lldb) which
error: 'which' is not a valid command.
(lldb) pwd
/Users/xxx
(lldb) cd /
(lldb) pwd
/
List directory contents on Mac.
(lldb) ls -l
total 10
drwxrwxr-x 61 root admin 1952 Jul 4 12:28 Applications
drwxr-xr-x 71 root wheel 2272 May 21 09:49 Library
drwxr-xr-x@ 10 root wheel 320 May 7 15:01 System
drwxr-xr-x 5 root admin 160 May 21 09:48 Users
drwxr-xr-x 4 root wheel 128 Jul 4 12:29 Volumes
drwxr-xr-x@ 39 root wheel 1248 May 7 15:01 bin
drwxr-xr-x 2 root wheel 64 Jul 14 2022 cores
dr-xr-xr-x 3 root wheel 4982 Jul 2 16:28 dev
lrwxr-xr-x@ 1 root wheel 11 May 7 15:01 etc -> private/etc
lrwxr-xr-x 1 root wheel 25 Jul 2 16:29 home -> /System/Volumes/Data/home
drwxr-xr-x 4 root wheel 128 May 16 14:10 opt
drwxr-xr-x 6 root wheel 192 Jul 2 16:29 private
drwxr-xr-x@ 64 root wheel 2048 May 7 15:01 sbin
lrwxr-xr-x@ 1 root wheel 11 May 7 15:01 tmp -> private/tmp
drwxr-xr-x@ 11 root wheel 352 May 7 15:01 usr
lrwxr-xr-x@ 1 root wheel 11 May 7 15:01 var -> private/var
(lldb) bundle_dir
/var/containers/Bundle/Application/63954B0E-79FA-42F2-A7EA-3568026008A1/Interlock.app
(lldb) home_dir
/var/mobile/Containers/Data/Application/1161FDFD-5D69-47CD-B5C6-C2724B8E2F28
(lldb) doc_dir
/var/mobile/Containers/Data/Application/1161FDFD-5D69-47CD-B5C6-C2724B8E2F28/Documents
(lldb) caches_dir
/var/mobile/Containers/Data/Application/1161FDFD-5D69-47CD-B5C6-C2724B8E2F28/Library/Caches
(lldb) lib_dir
/var/mobile/Containers/Data/Application/1161FDFD-5D69-47CD-B5C6-C2724B8E2F28/Library
(lldb) tmp_dir
/var/mobile/Containers/Data/Application/1161FDFD-5D69-47CD-B5C6-C2724B8E2F28/tmp
(lldb) group_dir
/private/var/mobile/Containers/Shared/AppGroup/9460EA21-AE6A-4220-9BB3-6EC8B971CDAE
List directory contents on remote device, just like ls -lh
on Mac.
(lldb) ils bu
/var/containers/Bundle/Application/D0419A6E-053C-4E35-B422-7C0FD6CAB060/Interlock.app
drwxr-xr-x 128B 1970-01-01 00:00:00 +0000 Base.lproj
drwxr-xr-x 96B 1970-01-01 00:00:00 +0000 _CodeSignature
drwxr-xr-x 64B 1970-01-01 00:00:00 +0000 META-INF
-rw-r--r-- 1.5K 2023-05-16 03:17:32 +0000 Info.plist
-rwxr-xr-x 103.0K 2023-05-19 11:07:02 +0000 Interlock
-rw-r--r-- 8B 2023-05-16 03:17:32 +0000 PkgInfo
-rw-r--r-- 194.7K 2023-05-16 03:17:31 +0000 embedded.mobileprovision
(lldb) ils home
/var/mobile/Containers/Data/Application/09E63130-623F-4124-BCBB-59E20BD28964
drwxr-xr-x 96B 2023-05-19 07:28:01 +0000 Documents
drwxr-xr-x 128B 2023-05-16 04:51:14 +0000 Library
drwxr-xr-x 64B 1970-01-01 00:00:00 +0000 SystemData
drwxr-xr-x 64B 2023-05-16 04:51:14 +0000 tmp
(lldb) ils /var/mobile/Containers/Data/Application/09E63130-623F-4124-BCBB-59E20BD28964/Documents
-rw-r--r-- 18B 2023-05-16 05:36:05 +0000 report.txt
Download file from home, bundle or group path.
(lldb) dfile /var/containers/Bundle/Application/7099B2B8-39BE-4204-9BEB-5DF6A75BAA29/JITDemo.app/Info.plist
dumping Info.plist, this may take a while
1464 bytes written to '/Users/xxx/Info.plist'
or
(lldb) dfile bundle/Info.plist
dumping Info.plist, this may take a while
1464 bytes written to '/Users/xxx/Info.plist'
Download dir from home, bundle or group path.
(lldb) ddir /var/containers/Bundle/Application/7099B2B8-39BE-4204-9BEB-5DF6A75BAA29/JITDemo.app
dumping JITDemo.app, this may take a while
1197 bytes written to '/Users/xxx/JITDemo.app/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib'
...
8 bytes written to '/Users/xxx/JITDemo.app/PkgInfo'
196731 bytes written to '/Users/xxx/JITDemo.app/embedded.mobileprovision'
Upload local file to the specified directory or path on device.
(lldb) doc
/var/mobile/Containers/Data/Application/1171F451-C2DC-47E6-B6E3-74A0FE5A6572/Documents
(lldb) ufile /Users/xxx/uploadfile /var/mobile/Containers/Data/Application/1171F451-C2DC-47E6-B6E3-74A0FE5A6572/Documents
uploading uploadfile, this may take a while
upload success
(lldb) ufile /Users/xxx/uploadfile /var/mobile/Containers/Data/Application/1171F451-C2DC-47E6-B6E3-74A0FE5A6572/Documents/test
uploading uploadfile, this may take a while
upload success
(lldb) ils doc
/var/mobile/Containers/Data/Application/1171F451-C2DC-47E6-B6E3-74A0FE5A6572/Documents
-rw-r--r-- 12.1K 2023-08-10 07:11:29 +0000 test
-rw-r--r-- 12.1K 2023-08-10 07:11:22 +0000 uploadfile
Remove file or directory on remote device.
(lldb) ils doc
/var/mobile/Containers/Data/Application/B142040E-B1A0-4E97-8E76-03357585BFF8/Documents
-rw-r--r-- 12.1K 2023-08-10 07:32:05 +0000 test
-rw-r--r-- 12.1K 2023-08-10 08:22:40 +0000 uploadfile
(lldb) irm /var/mobile/Containers/Data/Application/B142040E-B1A0-4E97-8E76-03357585BFF8/Documents/uploadfile
remove success
(lldb) ils doc
/var/mobile/Containers/Data/Application/B142040E-B1A0-4E97-8E76-03357585BFF8/Documents
-rw-r--r-- 12.1K 2023-08-10 07:32:05 +0000 test
List current executable and dependent shared library images, sorted by load address.
(lldb) image_list
index load_addr(slide) vmsize path
------------------------------------------------------------
[ 0] 0x1048dc000(0x0048dc000) 655.4K /private/var/containers/Bundle/Application/D5752641-F291-4170-9576-67D8011C88D3/JITDemo.app
[ 1] 0x10497c000(0x10497c000) 131.1K /Users/xxx/Library/Developer/Xcode/DerivedData/LLDBJIT-xxx/Build/Products/Debug-iphoneos/JITDemo.app/Frameworks/LLDBJIT.framework/LLDBJIT
...
(lldb) image_list -v
index load_addr - end_addr(slide) vmsize arch uuid path
------------------------------------------------------------
[ 0] 0x1048dc000 - 0x10497c000(0x0048dc000) 655.4K arm64 5B4BAB05-B614-339D-909E-1877AA53AD11 /private/var/containers/Bundle/Application/D5752641-F291-4170-9576-67D8011C88D3/JITDemo.app
[ 1] 0x10497c000 - 0x10499c000(0x10497c000) 131.1K arm64 E8938575-D438-3175-B846-B60CF9DE0304 /Users/xxx/Library/Developer/Xcode/DerivedData/LLDBJIT-xxx/Build/Products/Debug-iphoneos/JITDemo.app/Frameworks/LLDBJIT.framework/LLDBJIT
...
(lldb) image_list -u
index load_addr(slide) vmsize path
------------------------------------------------------------
[ 0] 0x1022f8000(0x0022f8000) 98.3K /private/var/containers/Bundle/Application/5DD99AF7-20FE-4369-AD0B-6A898DB12171/JITDemo.app
[ 1] 0x1024cc000(0x1024cc000) 147.5K /Users/xxx/Library/Developer/Xcode/DerivedData/LLDBJIT-bwkzhcqdptajftbnezhkwkpwqlqb/Build/Products/Debug-iphoneos/JITDemo.app/Frameworks/LLDBJIT.framework/LLDBJIT
[ 2] 0x1027a0000(0x1027a0000) 655.4K /Users/xxx/Library/Developer/Xcode/DerivedData/LLDBJIT-bwkzhcqdptajftbnezhkwkpwqlqb/Build/Products/Debug-iphoneos/JITDemo.app/JITDemo.debug.dylib
(lldb) info_plist
-----parsing module Demo-----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
...
</dict>
</plist>
Print main executable name.
(lldb) executable
LLDBCode
Find the class that conforms to the UIApplicationDelegate protocol.
(lldb) appdelegate
AppDelegate
Get module name with header address.
(lldb) p/x header
(const mach_header *) 0x1043e8000
(lldb) mname 0x1043e8000
LLDBCode
(lldb) mname header
LLDBCode
Print segments and section info of macho.
(lldb) segments JITDemo
-----parsing module JITDemo-----
[start - end) size name
------------------------------------------------------------
[0x497c000 -0x10497c000) 0x100000000 __PAGEZERO
------------------------------------------------------------
[0x10497c000-0x104984000) 0x8000 __TEXT
[0x104980000-0x1049811b0) 0x11b0 __text
[0x1049811b0-0x104981270) 0xc0 __stubs
[0x104981270-0x104981348) 0xd8 __stub_helper
[0x104981348-0x1049815a8) 0x260 __objc_stubs
[0x1049815a8-0x1049824e5) 0xf3d __objc_methname
[0x1049824e5-0x104982736) 0x251 __cstring
[0x104982736-0x1049827b5) 0x7f __objc_classname
[0x1049827b5-0x1049832de) 0xb29 __objc_methtype
[0x1049832e0-0x104983360) 0x80 __unwind_info
------------------------------------------------------------
[0x104984000-0x104988000) 0x4000 __DATA
[0x104984000-0x104984030) 0x30 __got
[0x104984030-0x1049840b0) 0x80 __la_symbol_ptr
[0x1049840b0-0x1049841f0) 0x140 __cfstring
[0x1049841f0-0x104984210) 0x20 __objc_classlist
[0x104984210-0x104984218) 0x8 __objc_nlclslist
[0x104984218-0x104984238) 0x20 __objc_protolist
[0x104984238-0x104984240) 0x8 __objc_imageinfo
[0x104984240-0x104985408) 0x11c8 __objc_const
[0x104985408-0x1049854a8) 0xa0 __objc_selrefs
[0x1049854a8-0x1049854e0) 0x38 __objc_classrefs
[0x1049854e0-0x1049854e8) 0x8 __objc_superrefs
[0x1049854e8-0x1049854f0) 0x8 __objc_ivar
[0x1049854f0-0x104985630) 0x140 __objc_data
[0x104985630-0x1049857c0) 0x190 __data
[0x1049857c0-0x104985800) 0x40 __common
[0x104985800-0x104985818) 0x18 __bss
------------------------------------------------------------
[0x104988000-0x104994000) 0xc000 __LINKEDIT
[0x1049887c0-0x1049887f0) 0x30 Function Starts
[0x1049887f0-0x104989d10) 0x1520 Symbol Table
[0x1049887f0-0x1049887f0) 0x0 Data In Code Entries
[0x104989d10-0x104989da8) 0x98 Dynamic Symbol Table
[0x104989da8-0x10498b470) 0x16c8 String Table
[0x10498b470-0x104990140) 0x4cd0 Code Signature
Print the address of main function.
(lldb) main
function main at 0x102911b70, fileoff: 0x5b70
Dump module init function(s) of specified module.
(lldb) initfunc
-----try to lookup init function in JITDemo-----
mod init func pointers found: __DATA,__mod_init_func
address = 0x100e08cb0 JITDemo`entry1 at main.m:708:0
address = 0x100e0960c JITDemo`entry2 at main.m:740:0
Print function starts
(lldb) func_starts
-----parsing module JITDemo-----
address = 0x1021bc5c8 size = 64 where = JITDemo`globalBlock_block_invoke at ViewController.m:17
address = 0x1021bc608 size = 20 where = JITDemo`+[ViewController load] at ViewController.m:27
...
address = 0x1021bdae0 size = 56 where = JITDemo`-[SceneDelegate .cxx_destruct] at SceneDelegate.m:14
(lldb)
(lldb) got
-----parsing module JITDemo-----
address = 0x1ac734ce0 where = where = Foundation`NSFileModificationDate -> NSFileModificationDate (not a function)
...
address = 0x180d44900 where = libobjc.A.dylib`objc_msgSend (matched)
address = 0x1814ce1c0 where = libdyld.dylib`dyld_stub_binder (matched)
13 location(s) found
(lldb) lazy_sym
-----parsing module JITDemo-----
address = 0x104c7fe14 where = JITDemo`my_NSHomeDirectory at ViewController.m:63 -> Foundation`NSHomeDirectory
...
address = 0x1815fb950 where = libsystem_kernel.dylib`open (matched)
36 location(s) found
Dump codesign entitlements of the specified module if any.
(lldb) ent
Interlock:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>XXXX.com.xxx.Interlock</string>
<key>com.apple.developer.team-identifier</key>
<string>XXXX</string>
<key>com.apple.security.application-groups</key>
<array/>
<key>get-task-allow</key>
<true/>
</dict>
</plist>
(lldb) ent UIKit
UIKit apparently does not contain code signature
Dump bundle ID in the codesign entitlements.
(lldb) ent -b
TeamID.com.xxx.LLDBCode
Dump team ID in the codesign entitlements.
(lldb) ent -t
TeamID
Dump group ID(s) in the codesign entitlements.
(lldb) ent -g
['group.com.xxx.JITDemo']
Print class names in the specified module.
(lldb) classes
AppDelegate <0x10468e378>
SceneDelegate <0x10468e418>
ViewController <0x10468e260>
Dumps all methods implemented by the NSObject subclass, supporting both iOS and MacOS.
(lldb) dmethods ViewController
<ViewController: 0x1021c9b48>:
in ViewController:
Properties:
@property unsigned long test; (@synthesize test = _test;)
Instance Methods:
- (void) setRepresentedObject:(id)arg1; (0x1021c7020)
- (void) setTest:(unsigned long)arg1; (0x1021c7190)
- (unsigned long) test; (0x1021c7170)
- (void) viewDidLoad; (0x1021c6e90)
(NSViewController ...)
Dumps all ivars for an instance of a particular class which inherits from NSObject, supporting both iOS and MacOS.
(lldb) divars ViewController
in ViewController:
_test (unsigned long): {length = 8, bytes = 0x5a00ab0000000000}
(lldb) duplicate_class
class DDContextAllowlistFilterLogFormatter is implemented in:
/JITDemo.app/Frameworks/JITMiddleWareSDK.framework/JITMiddleWareSDK
/JITDemo.app/Frameworks/LLDBLog.framework/LLDBLog
...
class DDLoggingContextSet is implemented in:
/JITDemo.app/Frameworks/LLDBJIT.framework/JITMiddleWareSDK
/JITDemo.app/Frameworks/LLDBLog.framework/LLDBLog
24 duplicate classes were found
Convert assembly instructions to machine code.
(lldb) inst2bytes 'mov x9, sp;mov x8, x0'
disassembly:
0: 910003e9 mov x9, sp
4: aa0003e8 mov x8, x0
machine code: e9030091e80300aa
Convert machine code to assembly instructions.
(lldb) bytes2inst e9030091e80300aa
<+0>: mov x9, sp
<+4>: mov x8, x0
(lldb) seg
...
------------------------------------------------------------
[0x102ee0000-0x102ee4000) 0x4000 __DATA
[0x102ee0000-0x102ee0000) 0x68 __got
...
[0x102ee02e0-0x102ee0560) 0x280 __cfstring
...
// read __got section
(lldb) read_mem_as_addr 0x102ee0000 0x102ee0068
0x102ee0000: 0x00000001ac734ce0 Foundation`NSFileModificationDate
...
0x102ee0058: 0x0000000180d44900 libobjc.A.dylib`objc_msgSend
0x102ee0060: 0x00000001814ce1c0 libdyld.dylib`dyld_stub_binder
// read __cfstring section
(lldb) read_mem_as_addr 0x102ee02e0 0x102ee0560
0x102ee02e0: 0x00000001b40b2610 (void *)0x00000001b40b25c0: __NSCFConstantString
0x102ee02e8: 0x00000000000007c8
0x102ee02f0: 0x0000000102ede156 "%s"
0x102ee02f8: 0x0000000000000002
...
0x102ee0540: 0x00000001b40b2610 (void *)0x00000001b40b25c0: __NSCFConstantString
0x102ee0548: 0x00000000000007c8
0x102ee0550: 0x0000000102ede2cc "Default Configuration"
0x102ee0558: 0x0000000000000015
(lldb) seg
...
[0x10077b3ae-0x10077b424) 0x76 __objc_classname
....
[0x100782898-0x1007857f0) 0x2f58 String Table
...
// read __TEXT.__objc_classname
(lldb) read_cstring 0x10077b3ae 0x10077b424
0x10077b3ae: "ViewController"
...
0x10077b414: "UISceneDelegate"
9 locations found
// read String Table
(lldb) read_cstring 0x100782898 0x1007857f0
0x100782898: " "
0x10078289a: "_JITDemoVersionNumber"
...
0x1007857c8: "__OBJC_PROTOCOL_$_UIWindowSceneDelegate"
338 locations found
Add debug symbol file(s) to corresponding module(s)
(lldb) load_dSYM /path/to/dSYMs/Alamofire.framework.dSYM
1 dSYM file(s) loaded
or
(lldb) load_dSYM /path/to/dSYMs
16 dSYM file(s) loaded
Symbolize address, uncaught exception address list or crash report file.
Symbolize address
(lldb) dis -c 1 -a 0x1045843d4
JITDemo`___lldb_unnamed_symbol302:
0x1045843d4 <+0>: sub sp, sp, #0x1f0
(lldb) symbolize 0x1045843d4
0x1045843d4: JITDemo`-[ViewController ls_dir:] + 0
Symbolize uncaught exception address list
(lldb) symbolic (0x1845aed8c 0x1837685ec 0x18450a448 0x104360f78 0x18e4fd83c 0x18e3a3760 0x18e39d7c8 0x18e392890 0x18e3911d0 0x18eb72d1c 0x18eb752c8 0x18eb6e368 0x184557404 0x184556c2c 0x18455479c 0x184474da8 0x186459020 0x18e491758 0x104361da0 0x183f05fc0)
backtrace:
frame #0: 0x1845aed8c CoreFoundation`__exceptionPreprocess + 228
frame #1: 0x1837685ec libobjc.A.dylib`objc_exception_throw + 56
frame #2: 0x18450a448 CoreFoundation`-[__NSArray0 objectEnumerator] + 0
frame #3: 0x104360f78 JITDemo`-[ViewController touchesBegan:withEvent:] + at ViewController.m:51:5
...
or
(lldb) symbolic 0x1845aed8c 0x1837685ec 0x18450a448 0x104360f78 0x18e4fd83c 0x18e3a3760 0x18e39d7c8 0x18e392890 0x18e3911d0 0x18eb72d1c 0x18eb752c8 0x18eb6e368 0x184557404 0x184556c2c 0x18455479c 0x184474da8 0x186459020 0x18e491758 0x104361da0 0x183f05fc0
backtrace:
frame #0: 0x1845aed8c CoreFoundation`__exceptionPreprocess + 228
frame #1: 0x1837685ec libobjc.A.dylib`objc_exception_throw + 56
frame #2: 0x18450a448 CoreFoundation`-[__NSArray0 objectEnumerator] + 0
frame #3: 0x104360f78 JITDemo`-[ViewController touchesBegan:withEvent:] + at ViewController.m:51:5
...
Symbolize crash report file.
(lldb) symbolize /Users/xxx/test/JITDemo-2024-07-29-163051.ips
or
(lldb) symbolize /Users/xxx/Desktop/JITDemo.crash
Debugkit is a framework for debugging, it is not loaded by default.
You can load it using the debugkit
command.
(lldb) debugkit
loading DebugKit, this may take a while
[INFO] GCDWebUploader started on port 80 and reachable at http://xxx.xxx.xxx.xxx/
DebugKit loaded
(lldb) po btn
<UIButton: 0x107d2eaf0; frame = (100 100; 200 30); opaque = NO; layer = <CALayer: 0x282f4ee20>>
control events list:
target: <ViewController: 0x107e2ac90>, action: -[ViewController clicked:], event: UIControlEventTouchUpInside
UIKit provides debugging methods in NSObject(IvarDescription)
,It works on iOS but not on macOS.Debugkit provides several alternative solutions for this.
Here's one solution in DebugKit:
(lldb) divars self
(FP)
in ViewController:
_test (unsigned long): {length = 8, bytes = 0x5a00ab0000000000}
(lldb) dmethods self
<ViewController: 0x1063c7c10>: (FP)
in ViewController:
Class Methods:
+ (void) ivar_description:(id)arg1; (0x1063c4d10)
+ (void) method_description:(id)arg1; (0x1063c4870)
Properties:
@property unsigned long test; (@synthesize test = _test;)
Instance Methods:
- (void) setRepresentedObject:(id)arg1; (0x1063c4800)
- (void) setTest:(unsigned long)arg1; (0x1063c5120)
- (unsigned long) test; (0x1063c5100)
- (void) viewDidLoad; (0x1063c4790)
(NSViewController ...)
Here's another solution in DebugKit (Powered by pookjw/IvarDescription):
(lldb) divars ofile
<CDMachOFile: 0x600002580000>: (DK)
in CDMachOFile:
<+ 32> _byteOrder (unsigned long): 0
...
<+ 24> _searchPathState (CDSearchPathState*): nil
in NSObject:
<+ 0> isa (Class): CDMachOFile(isa, 0x23d8001000711c5)
(lldb) dmethods ofile
<CDMachOFile: 0x1000711c0>: (DK)
in CDMachOFile:
Properties:
@property (readonly) unsigned long byteOrder;
...
@property (readonly, nonatomic) Class processorClass;
Instance Methods:
- (int) cputype; (0x10002b310)
...
- (id) segmentWithName:(id)arg1; (0x100028f00)
(CDFile ...)
block code sample
^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@ %d", self, fd);
}
Here is the official block description.
(lldb) po $x0
<__NSMallocBlock__: 0x282090ab0>
signature: "v24@?0@"NSURLSessionDataTask"8@"NSError"16"
invoke : 0x102fe4a4c (/private/var/containers/Bundle/Application/3AF6DA13-4E66-4E8F-89D0-BDD268A430A7/JITDemo.app/JITDemo.debug.dylib`__41-[ViewController touchesBegan:withEvent:]_block_invoke_2)
copy : 0x102fe4bc8 (/private/var/containers/Bundle/Application/3AF6DA13-4E66-4E8F-89D0-BDD268A430A7/JITDemo.app/JITDemo.debug.dylib`__copy_helper_block_e8_32s)
dispose : 0x102fe4c00 (/private/var/containers/Bundle/Application/3AF6DA13-4E66-4E8F-89D0-BDD268A430A7/JITDemo.app/JITDemo.debug.dylib`__destroy_helper_block_e8_32s)
Here is DebugKit's block description, it's clearer and more straightforward.
(lldb) po [$x0 description]
<__NSMallocBlock__: 0x282090ab0>
- size: 44
- func_addr: <0x102fe4a4c>
- func_prototype: void (*)(id(block) , NSURLSessionDataTask * , NSError * )
- variable or captured variable:
- <ViewController: 0x107e2ac90>
- int 20
Powered by GCDWebServer.The server starts along with DebugKit, and once it's running, you can access sandbox files via a web browser.
[INFO] GCDWebUploader started on port 80 and reachable at http://xxx.xxx.xxx.xxx/
(lldb) c
Process 4569 resuming
[INFO] GCDWebUploader now locally reachable at http://iPhone-8.local/
show vm map info of address
(lldb) po self
<ViewController: 0x105329a40>
(lldb) vmmap self
pid: 4713
path: /private/var/containers/Bundle/Application/08326E5F-4DEB-41CC-8320-4417B1649E7F/JITDemo.app/JITDemo
0000000105300000-0000000105400000 [ 1.0M] rw-/rwx SM=PRIVATE <MALLOC_TINY>
(offset 0) /usr/share/icu/icudt70l.dat
show vm map info of current process
(lldb) vmmap
pid: 4713
path: /private/var/containers/Bundle/Application/08326E5F-4DEB-41CC-8320-4417B1649E7F/JITDemo.app/JITDemo
DYLD all image info: 0000000104cd0000 + 170 format = 1
0000000104c00000-0000000104c04000 [ 16K] r-x/r-x SM=COW
104c00000-104c0c000: __TEXT r-x (/private/var/containers/Bundle/Application/08326E5F-4DEB-41CC-8320-4417B1649E7F/JITDemo.app/JITDemo) slide=4c00000
(offset 0) /private/var/containers/Bundle/Application/08326E5F-4DEB-41CC-8320-4417B1649E7F/JITDemo.app/JITDemo
0000000104c04000-0000000104c08000 [ 16K] r-x/rwx SM=PRIVATE
104c00000-104c0c000: __TEXT r-x (/private/var/containers/Bundle/Application/08326E5F-4DEB-41CC-8320-4417B1649E7F/JITDemo.app/JITDemo) slide=4c00000
(offset 0) /private/var/containers/Bundle/Application/08326E5F-4DEB-41CC-8320-4417B1649E7F/JITDemo.app/JITDemo
...
221e4c000-235b08000: __LINKEDIT r-- (/System/Library/PrivateFrameworks/AppSSOCore.framework/AppSSOCore) slide=c204000
221e4c000-235b08000: __LINKEDIT r-- (/System/Library/Frameworks/Accelerate.framework/Frameworks/vImage.framework/Libraries/libCGInterfaces.dylib) slide=c204000
0000000280000000-00000002a0000000 [ 512.0M] rw-/rwx SM=PRIVATE <MALLOC_NANO>
0000000fc0000000-0000001000000000 [ 1.0G] ---/--- SM=EMPTY
0000001000000000-0000007000000000 [ 384.0G] ---/--- SM=EMPTY
Detects endless loop in all threads at this point.
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
int a = 1;
NSLog(@"%s", __PRETTY_FUNCTION__);
while (a) {
a++;
}
}
# touch device screen
2023-05-20 12:29:52.604910+0800 Interlock[56660:1841567] -[ViewController touchesBegan:withEvent:]
# pause program execution, then execute find_el in lldb
(lldb) find_el
Breakpoint 1: where = Interlock`-[ViewController touchesBegan:withEvent:] + 136 at ViewController.mm:34:5, address = 0x109dd8d48
Breakpoint 2: where = Interlock`main + 110 at main.m:17:5, address = 0x109dd911e
delete breakpoint 2
call Interlock`-[ViewController touchesBegan:withEvent:] + 136 at ViewController.m:34:5, 22 times per second, hit_count: 100
...
Get extended backtrace of thread.
(lldb) bt
* thread #2, queue = 'com.apple.root.default-qos', stop reason = breakpoint 6.1
* frame #0: 0x0000000104ab58f8 Concurrency`__41-[ViewController touchesBegan:withEvent:]_block_invoke(.block_descriptor=0x0000000104ab80f8) at ViewController.m:29:13
frame #1: 0x0000000104df51dc libdispatch.dylib`_dispatch_call_block_and_release + 24
frame #2: 0x0000000104df519c libdispatch.dylib`_dispatch_client_callout + 16
frame #3: 0x0000000104e01200 libdispatch.dylib`_dispatch_queue_override_invoke + 968
frame #4: 0x0000000104e067c8 libdispatch.dylib`_dispatch_root_queue_drain + 604
frame #5: 0x0000000104e06500 libdispatch.dylib`_dispatch_worker_thread3 + 136
frame #6: 0x0000000181fc3fac libsystem_pthread.dylib`_pthread_wqthread + 1176
frame #7: 0x0000000181fc3b08 libsystem_pthread.dylib`start_wqthread + 4
(lldb) thread_eb
thread #4294967295: tid = 0x190c, 0x0000000104e907cc libdispatch.dylib`_dispatch_root_queue_push_override + 160, queue = 'com.apple.main-thread'
frame #0: 0x0000000104e907cc libdispatch.dylib`_dispatch_root_queue_push_override + 160
frame #1: 0x0000000104ded884 Concurrency`-[ViewController touchesBegan:withEvent:](self=<unavailable>, _cmd=<unavailable>, touches=<unavailable>, event=<unavailable>) at ViewController.m:25:5
frame #2: 0x000000018bb1583c UIKit`forwardTouchMethod + 340
frame #3: 0x000000018b9bb760 UIKit`-[UIResponder touchesBegan:withEvent:] + 60
...
https://github.com/DerekSelander/LLDB
https://github.com/facebook/chisel
https://github.com/aaronst/macholibre
https://github.com/swisspol/GCDWebServer
https://github.com/pookjw/IvarDescription
https://github.com/yulingtianxia/BlockHook (block with private data)
https://github.com/comex/myvmmap
YJLLDB is released under the Apache License 2.0. See LICENSE file for details.