herer is the code:
Code: Select all#include <ntddk.h>
const WCHAR deviceLinkBuffer[] = L"\\DosDevices\\my_driver";
const WCHAR deviceNameBuffer[] = L"\\Device\\my_driver";
PDEVICE_OBJECT g_Device;
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned char BYTE;
#pragma pack(1)
typedef struct ServiceDescriptorEntry
{
DWORD *KiServiceTable;
DWORD *CounterBaseTable;
DWORD *nSystemCalls;
DWORD *KiArgumentTable;
}SDE, *PSDE;
#pragma pack()
typedef struct ServiceDescriptorTable
{
SDE ServiceDescriptor[4];
} SDT;
__declspec(dllimport) SDE KeServiceDescriptorTable;
#define STANDARD_RIGHTS_REQUIRED (0x000F0000L)
#define PROCESS_TERMINATE (0x0001)
#define PROCESS_CREATE_THREAD (0x0002)
#define PROCESS_VM_OPERATION (0x0008)
#define PROCESS_VM_READ (0x0010)
#define PROCESS_VM_WRITE (0x0020)
#define PROCESS_DUP_HANDLE (0x0040)
#define PROCESS_CREATE_PROCESS (0x0080)
#define PROCESS_SET_QUOTA (0x0100)
#define PROCESS_SET_INFORMATION (0x0200)
#define PROCESS_QUERY_INFORMATION (0x0400)
#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
0xFFF)
#pragma pack(1)
typedef struct sPTE {
unsigned char P:1; // 0: Present
unsigned char RW:1; // 1: Read/Write
unsigned char US:1; // 2: User/Supervisor
unsigned char PWT:1; // 3: Write-Through
unsigned char PCD:1; // 4: Cache Disable
unsigned char A:1; // 5: Access
unsigned char D:1; // 6: Dirty
unsigned char PAT:1; // 7: Page Attribute
unsigned char G:1; // 8: Global
unsigned char CoW:1; // 9: Copy-On-Write
unsigned int UUU:22; //
}PTE_ST, *pPTE_ST;
#pragma pack()
typedef enum _MEMORY_INFORMATION_CLASS {
MemoryBasicInformation,
MemoryWorkingSetList,
MemorySectionName,
MemoryBasicVlmInformation
} MEMORY_INFORMATION_CLASS;
typedef struct _MEMORY_BASIC_INFORMATION { // Information Class 0
PVOID BaseAddress;
PVOID AllocationBase;
ULONG AllocationProtect;
ULONG RegionSize;
ULONG State;
ULONG Protect;
ULONG Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
typedef NTSTATUS
(NTAPI *MyZwQueryVirtualMemory)(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
OUT PVOID MemoryInformation,
IN ULONG MemoryInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
NTSTATUS Unload(IN PDRIVER_OBJECT DriverObject);
NTSTATUS Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS DeviceControl(IN PFILE_OBJECT FileObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject);
VOID NTAPI KeAttachProcess(IN PEPROCESS);
VOID NTAPI KeDetachProcess();
NTSTATUS PsLookupProcessByProcessId( IN ULONG ProcessId, OUT PEPROCESS *Process );
NTSTATUS defaultDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIRP);
#define FILE_DEVICE 0x0000584e
#define IOCTL_DEVICECONTROL (ULONG) CTL_CODE(FILE_DEVICE, 0x01, METHOD_BUFFERED, FILE_WRITE_ACCESS)
typedef struct _ioctlparams {
ULONG pid;
ULONG Reverse1;
ULONG Reverse2;
} IOCTLPARAMS;
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath )
{
NTSTATUS ntStatus;
UNICODE_STRING deviceNameUnicodeString;
UNICODE_STRING deviceLinkUnicodeString;
int i;
DbgPrint("Driver Started...\n");
RtlInitUnicodeString (&deviceNameUnicodeString, deviceNameBuffer );
RtlInitUnicodeString (&deviceLinkUnicodeString, deviceLinkBuffer );
ntStatus = IoCreateDevice ( DriverObject,
0,
&deviceNameUnicodeString,
FILE_DEVICE,
0,
TRUE,
&g_Device );
if(! NT_SUCCESS(ntStatus))
{
DbgPrint(("Failed to create device!\n"));
return ntStatus;
}
ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,
&deviceNameUnicodeString );
if(! NT_SUCCESS(ntStatus))
{
IoDeleteDevice(DriverObject->DeviceObject);
DbgPrint("Failed to create symbolic link!\n");
return ntStatus;
}
for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; ++i)
{
DriverObject->MajorFunction[i] = defaultDispatch;
}
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Dispatch;
DriverObject->DriverUnload = Unload;
return STATUS_SUCCESS;
}
NTSTATUS defaultDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIRP)
{
pIRP->IoStatus.Status = STATUS_SUCCESS;
pIRP->IoStatus.Information = 0;
IoCompleteRequest(pIRP,IO_NO_INCREMENT);
return (STATUS_SUCCESS);
}
NTSTATUS Unload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING deviceLinkUnicodeString;
PDEVICE_OBJECT p_NextObj;
DbgPrint("Driver Unload...\n");
p_NextObj = DriverObject->DeviceObject;
if (p_NextObj != NULL)
{
RtlInitUnicodeString(&deviceLinkUnicodeString, deviceLinkBuffer);
IoDeleteSymbolicLink(&deviceLinkUnicodeString);
IoDeleteDevice(DriverObject->DeviceObject);
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
NTSTATUS Dispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION irpStack;
PVOID inputBuffer;
PVOID outputBuffer;
ULONG inputBufferLength;
ULONG outputBufferLength;
ULONG ioControlCode;
NTSTATUS ntstatus;
ntstatus = Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
irpStack = IoGetCurrentIrpStackLocation(Irp);
inputBuffer = Irp->AssociatedIrp.SystemBuffer;
inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
outputBuffer = Irp->AssociatedIrp.SystemBuffer;
outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
switch (irpStack->MajorFunction){
case IRP_MJ_DEVICE_CONTROL:
if (ioControlCode == IOCTL_DEVICECONTROL){
ntstatus = DeviceControl(irpStack->FileObject,
inputBuffer, inputBufferLength,
outputBuffer, outputBufferLength,
&Irp->IoStatus, DeviceObject);
}
break;
}
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntstatus;
}
NTSTATUS DeviceControl(
IN PFILE_OBJECT FileObject,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
)
{
IOCTLPARAMS *params;
ULONG pid;
HANDLE hProcess;
OBJECT_ATTRIBUTES ObjectAttributes;
CLIENT_ID client_id;
NTSTATUS Status;
MEMORY_BASIC_INFORMATION mem_info = {0};
ULONG *systemCallTable = (ULONG*)KeServiceDescriptorTable.KiServiceTable;
MyZwQueryVirtualMemory ZwQueryVirtualMemory = (MyZwQueryVirtualMemory)(systemCallTable[0xB2]);;
if ((InputBufferLength < sizeof(int) * 3) || (InputBuffer == NULL))
{
IoStatus->Status = STATUS_INVALID_BUFFER_SIZE;
return IoStatus->Status;
}
params = (IOCTLPARAMS *)InputBuffer;
pid = params->pid;
DbgPrint("pid = %X\n", pid);
InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
client_id.UniqueProcess = (HANDLE) pid;
client_id.UniqueThread = NULL;
Status = ZwOpenProcess(&hProcess, PROCESS_QUERY_INFORMATION, &ObjectAttributes, &client_id);
if (!NT_SUCCESS(Status)){
DbgPrint("cannot get process handle, ERROR CODE = %08X\n", Status);
IoStatus->Status = STATUS_UNSUCCESSFUL;
return IoStatus->Status;
}
DbgPrint("process handle = %08X\n", hProcess);
Status = ZwQueryVirtualMemory(hProcess, (PVOID) 0x400000, MemoryBasicInformation, &mem_info, sizeof(MEMORY_BASIC_INFORMATION), NULL);
if (!NT_SUCCESS(Status)){
DbgPrint("cannot query memory, ERROR CODE = %08X\n", Status);
ZwClose(hProcess);
IoStatus->Status = STATUS_UNSUCCESSFUL;
return IoStatus->Status;
}
DbgPrint("base address: %08X\n", mem_info.BaseAddress);
DbgPrint("real base address: %08X\n", mem_info.AllocationBase);
DbgPrint("region size: %08X\n", mem_info.RegionSize);
ZwClose(hProcess);
return IoStatus->Status;
}
and usermode:
Code: Select all#include <winternl.h>
#include <Windows.h>
#include <stdio.h>
#define FILE_DEVICE 0x0000584e
#define IOCTL_DEVICECONTROL (ULONG) CTL_CODE(FILE_DEVICE, 0x01, METHOD_BUFFERED, FILE_WRITE_ACCESS)
typedef struct _ioctlparams {
ULONG pid;
ULONG Reverse1;
ULONG Reverse2;
} IOCTLPARAMS;
int wmain(int argc, wchar_t *argv[])
{
if (argc != 2){
fwprintf(stderr, L"usage: %s pid\n", argv[0]);
exit(1);
}
int PID = _wtoi(argv[1]);
HANDLE hFile = CreateFile(L"\\\\.\\my_driver", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE){
fwprintf(stderr, L"cannot get handle from symbol\n");
exit(1);
}
IOCTLPARAMS param;
DWORD d_bytesRead;
DWORD success;
param.pid = PID;
success = DeviceIoControl(hFile, IOCTL_DEVICECONTROL, ¶m, sizeof(IOCTLPARAMS), NULL, 0, &d_bytesRead, NULL);
if (success){
fwprintf(stderr, L"pid send successfully\n");
}else{
fwprintf(stderr, L"cannot send pid\n");
}
CloseHandle(hFile);
}