lldb Cheat Sheet for iOS RE

Attach & Control

lldb -n SpringBoard                    # Attach by name
lldb -p 1234                           # Attach by PID
(lldb) process attach --name target    # Attach after launch

(lldb) b main                          # Breakpoint at symbol
(lldb) br s -a 0x1000abcde            # Breakpoint at address
(lldb) br s -n '-[NSObject init]'     # ObjC method breakpoint
(lldb) br s -r 'IOSurface.*'          # Regex breakpoint
(lldb) br l                            # List breakpoints
(lldb) br del 1                        # Delete breakpoint #1
(lldb) c                               # Continue
(lldb) si                              # Step instruction
(lldb) ni                              # Next instruction (step over)
(lldb) finish                          # Run until return

Inspect State

(lldb) register read                   # All registers
(lldb) reg read x0 x1 x2 lr sp pc    # Specific registers
(lldb) reg read cpsr                   # Flags register

(lldb) memory read 0x12345678          # Hex dump
(lldb) x/10gx 0x12345678              # 10 uint64 hex values
(lldb) x/10wx 0x12345678              # 10 uint32 hex values
(lldb) x/s 0x12345678                  # Read as string
(lldb) memory read -f x -s 8 -c 4 $sp # 4 uint64 from stack

(lldb) dis -a 0x12345678              # Disassemble at address
(lldb) dis -n function_name            # Disassemble function
(lldb) dis -p                          # Disassemble at PC

(lldb) image list                      # Loaded images + slides
(lldb) image lookup -a 0x12345678     # Symbol at address
(lldb) image lookup -n symbol_name    # Address of symbol

Expressions

(lldb) p (int)getpid()                 # Call function
(lldb) p/x *(uint64_t*)$x0            # Dereference pointer
(lldb) p (char*)$x1                    # Print as string
(lldb) expr @import UIKit              # Import framework
(lldb) po [UIApplication sharedApplication]  # ObjC print object

Watchpoints

(lldb) watchpoint set expression -s 8 -- 0x12345678   # Watch memory write
(lldb) w s e -s 4 -w read -- 0x12345678               # Watch memory read

Kernel Debugging

Via Corellium

1. Create virtual iOS device on Corellium
2. Enable kernel debugging in device settings
3. Connect lldb:
   lldb
   (lldb) platform select remote-ios
   (lldb) process connect connect://CORELLIUM_IP:1234
4. Load kernel symbols from KDK
5. Set breakpoints in kernel code

Via KDP (Physical Device – macOS)

Requires:
  - Development/debug kernel (from KDK)
  - boot-args: debug=0x44 kdp_match_name=en0
  - Network connection between Mac and target

Setup:
  1. Install KDK on Mac
  2. Set boot-args on target
  3. Trigger NMI (panic) on target
  4. lldb connects via network

Apple Kernel Debug Kit (KDK)

Download: developer.apple.com → More Downloads → search "Kernel Debug Kit"
Contains:
  - kernel.development.* (debug kernel binary)
  - *.dSYM (symbol files)
  - lldb macros for kernel inspection
  
Usage with IDA:
  - Load kernelcache
  - File → Load file → DWARF file → KDK dSYM
  → Full symbol names + type info for kernel functions

Frida for iOS

Setup

# On jailbroken device
apt install frida frida-server

# On Mac
pip3 install frida-tools

# Connect via USB
frida -U -n SpringBoard
frida -U -f com.apple.mobilesafari  # Launch + attach

Useful Frida Scripts

// Hook IOConnectCallMethod
const IOConnectCallMethod = Module.getExportByName(
    'IOKit', 'IOConnectCallMethod');

Interceptor.attach(IOConnectCallMethod, {
    onEnter(args) {
        this.conn = args[0];
        this.selector = args[1].toInt32();
        console.log(`IOConnectCallMethod(conn=${this.conn}, sel=${this.selector})`);
    },
    onLeave(retval) {
        console.log(`  → returned ${retval}`);
    }
});

// Hook ObjC method
const hook = ObjC.classes.NSURLSession['- dataTaskWithURL:completionHandler:'];
Interceptor.attach(hook.implementation, {
    onEnter(args) {
        const url = ObjC.Object(args[2]).absoluteString().toString();
        console.log(`NSURLSession request: ${url}`);
    }
});

// Enumerate loaded modules
Process.enumerateModules().forEach(m => {
    console.log(`${m.name}: ${m.base} (${m.size})`);
});

Resources