Обьясните пожалуйста в чем отлицие функций с Nt префиксом от функций с Zw префиксом из (из ntdll.dll ). Заранее спасибо.
http://216.239.59.104/search?q=cache:e0zNVFXlsaMJ:www.osronline.com/article.cfm%3Farticle%3D257+Nt+vs+Zw&hl=ru&ct=clnk&cd=2&gl=ru
а у Шрайбера опечатка чтоли? обьясните пожалуйста какая из них все таки работает через обработчик прерывания? зачем вызывать из ядра функцию через INT 2Eh, если цель его - оградить ринг3-приложение от ядра
rudik или я чего не понял или меня речь о ntoskrnl.Nt*, ntoskrnl.Zw* т.е. в коде драйвера разница в чем если я вызываю NtOpenFile или ZwOpenFile и непонятно зачем их сделали, эти Zw* и еще может ктонибудь обьяснить этот процесс:
1. функции Nt собсно говоря надстройки над Zw, т.е. когда ты вызываешь функцию нт, происходит некоторые операции, например проверка валидности операндов, а затем вызывается все равно функция Zw. 2. функции Zw были "изначально"; "сделали" функции Nt. когдато мне так объяснили, и никаких проблем у меня не возникло (в смысле проверка на практике показала, что вроде бы так оно и есть)
вово а фразу типа подразумевают какбы наоброт что Zw надстройки над Nt, как тут не запутаться правильно я понял что эти операции происходят в обработчике прерываний? значит у шрайбера опечатка вышла правильно и получается что в драйвере безопаснее работать с Nt*, передача неправильных параметров к Zw может привести к BSOD, в то время как Nt обезопасит?
судя по следующему это распространенное заблуждение, на которое и я попался сечас напряг свои английские извилины и осилил статейку, которую дал gilg судя по дизассемблерному коду ntoskrnl.ZwReadFile Код (Text): 80504d4c b8b7000000 mov eax,0xb7 80504d51 8d542404 lea edx,[esp+0x4] 80504d55 9c pushfd 80504d56 6a08 push 0x8 80504d58 e89e550300 call nt!KiSystemService (8053a2fb) 80504d5d c22400 ret 0x24 это аналог вызова ядерных функций из ринга3 из ntdll.dll, и получается что никакой опечатки нет у шрайбера Zw работают через шлюз, а Nt - непосредственно сама функция.
k2 Zw* устанавливают PerviuosMode в KernelMode AFAIR и потом уже вызывают Nt*. В статье всё хорошо было расписано.
Я еще в 3 посте процитировал руссиновича, где правильно написано.. Насколько я понимаю, если вызов идёт из пользовательского режима, вызывается Zw, которая вызовет Nt, она проверит параметры, т.к. предывдущий режим был пользовательский и сделает все, что нужно, а Zw потом установит предыдущий режим обратно. А при вызове из драйверов стоит использовать Nt, получается, что так быстрее - не будет лишних проверок на KeGetPreviousMode и прочего, а Nt не будет проверять параметры, т.к. предыдущий режим ядерный. Повторюсь, это мое имхо
Great да вот определение это у Русиновича кривое какое-то и неполное, падеж неправильный можно подумать Nt сервисы устанавливают предыдущий режим не контролируются они в одном случае, если Zw* из KERNEL вызывать а если из USER MODE Zw* вызывать, они будут контролироваться потому как на самом деле все вызовы Nt* и Zw* из USER MODE, и только вызовы Zw* из KERNEL MODE в конечном итоге проходят через ядерный обработчик KiSystemService, в котором и устанавливается предыдущий режим, затем вызывается Nt* сервис. получается что я, только изучающий кернел мод уже утверждаю некоторые истины, что следовало бы делать вам, програмирующим в кернел мод ) на счет того что лучше в драйвере, насколько я понял, автор советует использовать Zw*, а Nt* только если нужно проверить полученные из USER MODE параметры при передаче их другой ядерной функции. теперь не понятна фраза мне у Шрайбера такая дизассемблерный код он не привел откуда и был мой 1-й вопрос в этой теме как видно инструкциями типа INT, SYSINTER даже и не пахнет в ntoskrnl.Zw*, только вызов KiSystemService
n0name я сомневаюсь что ее можно выполнить нормально в 0 кольце, даже если и можно то куда потом SYSEXIT управление-то передаст? в юзермод.. и этим все и закончится. Так что вряд ли SYSENTER в винде используется в ядре)
несправедливо как то... в sysexit знач if CPL!=0 then #GP(0)..., а в sysenter нима проверки на CPL!=3
вот бы сейчас сюда кодера из мелкософта, ну или когото кто точно знает ответ на этот вопрос. я, собственно, был уверен что Nt функции - это юзермодовые функции, которые в делают тоже что и Zw но с небольшими дополнениями, проверками, как и положено для юзермода. а Zw - тупо вызов соответствующей функции INT 2e. хотелось бы узнать точное.
Вот случайно "надыбал". Код (Text): If the system service is exported in the ZwXxx form, it can be used straightforwardly by kernel mode code. If the service is only exported in the NtXxx form, the kernel mode code must consider the checks performed on pointers and access to objects, as described in the Introduction. Код (Text): .text:0040142A ZwSetEvent proc near .text:0040142A .text:0040142A EventHandle = dword ptr 4 .text:0040142A PreviousState = dword ptr 8 .text:0040142A .text:0040142A mov eax, 0BFh .text:0040142F lea edx, [esp+4] .text:00401433 int 2Eh ; DOS 2+ internal - EXECUTE COMMAND .text:00401433 ; DS:SI -> counted CR-terminated command string .text:00401435 retn 8 .text:00401435 ZwSetEvent endp Код (Text): PAGE:00493813 ; NTSTATUS __stdcall NtSetEvent(HANDLE EventHandle,PULONG PreviousState) PAGE:00493813 public NtSetEvent PAGE:00493813 NtSetEvent proc near ; CODE XREF: PAGE:004FC003p PAGE:00493813 ; PAGE:0052F6EFp PAGE:00493813 PAGE:00493813 EventHandle = dword ptr 8 PAGE:00493813 PreviousState = dword ptr 0Ch PAGE:00493813 PAGE:00493813 push ebp PAGE:00493814 mov ebp, esp PAGE:00493816 push 0FFFFFFFFh PAGE:00493818 push offset unk_402A88 PAGE:0049381D push offset _except_handler3 PAGE:00493822 mov eax, large fs:0 PAGE:00493828 push eax PAGE:00493829 mov large fs:0, esp PAGE:00493830 push ecx PAGE:00493831 push ecx PAGE:00493832 sub esp, 18h PAGE:00493835 push ebx PAGE:00493836 push esi PAGE:00493837 push edi PAGE:00493838 mov [ebp-18h], esp PAGE:0049383B xor ebx, ebx PAGE:0049383D mov [ebp-4], ebx PAGE:00493840 mov eax, large fs:124h PAGE:00493846 mov [ebp-30h], eax PAGE:00493849 mov al, [eax+134h] PAGE:0049384F mov [ebp-24h], al PAGE:00493852 cmp al, bl PAGE:00493854 mov esi, [ebp+0Ch] PAGE:00493857 jz short loc_493861 PAGE:00493859 cmp esi, ebx PAGE:0049385B jnz loc_4C3DD7 PAGE:00493861 PAGE:00493861 loc_493861: ; CODE XREF: NtSetEvent+44j PAGE:00493861 ; PAGE:004C3DE6j PAGE:00493861 push ebx PAGE:00493862 lea eax, [ebp-1Ch] PAGE:00493865 push eax PAGE:00493866 push dword ptr [ebp-24h] PAGE:00493869 push ExEventObjectType PAGE:0049386F push 2 PAGE:00493871 push dword ptr [ebp+8] PAGE:00493874 call ObReferenceObjectByHandle PAGE:00493879 mov [ebp-20h], eax PAGE:0049387C cmp eax, ebx PAGE:0049387E jl short loc_4938A4 PAGE:00493880 push ebx PAGE:00493881 push dword_46D4B0 PAGE:00493887 push dword ptr [ebp-1Ch] PAGE:0049388A call KeSetEvent PAGE:0049388F mov edi, eax PAGE:00493891 mov [ebp-28h], edi PAGE:00493894 mov ecx, [ebp-1Ch] PAGE:00493897 call ObfDereferenceObject PAGE:0049389C cmp esi, ebx PAGE:0049389E jnz loc_4C3DEB PAGE:004938A4 PAGE:004938A4 loc_4938A4: ; CODE XREF: NtSetEvent+6Bj PAGE:004938A4 ; PAGE:004C3DF7j PAGE:004938A4 or dword ptr [ebp-4], 0FFFFFFFFh PAGE:004938A8 mov eax, [ebp-20h] PAGE:004938AB mov ecx, [ebp-10h] PAGE:004938AE mov large fs:0, ecx PAGE:004938B5 pop edi PAGE:004938B6 pop esi PAGE:004938B7 pop ebx PAGE:004938B8 leave PAGE:004938B9 retn 8 PAGE:004938B9 NtSetEvent endp ; sp = 24h PAGE:004938B9