据我了解,这些是.section指令:
awxMSGT
Run Code Online (Sandbox Code Playgroud)
如果使用 COFF 格式,“旧”指令具有“只读”。
如何将 ELF 格式的 .section 设置为只读?根本没有说明符吗?
在 C 语言中很容易得到函数的起始地址,但不能得到它的大小。因此,我目前正在目标文件上执行“nm”,以便找到我的函数,然后找到下一个函数的起始地址。我需要执行“nm”,因为编译器可以(在我的情况下实际上可以)重新排序函数,因此源顺序可以与对象顺序不同。
我想知道是否还有其他方法可以做到这一点。例如,指示编译器保留目标文件中的源代码顺序等。也许有一些 ELF 魔法?
我的编译器是 GCC、CLANG 和 Sun Studio。平台:Solaris 及其衍生产品、MacOSX、FreeBSD。未来要拓展。
c compiler-construction elf compiler-optimization object-files
我正在创建有关缓冲区溢出和堆栈/堆攻击的培训。我正在 Ubuntu 12.04 x86_64机器上工作,想要展示一些有错误的程序示例以及利用这些漏洞的方法。
我试图从迄今为止找到的最基本的 shellcode 开始,即简单的 exit 调用,它应该退出溢出的程序。
因此exitcall.asm:
;exitcall.asm
[SECTION .text]
global _start
_start:
xor ebx,ebx ; zero out ebx, same function as mov ebx,0
mov al, 1 ; exit command to kernel
int 0x80
Run Code Online (Sandbox Code Playgroud)
我从其他教程中得到了这个 asm 文件,但它是为i386架构编写的。接下来要做的是生成一个目标文件并将其设为二进制可执行文件:
# nasm -f elf64 exitcall.asm
# ld -o exitcall exitcall.o
# file exitcall
exitcall: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
# strace ./exitcall
execve("./exitcall", ["./exitcall"], [/* 73 vars */]) …Run Code Online (Sandbox Code Playgroud) 我在 linux ( man gcc)上查看 gcc 手册中的-c选项 ( gcc -c infile),其中指出:
-c:编译或汇编源文件,但不链接。链接阶段根本没有完成。最终的输出是以每个源文件的目标文件的形式。
默认情况下,源文件的目标文件名是通过将后缀 .c、.i、.s 等替换为 .o 来生成的。
更重要的是,在检查 ELF 文件和目标文件(使用filecomand )时,输出是相同的:
file ./out/main.o: ELF 32-bit LSB relocatable, Atmel AVR 8-bit, version 1 (SYSV), not stripped
file ./out/main.elf: ELF 32-bit LSB executable, Atmel AVR 8-bit, version 1 (SYSV), statically linked, not stripped
Run Code Online (Sandbox Code Playgroud)
所以他们都有相同的描述。我的问题是:
-c选项和一些标志(-Wall -g -std=c99 -Os)编译一些源文件并从中获取目标文件,这些标志是否会在 ELF 文件生成中持续存在(如果我在目标文件上使用它们,我可以在生成 ELF 文件时跳过这些标志)?我尝试建立一个简单的你好,世界 ELF对我的路由器Xiaomi Router 3g使用cmake。它运行
Linux OpenWrt 4.14.95 #0 SMP Wed Jan 30 12:21:02 2019 mips GNU/Linux
Run Code Online (Sandbox Code Playgroud)
这个想法是$(PKG_BUILD_DIR)用作目录来执行外部构建(通常通过mkdir build ; cd build ; cmake ..)
构建成功完成,当我将它安装在我的路由器上并启动它时,它失败了:
Linux OpenWrt 4.14.95 #0 SMP Wed Jan 30 12:21:02 2019 mips GNU/Linux
Run Code Online (Sandbox Code Playgroud)
当我构建ELF没有cmake(
include $(INCLUDE_DIR)/cmake.mk,$(CP) ...该define Build/Prepare部分中的 行define Build/Compile部分),它工作得很好:它打印Hello, World! .
日志文件在 …
我正在尝试使用LLVM(来自Homebrew)构建 ELF 文件,但我不知道如何链接它。
我的文件:
multiboot2.h:
struct multiboot2_header_t {
// Stub
} multiboot2_header __attribute__((section(".multiboot")));
Run Code Online (Sandbox Code Playgroud)
内核.c:
#include "multiboot2.h"
void _start() {
// Stub
}
Run Code Online (Sandbox Code Playgroud)
链接器.ld:
ENTRY(_start)
SECTIONS
{
.text: {
/* link the multiboot struct here */
. = ALIGN(8);
KEEP(*(.multiboot))
/* place all of your code afterwards */
*(.text)
}
}
Run Code Online (Sandbox Code Playgroud)
我可以通过命令将它编译为目标文件kernel.o,clang -c -o kernel.o kernel.c --target x86_64-none-gnu但我无法使用我的链接器脚本来链接这个目标文件。
PS在我从未直接使用LLVM和链接器之前,只使用GNU GCC构建简单的 Linux 应用程序。
我试图弄清楚这两个部分之间的区别,这似乎是这个问题的重复,但那里给出的答案没有解释太多,所以我想要更详细和简洁的解释。
在过去的几天里,我一直试图了解当我们执行一个 C 程序时幕后会发生什么。然而,即使在阅读了大量帖子后,我也找不到详细而准确的解释。有人可以帮我吗?
这是一个很简单的汇编程序,12执行完就返回。
$ cat a.asm
global _start
section .text
_start: mov rax, 60 ; system call for exit
mov rdi, 12 ; exit code 12
syscall
Run Code Online (Sandbox Code Playgroud)
它可以正确构建和执行:
$ nasm -f elf64 a.asm && ld a.o && ./a.out || echo $?
12
Run Code Online (Sandbox Code Playgroud)
但是a.out的大小很大,超过4k:
$ wc -c a.out
4664 a.out
Run Code Online (Sandbox Code Playgroud)
我尝试通过阅读精灵内容来理解它:
$ readelf -l a.out
Elf file type is EXEC (Executable file)
Entry point 0x401000
There are 2 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz …Run Code Online (Sandbox Code Playgroud) 我有一个 elf64 可执行文件 foo,我想“手动”加载和启动它,并能够从中调用其他函数。我如何将它加载到内存中,然后设置指令指针来运行它。
foo不是共享对象库,它是一个可执行文件,具有导出的某些功能,就好像它是 SO。
所以,有几个问题:
例如,我有以下内容,但它存在段错误:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <elf.h>
#define ELF_SIZE 10000
int main(int argc, char **argv)
{
FILE *fp;
void * entry_point ;
Elf64_Ehdr *elfHdr;
uint8_t *buffer = malloc(ELF_SIZE);
fp = fopen("./foo", "rb");
int read_size = fread(buffer, 1, ELF_SIZE, fp);
if (read_size == ELF_SIZE)
{
printf("loaded ELF onto heap
\n");
} else
{
printf("read failed: %d\n", read_size);
return 0;
}
printf("elf loaded at %x\n", buffer);
elfHdr …Run Code Online (Sandbox Code Playgroud)