Вопрос простой — если драйвер имеет Start = 0 (то есть SERVICE_BOOT_START) как можно получить базу ntdll.dll ?
Пробовал открыть ZwOpenFile (дальше хотел мапить и посмотреть ImageBase) — но не получилось, при открытии произошла ошибка STATUS_OBJECT_PATH_NOT_FOUND (если не ошибаюсь). Пробовал делать слепок модулей ZwQuerySystemInformation — но не повезло.
А>Пробовал открыть ZwOpenFile (дальше хотел мапить и посмотреть ImageBase) — но не получилось, при открытии произошла ошибка STATUS_OBJECT_PATH_NOT_FOUND (если не ошибаюсь).
какой путь передавали в ZwOpenFile ? надо бы "\\SystemRoot\\system32\\ntdll.dll", DOSовские симлинки (те которые \??\) на этом этапе еще не подмонтированы.
Как много веселых ребят, и все делают велосипед...
Re[2]: база модуля ntdll
От:
Аноним
Дата:
14.07.10 21:33
Оценка:
Здравствуйте, ononim, Вы писали:
А>>Пробовал открыть ZwOpenFile (дальше хотел мапить и посмотреть ImageBase) — но не получилось, при открытии произошла ошибка STATUS_OBJECT_PATH_NOT_FOUND (если не ошибаюсь). O>какой путь передавали в ZwOpenFile ? надо бы "\\SystemRoot\\system32\\ntdll.dll", DOSовские симлинки (те которые \??\) на этом этапе еще не подмонтированы.
Вы правы, передавал "\\SystemRoot\\system32\\ntdll.dll" — опробовал "\\Device\\HarddiskVolume1\\Windows\\system32\\ntdll.dll" — заработало, но тепер другой вопрос постает: как получить этот путь динамически?
Здравствуйте, x64, Вы писали:
А>>...как получить этот путь динамически?
x64>Не понял, зачем динамически? Вот это ("\\SystemRoot\\system32\\ntdll.dll") по идее должно работать в boot-time.
Вот это ("\\SystemRoot\\system32\\ntdll.dll") работать не будет.
AB>Вот это ("\\SystemRoot\\system32\\ntdll.dll") работать не будет.
Давненько не имел дела с boot-time. А почему, кстати? Ссылка \SystemRoot там уже есть, сформирована чуть по-другому (ARC-имя), но это вроде не смертельно. Что ещё?
Здравствуйте, x64, Вы писали:
AB>>Вот это ("\\SystemRoot\\system32\\ntdll.dll") работать не будет.
x64>Давненько не имел дела с boot-time. А почему, кстати? Ссылка \SystemRoot там уже есть, сформирована чуть по-другому (ARC-имя), но это вроде не смертельно. Что ещё?
Если посмотреть то ошибка возвращается в nt!ObpLookupObjectName, при повторном прохождении по символьной ссылке.
Вот вам call-stack:
при открытие символьной ссылки "\ArcName\multi(0)disk(0)rdisk(0)partition(1)" уже возвращает STATUS_OBJECT_NAME_NOT_FOUND(C0000034) и по этому не пройдет.
AB>при открытие символьной ссылки "\ArcName\multi(0)disk(0)rdisk(0)partition(1)" уже возвращает STATUS_OBJECT_NAME_NOT_FOUND(C0000034) и по этому не пройдет.
Да, всё верно, эта ссылка \ArcName\multi(0)disk(0)rdisk(0)partition(1) будет создана чуть позже. Автору в таком случае остаётся одно из двух:
1. Подождать, пока эта ссылка не будет создана и распарсить её рекурсивно (начиная, тем не менее, с \SystemRoot). Ждать тут, по идее, недолго.
2. Учитывая, что сами девайсы томов к этому моменту уже созданы, можно попытаться сопоставить \ArcName\multi(0)disk(0)rdisk(0)partition(1) девайсу тома \Device\HarddiskVolume1. По идее, ничего сложного, только не забыть учесть различные шины типа \ArcName\scsi(0)... и прочие.
Это более-менее документированные варианты. Возможно, ещё есть способы покопаться в блоке загрузчика, но это недокументировано и я не помню, чтобы там было что-то, что помогло бы при решении этой задачи. Есть другие идеи?
Здравствуйте, x64, Вы писали:
AB>>при открытие символьной ссылки "\ArcName\multi(0)disk(0)rdisk(0)partition(1)" уже возвращает STATUS_OBJECT_NAME_NOT_FOUND(C0000034) и по этому не пройдет.
x64>Да, всё верно, эта ссылка \ArcName\multi(0)disk(0)rdisk(0)partition(1) будет создана чуть позже. Автору в таком случае остаётся одно из двух:
x64>1. Подождать, пока эта ссылка не будет создана и распарсить её рекурсивно (начиная, тем не менее, с \SystemRoot). Ждать тут, по идее, недолго. x64>2. Учитывая, что сами девайсы томов к этому моменту уже созданы, можно попытаться сопоставить \ArcName\multi(0)disk(0)rdisk(0)partition(1) девайсу тома \Device\HarddiskVolume1. По идее, ничего сложного, только не забыть учесть различные шины типа \ArcName\scsi(0)... и прочие.
x64>Это более-менее документированные варианты. Возможно, ещё есть способы покопаться в блоке загрузчика, но это недокументировано и я не помню, чтобы там было что-то, что помогло бы при решении этой задачи. Есть другие идеи?
Есть. Например взять SharedUserData->NtSystemRoot и там будет C:\Windows, открыть символьную ссылку \Global??\C: и получить \Device\HarddiskVolumeX прилипить оставшийся путь от SharedUserData->NtSystemRoot (то есть Windows) ну и прилепить system32\ntdll.dll — вот вам путь
AB>Есть. Например взять SharedUserData->NtSystemRoot и там будет C:\Windows, открыть символьную ссылку \Global??\C: и получить \Device\HarddiskVolumeX прилипить оставшийся путь от SharedUserData->NtSystemRoot (то есть Windows) ну и прилепить system32\ntdll.dll — вот вам путь
x64>>Это ты в boot-time собрался всё проделывать? AB>а что плохого?
Вариант-то сам по себе неплохой (хотя в официальной документации о SharedUserData ни слова и это подозрительно), но всё же хотелось бы иметь некоторую уверенность:
1. Что \Global??\C: всегда будет готова к этому моменту.
2. Что формат KUSER_SHARED_DATA не будет меняться в будущих версиях.
По поводу п.2 есть такой комментарий:
//
// WARNING: This structure must have exactly the same layout for 32- and
// 64-bit systems. The layout of this structure cannot change and new
// fields can only be added at the end of the structure (unless a gap
// can be exploited). Deprecated fields cannot be deleted. Platform
// specific fields are included on all systems.
//
// Layout exactness is required for Wow64 support of 32-bit applications
// on Win64 systems.
//
// The layout itself cannot change since this structure has been exported
// in ntddk, ntifs.h, and nthal.h for some time.
//
Надеюсь, что это всё так и останется и в Windows 8 ничего не сломают =)
Здравствуйте, x64, Вы писали:
x64>Вариант-то сам по себе неплохой (хотя в официальной документации о SharedUserData ни слова и это подозрительно), но всё же хотелось бы иметь некоторую уверенность:
x64>1. Что \Global??\C: всегда будет готова к этому моменту. x64>2. Что формат KUSER_SHARED_DATA не будет меняться в будущих версиях.
x64>По поводу п.2 есть такой комментарий:
x64>
x64>//
x64>// WARNING: This structure must have exactly the same layout for 32- and
x64>// 64-bit systems. The layout of this structure cannot change and new
x64>// fields can only be added at the end of the structure (unless a gap
x64>// can be exploited). Deprecated fields cannot be deleted. Platform
x64>// specific fields are included on all systems.
x64>//
x64>// Layout exactness is required for Wow64 support of 32-bit applications
x64>// on Win64 systems.
x64>//
x64>// The layout itself cannot change since this structure has been exported
x64>// in ntddk, ntifs.h, and nthal.h for some time.
x64>//
x64>
x64>Надеюсь, что это всё так и останется и в Windows 8 ничего не сломают =)
SharedUserDat — должно быть в WDK.
насчет первого пункта — лучшая уверенность, это почитать книгу "Внутреннее устройство Microsoft Windows", глава 5 — там о загрузке системы. (если не ошибаюсь)
второй — ну сейчас работает на всех осях.
Здравствуйте, ononim, Вы писали:
AB>>Вот это ("\\SystemRoot\\system32\\ntdll.dll") работать не будет. O>а пробовали? O>кстати, загляните в \\REGISTRY\\MACHINE\\SYSTEM\\Setup
пробовал и как сказал х64 не работает.
а вот \\REGISTRY\\MACHINE\\SYSTEM\\Setup смотрел, но на ХР можно изменить информацию. Тоже видел эту ветку
Re: база модуля ntdll
От:
Аноним
Дата:
16.07.10 14:30
Оценка:
А>Вопрос простой — если драйвер имеет Start = 0 (то есть SERVICE_BOOT_START) как можно получить базу ntdll.dll ? А>Пробовал открыть ZwOpenFile (дальше хотел мапить и посмотреть ImageBase)
К начальному вопросу. Вот получит один путь к ntdll, откроет его и промапит – а что толку? Будет получена база для этого промапленного вида, не совпадающая с общесистемной базой – разве нет?
А>>Вопрос простой — если драйвер имеет Start = 0 (то есть SERVICE_BOOT_START) как можно получить базу ntdll.dll ? А>>Пробовал открыть ZwOpenFile (дальше хотел мапить и посмотреть ImageBase) А>К начальному вопросу. Вот получит один путь к ntdll, откроет его и промапит – а что толку? Будет получена база для этого промапленного вида, не совпадающая с общесистемной базой – разве нет?
База, по которой ntdll грузится, находится в ее PE хидере. Виндовый ASLR ее вроде пока еще не релокейтит.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, ononim, Вы писали:
А>>>Вопрос простой — если драйвер имеет Start = 0 (то есть SERVICE_BOOT_START) как можно получить базу ntdll.dll ? А>>>Пробовал открыть ZwOpenFile (дальше хотел мапить и посмотреть ImageBase) А>>К начальному вопросу. Вот получит один путь к ntdll, откроет его и промапит – а что толку? Будет получена база для этого промапленного вида, не совпадающая с общесистемной базой – разве нет? O>База, по которой ntdll грузится, находится в ее PE хидере. Виндовый ASLR ее вроде пока еще не релокейтит.
Вы абсолютно правы. Если загрузчик не сможет промапить ntdll на адрес который находиться PE хедере — будет бсод.
Re[4]: база модуля ntdll
От:
Аноним
Дата:
17.07.10 04:53
Оценка:
Если бы для ntdll не применялась ASLR, то ASLR бы эффективно отсутствовала – какой смысл рандомизировать что-то, если известна база хоть одного исполняемого модуля? Да ещё такой модуль как ntdll, ух.
Дело в другом. При создании секции для образов применяется ASLR и фиксятся релоки. Кроме того, соответствующим образом изменяется база в заголовке (для секции!). Когда такая секция мапится, система пытается отобразить её по выбранному ранее адресу (который редко совпадает с адресом в PE-хидере в файле на диске). Если это удаётся, возвращается STATUS_SUCCESS, а если нет, то маппирование происходит по другому адресу – и возвращается STATUS_IMAGE_NOT_AT_BASE (говорящий о том, что нужно пофиксить релоки перед использованием имаджа).
Так что способ узнать дефолтный рандомизированный адрес "промапить и прочитать из хидера" полностью валиден. Кстати, юзермодный загрузчик проверяет необходимость применения релоков к первичному модулю процесса именно таким способом – сравнивает базу в заголовке с заполненным ядром полем Peb->ImageBase.