even: first usable version

This commit is contained in:
Zephyr Lykos 2024-03-31 17:16:22 +08:00
parent 0920dee45e
commit 17ff33169b
No known key found for this signature in database
GPG Key ID: D3E9D31E2F77F04D
6 changed files with 1525 additions and 1470 deletions

View File

@ -17,7 +17,7 @@ INCLUDES +=
# but we'd have to be careful to "make clean" after changing # but we'd have to be careful to "make clean" after changing
# the driver name here in the makefile... # the driver name here in the makefile...
#CFLAGS = -Wall $(INCLUDES) -DEVEN_DRIVER_NAME=\"$(DRVNAME)\" #CFLAGS = -Wall $(INCLUDES) -DEVEN_DRIVER_NAME=\"$(DRVNAME)\"
CFLAGS = -Wall $(INCLUDES) CFLAGS = -Wall -Wpedantic -DNDEBUG $(INCLUDES)
# Kernel-mode libs: # Kernel-mode libs:
# libntoskrnl = basic kernel-mode environment # libntoskrnl = basic kernel-mode environment
@ -28,12 +28,12 @@ KRNLIBS = -lntoskrnl
CC = x86_64-w64-mingw32-gcc CC = x86_64-w64-mingw32-gcc
DLLTOOL = x86_64-w64-mingw32-dlltool DLLTOOL = x86_64-w64-mingw32-dlltool
STRIP = x86_64-w64-mingw32-strip STRIP = x86_64-w64-mingw32-strip
#STRIP = true
all: $(DRVNAME).sys all: $(DRVNAME).sys
# Dependencies on header files: # Dependencies on header files:
$(DRVNAME).sys: even_names.h $(DRVNAME).sys: even_names.h even_ioctl.h even_peb.h utlist.h
$(DRVNAME).sys: even_ioctl.h
# This shall get appended to the built-in set of suffixes supported: # This shall get appended to the built-in set of suffixes supported:
.SUFFIXES: .sys .exe .SUFFIXES: .sys .exe

228
even.c
View File

@ -18,25 +18,20 @@
* *
*/ */
#include "even_ioctl.h"
#include "even_names.h"
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#define uthash_nonfatal_oom(obj) \ #include "even_ioctl.h"
do \ #include "even_names.h"
{ \
return STATUS_INTERNAL_ERROR; \
} while (0)
#include "even_peb.h" #include "even_peb.h"
#include "uthash.h" #include "utlist.h"
/* /*
* Htsysm7679 constatns * Htsysm7679 constatns
*/ */
USE_EVEN_IOCTL_OUT_DATA(1); USE_EVEN_IOCTL_OUT_DATA(1)
USE_EVEN_IOCTL_OUT_DATA(2); USE_EVEN_IOCTL_OUT_DATA(2)
const struct even_ioctl_out_data1 htsysm_check_1 = {.result = 1, .data = {0x64, 0xBC, 0xD4, 0x56}}; const struct even_ioctl_out_data1 htsysm_check_1 = {.result = 1, .data = {0x64, 0xBC, 0xD4, 0x56}};
const struct even_ioctl_out_data2 htsysm_check_2 = { const struct even_ioctl_out_data2 htsysm_check_2 = {
@ -45,6 +40,60 @@ const struct even_ioctl_out_data2 htsysm_check_2 = {
}; };
const struct even_ioctl_out_data1 htsysm_check_3 = {.result = 1, .data = {0x48, 0xB3, 0xF7, 0x97}}; const struct even_ioctl_out_data1 htsysm_check_3 = {.result = 1, .data = {0x48, 0xB3, 0xF7, 0x97}};
even_peb_t *even_fake_peb = NULL;
static even_peb_t __stdcall *even_find_peb(HANDLE pid)
{
DbgPrint("Even Htsysm7679: Finding PEB for PID %d\r\n", pid);
even_peb_t *s;
DL_SEARCH_SCALAR(even_fake_peb, s, pid, pid);
DbgPrint("Even Htsysm7679: Found at %08x\r\n", s);
return s;
}
static NTSTATUS __stdcall even_create_peb(HANDLE pid)
{
DbgPrint("Even Htsysm7679: Creating PEB for PID %d\r\n", pid);
even_peb_t *s = even_find_peb(pid);
if (!s)
{
DbgPrint("Even Htsysm7679: Allocating new PEB\r\n");
s = ExAllocatePool(PagedPool, sizeof(*s));
if (!s)
return STATUS_INTERNAL_ERROR;
s->pid = pid;
s->refcnt = 0;
DL_APPEND(even_fake_peb, s);
}
DbgPrint("Even Htsysm7679: fake_peb at %08x\r\n", s);
s->refcnt++;
return STATUS_SUCCESS;
}
static NTSTATUS __stdcall even_delete_peb(even_peb_t *peb)
{
DbgPrint("Even Htsysm7679: PEB Refcnt for PID %d: %d\r\n", peb->pid, peb->refcnt);
if (--(peb->refcnt) <= 0)
{
DbgPrint("Even Htsysm7679: PEB Refcnt <= 0, deleting\r\n");
DL_DELETE(even_fake_peb, peb);
ExFreePool(peb);
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
static VOID __stdcall even_unload(IN PDRIVER_OBJECT DriverObject) static VOID __stdcall even_unload(IN PDRIVER_OBJECT DriverObject)
{ {
ANSI_STRING SymbolicLinkNameA; ANSI_STRING SymbolicLinkNameA;
@ -52,6 +101,13 @@ static VOID __stdcall even_unload(IN PDRIVER_OBJECT DriverObject)
DbgPrint("Even Htsysm7679: DriverUnload called\r\n"); // catch this using DBGVIEW from www.sysinternals.com DbgPrint("Even Htsysm7679: DriverUnload called\r\n"); // catch this using DBGVIEW from www.sysinternals.com
even_peb_t *el, *tmp;
DL_FOREACH_SAFE(even_fake_peb, el, tmp)
{
DL_DELETE(even_fake_peb, el);
ExFreePool(el);
}
/*RtlInitUnicodeString( &SymbolicLinkName, EVEN_DOSDEVICE_NAME );*/ /*RtlInitUnicodeString( &SymbolicLinkName, EVEN_DOSDEVICE_NAME );*/
/* If I want to use normal string combining logic in my_names.h, I need to mess with ANSI vs. Unicode */ /* If I want to use normal string combining logic in my_names.h, I need to mess with ANSI vs. Unicode */
RtlInitString(&SymbolicLinkNameA, EVEN_DOSDEVICE_NAME); RtlInitString(&SymbolicLinkNameA, EVEN_DOSDEVICE_NAME);
@ -71,52 +127,7 @@ static NTSTATUS __stdcall even_dispatch_create(IN PDEVICE_OBJECT DeviceObject, I
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
struct even_peb *fake_peb = NULL; static NTSTATUS __stdcall even_dispatch_open_close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
static NTSTATUS __stdcall even_create_peb(HANDLE pid)
{
struct even_peb *s;
HASH_FIND_INT(fake_peb, &pid, s);
if (s == NULL)
{
s = ExAllocatePool(PagedPool, sizeof(*s));
s->pid = pid;
PROCESS_BASIC_INFORMATION ProcessInformation;
NtQueryInformationProcess(pid, ProcessBasicInformation, &ProcessInformation, sizeof(ProcessInformation), NULL);
RtlCopyMemory(&s->fake_peb, ProcessInformation.PebBaseAddress, sizeof(*ProcessInformation.PebBaseAddress));
HASH_ADD_INT(fake_peb, pid, s);
}
s->refcnt += 1;
return STATUS_SUCCESS;
}
static NTSTATUS __stdcall even_delete_peb(struct even_peb *peb)
{
DbgPrint("Even Htsysm7679: PEB Refcnt for PID %d: %d\r\n", peb->pid, peb->refcnt);
if (peb->refcnt <= 0)
{
DbgPrint("Even Htsysm7679: PEB Refcnt <= 0, deleting\r\n");
HASH_DEL(fake_peb, peb);
return STATUS_SUCCESS;
}
peb->refcnt -= 1;
return STATUS_SUCCESS;
}
static NTSTATUS __stdcall *even_find_peb(IN HANDLE pid, OUT struct even_peb *s)
{
HASH_FIND_INT(fake_peb, &pid, s);
return STATUS_SUCCESS;
}
static NTSTATUS __stdcall even_dispatch_open_close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{ {
UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(DeviceObject);
@ -129,31 +140,35 @@ static NTSTATUS __stdcall even_dispatch_open_close(IN PDEVICE_OBJECT DeviceObjec
} }
HANDLE pid = PsGetCurrentProcessId(); HANDLE pid = PsGetCurrentProcessId();
switch (io_stack->MajorFunction) switch (io_stack->MajorFunction)
{ {
case IRP_MJ_CREATE: case IRP_MJ_CREATE: {
if (pid == 0) if (pid == 0)
goto err_out; goto err_out;
DbgPrint("Even Htsysm7679: Handle to symbolink link opened by PID %d\r\n", pid); DbgPrint("Even Htsysm7679: Handle to symbolink link opened by PID %d\r\n", pid);
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = even_create_peb(pid); Irp->IoStatus.Status = even_create_peb(pid);
IoCompleteRequest(Irp, IO_NO_INCREMENT); }
break;
return STATUS_SUCCESS; case IRP_MJ_CLOSE: {
case IRP_MJ_CLOSE:
if (pid == 0) if (pid == 0)
goto err_out; goto err_out;
DbgPrint("Even Htsysm7679: Handle to symbolink link closed by PID %d\r\n", pid); DbgPrint("Even Htsysm7679: Handle to symbolink link closed by PID %d\r\n", pid);
struct even_peb s; even_peb_t *s = even_find_peb(pid);
even_find_peb(pid, &s); if (!s)
goto err_out;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = even_delete_peb(&s); Irp->IoStatus.Status = even_delete_peb(s);
IoCompleteRequest(Irp, IO_NO_INCREMENT); }
break;
return STATUS_SUCCESS;
default: default:
break; break;
} }
@ -242,40 +257,35 @@ static NTSTATUS __stdcall even_dispatch_device_control(IN PDEVICE_OBJECT DeviceO
if ((io_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(struct even_ioctl_in_data)) || if ((io_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(struct even_ioctl_in_data)) ||
(!even_in_data) || (!even_in_data) ||
(io_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(struct even_ioctl_out_data1)) || (io_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(struct even_ioctl_out_data)) ||
(!even_out_data)) (!even_out_data))
{ {
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
goto err_out; goto err_out;
} }
struct even_peb s; even_peb_t *s = NULL;
if ((even_in_data->offset + 4) > sizeof(s.fake_peb)) if ((even_in_data->offset + 4) > sizeof(s->fake_peb))
{ {
DbgPrint("Even Htsysm7679: offset %d out of bounds\r\n", even_in_data->offset);
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
goto err_out; goto err_out;
}; };
HANDLE pid = PsGetCurrentProcessId(); s = even_find_peb(PsGetCurrentProcessId());
if (even_find_peb(pid, &s) != STATUS_SUCCESS) if (!s)
{ {
Irp->IoStatus.Status = STATUS_INTERNAL_ERROR; Irp->IoStatus.Status = STATUS_INTERNAL_ERROR;
goto err_out; goto err_out;
} }
void *fake_peb; DbgPrint("Even Htsysm7679: Passed Value = %08x\r\n", even_in_data->value);
fake_peb = &s.fake_peb;
int value; unsigned int value = ~even_in_data->value;
RtlCopyBytes(&value, even_in_data->value, sizeof(value));
value = ~value;
DbgPrint("Even Htsysm7679: Offset = %0x, Value = %0x\r\n", even_in_data->offset, value); DbgPrint("Even Htsysm7679: Write Offset = %08x, Value = %08x\r\n", even_in_data->offset, value);
for (size_t i = 0; i < 4; i++) *(int *)&s->fake_peb[even_in_data->offset] = value;
{
((char *)fake_peb)[even_in_data->offset + i] = ((char *)&value)[i];
}
even_out_data->result = 1; even_out_data->result = 1;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
@ -290,43 +300,35 @@ static NTSTATUS __stdcall even_dispatch_device_control(IN PDEVICE_OBJECT DeviceO
if ((io_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(struct even_ioctl_in_data)) || if ((io_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(struct even_ioctl_in_data)) ||
(!even_in_data) || (!even_in_data) ||
(io_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(struct even_ioctl_out_data1)) || (io_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(struct even_ioctl_out_data)) ||
(!even_out_data)) (!even_out_data))
{ {
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
goto err_out; goto err_out;
} }
struct even_peb s; even_peb_t *s = NULL;
if ((even_in_data->offset + 4) > sizeof(s.fake_peb)) if ((even_in_data->offset + 4) > sizeof(s->fake_peb))
{ {
DbgPrint("Even Htsysm7679: offset %d out of bounds\r\n", even_in_data->offset);
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
goto err_out; goto err_out;
}; };
HANDLE pid = PsGetCurrentProcessId(); s = even_find_peb(PsGetCurrentProcessId());
if (even_find_peb(pid, &s) != STATUS_SUCCESS) if (!s)
{ {
Irp->IoStatus.Status = STATUS_INTERNAL_ERROR; Irp->IoStatus.Status = STATUS_INTERNAL_ERROR;
goto err_out; goto err_out;
} }
void *fake_peb; DbgPrint("Even Htsysm7679: Write Offset = %08x, Value = %08x\r\n", even_in_data->offset, even_in_data->value);
fake_peb = &s.fake_peb; *(int *)&s->fake_peb[even_in_data->offset] = even_in_data->value;
int value;
RtlCopyBytes(&value, even_in_data->value, sizeof(value));
for (size_t i = 0; i < 4; i++)
{
((char *)fake_peb)[even_in_data->offset + i] = ((char *)&value)[i];
}
even_out_data->result = 1; even_out_data->result = 1;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(*even_out_data); Irp->IoStatus.Information = sizeof(*even_out_data);
DbgPrint("Even Htsysm7679: Offset = %0x, Value = %0x\r\n", even_in_data->offset, value);
} }
break; break;
@ -335,48 +337,44 @@ static NTSTATUS __stdcall even_dispatch_device_control(IN PDEVICE_OBJECT DeviceO
struct even_ioctl_in_data *even_in_data = (struct even_ioctl_in_data *)Irp->AssociatedIrp.SystemBuffer; struct even_ioctl_in_data *even_in_data = (struct even_ioctl_in_data *)Irp->AssociatedIrp.SystemBuffer;
struct even_ioctl_out_data1 *even_out_data = (struct even_ioctl_out_data1 *)Irp->AssociatedIrp.SystemBuffer; struct even_ioctl_out_data1 *even_out_data = (struct even_ioctl_out_data1 *)Irp->AssociatedIrp.SystemBuffer;
if ((io_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(struct even_ioctl_in_data)) || if ((io_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(*even_in_data)) || (!even_in_data) ||
(!even_in_data) || (io_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*even_out_data)) || (!even_out_data))
(io_stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(struct even_ioctl_out_data1)) ||
(!even_out_data))
{ {
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
goto err_out; goto err_out;
} }
struct even_peb s; even_peb_t *s = NULL;
if ((even_in_data->offset + 4) > sizeof(s.fake_peb)) if ((even_in_data->offset + 4) > sizeof(s->fake_peb))
{ {
DbgPrint("Even Htsysm7679: offset out of bounds\r\n");
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
goto err_out; goto err_out;
}; };
HANDLE pid = PsGetCurrentProcessId(); HANDLE pid = PsGetCurrentProcessId();
if (even_find_peb(pid, &s) != STATUS_SUCCESS) s = even_find_peb(pid);
if (!s)
{ {
Irp->IoStatus.Status = STATUS_INTERNAL_ERROR; Irp->IoStatus.Status = STATUS_INTERNAL_ERROR;
goto err_out; goto err_out;
} }
void *fake_peb; DbgPrint("Even Htsysm7679: Read Offset = %08x, Mask = %08x\r\n", even_in_data->offset, even_in_data->value);
fake_peb = &s.fake_peb;
char value[4]; unsigned int value = even_in_data->value;
RtlCopyBytes(&value, fake_peb + (even_in_data->offset), sizeof(value)); DbgPrint("Even Htsysm7679: Value = %08x\r\n", value);
for (size_t i = 0; i < 4; i++) RtlCopyBytes(&even_out_data->data, &s->fake_peb[even_in_data->offset], sizeof(even_out_data->data));
{
value[i] &= value[i]; *(int *)even_out_data->data &= value;
}
DbgPrint("Even Htsysm7679: Return = %08x\r\n", *(int *)even_out_data->data);
even_out_data->result = 1; even_out_data->result = 1;
RtlCopyMemory(even_out_data->data, value, sizeof(value));
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(*even_out_data); Irp->IoStatus.Information = sizeof(*even_out_data);
DbgPrint("Even Htsysm7679: Offset = %0x, Value = %0x\r\n", even_in_data->offset, *(int *)even_in_data->value);
DbgPrint("Even Htsysm7679: Return = %0x\r\n", *(int *)value);
} }
break; break;

View File

@ -1,5 +1,5 @@
#ifndef _MY_IOCTL_H_ #ifndef _EVEN_IOCTL_H_
#define _MY_IOCTL_H_ 1 #define _EVEN_IOCTL_H_ 1
/* /*
METHOD_BUFFERED handles the copy_to_user/copy_from_user automagically for us, at the cost of some overhead METHOD_BUFFERED handles the copy_to_user/copy_from_user automagically for us, at the cost of some overhead
@ -27,20 +27,20 @@
struct even_ioctl_in_data struct even_ioctl_in_data
{ {
unsigned int offset; unsigned int offset;
char value[4]; unsigned int value;
}; };
struct even_ioctl_out_data struct even_ioctl_out_data
{ {
int result; unsigned int result;
}; };
#define USE_EVEN_IOCTL_OUT_DATA(x) \ #define USE_EVEN_IOCTL_OUT_DATA(x) \
struct even_ioctl_out_data##x \ struct even_ioctl_out_data##x \
{ \ { \
unsigned int result; \ unsigned int result; \
char data[x * 4]; \ unsigned char data[x * 4]; \
}; };
#endif /* _MY_IOCTL_H_ */ #endif /* _EVEN_IOCTL_H_ */
// vim: sw=4 et // vim: sw=4 et

View File

@ -1,59 +1,15 @@
#ifndef _EVEN_PEB_H_ #ifndef _EVEN_PEB_H_
#define _EVEN_PEB_H_ 1 #define _EVEN_PEB_H_ 1
#include "uthash.h" #include <ntdef.h>
#include <ddk/ntddk.h>
#include <minwindef.h>
typedef struct _PEB_LDR_DATA typedef struct even_peb
{
BYTE Reserved1[8];
PVOID Reserved2[3];
LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
/* This function pointer is undocumented and just valid for windows 2000.
Therefore I guess. */
typedef VOID(NTAPI *PPS_POST_PROCESS_INIT_ROUTINE)(VOID);
typedef struct _PEB
{
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID Reserved4[3];
PVOID AtlThunkSListPtr;
PVOID Reserved5;
ULONG Reserved6;
PVOID Reserved7;
ULONG Reserved8;
ULONG AtlThunkSListPtr32;
PVOID Reserved9[45];
BYTE Reserved10[96];
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
BYTE Reserved11[128];
PVOID Reserved12[1];
ULONG SessionId;
} PEB, *PPEB;
struct even_peb
{ {
HANDLE pid; HANDLE pid;
int refcnt; int refcnt;
PEB fake_peb; char fake_peb[0x1000];
UT_hash_handle hh; struct even_peb *next, *prev;
}; } even_peb_t;
#endif #endif
// vim: sw=4 et // vim: sw=4 et

1297
uthash.h

File diff suppressed because it is too large Load Diff

1398
utlist.h Normal file

File diff suppressed because it is too large Load Diff