Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joshenders/ae6928ae9b34f6383ad13648eb2369d8 to your computer and use it in GitHub Desktop.
Save joshenders/ae6928ae9b34f6383ad13648eb2369d8 to your computer and use it in GitHub Desktop.
Importing Hand-Rolled C Header Files in LLDB

Importing Hand-Rolled C Header Files in LLDB

Scenario

  • We're debugging a dylib, libhello.dylib
  • The dylib is linked from hello
  • The exported function is helloworld()
  • We do not have source, but have reversed a struct from the library and created a hand-crafted header file

Header File

/* my-reversed-header.h */
struct hellostruct
{
    int what_is_this;
    char *some_string_i_think;
};

Module Map

We create a module map referencing the header file. This is a clang thing:

module mycustom {
    header "my-reversed-header.h"
}

Import Module in lldb

Put your .h file where the module map can find it, e.g., in the same directory.

$ ls -l hello modules/
-rwxr-xr-x  1 zach  staff  12564 Dec 11 13:32 hello*

modules/:
total 16
-rw-r--r--  1 zach  staff  49 Dec 11 14:31 module.map
-rw-r--r--  1 zach  staff  77 Dec 11 13:37 my-reversed-header.h

Steps

  1. Open target binary in lldb
lldb ./hello
(lldb)
  1. Before launching the process, set target.clang-module-search-paths to the directory with your module map & custom .h file
(lldb) settings set target.clang-module-search-paths "./modules"
  1. Set breakpoints wherever
(lldb) breakpoint set -n main
Breakpoint 1: where = hello`main, address = 0x0000000100000f60
(lldb) r
Process 6239 launched: '/Users/zach/example/hello' (x86_64)
Process 6239 stopped
...
(lldb) disas -n helloworld
libhello.dylib`helloworld:
    0x100108f40 <+0>:  push   rbp
    0x100108f41 <+1>:  mov    rbp, rsp
    0x100108f44 <+4>:  sub    rsp, 0x20
    0x100108f48 <+8>:  mov    rax, qword ptr [rip + 0xb9]
    0x100108f4f <+15>: mov    qword ptr [rbp - 0x10], rax
    0x100108f53 <+19>: mov    rax, qword ptr [rip + 0xb6]
    0x100108f5a <+26>: mov    qword ptr [rbp - 0x8], rax
    0x100108f5e <+30>: mov    rsi, qword ptr [rbp - 0x8]
    0x100108f62 <+34>: lea    rdi, [rip + 0x41]         ; "%s\n"
    0x100108f69 <+41>: mov    al, 0x0
    0x100108f6b <+43>: call   0x100108f7e               ; symbol stub for: printf
    0x100108f70 <+48>: mov    ecx, dword ptr [rbp - 0x10]
    0x100108f73 <+51>: mov    dword ptr [rbp - 0x14], eax
    0x100108f76 <+54>: mov    eax, ecx
    0x100108f78 <+56>: add    rsp, 0x20
    0x100108f7c <+60>: pop    rbp
    0x100108f7d <+61>: ret

(lldb) breakpoint set -a 0x100108f62
Breakpoint 2: where = libhello.dylib`helloworld + 34, address = 0x0000000100108f62
(lldb) c
Process 10195 resuming
Process 10195 stopped
...
(lldb)
  1. At any point, do @import module_name
(lldb) p *(struct hellostruct*)($rbp-0x10)
error: incomplete type 'struct hellostruct' where a complete type is required
forward declaration of 'hellostruct'
(lldb) expr @import mycustom
  1. Types defined in the .h file are now available to lldb
(lldb) p *(struct hellostruct*)($rbp-0x10)
(struct hellostruct) $0 = (what_is_this = 0, some_string_i_think = "hello world")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment