对于C中的全局变量
int aglobal = 5;
什么时候5被加载器转移到aglobal,它如何知道将5放入全局.
与函数中的静态声明相同的情况.喜欢
int afunc(){static int astatic = 8; 回归; }
我正在寻找一种简单的方法来重新排序ELF文件部分.我有一系列自定义部分,我希望所有部分按特定顺序对齐.
我发现如何做到这一点的唯一方法是使用链接器脚本.但是,文档指出指定自定义链接描述文件会覆盖默认值.默认的链接描述文件中包含很多内容,我不想在自定义脚本中复制只是为了让三个部分按特定顺序排在一起.对链接器行为进行硬编码似乎不太灵活.
我为什么要这样做?我有一段数据需要知道(开始和结束)的运行时内存位置.所以我创建了两个额外的部分并将sentinel变量放入其中.然后,我想使用这些变量的内存位置来了解内存中未知部分的范围.
.markerA
int markerA;
.targetSection
... Lots of variables ...
.markerB
int markerB;
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我知道.targetSection中的数据位于markerA和markerB的地址之间.
还有另一种方法来实现这一目标吗?是否有库可以让我读取当前正在执行的ELF图像并确定部分位置和大小?
#include <stdio.h>
const int str[1000] = {0};
int main(void)
{
printf("arr is %d\n", str[0]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有以下输出:
[-exercises/adam/stack2]:size a.out
text data bss dec hex filename
5133 272 24 5429 1535 a.out
Run Code Online (Sandbox Code Playgroud)
鉴于:
#include <stdio.h>
static int str[1000] = {0};
int main(void)
{
printf("arr is %d\n", str[0]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有以下输出:
[-exercises/adam/stack2]:size a.out
text data bss dec hex filename
1080 4292 24 5396 1514 a.out
Run Code Online (Sandbox Code Playgroud)
当数组未初始化时 - 它再次进入"const"的文本段和"静态"的BSS.
变量是全局变量,应该可以从可执行文件中的任何地方访问(因为没有"静态"),但是如果它是变量,我不知道它为什么放在文本段而不是数据段?
考虑使用GCC编译的C中的标准hello world程序,无需任何开关.如上所述readelf -s,它包含64个符号.它还说该.symtab段长度为1024字节.但是每个符号表条目有18个字节,那么它如何包含64个条目呢?它应该是56个条目.我正在构建我自己的程序,它读取符号表,它不会看到那些"缺失"的条目,因为它读到节结束.readelf如何知道读多长时间?
我有一个ELF文件,我想将其反编译为C代码,并对生成的C代码进行简单的更改,然后将其重建为ELF。
反编译的C代码不需要完全可读。例如,如果混淆了变量和函数名称,那就可以了。
我可以使用哪些工具在Linux上完成此任务?
PS:如果C无法进行编译或不容易进行编译,尽管对汇编源进行调整对我来说非常困难,但我愿意考虑对汇编语言进行反编译。
更新:您可能会假设我正在使用以下C程序来获取我的a.outELF。现在,进一步假设我已经失去了这个原始C资料。所以,我现在想将其编译到(一个可能混淆),C其中我至少能够改变像琴弦的小东西源"world","Hello"和"Bye",或能扭转感if等语句
#include <stdio.h>
#include <string.h>
char buf[256];
const char *Hello = "Hello";
const char *Bye = "Bye";
const char *Who = "world";
char * greet(const char *greeting, const char *str) {
strcpy(buf, greeting);
strcat(buf, ", ");
strcat(buf, str);
strcat(buf, "!");
return buf;
}
int main(int argc, char *argv[]) {
int sayHello …Run Code Online (Sandbox Code Playgroud) 在我关于手动生成核心转储文件的问题之后,我决定深入研究并弄脏我的手.
我能够构建基本的核心转储结构,并将我的死程序的内存返回到一个大的LOAD部分的核心转储中.在GDB中调试时,我的变量又回来了,没问题.这里有一个棘手的部分,我如何让GDB检索程序崩溃时的位置信息.
我知道核心转储的注释部分包含这些信息(cpu寄存器等).这是objdump -h为"真正的"核心转储提供的内容:
core.28339: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 note0 000001e8 00000000 00000000 000000f4 2**0
CONTENTS, READONLY
1 .reg/28339 00000044 00000000 00000000 00000150 2**2
CONTENTS
2 .reg 00000044 00000000 00000000 00000150 2**2
CONTENTS
3 .auxv 000000a0 00000000 00000000 0000023c 2**2
CONTENTS
4 load1a 00001000 08010000 00000000 00001000 2**12
CONTENTS, ALLOC, LOAD, READONLY, CODE
.. other load sections ...
Run Code Online (Sandbox Code Playgroud)
我想知道readelf那些.reg部分包含从某些结构映射的数据:
Notes at offset 0x000000f4 with length …Run Code Online (Sandbox Code Playgroud) 如何使用C++获取linux中elf二进制文件所需的所有动态库列表?
一旦我设法从二进制文件中提取信息(文件名?),我可以通过搜索找到实际文件PATH,但我无法找到有关从ELF二进制文件中提取未编码信息的任何信息.
思考?
我试图了解ELF段是如何进行内存映射的.我注意到各个部分都映射到同一个ELF段.例如,.rodata映射到与.text相同的段.
为什么会这样?为什么不将.rodata映射到单独的只读且不可执行的段?
此外,将.text部分映射到"仅执行"段(不可读)需要什么?是否存在可能阻碍此问题的内核/硬件限制?
编辑:我可以补充一点,我正在使用GNU链接器,如果这有所作为.
我正在尝试使用gcc和clang来查看它们是否可以优化
#define SCOPE static
SCOPE const struct wrap_ { const int x; } ptr = { 42 /*==0x2a*/ };
SCOPE struct wrap { const struct wrap_ *ptr; } const w = { &ptr };
int ret_global(void) { return w.ptr->x; }
Run Code Online (Sandbox Code Playgroud)
返回一个中间常量.
事实证明他们可以:
0000000000000010 <ret_global>:
10: b8 2a 00 00 00 mov $0x2a,%eax
15: c3 retq
Run Code Online (Sandbox Code Playgroud)
但令人惊讶的是,移除静态会产生相同的装配输出.这让我很好奇,因为如果全局不是static它应该是可插入的并且用中间体替换引用应该防止全局变量上的位置.
确实如此:
#!/bin/sh -eu
: ${CC:=gcc}
cat > lib.c <<EOF
int ret_42(void) { return 42; }
#define SCOPE
SCOPE const struct wrap_ { …Run Code Online (Sandbox Code Playgroud) elf ×10
c ×4
linux ×3
binary ×2
c++ ×1
coredump ×1
decompiling ×1
dos ×1
gdb ×1
global ×1
linker ×1
linux-kernel ×1
optimization ×1
static ×1
transform ×1