无法被检测的DMA物理读写内存设备到底是个啥 - 果核剥壳

import memprocfs # 导入memprocfs模块,用于获取系统进程的内存映射信息
vmm = memprocfs.Vmm(['-device', 'existingremote']) # 创建一个Vmm对象并传入选项'-device'和'existingremote'
for process in vmm.process_list(): # 遍历Vmm对象中所有进程列表
for entry in process.maps.pte(): # 遍历每个进程的映射表中的所有PTEs条目
if '-rwx' in entry['flags']: # 判断该PTEs条目是否可读、可写、可执行
print(str(process.pid) + ': ' + process.name + ': ' + str(entry)) # 打印符合条件的进程PID、名称和PTEs条目

这段代码使用memprocfs模块和Vmm对象来遍历系统中所有进程的内存布局,并输出符合条件(即可读、可写、可执行)的页面的相关信息,对于调试和分析进程的内存使用情况非常有用。

char* temp_str[] = { "","-device","FPGA" }; // 创建一个字符串数组,用于初始化VMM库
VMM_HANDLE handle = VMMDLL_Initialize(3, temp_str); // 调用VMMDLL_Initialize函数初始化VMM库并返回句柄

SIZE_T pcPIDs; // 定义一个变量pcPIDs,表示进程数目
VMMDLL_PidList(handle, nullptr, &pcPIDs); // 获取系统中所有进程的PID列表,并将进程数目存储在pcPIDs中
DWORD* pPIDs = (DWORD*)new char[pcPIDs * 4]; // 在堆上分配一块内存,用于存储进程PID列表
VMMDLL_PidList(handle, pPIDs, &pcPIDs); // 将系统中所有进程的PID列表存储到pPIDs指向的缓冲区中

for (int i = 0; i < pcPIDs; i++) // 遍历所有进程
{
VMMDLL_PROCESS_INFORMATION ProcessInformation = { 0 }; // 定义一个进程信息结构体ProcessInformation,用于存储进程的相关信息
ProcessInformation.magic = VMMDLL_PROCESS_INFORMATION_MAGIC; // 设置ProcessInformation的魔数为VMMDLL_PROCESS_INFORMATION_MAGIC
ProcessInformation.wVersion = VMMDLL_PROCESS_INFORMATION_VERSION; // 设置ProcessInformation的版本号为VMMDLL_PROCESS_INFORMATION_VERSION
SIZE_T pcbProcessInformation = sizeof(VMMDLL_PROCESS_INFORMATION); // 定义变量pcbProcessInformation,表示ProcessInformation结构体的大小
VMMDLL_ProcessGetInformation(handle, pPIDs[i], &ProcessInformation, &pcbProcessInformation); // 获取指定进程的信息,并存储在ProcessInformation中

std::cout << pPIDs[i] << "---" << ProcessInformation.szName; // 输出当前进程的PID和名称

VMMDLL_MAP_MODULEENTRY* ppModuleMapEntry = nullptr; // 定义一个指向VMMDLL_MAP_MODULEENTRY结构体的指针ppModuleMapEntry
VMMDLL_Map_GetModuleFromNameU(handle, pPIDs[i], ProcessInformation.szName, &ppModuleMapEntry, VMMDLL_MODULE_FLAG_NORMAL); // 获取指定模块的信息,并将结果存储在ppModuleMapEntry中

if (ppModuleMapEntry) // 如果获取到了模块信息
{
std::cout << "---" << ppModuleMapEntry->uszFullName << std::endl; // 输出该模块的完整路径
if (ProcessInformation.szName == std::string("dwm.exe")) // 如果当前进程是桌面窗口管理器
{
std::cout << "IMAGE:" << std::hex << ppModuleMapEntry->vaBase << std::endl; // 输出模块的基地址
ULONG temp = 0;
VMMDLL_MemRead(handle, pPIDs[i], ppModuleMapEntry->vaBase, (PBYTE)&temp, 4); // 读取内存页面信息
std::cout << "temp:" << temp << std::endl; // 输出读取到的内容
temp = 0;
VMMDLL_MemWrite(handle, pPIDs[i], ppModuleMapEntry->vaBase, (PBYTE)&temp, 4); // 修改内存页面信息
VMMDLL_MemRead(handle, pPIDs[i], ppModuleMapEntry->vaBase, (PBYTE)&temp, 4); // 再次读取内存页面信息
std::cout << "temp:" << temp << std::endl; // 输出修改后的内容
}
}
else // 如果没有获取到模块信息
{
std::cout << std::endl; // 输出一个换行符
}
}

