iosdebuggingreverse-engineeringlldbdisassembly

Disassembly view in Xcode: how can I symbolicate a function's address?


In Xcode, I set a breakpoint to a function which is a part of an iOS framework and the disassembly view showed up. All function calls except one (0x1bb286280) were symbolicated (i.e. Xcode showed the name of the function which is being called). How come Xcode wasn't able to look up the name of the function?

I suspect that the strings were stripped from the dynamic library which contains the function 0x1bb286280.

How can I at least tell which dynamic library is loaded into the portion of memory at 0x1bb286280?

I tried to disassemble the respective library in Hopper, but it also didn't symbolicate the function 0x1bb286280. Can Hopper show which dylib is that function a part of? When going through the binary in Hopper, I couldn't find the memory address 0x1bb286280.

Stepping into the function 0x1bb286280 in LLDB inside Xcode and then running thread backtrace when inside 0x1bb286280 in the LLDB console doesn't show any module/dylib (meanwhile all other frames in the stack trace do show which dylib it is a part of). I do only see * frame #0: 0x00000001bb286280 with no additional symbols after it.

Snippet of the disassembly from Xcode:

mov    x0, x8
bl     0x1b6fa47ac               ; symbol stub for: dispatch_sync
ldur   x8, [x29, #-0x28]
ldr    w19, [x8, #0x18]
sub    x0, x29, #0x30
mov    w1, #0x8                  ; =8 
bl     0x1bb286280               ; How do I symbolicate this function?

Solution

  • The lldb command image lookup -va <address> will tell you everything that lldb knows about that address, including what image & what section in the image contains it. It most likely can't tell you anything more.

    lldb prints the PC for the symbol in the current process (the "load address"), but that's not usually the address of the symbol in its binary image, since most libraries are slid to a new location during loading. The image lookup output above will also show you the "file address" in the binary. If you are feeding binary images (not processes) to some other tool, you need to use the file address, not the load address.

    You could also adjust the frame-format setting to always show the module.file.basename element. The default format only prints it if it can find some kind of name or name with offset in it which is why you aren't seeing it in the backtrace.

    That's probably not the most useful format, it's probably worth printing the image the symbol is contained in even if we know nothing else about it. This is fairly uncommon since if there were any symbol before this address in the image, lldb would have rendered this as that symbol plus an offset, and that would have triggered adding the module info as well. But in your case it looks like there isn't a symbol before this address... So likely no one noticed this. Feel free to file an issue report here:

    https://github.com/llvm/llvm-project/issues?q=is%3Aissue%20state%3Aopen%20label%3Alldb

    More info on how the frame-format setting works is given here:

    https://lldb.llvm.org/use/formatting.html