> Here is my thought…taking ZwOpenThread as an example.
Peter speaks about KM Zw… stubs in ntoskkrnl.exe and not UM ones in NTDLL.DLL
So I need some way to find nt!KiServiceLinkage, nt!KiServiceInternal …
NO!!!
Judging from the code, nt!KiServiceInternal is the place in NTDLL where systenter instruction is located, and nt!KiServiceLinkage is the place to which sysexit returns control (this place, apparently, is occupied by a single ret instruction). They are of ZERO use to the kernel-mode code…
Anton Bassov
From my perspective Anton I see otherwise:
This is the UM stub.
kd> u ntdll!ZwOpenThread
ntdll!ZwOpenThread:
0000000077777cc0 4c8bd1 mov r10,rcx 0000000077777cc3 b8f8000000 mov eax,0F8h
0000000077777cc8 0f05 syscall 0000000077777cca c3 ret
0000000077777ccb 666690 xchg ax,ax 0000000077777cce 6690 xchg ax,ax
and what I posted before is the KM stub.
You can retrieve the addresses at run time from an exported Zw stub.
On Wed, 12 Aug 2009 20:39:45 +0200, wrote:
> Thanks Peter…I had sort of forged down the path you
> describe…however I am hitting some bumps that are expected but
> curious about what to do…
>
> Yes I can write an x64 assembler function…but not sure about the
> “prefix and such for exception handling”
>
> Here is my thought…taking ZwOpenThread as an example…disassembles
> to the following on my 2k8 x64 system:
>
> nt!ZwOpenThread:
> fffff800016a0d80 488bc4 mov rax,rsp<br>> fffff800016a0d83 fa cli
> fffff800016a0d84 4883ec10 sub rsp,10h<br>> fffff800016a0d88 50 push rax
> fffff800016a0d89 9c pushfq<br>> fffff800016a0d8a 6a10 push 10h
> fffff800016a0d8c 488d056d360000 lea <br>> rax,[nt!KiServiceLinkage (fffff800016a4400)]
> fffff800016a0d93 50 push rax<br>> fffff800016a0d94 b8f8000000 mov eax,0F8h
> fffff800016a0d99 e9a22e0000 jmp nt!KiServiceInternal <br>> (fffff800016a3c40)
> fffff800`016a0d9e 6690 xchg ax,ax
>
>
> So I need some way to find nt!KiServiceLinkage, nt!KiServiceInternal and
> modify the 0F8 syscall number to use the one I find in case it is a
> different system.
>
> My assumption is I can calculate the addresses for the Ki* functions,
> lea and jmp to the calculated addresses but substitute for a far jmp
> instead.
>
> Does this seem reasonable?
>
> Also passing the args should be taken care of by the caller to my asm
> function…as that is what appears to happen for the available Zw
> calls.
>
> For the record all responses have been helpful.
> what I posted before is the KM stub.
Sorry, Jonathan - I overlooked CLI in the code you had posted. In fact, I did not even look at it carefully, because I was just misled by the name - I thought ZwOpenThread() is not exported by ntoskrnl.exe( it was not exported on XP, but, AFAIK, in subsequent versions quite a few Zw functions that kernel did not export before became exported and even documented in WDK).
Let’s look at the code:
pushfq
push 10h
lea rax,[nt!KiServiceLinkage]
push rax
The above excerpt looks suspiciously similar to setting up a stack frame that is meant to be subsequently
used by IRET - it pushes flags and kernel-mode CS of 0x10 below the return address that gets set to KiServiceLinkage. Therefore, if IRET is used execution will continue at the address
KiServiceLinkage that will eventually return to the actual caller (the original return address is on the stack).
In other words, it looks like INT 0x2E is still around , and KiServiceInternal happens to be its handler…
Anton Bassov
Jonathan, following up my previous post, please pay a special attention to CLI - KiServiceInternal is about
to enter execution with interrupts disabled, which, again, strongly suggests the whole thing simulates INT n instruction.
Therefore, if KiServiceInternal is INT 0x2E handler, its address is available from IDT. Concerning ServiceLinkage, you can implement the stub that re-enables interrupts (please note that
IF is clear in flags that are saved on the stack so that execution will continue with disabled interrupts after IRET) and return to the original callee (its address is on the stack)…
Anton Bassov
“Cay Bremer” wrote in message news:xxxxx@ntdev…
> You can retrieve the addresses at run time from an exported Zw stub.
Yep. This is what I did.
–pa