Трансляция адресов, x86, без PAE.

Тема в разделе "WASM.NT.KERNEL", создана пользователем lews, 10 сен 2007.

  1. lews

    lews New Member

    Публикаций:
    0
    Регистрация:
    12 авг 2007
    Сообщения:
    14
    Пытаюсь руками транслировать вирт. адрес в физический(или установить, что он недействителен) для заданного процесса в системе. Что я имею:
    на входе - PID процессе, по нему получаю адрес EPROCESS, дальше нахожу адрес физический адрес DirBase. А дальше туго :-(
    Теоретически, я знаю, как происходит трансляция - 10 бит адреса * 4 - смещение от DirBase. Там надо найти PDE, установить, действительна ли страница. Но тут начинаются у меня проблемы - DirBase - физический адрес, а я не могу обратиться по нему, только по виртуальному могу. Кроме того, даже если я обращусь по адресу этому, то дальше мне надо найти адрес первой таблицы страниц, чтобы найти PTE для моего адреса. (Где ?) Если бы все было в контексте текущего процесса, то просто - таблицы страниц проецируются по 0xC000000, каталог по 0xC030000.
    Может кто объяснит, куда копать?

    И не совсем по теме - как можно узнать, сколько и адреса всех страниц(виртуальные, для контекста этого процесса), переданных процессу.
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    MmMapIoSpace не поможет?
     
  3. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    lews
    вообще виртуальные адреса для всех каталогов страниц должны быть известны и не зависить от того, в контексте какого процесса мы работаем
    поэтому можно просканировать все PTE текущего процесса на предмет наличия физического адреса каталога страниц нужного тебе процесса
    если найдешь - получишь 2 индекса (PDE и PTE) и сможешь построить виртуальный адрес, если нет
    тогда можно тупо сделать так
    Код (Text):
    1. PVOID PageDirectoryBase;
    2. ...
    3. asm {
    4.     cli
    5.     mov    eax, PageDirectoryBase
    6.     mov    ebx, cr3
    7.     mov    cr3, eax
    8. ...
    9.     mov    cr3, ebx
    10. }
    11. ...    
    12. }
     
  4. lews

    lews New Member

    Публикаций:
    0
    Регистрация:
    12 авг 2007
    Сообщения:
    14
    Теоретически поможет.. Если работает она, как я понимаю, то я получу проекцию физической странички на виртуальную и смогу с ней работать нормально.

    Потом я найду нужный мне PDE... по идее, из PDE хитрыми махинациями я могу получить адрес таблицы страниц? И дальше на ней найти нужный мне PTE и по нему найти уже адрес нужной мне страницы с данными. Есть одна проблема - я не понимаю, что это за хитрые махинации, т.е. как отталкиваясь от PDE добраться до таблицы страниц, и как из PTE получить адрес страницы с данными :-(?
     
  5. lews

    lews New Member

    Публикаций:
    0
    Регистрация:
    12 авг 2007
    Сообщения:
    14
    Меня смущает тот факт, что для текущего процесса вирт. адрес каталога страниц процеруется по одному и тому же адресу 0xC030000... Каша у меня какая-то в голове :)

    По поводу поиска в текущем процессе - каким образом я могу пройтись все PTE? Я ведь не в курсе, сколько страниц выделено процессу, как бы не уйти в БСОД (

    А код зашибись, не догадался бы )
    Единственное - достаточно спин блокировки, чтобы у меня не получилась ерунда? Если она повысит IRQL до 2, то ниодин пользовательский поток не переключится на процессор в этот момент и CR3 останется нетронутым?
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    зато cr3 разные для каждого процесса.ы
     
  7. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    надо бы тебе документацию почитать для начала
    содержимое PDE & 0xFFFFF000 = физический адрес таблицы страниц
    содержимое PTE & 0xFFFFF000 = физический адрес страницы
    вначале проходишь по всем PDE (используя базовый адрес = 0xC0000000)
    если PDE валиден (бит P = 1), используя базовый адрес = 0xC0300000 находишь нужный PTE в таблице страниц по физическому адресу, который есть в PDE (виртуальный адрес PTE = 0xC0300000 + index * 4096 + offset, где индекс - номер PDE в каталоге страниц, offset - смещение внутри таблицы страниц)
     
  8. lews

    lews New Member

    Публикаций:
    0
    Регистрация:
    12 авг 2007
    Сообщения:
    14
    PFN - это физический адрес? Блин. Перечитал Руссиновича/Соломона 10ок раз, чтобы понять, и нигде там не упоминалось, что PFN это физ. адрес( Сидел и гадал, что за прикольная номер фрейма страницы :)

    Спасибо за разъяснение!

    ммм....а не наоборот? PDE с 0xC0300000, а PTE с 0xC0000000 ?
    rei3er
    Если не сложно, объясните, пожалуйста, такую штуку (можно смело послать в ман, просто найти интересного не получается :-( )
    Валидный PDE/PTE указывает на страницу, которая не сброшена на диск? У Руссиновича так описано, по крайней мере. Если это так, то как я найду, когда мне следует прекратить поиски - ведь таблицы страниц создаются не сразу все, а по мере надобности?

    И ведь нет смысла проходить по первым 512 PDE, потому что они описывают пользовательское пространство?
    Спасибо!
     
  9. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Вообще, валидность PDE/PTE понятие относительное. На пристутствие/отсутствие страницы в памяти указывает бит присутствия P -- нулевой бит элемента PTE. В итоге, когда происходит обращение к такой странице, процессор генерирует исключение (#PF) и передает управление ОС. А ОС заглядывает в свои структуры и уже сама решает, отчего это произошло. Если страница действительно была выгружена, то она вернет ее на место. Если страница не была отображена для процесса -- сообщит об исключении обработчику исключений процесса (потока).

    В итоге, сказать точно, выделена ли страница процессу, только по биту присутствия нельзя -- надо еще знать, что ОС "думает" по поводу отсутствующей страницы. IMHO!
     
  10. lews

    lews New Member

    Публикаций:
    0
    Регистрация:
    12 авг 2007
    Сообщения:
    14
    А есть варианты, как узнать список всех страниц, переданных процессу?
     
  11. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    можно узнать карту памяти, перебрав все PDPE/PDE/PTE... а насчет "переданных процессу" - в винде есть какаято шня, называется VAD. Точно не знаю, но вроде надо копать в эту сторону.. подробности у руссиновича
     
  12. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    да
    сформулируй четко, что ты вообще хочешь сделать
    опять таки, смотря какая у тебя цель
    а вообще Mika0x65 прав
    если P сброшен, то есть как минимум 8 вариантов типа PTE (3 USE-бита)
    исходя из этого обработчик #PF определяет, что делать
    можно поискать, что означает каждая конкретная комбинация
     
  13. lews

    lews New Member

    Публикаций:
    0
    Регистрация:
    12 авг 2007
    Сообщения:
    14
    На данный момент я хочу просто узнать список всех страниц, переданных процессу (и те, что сейчас в страничком файле, и те, что в памяти, и те, что только зарезервированы, но не переданы). Как подсказал Great, копать надо в сторону VAD, и вроде бы, оказался прав, судя по докам, что я нашел к текущему моменту - правда, пока только общие слова, ничего конкретного :)
     
  14. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Руссинович пишет, что именно исходя из VAD обработчик #PF решает что делать с Page Fault - подгружать страницу, если она выгружена, читать файл, если это проекция секции и т.п.
    Посмотри сорсы винды, а именно файлик ntos\mm\mmfault.c, кажется так зовется. там находятся обработчики MmAccessFault и прочие

     
  15. lews

    lews New Member

    Публикаций:
    0
    Регистрация:
    12 авг 2007
    Сообщения:
    14
    Чего-то у меня не то получается :| Руки надо выпрямлять )
    Подскажите, если я что-то не так делаю - на входе ID процесса и какой-то адрес в контексте этого процесса. Я хочу получить данные по этому адресу.
    Делаю так:

    первым делом получаю EPROCESS для данного PID - с этим все ок.
    Дальше, по смещению 0x18 получаю DirBase - с этим тоже ок - проверяю параллельно в windbg.
    Дальше хочу получить PDE, для этого сначала получаю виртуальный адрес для странички с PDE:
    Код (Text):
    1. dirBase = (unsigned int *)
    2.   MmMapIoSpace(
    3.     (PHYSICAL_ADDRESS)RtlConvertLongToLargeInteger(eproc->DirBase),
    4.     4096,
    5.     MmNonCached);
    6.   DbgPrint("%d", dirBase[address->pdeShift]);
    Где address экземпляр
    Код (Text):
    1. struct VirtualAddress{
    2.   ULONG shift:12;
    3.   ULONG pteShift:10;
    4.   ULONG pdeShift:10;
    5. };
    А его содержимое 0x401000, т.е. pdeShift = 0
    И в windbg делаю тоже самое:
    !dd dirBase

    И получаю разные результаты(
     
  16. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    набери !pte 0x401000
     
  17. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    rei3er

    код предложенный самый действенный способ, поскольку память в Windows имеет FLAT модель, то все можно промепить используя только средства процессора, только вот беда mov cr3, eax, может уничтожить мепирование твоего кода в память, т.е. следующая инструкция тут же приведет к PageFault.
     
  18. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    lews

    Юзай MmGetVirtualForPhysical(...). Только она если PAE режим включен почему-то не всегда выдает правильный адрес.
     
  19. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    PROFi
    вот именно... как раз в http://www.wasm.ru/forum/viewtopic.php?id=16528 писали что она работает не всегда при PAE.. лучше всетаки, Имхо, самостоятельно маппить себе через MmMapIoSpace все, что нужно.
     
  20. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    имхо, нет
    пространство ядра идентично для каждого процесса (т. е 512 (256) элементов PDE в каталоге страниц каждого процесса должны содержать одинаковые значения)
    запись в CR3 приведет к сбросу TLB
    что поначалу снизит производительность, но не более того