Подскажите плиз как в ядре создать файл маппинг? т.е. требуется что-то типа такого механизма: Файл отображается в оперативу и можно туда писать и читать, и всё сохраняется в файле. т.е. чтото типа файла подкачки. вернее его подобие. Под юзермодом там проще: CreateFile + CreateFileMapping + MapViewOfFile Под ядром пытался делать ZwCreateFile + ZwCreateSection + ZwMapViewOfSection, но он давал мне адреса памяти 0x00150000. А это уж точно не в ядерной части, а нужно в ядерной чати. И по этому подом дальнейшее использование загибалось. Как реализовать такие действия?
В функции ZwMapViewOfSection() во втором параметре ты передаёшь хендл целевого процесса. Если передашь туда хендл процесса ядра, то проекция будет выполнена на а.п. ядра.
Вот код: Код (Text): ULONG InitDB(WCHAR * name) { ULONG ret = 0; OBJECT_ATTRIBUTES oa; IO_STATUS_BLOCK io; UNICODE_STRING FileName; LARGE_INTEGER MaxSize; ULONG ViewSize; ViewSize = sizeof(DATA_BASE); MaxSize.LowPart = sizeof(DATA_BASE); MaxSize.HighPart = 0; RtlInitUnicodeString(&FileName, name); InitializeObjectAttributes(&oa, &FileName, OBJ_CASE_INSENSITIVE, 0, 0); if (ZwCreateFile(&DB_hFile, GENERIC_READ | GENERIC_WRITE, &oa, &io, 0, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN_IF, 0, 0, 0) == STATUS_SUCCESS) { if (ZwCreateSection(&DB_hSection, SECTION_MAP_READ | SECTION_MAP_WRITE, 0, &MaxSize, PAGE_READWRITE, SEC_COMMIT, DB_hFile) == STATUS_SUCCESS) { if (ZwMapViewOfSection(DB_hSection, ZwCurrentProcess(), (PVOID*)&ret, 0, sizeof(DATA_BASE), 0, &ViewSize, ViewUnmap, MEM_RESERVE, PAGE_READWRITE) != STATUS_SUCCESS) { ZwClose(DB_hSection); ZwClose(DB_hFile); ret = 0; } } else { ZwClose(DB_hFile); } } return ret; }
x64 Создайте топик. В нём напишите "сервисы в ядре = сервисы в юзермоде". И добавьте "полуядро левел глюкавый".
2 Clerk Как я понял из твоих слов - этот метод абсолютно не правильный. Тогда подскажи плз в какую сторону хотя бы копать.
Вообще есть предположения, что всё необходимо делать через менеджер кеша. А именно CcInitializeCacheMap и CcMapData. Вот только хз прав или нет.
Код корректный. Разве что указатели я не советовал бы приводить к числам типа ULONG (пользуйся хотя бы ULONG_PTR тогда уж), но тут, я надеюсь, ты знаешь что делаешь.
Менеджер кэша изначально разрабатывался исключительно для файловых систем. В общем-то, с тех пор не много изменилось.
Адресное пространство ядра не ограничивается верхней половиной виртуальных адресов. Например, у нас в нижней части АП ядра в данный момент присутствуют две ntdll, кодовые страницы, что-то похожее на Активационный Контекст и read-only _KUSER_SHARED_DATA. Таким образом, чтобы получить подходящий ответ, необходимо задать верный вопрос. Впрочем, очевидно, что тебе требуется не просто отображение вида секции на АП ядра, а отображение этого вида на его верхние адреса. ZwMapViewOfSection() не позволяет этого – вместо неё можешь воспользовать MmMapViewInSystemSpace(). И, раз уж мы на этом: 1) "== STATUS_SUCCESS" – не очень хорошая практика. NT_SUCCESS() предпочтителен. Хотя кое-кто из отписавшихся здесь тоже постоянно jz пользует вместо js ^) 2) Зачем использовать ULONG для хранения адреса? Лучшим решением здесь будет USHORT – 16 бит как раз соответствуют машинному слову и занимают всего один регистр общего назначения. В любом случае, даже не думай заменять это на PVOID. 3) Если далее не используешь файл и секцию, можешь сразу закрыть их хендлы и, таким образом, избавиться от глобальных переменных.
Для упрощения картины я бы предложил рассматривать а.п. ядра как а.п. самого обычного процесса, у которого есть как нижние адреса, так и верхние. Разница по сути только в том, что при переключении пользовательского потока в режим ядра верхние адреса процесса подменяются на верхние адреса ядра, таким образом позволяя потоку использовать объекты ядра и другие ядерные данные, которые шарятся между процессами. Это пока ни откуда не очевидно, человек хочет обычный file mapping.
Это очевидно из ([DriverEntry ==> System Сontext] + [Корректный ZwMapViewOfSection()] -> Task Still Unsolved) + ("а нужно в ядерной части" + System Сontext). Т.е. попросту нет схождения без предположения о некорректности начальных условий задачи – ведь при корректных условиях задача была бы уже решена (при этом данной темы бы не существовало). В то же время всё становится на свои места, если выполнить очень простой переход от "в ядерной части" до "в верхней половине АП".
Sol_Ksacap Ты слишком усложняешь, мне кажется. Задача у него решена, но он ещё не понял этого. Его сильно удивил тот факт, что ядерный адрес оказался в нижнем диапазоне, потому он решил, что допустил ошибку у себя в коде, вот и всё. Но если я всё же ошибаюсь и нужны именно верхние адреса, то таки да, функция MmMapViewInSystemSpace() будет решением в этом случае.
2 Sol_Ksacap Ты что-то путаешь тут. Адрес как не крути но в 16 бит не поместиш. Это тебе не дос. ULONG - занимает 2 слова и тоже помещается в регистр общего назначения. В данном случае в eax