From cb03d9a148dd306c2e7163f6a7360d6a8d7cd1f6 Mon Sep 17 00:00:00 2001 From: artradeskz Date: Thu, 30 Oct 2025 06:43:35 +0300 Subject: [PATCH] Add files via upload --- objdump_readelf/asm0_1.py | 243 +++++++++++++++++++++++++++++++++++++ objdump_readelf/asm0_o.py | 247 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 490 insertions(+) create mode 100644 objdump_readelf/asm0_1.py create mode 100644 objdump_readelf/asm0_o.py diff --git a/objdump_readelf/asm0_1.py b/objdump_readelf/asm0_1.py new file mode 100644 index 0000000..0180861 --- /dev/null +++ b/objdump_readelf/asm0_1.py @@ -0,0 +1,243 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Скрипт генерирует КОРРЕКТНЫЙ 64-битный исполняемый ELF-файл для Linux (x86-64), +# содержащий 12 инструкций NOP (0x90) в секции .text и один байт (0x0A) в секции .data. +# Файл полностью соответствует ELF-спецификации. + +import struct + +def align_up(offset, alignment): + """Выравнивание offset вверх до alignment""" + return (offset + alignment - 1) & ~(alignment - 1) + +def pack_elf(): + """ + Создаёт байтовое представление валидного ELF-исполняемого файла. + Возвращает bytes — содержимое файла. + """ + # Размер страницы памяти в Linux на x86-64 (4096 байт = 0x1000) + PAGE_SIZE = 0x1000 + + # Адрес точки входа программы — начало секции .text + ENTRY = 0x401000 + + # === СОДЕРЖИМОЕ СЕКЦИЙ === + # Машинный код: 12 инструкций NOP (код операции 0x90) + text_code = b'\x90' * 12 + + # Данные: один байт — символ новой строки (0x0A = '\n') + data_content = b'\x0a' + + # Таблица строк имён секций (обязательна для Section Headers) + # Формат: нуль-терминированные строки подряд. + # Порядок: "", ".text", ".data", ".shstrtab" + shstrtab_content = b'\x00.text\x00.data\x00.shstrtab\x00' + + # === СМЕЩЕНИЯ В ФАЙЛЕ (в байтах) === + # Program Headers (заголовки сегментов) начинаются сразу после ELF-заголовка + phdr_start = 64 # размер ELF-заголовка + + # Секция .text начинается с границы страницы 0x1000 (4096) + text_offset = 0x1000 + + # Секция .data начинается со следующей страницы — 0x2000 (8192) + data_offset = 0x2000 + + # Таблица имён секций (.shstrtab) размещается сразу после .data с ВЫРАВНИВАНИЕМ + shstrtab_offset = align_up(data_offset + len(data_content), 8) # 0x2008 вместо 0x2001 + + # Заголовки секций (Section Headers) размещаются сразу после .shstrtab с выравниванием + shdr_offset = align_up(shstrtab_offset + len(shstrtab_content), 16) # 0x2020 + + # === РАЗМЕРЫ КОМПОНЕНТОВ === + text_size = len(text_code) # 12 байт + data_size = len(data_content) # 1 байт + shstrtab_size = len(shstrtab_content) # 17 байт + + # Размер Program Headers: 3 заголовка × 56 байт + phdr_size = 3 * 56 # 168 байт + + # Размер одного заголовка секции — 64 байта для 64-битного ELF + # Всего 4 секции: NULL, .text, .data, .shstrtab + shdr_size = 4 * 64 # 256 байт + + # Общий размер файла: от начала до конца последнего заголовка секции + file_size = shdr_offset + shdr_size # 0x2020 + 256 = 0x2120 (8480 байт) + + # Создаём байтовый массив нужного размера, заполненный нулями + elf_data = bytearray(file_size) + + # === 1. ELF-ЗАГОЛОВОК (64 байта) === + # e_ident — магическое число и базовые параметры формата (ИСПРАВЛЕНО) + # Структура e_ident: 16 байт + e_ident = ( + b'\x7fELF' # ELF Magic (4 байта) + b'\x02' # 64-bit (1 байт) + b'\x01' # Little-endian (1 байт) + b'\x01' # ELF Version (1 байт) + b'\x00' # OS ABI: System V (1 байт) + b'\x00' # ABI Version (1 байт) + b'\x00\x00\x00\x00\x00\x00\x00' # Padding (7 байт) - ИТОГО 16 байт + ) + + assert len(e_ident) == 16, f"e_ident должен быть 16 байт, а не {len(e_ident)}" + + # Упаковываем ELF-заголовок в бинарный формат + elf_header = struct.pack( + '<16sHHIQQQIHHHHHH', + e_ident, # e_ident[16] - 16 байт + 2, # e_type = ET_EXEC (исполняемый файл) + 0x3e, # e_machine = EM_X86_64 (AMD x86-64) + 1, # e_version = 1 + ENTRY, # e_entry — адрес точки входа + phdr_start, # e_phoff — смещение Program Headers в файле + shdr_offset, # e_shoff — смещение Section Headers в файле + 0, # e_flags — флаги архитектуры (0 для x86-64) + 64, # e_ehsize — размер ELF-заголовка (64 байта) + 56, # e_phentsize — размер одного Program Header (56 байт) + 3, # e_phnum — количество Program Headers + 64, # e_shentsize — размер одного Section Header (64 байта) + 4, # e_shnum — количество Section Headers + 3 # e_shstrndx — индекс секции с именами (.shstrtab) + ) + # Записываем ELF-заголовок в начало файла + elf_data[0:64] = elf_header + + # === 2. PROGRAM HEADERS (заголовки сегментов) === + def make_phdr(p_type, p_offset, p_vaddr, p_paddr, p_filesz, p_memsz, p_flags, p_align): + """ + Создаёт бинарное представление заголовка сегмента. + """ + # Проверки корректности + assert p_offset % p_align == 0, f"Segment offset {p_offset:#x} not aligned to {p_align:#x}" + assert p_vaddr % p_align == 0, f"Virtual address {p_vaddr:#x} not aligned to {p_align:#x}" + assert p_filesz <= p_memsz, f"File size {p_filesz:#x} > memory size {p_memsz:#x}" + + return struct.pack('