Пытаюсь установить хук на функцию CreateFileW (прописать jmp на мой код в первые 5 байт тела функции), делаю это в обработчике уведомлений о загрузке образов, когда приходит уведомление о загрузке kernel32.dll для одного единственного процесса (обработчик зарегистрирован при помощи PsSetLoadImageNotifyRoutine). Проблема в том, что при записи в kernel32.dll из этого обработчика образ kernel32.dll изменяется во всех процессах, а не только в том, в контексте которого был вызван обработчик. Как из драйвера ядра изменить образ kernel32.dll только в одном процессе? Когда я ставлю этот хук на уровне пользователя, при помощи WriteProcessMemory, образ kernel32.dll патчится только в текущем процессе, как сделать что-то типа PAGE_WRITECOPY при патчинге на уровне ядра? ОС: Windows XP SP3
А какой смысл в KeAttachProcess, если обработчик PsSetLoadImageNotifyRoutine и так выполняется в контексте процесса, загрузившего dll?
Вызов в этом обработчике ZwProtectVirtualMemory приводит к зависанию системы, аналогичному описанному в этом топике http://wasm.ru/forum/viewtopic.php?id=19732. Если попытаться писать напрямую в тело kernel32.dll, без ZwProtectVirtualMemory, вылетает исключение. Поэтому я делаю так: pMdl = MmCreateMdl(NULL,VirtAddress,1); MmBuildMdlForNonPagedPool(pMdl); pMdl->MdlFlags = pMdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; MappedImTable = MmMapLockedPages(pMdl, KernelMode); status = MmProtectMdlSystemAddress(pMdl, PAGE_READWRITE); *MappedImTable = Value; pMdl->MdlFlags = pMdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA; MmUnmapLockedPages(MappedImTable,pMdl); IoFreeMdl(pMdl);
Monoprix Деадлоки возможны, например ожидание MmSystemLoadLock и пр. Универсальное решение заключается в бактрейсе. Так как образ мапится посредством сервиса, разумно получить управление как можно ближе к моменту возврата из сервиса, наилучший вариант - получить управление при возврате в менеджер сервисов, выполняющий трап-процессинг. Вот выполните бактрейс и замените адрес возврата в последнем стековом фрейме, это будет возврат из kssdoit. Можно поступить иначе - создать стаб и настроить контекст для вызова этого стаба. Тогда при загрузке задачи в процессор стаб получит управление. Это KiFastSystemCallRet, возврат из Int 0x2e, либо возврат в ядерные стабы.
Используй APC из этого обработчика, в нём уже сделаешь всё, что нужно, все локи к этому моменту уже будут освобождены.