Допустим по адресу 0х30000 есть выделенная через VirtualAlloc страница памяти.Можно ли как то из юзермода,засечь что в эту страницу пытаються записать какие то данные,еще до того как они будут записанны?Ну и желательно определить поток из которого такая попытка происходит,что бы приморозить его на время. Или это не реально реализовать(в юзермоде конечно же)в адресном пространстве своей проги.
Есть два варианта: 1. Поставить аппаратную точку останова. Устанавливается с помощью отладочных регистров (dr0-dr7), доступ к которым в user mode возможен через контекст потока (SEH, SetContextThread). 2. Выставить странице, в которой находится целевой адрес, атрибут PAGE_READ_ONLY и отлавливать исключения, вызванные записью в страницу. Но в этом случае исключение будет происходить при записи в любой адрес, принадлежащий странице. Чтобы понять, к какому именно адресу произошло обращение, нужен контекст потока на момент исключения + дизассемблер. В общем, для отслеживания обращения к ячейке памяти 1/2/4 байт лучше использовать отладочные регистры (возможно контролировать только 4 * кол-во процессоров/ядер адресов), а для отслежвания более крупных регионов -- изменения атрибутов страницы.
_nic указывает на то, что запись будет производиться из контекста того же процесса... указывает на то, что запись будет производиться из контекста другого процесса... так все же, я не понял, запись будет производиться из контекста текущего или другого процесса?
Текущего. Я просто ломаю голову как помирить сплайсинг с потоками.Ведь даже если отслеживать все потоки,не факт что нужный поток будет "заморожен" до того как он стукнеться по восстановленному адресу(
Mika0x65 1. A. Не годится. В ядре Dr-контекст ядерный. Посему запись из ядра отслежена не будет. B. Контекст локален для потока, посему в других потоках при не настроенном Dr-контексте останова не будет. C. Число точек останова и их размер фиксирован, нельзя отследить обращение к произвольному, заранее не известному адресу. 2. A. Не нужен контекст, дизассемблер также не нужен. В информации про фолт сохраняется линейный адрес, к которому произошло обращение(Cr2) и тип доступа. B. При записи посредством ядра или прочих функций, не разворачивающих фолт, будет возвращён код ошибки и дальнейшее поведение потока не определено, он к примеру может завершиться. Чтобы это отследить следует пропатчить системный шлюз и проверять возвращаемое значение на STATUS_ACCESS_VIOLATION и передаваемые параметры. Следует использовать маршрутизацию. Часть кода переносится в буфер, там изменяется и поток переключается на этот код. Это единственно стабильное решение.