Serenity Operating System
at master 123 lines 3.0 kB view raw
1/* 2 * Copyright (c) 2018-2020, the SerenityOS developers. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Types.h> 8#include <elf.h> 9#include <fcntl.h> 10#include <stdio.h> 11#include <string.h> 12#include <unistd.h> 13 14#if ARCH(X86_64) 15asm("haxcode:\n" 16 "1: jmp 1b\n" 17 "haxcode_end:\n"); 18#elif ARCH(AARCH64) 19asm("haxcode:\n" 20 "1: b 1b\n" 21 "haxcode_end:\n"); 22#else 23# error Unknown architecture 24#endif 25 26extern "C" void haxcode(); 27extern "C" void haxcode_end(); 28 29#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 30 31int main() 32{ 33 char buffer[16384]; 34 35 auto& header = *(Elf32_Ehdr*)buffer; 36 header.e_ident[EI_MAG0] = ELFMAG0; 37 header.e_ident[EI_MAG1] = ELFMAG1; 38 header.e_ident[EI_MAG2] = ELFMAG2; 39 header.e_ident[EI_MAG3] = ELFMAG3; 40 header.e_ident[EI_CLASS] = ELFCLASS32; 41 header.e_ident[EI_DATA] = ELFDATA2LSB; 42 header.e_ident[EI_VERSION] = EV_CURRENT; 43 header.e_ident[EI_OSABI] = ELFOSABI_SYSV; 44 header.e_ident[EI_ABIVERSION] = 0; 45 header.e_type = ET_EXEC; 46 header.e_version = EV_CURRENT; 47 header.e_ehsize = sizeof(Elf32_Ehdr); 48 header.e_machine = EM_386; 49 header.e_shentsize = sizeof(Elf32_Shdr); 50 51 header.e_phnum = 1; 52 header.e_phoff = 52; 53 header.e_phentsize = sizeof(Elf32_Phdr); 54 55 auto* ph = (Elf32_Phdr*)(&buffer[header.e_phoff]); 56 ph[0].p_vaddr = 0x20000000; 57 ph[0].p_type = PT_LOAD; 58 ph[0].p_filesz = sizeof(buffer); 59 ph[0].p_memsz = sizeof(buffer); 60 ph[0].p_flags = PF_R | PF_X; 61 ph[0].p_align = PAGE_SIZE; 62 63 header.e_shnum = 3; 64 header.e_shoff = 1024; 65 66 u32 secret_address = 0x00184658; 67 68 auto* sh = (Elf32_Shdr*)(&buffer[header.e_shoff]); 69 sh[0].sh_type = SHT_SYMTAB; 70 sh[0].sh_offset = 2048; 71 sh[0].sh_entsize = sizeof(Elf32_Sym); 72 sh[0].sh_size = 2 * sizeof(Elf32_Sym); 73 74 sh[1].sh_type = SHT_STRTAB; 75 sh[1].sh_offset = secret_address - 0x01001000; 76 sh[1].sh_entsize = 0; 77 sh[1].sh_size = 1024; 78 79 sh[2].sh_type = SHT_STRTAB; 80 sh[2].sh_offset = 4096; 81 sh[2].sh_entsize = 0; 82 sh[2].sh_size = 1024; 83 header.e_shstrndx = 2; 84 85 auto* sym = (Elf32_Sym*)(&buffer[2048]); 86 sym[0].st_value = 0x20002000; 87 sym[0].st_name = 0; 88 89 sym[1].st_value = 0x30000000; 90 sym[1].st_name = 0; 91 92 auto* strtab = (char*)&buffer[3072]; 93 strcpy(strtab, "sneaky!"); 94 95 auto* shstrtab = (char*)&buffer[4096]; 96 strcpy(shstrtab, ".strtab"); 97 98 auto* code = &buffer[8192]; 99 size_t haxcode_size = (uintptr_t)haxcode_end - (uintptr_t)haxcode; 100 printf("memcpy(%p, %p, %zu)\n", code, haxcode, haxcode_size); 101 memcpy(code, (void*)haxcode, haxcode_size); 102 103 header.e_entry = 0x20000000 + 8192; 104 105 int fd = open("x", O_RDWR | O_CREAT, 0777); 106 if (fd < 0) { 107 perror("open"); 108 return 1; 109 } 110 111 auto nwritten = write(fd, buffer, sizeof(buffer)); 112 if (nwritten < 0) { 113 perror("write"); 114 return 1; 115 } 116 117 if (execl("/home/anon/x", "x", nullptr) < 0) { 118 perror("execl"); 119 return 1; 120 } 121 122 return 0; 123}