Windows系统编程:跨进程使用句柄和操作内存详解
创作时间:
作者:
@小白创作中心
Windows系统编程:跨进程使用句柄和操作内存详解
引用
CSDN
1.
https://blog.csdn.net/weixin_58038441/article/details/143100414
在Windows系统编程中,跨进程使用句柄和操作内存是两个重要的技术点。本文将详细介绍如何通过继承和复制方式实现跨进程使用句柄,以及如何通过WinHex和WriteProcessMemory修改进程内存。同时,还会讲解内存属性和内存分页的相关知识。
前言
各位读者,大家好!本文将为大家讲解Windows系统编程中跨进程使用句柄和操作内存的相关知识。通过本文的学习,你将能够掌握如何在不同进程间共享句柄,以及如何通过编程方式修改其他进程的内存。
问题
让我们先抛出一个问题:进程A获得的句柄能否直接给进程B使用?
尝试通过以下代码进行实验:
// A程序
void CADlg::OnBnClickedGethandle()
{
DWORD dwPid = GetDlgItemInt(IDC_PID);
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
CString strFmt;
strFmt.Format("%08X", hProc);
SetDlgItemText(IDC_HANDLE, strFmt);
}
// B程序
void CBDlg::OnBnClickedUsehandle()
{
CString strHandle;
GetDlgItemText(IDC_HANDLE, strHandle);
HANDLE hProc = (HANDLE)strtoul(strHandle.GetBuffer(), NULL, 16);
if (TerminateProcess(hProc, 0))
{
AfxMessageBox("结束成功!");
}
else
{
AfxMessageBox("结束失败!");
}
}
实验过程:
- 结论:进程B是无法直接使用A的进程句柄的
OpenProcess
OpenProcess
函数用于打开进程对象。
HANDLE OpenProcess(
[in] DWORD dwDesiredAccess,
[in] BOOL bInheritHandle,
[in] DWORD dwProcessId
);
跨进程使用句柄
方式一:继承 - 子进程继承父进程已经打开的句柄
通过C++类来理解CreateProcess
和OpenProcess
的继承关系。
void CADlg::OnBnClickedGethandle()
{
DWORD dwPid = GetDlgItemInt(IDC_PID);
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwPid);
CString strFmt;
strFmt.Format("%08X", hProc);
SetDlgItemText(IDC_HANDLE, strFmt);
}
void CADlg::OnBnClickedCreatechild()
{
CString strPath;
GetDlgItemText(IDC_CHILD, strPath);
STARTUPINFO si = { };
si.cb = sizeof(si);
PROCESS_INFORMATION pi = { };
BOOL Ret = CreateProcess(
strPath.GetBuffer(),
NULL,
NULL,
NULL,
TRUE, // 允许子进程继承父进程的句柄
0,
NULL,
NULL,
&si,
&pi
);
if (!Ret)
{
AfxMessageBox("CreateProcess Failed!");
}
}
实验过程:
- 可以观察到通过继承的方式,成功跨进程使用句柄
- 子进程只能继承在自身被创建之前父进程打开的句柄,自身创建后父进程打开的句柄无法继承
方式二:复制句柄
使用DuplicateHandle
函数将句柄表里的句柄拷贝到对方的句柄表里。
BOOL DuplicateHandle(
[in] HANDLE hSourceProcessHandle,
[in] HANDLE hSourceHandle,
[in] HANDLE hTargetProcessHandle,
[out] LPHANDLE lpTargetHandle,
[in] DWORD dwDesiredAccess,
[in] BOOL bInheritHandle,
[in] DWORD dwOptions
);
void CADlg::OnBnClickedGethandle()
{
DWORD dwPid = GetDlgItemInt(IDC_PID);
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwPid);
HANDLE hProcSelf = GetCurrentProcess();
DWORD dwPidB = GetDlgItemInt(IDC_PID2);
HANDLE hProcB = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwPidB);
HANDLE hInB = NULL;
DuplicateHandle(hProcSelf, hProc, hProcB, &hInB, 0, FALSE, DUPLICATE_SAME_ACCESS);
CString strFmt;
strFmt.Format("%08X", hInB);
SetDlgItemText(IDC_HANDLE, strFmt);
}
实验过程:
- 适用场景:跨权限操作一些东西,比如有system权限的进程拿到句柄给管理员权限的进程用
跨进程操作内存
设计思路:通过修改进程内存地址,来修改游戏模式
通过WinHex修改内存
通过在WinHex中查找flag的位置,手动修改游戏模式
注意:当程序正在使用时,WinHex无法修改
通过WriteProcessMemory修改内存
函数原型:
BOOL WriteProcessMemory(
[in] HANDLE hProcess,
[in] LPVOID lpBaseAddress,
[in] LPCVOID lpBuffer,
[in] SIZE_T nSize,
[out] SIZE_T *lpNumberOfBytesWritten
);
示例代码:
int main()
{
HWND hWnd = FindWindow(NULL, "游戏");
DWORD dwPid;
GetWindowThreadProcessId(hWnd, &dwPid);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
LPVOID pAddr = (LPVOID)0x01B2A00B;
BYTE btCode = 0xFF;
WriteProcessMemory(hProcess, pAddr, &btCode, sizeof(btCode), NULL);
return 0;
}
- 通过
FindWindow
查找对应标题 - 从
GetWindowThreadProcessId
获取pid - 打开要写入的进程
- 写入内存
内存属性
- 内存访问属性:R读,W写,X执行,C写时拷贝。修改内存访问属性:
VirtualProtectEx
。 - ProcessHacker查看内存属性:exe双击 - Memory - Protection。
WriteProcessMemory
不用判断内存属性,每次写之前修改内存属性,写完后还原内存属性。- 写完数据不还原属性:会被检测(向只读内存写入数据,看是否触发异常,触发则表明正常)
- 内存的基本单位4k【一个分页0x1000】,所以当修改0x1225的内存属性实则修改了0x0 ~ 0x2048的内存属性
BOOL VirtualProtectEx(
HANDLE hProcess,
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flNewProtect,
PDWORD lpflOldProtect
);
参数说明:
- 参数3:修改属性的内存大小。修改内存属性会影响到这一段地址空间涉及到的所有内存分页。跨越页面边界的2字节范围会导致两个页面的保护属性都被更改。
- 参数4:内存属性
PAGE_READONLY
:只读PAGE_READWRITE
:可读可写PAGE_WRITECOPY
:写时拷贝PAGE_EXECUTE
:可执行PAGE_EXECUTE_READ
:可执行可读PAGE_EXECUTE_READWRITE
:可执行可读写PAGE_EXECUTE_WRITECOPY
:可执行可写时拷贝
内存分页
- 内存分页:大小0x1000(4096),4kb。系统管理内存的基本单位。属性改一字节影响一个分页。
- 申请内存时,系统至少分配一个分页,一个字节也分配一个分页。
new
和malloc
是在系统分配的基础上再次分配,在系统分配的分页中再次分配需要的字节。- 操作系统喜欢将统一权限属性的放在一起的原因是方便管理,且不浪费内存,也更容易维护。
总结
本文介绍了继承、复制句柄的方式跨进程使用句柄,使用WinHex、WriteProcessMemory修改内存,以及内存属性和内存分页的相关知识。这些内容对于Windows系统编程和进程间通信具有重要的参考价值。
热门推荐
考古南宋临安城:一座千年古都的历史魅力
交通事故简易处理:拨打120还是119?
辽宁自驾游:本溪枫叶&丹东银杏,你更爱哪个?
掌握交通事故简易程序,让道路更安全!
双十一期间,学会快速处理交通事故简易程序!
Excel表格间距调整:10种实用方法让你的表格整齐划一
福州南站到连江的最新交通指南
秋冬季打卡福州连江奇达村!
带团队的六个管理方法是什么?
主任科员一二三四级对应的级别是什么?
高压氧治疗:术后心理康复的新选择
高压氧治疗:职业病康复的新希望
刘传健机长亲述:高压氧治疗如何助他快速康复?
陈艺婷:亲子沟通中的倾听与提问艺术
盘点那些让人笑到肚子疼的傻狗瞬间
荷兰东印度公司的兴衰:从VOC到尘埃
荷兰东印度公司的亚洲霸业:从香料到鸦片的贸易帝国
从荷兰东印度公司看现代企业管理的那些事儿
两个人感情出问题的解决方法与建议 维护感情的有效策略与技巧
JIT让瓦楞纸板生产更高效!
糖尿病诊断标准:确定糖尿病的三个条件!2024最新血糖标准表
糖尿病的临床症状有哪些表现
不再视而不见!不宜察觉的7个糖尿病早期症状,你了解吗?
一文详解股票集合竞价:从基本概念到实战应用
无人机光纤模块:FPV穿越机通讯的超强助力
穿越机新手必看:从模拟器到真机全攻略
《春夜喜雨》古诗赏析 表达了什么思想感情
《江南逢李龟年》该如何赏析?其创作背景是什么?
无人机常用计算指标:已知两点经纬度,求解距离
未来无人机像飞鸟一样轻捷智能