Detours

Сижу, разбираюсь как Detours перехватывает функции Win32 API. Сама идея известна. В начало функции пишется безусловный JMP на функцию перехватчик. Для того, чтобы вызвать оригинальную функции, её код, на место которого помещается JMP, копируется в буфер и дополняется безусловным JMP на первую нетронутую инструкцию.

Интересно, однако, не это, а сколько дополнительных проверок делается, чтобы повысить надежность этого метода:

  1. Поверяется, не указывает ли указатель на перехватываемую функцию, не на саму функцию, а на элемент таблицы импорта. Если так, то в качестве указателя берется imm32 из JMP;

  2. Проверяется длина функции, причем считается, что функция может завершаться RET, JMP (разные варианты) или INT3. Последние два варианта не очень очевидны, хотя при взгляде на код становится ясно, что к чему;

  3. После JMP, завершающего скопированный из функции код, пишется INT3. То же, на всякий случай;

  4. Код установки перехватчиков завернут в транзакцию. Устанавливаются (или снимаются) либо все перехватчики, либо транзакция откатывается. Впрочем, 100% гарантии это все равно не дает;

  5. Ну и плюс ко всему поддерживается статическая установка перехватчиков, как раз чтобы избежать проблем с динамическим перехватом.

В этом списке не хватает только поддержки hotpatching. Код, скомпилированный с поддержкой hotpatching можно править прямо на ходу, не останавливая потоки в процессе.

comments powered by Disqus