📄 virtual.c
字号:
mm = first_thread->et_task->mm; addr_page = (PVOID)((ULONG)address & PAGE_MASK); size_page = PAGE_ALIGN((ULONG)address + size) - (ULONG)addr_page; if (AllocationType & _MEM_STACK) addr_page -= size_page; if (addr_page) { if (!(AllocationType & _MEM_STACK) && (mm->start_stack< (ULONG)addr_page + size_page || mm->end_data > (ULONG)addr_page)) return -EFAULT; vma = find_vma(mm, (ULONG)addr_page); if (vma) { if (vma->vm_start > (ULONG)addr_page && vma->vm_start < (ULONG)addr_page + size_page) return -EFAULT; if (vma->vm_end < (ULONG)addr_page +size_page) return -EFAULT; if (vma->vm_start <= (ULONG)addr_page && vma->vm_end >= (ULONG)addr_page + size_page) { if (do_munmap(mm, (ULONG)addr_page, size_page)) return -EFAULT; } } } status = MmCreateMemoryArea(process, NULL, MEMORY_AREA_VIRTUAL_MEMORY, &addr_page, size_page, Protect, NULL, 0, (AllocationType & MEM_TOP_DOWN) == MEM_TOP_DOWN, bound_addr_multi); if (status <0) return -EFAULT; if (AllocationType & _MEM_STACK) { vma = find_vma(mm, (unsigned long)addr_page); if (vma) vma->vm_flags |= VM_STACK_FLAGS; mm->start_stack = (unsigned long)addr_page; addr_page += size_page; } if ((ULONG)UBaseAddress < TASK_SIZE) { if (copy_to_user(UBaseAddress, &addr_page, sizeof(PVOID))) return -EFAULT; } else *UBaseAddress = addr_page; if ((ULONG)URegionSize < TASK_SIZE) { if (copy_to_user(URegionSize, &size_page, sizeof(ULONG))) return -EFAULT; } else *URegionSize = size_page; return status;} /* end NtAllocateVirtualMemory *//* * protect_memory */NTSTATUS STDCALLprotect_memory(struct mm_struct *mm, ULONG address, ULONG size, pgprot_t new_prot, pgprot_t *old_prot){ struct vm_area_struct *vma; NTSTATUS status = STATUS_SUCCESS; ktrace("protect_memory\n"); down_write(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma || vma->vm_start > address || vma->vm_end < address + size) goto out; if (old_prot) *old_prot = vma->vm_page_prot; vma->vm_page_prot = new_prot; up_write(&mm->mmap_sem); return status;out: up_write(&mm->mmap_sem); return -EFAULT;} /* end protect_memory *//* * NtWriteVirtualMemory * Write to memory */NTSTATUS STDCALLNtWriteVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL){ struct ethread *thread, *first_thread; struct eprocess *process; struct win32_object *obj; struct mm_struct *mm = NULL; struct mm_struct *cur_mm = NULL; pgprot_t old_prot; PVOID address; NTSTATUS status; ktrace("NtWriteVirtualMemory\n"); thread = thread_find(); if (!thread) return -EINVAL; if (ProcessHandle==NtCurrentProcess() || !ProcessHandle) process = thread->threads_process; else { etget(thread); obj = GetObject(thread, ProcessHandle, &process_objclass); etput(thread); if (IS_ERR(obj)) return PTR_ERR(obj); process = obj->o_private; } first_thread = get_first_thread(process); mm = first_thread->et_task->mm; /* Make sure the target memory is writable */ status = protect_memory(mm, (ULONG)BaseAddress, NumberOfBytesToWrite, protection_map[VM_WRITE], &old_prot); if (status < 0) return status; /* Write memory */ if (process == get_eprocess(thread)) memcpy(BaseAddress, Buffer, NumberOfBytesToWrite); else { address = kmalloc(NumberOfBytesToWrite, GFP_KERNEL); if (copy_from_user(address, Buffer, NumberOfBytesToWrite)) { goto out; } cur_mm = KeAttachProcess(&process->pcb); if (copy_to_user(BaseAddress, address, NumberOfBytesToWrite)) { KeDetachProcess(cur_mm); goto out; } KeDetachProcess(cur_mm); kfree(address); } /*Reset the protection of the target memory */ status = protect_memory(mm, (ULONG)BaseAddress, NumberOfBytesToWrite, old_prot, NULL); if (status < 0) return status; if ((ULONG)NumberOfBytesWritten < TASK_SIZE) { if (copy_to_user(NumberOfBytesWritten, &NumberOfBytesToWrite, sizeof(ULONG))) { return -EFAULT; } } else *NumberOfBytesWritten = NumberOfBytesToWrite; return status;out: kfree(address); return -EFAULT;} /* end NtWriteVirtualMemory *//* * NtReadVirtualMemory * Read from memory */NTSTATUS STDCALLNtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN ULONG NumberOfBytesToRead, OUT PULONG NumberOfBytesRead OPTIONAL){ struct ethread *thread; struct eprocess *process; struct win32_object *obj; PVOID address; struct mm_struct *mm; NTSTATUS status = STATUS_SUCCESS; ktrace("NtReadVirtualMemory\n"); thread = thread_find(); if (!thread) return -EINVAL; if (ProcessHandle==NtCurrentProcess() || !ProcessHandle) process = thread->threads_process; else { etget(thread); obj = GetObject(thread, ProcessHandle, &process_objclass); etput(thread); if (IS_ERR(obj)) return PTR_ERR(obj); process = obj->o_private; } /* Read memory */ if (process == get_eprocess(thread)) memcpy(Buffer, BaseAddress, NumberOfBytesToRead); else { address = kmalloc(NumberOfBytesToRead, GFP_KERNEL); mm = KeAttachProcess(&process->pcb); if(copy_from_user(address, BaseAddress, NumberOfBytesToRead)) { KeDetachProcess(mm); goto out; } KeDetachProcess(mm); if (copy_to_user(Buffer, address, NumberOfBytesToRead)) goto out; kfree(address); } if ((ULONG)NumberOfBytesRead < TASK_SIZE) { if (copy_to_user(NumberOfBytesRead, &NumberOfBytesToRead, sizeof(ULONG))) return -EFAULT; } else *NumberOfBytesRead = NumberOfBytesToRead; return status;out: kfree(address); return -EFAULT;} /* end NtReadVirtualMemory *//* * NtFreeVirtualMemory * Free a range of virtual memory */NTSTATUS STDCALLNtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID* PBaseAddress, IN PULONG PRegionSize, IN ULONG FreeType){ struct ethread *thread, *first_thread; struct eprocess *process; struct win32_object *obj; struct mm_struct *mm; struct vm_area_struct *vma; PVOID address; ULONG size, size_page, addr_page; NTSTATUS status = STATUS_SUCCESS; ktrace("NtFreeVirtualMemory\n"); if ((ULONG)PBaseAddress < TASK_SIZE) { if (copy_from_user(&address,PBaseAddress,sizeof(PVOID))) return -EFAULT; } else address = *PBaseAddress; if ((ULONG)PRegionSize < TASK_SIZE) { if (copy_from_user(&size,PRegionSize,sizeof(ULONG))) return -EFAULT; } else size = *PRegionSize; thread = thread_find(); if (!thread) return -EINVAL; if (ProcessHandle==NtCurrentProcess()||!ProcessHandle) process = thread->threads_process; else { etget(thread); obj = GetObject(thread, ProcessHandle, &process_objclass); etput(thread); if (IS_ERR(obj)) return PTR_ERR(obj); process = obj->o_private; } first_thread = get_first_thread(process); mm = first_thread->et_task->mm; addr_page = (ULONG)(address) & PAGE_MASK; size_page = PAGE_ALIGN((ULONG)(address) + (size)) - addr_page; if (mm->start_stack < addr_page + size_page || mm->end_data > addr_page) return -EFAULT; vma = find_vma(mm, addr_page); if (!vma || vma->vm_start > addr_page || vma->vm_end < addr_page + size_page) return -EFAULT; down_write(&mm->mmap_sem); switch (FreeType) { case MEM_RELEASE: if (do_munmap(mm, addr_page, size_page)) status = -EFAULT; break; default: ktrace("Unimplemented free type\n"); status = -EFAULT; break; } up_write(&mm->mmap_sem); return status;} /* end NtFreeVirtualMemory */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -