跨进程使用句柄

image-20240707160013270

A进程拿到句柄,把值给B进程,B进程能不能直接使用?

继承方式

创建MFC应用

image-20240707161715301

新建按钮

image-20240707163322151

使用多字节字符集

image-20240707163259082

新建编辑框,修改ID

image-20240707163540947

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void CADlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
STARTUPINFO si;
PROCESS_INFORMATION pi;

ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

SECURITY_ATTRIBUTES sa = {};
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;//进程句柄允许被继承

//Start the child process.
if (!CreateProcess(NULL,
"B.exe",
&sa,
NULL,
TRUE,
0,
NULL,
NULL,
&si,
&pi)
)
{
AfxMessageBox(_T("CreateProcess failed"));
return;
}

CString strFmt;
strFmt.Format("08X", pi.hProcess);
SetDlgItemText(EDT_BHDANDLE, strFmt);
}

新建一个B

image-20240707164047976

和A一样的配置

image-20240707164519023

使用多字符字符集

image-20240707172120243

1
2
3
4
5
6
7
void CBDlg::OnBnClickedButton1()
{
CString str;
GetDlgItemText(EDT_BHANDLE, str);
HANDLE hBProc = (HANDLE)strtoul(str.GetBuffer(), NULL, 16);
TerminateProcess(hBProc, 0);
}

修改输出目录

image-20240707170818439

生成解决目录后在对应的文件夹中可以看到B.exe

image-20240707170956629

重新生成后运行A,然后创建一个B,会出现2E4,再创建一个B,则这个第二个B会继承这个2E4,然后在第二个B中输入2E4再结束自己可以结束第一个B的进程,但是不能结束第二个B

image-20240707193139137

image-20240707193340877

image-20240707193904517

拷贝方式

image-20240707194119208

image-20240707194202074

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
void CADlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
STARTUPINFO si;
PROCESS_INFORMATION pi;

ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

SECURITY_ATTRIBUTES sa = {};
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;//进程句柄允许被继承

//Start the child process.
if (!CreateProcess(NULL,
"B.exe",
&sa,
NULL,
TRUE,
0,
NULL,
NULL,
&si,
&pi)
)
{
AfxMessageBox(_T("CreateProcess failed"));
return;
}

//将句柄拷贝给B进程
HANDLE hBProc = NULL;
DuplicateHandle(GetCurrentProcess(), pi.hProcess,
pi.hProcess, &hBProc,
0,
FALSE,
DUPLICATE_SAME_ACCESS);//拷贝出来的句柄,与自己的权限相同

CString strFmt;
strFmt.Format("%08X", hBProc);
SetDlgItemText(EDT_BHDANDLE, strFmt);
}

运行后创建一个B,然后在新生成的B中输入4并结束自己即可结束这个B的进程

image-20240707195322159

image-20240707203433361

伪句柄

运行后创建一个B

image-20240707204425634

然后在Process Hacker中找到B的属性

image-20240707205152563

然后在B中输入8再结束自己,可以结束B的进程

image-20240707205450326

image-20240707203443118

跨进程操作内存

找不到视频中的小游戏无法时实践,所以只能截图记录大概的过程

image-20240707211440769

image-20240707212639496

使用多字符字节集

image-20240707212835941

image-20240707213928016

image-20240707215130355

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// GameHelper.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
using namespace std;
#include <windows.h>
int main()
{
HWND hWndGame = FindWindow(NULL, "xxx");
if (hWndGame == NULL)
{
cout << "获取窗口句柄失败" << endl;
return 0;
}
DWORD dwProId = 0;
DWORD dwThreadId = GetWindowThreadProcessId(hWndGame, &dwProId);
if (dwThreadId == 0)
{
cout << "获取进程id失败" << endl;
return 0;
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProId);
if (hProc == NULL)
{
cout << "获取进程句柄失败" << endl;
return 0;
}

LPVOID pAddrGod = (LPVOID)0x00400016;
BYTE bt = 0xeb;
DWORD dwOldProc = 0;
BOOL bRet = VirtualProtectEx(hProc, pAddrGod, sizeof(bt), PAGE_READWRITE, &dwOldProc);
if (!bRet)
{
cout << "修改内存属性失败" << endl;
return 0;
}
bRet = WriteProcessMemory(hProc, pAddrGod, &bt, sizeof(bt), NULL);
if (!bRet)
{
cout << "无敌失败" << endl;
}
VirtualProtectEx(hProc, pAddrGod, sizeof(bt), dwOldProc, &dwOldProc);

CloseHandle(hProc);
std::cout << "Hello World!\n";
}

若成功运行则游戏中的飞机会变成无敌