我已经知道的:
ELF 可执行文件有许多部分,显然 .text 和 .data 部分被加载到内存中,因为它们是程序的主要部分。但是要使程序正常工作,它需要更多信息,尤其是在动态链接时。
我感兴趣的是 .plt、.got、.dynamic、.dynsym、.dynstr 等部分。ELF 中负责将函数链接到地址的部分。
从我到目前为止已经能够弄清楚的是,像 .symtab 和 .strtab 这样的东西不会被加载(或不会留在)内存中。但是链接器使用 .dynsym 和 .dynstr 吗?他们留在记忆中吗?我可以从程序代码访问它们吗?
是否有驻留在内核内存中的可执行文件的任何部分?
我对此的兴趣主要是法医,但有关此主题的任何信息都会有所帮助。我读过的关于这些表和动态链接的资源更高级,它们只解释了工作原理,而不是关于内存中的内容的任何实用内容。
如果我的问题有任何不清楚的地方,请告诉我。
我有一个可执行的二进制文件;让我们称之为a.out。我可以看到二进制文件包含字符串
$ strings a.out
...
/usr/share/foo
....
Run Code Online (Sandbox Code Playgroud)
我需要将字符串更改/usr/share/foo为/usr/share/bar. 我可以用sed?替换字符串吗?:
sed -i 's@/usr/share/foo@/usr/share/bar@' a.out
Run Code Online (Sandbox Code Playgroud)
这看起来是一件安全的事情。当字符串长度不同时,这也能工作吗?
我用gcc编译了一个小C程序(2行代码),试图理解ELF文件格式。readelf -h在目标文件上做一个,我在标题中有:
OS/ABI: UNIX - System V
Run Code Online (Sandbox Code Playgroud)
我正在使用 Fedora,那么为什么不是 Linux 呢?
编辑:我编译
int main(){
int x = 0;
x++;
}
Run Code Online (Sandbox Code Playgroud)
与gcc -o main.o -c main.c. 我的 gcc 版本是
gcc (GCC) 4.5.1 20100924 (Red Hat 4.5.1-4)
Run Code Online (Sandbox Code Playgroud) 一个最小的 ELF 可执行文件只需要 ELF 头和至少一个程序头才能起作用。但是,当我在一个简短的可执行文件上运行 strip 时,它决定不丢弃节头表或节字符串节,尽管它们对程序的执行没有任何目的(据我所知),但仍保留它们。
有没有理由不通过条带去除这些?是否有另一个实用程序可以删除可执行文件运行不需要的所有内容?我已经尝试手动编辑我正在制作的代码高尔夫可执行文件以删除部分标题,它似乎工作正常,并且要小得多。
我目前正在尝试让 python 在我的 NAS 上运行,这是一个 Zyxel NSA325。
我确实设法让 python 2.7 和 pip 运行,并且我能够使用 pip 成功安装看门狗模块。我按照这些说明让 python 和 pip 运行 btw。
当我运行一个使用 watchdog 模块的 python 脚本时,我得到了一个非常错误的错误,很难。
/usr/local/zy-pkgs/ffproot/ffp/bin/python2.7: '/ffp/lib/libc.so' is not an ELF file
Run Code Online (Sandbox Code Playgroud)
我用谷歌搜索了 ELF 文件的标题应该是什么样子,显然它以7f 45 4c 46转换为.ELF. 所以我做了一个快速cat /ffp/lib/libc.so的结果是:
/* GNU ld script
* Use the shared library, but some functions are only in
* the static library, so try that secondarily. */
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
"elf32-littlearm")
GROUP ( libc.so.0 …Run Code Online (Sandbox Code Playgroud) 我正在研究 ELF 规范(http://www.skyfree.org/linux/references/ELF_Format.pdf),关于程序加载过程我不清楚的一点是堆栈是如何初始化的,以及什么初始页面大小是。这是测试(在 Ubuntu x86-64 上):
$ cat test.s
.text
.global _start
_start:
mov $0x3c,%eax
mov $0,%edi
syscall
$ as test.s -o test.o && ld test.o
$ gdb a.out -q
Reading symbols from a.out...(no debugging symbols found)...done.
(gdb) b _start
Breakpoint 1 at 0x400078
(gdb) run
Starting program: ~/a.out
Breakpoint 1, 0x0000000000400078 in _start ()
(gdb) print $sp
$1 = (void *) 0x7fffffffdf00
(gdb) info proc map
process 20062
Mapped address spaces:
Start Addr End Addr Size Offset …Run Code Online (Sandbox Code Playgroud) 当我strace检查程序时,我经常很难找到动态加载程序的系统调用在哪里结束以及程序的系统调用在哪里开始。
strace ./hello一个简单的 hello world C 程序的输出hello有 36 行。这是一个示例:
execve("./hello", ["./hello"], 0x7fffb38f4a30 /* 73 vars */) = 0
brk(NULL) = 0x1304000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffe6715fe60) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=92340, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 92340, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f78d9fbd000
close(3) = 0
openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260|\2\0\0\0\0\0"..., 832) = 832 …Run Code Online (Sandbox Code Playgroud) 有两个文件,一个编译并链接,gcc另一个手动使用nasm,ld我得到
这两件事有什么区别?我可以看到readelf -h那个是
DYN (Shared object file)EXEC (Executable file)我可以在维基百科ET_DYNET_EXEC上看到这些记录为和。这两者之间有什么实际区别?
当我在 Linux Box 上时,我使用 bash 作为 shell。现在我想知道 bash 如何处理 ELF 文件的执行,即当我输入 ./program 并且 program 是一个 ELF 文件时。我搜索了 bash-4.3.tar.gz,似乎没有某种幻数解析器来确定文件是否为 ELF,也没有找到 exec() 系统调用。
整个进程如何运作?bash 如何将 ELF 的执行传递给操作系统?
我正在尝试减少运行 SuSE 的 Linux 映像,并考虑strip在所有系统的可执行文件上运行。即使我可能不会通过这种方式重新获得很多磁盘空间,这样做会有什么危害吗?