在笔者上一篇文章《驱动开发:内核MDL读写进程内存》
简单介绍了如何通过MDL映射的方式实现进程读写操作,本章将通过如上案例实现远程进程反汇编功能,此类功能也是ARK工具中最常见的功能之一,通常此类功能的实现分为两部分,内核部分只负责读写字节集,应用层部分则配合反汇编引擎对字节集进行解码,此处我们将运用capstone
引擎实现这个功能。
首先是实现驱动部分,驱动程序的实现是一成不变的,仅仅只是做一个读写功能即可,完整的代码如下所示;
// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com
#include <ntifs.h>
#include <windef.h>
#define READ_PROCESS_CODE CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ALL_ACCESS)
#define WRITE_PROCESS_CODE CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ALL_ACCESS)
#define DEVICENAME L"\\Device\\ReadWriteDevice"
#define SYMBOLNAME L"\\??\\ReadWriteSymbolName"
typedef struct
{
DWORD pid; // 进程PID
UINT64 address; // 读写地址
DWORD size; // 读写长度
BYTE* data; // 读写数据集
}ProcessData;
// MDL读取封装
BOOLEAN ReadProcessMemory(ProcessData* ProcessData)
{
BOOLEAN bRet = TRUE;
PEPROCESS process = NULL;
// 将PID转为EProcess
PsLookupProcessByProcessId(ProcessData->pid, &process);
if (process == NULL)
{
return FALSE;
}
BYTE* GetProcessData = NULL;
__try
{
// 分配堆空间 NonPagedPool 非分页内存
GetProcessData = ExAllocatePool(NonPagedPool, ProcessData->size);
}
__except (1)
{
return FALSE;
}
KAPC_STATE stack = { 0 };
// 附加到进程
KeStackAttachProcess(process, &stack);
__try
{
// 检查进程内存是否可读取
ProbeForRead(ProcessData->address, ProcessData->size, 1);
// 完成拷贝
RtlCopyMemory(GetProcessData, ProcessData->address, ProcessData->size);
}
__except (1)
{
bRet = FALSE;
}
// 关闭引用
ObDereferenceObject(process);
// 解除附加
KeUnstackDetachProcess(&stack);
// 拷贝数据
RtlCopyMemory(ProcessData->data, GetProcessData, ProcessData-