comment $


    ---------------------------------------------------
        Finding KiServiceTable in more stable way
    ---------------------------------------------------
         by Piotr Bania <bania.piotr@gmail.com>
	      http://www.piotrbania.com
		 All rights reserved!



  Disclaimer
  ----------

   Author takes no responsibility for any actions with provided 
   informations or codes. The copyright for any material created by the 
   author is reserved. Any duplication of codes or texts provided here 
   in electronic or printed publications is not permitted without the 
   author's agreement. 


  Info
  ----

   The idea was firstly introduced by 90210, this is mainly only a 
   assembly implementation of it. This method is finding the 
   KiServiceTable by checking requests to KeServiceDescriptorTable
   (relocation information, this appears in every ntoskrnl for
   obvious reasons). So here it is.


$



include my_macro.inc


		call	find_KiServiceTable
		call	get_ntos_base

		mov	eax,dword ptr [real_ntos_base]
		mov	ebx,dword ptr[KiServiceTable]
		add	ebx,eax
		int	3


exit:
		push 	0
		@callx 	ExitProcess



; ------------------------------------------------------------
; finds the KiServiceTable from ntoskrnl.exe
; ------------------------------------------------------------

find_KiServiceTable:
		pushad
		
		push	1			;DONT_RESOLVE_DLL_REFERENCES
		push	0
		@pushsz	"C:\windows\system32\ntoskrnl.exe"
		@callx	LoadLibraryExA
		@check 	0,"Error: cannot load library"
		mov	ebx,eax


		@pushsz	"KeServiceDescriptorTable"
		push	eax
		@callx	GetProcAddress
		mov	edi,eax

		; search for: 	mov ds:KeServiceDescriptorTable, offset _KiServiceTable
		; 		C7 05 C0 B1 54 80 A8 E7 4F 80
		; we need to find this instruction, here we will use relocations to gain
		; information


		mov	eax,[ebx+3ch]
		add	eax,ebx

		mov	edx,[eax+34h]
		mov	dword ptr [imagebase],edx

		mov	ecx,[eax+0a0h]					; fixup rva
		add	ecx,ebx						
		mov	dword ptr [base],ebx


SIZEOF_IMAGE_BASE_RELOCATION	equ 	8
IMAGE_REL_BASED_HIGHLOW		equ	30h

		mov	dword ptr [first],1
		sub	edi,ebx

	reloc_loop:
			add	ecx,dword ptr [block_size]
			mov	edx,ecx
			add	edx,SIZEOF_IMAGE_BASE_RELOCATION		

			mov	esi,[ecx+4]					
			mov	dword ptr [block_size],esi
			test	esi,esi
			jz	r_loop_c
			
			sub	esi,SIZEOF_IMAGE_BASE_RELOCATION
			shr	esi,1						

			
			
			xor	ebp,ebp	

		reloc_loop2:
			
				movzx	ebx,byte ptr [edx+1]
				and     ebx,0F0h
				
				cmp	ebx,IMAGE_REL_BASED_HIGHLOW		
				jne	r_loop2_c

				pushad

				movzx	ebp,word ptr [edx]
				and     ebp,0FFFh
				add	ebp,[ecx]				

				mov	edx,ebp
				add	edx,dword ptr [base]
				mov	edx,[edx]
				sub	edx,dword ptr [imagebase]


				cmp	edx,edi
				jne	not_needed

				; reloc points to our KeServiceDescriptorTable

				mov	ebx,dword ptr [base]
				cmp	word ptr [ebx+ebp-2],05c7h
				jne	not_needed

				mov	edx,[ebx+ebp+4]
				sub	edx,dword ptr [imagebase]
				mov	dword ptr [KiServiceTable],edx

		not_needed:
				popad
								
		r_loop2_c:
				add	edx,2						
				inc	ebp
				cmp	ebp,esi
				jl	reloc_loop2	


			cmp	dword ptr [first],1
			jne	r_loop_c
			mov	dword ptr [first],0
			jmp	reloc_loop

r_loop_c:		cmp	dword ptr [ecx],0
			jne	reloc_loop

		popad
		ret



get_ntos_base	proc
		local __MODULES	: _MODULES

		pushad

		@get_api_addr	"ntdll","NtQuerySystemInformation"
		@check	0,"Error: cannot grab NtQuerySystemInformation address"
		mov	ebx,eax

		call	a1
ns		dd	0
a1:		push	4
		lea	ecx,[__MODULES]
		push	ecx
		push	SystemModuleInformation
		call	eax
		cmp	eax,0c0000004h
		jne	error_ntos


		push	dword ptr [ns]				
		push	GMEM_FIXED or GMEM_ZEROINIT
		@callx	GlobalAlloc
		mov	ebp,eax

		push	0
		push	dword ptr [ns]
		push	ebp
		push	SystemModuleInformation
		call	ebx
		test	eax,eax
		jnz	error_ntos

		mov	eax,dword ptr [ebp.smi_Base]
		mov	dword ptr [real_ntos_base],eax
				
			
		push	ebp
		@callx	GlobalFree
				




		popad
		ret

error_ntos:	xor	eax,eax
		@check	0,"Error: cannot execute NtQuerySystemInformation"

get_ntos_base	endp






_MODULES		struct
	dwNModules	dd	0
	
;_SYSTEM_MODULE_INFORMATION:
	smi_Reserved	dd	2 dup (0)
	smi_Base	dd	0
	smi_Size	dd	0
	smi_Flags	dd	0
	smi_Index	dw	0
	smi_Unknown	dw	0
	smi_LoadCount	dw	0
	smi_ModuleName	dw	0
	smi_ImageName	db	256 dup (0)
;_SYSTEM_MODULE_INFORMATION_SIZE = $-offset _SYSTEM_MODULE_INFORMATION
			ends	


SystemModuleInformation equ    11





real_ntos_base		dd	0
KiServiceTable		dd	0

block_size		dd	0
base			dd	0
first			dd	0
imagebase		dd	0





end start