我没有成功找到这个问题的答案.
使用GDB,我可以使用命令"call"来获取函数的原型.例:
(gdb) call fn
$1 = {void (int, int)} 0x8048414 <fn>
Run Code Online (Sandbox Code Playgroud)
因此,GDB只能从elf文件中找出fn()返回void并将两个整数作为参数.
但是,我需要使用其他一些工具从elf文件中提取函数原型.最好,我想使用objdump/readelf.
有谁知道这是否可能?如果不可能,GDB如何做到这一点?elf文件的哪个部分是存储的函数原型?
register_tm_clones并且deregister_tm_clones正在引用我的RW部分末尾的内存地址.这个记忆是如何被追踪的?
示例:在下面的示例中deregister_tm_clones引用了内存地址0x601077,但是我们分配的最后一个RW部分,.bss从0x601069并且具有大小开始0x7,我们得到了0x601070.所以引用显然是过去为该.bss部分分配的,应该在我们的堆空间中,但谁在管理它.
objdump -d main
...
0000000000400540 <deregister_tm_clones>:
400540: b8 77 10 60 00 mov $0x601077,%eax
400545: 55 push %rbp
400546: 48 2d 70 10 60 00 sub $0x601070,%rax
40054c: 48 83 f8 0e cmp $0xe,%rax
...
readelf -S main
...
[25] .data PROGBITS 0000000000601040 00001040
0000000000000029 0000000000000000 WA 0 0 16
[26] .bss NOBITS 0000000000601069 00001069
0000000000000007 0000000000000000 WA 0 0 …Run Code Online (Sandbox Code Playgroud) 我知道ELF文件中虚拟地址和文件偏移量之间的关系
VirtAddr = Offset + k * Allin
Run Code Online (Sandbox Code Playgroud)
我知道这是由于页面尺寸(x86 架构中的 0x1000)造成的。第一个问题:
继续,如果我尝试readelf -lW /bin/ls,我会获得以下信息:
Elf file type is DYN (Shared object file)
Entry point 0x56d0
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x0001f8 0x0001f8 R E 0x8
INTERP 0x000238 0x0000000000000238 0x0000000000000238 0x00001c 0x00001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x01e4e8 0x01e4e8 R E 0x200000
LOAD 0x01f390 …Run Code Online (Sandbox Code Playgroud) nm -D /lib32/libc.so.6 | grep '\<fopen\>'
0005d0c0 T fopen
00109750 T fopen
readelf -s /lib32/libc.so.6 | egrep '0005d0c0|00109750'
181: 0005d0c0 50 FUNC GLOBAL DEFAULT 12 fopen@@GLIBC_2.1
182: 00109750 136 FUNC GLOBAL DEFAULT 12 fopen@GLIBC_2.0
679: 0005d0c0 50 FUNC GLOBAL DEFAULT 12 _IO_fopen@@GLIBC_2.1
680: 00109750 136 FUNC GLOBAL DEFAULT 12 _IO_fopen@GLIBC_2.0
Run Code Online (Sandbox Code Playgroud)
这是我的问题:
为什么/lib32/libc.so.6中有两个fopen符号?应禁止同一目标文件中的相同符号,对吗?
为什么readelf -s转出fopen @@ GLIBC_2.1和fopen@GLIBC_2.0而不是fopen?
谢谢
我正在编写一个脚本,用于提取二进制文件中的所有函数(由用户编写).
以下shell脚本提取我的函数名称以及以__开头的一些库函数
readelf -s ./a.out | gawk '
{
if($4 == "FUNC" && $3 != "0" && $7 == "13" && $8 != "main") {
print "b " $NF; //***Updated
}
}' &> function_names;
Run Code Online (Sandbox Code Playgroud)
function_names文件的输出:
b __libc_csu_fini
b PrintDivider
b PrintFooter
b __libc_csu_init
b PrintHeader
Run Code Online (Sandbox Code Playgroud)
我想只提取我的功能.那么如何检查函数名称是否以__开头,否则任何其他替代品也会高度评价.
更新::
@djf解决方案工作正常.如果.c编译的文件也可能包含以__?开头的函数怎么办?在那种情况下,如何区分?
我正在做一个项目,我们的验证测试脚本需要在被测试的软件构建中定位符号地址。这可能用于设置断点或从内存中读取静态数据。我所追求的是创建一个包含符号名称、内存中的基址和大小的映射文件。我们的构建输出一个包含我想要的信息的 ELF 文件。我一直在尝试使用readelf、nm 和 objdump工具来尝试获取我需要的符号地址。
我最初尝试过readelf -s file.elf,这似乎访问了一些符号,尤其是那些用汇编程序编写的符号。然而,我想要的许多符号都不在那里——特别是那些源自我们 Ada 代码的符号。
我曾经readelf --debug-dump file.elf转储所有调试信息。从中我确实看到了所有符号,包括那些在 Ada 代码中的符号。但是,格式似乎是 DWARF 格式。有谁知道为什么当我要求它列出符号信息时 readelf 不会输出这些符号?也许只是我缺少一个选项。
现在我可以麻烦地编写一个自定义 DWARF 解析器来获取信息,但是如果我可以使用 Binutils(nm、readelf、objdump)之一来获取它,那么我真的更喜欢标准解决方案。
问题场景:简单来说,我们是否有一个Trace32命令从加载到目标的ELF文件中读取符号(及其内容)?我们有这种特殊情况,其中ELF文件的特定于应用程序的调试符号是ELF中'.noload'部分的一部分,这意味着符号/内容是ELF文件的一部分(使用readelf -a xxxx读取时可用). elf_file_name)但不是生成的最终二进制图像的一部分,即ELF文件中的'.noload'部分在生成闪存到目标内存的xxx.bin时被剥离.
任何输入:
- 我需要一个trace32命令的帮助,该命令可以直接读取ELF文件中的符号内容而不是目标内存.
- 还不确定我是否可以在练习脚本中使用'readelf'?如果我们对上述查询没有任何解决方案,可以在这方面提供帮助吗?
例如:
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_producer : (indirect string, offset: 0xe): GNU C1
1 5.4.0 20160609 -masm=intel -m32 -mtune=generic -march=i686 -g -fst
ack-protector-strong
<10> DW_AT_language : 12 (ANSI C99)
<11> DW_AT_name : (indirect string, offset: 0xbe): hell
o.c
<15> DW_AT_comp_dir : (indirect string, offset: 0x97): /tmp
<19> DW_AT_low_pc : 0x804840b
<1d> DW_AT_high_pc : 0x2e
<21> DW_AT_stmt_list : 0x0
<1><25>: Abbrev Number: 2 (DW_TAG_base_type)
<26> DW_AT_byte_size : 4
<27> DW_AT_encoding : 7 (unsigned)
<28> DW_AT_name : (indirect string, offset: …Run Code Online (Sandbox Code Playgroud) 这是一个非常简单的 C++ 程序:
// main.cpp
int main() {}
Run Code Online (Sandbox Code Playgroud)
我Makefile生成以下命令来编译程序。
? make
g++ -O0 -fverbose-asm -o main main.cpp
Run Code Online (Sandbox Code Playgroud)
我检查命令file以查看它是一个 ELF 可执行文件:
? file main
main: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=921d352e49a0e4262aece7e72418290189520782, for GNU/Linux 3.2.0, not stripped
Run Code Online (Sandbox Code Playgroud)
一切似乎都很好,直到我尝试检查 ELF 标头:
? readelf -e main
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
...
Type: DYN …Run Code Online (Sandbox Code Playgroud) 我正在对这个简单的 C++ 程序的二进制文件进行一些修改,以了解 ELF 的程序头:
\n\nint main(){ }\nRun Code Online (Sandbox Code Playgroud)\n\n编译为:
\n\n\xe2\x9d\xaf make\ng++ -O0 -fverbose-asm -no-pie -o main main.cpp\nRun Code Online (Sandbox Code Playgroud)\n\n我曾经readelf -l main得到以下信息:
Elf file type is EXEC (Executable file)\nEntry point 0x401020\nThere are 11 program headers, starting at offset 64\n\nProgram Headers:\n Type Offset VirtAddr PhysAddr\n FileSiz MemSiz Flags Align\n PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040\n 0x0000000000000268 0x0000000000000268 R 0x8\n INTERP 0x00000000000002a8 0x00000000004002a8 0x00000000004002a8\n 0x000000000000001c 0x000000000000001c R 0x1\n [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]\n LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000\n 0x00000000000004c0 0x00000000000004c0 R …Run Code Online (Sandbox Code Playgroud)