HLP, как перехватить функции до инициализации самого приложения

Тема в разделе "WASM.WIN32", создана пользователем mcbain, 12 окт 2008.

  1. mcbain

    mcbain New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2008
    Сообщения:
    18
    Мне нужно перехватить кое какие функции из kernel32.dll в одном определённом приложении.
    Приложение я запускаю сам через CreateProcess.

    Для перехвата функций я раньше использовал стандартный метод подгружения своей дллки (подгружение делается через VirtualAllocEx и CreateRemoteThread), и потом переписывание начала функций уже из дллки.

    Этот метод работал без проблем, на уже запущенном приложении.

    Но сейчас я стартую приложение с CREATE_SUSPENDED и мне нужно перехватить функции до того как приложение запустится и начнёт инициализироваться. (Я перехватываю вызовы к CreateFile, и буду подставлять свои имена файлов настроек).

    Проблема заключается вот в чём:
    Старый метод не работает, так как я не могу сделать свой поток в чужом приложении до того как его первый поток запустился, потому что тогда всё вылетает с ошибкой. (насколько я понимаю, CreateProcess всего лишь создаёт объект ядра "процесс", но не инициализирует его никак, это делается в начале самого первого потока. По этому система не разрешает никаким другим потокам запускаться до того как первый поток всё проинициализирует)

    Теперь я вижу несколько вариантов:
    1) либо как-то изменять экзешник, так чтобы моя длл загружалась в процесс "легальным" способом через таблицу импорта. Тогда она сможет всё перехватить до того как управление перейдёт в entry point приложения. (через dllMain())

    2) Либо может как-то пропатчить entry point приложения в экзешнике, и вставить туда SuspendThread(GetCurrentThread)? И потом из лоадера ждать пока основной поток остановится, тогда я узнаю что инициализация процесса прошла успешно и пришло время создавать свой поток как я и раньше делал...

    3) как-то пропатчить entry point приложения в памяти, вставить свой CALL? Но как? Ведь насколько я знаю, до того как самый первый поток произведёт инициализацию, даже сам код приложения ещё в память не загружен, нечего патчить будет...

    4) ещё идея может изменять поле Entry Point в PE-заголовке, ведь на момент когда CreateProcess возвращает управление, заголовок то уже должен быть загружен? Но тогда мой инжект должен будет находиться внутри секции кода? а это не получится наверное через VirtualAlloc.

    В общем у меня много разных идей, и никакие из них мне не нравятся. Как самым простым образом сделать то что я хочу? Имеет ли какой-то из моих вариантов смысл? Если лучше всего патчить экзешник, как это легче всего сделать?
    Чё делать короче??
    Пардон если непонятно написал, задавайте вопросы, попытаюсь разъяснить.
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    http://www.wasm.ru/forum/viewtopic.php?pid=262266
    #15, 16
     
  3. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    Имя библиотеки, которая загрузится во все созданные процессы с того момента, как ты создашь этот ключ и до того как удалишь.
    Код (Text):
    1. HKEY_LOCAL_MACHINE\Software
    2. \Microsoft\Windows NT\
    3. CurrentVersion\Windows\APPINIT_DLLS
    И в DllEntry делай с приложением что душе угодно.
     
  4. barton

    barton New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2008
    Сообщения:
    164
    Адрес:
    Czechoslovakia
    Ну так надо поставить засуспендженому "родному" первому потоку контекст с новым eip, который будет указывать на твой код и запустить его, далее джамп обратно на ЕП.

    ээ.. CreateProcess вообще создает новый юзермодный процесс, включая объекты ядра, нотификацию csrss и тд

    уже будет в памяти
    проэкция уже создана после вызова CreateProcess

    вообще плохо понятно что у тебя за проблема ...
     
  5. mcbain

    mcbain New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2008
    Сообщения:
    18
    Спасибо всем уже ответившим!! (проблема пока остаётся ))

    Clerk
    Видимо прикольный метод, но не очень понял до конца в чём он состоит. Каким образом делается хук создания потоков? (system-wide или для каждого процесса?)

    slavanap
    Да видимо это и есть самый простой метод. Опасаюсь тока разных антивирусов, которым может быть такие выкрутасы не понравятся, к тому же придётся мою прогу тока узать в администратор юзерах. К тому же желательно было бы найти решение которое будет инжектировать библиотеку только в то единственное приложение которое я для этого запускаю. (ну хотя конечно код проверки процесса в длл запихать несложно)

    barton
    А так я кстати и пытался делать сначала. Напоролся на тот факт что когда ты запускаешь новый процесс с CREATE_SUSPENDED, то EIP потока указывает не на entry point приложения, а на какой-то код в винде, который по моему наверное и занимается подгрузкой библиотек и прочей инициализацией процесса.

    В общем нифига не получилось, приложение просто вылетело, в дллку управление так вообще и не попало никогда (она у меня лог пишет) (но лог тоже пробовал отключать, результат тот же)
    Ещё я смотрел через syser, сразу после создания процесса но до того как поток запустится, попытался во первых перейти на адрес entry point приложения, во вторых перейти в адреса kernel32.dll, так и в обоих случаях syser не смог показать мне дизассемблерный код, значит ни секция кода приложения, ни kernel32 ещё даже загружены не были.

    Код (Text):
    1. проэкция уже создана после вызова CreateProcess
    по ходу тока заголовок в памяти, остальное ещё нет.

    Код (Text):
    1. вообще плохо понятно что у тебя за проблема ...
    Попытаюсь максимально точно выразиться: мне надо без особых загонов, и желательно через лоадер перехватить в отдельно взятом приложении функции kernel32.dll, до того как приложение запустится со своего entry point.
    То есть чтобы в процессе инициализации приложению уже были подсунуты перехваченные функции.
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    mcbain
    А вот типа CreateRemoteThread в рабочий процесс все АВ просто обожают.
    BaseProcessStartThunk этот код называется.
    Подменяйте не eip, а eax. И возвращайтесь после исполнения кода на EP. Работать будет не везде, но для большинства процессов будет работать.
    Рано смотрели, видимо.
    Ерунда. Есть почти всё. SEH'а только нету.
     
  7. mcbain

    mcbain New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2008
    Сообщения:
    18
    А на что подменять? На абсолютный адрес моей инициализации?
    Можно поподробнее, почему это может помочь? (всмысле, почему вдруг eax) Или ссылочку какую..
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    mcbain
    Ну... эм... если Ваша "инициализация" - это внедрённый в процесс код, то да.
    Во время старта процесса в eax хранится EP, на который будет передано управление после исполнения BaseProcessStartThunk. Чем подмените eax, туда и будет передано управление. Более подробно, но вкратце, о создании процесса можете почитать у Нэббета. Там это упоминается.
     
  9. mcbain

    mcbain New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2008
    Сообщения:
    18
    Офигеть, и правда работает!! (всё равно прога вылетает с ошибкой, но в логах видно что дллка загрузилась по крайней мере). Попробую отладить и понять почему всё вылетает. (если туже дллку загружать через реестр, всё работает как надо).
     
  10. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    mcbain
    Use your force, Jedi. :derisive:
    Скорее всего из-за того, что плохо контекст в подгружающем коде сохраняете. Один из худших вариантов - сбиваете стэк.