Покритикуйте инжект

Тема в разделе "WASM.WIN32", создана пользователем GoldFinch, 25 янв 2010.

  1. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    Задача такая:
    Внедрить .dll написанную на ЯВУ в программу, не патча ее на диске. При этом программа не должна ничего понять, если вдруг попытается. Длл не малварная, пользователь знает об инжекте, но желательно чтоб антивирусы\фаерволы сильно не орали.
    Решение должно быть несложным, но в то же время эффективным. Несложным - значит юзермод. Должно работать на XP,висте,7ке.

    Пока что я остановился на коде, который
    создает процесс с флагом CREATE_SUSPENDED,
    сохраняет eip потока (GetThreadContext),
    выделяет в процессе память и записывает туда шеллкод (VirtualAllocEx+WriteProcessMemory),
    предварительно в шеллкод записывается начальный eip потока и RVA LoadLibraryA
    меняет eip на адрес шеллкода (SetThreadContext),
    запускает поток (ResumeThread).
    CloseHandle не используются, т.к. процесс-launcher всеравно после этого завершается.

    Шеллкод в свою очередь
    пихает в стек начальный адрес потока как адрес возврата, сохраняет все регистры
    получает базу kernel32.dll, при этом используются допущения, что начальный адрес потока находится в kernel32.dll, что образ kernel32.dll в памяти не поврежден, и что все его страницы доступны для чтения,
    добавляет к базе kernel32.dll RVA LoadLibraryA, и вызывает ее, загружая нужную длл,
    затем восстанавливает регистры и возвращается на начальный адрес потока.

    Собственно для меня основная непонятность - это безопасно ли вообще вызывать LoadLibrary до инициализации процесса в юзермоде, не случится ли чего?

    Просьба высказываться по существу дела, а не "фасм фигня, код неоптимальный, ТС неуч, и т.п."

    Сырец в аттаче.
     
  2. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Шеллкод получает управление уже после завершения базовой инициализации – в конце концов, до этой инициализации в адресном пространстве процесса нет даже kernel32.dll.
    К тому моменту, когда шеллкод начинает выполнение, все прямо и косвенно импортируемые длл уже промаплены, их релоки настроены, а точки входа вызваны с кодом DLL_PROCESS_ATTACH. Также уже вызваны tls-колбеки, длльные и экзешные. Из точек входа и tls-колбеков модули могут определить, что eip начального контекста подменён (не совпадает со стандартной ntdll!RtlUserThreadStart – ну или что там для конкретной оси). Определение несоответствия не составляет труда – третьим параметром в точки входа\tls-колбеки передаётся указатель на [псевдо]начальный контекст.
    Почему так? Очень просто – перед началом выполнения первичной функции потоку доставляется инициализирующая APC с rip == ntdll!LdrInitializeThunk. Т.е. актуальное выполнение начинается именно оттуда.

    >начальный адрес потока находится в kernel32.dll
    Для w7 это ntdll!RtlUserThreadStart. Впрочем, это не важно здесь.

    >безопасно ли вообще вызывать LoadLibrary до инициализации процесса в юзермоде?
    Как можно видеть, процесс к тому моменту уже почти проинициализирован. Так что в тот момент – да, считаем что вполне безопасно. Раньше (до загрузки kernel32) – можно воспользовать ntdll!LdrLoadDll.
     
  3. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    GoldFinch
    Я когда-то писал тулень для мониторинга мемори ликов, и там почти так же пробовал инжектиться, так вот наблюдались иногда при этом очень станные дедлоки, для некоторых приложений. Тогда мне опыта\знаний не хватило, чтобы расковырять за разумное время из-за чего это происходит, и я стал использовать то, что, кажется, в eax энтри пойнт хрантся, если после "create suspended" снять контекст, ну это для xp, а про висту и семерку мне не нужно было тогда париться.
     
  4. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Обязательно ли делать инжект перед запуском главного потока приложения?
     
  5. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    GoldFinch
    Когда поток перейдёт к исполнению кода по адресу в регистре Eip контекста инициализация процесса будет завершена. Поток не отсюда начинает исполняться, ядро сохранит в стеке потока пользовательский контекст, после чего загрузит ссылку на процедуру инициализации процесса и доставит юзермодную стартупапк, в конце которой пользовательский контекст будет загружен из стека в процессор, в общем как и сказал Sol_Ksacap. Поэтому вам можно не заботится про инициализацию процесса.
    Sol_Ksacap
    Единственное причина там оказаться это подгрузка верификатора, сразу за которой следует подгрузка kernel32. Есчо ранее лодер не инициализирован.