System calls for Windows

Source: Internet
Author: User
Tags ssdt

have been learning about Windows kernel recently, write a blog for memo.

The specific process of Windows system call in the Pan teacher's "Windows kernel Principle and implementation" in the 8th chapter has been written very clearly, first read the picture given in the.

Take CreateFile as an example, after some parameter checking in Ring3 's CreateFile, the final call is NtCreateFile in Ntdll. There are also zwcreatefile, but their addresses point to the same area, so they are essentially the same function.

You can see in the export table again Ntdll:

Then break into the RING0 layer via sysenter or 0x2e and put the service number in EAX.

Ntoskrnl.exe in the ZwCreateFile:

kd> u nt!zwcreatefile
Nt! ZwCreateFile:
80501010 b825000000 mov eax,25h; service number
80501015 8d542404 Lea Edx,[esp+4]
80501019 9c PUSHFD
8050101A 6A08 Push 8
8050101c e830140400 Call nt! KiSystemService (80542451)
80501021 C22C00 ret 2Ch

Enter RING0 using int 0x2e

With WinDbg, you can view the 0x2e interrupt of IDT directly:

Kd>!idt 2e

Dumping IDT:

2e:80542451 nt! KiSystemService; You can see that the kisystemservice is pointing to this routine.

Of course, you can also calculate the address pointed to by the 0x2e interrupt by looking at the IDT table, and first find the contents of the 0x2e item in the IDT table:

Kd>!PCR
KPCR for Processor 0 at ffdff000:
Major 1 Minor 1
Nttib.exceptionlist:80551cb0
Nttib.stackbase:805524f0
nttib.stacklimit:8054f700
nttib.subsystemtib:00000000
nttib.version:00000000
nttib.userpointer:00000000
nttib.selftib:00000000

selfpcr:ffdff000
prcb:ffdff120
irql:00000000
irr:00000000
Idr:ffffffff
interruptmode:00000000
idt:8003f400; address of the IDT table
gdt:8003f000
tss:80042000

Currentthread:8055ce60
nextthread:00000000
Idlethread:8055ce60

Calculate 8003f400 + 8*0x2e = 8003f570

View:

Kd> DB 8003f570
8003f570 in the 80-e0 of the XX, the 8e q$ .... T.. W.... T.
8003F580 1b 8e 80-1A 1b xx xx 54 80 ...... T....... T.
8003F590 1b 8e 80-2e 1b xx XX 54 80 $ ..... T....... T.
8003f5a0 1b, 8e 80-42 1b, XX, 8e 8.....t.b ..... T.

Depending on the format of the IDT interrupt descriptor, you know that the routine offset is 80542451 and the segment selector is 0x8 (the contents of the IDT structure are explained in chapter 5th of the Windows kernel Principles and implementations)

Knowing the offset address, you also need to know the segment address in order to calculate the actual address.

Now that you know the segment selector is 0x8, you can view the corresponding segment descriptor:

Where Ti is 0 to change the index point to GDT,RPL to 0 indicates that the current privilege level is 0, the index represents its position in the GDT is the first item.

(This part of the knowledge in the book is introduced in the 4th chapter, but not very detailed, the specific content can refer to some protection models of information)

View GDT:

Kd> R GDTR
gdtr=8003f000; You can also use the!PCR command to find the GDT address

Kd> DB 8003f000
8003f000 xx (xx) 00-ff FF, 9b CF 00 ......... .....
8003f010 FF FF, 00-FF FF, cf. 00 .............

Obtained base address as 0x0000 by Segment description format

The address of the interrupt routine is calculated as 0000:80,542,451 as the address obtained directly from the WinDbg.

Enter RING0 via Sysenter

First look at the call location of the Sysenter directive:

kd> u ntdll! Kifastsystemcall
ntdll! Kifastsystemcall:
770801D0 8BD4 mov edx,esp
770801D2 0f34 Sysenter

ntdll! Kifastsystemcallret:
770801D4 c3 ret
770801D5 8da42400000000 Lea Esp,[esp]
770801DC 8d642400 Lea Esp,[esp]

The sysenter instruction works by reading the MSR register, loading the CS,EIP,ESP of the RING0 layer, and clearly eflags the VM markings.

Ia32_sysenter_cs 0x174

Ia32_sysenter_esp 0x175

Ia32_sysenter_eip 0x176

Use WinDbg to view:

Kd> RDMSR 174
MSR[174] = 00000000 ' 00000008
Kd> RDMSR 175
MSR[175] = 00000000 ' f8ac2000
Kd> RDMSR 176
MSR[176] = 00000000 ' 80542520

The CS Segment selector is 0x00000008 the same as before, so the destination address is 0000:80,542,520

Disassembly this address:

kd> u 80542520
Nt! Kifastcallentry:
80542520 b923000000 mov ecx,23h
80542525 6a30 Push 30h
80542527 0FA1 Pop FS
80542529 8ED9 mov ds,cx
8054252b 8EC1 mov es,cx
8054252d 648b0d40000000 mov ecx,dword ptr fs:[40h]
80542534 8b6104 mov esp,dword ptr [ecx+4]

Kifastcallentry is the invocation routine that goes into RING0.

In fact, a review of KiSystemService's disassembly reveals that KiSystemService eventually invokes the Kifastcallentry routine:

Nt! KISYSTEMSERVICE+0X5A:
805424AB C74508000ddbba mov dword ptr [ebp+8],0badb0d00h
805424B2 895d00 mov dword ptr [EBP],EBX
805424B5 897D04 mov dword ptr [Ebp+4],edi
805424b8 F6462CFF test byte ptr [ESI+2CH],0FFH
805424BC 0f858afeffff jne nt! Dr_kss_a (8054234c)
805424C2 FB STI
805424C3 e9e7000000 jmp nt! kifastcallentry+0x8f (805425AF) ; jump to Kifastcallentry

Then take a look at what's being jumped in the kifastcallentry:

Nt! kifastcallentry+0x8f:
805425AF 8bf8 mov edi,eax; KiSystemService will jump to this place.
805425B1 c1ef08 shr edi,8
805425B4 83e730 and edi,30h
805425B7 8BCF mov Ecx,edi
805425B9 03bee0000000 add Edi,dword ptr [esi+0e0h]
805425BF 8BD8 mov ebx,eax
805425C1 25ff0f0000 and EAX,0FFFH
805425C6 3b4708 cmp eax,dword ptr [edi+8]

Get Kifastcallentry address via MSR Register


As in WinDbg, use the RDMSR instruction to obtain the contents of the MSR Register, and then obtain the segment address from the GDT to calculate the actual address of the kifastcallentry.

ULONG Getaddressofkifastcallentry () {ulong Address = 0;_asm{jmp func_main  vgdtr:  //Open up a control to hold the contents of the GDTR register C2/>_emit 0x00          _emit 0x00          _emit 0x00          _emit 0x00          _emit 0x00          _emit 0x00          _emit 0x00          _emit 0x00  func_main:  pushadmov ecx,0x174rdmsrmov ebx, eax        //Get segment selector SGDT VGDTR//      read GDTR register save to VGDTR        mov edx, vgdtr          add edx, 0x02          mov eax, [edx]      //Get the GDT address from the GDTR register, then calculate the segment address by the GDT format        add ebx, eax                 mov edx, ebx          add edx, 0x07          mov eax, [edx]          shl eax,;  The loop left moves after 2 bytes of        mov edx, ebx          add edx, 0x02          mov ecx, [edx] and          ecx, 0x00ffffff           add eax, ecx        / /Calculate the segment address        mov ebx, eax            mov ecx, 0x176//Get EIP        rdmsr          add eax, ebx            mov address, eax  Popa D}return Address;}

Stack backtracking to get kifastcallentry address

This method is 360 to start with, the principle is kifastcallentry through call ebx invoke the target routine, then the example stacks ebp+4 inside is to return to kifastcallentry the address of the next instruction.

Take a look at the disassembly of Kifastcallentry calls in XP:

; eax store the call number, EDI holds the address of SSDT or SHADOWSSDT
805425FD 8a0c18 mov cl,byte ptr [eax+ebx]80542600 8b3f mov edi,dword ptr [edi] ; get keservicedes   Criptortable.servicetablebase address 80542602 8b1c87 mov ebx,dword ptr [edi+eax*4]; The calling address in the table is calculated based on the service number, 80542605 2be1 Sub esp,ecx80542607 c1e902 shr ecx,28054260a 8bfc mov edi,esp8054260c 3b3534315680 cmp ESI , DWORD ptr [nt! Mmuserprobeaddress (80563134)]80542612 0f83a8010000 Jae nt!          kisystemcallexit2+0x9f (805427c0) 80542618 F3a5 Rep movs dword ptr es:[edi],dword ptr [esi]8054261a ffd3 Call ebx; calling routine 8054261c 8be5 mov esp,ebp ; This is the address returned. 

  

Here we learn 360 ways to get the Zwsetevent service number and install its SSDT HOOK. Call it yourself again.

HANDLE G_fakeeventhandle = (HANDLE) 0x288c58f1; This self-defined handle is used to identify functions that are not needed.

and then call

Zwsetevent (G_fakeeventhandle, NULL);

Judging in the hook routines

if (eventhandle! = G_fakeeventhandle | | Exgetpreviousmode () ==usermode)//Not our own call, or call from UserMode, call the original function directly

{

Return ((myzwsetevent) o_ntsetevent) (eventhandle,previousstate);

}

Get the Kifastcallentry address in the hook routine

_asm
{
Push EAX
XOR Eax,eax
Lea EAX, [ebp+4]//Address of the backtracking stack
mov eax, [eax]
mov Address, eax
Pop eax
}

As you can see, the address obtained is 0x8054261c

We'll use WINBDG to see this address.

kd> u 0x8054261c
Nt! KIFASTCALLENTRY+0XFC:
8054261c 8BE5 mov esp,ebp
8054261e 648b0d24010000 mov ecx,dword ptr fs:[124h]
80542625 8b553c mov edx,dword ptr [ebp+3ch]
80542628 899134010000 mov dword ptr [Ecx+134h],edx
Nt! Kiserviceexit:
8054262E FA CLI
8054262F f7457000000200 test DWORD ptr [ebp+70h],20000h
80542636 7506 jne nt! kiserviceexit+0x10 (8054263e)
80542638 f6456c01 test byte ptr [ebp+6ch],1

You can see the contents of the above call ebx, so we find the address of kifatcallentry.

System calls for Windows

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.