如何解读二进制文件Dump?并定位指定源码行的汇编指令
Alright, let's tackle these two questions step by step—they're core skills for digging into kernel module binaries and their source code mappings.
Let's break down a typical objdump output line to make sense of every part:
Each line follows this structure:
[address]: [machine code bytes] [assembly instruction] [optional symbol reference/comment]
Here's what each component means:
- Address: The relative offset within the kernel module where this instruction lives. Since modules load dynamically at runtime, this isn't a fixed physical/virtual address—just a position in the binary file.
- Machine Code Bytes: The raw hex values the CPU executes directly. These are the bytes you'd modify if patching the binary.
- Assembly Instruction: The human-readable translation of the machine code, using AT&T syntax (the default for objdump on x86_64).
- Symbol Reference: If the instruction calls a function, references a variable, or uses a named constant, objdump will show the symbol name (e.g.,
<usb_control_msg>for a function call) to clarify context.
For example, a line like this:
0000000000001abc: b8 03 00 00 00 mov $0x3,%eax
Means: at offset 0x1abc in the module, the CPU runs a mov instruction that loads the hex value 0x3 into the %eax register.
Additional tips for kernel modules:
- Look for function labels like
<acm_open>:to locate the start of a function from your source code. *UND*markers indicate undefined symbols (like kernel functions the module depends on) that get resolved when the module loads.- If you compiled the module with debug symbols (
-gflag), useobjdump -S cdc-acm.koto see source code interleaved with assembly—this drastically simplifies interpretation.
val = ACM_CTRL_DTR | ACM_CTRL_RTS; Here's a practical, step-by-step method to map that source line to its assembly instructions:
Step 1: Calculate the combined constant value
First, check the definitions of ACM_CTRL_DTR and ACM_CTRL_RTS in your source/header files. For example, they’re typically defined as:
#define ACM_CTRL_DTR 0x1 // Data Terminal Ready #define ACM_CTRL_RTS 0x2 // Request To Send
Their bitwise OR is 0x1 | 0x2 = 0x3—this is the value we’ll hunt for in the disassembly.
Step 2: Locate the function containing the source line
The line val = ACM_CTRL_DTR | ACM_CTRL_RTS; is almost certainly inside the acm_open function (standard for CDC-ACM device initialization). Find the start of this function in the objdump output by looking for the label <acm_open>:.
Step 3: Find the instruction using the combined value
Scan the assembly inside <acm_open> for any instruction that uses 0x3. The exact form depends on compiler optimizations:
- No optimization (
-O0):valwill be stored on the stack, so you’ll see something like:
This moves0000000000001abc: c7 45 fc 03 00 00 00 movl $0x3,-0x4(%rbp)0x3into the stack position-0x4(%rbp), which corresponds to thevalvariable. - Optimizations enabled (
-O2): The compiler may skip storingvalon the stack and pass the value directly to the next function call. For example:
Here,0000000000001abd: ba 03 00 00 00 mov $0x3,%edx%edxholds the value for the subsequentusb_control_msgcall (which usesvalas an argument).
Step 4: Verify with debug symbols (the easiest shortcut)
If you have the module compiled with debug symbols, run this command to see the source line directly paired with its assembly:
objdump -S cdc-acm.ko | grep -A 5 -B 5 "ACM_CTRL_DTR"
You can also use gdb: load the module and source code, run list acm_open to locate the line, then disassemble /m acm_open to view the mixed source-assembly output.
内容的提问来源于stack exchange,提问作者Igor Liferenko

