Изминения в полях PE для увеличения размера заголовка.

Тема в разделе "WASM.BEGINNERS", создана пользователем _sheva740, 18 май 2010.

  1. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    Хочу заразить файл внедрением в заголовок между последним элементом таблицы объектов
    и смещением первой секции.
    Но таких файлов (у которых есть такое место) немного.
    Решил:
    - открываю файл
    - резервирую заданный кусок памяти
    - добавляю в выделенную память :
    DOS Stub + PE Header + Object Table + НУЖНЫЙ МНЕ ОБЪЕМ ПАМЯТИ + Section 1 ... N
    - Сохряняю файл
    - Теперь внедряю в него код

    [​IMG]

    Вопрос: Какие поля нужно изменить в PE Header и Object Entry этого файла чтобы так вот добавить
    к нему нужный объем. Или как-то можно проще, ведь то что на диске - это не то что в памяти.


    Думаю нужно изменять тут:

    Код (Text):
    1. PE Header
    2. ---------------------------------
    3. 50h DWord Image Size    виртуальный размер в байтах всего загружаемого образа,
    4.             вместе с заголовками, кратен Object align
    5.  
    6. 54h DWord Header Size   общий размер всех заголовков:
    Код (Text):
    1. Object Entry
    2. ---------------------------------
    3. 14h DWord Physical Offset   физическое смещение относительно начала EXE файла, выровнено
    4.                 на границу File align поля заголовка PE Header.
    5.                 Смещение используется загрузчиком как seek значение.
    ... может что-то еще ?
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Структура PE формата предельно проста. MZ заголовок, досовский стаб после, далее по смещению IMAGE_DOS_HEADER::e_lfanew идут NT-headers (file & optional header). В file header есть размер optional header - IMAGE_FILE_HEADER::SizeOfOptionalHeader (размер массива в хвосте optional header может варьироваться), размер file header фиксирован.
    после optional header идет IMAGE_FILE_HEADER::NumberOfSections заголовков секций (IMAGE_SECTION_HEADER), а далее неиспользуемоме пространство вплоть до следующего выравнивания на IMAGE_OPTIONAL_HEADAER::FileAlignment.
    После идут данные секций. Размер заголовков (суммарный), каждой секции и указатель начала каждой секции должен быть кратен FileAlignment, в памяти они выравниваются на SectionAlignment (соотв. VirtualAddress должен быть кратен SectionAlignment). Если они совпадают, то файл будет загружен так же, как и лежит на диске. (про секции с VirtualSize > SizeOfRawData, то бишь неинициализированные, я не умомянул - там некуда внедряться).

    Не уверен, что хорошая идея внедряться в заголовок (насчет того, чтобы поле SizeOfHeaders двигать - не уверен, хотя можно попробовать добавить к нему, разумеется, кратное FileAlignment значение).
    Еще можно расширить какую-нибудь секцию. Наиболее просто - последнюю, тогда не придется двигать остальные. Можно расширить и первую, тогда нужно будет пройтись по таблице секций и добавить во все поля PointerToRawData дельту в размере.
    Но немногие секции в середине можно будет расширить - только до границы на SectionAlignment вверх. Если ее пересечь, изменится виртуальный размер секции и полетят все ссылки на последующие секции в коде. Но поскольку у многих ехе SectionAlignment сильно больше FileAlignment, то лишние два-три кило присунуть можно всяко. Ну это если я ниче не перепутал, чето спать хочется, мог и намудрить где-нибудь.
     
  3. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    Если не двигать секции в памяти и расчитывать только на выравнивание то

    IMAGE_FILE_HEADER.SizeOfOptionalHeader
    IMAGE_SECTION_HEADER[].PointerToRawData

    Если двигать секции в памяти

    IMAGE_FILE_HEADER.SizeOfOptionalHeader
    IMAGE_OPTIONAL_HEADER.SizeOfHeaders
    IMAGE_OPTIONAL_HEADER.SizeOfImage
    IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint;
    IMAGE_OPTIONAL_HEADER.BaseOfCode;
    IMAGE_OPTIONAL_HEADER.BaseOfData;
    IMAGE_DATA_DIRECTORY[].VirtualAddress
    IMAGE_SECTION_HEADER[].VirtualAddress
    IMAGE_SECTION_HEADER[].PointerToRawData
    IMAGE_SECTION_HEADER[].PointerToRelocations
    +поправить фиксапы

    вроде все
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Двигать секции можно только с учетом, что их виртуальные адреса останутся прежними. А значит, нельзя вылезать за границу SectionAlignment. То есть дописать в секцию можно только ALIGN_UP(SizeOfRawData,SectionAlignment) - SizeOfRawData.
    Иначе изменится виртуальный размер, придется двигать виртуаьлные адреса и везде менять ссылки - почти нереально. Даже если в ехе есть релоки (что будет весьма странно).
     
  5. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    В посте нет ничего ни о наличии релоков ни о типе PE
    Если релоки есть, либо есть возможность их восстановить, то адреса секций сменить можно
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    ...
    ====

    даже если и есть релоки, они не помогут для адресов вне секции кода.
     
  7. dermatolog

    dermatolog Member

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    406
    Адрес:
    Екатеринбург
    Раздвинуть хидер без всяких правок можно только если размер хидера будет меньше чем RVA первой секции. Для этого достаточно будет прописать новый размер SizeOfHeaders (ну и ессно физически пододвинуть все секции в файле). А вот если размер заголовка будет налезать на RVA первой секции, то придется двигать все секции ниже по памяти - тут без пересчета RVA секций, директорий, релоков и прочих радостей уже не обойтись.
     
  8. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    Код (Text):
    1. // IMAGE_FIRST_SECTION doesn't need 32/64 versions since the file header is the same either way.
    2.  
    3. #define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER)        \
    4.     ((ULONG_PTR)ntheader +                                              \
    5.     FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) +                 \
    6.     ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader   \
    7.     ))
     
  9. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    что за адреса? можно пример?