В предыдущей записи было обсуждение каким образом можно установить свой обработчик. Собственно код+экзе [в посте он бы выглядел просто отвратительно] для 64-бит
http://www.sendspace.com/file/yf28iu
Коротко о том, что я делаю. Получаю адреса лока для LdrpInvertedFunctionTable и самой LdrpInvertedFunctionTable. Для поиска переменных применяю дизассемблер distorm (его либу, кстати надо пересобирать под amd64).Затем в блокирую обращения к таблице. Ищу свой модуль, удаляю инфу о нем из кеша, обнуляю в пе-заголовке IMAGE_DIRECTORY_ENTRY_EXCEPTION. Разблокирую кеш. Добавляю свой обработчик, копирую старую ExceptionDirectory. После этого небольшая проверка на сохранность старых хендлеров и вызов нового.
Тест был на vista,7,xp (64).
Distorm
http://ragestorm.net/distorm/
скрины тестов
win7
winxp
vista



Комментариев: 2
Auto Code Review:
>main:
>case 7:
>//Seven
NtMajorVersion(Seven) == 6
>PatchLdrpInvertedFunctionTable:
>//затираем запись о нужном модуле в LdrpInvertedFunctionTable
>pInv->Entries[i].ImageBase=pInv->Entries[pInv->Count-1].ImageBase;
>…
(!) Для этой таблицы выполняется бинарный поиск – при наличии там многих модулей твой хитрый ход смутит винду. Теоретически можно даже не убирать запись из таблицы, а лишь обнулить одно поле – pInv->Entries[i].FunctionTable. FunctionTable – это самое первое поле структуры INVERTED_FUNCTION_TABLE_ENTRY (по крайней мере в 6.1.7600.16385 и 5.2.3790.3959):
0:000> dt INVERTED_FUNCTION_TABLE_ENTRY
ntdll!INVERTED_FUNCTION_TABLE_ENTRY
+0×000 FunctionTable : Ptr64 Void
+0×008 ImageBase : Ptr64 Void
+0×010 SizeOfImage : Uint4B
+0×014 SizeOfTable : Uint4B
Кстати, ещё способ залочить таблицу – добавить векторный хендлер исключений и установить DebugRegister-бряк доступа к какому-нибудь полю таблицы, после чего вызвать исключение. Винда залочит таблицу и обратится к её полю – здесь будет вызван наш векторный обработчик, при залоченной таблице, да. Преимущество – не надо выбирать способ залочки. Главный недостаток – таблица будет залочена только для чтения, так что будут допустимы только минимальные её изменения.
>Теоретически можно даже не убирать запись из таблицы, а лишь обнулить одно поле – pInv->Entries[i].FunctionTable.
Да, отработало хорошо на всех имеющихся системах.
>FunctionTable – это самое первое поле структуры INVERTED_FUNCTION_TABLE_ENTRY (по крайней мере в 6.1.7600.16385 и 5.2.3790.3959)
на висте тоже так
>NtMajorVersion(Seven) == 6
Действительно, недосмотр( Исправлено