Disclosure of Invention
In view of the above, the invention provides a method for debugging the kernel memory access boundary crossing based on global memory protection, which realizes the first time detection of the kernel memory access boundary crossing under the condition of no operating system kernel source code.
The invention provides a method for debugging kernel memory access boundary crossing based on global memory protection, which specifically comprises the following steps:
the method comprises the steps of constructing a kernel monitor for monitoring a loading process of a kernel module and a creation process of a kernel thread, constructing a virtual kernel debugger for monitoring heap memory access, performing heap memory region zero clearing and capturing memory access abnormality;
loading a kernel monitor and a virtual kernel debugger when a system to be tested is started, wherein the kernel monitor monitors kernel modules and kernel threads; the method comprises the steps that a physical memory page mapped to a kernel address space is recorded as a kernel physical memory page, a virtual kernel debugger starts monitoring of heap memory access, and a first heap memory address list is initialized, wherein the first heap memory address list is used for recording instruction addresses of heap memory access without memory access beyond boundaries;
in the running process of the system to be tested, the kernel monitor acquires the base address and the module size of the kernel module when monitoring the loading operation of the kernel module, acquires the stack base address and the stack limit of a new thread when monitoring that the kernel creates the new thread, and sends the base address, the module size, the stack base address and the stack limit to the virtual kernel debugger;
The virtual kernel debugger stores the received base address and the module size in a first kernel module address list, and stores an address space determined by a stack base address and a stack limit in a kernel stack memory list; setting memory areas except for the memory areas recorded in the first heap memory address list and the kernel stack memory list in the kernel physical memory page to be inaccessible;
When the virtual kernel debugger monitors heap memory allocation operation, marking an instruction address corresponding to a Hook function established for the heap memory allocation operation as a target instruction address, adding the target instruction address into a target instruction address list, and clearing a related heap memory area;
The virtual kernel debugger acquires an abnormal instruction address when monitoring that the memory access is abnormal, if the abnormal instruction address is in a first stack memory address list, suspending a system to be tested, determining an abnormal position according to an abnormal instruction address restoring call stack, and comparing the abnormal instruction address with an address in a first kernel module address list to determine a kernel module related to the abnormality; if the abnormal instruction address is not in the first heap memory address list and is in the target instruction address list, the current heap memory area is set to be accessible, the abnormal instruction address is added into the first heap memory address list, the currently executed instruction address is changed into the abnormal instruction address, an abnormal mark is cleared, and the system execution is resumed; if the abnormal instruction address is not in the first stack memory address list and is not in the target instruction address list, suspending the system to be tested, determining an abnormal position according to the abnormal instruction address restoring call stack, and comparing the abnormal instruction address with the kernel module related to the abnormal determination of the address in the first kernel module address list.
Further, the kernel monitor is built in a kernel driven manner.
Further, the method is constructed in a kernel driving mode, a callback function is registered for a kernel interface provided by a system, and when the kernel module is loaded, the callback function is called to monitor the kernel module.
Further, the base address, the module size, the stack base address and the stack limit are sent to the virtual kernel debugger, so as to transmit the communication interface between the operating system and the Hypervisor realized by LibVMI.
Further, the virtual kernel debugger is built in a Hypervisor manner based on hardware virtualization.
Further, the hardware-based virtualization is built in a Hypervisor mode, and is achieved by building a Hook function for heap memory access operation.
Further, the establishment of the Hook function is realized through ExAllocatePool, exAllocatePool, exAllocatePool or ExAllocatePoolWithTag functions of the Hook kernel.
Further, the current heap memory area related to the target instruction address is cleared, and the current heap memory area is written into the kernel of the system to be tested in the form of binary codes.
Advantageous effects
The invention constructs a kernel monitor and a virtual kernel debugger for a system to be tested, wherein the kernel monitor monitors the loading process of a kernel module and the creation process of a kernel thread in the system to be tested, and sends the obtained address information of the kernel module and the kernel thread to the virtual kernel debugger, the virtual kernel debugger dynamically modifies the access authority of a physical memory page of a specific kernel according to the received address information, and executes a zero clearing operation on a related memory area to trigger memory access abnormality when the allocation access operation of the heap memory is monitored, and the identification and the processing of the memory access boundary crossing of the kernel heap are realized through the judgment of the memory access abnormality, thereby realizing the first time detection of the memory access boundary crossing of the kernel under the condition without an operating system kernel source code and the kernel dynamic debugging analysis based on the detection result.
Detailed Description
The present invention will be described in detail with reference to the following examples.
The invention provides a method for debugging kernel memory access boundary crossing based on global memory protection, which has the following core ideas: the method comprises the steps that a kernel monitor and a virtual kernel debugger are built for a system to be tested, the kernel monitor monitors the loading process of a kernel module and the creation process of a kernel thread in the system to be tested, the obtained address information of the kernel module and the kernel thread is sent to the virtual kernel debugger, the virtual kernel debugger dynamically modifies the access authority of a physical memory page of a specific kernel according to the received address information, and when the allocation access operation of a heap memory is monitored, a zero clearing operation is carried out on a related memory area to trigger memory access abnormality, and timely identification and processing of memory access out-of-range of the heap memory are realized through judgment of the memory access abnormality.
The invention provides a method for debugging kernel memory access boundary crossing based on global memory protection, which specifically comprises the following steps:
The method comprises the steps of constructing a kernel monitor in a kernel driving mode, wherein the kernel monitor is used for monitoring a loading process of a kernel module and a creation process of a kernel thread in a system, acquiring related information of the kernel module and the kernel thread, and sending the information to a virtual kernel debugger. The related information of the kernel module comprises a kernel module base address and a module size, and the related information of the kernel thread comprises a stack base address (StackBase) and a stack limit (STACKLIMIT).
The kernel monitor is constructed in a kernel driving mode, a callback function can be registered by adopting a kernel interface provided by a system, and the callback function is called when the kernel module is loaded to monitor the kernel module. In addition, the information may be sent to the virtual kernel debugger by using a communication interface between the LibVMI operating system and the Hypervisor.
Based on hardware virtualization, a virtual kernel debugger is constructed in a Hypervisor mode, heap memory access operation is monitored and zero clearing operation on heap memory areas allocated by the heap memory access operation is executed by establishing a Hook function for the heap memory access operation, and memory access abnormality of a system to be tested is captured to finish debugging out of range of kernel memory access.
For Windows systems, the virtual kernel debugger may monitor heap memory access operations through memory allocation functions such as ExAllocatePool, exAllocatePool, exAllocatePool, or ExAllocatePoolWithTag of the Hook kernel. In the implementation process, a zero clearing operation of a heap memory area allocated by a heap memory access operation is executed, and the zero clearing operation is written into a kernel of a system to be tested in a binary code mode.
Loading a kernel monitor and a virtual kernel debugger when a system to be tested is started, wherein the kernel monitor monitors kernel modules and kernel threads; and recording the physical memory page mapped to the kernel address space as a kernel physical memory page, and starting monitoring of heap memory access operation by the virtual kernel debugger and initializing a first heap memory address list, wherein the first heap memory address list is used for recording the monitored instruction address related to the heap memory access operation which confirms that no memory access out-of-range exists.
In the running process of the system to be tested, the kernel monitor acquires the base address and the module size of the kernel module when monitoring the loading operation of the kernel module, acquires the stack base address and the stack limit of a new thread when monitoring that the kernel creates the new thread, and then sends the base address and the module size of the kernel module, the stack base address and the stack limit of the kernel thread to the virtual kernel debugger.
The virtual kernel debugger stores the received base address and the module size of the kernel module in a first kernel module address list, takes an address space determined by the stack base address and the stack limit of the kernel thread as a kernel thread stack memory, and stores the address space in the kernel stack memory list; and updating the access setting of the kernel physical memory page according to the first heap memory address list and the kernel stack memory list, namely setting the memory areas except the memory areas recorded by the first heap memory address list and the kernel stack memory list in the kernel physical memory page as inaccessible. The first kernel module address list is a list for storing the base address and the module size of the kernel module.
In the system execution process, some basic types of variables and reference variables of objects defined in the functions are distributed in stack memory of the functions, when a variable is defined in a section of code block, memory space is distributed for the variable in the stack, the variable is a local variable, after the scope of the variable is exceeded, the system automatically releases the memory space distributed for the variable, that is, the memory space can be immediately used for other purposes, therefore, the data type of the variable needs to be acquired from source code for the problem of whether the stack memory has access out-of-range, and the access out-of-range problem cannot be basically located in the absence of source code, so that the invention only detects the access out-of-range problem of the memory of the nuclear stack.
The virtual kernel debugger acquires an instruction address corresponding to the operation when monitoring heap memory allocation operation, marks the instruction address corresponding to a Hook function established for the memory allocation operation as a target instruction address, stores the target instruction address in a target instruction address list, and executes zero clearing operation on a related heap memory area;
The virtual kernel debugger acquires an abnormal instruction address when monitoring that the memory access is abnormal, judges whether the abnormal instruction address exists in a first heap memory address list, if so, suspends a system to be tested, determines an abnormal position according to an abnormal instruction address reduction call stack, and compares the abnormal instruction address with an address in the first kernel module address list to determine a kernel module related to the abnormality;
If the memory access abnormality is not caused by the fact that the memory area corresponding to the abnormal instruction address is set to be inaccessible, the current heap memory area is set to be accessible, the abnormal instruction address is added into the first heap memory address list, the instruction address to be executed at present is changed into the instruction address with the abnormality, an abnormality mark is cleared, and the system execution (i.e. re-execution) is resumed; if the memory access operation does not exist, the memory access boundary crossing generated by the current heap memory access operation is indicated, the system to be tested is suspended, the abnormal position is determined according to the abnormal instruction address reduction call stack, and the abnormal instruction address is compared with the kernel module with the address in the first kernel module address list to determine abnormal correlation.
The target instruction address list is a list for storing target instruction addresses.
Examples
The method for debugging the memory access boundary crossing of the kernel based on the global memory protection provided by the invention is adopted in the implementation, and the judgment and the debugging of the memory access boundary crossing of the heap memory are realized in a Windows system, and specifically comprises the following steps:
S1, creating a Windows kernel driver which is kernelMonitor, monitoring the loading process of a Windows kernel module, and sending the information of the kernel module to a constructed virtual kernel debugger hyperDebugger, wherein the method comprises the following steps:
S1.1, calling a kernel API of Windows: psSetLoadImageNotifyRoutine register a callback function, and when a new kernel module including a driver and the like loads, the callback function is called to monitor the loading of the kernel module and the kernel driver.
S1.2, enabling a registered callback function to be LoadImageNotifyRoutine, analyzing and reconstructing relevant information of a loaded kernel module in the callback function, and sending the information to hyperDebugger, wherein the method comprises the following steps:
(1) Examples of definitions for callback functions LoadImageNotifyRoutine are as follows:
LoadImageNotifyRoutine(
_In_opt_ PUNICODE_STRING FullImageName,
_In_ HANDLE ProcessId,
_In_ PIMAGE_INFO ImageInfo
)
wherein IMAGE INFO is defined as follows:
typedef struct _IMAGE_INFO {
union {
ULONG Properties;
struct {
ULONG ImageAddressingMode : 8;
ULONG SystemModeImage : 1;
ULONG ImageMappedToAllPids : 1;
ULONG ExtendedInfoPresent : 1;
ULONG MachineTypeMismatch : 1;
ULONG ImageSignatureLevel : 4;
ULONG ImageSignatureType : 3;
ULONG ImagePartialMap : 1;
ULONG Reserved : 12;
};
};
PVOID ImageBase;
ULONG ImageSelector;
SIZE_T ImageSize;
ULONG ImageSectionNumber;
} IMAGE_INFO, *PIMAGE_INFO;
(2) And constructing the memory layout information of each kernel module of the Windows kernel based on ImageBase, imageSize in the IMAGE_INFO, namely the starting address and the length of each kernel module.
(3) And acquiring the full path of the system file denoted by FullImageName, and extracting the manufacturer information of the kernel module, such as Microsoft and the like, by analyzing the PE file header information.
(4) The above information for each loaded kernel driver is passed to hyperDebugger through a communications interface implemented by LibVMI.
S2, in hyperDebugger, protecting all kernel heap memories, namely setting the heap memories to be inaccessible, and monitoring access operation to the heap memories to realize monitoring of access out-of-range, wherein the method specifically comprises the following steps:
s2.1, after the Windows kernel is loaded kernelMonitor, i.e. when DRIVERENTRY of kernelMonitor is executed, notify hyperDebugger to execute the following steps:
(1) And utilizing LibVMI to realize ExAllocatePool memory allocation function in the Hook Windows kernel to be tested in the Hypervisor layer, and executing a zero clearing operation to zero the allocated memory area after ExAllocatePool execution is finished. Since the first access to the memory after the allocation of the kernel memory is not necessarily a general kernel module, but should be a kernel module of Windows, and the access range is the allocated memory area. The method comprises the following specific steps:
with the associated API functions of interface Hook heap memory allocation provided by LibVMI, example code is as follows:
void hook_function(vmi_instance_t vmi, addr_t target_fn_addr) {
// Save original bytes of the target function
unsigned char original_bytes[5];
vmi_read_pa(vmi, target_fn_addr, 5, original_bytes);
// Write hook to target function
unsigned char hook_bytes[5] = {0xE9, HOOK_OFFSET}; // Example for x86 JMP
vmi_write_pa(vmi, target_fn_addr, 5, hook_bytes);
……
}
wherein vmi_read_pa and vmi_write_pa are functions provided by LibVMI to read and write upper level OS memory within Hypervisor.
The Hook function implementation steps are as follows:
executing standard related API functions of heap memory allocation, namely the original functions of the Hook;
The allocated heap memory region is cleared, written in assembly code, examples are as follows:
section .text
global _start
_start:
; the addresses assigned by the above functions are all return values and are stored in rax, so rax needs to be copied to rdi, i.e. rdi points to the memory region to be cleared, and rcx stores the region size
; The following is the hypothetical initialization, and these values need to be set according to the specific situation in actual use
mov rdi, rax
Mov rdi buffer, which is the starting address of the memory area
Mov rcx, buf_size, which is the size of the memory area
; Clearing regions in a high speed manner using rep stosq instructions
Xor rax, rax; set rax to zero
Rep stosq storing rax (0) to [ rdi ], (rdi +=8), decrementing rcx until rcx +=0
Ending the program and exiting
mov rax, 60 ; syscall: exit
xor rdi, rdi ; exit code 0
syscall
section .bss
buffer:
Resb 1024 defining a 1024 byte buffer
The buf_size equ $ -buffer is calculated
S2.2, kernelMonitor, after monitoring that the kernel creates a new thread, recorded as NEWKERNELTHREAD, notify hyperDebugger, hyperDebugger by LibVMI that all physical memory pages mapped by the kernel address space are set as inaccessible, and all physical memory pages marked as non-executable and not being stacks are specifically as follows:
(1) The LibVMI interface is adopted to acquire KTHREAD information of NEWKERNELTHREAD, two pieces of key information of StackBase, stackLimit are extracted, the two pieces of key information determine the address range of the thread stack memory, and the address range is recorded in listThreadStackBound.
(2) Core address space not previously checked and not in listThreadStackBound, identifying these physical memory pages as inaccessible, i.e., unreadable, unwritable, unexecutable, etc., example code for each hyperDebugger corresponding physical memory page:
Defining macros to assist page table resolution
#define PAGE_SHIFT 12
#define PML4_SHIFT 39
#define PDP_SHIFT 30
#define PD_SHIFT 21
#define PT_SHIFT 12
#define PML4_MASK 0x1FF
#define PDP_MASK 0x1FF
#define PD_MASK 0x1FF
#define PT_MASK 0x1FF
Function of/(and acquisition of CR3 register value)
unsigned __int64 GetCr3()
{
unsigned __int64 cr3_value;
__asm {
mov rax, cr3
mov cr3_value, rax
}
return cr3_value;
}
The address of the virtual page is the address of the virtual page
Function for resolving page tables and retrieving physical addresses
unsigned void ProtectVirtualToPhysical(PVOID virtual_address)
{
unsigned __int64 cr3 = GetCr3();
unsigned __int64* pml4_base = (unsigned __int64*)((cr3 & ~0xFFF) + 0xFFFFF80000000000);
unsigned __int64 pml4_index = ((unsigned __int64)virtual_address >> PML4_SHIFT) & PML4_MASK;
unsigned __int64 pdp_index = ((unsigned __int64)virtual_address >> PDP_SHIFT) & PDP_MASK;
unsigned __int64 pd_index = ((unsigned __int64)virtual_address >> PD_SHIFT) & PD_MASK;
unsigned __int64 pt_index = ((unsigned __int64)virtual_address >> PT_SHIFT) & PT_MASK;
unsigned __int64* pdp_base = (unsigned __int64*)(pml4_base[pml4_index] & ~0xFFF);
if (!pdp_base) return 0;
unsigned __int64* pd_base = (unsigned __int64*)(pdp_base[pdp_index] & ~0xFFF);
if (!pd_base) return 0;
unsigned __int64* pt_base = (unsigned __int64*)(pd_base[pd_index] & ~0xFFF);
if (!pt_base) return 0;
unsigned __int64 physical_address = (pt_base[pt_index] & ~0xFFF) + ((unsigned __int64)virtual_address & 0xFFF);
The physical address corresponding physical memory page is marked as unreadable, i.e. unreadable, unwritable, unexecutable, etc
}
S2.3, monitoring memory access abnormality and detecting memory access out-of-range.
The specific process is that when the memory access abnormality is monitored, the following judgment is carried out:
If the instruction address corresponding to the current memory access exception is an exception which occurs for the first time and the instruction address of the exception is at the code of the Hook function added by hyperDebugger, the instruction address is the first time to access the heap memory, the access range is just the allocated size, the current operation can be definitely not out of range, the attribute of the memory pages is set as readable and writable, and the execution of the Windows system to be tested is restored;
Otherwise, if the memory access is truly out of bounds, the Windows system to be tested is suspended, the call stack is restored based on the abnormal instruction address, and basic debugging functions of Windows, such as memory access, register access, data structure analysis and the like, are provided based on LibVMI, so that the out-of-bound adjustment of the memory access is completed.
In summary, the above embodiments are only preferred embodiments of the present invention, and are not intended to limit the scope of the present invention. Any modification, equivalent replacement, improvement, etc. made within the spirit and principle of the present invention should be included in the protection scope of the present invention.