Ke386IoSetAccessProcess и т.п.

Тема в разделе "WASM.NT.KERNEL", создана пользователем Wolfgang, 9 ноя 2006.

  1. Wolfgang

    Wolfgang New Member

    Публикаций:
    0
    Регистрация:
    11 май 2005
    Сообщения:
    82
    Адрес:
    Russia
    Делаю драйвер режима ядра, который позволяет процессу разблокировать для себя прямой доступ к портам ввода/вывода, использую Ke386IoSetAccessProcess и т.п. В этой связи возникло несколько вопросов:
    1. Почему функция Ke386QueryIoAccessMap не требует в качестве аргумента указатель на объект "процесс", а Ke386IoSetAccessProcess требует? Значит ли это, что функция Ke386QueryIoAccessMap работает с TSS текущего процесса?
    2. Действительно ли IOPM для всех процессов один?
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Wolfgang
    IOPM несколько. Ke386QueryIoAccessMap по номеру IOPM выдает эту таблицу. Ke386IoSetAccessProcess устанавливает IOPM для процесса одну из уже существующих карт.
    Ke386QueryIoAccessMap работает с глобальным списком карт, не для текущего процесса.
    Противоположность Ke386QueryIoAccessMap - Ke386SetIoAccessMap.
     
  3. Wolfgang

    Wolfgang New Member

    Публикаций:
    0
    Регистрация:
    11 май 2005
    Сообщения:
    82
    Адрес:
    Russia
    Дизасмил эту функцию, она пирнимает два аргумента - указатель на буффер, куда скопируется IOPM и 1, если второй аргумент не 1, то копирования просто не произойдет

    Опять же, дизассемблриование дает основание полагать, что функция просто копирует IOPM из буфера, указатель на который передается функции в качестве аргумента, второй аргумент должен быть только единицей, номер одной из существующих IOPM нигде не фигурирует.

    Не исключаю возможности, что я неправильно что-то понял, но вопросы мои остаются в силе
     
  4. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Угу. Потому что пока только 1 IOPM существует =)
    Хотя насколько я понял M$ реализовала возможность оперировать не только с 1 картой.
    Если MapNumber == 0, тогда битовая карта полностью заполняется еденицами.
    MapNumber <= IOPM_COUNT тогда копируется PCR->TSS->IoMaps[MapNumber].IoMap, но тк карта одна, то и копируется только она.
    Угу.
    Да.
     
  5. Wolfgang

    Wolfgang New Member

    Публикаций:
    0
    Регистрация:
    11 май 2005
    Сообщения:
    82
    Адрес:
    Russia
    Тогда как объяснить тот факт, что в моей системе один процесс имеет прямой доступ к портам ввода/вывода, а остальные - нет?!?! Это -проверенный факт.
    И если Ke386QueryIoAccessMap работает с TSS текущего процесса, то как получается, что функция этв, будучи вызванной в контексте SYSTEM, срабатывает для моего процесса?
    Очевидно, я не уловил какой-то ключевой момент :dntknw:
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Цитата из KmdTut.
    http://void.ru/?do=printable&id=701 - вот здесь хорошо описано.
     
  7. Wolfgang

    Wolfgang New Member

    Публикаций:
    0
    Регистрация:
    11 май 2005
    Сообщения:
    82
    Адрес:
    Russia
    Да этот-то материал от Four-F'а меня и сбил с толку! С помощью функций Ke386IoSetAccessProcess и Ke386IoSetIoAccessMap из драйвера в контексте процесса А я открываю прямой доступ к портам. Пробую доступ к портам из процесса Б, созданного после - исключение, пробую из процесса А - нет исключения. Как это можно объяснить???
    Этот вопрос и не возник бы у меня, если бы мой механизм работал, но иногда он не срабатывает и порты остаются залоченными :-(
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Wolfgang
    Так какой функцией пользуешься Ke386IoSetAccessProcess или Ke386IoSetIoAccessMap?
    Если тебе надо дать доступ всем процессам, то в статье выше описано ещё парочка способов.
     
  9. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    IOPM действительно одна (точнее, изначально был предусмотрен массив этих карт, но его размер == 1), но вот поле Process->IopmOffset у каждого процесса своё. Если оно указывает на карту, то процесс ей пользуется, если нет, то соответственно не может пользоваться.

    Т.о. сначала надо установить IOPM, у потом для каждого процесса, которому она нужна, вызвать Ke386IoSetAccessProcess, чтобы она прописала поле Process->IopmOffset.
     
  10. Wolfgang

    Wolfgang New Member

    Публикаций:
    0
    Регистрация:
    11 май 2005
    Сообщения:
    82
    Адрес:
    Russia
    Этот код выполняется в контексте процесса, которому нужен доступ к портам ввода/вывода, IOPM с номером один заполнена нулями, табличка эта действительно содержит нули... но при обращении к портам процесс все равно вызывает исключение

    Код (Text):
    1. kal db "IOPM: %08X...", 10, 0
    2.  
    3.   ...
    4.  
    5.   invoke PsGetCurrentProcess
    6.   invoke Ke386IoSetAccessProcess, eax, 1
    7.   test al, al
    8.   jnz  create_done
    9.  
    10.   push STATUS_IO_PRIVILEGE_FAILED
    11.   pop  status
    12.  
    13. create_done:
    14.   invoke Ke386QueryIoAccessMap, 1, addr pIopm
    15.   invoke DbgPrint, addr kal, pIopm[0]
    16.  
    17.   ...
    Уважаемый Four-F, в чем тут может быть причина?
     
  11. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    В аттаче измененный DateTime из KmdKit.

    1 - Только модифицирует и устанавливает новую IOPM (Ke386SetIoAccessMap).
    2 - Только разрешает процессу её использовать (Ke386IoSetAccessProcess).

    У меня работает.
     
  12. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Контекст, кстати, здесь не имеет значения.
     
  13. Wolfgang

    Wolfgang New Member

    Публикаций:
    0
    Регистрация:
    11 май 2005
    Сообщения:
    82
    Адрес:
    Russia
    Можно тогда несколько вопросов?

    1. Для чего выделяется постоянная неподкачиваемая память, если IOPM все равно лежит в другом месте и из выделенного буфера только один раз копируется?
    Код (Text):
    1.    
    2. invoke MmAllocateNonCachedMemory, IOPM_SIZE
    P.s.
    имеет для PsGetCurrentProcess
     
  14. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Хороший вопрос :) Мне он тоже приходил в голову. Точного ответа я не знаю, но, IMHO, выделять некешируемую память здесь не имеет смысла. Единственное жесткое требование - она должна быть из неподкачиваемого пула. Возможно, исторические причины: тот, кто первым писАл этот код, делал это очень давно и, возможно, тогда это имело значение. Ну а все последователи делают тоже самое на всякий случай. Я тоже так сделал ;)


    Упс... Конечно имеет. Я не обратил внимание на то, что указатель на процесс берется от PsGetCurrentProcess.
     
  15. Wolfgang

    Wolfgang New Member

    Публикаций:
    0
    Регистрация:
    11 май 2005
    Сообщения:
    82
    Адрес:
    Russia
    Тем не менее, почему-то не срабатывает на некоторых ХР-системах, проверяю обе IOPM, одна штатная - заполненная единичками, другая - сформированная мной, заполнена нулями. Видимо, по каким-то причинам не срабатывает Ke386IoSetAccessProcess :-(
    Что именно делает эта функция, помимо изменения поля в структуре EPROCESS? Чтобы эти изменения попали в TSS, нужно ли что-то еще предпринимать?
    Прилагаю свой небольшой исходник драйвера. Суть его работы - создание устройства, при открытии которого пользовательским процессом открывается доступ к портам.

    P.s. примечательно, что после некоторого количества запусков работать таки начинает
     
  16. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Код (Text):
    1. NTSTATUS DriverCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp){
    2.     ULONG pIopm[2048];
    3.     PEPROCESS pProc;
    4.  
    5.     RtlZeroMemory(pIopm, 0x2000);
    6.     pProc = PsGetCurrentProcess();
    7.     Ke386IoSetAccessProcess(pProc, 1);
    8.     Ke386SetIoAccessMap(1, pIopm);
    9.     Irp->IoStatus.Information = 0;
    10.     Irp->IoStatus.Status = STATUS_SUCCESS;
    11.     IoCompleteRequest(Irp, IO_NO_INCREMENT);
    12.     return STATUS_SUCCESS;
    13. }
    Обрати внимание на то, что Ke386SetIoAccessMap вызывается после Ke386IoSetAccessProcess.
     
  17. Wolfgang

    Wolfgang New Member

    Публикаций:
    0
    Регистрация:
    11 май 2005
    Сообщения:
    82
    Адрес:
    Russia
    сделал так же, не помогло :-(
     
  18. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    посмотри мой сорц.
    WinXP SP2 работает.
     
  19. Wolfgang

    Wolfgang New Member

    Публикаций:
    0
    Регистрация:
    11 май 2005
    Сообщения:
    82
    Адрес:
    Russia
    Работает... теперь самое интересное - почему не работает мой пример...
    1. Может быть, на момент загрузки драйвера (он у меня грузится автоматом при загрузке системы) еще нельзя заполнять альтернативную IOPL?
    2. Важно ли вызывать сначала Ke386IoSetAccessProcess, а потом Ke386SetIoAccessMap?
     
  20. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    угу, можно сказать это ключевой момент =)
    наврядли