Вызываю ExAllocatePool и выделяю в nonpaged пуле блок данных, копирую в этот блок свой код. Можно ли сделать этот код доступным на исполнение всем пользовательским процессам в системе, без его явного меппинга в адресное пространство каждого из процессов?
О каких лимитах ты толкуешь? У юзермодных дескрипторов 1B и 23 лимиты FFFFFFFF. Или мы говорим о разных вещах? В 64-бит лимиты вобще нах никому не нужны, ибо не чекаются
medstrax1 Не так выразился немного. Начало системного ап это конец пользовательского сегмента, он ограничен не лимитами дескрипторов, а битами в PTE/PDE.
Офф. Кто-нибудь помнит Win 3.x на 286-х? Как там разруливалось юзерское/ядерное ап? Учитывая, что MMU в процах еще не было, по логике - только с помощью лимитов сегментов. Или тогда защиты ядра от юзера вообще не было? Для общей эрудиции интересно
А если вручную подправить PTE в нужных таблицах страниц и сделать эту память доступной на чтение в 3 кольце? Кстати, когда процессоров несколько, у них каталог и таблицы страниц общие? Мне это нужно для глобального перехвата api. Пропатчить образ kernel32.dll сразу во всех процессах у меня получилось, но нужно еще где-то разместить код функций-перехватчиков - нужен блок памяти доступный на исполнение всем процессам в системе и расположенный в каждом из них по одному виртуальному адресу.
Интересная задача. Похоже кроме как правкой таблиц страниц не решается. Была грешная мысль сделать юзермодным дескрипторам DPL = 0. Не катит. Sysexit полюбому возвращается в ринг3. Да и iret при rpl!=dpl вызовет GP. В принципе тут 2 пути. Либо разрешать ядерное ап на доступ из ринг3, либо давать юзеркоду кпл<3. И то и то имхо сложно. Во втором случае я пока решения не вижу вообще.
Легко взвести биты в PTE/PDE. Тогда пользовательский код сможет юзать страницу из системного ап. Причём PT глобальна, PD локальна для процесса, тоесть нужно енумить все директории, впрочем это технические детали реализации. При этом непосредственно страница будет доступна, подобна как US в конце пользовательского ап, для ядра эта память будет не доступной(имеется ввиду что например при енуме блоков памяти этой страницы не будет и никакие тулзы её не покажут). Главная проблема в лимитах сегмента как и говорил ранее - ядро не допускает обращение за пределы пользовательского ап, проверяя диапазон в сервисах, да вобще эти проверки всюду, так что решение не тру. Промапить страницу ниже пользовательского ап по одному адресу во всех процессах не представляется возможным, так как память может быть занята, да и сейчас применяется ASLR. Monoprix Нет.
medstrax1 С переменными MmHighestUserAddress/MmUserProbeAddress. Кстате проверки введены в шедулер на NT.7(точто не знаю зачем).
Хотя в любом случае идея тухлая. Разрешить юзеркоду доступ в ядерное ап - это песец. Любая ошибка в адресации чревата крахом
Хотя, как вариант, разрешить юзермоду доступ можно к какой-то конкретной некритичной страничке в ядерном ап
И отсюда опять возвращаемся к поднятой клерком темой глобальных переменных. Тут возникла мысль для хранения глобальных переменных использовать CMOS-память. Вариант вроде приемлем, но возникает проблема гарантированного возврата измененных значений. Исследования показали, что в CMOS-памяти свободного места нифига нет. Поэтому для хранения своих переменных надо затереть оригинальные значения. Если их не восстановить, то при последущей перезагрузке это легко может выплыть (или комп вобще не загрузится). А гарантировать восстановление оригинальных значений нельзя, вдруг комп перегрузится по питанию, к примеру. Есть еще вариант - заюзать для хранения переменных видеопамять. Адреса A0000-BFFFF вроде мапятся стандартно. Но тут мне неясен алгоритм работы с видеопамятью со стороны дров видяхи. Скорей всего это ненадежно.
medstrax1 Валидность данных не проблема, тоже самое что через IOCTL в дров передавать. Вот лимит это проблема. Хотя если только для обмена данными, а не для хранения кода, то должно быть норм. В сайсе пример: (в Eax считано "MZ", страницы выше и ниже не доступны, текущая R/W). CMOS после ребута сбросит биос, если обнаружит инвалидные чексуммы.