А вот с COM-объектами и интерфейсами обертки работают как нельзя лучше. Для этого создается другой COM-объект, реализующий нужный нам интерфейс, к нему создатся аггрегированныйоригинальный com-объект, а перехватчик отдается тем кто с ним будет в дальнейшем работать. Если оригинальный COM-объект не поддерживает аггрегацию, то придется реализовать все его интерфейсы, и если у него нету никаких внутренних (недокументированных) интерфейсов, то, возможно, все и заработает.
Все это касается подмены API текущего процесса. Если понадобится перехватить вызов в чужом процессе, то следует выбрать любой из приведенных здесь методов, поместить их в DLL и закинуть ее в чужой процесс. Это тема для отдельного разговора и здесь рассматриваться не будет.
Использованные статьи и литература
Форматы PE и COFF файлов
Расширение MSGINA – это просто
API Spying Techniques for Windows 9x, NT and 2000
APIHijack
EliCZ ApiHooks
Контроль вызова API функций в среде систем Windows '95, Windows '98 и Windows NT
Это все на сегодня. Пока!
Алекс Jenter jenter@rsdn.ru Duisburg, 2001. Публикуемые в рассылке материалы принадлежат сайту RSDN.
Программирование на Visual C++
Выпуск №66 от 3 марта 2002 г.
Здравствуйте, дорогие подписчики!
Помнится, когда-то я уже публиковал статью, посвященную вопросу многозадачности и синхронизации потоков (нитей). Сегодня я предлагаю вам вернуться к этой теме, но уже на более подробном уровне. Вместе с Павлом Блудовым мы подробно рассмотрим один из объектов синхронизации – критические секции, и причем не просто их применение, но и их внутреннее устройство.
СТАТЬЯ
Критические секции
Автор: Paul Bludov
Демонстрационный проект CSTest(7.8kb)
Файл csdbg.h(1.8kb)
Файл csdbg2.h (2.5kb)
Классы-обертки для критических секций cswrap.h(0.5kb)
Введение
Критические секции – это объекты, используемые для блокироки доступа к некоторорым важным данным всем нитям (threads) приложения, кроме одной, в один момент времени. Например, имеется переменная m_pObject и несколько нитей, вызывающих методы объекта, на который ссылается m_pObject. Причем эта переменная может изменять свое значение время от времени. Иногда там даже оказывается нуль. Предположим, имеется вот такой код:
// Нить #1
void Proc1() {
if (m_pObject) m_pObject->SomeMethod();
}
// Нить #2
void Proc2(IObject *pNewObject) {
if (m_pObject) delete m_pObject;
m_pObject = pNewobject;
}
Тут мы имеем потенциальную опасность вызова m_pObject->SomeMethod()после того, как объект был уничтожен при помощи delete m_pObject. Дело в том, что в системах с вытесняющей многозадачностью выполнение любой нити процесса может прерваться в самый неподходящий для нее момент времени и начнет выполняться совершенно другая нить. В данном примере неподходящим моментом будет тот, в котором нить #1 уже проверила m_pObject, но еще не успела вызвать SomeMethod(). Выполнение нити #1 прервалось, и начала исполняться нить #2. Причем нить #2 успела вызвать деструктор объекта. Что же произойдет, когда нить #1 получит немного процессорного времени и вызовет-таки SomeMethod()у уже несуществующего объекта? Наверняка что-то ужасное.
Именно тут приходят на помощь критические секции. Перепишем наш пример.
// Нить #1
void Proc1() {
::EnterCriticalSection(&m_lockObject);
if (m_pObject) m_pObject->SomeMethod();
::LeaveCriticalSection(&m_lockObject);
}
// Нить #2
void Proc2(IObject *pNewObject) {
::EnterCriticalSection(&m_lockObject);
if (m_pObject) delete m_pObject;
m_pObject = pNewobject;
::LeaveCriticalSection(&m_lockObject);
}
Код, помещенный между ::EnterCriticalSection() и ::LeaveCriticalSection() с одной и той же критической секцией в качестве параметра, никогда не будет выполняться параллельно. Это означает, что если нить #1 успела "захватить" критическую секцию m_lockObject, то при попытке нити #2 заполучить эту же критическую секцию в свое единоличное пользование, ее выполнение будет приостановлено до тех пор, пока нить #1 не "отпустит" m_lockObject при помощи вызова ::LeaveCriticalSection(). И наоборот, если нить #2 успела раньше нити #1, то та "подождет", прежде чем начнет работу с m_pObject.
Работа с критическими секциями
Что же происходит внутри критических секций и как они устроены? Прежде всего, следует отметить, что критические секции это не объекты ядра операционной системы. Практически вся работа с критическими секциями происходит в создавшем их процессе. Их этого следует, что критические секции могут быть использованы только для синхронизации в пределах одного процесса. Теперь рассмотрим критические секции поближе.
Читать дальше