// crossfire: distributed brute force infrastructure // // Copyright (C) 2020 haskal // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #pragma once #include #include #include #include #include #include #include #include #include #include #define _SELF_NAME "/proc/self/exe" #if ELF_BITS == 32 #define Elf_Ehdr Elf32_Ehdr #define Elf_Shdr Elf32_Shdr #elif ELF_BITS == 64 #define Elf_Ehdr Elf64_Ehdr #define Elf_Shdr Elf64_Shdr #endif #define CHK_GENERIC(what, ret) if (what) { return ret; } #define CHK_NULL_NULL(what) CHK_GENERIC(what == NULL, NULL) #define CHK_NEG_NEG(what) CHK_GENERIC(what < 0, -1) static inline char* readlink_exactly(const char* name) { ssize_t len; ssize_t blen = 256; char* s = malloc(blen); CHK_NULL_NULL(s); while (true) { len = readlink(name, s, blen - 1); if (len == (blen - 1)) { free(s); blen *= 2; s = malloc(blen); CHK_NULL_NULL(s); } else if (len < 0) { return NULL; } else { return s; } } } static inline int readexactly(int fd, uint8_t* buf, size_t size) { for (size_t i = 0; i < size;) { ssize_t res = read(fd, &buf[i], size - i); if (res < 0) { if (errno == EINTR) { continue; } return -1; } i += res; } return size; } typedef struct { char* self_name; size_t self_size; void* self_mm; Elf_Ehdr* ehdr; char* strs; } boot_ctx; typedef struct { off_t offset; size_t size; } boot_lookup; static int init_boot_ctx(boot_ctx* ctx) { // i fucking hate C char* self_name = readlink_exactly(_SELF_NAME); CHK_GENERIC(self_name == NULL, -1); ctx->self_name = self_name; int fd = open(self_name, O_RDONLY); CHK_NEG_NEG(fd); ssize_t len = lseek(fd, 0, SEEK_END); CHK_NEG_NEG(len); ctx->self_size = len; void* map = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0); CHK_GENERIC(map == MAP_FAILED, -1); CHK_NEG_NEG(close(fd)); ctx->self_mm = map; ctx->ehdr = map; off_t shdr_off = ctx->ehdr->e_shoff + (ctx->ehdr->e_shstrndx * ctx->ehdr->e_shentsize); Elf_Shdr* shdr = (void*) (((uint8_t*) map) + shdr_off); ctx->strs = ((uint8_t*) map) + shdr->sh_offset; return 0; } static boot_lookup boot_ctx_lookup(boot_ctx* ctx, const char* sectname) { boot_lookup bl = { (off_t) -1, (size_t) -1 }; for (size_t i = 0; i < ctx->ehdr->e_shnum; i++) { Elf_Shdr* shdr = (void*) (((uint8_t*) ctx->self_mm) + ctx->ehdr->e_shoff + (i * ctx->ehdr->e_shentsize)); if (!strcmp(ctx->strs + shdr->sh_name, sectname)) { bl.offset = shdr->sh_offset; bl.size = shdr->sh_size; return bl; } } return bl; } static void unload_boot_ctx(boot_ctx* ctx) { free(ctx->self_name); if (munmap(ctx->self_mm, ctx->self_size) < 0) { printf("NO SHONKS\n"); exit(-1); } }