Skip to content

Instantly share code, notes, and snippets.

@lukas2511
Last active March 20, 2019 20:32
Show Gist options
  • Save lukas2511/ffd6a30a4ba3b465745cdfc9d3d80c72 to your computer and use it in GitHub Desktop.
Save lukas2511/ffd6a30a4ba3b465745cdfc9d3d80c72 to your computer and use it in GitHub Desktop.
Tiny gcc compiled binary experiment
int main();
void exit(int x) {
asm("movl %0, %%ebx" : : "r"(x) :);
asm("movl $1, %eax");
asm("int $0x80");
while(1);
}
void _start() {
exit(main());
}
int main() {
return 42;
}
BITS ?= 32
.PHONY: main clean test
main:
gcc -o main main.c -nodefaultlibs -nostdlib -m$(BITS) -nostartfiles -Os -s -static -Wl,--build-id=none -Wl,--nmagic
strip --remove-section=.comment --remove-section=.eh_frame --strip-all main
sstrip -z main
python strip.py main
clean:
rm main
test: main
@stat --printf="Size: %s Byte\n" main
@./main; if [ $${?} = 42 ]; then echo "Seems good :)"; else echo "Seems broken :-/"; fi
#!/usr/bin/env python3
import sys
import struct
binary = open(sys.argv[1], "rb").read()
is_64bit = binary[0x04] == 0x02
elf_header_names = ['e_ident[EI_MAG]', 'e_ident[EI_CLASS]', 'e_ident[EI_DATA]', 'e_ident[EI_VERSION]', 'e_ident[EI_OSABI]', 'e_ident[EI_ABIVERSION]', 'e_ident[EI_RESERVED]', 'e_type', 'e_machine', 'e_version', 'e_entry', 'e_phoff', 'e_shoff', 'e_flags', 'e_ehsize', 'e_phentsize', 'e_phnum', 'e_shentsize', 'e_shnum', 'e_shstrndx']
elf_header = {}
program_header = {}
if is_64bit:
elf_header_format = "<IBBBBB7sHHIQQQIHHHHHH"
program_header_format = "<IIQQQQQQ"
program_header_names = ['p_type', 'p_flags', 'p_offset', 'p_vaddr', 'p_paddr', 'p_filesz', 'p_memsz', 'p_align']
else:
elf_header_format = "<IBBBBB7sHHIIIIIHHHHHH"
program_header_format = "<IIIIIIII"
program_header_names = ['p_type', 'p_offset', 'p_vaddr', 'p_paddr', 'p_filesz', 'p_memsz', 'p_flags', 'p_align']
elf_header_length = struct.calcsize(elf_header_format)
program_header_length = struct.calcsize(program_header_format)
elf_header_values = list(struct.unpack(elf_header_format, binary[0x00:0x00+elf_header_length]))
program_header_values = list(struct.unpack(program_header_format, binary[elf_header_length:elf_header_length+program_header_length]))
for i in range(len(elf_header_names)):
elf_header[elf_header_names[i]] = elf_header_values[i]
for i in range(len(program_header_names)):
program_header[program_header_names[i]] = program_header_values[i]
program_offset = elf_header_length + elf_header['e_phnum'] * program_header_length
program = binary[program_offset:program_offset+program_header['p_filesz']]
elf_header['e_entry'] -= program_header_length
elf_header['e_phnum'] = 1
elf_header['e_ident[EI_RESERVED]'] = b"METTIGL"
program_header['p_offset'] -= program_header_length
program_header['p_vaddr'] -= program_header_length
program_header['p_paddr'] -= program_header_length
for i, e_name in enumerate(elf_header_names):
elf_header_values[i] = elf_header[e_name]
for i, p_name in enumerate(program_header_names):
program_header_values[i] = program_header[p_name]
new_elf_header = struct.pack(elf_header_format, *elf_header_values)
new_program_header = struct.pack(program_header_format, *program_header_values)
new_binary = new_elf_header + new_program_header + program
print("ELF header size: %d" % len(new_elf_header))
print("Program header size: %d" % len(new_program_header))
print("Program size: %d" % len(program))
print("Total size: %d" % len(new_binary))
open(sys.argv[1], "wb").write(new_binary)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment