我正在研究一个实用程序,它需要将十六进制地址解析为二进制内的符号函数名和源代码行号.该实用程序将在x86上的Linux上运行,但它分析的二进制文件将用于基于MIPS的嵌入式系统.MIPS二进制文件采用ELF格式,使用DWARF作为符号调试信息.
我目前正计划派生objdump,传入十六进制地址列表并解析输出以获取函数名称和源行号.我已经编译了一个支持MIPS二进制文件的objdump,它正在工作.
我更喜欢有一个软件包,允许我从Python代码本地查找内容而不需要另外的进程.我在python.org上找不到libdwarf,libelf或libbfd,也没有提到dwarfstd.org上的python.
某处有合适的模块吗?
如果在w/gcc的不同时间构建相同的代码,则生成的二进制文件将具有不同的内容.好吧,我对此并不狂热,但事实就是如此.
但是,我最近遇到的情况是,使用相同版本的gcc构建的相同代码生成的二进制文件大小与先前版本不同(大约1900字节).
有谁知道可能导致这些情况的原因是什么?这是某种ELF问题吗?是否有任何工具(除了ldd)可用于转储二进制文件的内容以查看究竟有什么不同?
提前致谢.
我有一个系统"fsimage.so"需要mkdirp,它恰好存在于libgen.so中.但fsimage.so不知道这一点.例如:
# ldd /usr/lib/python2.4/vendor-packages/fsimage.so
libfsimage.so.1.0 => /usr/lib/libfsimage.so.1.0
libxml2.so.2 => /lib/libxml2.so.2
libgcc_s.so.1 => /usr/sfw/lib/libgcc_s.so.1
libpthread.so.1 => /lib/libpthread.so.1
libz.so.1 => /lib/libz.so.1
libm.so.2 => /lib/libm.so.2
libsocket.so.1 => /lib/libsocket.so.1
libnsl.so.1 => /lib/libnsl.so.1
libc.so.1 => /lib/libc.so.1
libmp.so.2 => /lib/libmp.so.2
libmd.so.1 => /lib/libmd.so.1
# ./test
Traceback (most recent call last):
File "./test", line 26, in ?
import fsimage
ImportError: ld.so.1: isapython2.4: fatal: relocation error: file /usr/lib/python2.4/vendor-packages/fsimage.so: symbol mkdirp: referenced symbol not found
# LD_PRELOAD=/usr/lib/libgen.so ./test
Usage: ./test
Run Code Online (Sandbox Code Playgroud)
当然,如果我有源等,我可以简单地再次链接它,并添加"-lgen",它将添加libgen.so作为依赖.
但作为hackery的练习,说我没有任何资源,只是想添加fsimage.so还需要加载libgen.so.使用elfedit/objcopy等,这是不可能的?我不认为我可以使用"ld"来使用.so作为输入,并用额外的库写一个新的.so?
# elfdump /usr/lib/python2.4/vendor-packages/fsimage.so|grep NEEDED
[0] NEEDED 0x5187 …Run Code Online (Sandbox Code Playgroud) objdump如何计算精灵部分的物理地址(LMA)?据我所知,elf节头只包含节[1]的虚拟地址(VMA).
通常,VMA和LMA是相同的.但对于初始化数据段(.data),VMA是变量的RAM位置,LMA是初始值所在的ROM位置.Crt0负责在调用main()之前将初始值复制到RAM中.例如:
$ objdump -h my.elf
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0003c3d0 00080000 00080000 00010000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
5 .data 000008d0 40000000 000d08d4 00060000 2**3
CONTENTS, ALLOC, LOAD, DATA
Run Code Online (Sandbox Code Playgroud)
-Tom
我将从最终的问题开始:在C中使用gcc,是否可以获得__func__(或等效地__FUNCTION__)存储在除.rodata(或其中任何-mrodata=点)或子部分之外的部分的值(?)?
完整的解释:
假设我有一个记录宏:
#define LOG(fmt, ...) log_internal(__FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
(##当且仅当__VA_ARGS__列表为空时,在该一元上下文中使用的字符串连接运算符使用前面的逗号,从而允许使用带或不带参数的格式字符串.)
然后我可以正常使用宏:
void my_function(void) {
LOG("foo!");
LOG("bar: %p", &bar);
}
Run Code Online (Sandbox Code Playgroud)
可能打印(显然取决于实施log_internal):
foo.c:201(my_function) foo!
foo.c:202(my_function) bar: 0x12345678
Run Code Online (Sandbox Code Playgroud)
在这种情况下,格式字符串("foo"和"bar: %p")和预处理程序字符串("foo.c"和"my_function")是匿名只读数据,它们会.rodata自动放入该部分.
但是我说他希望他们去另一个地方(我在一个嵌入式平台上运行几乎所有来自RAM的速度,但内存限制正在推动将一些东西转移到ROM中).移动__FILE__和格式字符串"简单" :
#define ROM_STR(str) (__extension__({static const __attribute__((__section__(".rom_data"))) char __c[] = (str); (const char *)&__c;}))
#define LOG(fmt, ...) log_internal(ROM_STR(__FILE__), __LINE__, __func__, ROM_STR(fmt), ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
你不能放一个__attribute__匿名字符串,所以 …
我正在寻找解释.dynsymELF可执行文件的动态符号表().我可以.symtab使用该value属性成功解释符号表(每个符号16个字节),以表示符号和name属性的地址,以表示.strtab段中字符串开头的偏移量.但是我无法.dynsym使用相同的方法解释动态符号表().我用阿里的博客[1]作为参考.
我查看了Ali的另一个博客[2],但我不明白如何使用哈希表来解释动态符号表.显然,它与符号表使用的映射不同.我该如何解释动态符号表(.dynsym)?
另外,我正在查看的ELF可执行文件有两个部分,即.hash和.gnu.hash.我在哪个部分引用哈希值?
[1] http://blogs.oracle.com/ali/entry/inside_elf_symbol_tables
[2] http://blogs.oracle.com/ali/entry/gnu_hash_elf_sections
出于各种目的,我试图在不解析的情况下获取主可执行文件的ELF头的地址/proc/self/maps.我尝试解析/ functions link_list给出的链,但它们不包含指向主可执行文件基址的条目.有没有办法做到这一点(标准与否)没有解析?dlopendlinfol_addr/proc/self/maps
我正在尝试做的一个例子:
#include <stdio.h>
#include <elf.h>
int main()
{
Elf32_Ehdr* header = /* Somehow obtain the address of the ELF header of this program */;
printf("%p\n", header);
/* Read the header and do stuff, etc */
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我在Ubuntu-Linux 11.10的平台上开发了一个小型的cpp程序.现在我想对它进行逆向工程.我是初学者.我使用这样的工具:GDB 7.0,hte编辑器,hexeditor.
这是我第一次轻松搞定.在符号信息的帮助下,我创建了主要功能的地址,并完成了我需要的一切.然后我条纹(--strip-all)可执行的elf文件,我有一些问题.我知道main这个程序中的函数从0x8960开始.但我不知道如果没有这方面的知识我怎么能找到这一点.我试着调试一步用gdb我的程序一步,但它进入 __libc_start_main
然后进入ld-linux.so.3(所以,它找到并加载一个程序运行所需的共享库).我调试了大约10分钟.当然,可能在20分钟内我可以到达主要功能的切入点,但似乎更容易存在.
如何在main没有任何符号信息的情况下找到函数的入口点?在gdb的帮助下,您能否通过elf文件的逆向工程向我推荐一些好的书籍/网站/ other_sources?任何帮助,将不胜感激.
在某些目标文件上有objdump的输出:
$ objdump -h main.o
main.o: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000000b 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00000000 00000000 00000040 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000040 2**2
ALLOC
3 .note.GNU-stack 00000000 00000000 00000000 00000040 2**0
CONTENTS, READONLY, CODE
Run Code Online (Sandbox Code Playgroud)
这些标志CONTENTS,ALLOC,LOAD等是什么意思?
我从http://newlib.sourcearchive.com/documentation/1.18.0/init_8c-source.html查看了__libc_init_array的源代码.
但我不太明白这个功能是做什么的.
我知道这些符号
/* These magic symbols are provided by the linker. */
extern void (*__preinit_array_start []) (void) __attribute__((weak));
extern void (*__preinit_array_end []) (void) __attribute__((weak));
extern void (*__init_array_start []) (void) __attribute__((weak));
extern void (*__init_array_end []) (void) __attribute__((weak));
extern void (*__fini_array_start []) (void) __attribute__((weak));
extern void (*__fini_array_end []) (void) __attribute__((weak));
Run Code Online (Sandbox Code Playgroud)
在链接描述文件中定义.
链接器脚本的一部分可能如下所示:
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN …Run Code Online (Sandbox Code Playgroud)