这段代码使用了VMM库提供的函数,通过遍历进程列表、获取进程信息和模块信息,并读写进程的内存页面,用于实现对某些进程的监视和调试。
下面是对上面代码的每个函数的注释:

// 创建一个字符串数组temp_str,用于初始化VMM库时的选项
char* temp_str[] = { "","-device","FPGA" };

// 调用VMMDLL_Initialize函数初始化VMM库,并将句柄存储在handle中
VMM_HANDLE handle = VMMDLL_Initialize(3, temp_str);

// 定义变量pcPIDs,表示系统中进程的数量
SIZE_T pcPIDs;

// 获取系统中所有进程的PID列表,并将进程数目保存在pcPIDs中
VMMDLL_PidList(handle, nullptr, &pcPIDs);

// 在堆上分配一块内存,用于存储进程PID列表
DWORD* pPIDs = (DWORD*)new char[pcPIDs * 4];

// 将系统中所有进程的PID列表存储到pPIDs指向的缓冲区中
VMMDLL_PidList(handle, pPIDs, &pcPIDs);

// 遍历所有系统进程
for (int i = 0; i < pcPIDs; i++) {

// 定义一个结构体ProcessInformation,用于存储进程信息
VMMDLL_PROCESS_INFORMATION ProcessInformation = { 0 };

// 设置ProcessInformation的魔数
ProcessInformation.magic = VMMDLL_PROCESS_INFORMATION_MAGIC;

// 设置ProcessInformation的版本号
ProcessInformation.wVersion = VMMDLL_PROCESS_INFORMATION_VERSION;

// 定义变量pcbProcessInformation,表示ProcessInformation结构体的大小
SIZE_T pcbProcessInformation = sizeof(VMMDLL_PROCESS_INFORMATION);

// 获取指定进程的信息,并将结果存储在ProcessInformation中
VMMDLL_ProcessGetInformation(handle, pPIDs[i], &ProcessInformation, &pcbProcessInformation);

// 定义一个指向VMMDLL_MAP_MODULEENTRY结构体的指针ppModuleMapEntry
VMMDLL_MAP_MODULEENTRY* ppModuleMapEntry = nullptr;

// 获取指定模块的信息,并将结果存储在ppModuleMapEntry中
VMMDLL_Map_GetModuleFromNameU(handle, pPIDs[i], ProcessInformation.szName, &ppModuleMapEntry, VMMDLL_MODULE_FLAG_NORMAL);

// 判断是否成功获取到模块的信息
if (ppModuleMapEntry) {

// 定义一个变量temp,用于存储从内存中读取的数据
ULONG temp = 0;

// 读取指定模块的内存页面信息
VMMDLL_MemRead(handle, pPIDs[i], ppModuleMapEntry->vaBase, (PBYTE)&temp, 4);

// 修改指定模块的内存页面信息
VMMDLL_MemWrite(handle, pPIDs[i], ppModuleMapEntry->vaBase, (PBYTE)&temp, 4);

// 输出当前进程的PID和名称
std::cout << pPIDs[i] << "---" << ProcessInformation.szName;

// 输出当前模块的完整路径
std::cout << "---" << ppModuleMapEntry->uszFullName << std::endl;

// 输出从内存中读取的数据
std::cout << "temp:" << temp << std::endl;

// 输出修改后从内存中读取的数据
std::cout << "temp:" << temp << std::endl;
}
}

 

