📄 callgate.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 + -