GetServiceDescriptorTableShadowAddress proc uses esi edi ebx
local dwThreadId:DWORD
xor ebx, ebx ; = NULL. Assume ServiceDescriptorTableShadow will be not found
mov eax, KeServiceDescriptorTable
mov esi, [eax]
; Find KTHREAD.ServiceTable field
; For non-GUI threads this field == KeServiceDescriptorTable
; and it points to ServiceDescriptorTable
; For GUI threads
; ServiceDescriptorTableShadow
invoke KeGetCurrentThread
mov edi, 200h-4
.while edi
.break .if dword ptr [eax][edi] == esi
dec edi
.endw
.if edi != 0
; edi = offset to ServiceTable field in KTHREAD structure
mov dwThreadId, 080h
.while dwThreadId < 400h
push eax ; reserve DWORD on stack
invoke PsLookupThreadByThreadId, dwThreadId, esp
pop ecx ; -> ETHREAD/KTHREAD
.if eax == STATUS_SUCCESS
push dword ptr [ecx][edi]
fastcall ObfDereferenceObject, ecx
pop eax
.if eax != esi
mov edx, MmSystemRangeStart
mov edx, [edx]
mov edx, [edx]
.if eax > edx ; some stupid error checking
mov ebx, eax
invoke DbgPrint, $CTA0("FindShadowTable: Found in thread with ID: %X\n"), dwThreadId
.break
.endif
.endif
.endif
add dwThreadId, 4
.endw
.endif