Пример #1
0
void symbol_restore(struct kernsym *sym) {

	bool pte_ro;

	if (sym->hijacked) {

		set_addr_rw((unsigned long) sym->addr, &pte_ro);

		memcpy(sym->addr, &sym->orig_start_bytes[0], OP_JMP_SIZE);

		set_addr_ro((unsigned long) sym->addr, pte_ro);

		sym->hijacked = false;

		malloc_free(sym->new_addr);

	}

	if (sym->name_alloc) {
		malloc_free(sym->name);
		sym->name_alloc = false;
	}

	return;
}
Пример #2
0
void __exit exit_hooking(void)
{
    sys_call_table[__NR_regdev] = original_call;
    set_addr_ro((unsigned long)sys_call_table);

    unregister_chrdev(Major, DEVICE_NAME);

    return;
}
Пример #3
0
static void proc_init(void)
{
	uptime_proc_file = create_proc_entry(MODULE_NAME, 0, NULL);
	if (uptime_proc_file == NULL)
	{
#ifdef DEBUG
		printk(KERN_ALERT "%s error: could not create temporary /proc entry\n",
				MODULE_NAME);
#endif
		proc_failed = 1;
		return;
	}
	proc_root = uptime_proc_file->parent;
	if (proc_root == NULL || strcmp(proc_root->name, "/proc") != 0)
	{
#ifdef DEBUG
		printk(KERN_ALERT "%s error: could not identify /proc root entry\n",
				MODULE_NAME);
#endif
		proc_failed = 1;
		return;
	}
	proc_root_fops = (struct file_operations *)proc_root->proc_fops;
	remove_proc_entry("temp_hack", NULL);

	uptime_proc_file = proc_root->subdir;
	while (uptime_proc_file) {
		if (strcmp(uptime_proc_file->name, PROCFS_NAME) == 0)
			goto found;
		uptime_proc_file = uptime_proc_file->next;
	}
	proc_failed = 1;
#ifdef DEBUG
	printk(KERN_ALERT "%s did not found /proc/%s file", MODULE_NAME,
			PROCFS_NAME);
#endif
	return;

found:
	uptime_proc_fops = (struct file_operations *)uptime_proc_file->proc_fops;
	old_uptime_proc_open = uptime_proc_fops->open;

	if (uptime_proc_fops != NULL)
	{
		set_addr_rw(uptime_proc_fops);
		uptime_proc_fops->open = uptime_proc_open;
		set_addr_ro(uptime_proc_fops);

#ifdef DEBUG
		printk(KERN_INFO "%s: successfully wrapped /proc/%s\n",
				MODULE_NAME, PROCFS_NAME);
#endif
	}
}
Пример #4
0
static void proc_cleanup(void)
{
	if (!proc_failed && (uptime_proc_fops != NULL))
	{
		set_addr_rw(uptime_proc_fops);
		uptime_proc_fops->open = old_uptime_proc_open;
		set_addr_ro(uptime_proc_fops);

#ifdef DEBUG
		printk(KERN_INFO "%s: successfully unwrapped /proc/%s\n",
				MODULE_NAME, PROCFS_NAME);
#endif
	}
#ifdef DEBUG
	else
		printk(KERN_INFO "%s: nothing to unwrap, exiting\n", MODULE_NAME);
#endif
}
Пример #5
0
int symbol_hijack(struct kernsym *sym, const char *symbol_name, unsigned long *code) {

	int ret;
	unsigned long orig_addr;
	unsigned long dest_addr;
	unsigned long end_addr;
	u32 *poffset;
	struct insn insn;
	bool pte_ro;
	
	ret = find_symbol_address(sym, symbol_name);

	if (IN_ERR(ret))
		return ret;

	if (*(u8 *)sym->addr == OP_JMP_REL32) {
		printk(PKPRE "error: %s already appears to be hijacked\n", symbol_name);
		return -EFAULT;
	}

	sym->new_addr = malloc(sym->size);

	if (sym->new_addr == NULL) {
		printk(PKPRE
			"Failed to allocate buffer of size %lu for %s\n",
			sym->size, sym->name);
		return -ENOMEM;
	}

	memset(sym->new_addr, 0, (size_t)sym->size);

	if (sym->size < OP_JMP_SIZE) {
		ret = -EFAULT;
		goto out_error;
	}
	
	orig_addr = (unsigned long)sym->addr;
	dest_addr = (unsigned long)sym->new_addr;
	
	end_addr = orig_addr + sym->size;
	while (end_addr > orig_addr && *(u8 *)(end_addr - 1) == '\0')
		--end_addr;
	
	if (orig_addr == end_addr) {
		printk(PKPRE
			"A spurious symbol \"%s\" (address: %p) seems to contain only zeros\n",
			sym->name,
			sym->addr);
		ret = -EILSEQ;
		goto out_error;
	}
	
	while (orig_addr < end_addr) {
		tpe_insn_init(&insn, (void *)orig_addr);
		tpe_insn_get_length(&insn);
		if (insn.length == 0) {
			printk(PKPRE
				"Failed to decode instruction at %p (%s+0x%lx)\n",
				(const void *)orig_addr,
				sym->name,
				orig_addr - (unsigned long)sym->addr);
			ret = -EILSEQ;
			goto out_error;
		}
		
		copy_and_fixup_insn(&insn, (void *)dest_addr, sym);
		
		orig_addr += insn.length;
		dest_addr += insn.length;
	}
	
	sym->new_size = dest_addr - (unsigned long)sym->new_addr;

	sym->run = sym->new_addr;

	set_addr_rw((unsigned long) sym->addr, &pte_ro);

	memcpy(&sym->orig_start_bytes[0], sym->addr, OP_JMP_SIZE);

	*(u8 *)sym->addr = OP_JMP_REL32;
	poffset = (u32 *)((unsigned long)sym->addr + 1);
	*poffset = CODE_OFFSET_FROM_ADDR((unsigned long)sym->addr, 
		OP_JMP_SIZE, (unsigned long)code);

	set_addr_ro((unsigned long) sym->addr, pte_ro);

	sym->hijacked = true;

	return 0;

out_error:
	malloc_free(sym->new_addr);

	return ret;
}