我对这个主题相当陌生,即 ELF 和任何与 Linux 相关的东西。我正在尝试编写 ELF 文件,并且更喜欢在 WinXP 上执行此操作。
我的问题是,这可以用 MS Visual Studio 完成,包括编译吗?据我了解,ELF文件不能在Windows操作系统上编译。好吧,至少这是我在谷歌研究中发现的。我是否必须设置 Linux 操作系统并在那里进行编译?
我可以使用 objdumo(GNU binutils 的一部分)来分析 WindowsXP 上的任何 ELF 文件吗?
非常感谢任何帮助和链接。
如何区分两个二进制文件?
我有一个程序的两个版本,版本 1 和版本 2。我在两个版本之间做了少量更改,但遗憾的是没有定期备份,所以虽然我已经获得了版本 2 的源代码,我只有版本 1 的二进制文件。我需要找出我在两个版本之间究竟更改了什么。我尝试创建两个版本的 objdump,然后使用 diff 来查找更改,但这不起作用,因为偏移量不同,因此 diff 认为几乎每一行都已更改。
例如,一行可能bgez v0,4074d0<daemonize+0xd4>在版本 1 中,bgez v0,4073d4<daemonize+0xd4>在版本 2 中。这些是直接从转储文件中复制的 - 您可以看到这两行执行相同的操作,但 diff 无法区分它们。文件太大了,我无法手动检查每一行;如何检测功能更改,同时忽略偏移差异?
首先,我对这篇文章的篇幅感到抱歉,但我想清楚地解释这个问题.
我尝试在C中编写一种小型自修改程序,但是我遇到了一些麻烦,我不确切知道为什么.
平台是: Ubuntu/Linux 2.6.32-40 x86_64,prog是基于x86 arch,gcc(Ubuntu 4.4.3-4ubuntu5.1)4.4.3,GNU ld(GNU Binutils for Ubuntu)2.20.1-system.20100303
该程序的目的是创建一个读/写/执行内存块(使用memalign(3)和mprotect(2)),复制一个在这块内存中调用p()(在.text段中定义)的小函数,然后执行通过指针复制函数.该p()函数只显示一条消息printf(puts).
为了得到的代码的开始和结束地址p()(以复制),我用的是函数本身的地址和地址dummy()刚过创建功能p()在.text.
int p() { ... } <- address where the copy starts
int dummy() { ... } <- address where the copy stops
Run Code Online (Sandbox Code Playgroud)
成功完成块内存创建和复制,但是当块中的代码运行时,会发生段错误.通过使用gdb它很明显我们输入了块的代码(复制函数的主体),但是对printf的调用失败了.当反汇编p()函数和块中的代码时,我发现'call'中使用的地址不一样.
而且我不知道为什么地址不正确,当代码被复制时它被显示,并且它与objdump(或gdb)在我反汇编p()函数时给我的相同.
创建二进制文件是-static为了避免got/plt …
我正在尝试更多地了解可执行文件的"常见"部分,我注意到objdump在编译代码时,我可以看到只在对象文件(*.o而不是可执行文件)上放置在公共代码中的变量.
这是为什么?
//test.c
int i[1000];
int main(){return 0;}
Run Code Online (Sandbox Code Playgroud)
构建命令:
> gcc -g0 -fcommon -c test.c
> gcc -g0 -fcommon test.c
Run Code Online (Sandbox Code Playgroud)
objdump显示i在符号表的公共部分中:
> objdump -x test.o
...
SYMBOL TABLE:
...
00000fa0 O *COM* 00000020 i
Run Code Online (Sandbox Code Playgroud)
除非我在可执行文件上运行它:
> objdump -x a.out
...
SYMBOL TABLE:
...
0804a040 g O .bss 00000fa0 i
Run Code Online (Sandbox Code Playgroud)
如果我使用-fno-common标志重建目标文件,而不是.bss像在可执行文件上那样显示在段中.最终的可执行文件没有这个"COMMON"部分吗?
我无法objdump在 IBM AIX 5.1 机器中找到命令。实际上我想从 AIX 中生成的库中获取汇编指令(反汇编)。Linux 有objdump命令和solarisdis命令可以执行此操作。IBM AIX 中的等效命令是什么?
我在 linux 发行版中工作。我正在编写一个 C/C++ 程序,它需要一个编译二进制(可执行文件)的源文件列表。当然,我使用带有 -g 标志的 GCC 编译了二进制文件。使用gdb我发现二进制文件的格式是 DWARF2:
(gdb) info source
Current source file is src/main.cpp
Compilation directory is /path/to/source
Located in /path/to/source/src/main.cpp
Contains 43 lines.
Source language is c++.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
Run Code Online (Sandbox Code Playgroud)
使用objdump或elfread我看到了我需要的信息:
bash> objdump -W binary
...
The File Name Table:
Entry Dir Time Size Name
1 1 0 0 main.cpp
2 2 0 0 curses.h
3 3 0 0 tprint.h …Run Code Online (Sandbox Code Playgroud) 我有一个精灵臂aarch64二进制文件,我想使用objdump拆解它.text节。我的机器是amd64。
我尝试将objdump用于ARM体系结构:反汇编为ARM,但是objdump不能识别二进制文件,因此无法反汇编它。
我正在使用 objdump 来生成 C 代码的反汇编,并想知道是否有办法从堆(.bss 部分)中获取变量名称以用于 .text 部分反汇编,而不是十六进制地址。
例如,
int main(void)
{
while (1)
{
request_ID = Receive(0, buffer, MSG_SIZE, 0);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是编译的,然后使用objdump -D file.o我得到反汇编,包括 .bss 部分:
400: 55 push ebp
401: 89 e5 mov ebp,esp
403: 83 ec 18 sub esp,0x18
...
43d: a1 cc 24 00 00 mov eax,ds:0x24cc
...
Disassembly of section .bss:
000024cc <request_pID>:
Run Code Online (Sandbox Code Playgroud)
我想要的是将变量的十六进制地址替换为它们的名称:
43d: a1 cc 24 00 00 mov eax, <request_pID>
Run Code Online (Sandbox Code Playgroud)
我可以编写一个 sed 脚本或类似的东西来实现这一点,但想知道是否有更简单的选择。
更好的是同时打印地址和变量名称以帮助调试。
43d: a1 cc …Run Code Online (Sandbox Code Playgroud) 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) GNU汇编程序似乎有一些方法可以控制为某些指令发出的操作码的替代形式.例如
.intel_syntax noprefix
mov eax, ecx
mov.s eax, ecx
Run Code Online (Sandbox Code Playgroud)
处理上面的代码as test.s -o test.o && objdump -d test.o -M intel给出了以下反汇编:
0: 89 c8 mov eax,ecx
2: 8b c1 mov eax,ecx
Run Code Online (Sandbox Code Playgroud)
我们可以看到.s后缀似乎将89操作码切换到8b版本(并适当地更改了ModRM字节).
这种语法在GAS中如何工作?我找不到任何相关文件.