Сорри, забыл совсем отписаться о результатах. В общем, суть такова: достаточно открыть ntdll.dll, создать на нём секцию вызовом ZwCreateSection(), а затем запросить информацию об образе через ZwQuerySection() с классом SectionImageInformation, поле TransferAddress в соответствующей структуре и будет адресом базы. Проверял и на x86, и на x64-системе, — работает, адрес правильный, т.е. тот же, что выдает lm a ntdll в отладчике. К слову, в PE-заголовке ntdll.dll поле AddressOfEntryPoint равно 0.
O>>>...впрочем мона извернуться примерно так: x64>>Нельзя, к сожалению, нужно всё сделать в драйвере. x64>>Вот мне и хотелось бы обойтись без всяких подобных кривохаков. O>Ну в кернеле есть ZwOpenFile/ZwCreateSection/ZwQuerySection O>А вот ZwQueryVirtualMemory чтобы добрацца до базы нету O>Впрочем мона думаю доколупаться до allocation base'а без поскипанного хака тем что начинаецца на Mm*, но как — сходу не скажу..
Вот еще подумалось: получить entry point вышеописанным образом, далее мапим длл себе в ядро каким нить Zw/MmMapViewOfSection, парсим DOS/PE хедер, находим RVA на entry point, потом вычитаем его из полученного от ZwQuerySection и получаем базу на руки. Технически хаков нету
Как много веселых ребят, и все делают велосипед...
Выяснилось, что в Windows 8 системный сервис NtQuerySystemInformation() с классом SystemModuleInformation теперь не возвращает в буфере информацию о загруженном в а.п. ядра модуле ntdll.dll, хотя вплоть до Windows 7 всё было ok. Класс SystemModuleInformationEx не помогает, информации о ntdll.dll там тоже нет. В общем-то, нужна по сути только база этого модуля, хотя, конечно, лучше, чтобы и всё остальное тоже было. Вариант мониторить загрузку всех модулей в системе не подходит мне. Какие ещё варианты есть?
O>>Вот еще подумалось: получить entry point вышеописанным образом, далее мапим длл себе в ядро каким нить Zw/MmMapViewOfSection, парсим DOS/PE хедер, находим RVA на entry point, потом вычитаем его из полученного от ZwQuerySection и получаем базу на руки. x64>Это всё интересно и понятно, но мне всё же желательно базу именно той ntdll.dll, которая загружена ядром.
А это и даст именно ту самую базу.
Как много веселых ребят, и все делают велосипед...
x64>Сорри, забыл совсем отписаться о результатах. В общем, суть такова: достаточно открыть ntdll.dll, создать на нём секцию вызовом ZwCreateSection(), а затем запросить информацию об образе через ZwQuerySection() с классом SectionImageInformation, поле TransferAddress в соответствующей структуре и будет адресом базы. Проверял и на x86, и на x64-системе, — работает, адрес правильный, т.е. тот же, что выдает lm a ntdll в отладчике. К слову, в PE-заголовке ntdll.dll поле AddressOfEntryPoint равно 0.
Ага, у его LdrInitializeThunk является ентри по сути.
Как много веселых ребят, и все делают велосипед...
x64>Выяснилось, что в Windows 8 системный сервис NtQuerySystemInformation() с классом SystemModuleInformation теперь не возвращает в буфере информацию о загруженном в а.п. ядра модуле ntdll.dll, хотя вплоть до Windows 7 всё было ok. Класс SystemModuleInformationEx не помогает, информации о ntdll.dll там тоже нет. В общем-то, нужна по сути только база этого модуля, хотя, конечно, лучше, чтобы и всё остальное тоже было. Вариант мониторить загрузку всех модулей в системе не подходит мне. Какие ещё варианты есть?
x64>Выяснилось, что в Windows 8 системный сервис NtQuerySystemInformation() с классом SystemModuleInformation теперь не возвращает в буфере информацию о загруженном в а.п. ядра модуле ntdll.dll, хотя вплоть до Windows 7 всё было ok. Класс SystemModuleInformationEx не помогает, информации о ntdll.dll там тоже нет. В общем-то, нужна по сути только база этого модуля, хотя, конечно, лучше, чтобы и всё остальное тоже было. Вариант мониторить загрузку всех модулей в системе не подходит мне. Какие ещё варианты есть?
э. а что ntdll делает в АП ядра? Или ты про это? —
правда тут получится не база, а entry point, но оттуда до базы уж рукой подать, так сказать..
Хотя из кернела сложновато наверно будет подавать рукой, разве что если попрыгать по allocation granularity вниз, пока не наткнемся на валидный MZ/PE header, но это уже какое то тонкое извращение..
Как много веселых ребят, и все делают велосипед...
Нет, во-первых, дело в драйвере происходит, во-вторых, чтобы вызвать LdrGetDllHandle(), необходимо сначала добраться до ntdll.dll, т.к. она только оттуда и экспортируется =)
Ну это вопрос терминологии.
Из ядра-то доступен модуль? Доступен.
O>...впрочем мона извернуться примерно так:
Нельзя, к сожалению, нужно всё сделать в драйвере.
O>Хотя из кернела сложновато наверно будет подавать рукой, разве что если попрыгать по allocation granularity вниз, пока не наткнемся на валидный MZ/PE header, но это уже какое то тонкое извращение.
Вот мне и хотелось бы обойтись без всяких подобных кривохаков.
x64>Угу, оно. O>>дык этож не ап ядра... x64>Ну это вопрос терминологии. x64>Из ядра-то доступен модуль? Доступен.
Нууу это как сказать.. Не доступнее чем kernel32.dll. Просто kernel32.dll есть тока в win32 процессах и мапиться туда в процесса стартапа процесса, а ntdll во все мапиться прямо из NtCreate*Process*, не уверен правда насчет System — проверь, может как раз таки и нет ее там больше, ибо нафига попу гармонь .
O>>...впрочем мона извернуться примерно так: x64>Нельзя, к сожалению, нужно всё сделать в драйвере. x64>Вот мне и хотелось бы обойтись без всяких подобных кривохаков.
Ну в кернеле есть ZwOpenFile/ZwCreateSection/ZwQuerySection
А вот ZwQueryVirtualMemory чтобы добрацца до базы нету
Впрочем мона думаю доколупаться до allocation base'а без поскипанного хака тем что начинаецца на Mm*, но как — сходу не скажу..
Как много веселых ребят, и все делают велосипед...
O>Вот еще подумалось: получить entry point вышеописанным образом, далее мапим длл себе в ядро каким нить Zw/MmMapViewOfSection, парсим DOS/PE хедер, находим RVA на entry point, потом вычитаем его из полученного от ZwQuerySection и получаем базу на руки.
Это всё интересно и понятно, но мне всё же желательно базу именно той ntdll.dll, которая загружена ядром.
Здравствуйте, x64, Вы писали:
x64>Сорри, забыл совсем отписаться о результатах. В общем, суть такова: достаточно открыть ntdll.dll, создать на нём секцию вызовом ZwCreateSection(), а затем запросить информацию об образе через ZwQuerySection() с классом SectionImageInformation, поле TransferAddress в соответствующей структуре и будет адресом базы. Проверял и на x86, и на x64-системе, — работает, адрес правильный, т.е. тот же, что выдает lm a ntdll в отладчике.
Не знаю как вы проверяли, но под XP x86 я получаю другой адрес по этому алгоритму:
GetBaseAddress32: 7C9120F8
0: kd> lm a ntdll
start end module name
7c900000 7c9b3000 ntdll (pdb symbols)
0: kd> !peb 7ffd4000
PEB at 7ffd4000
InheritedAddressSpace: No
ReadImageFileExecOptions: No
BeingDebugged: No
ImageBaseAddress: 01000000
Ldr 00171e90
Ldr.Initialized: Yes
Ldr.InInitializationOrderModuleList: 00171f28 . 00176030
Ldr.InLoadOrderModuleList: 00171ec0 . 00176020
Ldr.InMemoryOrderModuleList: 00171ec8 . 00176028
Base TimeStamp Module
1000000 48027549 Apr 14 01:04:09 2008 \??\C:\WINDOWS\system32\winlogon.exe
7c900000 4d00f287 Dec 09 19:15:19 2010 C:\WINDOWS\system32\ntdll.dll