温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,汇文网负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
网站客服:3074922707
瑞客论坛 www.ruike1.com
D024-突破TP
NP保护跨进程读写内存1【瑞客论坛
www.ruike1.com】
D024
突破
TP
NP
突破TP,NP保护跨进程读写内存1
2021在线班
郁金香灬老师 QQ 150330575
交流群:158280115
学习目标:
突破TP,NP保护跨进程读写内存1
#include <ntifs.h>
OpenProcess->ReadProcessMemory->WriteProcessMemory
//OK 测试通过 遇到2个坑
//第1个坑 sizeof(PKAPC_STATE)是指针 得改结构大小 sizeof(KAPC_STATE)
//第2个坑 KeStackAttachProcess后 进程空间变化了 得用内核内存 中转 BUF缓冲区
//Address为目标进程的内存地址
//Buffer //当前进程的地址
BOOLEAN KReadProcessMemory(IN PEPROCESS Process, IN PVOID Address, IN UINT32 Length, IN OUT PVOID Buffer)
{
KAPC_STATE apc_state;
RtlZeroMemory(&apc_state, sizeof(KAPC_STATE));
//在所有进程通用
PVOID tmpBuf_Kernel = ExAllocatePool(NonPagedPool, Length);
//可以改MDL把 进程地址 映射到 内核驱动也可以
//中转内存地址 因为 KeStackAttachProcess后 原来的进程R3 Buffer 在目标地址里不存在
//RtlCopyMemory(tmpBuf_Kernel, Buffer, Length);
//进入到目标进程的 内存空间
DbgPrint("yjx:附加到目标进程 Address=%p Buffer=%p", Address, Buffer);
//进入目标进程内存空间
KeStackAttachProcess((PVOID)Process, &apc_state);
//判断目标地址是否可以访问
BOOLEAN dwRet = MmIsAddressValid(Address);
if (dwRet)
{
KdPrint(("yjx[sys64] RtlCopyMemory(Address, Buffer, Length);\r\n", Address, Buffer, Length));
//RtlCopyMemory(Address, tmpBuf_Kernel, Length); //一定要用内核内存 中转
RtlCopyMemory(tmpBuf_Kernel, Address, Length); // c/c++ memcpy
}
else
{
KdPrint(("yjx:sys64:Error Line37"));
}
//分离目标进程空间 恢复环境
KeUnstackDetachProcess(&apc_state);
DbgPrint("yjx: sys分离目标进程");
RtlCopyMemory(Buffer, tmpBuf_Kernel, Length);
//DbgPrint("yjx:sys: Buffer[0]=%llx", *(UINT64*)Buffer);;
ExFreePool(tmpBuf_Kernel);
return dwRet;
}
//dwPid为目标进程id
//lpBaseAddress 目标进程地址
//lpBuffer 当前进程地址 1
//内核内存地址 当前进程地址 2
int ReadProcessMemoryForPid(UINT32 dwPid, PVOID pBase, PVOID lpBuffer, UINT32 nSize)
{
//根据pid获取PEPROCESS OpenProcess
PEPROCESS Seleted_pEPROCESS = NULL;
DbgPrint("yjx:sys64 ReadMemory pid=%d pBase=%p", dwPid, pBase);
if (PsLookupProcessByProcessId((PVOID)(UINT_PTR)(dwPid), &Seleted_pEPROCESS) == STATUS_SUCCESS)
{
BOOLEAN br = KReadProcessMemory(Seleted_pEPROCESS, (PVOID)pBase, nSize, lpBuffer);
ObDereferenceObject(Seleted_pEPROCESS);
if (br)
{
return nSize;
}
}
else
{
KdPrint(("yjx sys64 PsLookupProcessByProcessId Fail..."));
}
return STATUS_SUCCESS;// STATUS_UNSUCCESSFUL;
}
//int ReadProcessMemoryForPid(UINT32 dwPid, PVOID pBase, PVOID lpBuffer, UINT32 nSize);
void IRP_IO_通过PID读取数据(PIRP pirp)
{
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(pirp); //获取应用层传来的参数
UINT64* 缓冲区 = (UINT64*)(pirp->AssociatedIrp.SystemBuffer);
KdPrint(("yjx:%s 行号%d\n", __FUNCDNAME__, __LINE__));
if (缓冲区)
{
//
//int*p = (int*)缓冲区;
UINT32 PID = (UINT32)(UINT64)缓冲区[0]; //传入数据
PVOID pBase = (PVOID)(UINT64)缓冲区[1]; //传入数据
//PVOID lpBuffer = (PVOID)(UINT64)缓冲区[2]; //传入数据
UINT32 nSize = (UINT32)(UINT64)缓冲区[3]; //传入数据
UINT32 ReadSize= ReadProcessMemoryForPid(PID, pBase, 缓冲区, nSize);
pirp->IoStatus.Status = STATUS_SUCCESS;
pirp->IoStatus.Information = nSize;//返回给DeviceIoControl中的 倒数第二个参数lpBytesReturned
IoCompleteRequest(pirp, IO_NO_INCREMENT);//调用方已完成所有I/O请求处理操作 并且不增加优先级
}
irpStack;
}