EXE руками (помогите выловить ошибку)

Тема в разделе "WASM.BEGINNERS", создана пользователем Kozyr__, 23 фев 2006.

  1. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    Приветствую.



    Хочу разобраться с РЕ. Здесь есть пример создания PE-файла руками. Я повторил (мне кажется полностью - 1:1) код, но при запуске выдает ошибку - "не является пирложением Win32".



    Что сделал не правильно?

    [​IMG] 669234194__tiny.zip
     
  2. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    Вложил еще один вариант, в котором пытался уже с помощью меток вычислять все смещения.



    Пример запускается, но ничего не выдает. А PETool32.exe - вылетает на нем с ошибкой.



    [​IMG] 577289487__tiny.zip
     
  3. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.557
    Адрес:
    Russia
    Ну точно не скажу в чем трабла, сразу говорю что :

    1) База должно быть 00400000h

    2) выравнивание в 00001000h желательно.



    А вообще глянь аттач . Я когда-то собирал ручками ехе . Кода не нашел , но ехе остался.

    [​IMG] 1122679485__Hello.rar
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Kozyr__

    > "Что сделал не правильно?"

    Да всё =O

    Оно тебе вообще нужно ? Может для начала спецификацию почитать, да на примерах посмотреть что к чему ?!

    Очевидные ошибки:

    1) DOS stub по смещению 3Ch должна содержать Offset to PE Header (_pe)

    2) Неверно указано AddressOfEntryPoint = смещению в файле, а нужно RVA = SectionAlignment = 1000h

    3) Нужно NumberOfRvaAndSizes = 16, а не 1

    4) ImportTableAddress указан неверно = смещению в файле, а нужно RVA

    5) Все адреса и размеры секций неверные

    6) Метки code_ и data_ должны быть выравнены на FileAlignment = 200h

    7) Все адреса в коде неверные - опять смещения в файле, а нужны абсолютные RVA+ImageBase



    Видать ты не понимаешь разницу между смещением в файле (PointerToRawData) и RVA.

    Секции в файле выравниваются на FileAlignment = 200h, но при загрузке они "раздвигаются" и выравниваются по SectionAlignment = 1000h (4К размер страницы). Соответсвенно AddressOfEntryPoint, ImportTableAddress и VirtualAddress секций это RVA и их нужно записывать с учетом этой "раздвижки". Адреса данных и импорта в коде это вообще абсолютные адреса, т.е. RVA+ImageBase
     
  5. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    TermoSINteZ

    спасибо, аттач пригодился



    leo

    Может для начала спецификацию почитать, да на примерах посмотреть что к чему ?!



    Читал, но не все понял, поэтому решил попробовать на практике.



    Спасибо за разъяснения, теперь у меня код получше будет.



    Вложил пример, есть вопрос:

    - секция выровнивается по адресу 512 относительно начала файла. из-за этого выравнивания образовывается свободное место - байт 200. как этого избежать? (я пытался изменить знечения FileAlignment, SizeOfHeaders, PointerToRawData - но ничего не получилось).





    [​IMG] _1297740936__tiny.zip
     
  6. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    Еще подскажите: как сделать, чтобы с этой секцией можно было работать как с секцией данных?

    (выставленные характеристики секции 0E0000020h - не достаточно?).
     
  7. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    writable для секции получилось выставить - теперь работает (я неправильно к метке обращался).



    Подскажите как от выравнивания секции избавиться.
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Kozyr__

    1) Не знаю на какой винде ты проверяешь свой PE, но задавать NumberOfRvaAndSizes < 16 и VirtualSize секции = 0 - это не надежно, т.к. не все версии винды и не все отладчики и PE-тулзы это понимают. Например win98 выполняет недопустимую операцию при NumberOfRvaAndSizes < 5; OllyDbg не распознает начало описания секций (exe открывает, но ничего не анализирует и не показывает), PE Editor описание секций находит, но в таблицу директорий тупо лепит данные из описания секций. WinXP вроде как не допускает VirtualSize = 0 (этот вопрос обсуждался на борде flatassembler).

    Поэтому лучше не экспериментировать и по крайней мере задавать правильный VirtualSize = section_end-section_start. На таблице директорий тоже нет смыла экономить, если общий размер PE-заголовка получается менее 512 - все равно нужно выравнивание начала первой секции на 512.



    2) Чтобы читать\писать данные в секцию кода достаточно установить характеристики 0xE0000020h (даже 0xС0000020h, т.к. флаг 20h - IMAGE_SCN_CNT_CODE автоматом делает секцию исполняемой). Но следует иметь в виду, что запись в секцию кода на расстоянии менее 1Кб от исполняемого куска приводит к огромным штрафам на P4 и атлонах (сброс преддекодирования в кэше инструкций).



    3) Избавится от выравнивания секций на 200h в приложениях видимо нельзя (если только в драйверах). Этот вопрос задавался и обсуждался не раз, см. например тут

    И по спецификации FileAlignment - "The value should be a power of 2 between 512 and 64K inclusive", и по жизни, по кр.мере 9x и XP грязно ругаются на FileAlignment < 512
     
  9. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    leo

    Спасибо за развернутый ответ :)



    Не знаю на какой винде ты проверяешь свой PE

    На XP. Еще проверю на win98 - если с NumberOfRvaAndSizes = 2 будет работать, то оставлю как есть.



    VirtualSize выставил, выравнивание секции оставил 200h.



    Еще один вопрос созрел: как зарезервировать много неинициализированных данных (например, 1Mb) в этой секции?



    Я после метки section_end написал:
    Код (Text):
    1. hugeData        db      1024*1024 dup(?)
    2. end_:


    но при обращении к этой памяти вылетает ошибка. Пытался соответственно скорректировать для секции .VirtualSize и .SizeOfRawData - не помогло.
     
  10. Kozyr__

    Kozyr__ New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2005
    Сообщения:
    213
    Адрес:
    Ukraine
    Разобрался с данными. Нужно правильно выставить .SizeOfImage, .VirtualSize сделать большим, .SizeOfRawData - оставить как есть:
    Код (Text):
    1. dd      1000h + end_ - section  ; .SizeOfImage
    2. ...
    3. dd      end_ - section_         ; .VirtualSize
    4. dd      1000h                   ; .VirtualAddress
    5. dd      section_end - section_  ; .SizeOfRawData