void IODTFreeLoaderInfo( const char *key, void *infoAddr, int infoSize ) { vm_offset_t range[2]; IORegistryEntry *chosen; range[0] = (vm_offset_t)infoAddr; range[1] = (vm_offset_t)infoSize; FreePhysicalMemory( range ); if ( key != 0 ) { chosen = IORegistryEntry::fromPath( "/chosen/memory-map", gIODTPlane ); if ( chosen != 0 ) { chosen->removeProperty(key); } } }
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 }