1、 突破TP,NP保护跨进程读写内存12021在线班郁金香灬老师 QQ 150330575交流群:158280115学习目标: 突破TP,NP保护跨进程读写内存1 #include OpenProcess-ReadProcessMemory-WriteProcessMemory/OK 测试通过 遇到2个坑 /第1个坑 sizeof(PKAPC_STATE)是指针 得改结构大小 sizeof(KAPC_STATE)/第2个坑 KeStackAttachProcess后 进程空间变化了 得用内核内存 中转 BUF缓冲区/Address为目标进程的内存地址/Buffer /当前进程的地址BOOLEAN
2、 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
3、 在目标地址里不存在/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(yjxsys64 RtlCopyMemory(Address, Buffer
4、, Length);rn, Address, Buffer, Length);/RtlCopyMemory(Address, tmpBuf_Kernel, Length); /一定要用内核内存 中转RtlCopyMemory(tmpBuf_Kernel, Address, Length); / c/c+ memcpy elseKdPrint(yjx:sys64:Error Line37);/分离目标进程空间 恢复环境KeUnstackDetachProcess(&apc_state);DbgPrint(yjx: sys分离目标进程);RtlCopyMemory(Buffer, tmpBuf_K
5、ernel, Length);/DbgPrint(yjx:sys: Buffer0=%llx, *(UINT64*)Buffer);ExFreePool(tmpBuf_Kernel);return dwRet;/dwPid为目标进程id/lpBaseAddress 目标进程地址/lpBuffer 当前进程地址 1/内核内存地址 当前进程地址 2int ReadProcessMemoryForPid(UINT32 dwPid, PVOID pBase, PVOID lpBuffer, UINT32 nSize)/根据pid获取PEPROCESS OpenProcessPEPROCESS Sele
6、ted_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 (
7、br)return nSize;elseKdPrint(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);
8、/获取应用层传来的参数UINT64* 缓冲区 = (UINT64*)(pirp-AssociatedIrp.SystemBuffer);KdPrint(yjx:%s 行号%dn, _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中的 倒数第二个参数lpBytesReturnedIoCompleteRequest(pirp, IO_NO_INCREMENT);/调用方已完成所有I/O请求处理操作 并且不增加优先级 irpStack;