Доброго времени суток! Перехватываю NtOpenFile путем изменения адреса в таблице SST, переход на мой обработчик происходит, но при попытке обработать уже открытый файл при помощи NtQueryInformationFile и т.п. получаю ошибку. В идеале было бы обалденно считать первые 4 байта файла и проверить их на наличие сигнатуры (если совпадает - файл зашифрован). К сожалению, в С/С++ полный дуб . Делаю примерно так: Код (Text): .data? fsi FILE_STANDARD_INFORMATION <> true_eax dd ? ;..................... .code ;..................... NewNtOpenFile proc hFile:PHANDLE, des_acs:ACCESS_MASK, oa:POBJECT_ATTRIBUTES, \ iosb:PIO_STATUS_BLOCK, shr_acs:ULONG, op_op:ULONG mov true_eax,eax call DispatchHook ;снимаем хук mov eax, true_eax invoke NtOpenFile, hFile, des_acs, oa, iosb, shr_acs, op_op mov true_eax, eax .if eax == STATUS_SUCCESS invoke DbgPrint, $CTA0("File openeded\n") invoke NtQueryInformationFile, hFile, iosb, addr fsi, sizeof fsi, FileStandardInformation .if eax == STATUS_SUCCESS ;===== ; здесь код не выполняется ;===== .else invoke DbgPrint, $CTA0("NtQueryInformationFile not works\n") .endif .else invoke DbgPrint, $CTA0("Can't open file.\n") .endif call SetHook mov eax,true_eax ret NewNtOpenFile endp
А можно подробнее? Смотрел SoftIce'ом, перед вызовом call NtQueryInformationFile последним в стек отправляется push [ebp+08] - указатель на HANDLE. Что-то я уже совсем запутался (
NewNtOpenFile proc hFile:PHANDLE При вызове NtOpenFile все верно, передается hFile - указатель на хендл. При вызове NtQueryInformationFile должен передаваться не указатель, а сам хендл. Если на С, то *hFile. А на асме суть такая: lea eax,hFile mov eax,[eax] invoke NtQueryInformationFile, eax, iosb, addr fsi, sizeof fsi, FileStandardInformation
Пробовал уже... Результат тот же. И сейчас тоже. Передается что-то типа 8000112Bh в качестве хэндла и все. При этом NtOpenFile проходит нормально.
Что-то никак не могу избавиться от 80000002h. Я так понимаю что это STATUS_DATATYPE_MISALIGNMENT, но причем тут выравнивание? А может есть какой-нибудь другой способ получить первые 4 байта открываемого файла?
Все структуры должны быть выравнены по 4-байтовой границе. На асме так, если не ошибаюсь: Код (Text): .align 4 fsi FILE_STANDARD_INFORMATION <> Это же касается OBJECT_ATTRIBUTES и IO_STATUS_BLOCK. ЗЫ: Или org? Кто-нибудь поправьте, плз
Ну вы и приколисты! Может я чего-то не догнал, но структуры OBJECT_ATTRIBUTES и IO_STATUS_BLOCK передаются как AS_IS. Перед вызовом NtOpenFile сруктура OBJECT_ATTRIBUTES должна быть уже инициализирована, о чем говорит успешное выполнение функции. В NtQueryInformationFile отправляется только указатель на FILE_STANDARD_INFORMATION (OUT) и его размер, а на его структуру (выравнивание) функции плевать (будет заполнять по-своему, а в крайнем случае будет BSOD). Поправьте, где я не прав. Кстати, тут пытался решить проблему другим путем - перехватом NtQueryDirectoryFile, и выяснилось, что FILE_BOTH_DIRECTORY_INFORMATION описана в masm'е неверно. Возможно это касается и FILE_STANDARD_INFORMATION. Вызывая NtQueryDirectoryFile, я сообщаю, что хочу получить FileStandardInformation (вот его addr fsi и sizeof fsi) файла hFile с его IO_STATUS_BLOCK. Где тут грабли?? Примеров на асме почти нет. Уже вторую неделю бьюсь головой...
Верно, указатель. Так вот если этот адрес будет, например, 0xcfff0003, то при проверке аргументов функция вернет STATUS_DATATYPE_MISALIGNMENT. И это единственный случай, в котором можно схлопотать такую ошибку. Если структура описана неверно, то виндовсу на это действительно наплевать. Главное, чтобы передаваемый размер совпадал.
Кажется, все это время копали не в том направлении. Тут вдруг обнаружил что NtQueryInformationFile все же иногда срабатывает, но только если: 1. в структуре OBJECT_ATTRIBUTES значение ObjectName начинается с \\SystemRoot\\......... 2. PsGetCurrentProcessId возвращает значение 4 (SYSTEM) 3. handle начинается с 8, т.е. 800012c3 и т.п. Истнина где-то рядом? Ведь дровина тоже запускается в контексте SYSTEM, если не ошибаюсь. Т.е. получается, что имя получить можно, а доступ к файлу надо открывать отдельно в своем контексте? Думаю, будет сильно тормозить. Есть какие-нибудь соображения по этому поводу?
Ну вобщем, всем огромное спасибо! Действительно, если предварительно открывать файл в своем контексте, то содержимое получить можно. Видимо, проблема была в том, что перехватываемый хэндл не обрабатывается в контексте перехватчика. Жаль, что такой способ довольно грубоват и малость тормозной.