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

📄 w32init.c

📁 linux unified kernel test
💻 C
字号:
/*
 * w32init.c
 *
 * Copyright (C) 2006  Insigme Co., Ltd
 *
 * Authors: 
 * - Decao Mao, Chenzhan Hu, Lixing Chu, Zhiqiang Jiao 
 *
 * 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.
 */
 
 /*
  * w32init.c implements the w32 module initialization and exit.
  * Initialized 0x2E when the module is loaded , and restore it when the 
  * module is unloaded.  
  */

#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
#include "sysmap.h"
asmlinkage int w32system_call(void);
int set_w32system_gate(unsigned int, void *);
int backup_idt_entry(unsigned int n, unsigned long *a, unsigned long *b);
int restore_idt_entry(unsigned int n, unsigned long a, unsigned long b);

int init_syscall_table();
unsigned long orig_idt_2e_a, orig_idt_2e_b;

__attribute__((regparm(3)))
void do_apc(struct pt_regs *regs, sigset_t *oldset,
		      __u32 thread_info_flags)
{
	/* deal with w32 APC, to be implemented */
}

static int w32_init(void)
{
	if(init_syscall_table() != 0)
	{
		printk("Module not loaded.system call table initialize faild!\n");
		return -1;
	}
	
	/* store the original address that the 0x2E points */ 
	if (backup_idt_entry(0x2E, &orig_idt_2e_a, &orig_idt_2e_b) == -1) {
		printk("Module not loaded. backup_idt_entry error: bad idt entry\n");
		return -1;
	}
	
	/* initialize 0x2E */
	if (set_w32system_gate(0x2E, &w32system_call) == -1) {
		printk("Module not loaded. set_w32system_gate error: bad idt entry\n");
		return -1;
	}
	printk("Module w32 On! vector 0x2E initialized for w32 syscall!\n");
	return 0;
}

