Трансляция адресов, MmMapIoSpace

Тема в разделе "WASM.BEGINNERS", создана пользователем HoShiMin, 10 ноя 2018.

  1. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.460
    Адрес:
    Россия, Нижний Новгород
    Добрый день форумчанам!
    Пишу транслятор адресов, чтобы бегать по PTE-записям и напрямую менять атрибуты страниц.
    Объявил необходимые структурки по амдшным спекам: https://hastebin.com/uhocilubat.h
    Читаю CR3, получаю адрес PML4E:
    Код (C++):
    1.  
    2. #define PFN_TO_PAGE(pfn) (pfn << 12)
    3.  
    4. VIRTUAL_ADDRESS Va = {};
    5. Va.Value = (unsigned long long)&Va; // Найдём самого себя
    6.  
    7. CR3 Cr3 = {}
    8. Cr3.Value = __readcr3();
    9.  
    10. UINT64 pPml4e = PFN_TO_PAGE(Cr3.x64.Bitmap.PML4) + Va.x64.Page4Kb.PageMapLevel4Offset * sizeof(PML4E);
    11.  
    12. // Возвращает NULL:
    13. PML4E* Pml4e = MmMapIoSpace(pPml4e, sizeof(PML4E), MmNonCached);
    14.  
    MmMapIoSpace возвращает NULL. Физический адрес выглядит нормальным - не вылезает за границы доступной физической памяти (например, pPml4e = 0x3.29e0.0000, физической памяти 16 Гб (0х4.0000.0000)). Но не мапится. MiMapContiguousMemory возвращает STATUS_CONFLICTING_ADDRESSES. Какие могут быть причины?

    И небольшой смежный вопрос: здесь упоминают, что адреса этих таблиц уже отображены на виртуальные адреса (например, в х32 на 0xC0000000). Где можно посмотреть эти адреса для х64 (понятно, что в иде, только где искать?) и насколько надёжно их хардкодить?
     
    Последнее редактирование: 10 ноя 2018
  2. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.241
  3. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.460
    Адрес:
    Россия, Нижний Новгород
  4. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.241
    в отладчике крути маппинг и узришь где вылетает..

    1. можь памяти не хватает.
    2. с разрешением на доступ к адресам памяти фигня.
    3. можь железку плющит.
    ===
    --- Сообщение объединено, 11 ноя 2018 ---
    https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/-pte
    --- Сообщение объединено, 11 ноя 2018 ---
    https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/allocating-system-space-memory
     
  5. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.460
    Адрес:
    Россия, Нижний Новгород
    Ну вот читаем спеки:
    upload_2018-11-11_15-50-10.png
    40-битный адрес расширяем до 52х-битного, сдвигая на 12 бит.
    На виртуалке с 4 гигами памяти читаем CR3, получаем, например, 0x119C00000.
    40 бит PML4E = 0x119C00. Сдвигаем на 12 бит и получаем тот же 0x119C00000.
    Но он УЖЕ больше четырёх гигабайт! Это нормально? Он тоже не мапится.
    С другой стороны, MmMapIoSpace на основной машине (там, где 16 гигов), успешно мапит адреса выше 0x400000000. Что это за память?
     
  6. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.241
    HoShiMin, так у тебя в виртуалке не пашет?
    --- Сообщение объединено, 11 ноя 2018 ---
    если не работает именно в виртуалке, надо смотреть настройки сией вм-ки…

    1. либо настройки.
    2. слишком большой кусок пытаешься мапить и элементарно памяти на такое нет.
    3. у самой вирты косяки.
     
  7. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    HoShiMin,

    Виндебагом пройди данную апи и найди проблемное место. В чём проблема ?
     
  8. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.460
    Адрес:
    Россия, Нижний Новгород
    Не работает и в виртуалке, и на хосте. Пытаюсь смапить всего 8 байт - размер одной записи, куда уж меньше...
    И что интересно, почему-то успешно памятся адреса намного выше верхнего возможного адреса физической памяти. Что там за адреса? А CR3 в виртуалке тоже выше верхней границы (это вообще нормально?), но не мапится.
    Во внутренностях MiMapContiguousMemory чёрт ногу сломит даже с Hex-Rays'ом. Там начинаются сплошные захардкоженные числа. Откуда что берётся - непонятно...

    Внутри MiReservePtes вообще ад. Ну вот что это?
    upload_2018-11-11_19-14-20.png
    --- Сообщение объединено, 11 ноя 2018 ---
    Это я к тому, что, возможно, что-то концептуально делаю неправильно. Меня смущает, что CR3 получается выше, чем верхний доступный адрес в оперативке. Как, например, в виртуалке 4 гига, а CR3 залез на 700 мегабайт выше? Это что же получается, граждане?
     
    Последнее редактирование: 11 ноя 2018
  9. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    HoShiMin,

    Менеджер памяти, вы веть сами решили в него лезть, нет смысла идти назад.

    > почему-то успешно памятся адреса намного выше верхнего возможного адреса физической памяти. Что там за адреса?

    Мапяться". физический адрес не равен виртуальному.

    В механизмы трансляции никогда никто не вмешивается, так что ошибка явно у вас в чём то.

    > CR3 получается выше, чем верхний доступный адрес в оперативке.

    А вы уверены что это pdbr, а не есчо что то.
     
  10. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.460
    Адрес:
    Россия, Нижний Новгород
    Правильно ли понимаю, что если установлено N байт оперативки, то физическое адресное пространство [0, N - 1] полностью принадлежит ей? Если так, то отображение какой памяти создаётся по физическим адресам, большим, чем N - 1?
    Но на х64 в cr3 ничего другого и быть не может!
     
  11. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    HoShiMin,

    > Правильно ли понимаю, что если установлено N байт оперативки, то

    Нет. Память замещается для экономии. Ничего нельзя сказать про её лимиты. Физические механизмы аллокации тёмный лес.

    > Но на х64 ничего другого и быть не может!

    Может вы не там поле прочитали, почему то мне кажется именно это важным.
     
  12. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.460
    Адрес:
    Россия, Нижний Новгород
    Перепроверял с WinDbg, что он сам выводит в @CR3, то и у меня через __readcr3(), те же 40 бит.
     
  13. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    HoShiMin,

    Тогда если pdbr верен, выполняйте трансляцию. PTE/PDE etc это системный ll уровень, это никогда никто не использует. Следует выяснить почему отображение возвращает ошибку, не вся память может быть отображена.

    Это хороший путь что бы разобраться в механизмах памяти, но такой путь не приемлем для обычной реализации. Всё кончается на высокоуровневых апи.
     
  14. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.460
    Адрес:
    Россия, Нижний Новгород
    Почему-то засомневался, эквивалентны ли MmMapIoSpace и отображение \\.\Device\PhysicalMemory через ZwMapViewOfSection?
     
  15. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.553
    Адрес:
    Russia
    HoShiMin,
    на сколько я помню - скорее всего проблема в том что адрес уже замаплен. Да и вообще так делать нельзя.
    Для начала возьмите MmAllocateContiguousMemory
    она даст вам физический адрес. Его отправьте в MmMapIoSpace. Если все работает, значит (очевидно), что дело не в функции, а в том, что вы передаете невалидный физический адрес, либо адрес уже замаплен )
    если хотите получить виртуальный из физического - юзайте MmGetVirtualForPhysical
     
    UbIvItS и Indy_ нравится это.
  16. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    TermoSINteZ,

    С этим отображением довольно хитрое дело как помню. Бала давно проблема - блок был подкачан, соответственно эти апи фейлили(то самое, занятая память" ?). Дёргалась MmTrim*(), после чего весь рабочий набор системы отгружался и можно было после этого выделить непрерывный физ блок. Там походу какие то не очевидные фичи имеются. Я давно это уже не трогал, по памяти сложно точно сказать. Посмотрите сурки. Кстате это для тс.

    Так что если есть такие проблемы - сбросте системный WS(это освободит весь рабочий набор ядра - он будет откачан принудительно) через MmTrim..найдите апи, я не помню точно. По идеи это должно сработать.
    --- Сообщение объединено, 12 ноя 2018 ---
    MmTrimAllSystemPageableMemory() врк.

    MmAllocateContiguousMemorySpecifyCache() -> MmEmptyAllWorkingSets(), у меня где то в старых сурках нашёлся такой комент. MmTrimAllSystemPag[e]ableMemory() - выгружает только системную память". Квадратная скобка значит что есть в какой то версии экспортный баг с именами.

    Может это чем то поможет.
    --- Сообщение объединено, 12 ноя 2018 ---
    TermoSINteZ,

    > Для начала возьмите MmAllocateContiguousMemory она даст вам физический адрес.

    Судя по коменту выше эта апи именно и выгружает рн для освобождения памяти перед поиском.
     
  17. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.553
    Адрес:
    Russia
    Indy_, да именно так и происходит. Просто тс сделал какой-то код не почитав даже рекомендации WDK (MSDN)
     
  18. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    TermoSINteZ,

    Там по этой теме ничего нет. Была подобная проблема, но по описанию решение найти было невозможно. Пришлось реверсить нт, отсюда и баг с именами нашёлся. Забавно ведь - разраб ошибся, допустив опечатку.
     
  19. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.553
    Адрес:
    Russia
    Indy_, про почитать - я имел ввиду только то что, в мсдн нигде нет примеров по типу дергаем MmMapIoSpace для любого физ адреса и прочее.
     
  20. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775