format PE DLL native 4.0 at 10000h
entry DriverEntry
include 'win32.inc'
IOPM_SIZE = 2000h ; sizeof I/O permission map
;====================================================================
section '.text' code readable executable notpageable
proc DriverEntry lpDriverObject, lpusRegistryPath
local status:NTSTATUS
local oa:OBJECT_ATTRIBUTES
local hKey:HANDLE
local kvpi:KEY_VALUE_PARTIAL_INFORMATION
local pIopm:PVOID
local pProcess:PVOID
invoke DbgPrint, szMsg0
mov [status], STATUS_DEVICE_CONFIGURATION_ERROR
xor eax, eax
mov [oa.Length], sizeof.OBJECT_ATTRIBUTES
mov [oa.RootDirectory], eax ; NULL
push [lpusRegistryPath]
pop [oa.ObjectName]
mov [oa.Attributes], eax ; 0
mov [oa.SecurityDescriptor], eax ; NULL
mov [oa.SecurityQualityOfService], eax ; NULL
lea ecx, [oa]
lea eax, [hKey]
invoke ZwOpenKey, eax, KEY_READ, ecx
.if eax = STATUS_SUCCESS
push eax
lea eax, [kvpi]
invoke ZwQueryValueKey, [hKey], us, KeyValuePartialInformation,eax,sizeof.KEY_VALUE_PARTIAL_INFORMATION, esp
pop ecx
.if (eax <> STATUS_OBJECT_NAME_NOT_FOUND) & (ecx <> 0)
invoke DbgPrint, szMsg1, dword [kvpi+KEY_VALUE_PARTIAL_INFORMATION.Data]
; Allocate a buffer for the IOPM (I/O permission map).
; Holds 8K * 8 bits -> 64K bits of the IOPM, which maps the
; entire 64K I/O space of the x86 processor.
; Any 0 bits will give access to the corresponding port for user mode processes.
; Any 1 bits will disallow I/O access to the corresponding port.
invoke MmAllocateNonCachedMemory, IOPM_SIZE
.if eax <> NULL
mov [pIopm], eax
lea ecx,[kvpi]
lea eax,[pProcess]
invoke PsLookupProcessByProcessId, dword [ecx+KEY_VALUE_PARTIAL_INFORMATION.Data],eax
.if eax = STATUS_SUCCESS
invoke DbgPrint, szMsg2, [pProcess]
invoke Ke386QueryIoAccessMap, 0, [pIopm]
.if al <> 0
; We need only 70h & 71h I/O port access.
; So, we clear corresponding bits in IOPM.
; I/O access for 70h port
mov ecx, [pIopm]
add ecx, 70h / 8
mov eax, [ecx]
btr eax, 70h mod 8
mov [ecx], eax
; I/O access for 71h port
mov ecx, [pIopm]
add ecx, 71h / 8
mov eax, [ecx]
btr eax, 71h mod 8
mov [ecx], eax
; Set modified IOPM
invoke Ke386SetIoAccessMap, 1, [pIopm]
.if al <> 0
; If second parameter to Ke386IoSetAccessProcess is 1, the process is given I/O access.
; If it is 0, access is removed.
invoke Ke386IoSetAccessProcess, [pProcess], 1
.if al <> 0
invoke DbgPrint, szMsg3
.else
invoke DbgPrint, szMsg4
mov [status], STATUS_IO_PRIVILEGE_FAILED
.endif
.else
mov [status], STATUS_IO_PRIVILEGE_FAILED
.endif
.else
mov [status], STATUS_IO_PRIVILEGE_FAILED
.endif
invoke ObDereferenceObject, [pProcess]
.else
mov [status], STATUS_OBJECT_TYPE_MISMATCH
.endif
invoke MmFreeNonCachedMemory, [pIopm], IOPM_SIZE
.else
invoke DbgPrint, szMsg5
mov [status], STATUS_INSUFFICIENT_RESOURCES
.endif
.endif
invoke ZwClose, [hKey]
.endif
invoke DbgPrint, szMsg6
mov eax, [status]
ret
endp
;====================================================================
section '.data' data readable writeable notpageable
align 4
usz du 'ProcessId',0
align 4
us UNICODE_STRING 9*2,10*2,usz
szMsg0 db 'giveio: Entering DriverEntry',0
szMsg1 db 'giveio: Process ID: %d',0
szMsg2 db 'giveio: PTR KPROCESS: %08X',0
szMsg3 db 'giveio: I/O permission is successfully given',0
szMsg4 db 'giveio: I/O permission is failed',0
szMsg5 db 'giveio: Call to MmAllocateNonCachedMemory failed',0
szMsg6 db 'giveio: Leaving DriverEntry',0
;====================================================================
section 'INIT' import code discardable executable readable writeable
library ntoskrnl,'ntoskrnl.exe'
include 'api/ntoskrnl.inc'
;====================================================================
section '.reloc' fixups data readable discardable