MCPcopy Create free account
hub / github.com/GJDuck/e9patch / emitElf

Function emitElf

src/e9patch/e9elf.cpp:448–820  ·  view source on GitHub ↗

* Emit the (modified) ELF binary. */

Source from the content-addressed store, hash-verified

446 * Emit the (modified) ELF binary.
447 */
448size_t emitElf(Binary *B, const MappingSet &mappings, size_t mapping_size)
449{
450 uint8_t *data = B->patched.bytes;
451 size_t size = B->patched.size;
452
453 // Step (0): Round-up to nearest page boundary (zero-fill)
454 stat_input_file_size = size;
455 size = (size % PAGE_SIZE == 0? size:
456 size + PAGE_SIZE - (size % PAGE_SIZE));
457
458 // Step (1): Refactor the patching (if necessary):
459 RefactorSet refactors;
460 size += emitRefactoredPatch(B->original.bytes, data, size, mapping_size,
461 B->Is, refactors);
462
463 // Step (2): Disable incompatible ELF features:
464 ElfInfo &info = B->elf;
465 if (info.features != nullptr)
466 {
467 if ((*info.features & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0)
468 *info.features &= ~GNU_PROPERTY_X86_FEATURE_1_IBT;
469 if ((*info.features & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0)
470 *info.features &= ~GNU_PROPERTY_X86_FEATURE_1_SHSTK;
471 }
472
473 // Step (3): Emit all mappings:
474 for (auto *mapping: mappings)
475 {
476 uint8_t *base = data + size;
477 mapping->offset = (off_t)size;
478 flattenMapping(B, base, mapping, /*int3=*/0xcc);
479 size += mapping->size;
480 }
481
482 // Step (4): Emit the loader:
483 size = (size % PAGE_SIZE == 0? size:
484 size + PAGE_SIZE - (size % PAGE_SIZE));
485 struct e9_config_s *config = (struct e9_config_s *)(data + size);
486 size_t config_offset = size;
487 size += sizeof(struct e9_config_s);
488 struct e9_config_elf_s *config_elf =
489 (struct e9_config_elf_s *)(data + size);
490 size += sizeof(struct e9_config_elf_s);
491 const char magic[] = "E9PATCH";
492 memcpy(config->magic, magic, sizeof(magic));
493 const char version[] = STRING(VERSION);
494 static_assert(sizeof(version) <= sizeof(config->version),
495 "VERSION string is too long");
496 memcpy(config->version, version, sizeof(version));
497 config->base = option_loader_base;
498 if (B->mmap != INTPTR_MIN)
499 {
500 config->mmap = BASE_ADDRESS(B->mmap);
501 config->mmap |= (IS_ABSOLUTE(config->mmap)? E9_ABS_ADDR: 0);
502 }
503 std::vector<uint32_t> preinits, postinits;
504 for (auto preinit: B->preinits)
505 {

Callers 1

parseEmitFunction · 0.85

Calls 9

emitRefactoredPatchFunction · 0.85
flattenMappingFunction · 0.85
memcpyFunction · 0.85
getVirtualBoundsFunction · 0.85
emitLoaderMapFunction · 0.85
errorFunction · 0.85
replaceInitFiniFunction · 0.85
warningFunction · 0.85
sizeMethod · 0.45

Tested by

no test coverage detected