Я изучаю программирование ядра Windows и сосредотачиваюсь на написании чистого кода C, который правильно обрабатывает и распространяет ошибки. Следующий фрагмент кода довольно прост, но я хотел бы получить отзывы о нем, прежде чем применять этот интерфейс и стиль кодирования к остальной части кода.
Приведенный ниже код отвечает за инициализацию объектов процесса, чтение и запись в их памяти и их очистку.
process.h:
#pragma once
#include <ntdef.h>
#include <ntifs.h>
typedef enum {
EProcessSuccess,
EProcessInvalid,
EProcessInvalidArgs,
EProcessAccessDenied,
EProcessFail
} EProcessStatus;
#define PROCESS_STATUS_SUCCESS(EValue) (EValue == EProcessSuccess)
typedef struct _Process {
HANDLE id;
PEPROCESS process;
BOOLEAN initialized;
} Process;
EProcessStatus processInit(HANDLE processId, Process* process);
EProcessStatus processDestroy(Process* process);
EProcessStatus processReadMemory(Process* process, PVOID sourceAddress, PVOID targetAddress, SIZE_T size);
EProcessStatus processWriteMemory(Process* process, PVOID sourceAddress, PVOID targetAddress, SIZE_T size);
EProcessStatus processGetId(Process* process, HANDLE* id);
process.c
#include "process.h"
#include "log.h"
NTSTATUS NTAPI MmCopyVirtualMemory(
PEPROCESS SourceProcess,
PVOID sourceAddress,
PEPROCESS TargetProcess,
PVOID targetAddress,
SIZE_T BufferSize,
KPROCESSOR_MODE PreviousMode,
PSIZE_T ReturnSize
);
void printErrorRW(char* msg, HANDLE id, NTSTATUS status, PVOID address, SIZE_T size) {
DEBUG_LOG("[ERROR] %s - %x n", msg, status);
DEBUG_LOG("ttProcess: %pn", id);
DEBUG_LOG("ttSourceAddress: %pn", address);
DEBUG_LOG("ttBytes: %pn", size);
}
BOOLEAN isValid(Process* process) {
return process && process->initialized;
}
EProcessStatus processInit(HANDLE processId, Process* process) {
DEBUG_VERBOSE("Create process with PID %dn", processId);
if (process == NULL) {
DEBUG_LOG("[ERROR] Can't initialize NULL Process.n");
return EProcessInvalid;
}
process->id = processId;
process->initialized = NT_SUCCESS(PsLookupProcessByProcessId(processId, &process->process));
if (!process->initialized) {
DEBUG_LOG("[ERROR] Unable to initialize process with PID %dn", processId);
return EProcessInvalid;
}
return EProcessSuccess;
}
EProcessStatus processDestroy(Process* process) {
if (isValid(process) && process->initialized) {
ObDereferenceObject(process->process);
}
return EProcessSuccess;
}
EProcessStatus processReadMemory(Process* process, PVOID sourceAddress, PVOID targetAddress, SIZE_T size) {
if (!isValid(process)) {
DEBUG_LOG("[ERROR] Can't read memory from invalid processn");
return EProcessInvalid;
}
DEBUG_VERBOSE("Read memory from process %d at address %pn", process->id, sourceAddress);
SIZE_T Bytes = 0;
NTSTATUS Status = STATUS_SUCCESS;
__try
{
Status = MmCopyVirtualMemory(process->process, sourceAddress, PsGetCurrentProcess(), targetAddress, size, KernelMode, &Bytes);
if (!NT_SUCCESS(Status))
{
printErrorRW("readMemory", process->id, Status, sourceAddress, Bytes);
return EProcessFail;
}
return EProcessSuccess;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printErrorRW("readMemory exception", process->id, Status, sourceAddress, Bytes);
return EProcessAccessDenied;
}
}
EProcessStatus processWriteMemory(Process* process, PVOID sourceAddress, PVOID targetAddress, SIZE_T size) {
if (!isValid(process)) {
DEBUG_LOG("[ERROR] Can't write memory from invalid processn");
return EProcessInvalid;
}
DEBUG_VERBOSE("Write memory from process %d at address %pn", process->id, sourceAddress);
SIZE_T Bytes = 0;
NTSTATUS Status = STATUS_SUCCESS;
__try
{
Status = MmCopyVirtualMemory(PsGetCurrentProcess(), sourceAddress, process->process, targetAddress, size, KernelMode, &Bytes);
if (!NT_SUCCESS(Status))
{
printErrorRW("writeMemory", process->id, Status, sourceAddress, Bytes);
return EProcessFail;
}
return EProcessSuccess;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printErrorRW("writeMemory exception", process->id, Status, sourceAddress, Bytes);
return EProcessAccessDenied;
}
}
EProcessStatus processGetId(Process* process, HANDLE* id) {
if (process == NULL) {
DEBUG_LOG("[ERROR] Can't get PID of invalid processn");
return EProcessInvalid;
}
if (id == NULL) {
DEBUG_LOG("[ERROR] processGetId - NULL id pointern");
return EProcessInvalidArgs;
}
*id = process->id;
return EProcessSuccess;
}
Спасибо за ваше время.