typedef struct tdVMMDLL_PROCESS_INFORMATION {
ULONG64 magic; // 魔数,用于检查结构体是否合法
WORD wVersion; // 结构体版本号
WORD wSize; // 结构体大小
VMMDLL_MEMORYMODEL_TP tpMemoryModel; // 内存模型类型,使用VMMDLL_MEMORYMODEL_*枚举类型表示
VMMDLL_SYSTEM_TP tpSystem; // 系统类型,使用VMMDLL_SYSTEM_*枚举类型表示
BOOL fUserOnly; // 是否只列出用户模式页面
DWORD dwPID; // 进程ID
DWORD dwPPID; // 父进程ID
DWORD dwState; // 进程状态
CHAR szName[16]; // 进程名称,最长为15个字符(不含空字符)
CHAR szNameLong[64]; // 进程完整名称,最长为63个字符(不含空字符)
ULONG64 paDTB; // 进程页目录表的物理地址
ULONG64 paDTB_UserOpt; // 可能不存在,表示用户模式页目录表的物理地址
struct {
ULONG64 vaEPROCESS; // EPROCESS结构的虚拟地址
ULONG64 vaPEB; // PEB结构的虚拟地址
ULONG64 _Reserved1; // 保留字段
BOOL fWow64; // 进程是否是32位应用程序(只有在64位系统上才有)
DWORD vaPEB32; // 32位应用程序的PEB结构虚拟地址(只有在64位系统上才有)
DWORD dwSessionId; // 进程所属会话ID
ULONG64 qwLUID; // 进程所属用户的唯一标识符
CHAR szSID[MAX_PATH]; // 进程所属用户的安全标识符(SID)
VMMDLL_PROCESS_INTEGRITY_LEVEL IntegrityLevel; // 进程完整性级别,使用VMMDLL_PROCESS_INTEGRITY_LEVEL枚举类型表示
} win;
} VMMDLL_PROCESS_INFORMATION, *PVMMDLL_PROCESS_INFORMATION;

这是一个定义了进程信息的结构体。其中包括了进程的基本信息和其他一些详细信息,如进程的内存模型类型、系统类型、进程名称等。

typedef struct tdVMMDLL_MAP_MODULEENTRY {
QWORD vaBase; // 模块基址的虚拟地址
QWORD vaEntry; // 模块入口点的虚拟地址
DWORD cbImageSize; // 模块在内存中的映像大小
BOOL fWoW64; // 模块是否为32位应用程序(只有在64位系统上才有)
union { LPSTR uszText; LPWSTR wszText; }; // 模块名称,使用LPSTR或LPWSTR表示(取决于编译选项)
DWORD _Reserved3; // 保留字段
DWORD _Reserved4; // 保留字段
union { LPSTR uszFullName; LPWSTR wszFullName; }; // 模块完整路径,使用LPSTR或LPWSTR表示(取决于编译选项)
VMMDLL_MODULE_TP tp; // 模块类型,使用VMMDLL_MODULE_TP枚举类型表示
DWORD cbFileSizeRaw; // 模块文件大小
DWORD cSection; // 模块的节数
DWORD cEAT; // 导出函数表的数量(Export Address Table)
DWORD cIAT; // 导入函数表的数量(Import Address Table)
DWORD _Reserved2; // 保留字段
QWORD _Reserved1[3]; // 保留字段
PVMMDLL_MAP_MODULEENTRY_DEBUGINFO pExDebugInfo; // 扩展调试信息,仅在指定了VMMDLL_MODULE_FLAG_DEBUGINFO标志时包含
PVMMDLL_MAP_MODULEENTRY_VERSIONINFO pExVersionInfo; // 扩展版本信息,仅在指定了VMMDLL_MODULE_FLAG_VERSIONINFO标志时包含
} VMMDLL_MAP_MODULEENTRY, *PVMMDLL_MAP_MODULEENTRY;

这是一个定义了模块信息的结构体。其中包括了模块的基本信息和其他一些详细信息,如模块的名称、完整路径、大小等。需要注意的是,该结构体中的某些字段可能仅适用于特定的操作系统平台或CPU体系结构。同时,该结构体中还包括了扩展的调试和版本信息,只有在指定了相应的编译选项时才会包含。

该代码主要用于演示在Windows操作系统上使用VMM库进行进程和内存的监视和调试,仅供学习和参考目的。在实际使用时,应遵循相关法规,并确保以安全的方式使用该功能!

如果您喜欢本站,点击这儿不花一分钱捐赠本站

这些信息可能会帮助到你: 下载帮助 | 报毒说明 | 进站必看

修改版本安卓软件,加群提示为修改者自留,非本站信息,注意鉴别

(1)
上一篇 2023年8月4日 上午10:49
下一篇 2023年8月4日 上午11:01

相关推荐

发表回复

评论问题之前,点击我,能帮你解决大部分问题

您的电子邮箱地址不会被公开。 必填项已用*标注