⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 section.c

📁 该项目主要是将wingdows程序直接运行在linux上
💻 C
字号:
/* * section.c * * Copyright (C) 2006  Insigme Co., Ltd * * Authors:  * - Chenzhan Hu * * This software has been developed while working on the Linux Unified Kernel * project (http://linux.insigma.com.cn) in the Insigma Reaserch Institute,   * which is a subdivision of Insigma Co., Ltd (http://www.insigma.com.cn). *  * The project is sponsored by Insigma Co., Ltd. * * The authors can be reached at linux@insigma.com.cn. * * This program is free software; you can redistribute it and/or modify it * under the terms of  the GNU General  Public License as published by the * Free Software Foundation; either version 2 of the  License, or (at your * option) any later version. * * Revision History: *   Jan 2006 - Created. */ /*  * section.c: section syscall functions * Reference to Kernel-win32 code */#include <linux/module.h>#include "section.h"#include "objwait.h"#include "thread.h"#include <asm/uaccess.h>#include <linux/file.h>#include <linux/mman.h>#include <linux/win32_process.h>#ifdef CONFIG_UNIFIED_KERNELstatic int  SectionConstructor(struct win32_object *, void *);static int  SectionReconstructor(struct win32_object *, void *);static void SectionDestructor(struct win32_object *);static int  SectionPoll(struct wait_table_entry *, struct ethread *);extern int  data_section_map(struct win32_section *, unsigned long *,		unsigned long, unsigned long, unsigned long);struct win32_object_class section_objclass = {	oc_type:	"SECTN",	constructor:	SectionConstructor,	reconstructor:	NULL,	destructor:	SectionDestructor,	poll:		SectionPoll,};static unsigned long prot2linux[] = {	/* _PAGE_NOACCESS */	PROT_NONE,	/* _PAGE_READONLY */	PROT_READ,	/* _PAGE_READWRITE */	PROT_READ | PROT_WRITE,	/* _PAGE_WRITECOPY */	PROT_READ,	/* _PAGE_EXECUTE */	PROT_EXEC,	/* _PAGE_EXECUTE_READ */	PROT_EXEC | PROT_READ,	/* _PAGE_EXECUTE_READWRITE */	PROT_EXEC | PROT_READ | PROT_WRITE,	/* _PAGE_EXECUTE_WRITECOPY */	PROT_EXEC | PROT_READ};/* * initialise the section object classes */void SectionClassInit(void){	InitObjectClass(&section_objclass);} /* end SectionClassInit() *//* * open a section object, maybe creating if non-existent */NTSTATUSSTDCALLNtCreateSection(		OUT PHANDLE  SectionHandle,		IN ACCESS_MASK  DesiredAccess,		IN POBJECT_ATTRIBUTES  ObjectAttributes OPTIONAL,		IN PLARGE_INTEGER  MaximumSize OPTIONAL,		IN ULONG  SectionPageProtection,		IN ULONG  AllocationAttributes,		IN HANDLE  FileHandle OPTIONAL		){	HANDLE	hSection;	char	*oname;	struct win32_object	*obj, *fobj = NULL;	struct ethread	*thread;	struct section_args	args;	OBJECT_ATTRIBUTES	obj_attr;	UNICODE_STRING		obj_name;	LARGE_INTEGER	max_size;	if (!(thread = thread_find()))		return -EINVAL;		if (ObjectAttributes) {		if ((unsigned long)ObjectAttributes < TASK_SIZE) { /* FIXME */			if (copy_from_user(&obj_attr, ObjectAttributes, sizeof(obj_attr)))				return -EFAULT;			if(obj_attr.ObjectName){				if (copy_from_user(&obj_name, obj_attr.ObjectName, sizeof(obj_name)))					return -EFAULT;				obj_attr.ObjectName = &obj_name;				args.ObjectAttributes = &obj_attr;				oname = (char *)(obj_name.Buffer);			} else {				obj_attr.ObjectName = NULL;				args.ObjectAttributes = &obj_attr;				oname = NULL;			}		}		else {			args.ObjectAttributes = ObjectAttributes;			oname = (char *)(ObjectAttributes->ObjectName->Buffer);		}	} else {		args.ObjectAttributes = NULL;		oname = NULL;	}	if (MaximumSize) {		if ((unsigned long)MaximumSize < TASK_SIZE) { /* FIXME */			if (copy_from_user(&max_size, MaximumSize, sizeof(max_size)))				return -EFAULT;			args.MaximumSize = &max_size;		}		else			args.MaximumSize = MaximumSize;	}	else		args.MaximumSize = NULL;		/* gain access to the file */	if (FileHandle) {		etget(thread);		fobj = GetObject(thread, FileHandle, &file_objclass);		etput(thread);		if (IS_ERR(fobj))			return PTR_ERR(fobj);	}		/* create a section_args struct */	args.DesiredAccess = DesiredAccess;	args.SectionPageProtection = SectionPageProtection;	args.AllocationAttributes = AllocationAttributes;	args.FileHandle = FileHandle;	args.FileObject = fobj;	/* create a section object */	etget(thread);	obj = CreateObject(thread, &section_objclass, oname, &args, &hSection);	etput(thread);	if (IS_ERR(obj)) {		if (fobj)			objput(fobj);		return (NTSTATUS)PTR_ERR(obj);	}		ktrace("*** NtCreateSection(%p) = %p\n",obj,hSection);	objput(obj);	if (fobj)		objput(fobj);	if ((unsigned long)SectionHandle < TASK_SIZE			&& copy_to_user(SectionHandle, &hSection, sizeof(hSection)))		return -EFAULT;	else		return STATUS_SUCCESS;} /* end NtCreateSection() *//* * map a view of the section to the process's address space */NTSTATUSSTDCALLNtMapViewOfSection(		IN HANDLE  SectionHandle,		IN HANDLE  ProcessHandle,		IN OUT PVOID  *BaseAddress,		IN ULONG  ZeroBits,		IN ULONG  CommitSize,		IN OUT PLARGE_INTEGER  SectionOffset  OPTIONAL,		IN OUT PSIZE_T  ViewSize,		IN SECTION_INHERIT  InheritDisposition,		IN ULONG  AllocationType,		IN ULONG  Protect		){	NTSTATUS	status = -EINVAL;	size_t		size = 0;	unsigned long	addr = 0;	unsigned long	flags = 0;	struct win32_object	*sec_obj, *proc_obj = NULL;	struct ethread	*thread;	struct eprocess *process;	LARGE_INTEGER	sec_off = {.QuadPart = 0};	if (!(thread = thread_find()))		return -EINVAL;		if (BaseAddress) {		if (copy_from_user(&addr, BaseAddress, sizeof(PVOID)))			return -EFAULT;	}		if (addr) {		/* fixed address map, align to 64k */		flags = MAP_FIXED;		addr = (addr + BASE_ADDRESS_ALIGN - 1) & ~(BASE_ADDRESS_ALIGN - 1);	}	/* map offset, aligned to PAGE_SIZE */	if (SectionOffset) {		if (copy_from_user(&sec_off, SectionOffset, sizeof(sec_off)))			return -EFAULT;		/* TODO: not support 64bit offset */		if (sec_off.u.HighPart)			return -EINVAL;	}		sec_off.u.LowPart &= PAGE_MASK;	if (ViewSize) {		if (copy_from_user(&size, ViewSize, sizeof(size)))			return -EFAULT;	}		/* access the section object */	etget(thread);	sec_obj = GetObject(thread, SectionHandle, &section_objclass);	if (IS_ERR(sec_obj)) {		etput(thread);		return PTR_ERR(sec_obj);	}		if (!ProcessHandle || ProcessHandle == NtCurrentProcess()) {		process = thread->threads_process;		etput(thread);	}	else {		proc_obj = GetObject(thread, ProcessHandle, &process_objclass);		etput(thread);		if (IS_ERR(proc_obj)) {			objput(sec_obj);			return PTR_ERR(proc_obj);		}		process = proc_obj->o_private;	}		status = MmMapViewOfSection(			(PVOID)sec_obj,			process,			BaseAddress ? (void *)&addr : NULL,			ZeroBits,			CommitSize,			SectionOffset ? (PLARGE_INTEGER)&sec_off : NULL,			ViewSize ? (PSIZE_T)&size : NULL,			InheritDisposition,			AllocationType,			Protect			);	/* return the address if sucess */	if (!status)		if(copy_to_user(BaseAddress, &addr, sizeof(PVOID)))			status = -EFAULT;	if (proc_obj)		objput(proc_obj);	objput(sec_obj);	ktrace("*** NtMapViewOfSection(%p) = %d\n", sec_obj, status);	return status;} /* end NtMapViewOfSection() *//* * unmap a mapped view of the file * - the view must start _exactly_ on the address */NTSTATUSSTDCALLNtUnmapViewOfSection(		IN HANDLE  ProcessHandle,		IN PVOID  BaseAddress		){	/* only unmap DATA SECTION */	struct vm_area_struct	*vma;	struct mm_struct	*mm;	unsigned long	len, addr;	NTSTATUS	ret = -EINVAL;	/* TODO: how to unmap PE IMAGE */	ktrace("*** NtUnmapViewOfSection %p\n", BaseAddress);	mm = current->mm;	addr = (unsigned long)BaseAddress;	vma = find_vma(mm, addr);	if (vma) {		struct win32_section	*ws;		if ((ws = (struct win32_section *)vma->vm_private_data) && ws->ws_munmap)			return ws->ws_munmap(ws);		len = vma->vm_end - vma->vm_start;		/* grab the process's memory mapping semaphore */		down_write(&mm->mmap_sem);		/* do the munmap operation */		ret = do_munmap(mm, addr, len);		/* release the process's memory mapping semaphore */		up_write(&mm->mmap_sem);	}	return ret;} /* NtUnmapViewOfSection() *//*  * NtQuerySection */NTSTATUS STDCALLNtQuerySection(IN HANDLE SectionHandle,		IN SECTION_INFORMATION_CLASS SectionInformationClass,		OUT PVOID SectionInformation,		IN ULONG SectionInformationLength,		OUT PULONG ResultLength  OPTIONAL){	struct win32_section    *ws;	struct win32_object     *sec_obj;	struct ethread  *thread;	long len;	PSECTION_IMAGE_INFORMATION sii;	PSECTION_BASIC_INFORMATION sbi;	ktrace("NtQuerySection\n");	if(!(thread = thread_find())) {		kdebug("***error find thread\n");		return -EINVAL;	}	sec_obj = GetObject(thread, SectionHandle, &section_objclass);	if (IS_ERR(sec_obj)) {		kdebug("can't find created eprocess\n");		return -EINVAL;	}	ws = sec_obj->o_private;	switch (SectionInformationClass) {		case SectionBasicInformation:			if(!(sbi = kmalloc(sizeof(SECTION_BASIC_INFORMATION), GFP_KERNEL))) {				kdebug("***error malloc, No memory\n");				return -ENOMEM;			}			sbi->Attributes = ws->ws_alloctype;			if (ws->ws_alloctype & _SEC_IMAGE) {				sbi->BaseAddress = 0;				sbi->Size.QuadPart = 0;			}			else {				sbi->BaseAddress = (void *)ws->ws_sections->wis_rva;				sbi->Size.QuadPart = ws->ws_sections->wis_size;			}			if (ResultLength != NULL) {				len = sizeof(SECTION_BASIC_INFORMATION);				if(copy_to_user(ResultLength, &len, sizeof(long))) {					kdebug("wrong copy to user\n");					kfree(sbi);					return -EFAULT;				}			}			if (copy_to_user(SectionInformation, sbi, sizeof(*sbi))) {				kdebug("wrong copy to user\n");				kfree(sbi);				return -EFAULT;			}			break;		case SectionImageInformation:			if(!(sii = kmalloc(sizeof(SECTION_IMAGE_INFORMATION), GFP_KERNEL))) {				kdebug("***error malloc, No memory\n");				return -ENOMEM;			}			if(ws->ws_alloctype & _SEC_IMAGE) {				sii->EntryPoint = ws->ws_entrypoint;				sii->StackReserve = ws->ws_stackresv;				sii->StackCommit = ws->ws_stackcommit;				sii->Subsystem= ws->ws_subsystem;				sii->MinorSubsystemVersion = ws->ws_minorver;				sii->MajorSubsystemVersion = ws->ws_majorver;				sii->Characteristics = ws->ws_imagecharacter;				sii->ImageNumber = ws->ws_machine;				sii->Executable = ws->ws_executable;			}			if (ResultLength != NULL) {				len = sizeof(SECTION_IMAGE_INFORMATION);				if(copy_to_user(ResultLength, &len, sizeof(long))){					kdebug("wrong copy to user\n");					kfree(sii);					return -EFAULT;				}			}			if (copy_to_user(SectionInformation, sii, sizeof(*sii))) {				kdebug("wrong copy to user\n");				kfree(sii);				return -EFAULT;			}			break;		default:			break;	}	objput(sec_obj);	return STATUS_SUCCESS;} /* end NtQuerySection *//* * construct a section access object (allocate its private data) * - called by CreateObject if the section does not already exists * - called with data pointing to section_args arguments *   - hFile replaced with file struct win32_object pointer (or NULL) */static int SectionConstructor(struct win32_object *obj, void *data){	int		tmp, err;	struct win32_section	*ws;	struct section_args	*args = (struct section_args *)data;	ktrace("SectionConstructor(%p)\n", obj);	/* construct the section information record */	ws = (struct win32_section *)kmalloc(sizeof(struct win32_section), GFP_KERNEL);	if (!ws)		return -ENOMEM;	memset(ws, 0, sizeof(*ws));	obj->o_private = ws;	ws->ws_obj = obj;	/* attach the file */	ws->ws_fileobj = args->FileObject;	if (ws->ws_fileobj) {		ws->ws_wfile = ws->ws_fileobj->o_private;		objget(ws->ws_fileobj);	}	/* TODO: 64bit size is not support */	err = -EINVAL;	if (args->MaximumSize && args->MaximumSize->u.HighPart)		goto failed;	ws->ws_len = args->MaximumSize ? args->MaximumSize->u.LowPart : 0;	/* TODO: PE IMAGE section is not support */	ws->ws_alloctype = args->AllocationAttributes;	if (args->AllocationAttributes & _SEC_IMAGE) {		if (!args->FileObject || image_section_setup(ws) < 0)			goto failed;	}	else {		/* translate the protection flags to syscall mmap() prot */		tmp = ffs(args->SectionPageProtection & 0x000000ff);		if (tmp == 0 || tmp == 1)			goto failed;		ws->ws_protect = prot2linux[tmp - 1];		/* anonymous map, map len is need */		if (!args->FileObject && !ws->ws_len)			goto failed;		if (args->SectionPageProtection & _PAGE_WRITECOPY				|| args->SectionPageProtection & _PAGE_EXECUTE_WRITECOPY)			/* copy on write */			ws->ws_flags |= MAP_PRIVATE;		else			/* shared map */			ws->ws_flags |= MAP_SHARED;		/* get the file size, when paramter len is 0 */		if (!ws->ws_len && ws->ws_wfile)			ws->ws_len = ws->ws_wfile->wf_file->f_dentry->d_inode->i_size;		ws->ws_pagelen = PAGE_ALIGN(ws->ws_pagelen);		if ((err = data_section_setup(ws)) < 0)			goto failed;	}	return 0;failed:	if (ws->ws_fileobj)		objput(ws->ws_fileobj);	kfree(ws);	return err;} /* end SectionConstructor() *//* * reconstruct a section (allocate its private data) * - called by CreateObject if the section already exists * - for section, no operation is needed */static int SectionReconstructor(struct win32_object *obj, void *data){	return 0;} /* end SectionReconstructor() *//* * destroy a section (discard its private data) */static void SectionDestructor(struct win32_object *obj){	struct win32_section	*ws = obj->o_private;	ktrace("SectionDestructor(%p)\n",obj);	/* discard the association with the file object */	if (ws->ws_fileobj)		objput(ws->ws_fileobj);	if (ws->ws_sections)		kfree(ws->ws_sections);	kfree(obj->o_private);} /* end SectionDestructor() *//* * never used for section */static int SectionPoll(struct wait_table_entry *wte, struct ethread *filp){	return POLL_NOTSIG;} /* end SectionPoll() */#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -