📄 ntoskernel.c
字号:
return ret;}int dereference_object(void *object){ struct common_object_header *hdr; int ref_count; ENTER2("object: %p", object); hdr = OBJECT_TO_HEADER(object); TRACE2("hdr: %p", hdr); ref_count = post_atomic_add(hdr->ref_count, -1); TRACE2("object: %p, %d", object, ref_count); if (ref_count < 0) ERROR("invalid object: %p (%d)", object, ref_count); if (ref_count <= 0) { free_object(object); return 1; } else return 0;}wfastcall void WIN_FUNC(ObfDereferenceObject,1) (void *object){ TRACE2("%p", object); dereference_object(object);}wstdcall NTSTATUS WIN_FUNC(ZwCreateFile,11) (void **handle, ACCESS_MASK access_mask, struct object_attributes *obj_attr, struct io_status_block *iosb, LARGE_INTEGER *size, ULONG file_attr, ULONG share_access, ULONG create_disposition, ULONG create_options, void *ea_buffer, ULONG ea_length){ struct common_object_header *coh; struct file_object *fo; struct ansi_string ansi; struct wrap_bin_file *bin_file; char *file_basename; NTSTATUS status; spin_lock_bh(&ntoskernel_lock); nt_list_for_each_entry(coh, &object_list, list) { if (coh->type != OBJECT_TYPE_FILE) continue; /* TODO: check if file is opened in shared mode */ if (!RtlCompareUnicodeString(&coh->name, obj_attr->name, TRUE)) { fo = HEADER_TO_OBJECT(coh); bin_file = fo->wrap_bin_file; *handle = coh; spin_unlock_bh(&ntoskernel_lock); ObReferenceObject(fo); iosb->status = FILE_OPENED; iosb->info = bin_file->size; EXIT2(return STATUS_SUCCESS); } } spin_unlock_bh(&ntoskernel_lock); if (RtlUnicodeStringToAnsiString(&ansi, obj_attr->name, TRUE) != STATUS_SUCCESS) EXIT2(return STATUS_INSUFFICIENT_RESOURCES); file_basename = strrchr(ansi.buf, '\\'); if (file_basename) file_basename++; else file_basename = ansi.buf; TRACE2("file: '%s', '%s'", ansi.buf, file_basename); fo = allocate_object(sizeof(struct file_object), OBJECT_TYPE_FILE, obj_attr->name); if (!fo) { RtlFreeAnsiString(&ansi); iosb->status = STATUS_INSUFFICIENT_RESOURCES; iosb->info = 0; EXIT2(return STATUS_FAILURE); } coh = OBJECT_TO_HEADER(fo); bin_file = get_bin_file(file_basename); if (bin_file) { TRACE2("%s, %s", bin_file->name, file_basename); fo->flags = FILE_OPENED; } else if (access_mask & FILE_WRITE_DATA) { bin_file = kzalloc(sizeof(*bin_file), GFP_KERNEL); if (bin_file) { strncpy(bin_file->name, file_basename, sizeof(bin_file->name)); bin_file->name[sizeof(bin_file->name)-1] = 0; bin_file->data = vmalloc(*size); if (bin_file->data) { memset(bin_file->data, 0, *size); bin_file->size = *size; fo->flags = FILE_CREATED; } else { kfree(bin_file); bin_file = NULL; } } } else bin_file = NULL; RtlFreeAnsiString(&ansi); if (!bin_file) { iosb->status = FILE_DOES_NOT_EXIST; iosb->info = 0; free_object(fo); EXIT2(return STATUS_FAILURE); } fo->wrap_bin_file = bin_file; fo->current_byte_offset = 0; if (access_mask & FILE_READ_DATA) fo->read_access = TRUE; if (access_mask & FILE_WRITE_DATA) fo->write_access = TRUE; iosb->status = FILE_OPENED; iosb->info = bin_file->size; *handle = coh; TRACE2("handle: %p", *handle); status = STATUS_SUCCESS; EXIT2(return status);}wstdcall NTSTATUS WIN_FUNC(ZwOpenFile,6) (void **handle, ACCESS_MASK access_mask, struct object_attributes *obj_attr, struct io_status_block *iosb, ULONG share_access, ULONG open_options){ LARGE_INTEGER size; return ZwCreateFile(handle, access_mask, obj_attr, iosb, &size, 0, share_access, 0, open_options, NULL, 0);}wstdcall NTSTATUS WIN_FUNC(ZwReadFile,9) (void *handle, struct nt_event *event, void *apc_routine, void *apc_context, struct io_status_block *iosb, void *buffer, ULONG length, LARGE_INTEGER *byte_offset, ULONG *key){ struct file_object *fo; struct common_object_header *coh; ULONG count; size_t offset; struct wrap_bin_file *file; TRACE2("%p", handle); coh = handle; if (coh->type != OBJECT_TYPE_FILE) { ERROR("handle %p is invalid: %d", handle, coh->type); EXIT2(return STATUS_FAILURE); } fo = HANDLE_TO_OBJECT(coh); file = fo->wrap_bin_file; TRACE2("file: %s (%zu)", file->name, file->size); spin_lock_bh(&ntoskernel_lock); if (byte_offset) offset = *byte_offset; else offset = fo->current_byte_offset; count = min((size_t)length, file->size - offset); TRACE2("count: %u, offset: %zu, length: %u", count, offset, length); memcpy(buffer, ((void *)file->data) + offset, count); fo->current_byte_offset = offset + count; spin_unlock_bh(&ntoskernel_lock); iosb->status = STATUS_SUCCESS; iosb->info = count; EXIT2(return STATUS_SUCCESS);}wstdcall NTSTATUS WIN_FUNC(ZwWriteFile,9) (void *handle, struct nt_event *event, void *apc_routine, void *apc_context, struct io_status_block *iosb, void *buffer, ULONG length, LARGE_INTEGER *byte_offset, ULONG *key){ struct file_object *fo; struct common_object_header *coh; struct wrap_bin_file *file; unsigned long offset; TRACE2("%p", handle); coh = handle; if (coh->type != OBJECT_TYPE_FILE) { ERROR("handle %p is invalid: %d", handle, coh->type); EXIT2(return STATUS_FAILURE); } fo = HANDLE_TO_OBJECT(coh); file = fo->wrap_bin_file; TRACE2("file: %zu, %u", file->size, length); spin_lock_bh(&ntoskernel_lock); if (byte_offset) offset = *byte_offset; else offset = fo->current_byte_offset; if (length + offset > file->size) { WARNING("%lu, %u", length + offset, (unsigned int)file->size); /* TODO: implement writing past end of current size */ iosb->status = STATUS_FAILURE; iosb->info = 0; } else { memcpy(file->data + offset, buffer, length); iosb->status = STATUS_SUCCESS; iosb->info = length; fo->current_byte_offset = offset + length; } spin_unlock_bh(&ntoskernel_lock); EXIT2(return iosb->status);}wstdcall NTSTATUS WIN_FUNC(ZwClose,1) (void *handle){ struct common_object_header *coh; TRACE2("%p", handle); if (handle == NULL) { TRACE1(""); EXIT2(return STATUS_SUCCESS); } coh = handle; if (coh->type == OBJECT_TYPE_FILE) { struct file_object *fo; struct wrap_bin_file *bin_file; typeof(fo->flags) flags; fo = HANDLE_TO_OBJECT(handle); flags = fo->flags; bin_file = fo->wrap_bin_file; if (dereference_object(fo)) { if (flags == FILE_CREATED) { vfree(bin_file->data); kfree(bin_file); } else free_bin_file(bin_file); } } else if (coh->type == OBJECT_TYPE_NT_THREAD) { struct nt_thread *thread = HANDLE_TO_OBJECT(handle); TRACE2("thread: %p (%p)", thread, handle); ObDereferenceObject(thread); } else { /* TODO: can we just dereference object here? */ WARNING("closing handle 0x%x not implemented", coh->type); } EXIT2(return STATUS_SUCCESS);}wstdcall NTSTATUS WIN_FUNC(ZwQueryInformationFile,5) (void *handle, struct io_status_block *iosb, void *info, ULONG length, enum file_info_class class){ struct file_object *fo; struct file_name_info *fni; struct file_std_info *fsi; struct wrap_bin_file *file; struct common_object_header *coh; ENTER2("%p", handle); coh = handle; if (coh->type != OBJECT_TYPE_FILE) { ERROR("handle %p is invalid: %d", coh, coh->type); EXIT2(return STATUS_FAILURE); } fo = HANDLE_TO_OBJECT(handle); TRACE2("fo: %p, %d", fo, class); switch (class) { case FileNameInformation: fni = info; fni->length = min(length, (typeof(length))coh->name.length); memcpy(fni->name, coh->name.buf, fni->length); iosb->status = STATUS_SUCCESS; iosb->info = fni->length; break; case FileStandardInformation: fsi = info; file = fo->wrap_bin_file; fsi->alloc_size = file->size; fsi->eof = file->size; fsi->num_links = 1; fsi->delete_pending = FALSE; fsi->dir = FALSE; iosb->status = STATUS_SUCCESS; iosb->info = 0; break; default: WARNING("type %d not implemented yet", class); iosb->status = STATUS_FAILURE; iosb->info = 0; break; } EXIT2(return iosb->status);}wstdcall NTSTATUS WIN_FUNC(ZwOpenSection,3) (void **handle, ACCESS_MASK access, struct object_attributes *obj_attrs){ INFO("%p, 0x%x, %d", obj_attrs, obj_attrs->attributes, access); TODO(); *handle = obj_attrs; return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(ZwMapViewOfSection,10) (void *secn_handle, void *process_handle, void **base_address, ULONG zero_bits, LARGE_INTEGER *secn_offset, SIZE_T *view_size, enum section_inherit inherit, ULONG alloc_type, ULONG protect){ INFO("%p, %p, %p", secn_handle, process_handle, base_address); TODO(); *base_address = (void *)0xdeadbeef; return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(ZwUnmapViewOfSection,2) (void *process_handle, void *base_address){ INFO("%p, %p", process_handle, base_address); TODO(); return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(ZwCreateKey,7) (void **handle, ACCESS_MASK desired_access, struct object_attributes *attr, ULONG title_index, struct unicode_string *class, ULONG create_options, ULONG *disposition){ struct ansi_string ansi; if (RtlUnicodeStringToAnsiString(&ansi, attr->name, TRUE) == STATUS_SUCCESS) { TRACE1("key: %s", ansi.buf); RtlFreeAnsiString(&ansi); } *handle = NULL; return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(ZwOpenKey,3) (void **handle, ACCESS_MASK desired_access, struct object_attributes *attr){ struct ansi_string ansi; if (RtlUnicodeStringToAnsiString(&ansi, attr->name, TRUE) == STATUS_SUCCESS) { TRACE1("key: %s", ansi.buf); RtlFreeAnsiString(&ansi); } *handle = NULL; return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(ZwSetValueKey,6) (void *handle, struct unicode_string *name, ULONG title_index, ULONG type, void *data, ULONG data_size){ struct ansi_string ansi; if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) == STATUS_SUCCESS) { TRACE1("key: %s", ansi.buf); RtlFreeAnsiString(&ansi); } return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(ZwQueryValueKey,6) (void *handle, struct unicode_string *name, enum key_value_information_class class, void *info, ULONG length, ULONG *res_length){ struct ansi_string ansi; if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) == STATUS_SUCCESS) { TRACE1("key: %s", ansi.buf); RtlFreeAnsiString(&ansi); } TODO(); return STATUS_INVALID_PARAMETER;}wstdcall NTSTATUS WIN_FUNC(ZwDeleteKey,1) (void *handle){ ENTER2("%p", handle); return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(ZwPowerInformation,4) (INT info_level, void *in_buf, ULONG in_buf_len, void *out_buf, ULONG out_buf_len){ INFO("%d, %u, %u", info_level, in_buf_len, out_buf_len); TODO(); return STATUS_ACCESS_DENIED;}wstdcall NTSTATUS WIN_FUNC(WmiSystemControl,4) (struct wmilib_context *info, struct device_object *dev_obj, struct irp *irp, void *irp_disposition){ TODO(); return STATUS_SUCCESS;}wstdcall NTSTATUS WIN_FUNC(WmiCompleteRequest,5) (struct device_object *dev_obj, struct irp *irp, NTSTATUS status, ULONG buffer_used, CCHAR priority_boost){ TODO(); return STATUS_SUCCESS;}noregparm NTSTATUS WIN_FUNC(WmiTraceMessage,12) (void *tracehandle, ULONG message_flags, void *message_guid, USHORT message_no, ...){ TODO(); EXIT2(return STATUS_SUCCESS);}wstdcall NTSTATUS WIN_FUNC(WmiQueryTraceInformation,4) (enum trace_information_class trace_info_class, void *trace_info, ULONG *req_length, void *buf){ TODO(); EXIT2(return STATUS_SUCCESS);}/* this function can't be wstdcall as it takes variable number of args */noregparm ULONG WIN_FUNC(DbgPrint,12) (char *format, ...){#ifdef DEBUG va_list args; static char buf[100]; va_start(args, format); vsnprintf(buf, sizeof(buf), format, args); printk(KERN_DEBUG "%s (%s): %s", DRIVER_NAME, __FUNCTION__, buf); va_end(args);#endif return STATUS_SUCCESS;}wstdcall void WIN_FUNC(KeBugCheckEx,5) (ULONG code, ULONG_PTR param1, ULONG_PTR param2, ULONG_PTR param3, ULONG_PTR param4){ TODO(); return;}wstdcall void WIN_FUNC(ExSystemTimeToLocalTime,2) (LARGE_INTEGER *system_time, LARGE_INTEGER *local_time){ *local_time = *system_time;}wstdcall ULONG WIN_FUNC(ExSetTimerResolution,2) (ULONG time, BOOLEAN set){ /* why a driver should change system wide timer resolution is * beyond me */ return time;}wstdcall void WIN_FUNC(DbgBreakPoint,0) (void){ TODO();}wstdcall void WIN_FUNC(_except_handler3,0) (void){ TODO();}wstdcall void WIN_FUNC(__C_specific_handler,0) (void){ TODO();}void WIN_FUNC(_purecall,0) (void){ TODO();}void WIN_FUNC(__chkstk,0) (void){ TODO();}#include "ntoskern
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -