Esempio n. 1
0
// Perform IO instruction according with parameters
_Use_decl_annotations_ static void VmmpIoWrapper(bool to_memory, bool is_string,
                                                 SIZE_T size_of_access,
                                                 unsigned short port,
                                                 void *address,
                                                 unsigned long count) {
  NT_ASSERT(size_of_access == 1 || size_of_access == 2 || size_of_access == 4);

  // Update CR3 with that of the guest since below code is going to access
  // memory.
  const auto guest_cr3 = UtilVmRead(VmcsField::kGuestCr3);
  const auto vmm_cr3 = __readcr3();
  __writecr3(guest_cr3);

  // clang-format off
  if (to_memory) {
    if (is_string) {
      // IN
      switch (size_of_access) {
      case 1: *reinterpret_cast<UCHAR*>(address) = __inbyte(port); break;
      case 2: *reinterpret_cast<USHORT*>(address) = __inword(port); break;
      case 4: *reinterpret_cast<ULONG*>(address) = __indword(port); break;
      }
    } else {
      // INS
      switch (size_of_access) {
      case 1: __inbytestring(port, reinterpret_cast<UCHAR*>(address), count); break;
      case 2: __inwordstring(port, reinterpret_cast<USHORT*>(address), count); break;
      case 4: __indwordstring(port, reinterpret_cast<ULONG*>(address), count); break;
      }
    }
  } else {
    if (is_string) {
      // OUT
      switch (size_of_access) {
      case 1: __outbyte(port, *reinterpret_cast<UCHAR*>(address)); break;
      case 2: __outword(port, *reinterpret_cast<USHORT*>(address)); break;
      case 4: __outdword(port, *reinterpret_cast<ULONG*>(address)); break;
      }
    } else {
      // OUTS
      switch (size_of_access) {
      case 1: __outbytestring(port, reinterpret_cast<UCHAR*>(address), count); break;
      case 2: __outwordstring(port, reinterpret_cast<USHORT*>(address), count); break;
      case 4: __outdwordstring(port, reinterpret_cast<ULONG*>(address), count); break;
      }
    }
  }
  // clang-format on

  __writecr3(vmm_cr3);
}
Esempio n. 2
0
NTSTATUS __fastcall DispatchIOCTL(IN PIOCTL_INFO RequestInfo, OUT PULONG ResponseLength) {
	NTSTATUS Status = STATUS_SUCCESS;

#define INPUT(Type)  ((Type)(RequestInfo->InputBuffer)) 
#define OUTPUT(Type) ((Type)(RequestInfo->OutputBuffer))
#define SET_RESPONSE_LENGTH(Length) if (ResponseLength != NULL) {*ResponseLength = (Length);}

	switch (RequestInfo->ControlCode) {
	
// DriverFunctions:

	case GET_HANDLES_COUNT:
		*OUTPUT(PULONG) = GetHandlesCount();
		SET_RESPONSE_LENGTH(sizeof(ULONG));
		break;

// NativeFunctions:

	case START_BEEPER:
		__outbyte(0x61, __inbyte(0x61) | 3); 
		break;
	
	case STOP_BEEPER: 
		__outbyte(0x61, __inbyte(0x61) & 252);
		break;
	
	case SET_BEEPER_REGIME: 
		__outbyte(0x43, 0xB6);
		break;
	
	case SET_BEEPER_OUT: 
		__outbyte(0x61, __inbyte(0x61) | 2);
		break;
	
	case SET_BEEPER_IN: 
		__outbyte(0x61, __inbyte(0x61) & 253);
		break;

	case SET_BEEPER_DIVIDER:
		SetBeeperDivider(*INPUT(PWORD));
		break;

	case SET_BEEPER_FREQUENCY:
		SetBeeperFrequency(*INPUT(PWORD));
		break;

	case READ_IO_PORT_BYTE:
		*OUTPUT(PBYTE) = __inbyte(*INPUT(PWORD));
		SET_RESPONSE_LENGTH(sizeof(BYTE));
		break;

	case READ_IO_PORT_WORD:
		*OUTPUT(PWORD) = __inword(*INPUT(PWORD));
		SET_RESPONSE_LENGTH(sizeof(WORD));
		break;

	case READ_IO_PORT_DWORD:
		*OUTPUT(PDWORD32) = __indword(*INPUT(PWORD));
		SET_RESPONSE_LENGTH(sizeof(DWORD));
		break;

	case WRITE_IO_PORT_BYTE:
		__outbyte(
			INPUT(PWRITE_IO_PORT_BYTE_INPUT)->PortNumber,
			INPUT(PWRITE_IO_PORT_BYTE_INPUT)->Data
		);
		break;

	case WRITE_IO_PORT_WORD:
		__outword(
			INPUT(PWRITE_IO_PORT_WORD_INPUT)->PortNumber,
			INPUT(PWRITE_IO_PORT_WORD_INPUT)->Data
		);
		break;

	case WRITE_IO_PORT_DWORD:
		__outdword(
			INPUT(PWRITE_IO_PORT_DWORD_INPUT)->PortNumber,
			INPUT(PWRITE_IO_PORT_DWORD_INPUT)->Data
		);
		break;

	case RDPMC:
		*OUTPUT(PULONGLONG) = __readpmc(*INPUT(PULONG));
		SET_RESPONSE_LENGTH(sizeof(ULONGLONG));
		break;

	case RDMSR:
		*OUTPUT(PULONGLONG) = __readmsr(*INPUT(PULONG));
		SET_RESPONSE_LENGTH(sizeof(ULONGLONG));
		break;

	case WRMSR:
		__writemsr(INPUT(PWRMSR_INPUT)->Index, INPUT(PWRMSR_INPUT)->Data);
		break;

// MemoryUtils:

	case ALLOC_KERNEL_MEMORY:
		*OUTPUT(PUINT64) = (SIZE_T)GetMem(*INPUT(PSIZE_T));
		SET_RESPONSE_LENGTH(sizeof(UINT64));
		break;

	case FREE_KERNEL_MEMORY:
		FreeMem((PVOID)*INPUT(PUINT64));
		break;

	case COPY_MEMORY:
		RtlCopyMemory(
			(PVOID)INPUT(PCOPY_MEMORY_INPUT)->Destination,
			(PVOID)INPUT(PCOPY_MEMORY_INPUT)->Source,
			(SIZE_T)INPUT(PCOPY_MEMORY_INPUT)->Size
		);
		break;

	case FILL_MEMORY:
		RtlFillMemory(
			(PVOID)INPUT(PFILL_MEMORY_INPUT)->Destination,
			(SIZE_T)INPUT(PFILL_MEMORY_INPUT)->Size,
			(BYTE)INPUT(PFILL_MEMORY_INPUT)->FillingByte
		);
		break;

	case ALLOC_PHYSICAL_MEMORY:
		*OUTPUT(PUINT64) = (SIZE_T)AllocPhysicalMemory(
			INPUT(PALLOC_PHYSICAL_MEMORY_INPUT)->PhysicalAddress,
			(SIZE_T)INPUT(PALLOC_PHYSICAL_MEMORY_INPUT)->Size
		);
		SET_RESPONSE_LENGTH(sizeof(UINT64));
		break;

	case FREE_PHYSICAL_MEMORY:
		FreePhysicalMemory((PVOID)*INPUT(PUINT64));
		break;

	case GET_PHYSICAL_ADDRESS:
		*OUTPUT(PPHYSICAL_ADDRESS) = GetPhysicalAddressInProcess(
			(HANDLE)INPUT(PGET_PHYSICAL_ADDRESS_INPUT)->ProcessID,
			(PVOID)INPUT(PGET_PHYSICAL_ADDRESS_INPUT)->VirtualAddress
		);
		SET_RESPONSE_LENGTH(sizeof(PHYSICAL_ADDRESS));
		break;

	case READ_PHYSICAL_MEMORY:
		*OUTPUT(PBOOL) = ReadPhysicalMemory(
			INPUT(PREAD_PHYSICAL_MEMORY_INPUT)->PhysicalAddress,
			(PVOID)INPUT(PREAD_PHYSICAL_MEMORY_INPUT)->Buffer,
			INPUT(PREAD_PHYSICAL_MEMORY_INPUT)->BufferSize
		);
		SET_RESPONSE_LENGTH(sizeof(BOOL));
		break;

	case WRITE_PHYSICAL_MEMORY:
		*OUTPUT(PBOOL) = WritePhysicalMemory(
			INPUT(PWRITE_PHYSICAL_MEMORY_INPUT)->PhysicalAddress,
			(PVOID)INPUT(PWRITE_PHYSICAL_MEMORY_INPUT)->Buffer,
			INPUT(PWRITE_PHYSICAL_MEMORY_INPUT)->BufferSize
		);
		SET_RESPONSE_LENGTH(sizeof(BOOL));
		break;

	case READ_DMI_MEMORY:
		ReadDmiMemory((PVOID)*INPUT(PUINT64), DMI_SIZE);
		SET_RESPONSE_LENGTH(DMI_SIZE);
		break;

// ShellCode:

	case EXECUTE_SHELL_CODE:
		*OUTPUT(PSHELL_STATUS) = ExecuteShell(
			(PVOID)INPUT(PEXECUTE_SHELL_CODE_INPUT)->EntryPoint,
			(PVOID)INPUT(PEXECUTE_SHELL_CODE_INPUT)->CodeBlock,
			(PVOID)INPUT(PEXECUTE_SHELL_CODE_INPUT)->InputData,
			(PVOID)INPUT(PEXECUTE_SHELL_CODE_INPUT)->OutputData,
			(PVOID)INPUT(PEXECUTE_SHELL_CODE_INPUT)->Result
		);
		SET_RESPONSE_LENGTH(sizeof(SHELL_STATUS));
		break;

// ProcessesUtils:

	case ALLOC_VIRTUAL_MEMORY:
		OUTPUT(PALLOC_VIRTUAL_MEMORY_OUTPUT)->Status = VirtualAllocInProcess(
			(HANDLE)INPUT(PALLOC_VIRTUAL_MEMORY_INPUT)->ProcessId,
			(SIZE_T)INPUT(PALLOC_VIRTUAL_MEMORY_INPUT)->Size,
			(PVOID*)&OUTPUT(PALLOC_VIRTUAL_MEMORY_OUTPUT)->VirtualAddress
		);
		SET_RESPONSE_LENGTH(sizeof(ALLOC_VIRTUAL_MEMORY_OUTPUT));
		break;

	case FREE_VIRTUAL_MEMORY:
		*OUTPUT(PNTSTATUS) = VirtualFreeInProcess(
			(HANDLE)INPUT(PFREE_VIRTUAL_MEMORY_INPUT)->ProcessId,
			(PVOID)INPUT(PFREE_VIRTUAL_MEMORY_INPUT)->VirtualAddress
		);
		SET_RESPONSE_LENGTH(sizeof(NTSTATUS));
		break;

	case MAP_VIRTUAL_MEMORY:
		OUTPUT(PMAP_VIRTUAL_MEMORY_OUTPUT)->MappedMemory = MapVirtualMemory(
			(HANDLE)INPUT(PMAP_VIRTUAL_MEMORY_INPUT)->ProcessId,
			INPUT(PMAP_VIRTUAL_MEMORY_INPUT)->VirtualAddress,
			INPUT(PMAP_VIRTUAL_MEMORY_INPUT)->MapToVirtualAddress,
			INPUT(PMAP_VIRTUAL_MEMORY_INPUT)->Size,
			UserMode,
			(PMDL*)&(OUTPUT(PMAP_VIRTUAL_MEMORY_OUTPUT)->Mdl)
		);
		SET_RESPONSE_LENGTH(sizeof(MAP_VIRTUAL_MEMORY_OUTPUT));
		break;

	case UNMAP_VIRTUAL_MEMORY:
		UnmapVirtualMemory(
			INPUT(PUNMAP_VIRTUAL_MEMORY_INPUT)->Mdl,
			INPUT(PUNMAP_VIRTUAL_MEMORY_INPUT)->MappedMemory
		);
		break;

	case READ_PROCESS_MEMORY:
		*OUTPUT(PBOOL) = ReadProcessMemory(
			(HANDLE)INPUT(PREAD_PROCESS_MEMORY_INPUT)->ProcessId,
			(PVOID)INPUT(PREAD_PROCESS_MEMORY_INPUT)->VirtualAddress,
			(PVOID)INPUT(PREAD_PROCESS_MEMORY_INPUT)->Buffer,
			INPUT(PREAD_PROCESS_MEMORY_INPUT)->BytesToRead,
			TRUE,
			(MEMORY_ACCESS_TYPE)INPUT(PREAD_PROCESS_MEMORY_INPUT)->AccessType
		);
		SET_RESPONSE_LENGTH(sizeof(BOOL));
		break;

	case WRITE_PROCESS_MEMORY:
		*OUTPUT(PBOOL) = WriteProcessMemory(
			(HANDLE)INPUT(PWRITE_PROCESS_MEMORY_INPUT)->ProcessId,
			(PVOID)INPUT(PWRITE_PROCESS_MEMORY_INPUT)->VirtualAddress,
			(PVOID)INPUT(PWRITE_PROCESS_MEMORY_INPUT)->Buffer,
			INPUT(PWRITE_PROCESS_MEMORY_INPUT)->BytesToWrite,
			TRUE,
			(MEMORY_ACCESS_TYPE)INPUT(PWRITE_PROCESS_MEMORY_INPUT)->AccessType
		);
		SET_RESPONSE_LENGTH(sizeof(BOOL));
		break;

	case RAISE_IOPL_BY_TF:
#ifdef _AMD64_
		RaiseIOPLByTrapFrame();
#else
		Status = STATUS_NOT_IMPLEMENTED;
#endif
		break;

	case RESET_IOPL_BY_TF:
#ifdef _AMD64_
		ResetIOPLByTrapFrame();
#else
		Status = STATUS_NOT_IMPLEMENTED;
#endif
		break;

	case RAISE_IOPL_BY_TF_SCAN:
		RaiseIOPLByTrapFrameScan();
		break;

	case RESET_IOPL_BY_TF_SCAN:
		ResetIOPLByTrapFrameScan();
		break;

	case RAISE_IOPL_BY_TSS:
#ifdef _X86_
		RaiseIOPLByTSS();
#else
		Status = STATUS_NOT_IMPLEMENTED;
#endif
		break;

	case RESET_IOPL_BY_TSS:
#ifdef _x86_
		ResetIOPLByTSS();
#else
		Status = STATUS_NOT_IMPLEMENTED;
#endif
		break;

	case RAISE_IOPM:
#ifdef _X86_
		*OUTPUT(PNTSTATUS) = RaiseIOPM((HANDLE)*INPUT(PUINT64));
		SET_RESPONSE_LENGTH(sizeof(NTSTATUS));
#else
		Status = STATUS_NOT_IMPLEMENTED;
#endif
		break;

	case RESET_IOPM:
#ifdef _X86_
		*OUTPUT(PNTSTATUS) = ResetIOPM((HANDLE)*INPUT(PUINT64));
		SET_RESPONSE_LENGTH(sizeof(NTSTATUS));
#else
		Status = STATUS_NOT_IMPLEMENTED;
#endif
		break;

// PCI:

	case READ_PCI_CONFIG:
		OUTPUT(PREAD_PCI_CONFIG_OUTPUT)->Status = ReadPciConfig(
			INPUT(PREAD_PCI_CONFIG_INPUT)->PciAddress,
			INPUT(PREAD_PCI_CONFIG_INPUT)->PciOffset,
			(PVOID)INPUT(PREAD_PCI_CONFIG_INPUT)->Buffer,
			INPUT(PREAD_PCI_CONFIG_INPUT)->BufferSize,
			&OUTPUT(PREAD_PCI_CONFIG_OUTPUT)->BytesRead
		);
		SET_RESPONSE_LENGTH(sizeof(READ_PCI_CONFIG_OUTPUT));
		break;

	case WRITE_PCI_CONFIG:
		OUTPUT(PWRITE_PCI_CONFIG_OUTPUT)->Status = WritePciConfig(
			INPUT(PWRITE_PCI_CONFIG_INPUT)->PciAddress,
			INPUT(PWRITE_PCI_CONFIG_INPUT)->PciOffset,
			(PVOID)INPUT(PWRITE_PCI_CONFIG_INPUT)->Buffer,
			INPUT(PWRITE_PCI_CONFIG_INPUT)->BufferSize,
			&OUTPUT(PWRITE_PCI_CONFIG_OUTPUT)->BytesWritten
		);
		SET_RESPONSE_LENGTH(sizeof(WRITE_PCI_CONFIG_OUTPUT));
		break;

	default: 
		Status = STATUS_NOT_IMPLEMENTED;
		break;
	}

	return Status;

#undef INPUT
#undef OUTPUT

#undef SET_RESPONSE_LENGTH

}
Esempio n. 3
0
File: pci.c Progetto: google/rekall
void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 value) {
  __outdword(PCI_CONFIG_ADDRESS,
	     0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset);
  __outword(PCI_CONFIG_DATA, value);
}