LLDB Cheatsheet#
Basic Commands#
| Command | Description |
|---|
lldb <program> | Launch LLDB with a specific program. |
run/r | Start or restart the program. |
shell clear | Clear the LLDB console screen. |
quit/q | Exit LLDB. |
Ctrl+D | Exit LLDB. |
Process & Attach#
| Command | Description |
|---|
process attach --name <name> | Attach to a process by name. |
process attach --pid <pid> | Attach to a process by PID. |
process attach --name <name> --waitfor | Attach to process by name when it launches. |
Breakpoints#
| Command | Description |
|---|
breakpoint set --name <function> | Set a breakpoint at the specified function. |
breakpoint set -n <function> | Set a breakpoint at the specified function (short form). |
breakpoint set -a <address> | Set a software breakpoint at address. |
breakpoint set -H -a <address> | Set a hardware breakpoint at address. |
breakpoint set -f <file> -l <line> | Set a breakpoint at file:line. |
breakpoint set -r <regex> | Set a breakpoint by function name regex. |
breakpoint set -p <regex> -f <file> | Set a breakpoint by source pattern regex. |
breakpoint set -M <method> | Set a breakpoint by C++ method name. |
breakpoint set --method <method> | Set a breakpoint by C++ method name (long form). |
breakpoint set -S <selector> | Set a breakpoint by Objective-C selector. |
breakpoint set --selector <selector> | Set a breakpoint by Objective-C selector (long form). |
breakpoint set -n <function> -s <lib> | Set a breakpoint only in specified shared library. |
breakpoint set -n <function> -c "x == 5" | Set a conditional breakpoint. |
breakpoint set -n <function> -i <count> | Set a breakpoint with ignore count. |
breakpoint set -n <function> -o true | Set a one-shot breakpoint (deleted after first hit). |
breakpoint set -n <function> -G true | Set a breakpoint that auto-continues after commands. |
breakpoint set -n <function> -t <thread-id> | Set a breakpoint for a specific thread ID only. |
breakpoint set -n <function> -C "expr var" | Set a breakpoint with command to run when hit. |
breakpoint list | List all breakpoints. |
breakpoint delete | Delete all breakpoints. |
breakpoint delete <id> | Delete specific breakpoint by ID. |
breakpoint disable <id> | Disable a specific breakpoint. |
breakpoint enable <id> | Enable a specific breakpoint. |
breakpoint command add <id> | Add commands to execute when a breakpoint is hit. |
Note: Alias: b bp | |
Execution Control#
| Command | Description |
|---|
step/s | Step into the next line or function call. |
next/n | Step over the current line (skips stepping into functions). |
finish | Step out of the current function and return to the caller. |
thread return | Return from the current function without executing the rest. |
continue/c | Resume execution until the next breakpoint or program ends. |
Stack & Frames#
| Command | Description |
|---|
thread backtrace/bt | Display the current thread’s call stack. |
frame info | Show information about the current stack frame. |
frame variable/v | Show all variables in the current frame. |
frame variable <name> | Show a specific variable in the current frame. |
Disassembly#
| Command | Description |
|---|
disassemble | Disassemble the current function. |
disassemble -f | Disassemble from the start of the current frame’s function. |
disassemble -p | Disassemble around the current PC. |
disassemble -n <function> | Disassemble entire contents of the given function name. |
disassemble -a <address> | Disassemble function containing this address. |
disassemble -s <start> -e <end> | Disassemble from start address to end address. |
disassemble -s <start> -c <count> | Disassemble <count> instructions starting at address. |
disassemble --force | Force disassembly of large functions. |
Note: Alias: di dis disas | |
Memory#
| Command | Description |
|---|
memory read <address> | Read memory at a specific address. |
memory read <start> <end> | Read memory from start to end address. |
memory read --binary --outfile <file> <start> <end> | Dump memory to a binary file. |
memory write <address> <value> | Write a value to a specific memory address. |
Watchpoints#
| Command | Description |
|---|
watchpoint set variable <var> | Stop execution when a variable is modified. |
watchpoint set expression -- <address> | Set a watchpoint on an address expression. |
watchpoint set expression -w write -s <size> -- <address> | Watchpoint on write with byte size. |
watchpoint list | List all watchpoints. |
watchpoint delete | Delete all watchpoints. |
Registers#
| Command | Description |
|---|
register read | Show all general-purpose registers. |
register read <reg> | Show a specific register. |
register write <reg> <value> | Write a value to a register. |
Note:
| Argument | Register | x86_64 | arm64 |
|---|
| Return | - | RAX | - |
| First | arg1 | RDI | x0 |
| Second | arg2 | RSI | x1 |
| Third | arg3 | RDX | x2 |
| Fourth | arg4 | RCX | x3 |
| Fifth | arg5 | R8 | x4 |
| Sixth | arg6 | R9 | x5 |
| Syscalls | - | syscall | x16 |
Expressions & Variables#
| Command | Description |
|---|
expr int $delta = 0xb3000 | Define a convenience variable with a value. |
expr $delta | Print the value of a convenience variable. |
expr $delta = 0xc4000 | Update the value of an existing convenience variable. |
expr (int)$delta + 0x1000 | Use a convenience variable in an expression. |
p/d 0x1a | Print a value in decimal format. |
p/x $delta | Print a convenience variable in hexadecimal. |
p/t <value> | Print a value in binary (two’s complement) format. |
po <object> | Print the description of an object (Objective-C/Swift). |
breakpoint set -a $delta+0x1234 | Use a convenience variable in a breakpoint address. |
memory read $delta | Use a convenience variable as a memory address. |
Note: Convenience variables start with $ and persist for the entire debug session.
iOS Remote Debugging#
| Command | Description |
|---|
iproxy 6666 6666 | Forward port 6666 from device to localhost (on host). |
debugserver 127.0.0.1:6666 | Start debugserver on device listening on port 6666. |
frida-server -l 0.0.0.0 & | Start frida-server on device (background). |
See Frida for detailed instructions on using Frida.
| Command | Description |
|---|
platform select remote-ios | Select remote iOS platform for debugging. |
process connect connect://<ip>:<port> | Connect to a remote debug server (e.g., debugserver). |
process connect connect://localhost:6666 | Connect to debugserver running on port 6666 via iproxy |
image list | List all loaded images/modules. |
image dump sections <name> | Dump sections of a specific module. |
image lookup -a <address> | Look up symbol information for a specific address. |
p/x <runtime_address>-0x100000000 | Calculate ASLR slide from runtime base address. |
settings set target.process.stop-on-sharedlibrary-events 1 | Stop when shared libraries are loaded. |
settings set target.process.stop-on-sharedlibrary-events 0 | Don’t stop when shared libraries are loaded. |
LLDBInit Commands#
lldbinit is a Python plugin that adds GDB-like workflows to LLDB: automated context display, register/flag shortcuts, memory patching, anti-anti-debug, and more.
Installation#
# Save lldbinit.py to ~ then add to ~/.lldbinit:
command script import ~/lldbinit.py
# Optional: pip install keystone-engine (for asm commands)
Configuration#
| Variable | Description |
|---|
CONFIG_APPEARANCE | "light" or "dark" color scheme. |
CONFIG_FLAVOR | "intel" (default) or "att" disassembly syntax. |
CONFIG_DISASSEMBLY_LINE_COUNT | Number of instructions in the code window (default: 8). |
CONFIG_DISPLAY_STACK_WINDOW | 1 to show stack dump on stop. |
CONFIG_DISPLAY_DATA_WINDOW | 1 to show data window (set address via datawin). |
Settings & General#
| Command | Description |
|---|
lldbinitcmds | List all available lldbinit commands. |
enable solib | Stop on shared library events. |
enable aslr | Enable ASLR. |
enable stack | Show stack window in context. |
enable data | Show data window in context. |
disable <setting> | Disable a specific setting. |
contextcodesize <n> | Set the number of disassembly lines. |
context / ctx | Manually refresh the context display. |
Breakpoints (lldbinit)#
| Command | Description |
|---|
b <addr> [name] | Set a software breakpoint. Accepts expressions. |
bh <addr> [name] | Set a hardware breakpoint. |
bpt <addr> | Set a temporary breakpoint (deleted after first hit). |
bpn | Set a temporary breakpoint on the next instruction. |
bm <module_path> | Break when a specific module (dylib) is loaded. |
bpl | List all breakpoints with details (ID, Type, Address, Hit Count). |
bpc <id> | Clear a specific breakpoint. |
bpda | Disable all breakpoints. |
bpe <id> | Enable a specific breakpoint. |
Execution Control (lldbinit)#
| Command | Description |
|---|
r [args] | Run the target, stops at entry point. |
stepo | Step over call instructions and loops. |
skip | Skip the current instruction (advance PC without executing). |
antidebug | Hook ptrace, sysctl, exception ports to hide the debugger. |
Memory Dumping & Patching#
| Command | Description |
|---|
db <addr> <size> | Dump memory as bytes. |
dw <addr> <size> | Dump memory as words (2-byte). |
dd <addr> <size> | Dump memory as dwords (4-byte). |
dq <addr> <size> | Dump memory as qwords (8-byte). |
findmem -s "string" | Search memory for an ASCII string. |
findmem -d 0x41414141 | Search memory for a dword value. |
findmem -b 414243 | Search memory for hex bytes. |
nop <addr> [count] | Patch memory with 0x90 (NOP). |
null <addr> [count] | Patch memory with 0x00. |
int3 <addr> | Patch memory with 0xCC (INT3/BRK). |
Register Shortcuts & Flag Toggles#
| Command | Description |
|---|
rax 0x1000 | Set RAX to 0x1000 (works for any register). |
rip $pc+10 | Set RIP relative to current PC. |
x0 0 | Set ARM64 register X0 to 0. |
cfc | Toggle Carry Flag. |
cfz | Toggle Zero Flag. |
cfs | Toggle Sign Flag. |
cfo | Toggle Overflow Flag. |
cfa | Toggle Auxiliary Flag. |
cfp | Toggle Parity Flag. |
cft | Toggle Trap Flag. |
cfd | Toggle Direction Flag. |
cfi | Toggle Interrupt Flag. |
Cracking & Forced Returns#
| Command | Description |
|---|
crack <value> | Set return register (RAX/X0) to <value> and return immediately. |
crackcmd <addr> <value> | Break at <addr>, set return register to <value>, and return. |
crackcmd_noret <addr> <reg> <value> | Break at <addr>, set <reg> to <value>, and continue. |
| Command | Description |
|---|
ss [name] | Save current session (breakpoints, comments) to JSON. |
rs [name] | Restore a previously saved session. |
ls | List available saved sessions. |
acm <addr> <text> | Add a comment at an address in disassembly view. |
dcm <addr> | Delete a comment. |
lcm | List all comments. |
Assembly (Requires Keystone)#
| Command | Description |
|---|
asm32/asm64 | Interactive assembler for x86/x64. |
arm64 | Interactive assembler for ARM64. |
Type instructions line by line. End with stop or end.
| Command | Description |
|---|
show_loadcmds <addr> | Display Mach-O load commands (otool -l). |
show_header <addr> | Display Mach-O header (otool -h). |
LLDBInit Usage Examples#
Bypass a check:
(lldbinit) b 0x100004020
(lldbinit) c
(lldbinit) crack 1 # Force return 1 (True)
Break on library load:
(lldbinit) bm /usr/lib/libSystem.B.dylib
(lldbinit) c
Search memory:
(lldbinit) findmem -s "password"
NOP patch 5 bytes at current PC:
(lldbinit) nop $pc 5
Add comment and save session:
(lldbinit) acm $pc "This is the decryption loop"
(lldbinit) ss my_analysis
Python Scripting#
API Reference#
1. Debugger Setup (SBDebugger)#
The entry point for the debugger API.
| Method/Property | Description |
|---|
lldb.SBDebugger.Initialize() | Initialize the debugger (call once at startup). |
debugger = lldb.SBDebugger.Create() | Create a new debugger instance. |
target = debugger.GetSelectedTarget() | Get the currently selected target. |
debugger.HandleCommand("thread backtrace") | Execute an LLDB command from Python. |
debugger.SetAsync(True) | Enable async mode (useful for scripting flow). |
2. Targets (SBTarget)#
Represents the executable program.
| Method/Property | Description |
|---|
module = target.FindModule(lldb.SBFileSpec("mylib.so")) | Find a loaded module by name. |
process = target.LaunchSimple(None, None, os.getcwd()) | Launch the process with simple arguments. |
target.AttachToProcessWithID(listener, pid, error) | Attach to an existing process by PID. |
bp = target.BreakpointCreateByName("main") | Create a breakpoint by function name. |
bp = target.BreakpointCreateByLocation("main.c", 10) | Create a breakpoint by file and line number. |
bp = target.BreakpointCreateByAddress(0x100000) | Create a breakpoint at a specific address. |
target.DeleteAllBreakpoints() | Delete all breakpoints in the target. |
target.DeleteAllWatchpoints() | Delete all watchpoints in the target. |
target.DeleteBreakpointName("name") | Delete a named breakpoint. |
target.DisableAllBreakpoints() | Disable all breakpoints (returns bool). |
target.DisableAllWatchpoints() | Disable all watchpoints (returns bool). |
target.EnableAllBreakpoints() | Enable all breakpoints (returns bool). |
target.EnableAllWatchpoints() | Enable all watchpoints (returns bool). |
for bp in target.breakpoint_iter() | Iterate over all breakpoints in the target. |
3. Breakpoints (SBBreakpoint)#
Managing logical breakpoints.
| Method/Property | Description |
|---|
bp.SetCondition("x == 5") | Set a condition for the breakpoint. |
bp.SetScriptCallbackFunction("module.function_name") | Set a Python callback function for the breakpoint. |
bp_loc = bp.GetLocationAtIndex(0) | Get a specific breakpoint location. |
bp.SetIgnoreCount(5) | Ignore the breakpoint for the first N hits. |
4. Process & Threads (SBProcess, SBThread)#
Controlling execution state.
| Method/Property | Description |
|---|
state = process.GetState() | Get process state (returns lldb.StateType, e.g., eStateStopped). |
process.Continue() | Resume execution. |
process.Stop() | Stop/pause execution. |
process.Destroy() | Kill the process. |
thread = process.GetSelectedThread() | Get the currently selected thread. |
thread.StepOver() | Step over the current instruction/line. |
thread.StepInto() | Step into the current function call. |
5. Stack Frames & Values (SBFrame, SBValue)#
Inspecting variables and memory.
| Method/Property | Description |
|---|
frame = thread.GetSelectedFrame() | Get the currently selected stack frame. |
val = frame.FindVariable("my_var") | Get a local variable by name. |
val = frame.EvaluateExpression("ptr->field") | Evaluate an expression in the current frame. |
val.GetValue() | Get the value as a string (e.g., "123"). |
val.GetValueAsSigned() | Get the value as a signed integer. |
val.GetTypeName() | Get the type name of the value. |
num_children = val.GetNumChildren() | Get the number of children (e.g., struct fields). |
child = val.GetChildAtIndex(0) | Get a child value by index. |
addr = val.GetAddress() | Get the address of the value. |
load_addr = val.GetLoadAddress() | Get the load address of the value. |
6. Memory (SBProcess, SBData)#
Reading/Writing raw memory.
| Method/Property | Description |
|---|
error = lldb.SBError() | Create an error object for operations. |
content = process.ReadMemory(addr, size, error) | Read memory from an address. |
process.WriteMemory(addr, data_buffer, error) | Write data to a memory address. |
7. Utility Functions#
| Method/Property | Description |
|---|
lldb.SBDebugger.StateIsStoppedState(state) | Check if the process is in a stopped state. |
lldb.SBFileSpec.ResolvePath(path, dst, len) | Resolve a file path. |
Example#
C program to test LLDB Python hooks
#include <stdio.h>
#include <unistd.h>
void secret_function(int value) {
printf("[C Code] Executing secret_function with value: %d\n", value);
}
int main() {
printf("[C Code] Starting program...\n");
for (int i = 0; i < 5; i++) {
secret_function(i * 10);
sleep(1);
}
printf("[C Code] Finished.\n");
return 0;
}
Compile the C code with debug symbols (-g) so LLDB can find the function names.
Python script and its usage
import lldb
def test(debugger, command, result, internal_dict):
target = debugger.GetSelectedTarget()
if not target.IsValid():
result.SetError("No target found. Are you debugging a binary?")
return
# Set breakpoint on the C function 'secret_function'
breakpoint = target.BreakpointCreateByName("secret_function")
if not breakpoint.IsValid():
result.SetError("Failed to create breakpoint on 'secret_function'")
return
# Attach the Python callback function
# Format: 'module_name.function_name'
breakpoint.SetScriptCallbackFunction('test.breakpoint_callback')
result.AppendMessage(f"Breakpoint {breakpoint.GetID()} set on 'secret_function' with callback.")
def breakpoint_callback(frame, bp_loc, internal_dict):
# Example: Get the argument 'value' passed to secret_function
# frame.GetFunction() returns the function, we can look up arguments
val = frame.FindVariable("value")
if val.IsValid():
print(f"\n[Python Hook] Breakpoint hit! Argument 'value' = {val.GetValueAsSigned()}")
else:
print("\n[Python Hook] Breakpoint hit!")
# Return False to continue execution automatically
# Return True to stop execution and give control to the user
return False
def __lldb_init_module(debugger, internal_dict):
# Register the 'test' command in LLDB
debugger.HandleCommand('command script add -f test.test test')
print("[Python] 'test' command loaded. Type 'test' to hook the function.")
% lldb ./demo
[+] Loaded lldbinit
(lldbinit) target create "./demo"
Current executable set to 'demo' (arm64).
(lldbinit) command script import test.py
[Python] 'test' command loaded. Type 'test' to hook the function.
(lldbinit) test
Breakpoint 1 set on 'secret_function' with callback.
(lldbinit) r
Process 15492 stopped
* thread #1, stop reason = signal SIGSTOP
frame #0: 0x00000001000107c0 dyld`_dyld_start
(lldbinit) c
Process 15492 resuming
[C Code] Starting program...
[Python Hook] Breakpoint hit! Argument 'value' = 0
[C Code] Executing secret_function with value: 0
[Python Hook] Breakpoint hit! Argument 'value' = 10
[C Code] Executing secret_function with value: 10
...
Appendix: Disabling SIP#
Some processes on macOS are protected by System Integrity Protection (SIP), which prevents debugging and memory access. To debug these processes, you may need to disable SIP.
error: attach failed: cannot attach to process due to System Integrity Protection
System Integrity Protection (SIP) in macOS protects the entire system by preventing the execution of unauthorized code. The system automatically authorizes apps that the user downloads from the App Store. The system also authorizes apps that a developer notarizes and distributes directly to users. The system prevents the launching of all other apps by default.
During development, it may be necessary for you to disable SIP temporarily to install and test your code. You don’t need to disable SIP to run and debug apps from Xcode, but you might need to disable it to install system extensions, such as DriverKit drivers.
https://developer.apple.com/documentation/security/disabling-and-enabling-system-integrity-protection
Restart your computer in Recovery mode, launch Terminal from the Utilities menu, run the command :
Resources:#