Вот, возник очередной вопрос.. Как получить имя процесса? (как в taskmgr) (ZwQuerySystemInfo конешно рулит но чето слишком сложно получается...) И как перевести Unicode строку в простую или хотябы юникод вывести на экран? (Да, я знаю, что я нуб =) Желательно с описанием параметров... (нашел RtlUnicodeToMultiByteN, а чё толку там параметров куча) Спасибо
А если точнее, то так: DbgPrint( " String is '%ls' ", UnicodeString.Buffer ); Однако, в силу "специфики" типа UNICODE_STRING, надежнее писать следующим образом: DbgPrint( " String is '%wZ' ", &UnicodeString ); -- добавлено позднее -- PS. В приведенных выше примерах подразумевается, что переменная UnicodeString имеет тип UNICODE_STRING.
aintrust смотря что понимается под UnicodeString - объект или буфер, не все соблюдают венгерскую нотацию а что это за "специфика" _UNICODE_STRING?
знаете ли, это зависит от типа UnicodeString. если это UNICODE_STRING*, то я написал выше как надо. Если это сразу объект, то как ты. что еще за %wZ и специфика _UNICODE_STRING?
Речь вроде шла о Unicode-строке (UNICODE_STRING, насколько я понимаю), а не об указателе на нее, т.е. я имел ввиду объект типа UNICODE_STRING. Это мелочь, конечно, но новичка может смутить. Специфика состоит в том, что 1) "реальная" строка (то, на что указывает PWSTR Buffer в структуре UNICODE_STRING) необязательно должна терминироваться нулем ((WCHAR)0); 2) структура UNICODE_STRING содержит реальную длину строки в байтах (USHORT Length), т.е. без учета терминирующего нуля, если он даже в строке присутствует. Шаблон "%wZ" это учитывает.
<Вот, возник очередной вопрос.. Как получить имя процесса? (как в taskmgr) (ZwQuerySystemInfo конешно рулит но чето слишком сложно получается...) И как перевести Unicode строку в простую или хотябы юникод вывести на экран? (Да, я знаю, что я нуб =) Желательно с описанием параметров... (нашел RtlUnicodeToMultiByteN, а чё толку там параметров куча)> Находишь EPROCESS процесса к примеру функцией PsLookup... Затем лезешь в эту структуру и по определённому смещению(см. структуру в символах ntoskrnl) вытаскиваешь имя процесса.
Length = размер строки без нуля в байтах MaximumLength при инициализации ее через RtlInitUnicodeString равен размеру строки с завершающим нулем в байтах. Если инициализируется строка через RtlInitUnicodeString, то завершающий ноль там будет стопудов. А вообще, спасибо, про %wZ я не знал. Всегда записывал ноль вручную по смещению Length в строке.
Пока дописывал драйвер возникло ещё пару вопросов. Совсем уж оффтоп, ну да ладно создавать новую тему не буду... 1) Из Код (Text): DriverUnload proc pDriverObject:PDRIVER_OBJECT local CR0Reg1:dword invoke DbgPrint, $CTA0("DriverUnloaded\n") cli mov eax, CR0 mov CR0Reg1, eax and eax, 0FFFEFFFFh mov cr0, eax mov eax, KeServiceDescriptorTable mov eax, [eax] mov eax, [eax] mov ecx,OpenProcId mov edx,TrueNtOpenProcess mov [eax+ecx*04h],edx mov eax, CR0Reg1 mov CR0, eax sti ;invoke IoDeleteSymbolicLink, addr dSymbolicLinkName ;mov eax, pDriverObject ;invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject ret DriverUnload endp пытаюсь вынести код в макрос: Код (Text): nt_unhk macro num, prestore cli mov eax, CR0 mov ebx, eax and eax, 0FFFEFFFFh mov cr0, eax push num mov eax, KeServiceDescriptorTable mov eax, [eax] mov eax, [eax] pop ecx mov edx,prestore mov [eax+ecx*04h],edx mov eax, ebx mov CR0, eax sti endm DriverUnload proc pDriverObject:PDRIVER_OBJECT local pronum:dword invoke DbgPrint, $CTA0("DriverUnloaded\n") mov eax, OpenProcId mov pronum, eax nt_unhk pronum, TrueNtOpenProcess ;invoke IoDeleteSymbolicLink, addr dSymbolicLinkName ;mov eax, pDriverObject ;invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject ret DriverUnload endp На первый взгляд различий нет, но первый вариант работает, а второй.. со свистом вылетает в форточку яростно ругаясь неизвестными мне словами (белым по синему): WORKER_THREAD_RETURNED_AT_BAD_IRQL ЛОЛ кароче... Чем я его обидел? 2) Как реализуется загрузка ос? Допустим, написал я ничего не делающий загрузчик, поместил куда надо. Как теперь из него загрузить ос?=) Гдето я чето мельком слышал про .bin но слишком уж... Не понятно кароче... И как вообще делаются загрузочные диски и дискеты? Заранее спасибо%)
Ты повысил IRQL и забыл его понизить где-то, возможно, неявно. Поскольку драйвера загружаются так называемыми Worker Threads (Рабочие потоки) из процесса System, им сильно не нравится, когда DriverEntry возвращается с повышенным IRQL. Ты нажимаешь кнопку Power на системнике. Процессор принимает сигнал #RESET и производит аппаратный сброс. Процессор выполняется в реальном режиме для совместимости. Регистры устанавливаются в специально заготовленные для этого значения, в том числе EIP устанавливается в (кажется) FFFFFFF0. Там содержится команда JMP на процедуру инициализации. Производится Power-On-Self-Test (POST), включающий в себя проверку памяти и устройств. Далее вызывается прерывание INT19h и вся ответственность ложится на него. Обработчик этого прерывания опрашивает все дисководы системы в соответствии с порядком, установленным в настройках BIOS, на наличие загрузочного диска. Если таковой находится, сразу же первый (по порядку) сектор этого диска загружается по линейному адресу 07C00 и передает ему бразды правления. Далее, если этим сектором оказался Boot-сектор загрузочной дискеты MS-DOS, загрузчик считывает файлики IO.SYS и MSDOS.SYS и передает управление им управление. Если это Boot-сектор загрузочной дискеты Linux, он загружает другую часть загрузчика, которая грузит ядро Linux. Если это MBR какого-то жесткого диска, то он загружает поверх своего тела (опять по адресу 07C00) boot-сектор активного раздела. Тот загрузчик находит файл NTLDR (если стоит NT-based система на разделе) и передает ему управление. NTLDR показывает менюшку с вариантами загрузки, предложениями нажать F8 и прочее, потом инициализирует защищенный режим процессора, производит кое-чего и грузит ядро винды. Так вот, к чему я все это рассказываю. Загрузчик можно спокойно записать на место 1 сектора дискеты (boot-сектор). Управление получит первая команда этого сектора. Я, кстати, пишу сейчас по приколу загрузчик. Посмотреть на результаты моих трудов можно тут (http://www.wasm.ru/forum/viewtopic.php?id=18880). У меня есть шальная мысль дописать все это дело до какой-нибудь мини-ОС. Но я ее всячески отталкиваю, потому что это трудно и нету смысла. Пишу я скорее всего эту фигню просто для себя Как тестировать твой загрузчик. Ты собираешь свой ASM (или не ASM =)) файл в чистый бинарный файл. Лучше это делать FASM'ом. Он присвоит файлу расширение BIN. Далее указывай этот файл как образ загрузочной дискеты в эмуляторе VMWare Workstation. Ей плевать, что он меньше 1.44 мб. После этого, когда ты в ней выставишь загрузку с дискеты, она загрузит первый сектор (первые 512 байт) твоего загрузчика по линейному адресу 07c00 и передаст управление. Задачи "нормального" загрузчика: - считать с диска все остальные сектора со своим телом (в памяти сейсас лежат только первые 512 байт!!) - инициализировать IDT, GDT - отключить прерывания, перейти в защищенный режим, включить прерывания Если что, спрашивай Отвечу. PS. Предлагаю переместить наши дискуссии на тему загрузчиков в отдельную тему, линк выше в моем посте лежит.
Ок, писать начну обязательно спрошу=) А можно про IRQL попродробнее, как сделать так чтоб его не было?=\ (избавиться короче от бсод'а) Код я вроде привел, или, может быть, не в нем дело? Скину весь, буду надеяться на добрых опытных людей, мб ткнут носом... (мб при копипасте чего-нить напутал, н\р с cr0 в nt_hk макросе?)