Господа!!! Как можно вызвать NtProtectVirtualMemory на данном ядре. Идеи? Аналог? спасибо! P.S. KeServiceDescriptorTable не экспортируется ядром.
Алгоритм для всех 64-битных ядер: 1. Вычислить индекс/смещение функции в таблице. 2. Эвристически (почти без дизасма) найти базовый адрес таблицы системных сервисов. 3. Вычислить адрес требуемой функции, используя информацию, полученную на предыдуших шагах.
Код (Text): lkd> x nt!*ProtectVirtual* fffff800`02be6984 nt!NtProtectVirtualMemory (void *, void **, unsigned long *, unsigned long, unsigned long *) fffff800`028c5e60 nt!ZwProtectVirtualMemory = <no type information> fffff800`02be6470 nt!MiProtectVirtualMemory (struct _EPROCESS *, void **, unsigned long *, unsigned long, unsigned long *) lkd> u fffff800`028c5e60 L20 nt!ZwProtectVirtualMemory: fffff800`028c5e60 488bc4 mov rax,rsp fffff800`028c5e63 fa cli fffff800`028c5e64 4883ec10 sub rsp,10h fffff800`028c5e68 50 push rax fffff800`028c5e69 9c pushfq fffff800`028c5e6a 6a10 push 10h fffff800`028c5e6c 488d057d280000 lea rax,[nt!KiServiceLinkage (fffff800`028c86f0)] fffff800`028c5e73 50 push rax fffff800`028c5e74 b84d000000 mov eax,4Dh ; <<<<<<<<<< fffff800`028c5e79 e9c25f0000 jmp nt!KiServiceInternal (fffff800`028cbe40) fffff800`028c5e7e 6690 xchg ax,ax nt!ZwQuerySection: fffff800`028c5e80 488bc4 mov rax,rsp fffff800`028c5e83 fa cli fffff800`028c5e84 4883ec10 sub rsp,10h fffff800`028c5e88 50 push rax fffff800`028c5e89 9c pushfq fffff800`028c5e8a 6a10 push 10h fffff800`028c5e8c 488d055d280000 lea rax,[nt!KiServiceLinkage (fffff800`028c86f0)] fffff800`028c5e93 50 push rax fffff800`028c5e94 b84e000000 mov eax,4Eh ; <<<<<<<<<< fffff800`028c5e99 e9a25f0000 jmp nt!KiServiceInternal (fffff800`028cbe40) fffff800`028c5e9e 6690 xchg ax,ax nt!ZwResumeThread: fffff800`028c5ea0 488bc4 mov rax,rsp fffff800`028c5ea3 fa cli fffff800`028c5ea4 4883ec10 sub rsp,10h fffff800`028c5ea8 50 push rax fffff800`028c5ea9 9c pushfq fffff800`028c5eaa 6a10 push 10h fffff800`028c5eac 488d053d280000 lea rax,[nt!KiServiceLinkage (fffff800`028c86f0)] fffff800`028c5eb3 50 push rax fffff800`028c5eb4 b84f000000 mov eax,4Fh ; <<<<<<<<<< fffff800`028c5eb9 e9825f0000 jmp nt!KiServiceInternal (fffff800`028cbe40) lkd> ?fffff800`028c5e60 - 20*4D Evaluate expression: -8796050271040 = fffff800`028c54c0 lkd> u fffff800`028c54c0 L10 nt!ZwMapUserPhysicalPagesScatter: fffff800`028c54c0 488bc4 mov rax,rsp fffff800`028c54c3 fa cli fffff800`028c54c4 4883ec10 sub rsp,10h fffff800`028c54c8 50 push rax fffff800`028c54c9 9c pushfq fffff800`028c54ca 6a10 push 10h fffff800`028c54cc 488d051d320000 lea rax,[nt!KiServiceLinkage (fffff800`028c86f0)] fffff800`028c54d3 50 push rax fffff800`028c54d4 b800000000 mov eax,0 ; <<<<<<<<<< fffff800`028c54d9 e962690000 jmp nt!KiServiceInternal (fffff800`028cbe40) fffff800`028c54de 6690 xchg ax,ax nt!ZwWaitForSingleObject: fffff800`028c54e0 488bc4 mov rax,rsp fffff800`028c54e3 fa cli fffff800`028c54e4 4883ec10 sub rsp,10h fffff800`028c54e8 50 push rax fffff800`028c54e9 9c pushfq lkd> .for (r$t0=fffff800`028c54c0, $t1=0; @$t1 < 191; r$t1=@$t1+1) {.if dwo(@$t0 + @$t1 * 20 + 15) != @$t1 {.echo wtf?}} lkd> * no "wtf" Как видно, ZW-стабы идут по порядку и их размер одинаков. Т.е. достаточно получить каким-либо способом номер требуемого сервиса и номер какого-либо экспортируемого, после чего воспользовать арифметику.
Сие зависит от рук, ну и от ДНК наверно ещё. Что я использую (вкратце см. выше), то вполне стабильно.
приведите пример Вашего "эвристического" метода поиска базового адреса таблицы сс, который на 100% работает на winxp x64, w2k3 sp2 r1/r2 x64, vista sp1/sp2 x64, server 2k8 sp1/sp2 r1/r2 x64, win7 x64.
retmas >хотя конечно никакой стабильностью данные методы и не пахнут) Если уж ты посмотрел, как эти стабы реализованы на других 64-битных системах и увидел отличия, которые позволяют утверждать о нестабильности метода, то было бы здорово в таком случае привести отличительные особенности и аргументировать высказывание. Если же ты не смотрел отличия и утверждение о нестабильности голословно – что ж, ничего хорошего здесь.
Sol_Ksacap, win2k8 r2, есть проблема с постоянством длинны элемента данного обобщенного массива сервисов.. А ГЛАВНОЕ никакой уверенности, что в следующем билде что-то не изменится. Данный метод хорош, если больше нет никаких вариантов.. Но я последнее время стараюсь реализовывать задачи как можно более рекомендуемыми механизмами, только при таком подходе можно быть уверенным, что драйвер будет работать стабильно.. Но метод неплох, так же как и метод с непосредственным поиском смещения KeServiceDescriptorTable. Спасибо, господа, за помощь.