示例#1
0
void schedule(struct cpuRegs_s *regs)
{
	if (allocatedVMs > 0) {
		saveVMState(regs);
		currentVMID++;
		if (currentVMID >= allocatedVMs)
			currentVMID = 0;
		switchToVM(virtualMachines[currentVMID], regs);
	}
}
示例#2
0
/**
 * Inject the given code into the VM.
 *
 * @param inject A pointer to the XTIER_inject structure used for injection.
 *               It contains a pointer to the code and the length of the code.
 */
void XTIER_inject_code(struct kvm_vcpu *vcpu, struct injection *inject)
{
	u64 virt_code = 0;
	u64 virt_stack = 0;
	u64 phys_code = 0;
	u64 phys_stack = 0;
	struct x86_exception error;

	int ret = 0;

	u32 state = 0;

	PRINT_DEBUG("Injecting code...\n");

	// Get Time
	XTIER_inject_begin_time_measurement(&_starttime);

	if(_XTIER_inject.new_module)
	{
		// This is the first injection, reset the timer
		XTIER_inject_init_performance_struct();

		// Reset
		_XTIER_inject.new_module = 0;
	}

	// Reduce auto injection if enabled
	if(inject->auto_inject > 0)
		inject->auto_inject--;

	// Disable hooks to avoid exceptions during injection
	if(inject->event_based)
		XTIER_inject_disable_hook(vcpu);

	// Reset the fault variable
	_XTIER_inject.injection_fault = 0;

	// Save VM state
	saveVMState(vcpu);

	// Get a mapping
	// We currently can only reserve space for a little less than 4MB.
	if(inject->code_len > (512 * 4096))
	{
		/*
		virt_code = XTIER_memory_establish_mapping(vcpu, XTIER_INJECTION_PID, _XTIER_inject.sregs.cr3, 512 * 4096);
		XTIER_memory_establish_mapping(vcpu, XTIER_INJECTION_PID, _XTIER_inject.sregs.cr3, inject->code_len - (512 * 4096));
		*/
		PRINT_ERROR("The module that should be injected is to large!\n");
		return;
	}

	// Code
	virt_code = XTIER_memory_establish_mapping(vcpu, XTIER_INJECTION_PID, _XTIER_inject.sregs.cr3, inject->code_len);

	// Stack
	// Do NOT modify the stack pointer in case of event based injection
	if(!inject->event_based)
	{
		// Reserve space for the args and the stack itself
		virt_stack = XTIER_memory_establish_mapping(vcpu, XTIER_INJECTION_PID, _XTIER_inject.sregs.cr3,
				                      inject->args_size + 4096);

		if (virt_stack)
		{
			// Currently virt_stack points to the end of the stack
			// Fix that
			virt_stack += inject->args_size + 4000; // We leave 96 bytes free

			// Prepare Stack
			switch(_XTIER.os)
			{
				case XTIER_OS_UBUNTU_64:
					prepareStack64(vcpu, inject, &virt_stack);
					break;
				case XTIER_OS_WINDOWS_7_32:
					/* Fall through*/
				case XTIER_OS_UBUNTU_32:
					virt_stack -= 4;

					// Write address of the original kernel stack on the new stack
					phys_stack = vcpu->arch.mmu.gva_to_gpa(vcpu, virt_stack, 0, &error);

					ret = kvm_write_guest(vcpu->kvm, phys_stack, &_XTIER_inject.regs.rsp, 4);
					kvm_register_write(vcpu, VCPU_REGS_RSP, virt_stack);

					if(inject->args_size > 0)
						PRINT_WARNING("Module arguments for 32-bit OSs are currently not supported!\n");

					break;
				default:
					PRINT_ERROR("OS type is unknown! Cannot inject module!\n");
					XTIER_memory_remove_mappings_pid(vcpu, XTIER_INJECTION_PID);
					return;
			}

		}
	}
	else
	{
		// Event based injection

		// Set the stack to the original stack - The SC offset
		virt_stack = _XTIER_inject.regs.rsp - STACK_AREA_SC;

		// Prepare Stack
		switch(_XTIER.os)
		{
			case XTIER_OS_UBUNTU_64:
				// Place the original kernel pointer on the stack
				virt_stack -= 8;

				// Write address of the original kernel stack on the new stack
				phys_stack = vcpu->arch.mmu.gva_to_gpa(vcpu, virt_stack, 0, &error);

				ret = kvm_write_guest(vcpu->kvm, phys_stack, &_XTIER_inject.regs.rsp, 8);
				kvm_register_write(vcpu, VCPU_REGS_RSP, virt_stack);
				break;
			case XTIER_OS_WINDOWS_7_32:
				/* Fall through*/
			case XTIER_OS_UBUNTU_32:
				virt_stack -= 4;

				// Write address of the original kernel stack on the new stack
				phys_stack = vcpu->arch.mmu.gva_to_gpa(vcpu, virt_stack, 0, &error);

				ret = kvm_write_guest(vcpu->kvm, phys_stack, &_XTIER_inject.regs.rsp, 4);
				kvm_register_write(vcpu, VCPU_REGS_RSP, virt_stack);
				break;
			default:
				PRINT_ERROR("OS type is unknown! Cannot inject module!\n");
				XTIER_memory_remove_mappings_pid(vcpu, XTIER_INJECTION_PID);
				return;
		}

		if(inject->args_size > 0)
			PRINT_WARNING("Module arguments are not supported in the case of event-based injection!\n");
	}

	// Verify that the memory was reserved
	if(virt_code == 0 || virt_stack == 0)
	{
		PRINT_ERROR("Could not establish the mappings for code injection. Aborting.\n");
		return;
	}

	// Get Physical address
	phys_code = vcpu->arch.mmu.gva_to_gpa(vcpu, virt_code, 0, &error);

	// Write Data
	ret = kvm_write_guest(vcpu->kvm, phys_code, inject->code, inject->code_len);

	if(ret < 0)
	{
		PRINT_ERROR("An error (code: %d) occurred while writing the binary to memory!\n", ret);

		// Remove Mappings
		XTIER_memory_remove_mappings_pid(vcpu, XTIER_INJECTION_PID);

		// Reenable hook
		if(inject->event_based)
				XTIER_inject_enable_hook(vcpu, inject);

		return;
	}

	// Set params
	_XTIER_inject.event_based = inject->event_based;
	_XTIER_inject.exit_after_injection = inject->exit_after_injection;

	// Increase injections
	_XTIER_performance.injections++;

	PRINT_INFO("Running shellcode @ 0x%llx (ESP: 0x%llx, KERNEL ESP: 0x%llx, SEIP: 0x%llx, CR3: 0x%llx)\n",
				virt_code, virt_stack, _XTIER_inject.regs.rsp, _XTIER_inject.regs.rip, _XTIER_inject.sregs.cr3);

	// Set Mode
	_XTIER.mode |= XTIER_CODE_INJECTION;

	// Set HALT Exiting
	XTIER_enable_hlt_exiting();

	// Set Exception Exiting
	XTIER_enable_interrupt_exiting(vcpu);

	// Set EIP
	kvm_rip_write(vcpu, virt_code);

	// Flush TLB
	//kvm_x86_ops->tlb_flush(vcpu);

	// Get Time
	XTIER_inject_end_time_measurement(&_starttime, &_XTIER_performance.total_module_load_time);

	// Take Time for execution just before we enter the VM
	XTIER_take_time_on_entry(&_starttime);

	// Make sure the VM is not halted
	XTIER_read_vmcs(GUEST_ACTIVITY_STATE, &state);
	if(state == GUEST_ACTIVITY_HLT)
		XTIER_write_vmcs(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE);
}