⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 callgate.c

📁 这是一本学习 window编程的很好的参考教材
💻 C
字号:
#include "callgate.h"
NTSTATUS DriverDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
void DriverUnload(IN PDRIVER_OBJECT DriverObject);
NTSYSAPI 
NTSTATUS 
NTAPI 
KeI386AllocateGdtSelectors(
	PUSHORT pSelectorArray, 
	ULONG NumberOfSelectors
);

NTSYSAPI 
NTSTATUS 
NTAPI 
KeI386ReleaseGdtSelectors(
	PUSHORT pSelectorArray, 
	ULONG NumberOfSelectors
);

NTSYSAPI 
NTSTATUS 
NTAPI 
KeI386SetGdtSelector(
	ULONG Selector, 
	PVOID pDescriptor
);

WCHAR                  deviceNameBuffer[]  = L"\\Device\\callgate"; 
WCHAR                  deviceLinkBuffer[]  = L"\\DosDevices\\callgate"; 
/* This function creates a callgate on request from the application and 
returns the callgate to the application, which the application can use
to run privileged instructions from user level application */
NTSTATUS CreateCallGate(PCallGateInfo_t CallGateInfo)
{
    static CALLGATE_DESCRIPTOR callgate_desc;
    static CODE_SEG_DESCRIPTOR ring0_desc;
    unsigned short SelectorArray[2];
    NTSTATUS rc;
    #define LOWORD(l)           ((unsigned short)(unsigned int)(l))
    #define HIWORD(l)           ((unsigned short)((((unsigned int)(l)) >> 16) & 0xFFFF))

    rc=KeI386AllocateGdtSelectors(SelectorArray, 0x02);
    if (rc!=STATUS_SUCCESS) {
        MYTRACE("Unable to allocate selectors from GDT\n");
        return rc;
    }

    MYTRACE("Selectors allocated = %x %x\n", SelectorArray[0], SelectorArray[1]);
    
    /* Fill the descriptor according to the requirements of the code descriptor */
    ring0_desc.limit_0_15 = 0xFFFF;
    ring0_desc.base_0_15 = 0;
    ring0_desc.base_16_23 = 0;
    ring0_desc.readable = 1;
    ring0_desc.conforming = 0;
    ring0_desc.code_data = 1;
    ring0_desc.app_system = 1;
    ring0_desc.dpl = 0;
    ring0_desc.present = 1;
    ring0_desc.limit_16_19 = 0xF;
    ring0_desc.always_0 = 0;
    ring0_desc.seg_16_32 = 1;
    ring0_desc.granularity = 1;
    ring0_desc.base_24_31 = 0;

    /* Fill the descriptor according to the requirements of the call gate descriptor */
    callgate_desc.offset_0_15 = LOWORD( CallGateInfo->FunctionLinearAddress );
    callgate_desc.selector = SelectorArray[0];
    callgate_desc.param_count = CallGateInfo->NumberOfParameters;
    callgate_desc.some_bits = 0;
    callgate_desc.type = 0xC;          // 386 call gate
    callgate_desc.app_system = 0;      // A system descriptor
    callgate_desc.dpl = 3;             // Ring 3 code can call
    callgate_desc.present = 1;
    callgate_desc.offset_16_31 = HIWORD(CallGateInfo->FunctionLinearAddress);

    /* Return to the caller application the selectors allocated, caller
    is only interested in CallGateSelector */
    CallGateInfo->CodeSelector=SelectorArray[0];
    CallGateInfo->CallGateSelector=SelectorArray[1];

    /* Set the descriptor entry for code selector */
    rc=KeI386SetGdtSelector(SelectorArray[0], &ring0_desc);
    if (rc!=STATUS_SUCCESS) {
        MYTRACE("SetGdtSelector=%x\n", rc);
        KeI386ReleaseGdtSelectors(SelectorArray, 0x02);        
        return rc;
    }

    /* Set the descriptor entry for call gate selector */
    rc=KeI386SetGdtSelector(SelectorArray[1], &callgate_desc);
    if (rc!=STATUS_SUCCESS) {
        MYTRACE("SetGdtSelector=%x\n", rc);
        KeI386ReleaseGdtSelectors(SelectorArray, 0x02);        
        return rc;
    }

    /* Return success */
    return STATUS_SUCCESS;
}

