Detours
Aug 4, 2008 · CommentsCode patchingПрограммированиеReverse engineering
Сижу, разбираюсь как Detours перехватывает функции Win32 API. Сама идея известна. В начало функции пишется безусловный JMP на функцию перехватчик. Для того, чтобы вызвать оригинальную функции, её код, на место которого помещается JMP, копируется в буфер и дополняется безусловным JMP на первую нетронутую инструкцию.
Интересно, однако, не это, а сколько дополнительных проверок делается, чтобы повысить надежность этого метода:
-
Поверяется, не указывает ли указатель на перехватываемую функцию, не на саму функцию, а на элемент таблицы импорта. Если так, то в качестве указателя берется imm32 из JMP;
-
Проверяется длина функции, причем считается, что функция может завершаться RET, JMP (разные варианты) или INT3. Последние два варианта не очень очевидны, хотя при взгляде на код становится ясно, что к чему;
-
После JMP, завершающего скопированный из функции код, пишется INT3. То же, на всякий случай;
-
Код установки перехватчиков завернут в транзакцию. Устанавливаются (или снимаются) либо все перехватчики, либо транзакция откатывается. Впрочем, 100% гарантии это все равно не дает;
-
Ну и плюс ко всему поддерживается статическая установка перехватчиков, как раз чтобы избежать проблем с динамическим перехватом.
В этом списке не хватает только поддержки hotpatching. Код, скомпилированный с поддержкой hotpatching можно править прямо на ходу, не останавливая потоки в процессе.