Перехват API

Тема в разделе "WASM.BEGINNERS", создана пользователем Wereww, 13 июн 2009.

  1. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    Clerk
    Хм, интересная штука с запрещением записи, если потребуеться обязательно применю, а обойти как ее можно? закрыть хендел?
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    SPA
    Никак, можно проделать обратные действия, тоесть заменить проекции не файловой секции на приватную память, но это доселе видимо никто не юзал.
     
  3. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    MSoft
    Ну автор же сказал, что не знает, какие именно функции восстанавливать.
    Clerk
    Интересный способ. Странно, что после этого ZwProtectVirtualMemory не работает... Т.е. мне странно. :) Я не ковыряюсь в ядре.
    Но не сработает, если приложению самому требуется писать в секции, в которые пишет чит. Хотя выглядит гораздо проще, чем всякие морфинги.
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    l_inc
    Почемуже не сработает запись самого приложения, создана разделяемая память и для записи в секцию кода нужно писать во вторую проекцию секции, данные отображаются в файл подкачки, а из него во вторую проекцию сразу. Тоесть пишём по одному адресу, а данные появляются по другому. Это кстати и может являться способом обнаружения снятия подобной защиты - взводим флажёк во второй проекции и читаем его с первой, которая на запись не доступна. Если он изменился - значит защита не снята.
     
  5. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Можно проэмулировать запись, тоесть чтобы инструкция пишущая по адресу в проекцию защищённую от записи выполнилась успешно без исключений. Делается элементрано - устанавливается диспетчер исключений, который проверит адрес куда выполнялась запись и выполнит трассировку инструкции с заменой селектора. Либо что более сложно сам запишет необходимые данные во вторую проекцию.
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Clerk
    Я имел в виду тот код, ссылку на который Вы дали. Вы ведь потом освобождаете проекцию с копиями секций. А если устанавливать диспетчер исключений, то в обработчике надо ещё проверять, кто именно пытался писать в защищённые секции. А это по идее может быть нелегко. Да и одним обработчиком исключений в юзермоде, если я правильно понимаю, не обойтись. Надо ещё за NtWriteVirtualMemory следить. Или нет?
     
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Нет. Секция то одна(обьект секция), просто мапяться разные блоки из неё. Освобождается сдесь, просто мне не нужно было писать туда вот и анмапнул. Обработчика исключений вполне достаточно и весьма просто реализуется, там гдето был код уже не помню и статья на вт. Ядро тут не причём и про NtWriteVirtualMemory ничего знать не нужно и следить за ним.
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Clerk
    Если приложению требуется записать код в защищённую секцию, и оно использует для этого WriteProcessMemory, то исключение не возникнет. Просто будет возвращена ошибка.
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Если средствами процессора. Например подобным способом лдр защищалась - при её парсинге/изменении например при загрузке модуля возникают исключения, которые обрабатывались, заменялся селектор и инструкция перезапускалась в пошаговом режиме. Это позволяло писать в копию блока.
     
  10. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Clerk
    Над Вашими постами надо долго медитировать, чтобы вникнуть в смысл. В общем 15 минут медитировал и ни слова не понял. :) Даже не уверен, мне ли это ответ. Чисто интуитивно могу предположить, что имеется в виду аппаратный брейкпоинт на ZwProtectVirtualMemory и на ZwWriteVirtualMemory.
    Но так всё-таки надо за ними следить?
     
  11. Wereww

    Wereww Дмитрий

    Публикаций:
    0
    Регистрация:
    13 июн 2009
    Сообщения:
    55
    Аналогично. Возможно предложение и тупо но что если задействовать сплайсинг всех API ? Прошлый вариант с 3 ф-ями не помог - чит пашет.
     
  12. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    l_inc
    Не нужно не за чем следить. Что именно вам не понятно ?
     
  13. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Clerk
    Ещё раз. Защищаемое приложение пытается записать в свою секцию (защищённую Вашей процедурой с помощью двойного копирования) с помощью WriteProcessMemory. Но WriteProcessMemory обламывается при вызове ZwProtectVirtualMemory и возвращает ошибку. Исключение при этом не возникает. Как Вы предлагаете обрабатывать такую ситуацию? Ведь приложение ожидает, что WriteProcessMemory выполнится успешно?
     
  14. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    l_inc
    Зачем приложению себе писать в память посредством сервиса, может есчо текущий процесс открыть а потом хэндл в этот сервис передать :)
     
  15. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Clerk
    Ну зачем - это уже второй вопрос. :) ИМХО вполне реальная ситуация. Особенно если не хочется задумываться о правах доступа на секцию, вызываешь себе WriteProcessMemory и не ожидаешь никаких проблем. Собсно об этом я и писал в посте 26.
     
  16. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    l_inc
    Хватайте сервис и обрабатывайте, что проблема чтоли.
     
  17. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Clerk
    Вооот... с чего начали, к тому и пришли. :) Т.е. установка перехвата на ZwWriteProcessMemory. В купе с обработкой исключений обычной записи да ещё проверкой, а не чит ли эту запись пытается выполнить (проверка по идее нетривиальная), получится нехилых себе размеров код.
    Так вот к чему это я всё... Вместо изобретения панацеи, проще посмотреть, что же делает чит. Для частного случая всё может оказаться гораздо проще.
    Хотя Ваш метод двойного копирования довольно удачный. Если приложению не нужно писать в себя, то от юзермодного перехвата отлично защищает. Особенно если учесть, что Ваш код нагружен сплошь и рядом проверками на трассировку, то по сути код получается компактный и несложный.
     
  18. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    l_inc
    какието сказки придумываешь имхо
     
  19. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    l_inc
    Какие перехваты, это защита от записи, а не её обход. Не пишет - вот и отлично. Легальное приложение в секции кода не пишет(IAT лоадер заполняет). В аттаче простой пример хорошо отражающий запись если приложению она будет нужна в защищённую проекцию. Единственная проблема это инструкция movs, хотя можно её эмулировать.
     
  20. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    640
    ...Ребята, я нашёл "свой" способ перехватывания API-функций. Ну, он, конечно, может не совсем мой, но нашёл я его самостоятельно. Мэтры, может, и не обратят внимания, а новичкам пригодится, пусть ковыряются. Не без недостатков, конечно. Так, если api-функции перехватываются несколькими потоками, то он не годится. То есть его надо много усовершенствовать в этом случае.
    Зато он прост и понятен. Никаких тебе подмен dll
    Увидел тему и решил сюда его пихнуть. Поделиться хочется.

    Суть.
    1) Узнаём библиотеку *.dll, в которой прописана функция, которую нам надо перехватить
    2) Открываем эту библиотеку в отладчике OllyDbg (способов много. Допустим, пишем минимальную прогу, к которой статически присоединяем эту библиотеку. И открываем эту прогу в OllyDbg)
    3) В OllyDbg ищем эту библиотеку, секцию кода, в частности.
    4) "Идём" в конец этой секции, в незадействованное пространство, где они ноли.
    5)Пишем по понравившемуся нам адресу (например, 0xcafebabe) код, который должен выполниться вместо перехваченной функции (Ну, то есть в различных вариантах, найденных в интернете, свободное место для кода выделяет специальная функция- я забыл, какая, поскольку ей не пользовался. А в моём варианте вручную ищем это свободное место, где одни ноли.)
    6)Дампируем этот участок. Сохраняем, допустим, в какой-нибудь текстовый файл
    7)Запускаем прогу, в которой необходимо осуществить перехват api-функции
    8)С помощью функции WriteProcessMemory прописываем дампированный нами код по адресу 0xcafebabe (помним, что там одни ноли и нет никаокого полезного кода)
    9)С помощью функции WriteProcessMemory прописываем в начало перехватываемой функции прыжок на 0xcafebabe (а там уже "наш" код)

    Всё, при следующем вызове api-функции, о которой идёт речь, перехват сработает
    ...А вот насколько он успешно завершится- зависит от написанного нами кода.
    Так, в конце его наверное (!), должно быть что-то типа
    Код (Text):
    1. mov edi, edi
    2. push ebp
    3. mov ebp, esp
    4. jmp <адрес перехватываемой функции+5>
    Про оконцовку кода: вопрос этот для себя я решил, кто и так знает, ему объяснять не надо, а кто не знает, пусть сами это освоят.
    Простые перехваты делает на "ура".
    А для более сложных нужно разбираться самим. Так, в многопоточном приложении мне не удалось (пока) корректно вызвать из прописанного кода функцию (CreateProcess)

    Наконец, если возможно запустить прогу непосредственно в отладчике, то ещё все проще.
    Запускаем её в отладчике, прописываем по адресу 0xcafebabe нужный нам код (вручную, понятно) и прописываем по адресу функции прыжок на этот код.
    Недостаток: если код длинный, то устанешь каждый раз прописывать (вручную ведь). Достоинство: и отладка и внедрение api-функции- всё в одном флаконе. Наблюдай за поведением программы, изменяй, что тебе надо он-лайн, что называется. Только не увлекайся слишком, а то закалебёшься отладчик перезапускать.