Перехват обращения к определенному адресу

Тема в разделе "WASM.BEGINNERS", создана пользователем _nic, 30 ноя 2011.

  1. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Допустим по адресу 0х30000 есть выделенная через VirtualAlloc страница памяти.Можно ли как то из юзермода,засечь что в эту страницу пытаються записать какие то данные,еще до того как они будут записанны?Ну и желательно определить поток из которого такая попытка происходит,что бы приморозить его на время.
    Или это не реально реализовать(в юзермоде конечно же)в адресном пространстве своей проги.
     
  2. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Есть два варианта:

    1. Поставить аппаратную точку останова. Устанавливается с помощью отладочных регистров (dr0-dr7), доступ к которым в user mode возможен через контекст потока (SEH, SetContextThread).

    2. Выставить странице, в которой находится целевой адрес, атрибут PAGE_READ_ONLY и отлавливать исключения, вызванные записью в страницу. Но в этом случае исключение будет происходить при записи в любой адрес, принадлежащий странице. Чтобы понять, к какому именно адресу произошло обращение, нужен контекст потока на момент исключения + дизассемблер.

    В общем, для отслеживания обращения к ячейке памяти 1/2/4 байт лучше использовать отладочные регистры (возможно контролировать только 4 * кол-во процессоров/ядер адресов), а для отслежвания более крупных регионов -- изменения атрибутов страницы.
     
  3. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.315
    _nic
    указывает на то, что запись будет производиться из контекста того же процесса...
    указывает на то, что запись будет производиться из контекста другого процесса...
    так все же, я не понял, запись будет производиться из контекста текущего или другого процесса?
     
  4. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Текущего.
    Я просто ломаю голову как помирить сплайсинг с потоками.Ведь даже если отслеживать все потоки,не факт что нужный поток будет "заморожен" до того как он стукнеться по восстановленному адресу(
     
  5. Malfoy

    Malfoy New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2012
    Сообщения:
    698
    Mika0x65
    1.
    A. Не годится. В ядре Dr-контекст ядерный. Посему запись из ядра отслежена не будет.
    B. Контекст локален для потока, посему в других потоках при не настроенном Dr-контексте останова не будет.
    C. Число точек останова и их размер фиксирован, нельзя отследить обращение к произвольному, заранее не известному адресу.

    2.
    A. Не нужен контекст, дизассемблер также не нужен. В информации про фолт сохраняется линейный адрес, к которому произошло обращение(Cr2) и тип доступа.
    B. При записи посредством ядра или прочих функций, не разворачивающих фолт, будет возвращён код ошибки и дальнейшее поведение потока не определено, он к примеру может завершиться. Чтобы это отследить следует пропатчить системный шлюз и проверять возвращаемое значение на STATUS_ACCESS_VIOLATION и передаваемые параметры.

    Следует использовать маршрутизацию. Часть кода переносится в буфер, там изменяется и поток переключается на этот код. Это единственно стабильное решение.