驱动编程方式实现win10 64位下读写某一进程的内存数据
//实现功能:为当前运行中的某一程序申请一块内存,并可进行读写。//有什么用?如何功能扩展?请有兴趣的朋友自己探索!
#include <ntddk.h>
typedef struct _KAPC_STATE {
LIST_ENTRY ApcListHead;
struct _KPROCESS *Process;
union {
UCHAR InProgressFlags;
struct {
BOOLEAN KernelApcInProgress : 1;
BOOLEAN SpecialApcInProgress : 1;
};
};
BOOLEAN KernelApcPending;
BOOLEAN UserApcPending;
} KAPC_STATE, *PKAPC_STATE, *PRKAPC_STATE;
#if (NTDDI_VERSION >= NTDDI_WIN2K)
_IRQL_requires_max_(APC_LEVEL)
NTKERNELAPI
VOID
KeStackAttachProcess (
_Inout_ PRKPROCESS PROCESS,
_Out_ PRKAPC_STATE ApcState
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN2K)
_IRQL_requires_max_(APC_LEVEL)
NTKERNELAPI
VOID
KeUnstackDetachProcess (
_In_ PRKAPC_STATE ApcState
);
#endif
NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(_In_ HANDLE ProcessId,_Outptr_ PEPROCESS *Process);
NTSTATUS
ZwAllocateVirtualMemory(
__in HANDLEProcessHandle,
__inout PVOID*BaseAddress,
__in ULONG_PTRZeroBits,
__inout PSIZE_TRegionSize,
__in ULONGAllocationType,
__in ULONGProtect
);
KIRQL Irql;
VOID WPOFF()
{
ULONG_PTR cr0 = 0;
Irql = KeRaiseIrqlToDpcLevel();
cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
#ifdef _WIN64
_disable();
#endif
}
VOID WPON()
{
ULONG_PTR cr0 = __readcr0();
cr0 |= 0x10000;
#ifdef _WIN64
_enable();
#endif
__writecr0(cr0);
KeLowerIrql(Irql);
}
NTSTATUS ReadWriteProcess()
{
NTSTATUS Status;
HANDLEhProcess;
CLIENT_ID ClientId;
PVOID AllocateAddress;
size_t ReginSize;
OBJECT_ATTRIBUTES ObjAttr;
PEPROCESS Process = NULL;
ClientId.UniqueProcess = (HANDLE)9544; //进程句柄,可从任务管理器中取得
ClientId.UniqueThread = 0;
AllocateAddress = 0; //不赋值 会C000018错误
memset(&ObjAttr, 0, sizeof(OBJECT_ATTRIBUTES));
PsLookupProcessByProcessId((HANDLE)ClientId.UniqueProcess, &Process);
Status = ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &ObjAttr, &ClientId);
if (!NT_SUCCESS(Status))
{
DbgPrint("ZwOpenProcess Error -- %#X", Status);
ZwClose(hProcess);
return Status;
}
DbgPrint("ZwOpenProcess Success");
ReginSize = 0xff;
Status = ZwAllocateVirtualMemory(hProcess, &AllocateAddress, 0, &ReginSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
DbgPrint("ZwAllocateVirtualMemory Error -- %#X", Status);
ZwClose(hProcess);
return Status;
}
/*要依附所在进程,才可以更改对应内存中的值*/
//--------------------------------------------------------
KAPC_STATE kApc;
KeStackAttachProcess((PRKPROCESS)Process, &kApc);
//--------------------------------------------------------
(DWORD32)(*(PVOID*)AllocateAddress) = 0xABCD; //写入内存
//---------------------
// (DWORD32)(*((PVOID*)AllocateAddress+4)) = 0xDCBA; //写入内存------------------------------------
KeUnstackDetachProcess(&kApc);
//////////////////////////////////////////////////////////
DbgPrint("address: %p - %p -size:- %d", &AllocateAddress, AllocateAddress, ReginSize);
// WPON();
// DbgPrint("%p\n",*(PVOID*)AllocateAddress);
// WPOFF();
ZwClose(hProcess);
return Status;
}
HANDLE DriverAllocMem(HANDLE ProcessId, ULONG RegionSize)
{
NTSTATUS status;
PEPROCESS Process;
HANDLE BaseAddr = NULL;
KAPC_STATE ApcState;
status = PsLookupProcessByProcessId(ProcessId, &Process);
if (NT_SUCCESS(status))
{
KeStackAttachProcess((PKPROCESS)Process, &ApcState);
_try
{
ZwAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&BaseAddr, 0, (PSIZE_T)&RegionSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
MmProtectMdlSystemAddress(BaseAddr, PAGE_EXECUTE_READWRITE);
RtlZeroMemory(BaseAddr, RegionSize); //关键点
//这里是关键点,内存清理后,然后ring0下再调用 VirtualProtectEx() 修改内存属性,这样申请到的内存,用之前的代码,就莫名其妙的就可以访问了
//原因我不懂,之前因为申请到的内存,不能访问,我就用CE查看内存,然后发现用CE访问过后的内存就可以驱动读写了
//后来我就胡乱测试,发现这个方法可以,ring0申请内存,然后清零,然后ring3修改内存属性,就可以访问
KeUnstackDetachProcess(&ApcState);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KeUnstackDetachProcess(&ApcState);
return 0;
}
}
return BaseAddr;
}
VOID MyUnload(PDRIVER_OBJECT pDriverObject)
{
DbgPrint("GoodBye World!");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegisterPath)
{
pDriverObject->DriverUnload = MyUnload;
DbgPrint("Hello World");
ReadWriteProcess();
return STATUS_SUCCESS;
}
//可用CheatEngine 软件工具打开对应进程句柄号的程序,查看相应内容地址的属性和内容
你不如直接替换cr3寄存器
#include <intrin.h>
#include <ntifs.h>
VOIDUnloadDriver(PDRIVER_OBJECT pDriver)
{}
typedef struct _PROCESS_DATA_
{
CHAR ignore;
ULONGLONG DirectoryTableBase;
}PROCESS_DATA,*PPROCESS_DATA;
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegpath)
{
pDriver->DriverUnload = UnloadDriver;
NTSTATUS status = STATUS_SUCCESS;
PEPROCESS pEprocess = NULL;
ULONG oldcr3;
status = PsLookupProcessByProcessId(5420,&pEprocess);
if (!NT_SUCCESS(status))
{
return STATUS_UNSUCCESSFUL;
}
ObDereferenceObject(pEprocess);
PPROCESS_DATA pdata = pEprocess;
_disable();
oldcr3 = __readcr3();
__writecr3(pdata->DirectoryTableBase);
CHAR buffer = { 0 };
__try {
ProbeForRead(0xf20020,10,1);
RtlCopyMemory(buffer, 0xf20020, 10);
for (size_t i = 0; i < 10; i++)
{
DbgPrintEx(77, 0, "%2x ", buffer);
}
DbgPrintEx(77, 0, "\n");
}
__except(1){
}
__writecr3(oldcr3);
_enable();
return STATUS_SUCCESS;
} 学习了,谢谢!{:1_921:} 会编程的人都好厉害。 那个啥,这个驱动编程写的是到底是驱动文件(配置文件inf),还是里面的驱动文件内容
页:
[1]