From 9eb604113b9a531331897e14fafe0bef7f62d236 Mon Sep 17 00:00:00 2001 From: Mitja Felicijan Date: Thu, 19 Sep 2024 14:13:59 +0200 Subject: Added reading of ELF binaries in Zig --- README.md | 1 + zig-elf/.clang-format | 4 ++++ zig-elf/Makefile | 5 +++++ zig-elf/elf | Bin 0 -> 16048 bytes zig-elf/elf-64-gen.pdf | Bin 0 -> 172444 bytes zig-elf/elf.c | 6 ++++++ zig-elf/elf.png | Bin 0 -> 326086 bytes zig-elf/main.zig | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 67 insertions(+) create mode 100644 zig-elf/.clang-format create mode 100644 zig-elf/Makefile create mode 100755 zig-elf/elf create mode 100644 zig-elf/elf-64-gen.pdf create mode 100644 zig-elf/elf.c create mode 100644 zig-elf/elf.png create mode 100644 zig-elf/main.zig diff --git a/README.md b/README.md index 22944a7..b90eafe 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ running it. | [zig-tlv-encoding](./zig-tlv-encoding) | zig-0.13.0 | Naive implementation of TLV encoding in Zig. | | [zig-embed](./zig-embed) | zig-0.13.0 | Embedding external resources in compiled binary. | | [zig-struct-bin](./zig-struct-bin) | zig-0.13.0 | Save a struct into binary file and then reading it back. | +| [zig-elf](./zig-elf) | zig-0.14.0 | Read execution header of Elf64 format in Zig. | ## License diff --git a/zig-elf/.clang-format b/zig-elf/.clang-format new file mode 100644 index 0000000..84ac618 --- /dev/null +++ b/zig-elf/.clang-format @@ -0,0 +1,4 @@ +BasedOnStyle: LLVM +ColumnLimit: 120 +IndentWidth: 4 + diff --git a/zig-elf/Makefile b/zig-elf/Makefile new file mode 100644 index 0000000..52899e3 --- /dev/null +++ b/zig-elf/Makefile @@ -0,0 +1,5 @@ +default: + zig run main.zig + +elf: + clang -o elf elf.c diff --git a/zig-elf/elf b/zig-elf/elf new file mode 100755 index 0000000..7178622 Binary files /dev/null and b/zig-elf/elf differ diff --git a/zig-elf/elf-64-gen.pdf b/zig-elf/elf-64-gen.pdf new file mode 100644 index 0000000..d80b546 Binary files /dev/null and b/zig-elf/elf-64-gen.pdf differ diff --git a/zig-elf/elf.c b/zig-elf/elf.c new file mode 100644 index 0000000..c038330 --- /dev/null +++ b/zig-elf/elf.c @@ -0,0 +1,6 @@ +#include + +int main(void) { + printf("Oh, hi Mark!\n"); + return 0; +} diff --git a/zig-elf/elf.png b/zig-elf/elf.png new file mode 100644 index 0000000..22685f5 Binary files /dev/null and b/zig-elf/elf.png differ diff --git a/zig-elf/main.zig b/zig-elf/main.zig new file mode 100644 index 0000000..3b4e116 --- /dev/null +++ b/zig-elf/main.zig @@ -0,0 +1,51 @@ +// $ readelf -h ./elf +// https://github.com/bminor/binutils-gdb/blob/master/binutils/readelf.c + +// There is still a problem with packed structs and aligment padding +// better referenced in these two threads (sometime struct is not aligned +// properly or even has 1 byte more than its C alternative): +// - https://ziggit.dev/t/mapping-64-u8-buffer-to-a-struct/6052/19 +// - https://ziggit.dev/t/wrong-sizes-of-extern-packed-structs/6053/6 + +const std = @import("std"); + +const Elf64ExecutionHeader = packed struct { + ident: u128, + type: u16, + machine: u16, + version: u32, + entry: u64, + phoff: u64, + shoff: u64, + flags: u32, + ehsize: u16, + phentsize: u16, + phnum: u16, + shentsize: u16, + shnum: u16, + shstrndx: u16, +}; + +pub fn main() !void { + var file = try std.fs.cwd().openFile("./elf", .{}); + defer file.close(); + + var buffer: [64]u8 = undefined; + _ = try file.read(buffer[0..]); + + const header: *Elf64ExecutionHeader = @ptrCast(@alignCast(&buffer)); + + std.debug.print("Object file type: {}\n", .{header.type}); + std.debug.print("Architecture: {}\n", .{header.machine}); + std.debug.print("Object file version: 0x{X:0>2}\n", .{header.version}); + std.debug.print("Entry point virtual address: 0x{X:0>2}\n", .{header.entry}); + std.debug.print("Program header table file offset: {}\n", .{header.phoff}); + std.debug.print("Section header table file offset: {}\n", .{header.shoff}); + std.debug.print("Processor-specific flags: 0x{X:0>2}\n", .{header.flags}); + std.debug.print("ELF header size in bytes: {}\n", .{header.ehsize}); + std.debug.print("Program header table entry size: {}\n", .{header.phentsize}); + // std.debug.print("Program header table entry count: {}\n", .{header.phnum}); + // std.debug.print("Section header table entry size: {}\n", .{header.shentsize}); + // std.debug.print("Section header table entry count: {}\n", .{header.shnum}); + // std.debug.print("Section header string table index: {}\n", .{header.shstrndx}); +} -- cgit v1.2.3