Вызов точки входа кодом

Тема в разделе "WASM.X64", создана пользователем Rel, 23 авг 2010.

  1. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.320
    внедряю в другой x64-процесс x64-exe файл, настраиваю ему релоки, импорты... вызываю точку входа внутри чужого процесса с помощью кода:
    Код (Text):
    1. nop
    2. mov rax, EntryPoint
    3. call rax
    возникает эксес вайолейтинг внутри точки входа, глубоко после вызова MessageBox где-то в библиотеке lkp.dll... что в принципе странно, так как если делать CreateRemoteThread на EntryPoint, а не на код, то все прекрасно работает... более того, если тоже самое проделать в контексте текущего процесса (CreateThread на такой же код), то все так же прекрасно отрабатывает... x86-exe файл с аналогичным кодом тоже исполняется без проблем, как в текущем, так и в чужом процессе... сделал вывод, что вызов кодом что-то портит в стеке, но не могу понять что, и как... подскажите пожалуйста в чем может быть проблема?
     
  2. Flint_ta

    Flint_ta New Member

    Публикаций:
    0
    Регистрация:
    25 май 2008
    Сообщения:
    312
    Предположу что адрес возврата остается в стэке и может как-то влияет. Сделай переход на OEP так:

    push EntryPoint
    ret

    либо

    nop
    mov rax, EntryPoint
    jmp rax
     
  3. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    Правильно предполагаешь.
    А если быть точнее то это обусловлено новыми соглашениями по передаче аргументов.
     
  4. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.320
    спасибо, но можно поподробнее объяснить, почему адрес возврата может портить стек... дело в том, что после ret из EntryPoint поток должен вернуться на код с которого он стартовал (на инструкцию следующую за call rax)... далее за call rax происходит вызов ExitThread, это сделано для контроля того, что поток может уйти неизвестно куда, если PE-файл собирался с какой-нить левой CRT или если это вообще не PE-файл, а какой-нить независимый от базы кодец... соответственно EntryPoint во всех случаях без параметров, но если PE-файл является DLL, то в этом случае - три параметра (передаются через RCX, EDX, R8)...
     
  5. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    Значит подробнее.

    1. Перед вызовом функции т. е. непосредственно перед call`oм стэк должен быть выравнен на границу 16-байт.
    2. При написании программ на ассемблере становиться необходимым использование хорошо продуманного пролога и эпилога плюс макроса invoke. Я подчёркиваю что это именно минимум, если ты пытаешься написать, что-нибудь отличное Хеллоу Ворлда на Месседж Боксе. Также я видел что упаковщики сохраняют значения всех 16 регистров push/pop`aми.
     
  6. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.320
    да... большое спасибо! я по глупости упустил этот момент из виду... теперь перед вызовом делаю sub rsp, 8... на первичных тестах работает, как надо...

    это да, но все PE-файлы, что я гружу компилируются студией, то есть фактически мне важно чтобы стек был выровнен до вызова EntryPoint, далее вопросы вызова уже решены компилятором...