Перехватил NtCreateProcessEx. Надо забанить запуск заданного процесса. Но в NtCreateProcessEx приходит NULL в (POBJECT_ATTRIBUTES ObjectAttributes). Порыл сей форум, в частности http://www.wasm.ru/forum/viewtopic.php?id=19562 и это http://www.wasm.ru/forum/viewtopic.php?id=29309 . Там обсуждался вариант перехвата NtCreateSection и отслеживание имени файла. Я тоже перехватил и сие подходит, но если кто-либо вызовет LoadLibrary("нужный мне екзешник") -- то в NtCreateSection я его получается тоже обрублю. В одном из форумов (http://www.wasm.ru/forum/viewtopic.php?id=29309) Clerk сказал что: "Находим указатель на секцию, хэндл которой передаётся, извлекаем полное имя модуля." (я так понимаю хендл секции который передается в NtCreateProcessEx, я прав?) Но как сие корректно сделать я не представляю. Попробывал вызвать ObReferenceObjectByHandle, как писал сей автор http://www.wasm.ru/forum/viewtopic.php?pid=166927#p166927 и ничего не вышло, в полях либо NULL, либо невалидные адреса. Подскажите кто сталкивался...
http://www.wasm.ru/article.php?article=drvw2k14 В статье описано как найти полный путь к файлу если известен указатель на секцию. Указатель по хендлу получаешь с помощью ObReferenceObjectByHandle.
Я смотрел этот код. Помоему это немного не мой случай. Т.к. там получается имя секции на этапе уже нотификации, т.е. процесс или создан, или почти создан, как минимум уже создана EPROCESS. Код (Text): xor ebx, ebx mov edi, 4 .while ebx < 3 invoke IoGetCurrentProcess .if eax == peProcess mov ecx, MmSectionObjectType mov ecx, [ecx] mov ecx, [ecx] ; PTR OBJECT_TYPE invoke ObReferenceObjectByHandle, edi, SECTION_QUERY, ecx, KernelMode, addr pSection, NULL mov status, eax .else invoke KeAttachProcess, peProcess mov ecx, MmSectionObjectType mov ecx, [ecx] mov ecx, [ecx] invoke ObReferenceObjectByHandle, edi, SECTION_QUERY, ecx, KernelMode, addr pSection, NULL mov status, eax invoke KeDetachProcess .endif .break .if status == STATUS_SUCCESS .if ebx == 0 mov edi, 03F8h ; Try 03F8h handle. .elseif ebx == 1 mov eax, peProcess add eax, 01ACh mov eax, [eax] mov edi, eax and eax, (4 - 1) .break .if ( eax != 0 ) || ( edi >= 800h ) .endif inc ebx .endw Тут или текущий процесс, или вызывается KeAttachProcess. У меня еще процесса нет, я нахожусь в перехваченной NtCreateProcessEx и ей передается хендл секции. Пробовал вызвать ObReferenceObjectByHandle так как в статье вызывается: Код (Text): PSECTION *section_ptr = NULL; NTSTATUS status = ObReferenceObjectByHandle( SectionHandle, SECTION_QUERY, MmSectionObjectType, KernelMode, (PVOID*)§ion_ptr, NULL); if (NT_SUCCESS(status)) { TRACE(("section_ptr=0x%.8X\n", *section_ptr)); ObDereferenceObject(*section_ptr); } else { TRACE(("ERROR ObReferenceObjectByHandle=0x%.8X\n", status)); } ObReferenceObjectByHandle выдает ошибку STATUS_OBJECT_TYPE_MISMATCH(0xC0000024L)... как поправить?
1. перехватывай ZwCreateThread, на этом этапе это peb процесса заполнен(на этапе NtCreateProcessEx нет ещё), и можно сразу вытянуть имя файла. 2. в win2k вызывается функция NtCreateProcess, поэтому придётся ещё её хукать
как вариант дать процессу создаться, если STATUS_SUCCESS, то по PID получить EPROCESS и далее до FILE_OBJECT как в статье готовое решение есть на форуме (автор поста - Twister) также никто не отменял ZwQueryInformationProcess(ProcessImageFileName)
На Windows XP и выше достаточно похукать NtCreateProcessEx() и вытягивать всю информацию из объекта-секции по её хендлу. Ну это как обычно: секция, сегмент, файл и там уже имя можно вытянуть как у меня в блоге расписано. В случае, если в качестве хендла секции указан NULL, значит это fork'ается родительский процесс и всю информацию (например, имя файла-образа) можно вытянуть по указателю на процесс-родитель. Ну а это просто: по EPROCESS'у получаем указатель на секцию, а далее как в предыдущем случае. Не вижу смысла хукать NtCreateThread() или NtCreateSection().
пишешь на си, который не контролирует тип указателей? по-моему, надо все-таки *MmSectionObjectType вместо MmSectionObjectType.
Порыл я блог ваш, но ответа не нашел. Код (Text): if (NULL != SectionHandle) { PSECTION *section_ptr = NULL; NTSTATUS status = ObReferenceObjectByHandle( SectionHandle, SECTION_QUERY, *MmSectionObjectType, KernelMode, (PVOID*)§ion_ptr, NULL); if (NT_SUCCESS(status)) { ..... } else { ..... } } Вот код, который отрабатывает, но в *section_ptr возвращает NULL. Что не так делаю?
А кто сказал, что возвращает оно PSECTION*? Возвращается указатель на объект. эТо просто PSECTION. Не нужно разыменовыать полученный указатель Читайте MSDN перед тем как писать
Да, глупая ошибка с моей стороны, согласен. Но пока вы не убежали мот еще подскажете: section_ptr->_Segment->ControlArea == 0x08e6742a Это, как я понимаю, не кернеловский адрес. Что вызвать чтобы получить к нему доступ?