简体   繁体   English

使用调试符号从 ELF 中提取源代码

[英]extract source code from ELF with debug symbols

I'm trying to extract the original source code from an ELF with debug symbols.我正在尝试从带有调试符号的 ELF 中提取原始源代码。

$ sed -n "14,16p" main.c
    for (int p=start;p<end;p++)
        if (isPrime(p))
            printf("%d\n",p);

I want the "closest", preceeding source line from a given address:我想要来自给定地址的“最接近”的源代码行:

$ gcc -g -O0 main.c -o main
$ objdump -D -S main > main.asm
$ sed -n "451,457p" main.asm
        if (isPrime(p))
 6ba:   8b 45 f4                mov    -0xc(%rbp),%eax
 6bd:   89 c7                   mov    %eax,%edi
 6bf:   e8 86 ff ff ff          callq  64a <isPrime>
 6c4:   85 c0                   test   %eax,%eax
 6c6:   74 16                   je     6de <main+0x49>
            printf("%d\n",p);

So given the 0x6bf call instruction, I would like to extract if (isPrime(p)) .因此,鉴于0x6bf调用指令,我想提取if (isPrime(p))

This seems possible since objdump does it (right?)这似乎是可能的,因为 objdump 做到了(对吗?)

It turns out that it can be quite easily done with pyelftools :事实证明,使用pyelftools可以很容易地完成:

import elftools
from elftools.elf.elffile import ELFFile as ELF

def addr_2_line(ELFname: str, addr: int) -> int:
    with open(ELFname, "rb") as fl:
        elf = ELF(fl)
        dwarf_info = elf.get_dwarf_info()
        for cu in dwarf_info.iter_CUs():
            line = 1
            for entry in dwarf_info.line_program_for_CU(cu).get_entries():
                if entry.state:
                    if addr > entry.state.address:
                        line = entry.state.line
                    else:
                        return line
address = addr_2_line("main", 0x6bf)
print(f"src code[ 0x6bf ] = {address}")

When I run it it indeed gives the desired line:当我运行它时,它确实给出了所需的行:

src code[ 0x6bf ] = 15

It is probably worth checking if no adjustments are needed when there are more than just one compilation unit ( cu )这可能是值得一试,如果当有不止一个编译单元(不需要调整cu

I'm trying to extract the original source code from an ELF with debug symbols.我正在尝试从带有调试符号的 ELF 中提取原始源代码。

That's impossible: the ELF with debug symbols contains no original source code.这是不可能的:带有调试符号的 ELF包含原始源代码。

What you appear to be after is source code location , ie file and line.您似乎在追求的是源代码位置,即文件和行。 Armed with file name, line number, and the original source, you can trivially print that line.有了文件名、行号原始来源,您就可以轻松打印该行。

To recover file/line info, you could use addr2line -e main 0x6bf .要恢复文件/行信息,您可以使用addr2line -e main 0x6bf

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM