基于Intel Pin修改SYSTEM_PROCESS_INFO中cmd.exe名称触发访问错误求助
问题分析与解决思路
1. 先定位0x1d访问错误的根源
访问地址0x1d属于极低内存地址,几乎可以确定是空指针加上0x1d偏移导致的非法访问。这说明你在遍历SYSTEM_PROCESS_INFO链表时,某个环节的指针处理出错,或者修改进程名时破坏了链表结构/相邻内存字段。
2. 修正链表遍历逻辑
SYSTEM_PROCESS_INFO的链表依赖NextEntryOffset字节偏移推进,必须严格遵守以下规则:
- 下一个节点的计算必须用
(PSYSTEM_PROCESS_INFO)((BYTE*)currentEntry + currentEntry->NextEntryOffset),不能直接用指针加法(指针大小偏移)。 - 遍历终止条件必须是
currentEntry->NextEntryOffset == 0,不能靠指针是否为空判断。 - 确保你使用的是32位版本的
SYSTEM_PROCESS_INFO结构定义,Wow64环境下32位进程调用NtQuerySystemInformation返回的是32位结构,禁止混用64位结构。
3. 修复进程名修改的内存问题
直接修改ImageName.Buffer容易触发权限错误或内存溢出:
- 内存权限问题:
ImageName.Buffer指向的系统内存默认是只读的,修改前必须先调整权限:DWORD oldProtect; // 申请足够覆盖新字符串的可写权限(包含终止符) VirtualProtect(entry->ImageName.Buffer, entry->ImageName.Length + sizeof(WCHAR), PAGE_READWRITE, &oldProtect); // 用PIN_SafeCopy确保写入长度不越界 PIN_SafeCopy(entry->ImageName.Buffer, L"abc.exe", min(sizeof(L"abc.exe"), entry->ImageName.Length)); // 恢复原权限 VirtualProtect(entry->ImageName.Buffer, entry->ImageName.Length + sizeof(WCHAR), oldProtect, &oldProtect); - 长度溢出问题:新字符串的字节数必须严格小于等于
entry->ImageName.Length,否则会覆盖NextEntryOffset等关键字段,直接导致后续遍历出现空指针偏移错误。
4. Wow64环境下的拦截注意事项
32位Pin在64位系统插装32位程序时:
- 确保拦截的是32位NTDLL导出的
NtQuerySystemInformation,Pin会自动处理,但要避免误操作64位内核结构。 - 所有指针操作必须基于32位地址空间,禁止直接访问64位内存区域。
5. 更可靠的进程隐藏方案(替代修改名称)
修改名称容易引发内存问题,建议直接从链表中移除目标节点:
- 遍历链表时记录前一个节点
prevEntry,当匹配到cmd.exe时,将prevEntry->NextEntryOffset += currentEntry->NextEntryOffset,跳过当前节点。 - 这种方式仅调整链表偏移,无需修改任何内存内容,彻底规避权限和溢出风险。
内容的提问来源于stack exchange,提问作者Claire Robbie
相关产品推荐
相关产品推荐