/* This function releases the previously allocated callgate */
NTSTATUS ReleaseCallGate(PCallGateInfo_t CallGateInfo)
{
        unsigned short SelectorArray[2];
        int rc;

        SelectorArray[0]=CallGateInfo->CodeSelector;
        SelectorArray[1]=CallGateInfo->CallGateSelector;

        rc=KeI386ReleaseGdtSelectors(SelectorArray, 0x02);
        if (rc!=STATUS_SUCCESS) {
                MYTRACE("ReleaseGDTSelectors failed, rc=%x\n", rc);
        }
        return rc;
}

NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
	PDEVICE_OBJECT         deviceObject        = NULL;
	NTSTATUS               ntStatus; 
	UNICODE_STRING         deviceNameUnicodeString;
	UNICODE_STRING         deviceLinkUnicodeString;
	RtlInitUnicodeString (&deviceNameUnicodeString, deviceNameBuffer); 
	ntStatus = IoCreateDevice (DriverObject, 
			   0, 
			   &deviceNameUnicodeString, 
			   FILE_DEVICE_CALLGATE, 
			   0,
			   FALSE, 
			   &deviceObject
			   ); 

	if (NT_SUCCESS(ntStatus)) { 
		 MYTRACE("创建设备成功\n");
		 RtlInitUnicodeString (&deviceLinkUnicodeString, deviceLinkBuffer);
		 ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString, 
				    &deviceNameUnicodeString);
		 if (!NT_SUCCESS(ntStatus)) {
					MYTRACE("创建符号失败\n");
					IoDeleteDevice (deviceObject); 
					IoDeleteSymbolicLink(&deviceLinkUnicodeString); 
					 return ntStatus; 
		 } 
		 	MYTRACE("初始化成功\n");
		 DriverObject->MajorFunction[IRP_MJ_CREATE]         = DriverDispatch; 
		 DriverObject->MajorFunction[IRP_MJ_CLOSE]          = DriverDispatch; 
		 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDispatch; 
		 DriverObject->DriverUnload                         = DriverUnload; 
		 return STATUS_SUCCESS; 
	}
	else{
		MYTRACE("创建设备失败\n");
		IoDeleteSymbolicLink(&deviceLinkUnicodeString); 


	}

    return ntStatus;
}


NTSTATUS
DriverDispatch(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
{
    PIO_STACK_LOCATION  irpStack;
    PVOID               ioBuffer;
    ULONG               inputBufferLength;
    ULONG               outputBufferLength;
    ULONG               ioControlCode;
    NTSTATUS            ntStatus;

    Irp->IoStatus.Status      = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    irpStack = IoGetCurrentIrpStackLocation (Irp);

    ioBuffer           = Irp->AssociatedIrp.SystemBuffer;
    inputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;

    switch (irpStack->MajorFunction)
    {
    case IRP_MJ_DEVICE_CONTROL:
        MYTRACE("CALLGATE.SYS: IRP_MJ_DEVICE_CONTROL\n");
        ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

        switch (ioControlCode)
        {
        case IOCTL_CALLGATE_CREATE:
        {
            PCallGateInfo_t CallGateInfo;

            CallGateInfo=(PCallGateInfo_t)ioBuffer;
            Irp->IoStatus.Status=CreateCallGate(CallGateInfo);
            MYTRACE("CreateCallGate rc=%x\n", Irp->IoStatus.Status);
            if (Irp->IoStatus.Status==STATUS_SUCCESS) {
                Irp->IoStatus.Information = sizeof(CallGateInfo_t);
            }
            break;
        }
        case IOCTL_CALLGATE_RELEASE:
        {
            PCallGateInfo_t CallGateInfo;

            CallGateInfo=(PCallGateInfo_t)ioBuffer;
            ntStatus=ReleaseCallGate(CallGateInfo);
            MYTRACE("ReleaseCallGate rc=%x\n", ntStatus);
            break;
        }

        default:

            Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
            MYTRACE("CALLGATE.SYS: unknown IRP_MJ_DEVICE_CONTROL\n");
            break;
        }

        break;
    }
    ntStatus = Irp->IoStatus.Status;
    IoCompleteRequest (Irp,
                       IO_NO_INCREMENT
                       );

    return ntStatus;
}



VOID
DriverUnload(
    IN PDRIVER_OBJECT DriverObject
    )
{
    UNICODE_STRING         deviceLinkUnicodeString;

    RtlInitUnicodeString (&deviceLinkUnicodeString,
                          deviceLinkBuffer
                          );
    IoDeleteSymbolicLink (&deviceLinkUnicodeString);
    IoDeleteDevice (DriverObject->DeviceObject);
    MYTRACE("CALLGATE.SYS: unloading\n");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -