💂 Personal homepage: Your little sweet heart~_ CSDN blog
🤟 Update / learn tutorials / WEB Security / Intranet penetration / binary security / reverse engineering / and other articles every day. You can continue to pay attention to them
💬 If the article is helpful to you, welcome to follow, like, collect (one click three links) and subscribe to the column.
💅 If you have any questions, you are welcome to send a private letter and will reply in time!
Â
System call learning
Review above
According to the analysis of the previous article:
1.3 the two methods of looping into the 0 ring are interrupt gate and fast call. The CPU supports fast call, then_ KUSER_ SHARED_ The function pointed to by the SystemCall attribute of the data structure is KiFastSystemCall. Execute KiFastSystemCall and enter the 0 ring by means of quick call; If it is not supported, the function pointed to by SystemCall is KiIntSystemCall, execute KiIntSystemCall, and enter the 0 ring in the form of interrupt gate.
2. Fast call does not need to access memory, and the interrupt gate needs to read TSS and IDT tables
3. After the int 0x2e and sysenter instructions enter the 0 loop, the two functions KiSystemService and KiFastCallEntry are called respectively.
4. The original register is stored in_ KTRAP_ In the frame structure, the API parameter pointer of ring 3 is passed to ring 0 through EDX.
According to the analysis results of the previous article, the two functions finally execute the same piece of code, as shown in the figure
The 407781 function is marked in the figure, followed by the same code part executed. The 7781 function is in_ Inside the KiFastCallEntry function. The picture is too big to capture all of it.
KiSystemService / KiFastCallEntry padding_ KTRAP_ Subsequent parts of frame
Although the entries of these two functions are different, they are filled_ KTRAP_ After frame, the same code will be executed.
Preliminary knowledge:
Storage system service number 0BAh in eax
Parameter pointer of three rings stored in edx
System service table
_KTHREAD+0xE0= +0x0e0 ServiceTable : Ptr32 Void
There are two system service tables. The first one is to find the kernel function and the second one is to find the Win32k.sys driver function
Structure: 0x10 size
typedef struct _SERVICE_DESCRIPTOR_TABLE { PULONG ServiceTableBase; // Pointer, pointing to the function address, each member occupies 4 bytes PULONG ServiceCounterTableBase; // The number of times the current system service table has been called ULONG NumberOfService; // Total number of service functions PUCHAR ParamTableBase; // The total length of the parameters of the service function, in bytes, one byte for each member // For example, if the service function has two parameters, and each parameter accounts for four bytes, the total length of the corresponding parameters is 8 // The function address member corresponds to the total length member of the parameter one by one } SSDTEntry, *PSSDTEntry;
- The functions in the system service table are exported from the kernel file
- It does not contain all functions exported from the kernel file, but the most commonly used kernel functions of the 3-ring
SSDT table
Full name: System Services Descriptor Table
Each member of the SSDT is called the system service table
View SSDT table
kd> dd nt!KeServiceDescriptorTable
The second table is 0. Using the public export function KeServiceDescriptorTable, we can't see the table structure of win32k.sys
The win32k.sys system service table is visible
System service No.: the lower 12 bits are the subscripts of the function parameter table and the function address table. If the 13th bit (subscript 12) is 0, it means to find the first system service table Ntoskrl.exe. If it is 1, it means to find the second table win32k.sys. The last 12 bits are the indexes of the function address table and the function parameter table.
analysis
.text:00407781 .text:00407781 loc_407781: ; CODE XREF: _KiBBTUnexpectedRange+18↑j .text:00407781 ; _KiSystemService+6E↑j .text:00407781 mov edi, eax ;eax In is the system service number .text:00407783 shr edi, 8 ;edi Shift right 8 bits .text:00407786 and edi, 30h ;Judge the system service number, 12 digits, 0:edi == 0x00 ;1:edi == 0x10 .text:00407789 mov ecx, edi .text:0040778B add edi, [esi+0E0h]; [esi+0E0h]:_KTHREAD+0xE0=ServiceTable,edi Point to the system service table, where the address of the system service table is added directly edi According to the operation result, we can skillfully get which table to check (the two tables are continuous), and each table accounts for 16 bytes .text:00407791 mov ebx, eax .text:00407793 and eax, 0FFFh ;After the and operation, only the lower 12 digits of the system service number are reserved .text:00407798 cmp eax, [edi+8] ;edi Point to the system service table,[edi+8]: NumberOfService,Determine whether the function you are looking for is out of range .text:0040779B jnb _KiBBTUnexpectedRange ;If it is greater than the number of system call numbers, jump, that is, the system call number is out of bounds .text:004077A1 cmp ecx, 10h ;ecx Saved is edi And 0 x30 The result of and operation can only be 0 x00 Or 0 x10 .text:004077A4 jnz short loc_4077C0 ;If the system call number is less than 0 x1000,Then jump .text:004077A6 mov ecx, ds:0FFDFF018h ;Only when ecx == 0x10 Will be executed downward,The function is dynamic loading GUI Equal graph correlation function .text:004077AC xor ebx, ebx .text:004077AE .text:004077AE loc_4077AE: ; DATA XREF: _KiTrap0E+110↓o .text:004077AE or ebx, [ecx+0F70h] .text:004077B4 jz short loc_4077C0 .text:004077B6 push edx .text:004077B7 push eax .text:004077B8 call ds:_KeGdiFlushUserBatch .text:004077BE pop eax .text:004077BF pop edx .text:004077C0 .text:004077C0 loc_4077C0: ; CODE XREF: _KiFastCallEntry+B4↑j .text:004077C0 ; _KiFastCallEntry+C4↑j .text:004077C0 inc dword ptr ds:0FFDFF638h; .text:004077C6 mov esi, edx ;edx:Three ring parameter pointer .text:004077C8 mov ebx, [edi+0Ch] ; [edi+0Ch]:ParamTableBase(Parameter table (pointer) .text:004077CB xor ecx, ecx ;eax The system call number passed in by the 3 ring is saved .text:004077CD mov cl, [eax+ebx] ;eax The system call number passed in by the 3 ring is saved,ebx The parameter table pointer is saved,The purpose of this instruction is to get the total length of the parameters of the kernel function and store them in the cl .text:004077D0 mov edi, [edi] ;Get the first member of the system call table (function address pointer) .text:004077D2 mov ebx, [edi+eax*4] ;Function address pointer + System call number*4(Multiply by 4 because each member occupies 4 bytes),ebx Function address stored in .text:004077D5 sub esp, ecx ;Raise the stack to a height of cl,The purpose is to save the parameters in the three ring stack .text:004077D7 shr ecx, 2 ;Parameter total length/4=Number of parameters .text:004077DA mov edi, esp ;Set the 0 ring stack address of the parameter .text:004077DC cmp esi, ds:_MmUserProbeAddress ;judge esi Is it out of bounds with the maximum address range that the user program can access .text:004077E2 jnb loc_407990 ;If the boundary is exceeded, jump and handle the exception .text:004077E8 .text:004077E8 loc_4077E8: ; CODE XREF: _KiFastCallEntry+2A4↓j .text:004077E8 ; DATA XREF: _KiTrap0E+106↓o .text:004077E8 rep movsd ;Copy parameters(How many times depends on the number of parameters<-004077D7 result )Stack to 0 ring .text:004077EA call ebx ;Calling kernel functions NtReadVirtualMemory
experiment:
View function address:
[function address table] + System service number * 4]= Kernel function address 805aa712
View parameter address
[parameter table + [system service number]= Number of kernel function parameters (unit: bytes) 14
To view kernel function disassembly:
If the article is helpful to you, welcome to follow, like, collect (one click three links) and subscribe to the column.
Â
Â