static void w32_exit(void)
{
	
	/* restore 0x2E */
	restore_idt_entry(0x2E, orig_idt_2e_a, orig_idt_2e_b);
	printk("Module w32 Off!\n");
}
int backup_idt_entry(unsigned int n, unsigned long *a, unsigned long *b)
{
	unsigned long	*gate_addr;
	struct desc_struct *idt_table;
	char szidt[8];

	asm("sidt %0"::"m"(*szidt));
	idt_table = *(struct desc_struct**)(szidt+2);

	/* 0x20 ~ 0x2f could be backup */
	if ((n & 0xfffffff0) != 0x20)
		return -1;
	gate_addr = (unsigned long *)(idt_table + n);
	*a = *gate_addr;
	*b = *(gate_addr + 1);

	return 0;
}
int restore_idt_entry(unsigned int n, unsigned long a, unsigned long b)
{
	unsigned long	*gate_addr;
	struct desc_struct *idt_table;
	char szidt[8];

	asm("sidt %0"::"m"(*szidt));
	idt_table = *(struct desc_struct**)(szidt+2);
	/* 0x20 ~ 0x2f could be restore */
	if ((n & 0xfffffff0) != 0x20)
		return -1;
	gate_addr = (unsigned long *)(idt_table + n);
	*gate_addr = a;
	*(gate_addr + 1) = b;
	return 0;
}
static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entry_b)
{
	__u32 *lp = (__u32 *)((char *)dt + entry*8);
	*lp = entry_a;
	*(lp+1) = entry_b;
}
static inline void pack_gate(__u32 *a, __u32 *b,
							 unsigned long base, unsigned short seg, unsigned char type, unsigned char flags)
{
	*a = (seg << 16) | (base & 0xffff);
	*b = (base & 0xffff0000) | ((type & 0xff) << 8) | (flags & 0xff);
}
int set_w32system_gate(unsigned int n, void *addr)
{
	__u32 a, b;
	struct desc_struct *idt_table;
	char szidt[8];

	asm("sidt %0"::"m"(*szidt));
	idt_table = *(struct desc_struct**)(szidt+2);
	/* 0x20 ~ 0x2f could be set */
	if ((n & 0xfffffff0) != 0x20)
		return -1;
	pack_gate(&a, &b, (unsigned long)addr, __KERNEL_CS, 0xef, 0);
	write_dt_entry(idt_table,n,a,b);
	asm("lidt %0"::"m"(*szidt));
	return 0;
}
typedef int (*PDO_SYSCALL_TRACE)(struct pt_regs *regs, int entryexit);
typedef void (*PDO_NOTIFY_RESUME)(struct pt_regs *regs, void *_unused,__u32 thread_info_flags);
typedef struct pt_regs * fastcall (*PSAVE_V86_STATE)(struct kernel_vm86_regs * regs);
typedef struct _KERNEL_CALL_TABLE
{
	PDO_SYSCALL_TRACE pdo_syscall_trce;/*1*/
	PDO_NOTIFY_RESUME pdo_notify_resume;/*2*/
	PSAVE_V86_STATE psave_v86_state;/*3*/
}KERNEL_CALL_TABLE,*PKERNEL_CALL_TABLE;
KERNEL_CALL_TABLE kct;
int init_syscall_table()
{
	int i;
	unsigned long *p;
	/*load system map file */
	if(load_system_map() != 0)
	{
		printk("Module not loaded.system map load faild!\n");
		return -1;
	}
	memset(&kct,0,sizeof(KERNEL_CALL_TABLE));
	kct.pdo_syscall_trce = (PDO_SYSCALL_TRACE)get_addr_from_map("do_syscall_trace");
	kct.pdo_notify_resume = (PDO_NOTIFY_RESUME)get_addr_from_map("do_notify_resume");
	kct.psave_v86_state = (PSAVE_V86_STATE)get_addr_from_map("save_v86_state");

	unload_system_map();
	/*check the table*/
	p = (long *)&kct;
	for (i = 0; i < 3 ; i++)
	{
		if(p[i] == 0)
			return -1;
	}

	return 0;
}
int do_syscall_trace(struct pt_regs *regs, int entryexit)
{
	asm("jmp %0"::"r"(kct.pdo_syscall_trce));
	return 0;
}
void do_notify_resume(struct pt_regs *regs, void *_unused,
					  __u32 thread_info_flags)
{
	asm("jmp %0"::"r"(kct.pdo_notify_resume));
	return;
}
struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs)
{	
	asm("jmp %0"::"r"(kct.psave_v86_state));
	return 0;
}
// fastcall void setup_x86_bogus_stack(unsigned char * stk)
// {
// 	unsigned long *switch16_ptr, *switch32_ptr;
// 	struct pt_regs *regs;
// 	unsigned long stack_top, stack_bot;
// 	unsigned short iret_frame16_off;
// 	int cpu = smp_processor_id();
// 	/* reserve the space on 32bit stack for the magic switch16 pointer */
// 	memmove(stk, stk + 8, sizeof(struct pt_regs));
// 	switch16_ptr = (unsigned long *)(stk + sizeof(struct pt_regs));
// 	regs = (struct pt_regs *)stk;
// 	/* now the switch32 on 16bit stack */
// 	stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu);
// 	stack_top = stack_bot +	CPU_16BIT_STACK_SIZE;
// 	switch32_ptr = (unsigned long *)(stack_top - 8);
// 	iret_frame16_off = CPU_16BIT_STACK_SIZE - 8 - 20;
// 	/* copy iret frame on 16bit stack */
// 	memcpy((void *)(stack_bot + iret_frame16_off), &regs->eip, 20);
// 	/* fill in the switch pointers */
// 	switch16_ptr[0] = (regs->esp & 0xffff0000) | iret_frame16_off;
// 	switch16_ptr[1] = __ESPFIX_SS;
// 	switch32_ptr[0] = (unsigned long)stk + sizeof(struct pt_regs) +
// 		8 - CPU_16BIT_STACK_SIZE;
// 	switch32_ptr[1] = __KERNEL_DS;
// }

module_init(w32_init);
module_exit(w32_exit);
MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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