我有一个十六进制偏移量,比如说0xcccddd。使用gdb info symbol 0xcccdddI 可以获得符号名称,例如fn()在section_name.
如何使用readelf或objdump命令或任何其他命令而不运行 gdb 来执行此操作?
编辑: 使用以下命令后
objdump -d --start-address 0xcccddd --stop-address 0xcccdde filename.axf
Run Code Online (Sandbox Code Playgroud)
我正进入(状态
filename.axf: file format elf32-little
objdump: can't disassemble for architecture UNKNOWN!
Run Code Online (Sandbox Code Playgroud) 通过使用该命令,我发现内存中的objdump地址包含 start the path ,并且由于 C 标准,该路径以一个字节结束。0x02a8/lib64/ld-linux-x86-64.so.20x00
因此,我尝试编写一个简单的 C 程序来打印这一行(我使用了 Denis Yurichev 所著的《RE for Beginners》一书中的示例 - 第 24 页):
#include <stdio.h>
int main(){
printf(0x02a8);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但我很失望地得到了分段错误而不是预期的/lib64/ld-linux-x86-64.so.2输出。
我发现使用这样一个printf不带说明符或至少不带指针转换的“快速”调用很奇怪,所以我尝试使代码更自然:
#include <stdio.h>
int main(){
char *p = (char*)0x02a8;
printf(p);
printf("\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
运行后我仍然遇到分段错误。
我不相信这是因为内存区域受限而发生的,因为在书中,第一次尝试一切都很顺利。我不确定,也许还有那本书中没有提到的事情。
因此,需要一些清晰的解释来解释为什么每次我尝试运行程序时都会发生分段错误。
我正在使用最新的完全升级的 Kali Linux 版本。
现在我正在尝试了解 RISC-V ISA,但我对机器代码和汇编有不清楚的地方。
我写了这样的C代码:
int main() {
return 42;
}
Run Code Online (Sandbox Code Playgroud)
然后,我通过以下命令生成了 .s 文件:
$ /opt/riscv/bin/riscv64-unknown-linux-gnu-gcc -S 42.c
输出是:
.file "42.c"
.option nopic
.text
.align 1
.globl main
.type main, @function
main:
addi sp,sp,-16
sd s0,8(sp)
addi s0,sp,16
li a5,42
mv a0,a5
ld s0,8(sp)
addi sp,sp,16
jr ra
.size main, .-main
.ident "GCC: (g5964b5cd727) 11.1.0"
.section .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)
现在,我运行以下命令来生成一个精灵。
$ /opt/riscv/bin/riscv64-unknown-linux-gnu-gcc -nostdlib -o 42 42.s
这样,就生成了一个二进制文件。我尝试通过 objdump 读取该内容,如下所示:
$ /opt/riscv/bin/riscv64-unknown-linux-gnu-objdump -d 42
所以输出是这样的:
42: file format elf64-littleriscv
Disassembly of section .text:
00000000000100b0 …Run Code Online (Sandbox Code Playgroud) 为了更好地理解ELF格式和ARMaarch64,我尝试在没有编译器的情况下创建我的 elf 二进制文件,只是用 bash 回显字节。
可以在这里看到我的努力: http: //www.github.com/glaudiston/elf
我已经成功地实现了一个完全工作的精灵sys_write和sys_exit系统调用x64。
但对于aarch64,它没有像我预期的那样工作:
# cat make-elf.sh
#!/bin/bash
#
# depends on:
# - elf_fn.sh (github.com/glaudiston/elf)
# - base64 (gnu-coreutils)
#
. elf_fn.sh
instructions="";
instructions="${instructions}\nwrite $(echo -en "hello world\n" | base64 -w0)";
instructions="${instructions}\nexit 3";
write_elf elf "${instructions}";
Run Code Online (Sandbox Code Playgroud)
它生成:
$ xxd elf
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
00000010: 0200 b700 0100 0000 7800 0100 0000 0000 ........x.......
00000020: …Run Code Online (Sandbox Code Playgroud) 我正在测试以确保我的交叉编译器正常工作.当我编译hello world时,似乎编译得很好但是当我将hello.cpp更改为循环1000次的同一程序时,生成的elf文件大小完全相同.无论我做什么改变,文件总是相同的大小,据我所知,具有相同的内容.什么会导致这个?
我有以下要求:查找我的二进制文件是否已更改。
我的源代码未更改。当我重新编译二进制文件时(在源代码中没有更改),我注意到二进制文件已更改。不是大小,而是内容。
稍微调试一下,我发现二进制文件中有一个叫做“链接时间”的东西。这是链接二进制文件时的实际时间戳。现在,由于每次编译都会给出不同的时间戳,因此我的二进制内容总是不同的。但实际上应该是一样的。
有人可以建议我一种方法来找出二进制文件是否确实由于源代码的更改而发生了更改,而不是其他任何更改。
谢谢
我想更改ELF文件中的全局结构.我首先想知道全局变量是否是一个结构?但我看到的唯一信息是变量的名称和大小.
在ELF-header中,value e_ident[EI_CLASS]可以是1或2,表示32位操作或64位操作系统.但是从历史上我们知道ELF首次出现在1993年发布的Solaris 2.0中.然而,广泛使用的32位处理器Pentium Pro直到1995年才出现.那么为什么ELF头没有关于16位甚至是16位的信息8位信息?
默认情况下,所有符号都导出到动态表,那么为什么要使用-rdynamic标志?即使我们通过attribute /隐藏某些符号-fvisibility=hidden- -rdynamic不会更改结果,也不会取消隐藏先前隐藏的符号。那有什么意义呢?