한 걸음씩..

IOPM(I/O Permission Bitmap) 구현 본문

프로그래밍

IOPM(I/O Permission Bitmap) 구현

smdy0426 2013. 7. 15. 10:58
반응형

1. 공통사항 ( IOCTL 정의 Drv / App 추가 )

#define IOCTL_TEST_PORT_ALLOW_ACCESS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0800, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_TEST_PORT_ACCESS_DENIED CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0801, METHOD_BUFFERED, FILE_ANY_ACCESS)


2. Driver 에서..

// IOPM 구조 정의

#define IOPM_SIZE 0x2000

typedef UCHAR IOPM[IOPM_SIZE];

IOPM *IOPM_local = 0;


//Undocument API 함수 원형 정의

void Ke386SetIoAccessMap(int, IOPM *);

void Ke386QueryIoAccessMap(int, IOPM *);

void Ke386IoSetAccessProcess(PEPROCESS, int);


NTSTATUS DriverEntry( PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath )

{

//.....중략

pDriverObject->MajorFunction[IRP_MJ_CREATE] = PCIDrv_CreateClose;

pDriverObject->MajorFunction[IRP_MJ_CLOSE] = PCIDrv_CreateClose;

pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PCIDrv_DeviceIO;

return STATUS_SUCCESS;

}


NTSTATUS PCIDrv_CreateClose( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp )
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pStack = NULL;
PPCI_DEVICE_EXTENSION pDeviceExtension = NULL;

if( (pFunctionDeviceObject == NULL) || (pIrp == NULL) )
return STATUS_UNSUCCESSFUL;

pStack = IoGetCurrentIrpStackLocation( pIrp );
if( pStack == NULL )
{
ntStatus = STATUS_UNSUCCESSFUL;
        pIrp->IoStatus.Status = ntStatus;
        pIrp->IoStatus.Information = 0;
        IoCompleteRequest( pIrp, IO_NO_INCREMENT );
        return ntStatus;
}

pDeviceExtension = (PPCI_DEVICE_EXTENSION) pDeviceObject->DeviceExtension;
if ( pDeviceExtension == NULL )
{
ntStatus = STATUS_UNSUCCESSFUL;
        pIrp->IoStatus.Status = ntStatus;
        pIrp->IoStatus.Information = 0;
        IoCompleteRequest( pIrp, IO_NO_INCREMENT );
        return ntStatus;
}

switch( pStack -> MajorFunction )
{
case IRP_MJ_CREATE:
{
                         // CreateFile은 한번만 허용한다
IoSetDeviceInterfaceState( &pDeviceExtension->Symbol, FALSE );

IOPM_local = MmAllocateNonCachedMemory(sizeof(IOPM));
if(IOPM_local == 0)
return STATUS_INSUFFICIENT_RESOURCES;

RtlZeroMemory(IOPM_local, sizeof(IOPM));
    break;
}
case IRP_MJ_CLOSE:
{
                         // CreateFile은 한번만 허용한다
IoSetDeviceInterfaceState( &pDeviceExtension->Symbol, TRUE);

Ke386IoSetAccessProcess(PsGetCurrentProcess(), 0);
if(IOPM_local)
MmFreeNonCachedMemory(IOPM_local, sizeof(IOPM));

    break;
}
}

pIrp->IoStatus.Status = ntStatus;
pIrp->IoStatus.Information = 0;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return ntStatus;
}

NTSTATUS PCIDrv_DeviceIO( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp )

{

NTSTATUS ntStatus = STATUS_SUCCESS;

PIO_STACK_LOCATION pStack = NULL;

        PPCI_DEVICE_EXTENSION pDeviceExtension  = NULL;


if( (pDeviceObject == NULL) || (pIrp == NULL) )

return STATUS_UNSUCCESSFUL;


pStack = IoGetCurrentIrpStackLocation( pIrp );

if( pStack == NULL )

{

ntStatus = STATUS_UNSUCCESSFUL;

    pIrp->IoStatus.Status = ntStatus; 

    IoCompleteRequest( pIrp, IO_NO_INCREMENT ); 

    return ntStatus;

}


pDeviceExtension = (PPCI_DEVICE_EXTENSION)pDeviceObject->DeviceExtension;

if( pDeviceExtension == NULL )

{

ntStatus = STATUS_UNSUCCESSFUL;

    pIrp->IoStatus.Status = ntStatus; 

    IoCompleteRequest( pIrp, IO_NO_INCREMENT ); 

                return ntStatus;

}


IoctlCode = pStack->Parameters.DeviceIoControl.IoControlCode;

switch( IoctlCode )

{

case IOCTL_TEST_PORT_ALLOW_ACCESS:

{

Ke386IoSetAccessProcess(PsGetCurrentProcess(), 1);

Ke386SetIoAccessMap(1, IOPM_local);

pIrp->IoStatus.Information = 0;

ntStatus = STATUS_SUCCESS;

break;

}

case IOCTL_HAJE_TEST_PORT_ACCESS_DENIED:

{

Ke386IoSetAccessProcess( PsGetCurrentProcess(), 0 );

      pIrp->IoStatus.Information = 0;

      ntStatus = STATUS_SUCCESS;

      break;

}

default:

{

ntStatus = STATUS_UNSUCCESSFUL;

break;

}

}

pIrp->IoStatus.Status = ntStatus;

IoCompleteRequest( pIrp, IO_NO_INCREMENT );

return ntStatus;

}




3. App에서는 별다른거 없으므로 패쓰.. 



반응형