mavenor
mavenor

Reputation: 338

How to (re)name a stripped (unnamed) LLDB symbol?

TL;DR

I’m trying to debug a binary that’s been stripped, thus missing symbol names for some procedures. Is there some way I can — even if only for the session — name particular unnamed/stripped procedures for debugging convenience?

Re-compiling the binary with those symbols (and even perhaps debug information) is not an option.


In More Detail...

When LLDB imports an image, it seems to automatically name all procedures that are absent from the symbol table with a ___lldb_unnamed_symbolXXX[1], where XXX is the symbol index, in numerically increasing order of (runtime) load address. When printing the symbol table of a binary with im dump symt <image>, LLDB labels these auto-named procs as Synthetic Symbols[2].

I’d like to be able to tag these Synthetic Symbols with specific names somehow — even if temporarily, only for the duration of the LLDB debug session; I want to be able to use the name functionally too, e.g. setting breakpoints with br set -n myRenamedProc -s myBinary. Importantly, I want the name to be displayed in place of the synthetic auto-generated name (i.e. ___lldb_unnamed_symbolXXX). So ideally, instead of a solution that substitutes the existing auto-generated name on-the-fly, it would be nice to replace it.

Related Questions

N.B.: Unlike in this post and this one, neither do I remember what the original methods were called, nor do I wish to use the original names in any way. In this post the OP suggests that they may want to achieve something similar to what I want — an alias to an existing symbol — as a prospective solution to another underlying issue, but it remains unexplored. Besides, I want the name to reflect, not just be a functional alias; i.e., I’m looking to replace the unhelpful ___lldb_unnamed_symbolXXX name so that references to the procedure (e.g. when printing disassembled instructions with di, or the name shown in the backtrace) then use the new name.
Had it not been for this requirement, the solution in this post makes for good aliases using function pointers.

Example

Here’s an excerpt from the LLDB-reported symbol-table of the binary in question:

(lldb) im dump symt firmwarepasswd
Symtab, file = <path-to-my-binary>, num_symbols = 68:
               Debug symbol
               |Synthetic symbol
               ||Externally Visible
               |||
Index   UserID DSX Type            ... Name
------- ------ --- --------------- ... ----------------------------------
...
[   42]     42  S  Code            ... ___lldb_unnamed_symbol42
...

I’d like to be able to rename ___lldb_unnamed_symbol42 to, e.g., WriteEfiVariable.

I’m aware that more sophisticated debugging/disassembly tools like IDA Pro and Hopper — both freemium pieces of software — are capable of doing this, but I couldn’t find anything relevant for LLDB. Although an LLDB solution is preferred, any solution with a FOSS (debugger) tool works too. Maybe this is trivial in GDB and I need to switch?


Context & Environment
  • The executable in question was originally written in Objective-C, its source code has since been misplaced. This post should also be just as valid for C/C++ files as well, though.
  • lldb-1400.0.38.17 (LLVM/clang 14.0.0, clang-1400.0.29.51 from Xcode 14.2)
  • macOS Monterey 12.7.4
References
  1. Another SO question about unnamed LLDB symbols in iOS apps.
  2. LLDB output of any image dump symtab (I tried, but in vain to find relevant LLDB documentation on this).

Upvotes: 0

Views: 226

Answers (1)

Jim Ingham
Jim Ingham

Reputation: 27110

lldb doesn't currently have a user-customizable symbol name substitution feature. There's no reason it couldn't, but no one has needed this enough to add it. You can use some of lldb's scripting affordances to add this for various use cases.

For backtraces, you can use the fact that the frame-format setting is customizable, and you can add elements implemented in Python. So you could remove the ${function.name-with-args} token from your frame-format setting and replace it with a ${script.frame:my_translator:translate}, and in that translate function do the name replacement:

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

You could also make your own python wrapper for disassemble that consults your lookup table first, and then sends the un-cooked name to the actual disassemble command:

https://lldb.llvm.org/use/python-reference.html#create-a-new-lldb-command-using-a-python-function

BTW, if someone were motivated to try adding this to lldb, it would be pretty straightforward to add a function_name() API to the frame recognizer infrastructure in lldb. Then you could register the recognizer for the ___lldb_unnamed_symbol name, and replace it with the known one.

Upvotes: 1

Related Questions