windows系统编程

进程相关基础

创建进程

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
48
49
50
51
52
53
54
55
56
57
58
59
int CreateProcessDemo()
{
/*
DWORD cb; 当前结构的大小,需要事先填充,防止后续新增字段导致结构体大小变更
LPWSTR lpReserved; 保留字段未使用
LPWSTR lpDesktop; 指定桌面名称
LPWSTR lpTitle; 控制台程序的窗口标题
DWORD dwX; 新窗口的位置信息和尺寸信息
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars; 新窗口控制台可以显示的行数和列数
DWORD dwYCountChars;
DWORD dwFillAttribute;指定控制台程序的背景颜色
DWORD dwFlags; 标志,指定当前结构的哪些成员是有效的
WORD wShowWindow; 窗口的显示方式是什么
WORD cbReserved2; 保留字段
LPBYTE lpReserved2; 保留字段
HANDLE hStdInput; 标准输入句柄
HANDLE hStdOutput; 标准输出句柄
HANDLE hStdError; 标准错误句柄
*/
STARTUPINFO StartupInfo{};
StartupInfo.cb = sizeof(StartupInfo);
PROCESS_INFORMATION ProcessInformation;
BOOL rtn = CreateProcess(
//_In_opt_ LPCWSTR lpApplicationName,
L"G:\\Tools\\Layer5.0SAINTSEC\\Layer.exe",//想要执行的程序路径
//_Inout_opt_ LPWSTR lpCommandLine,
NULL,//要传递给可执行模块的参数
//_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
NULL,//进程安全属性,如果是NULLL则使用默认的安全属性
//_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
NULL,//线程安全属性,如果是NULLL则使用默认的安全属性
//_In_ BOOL bInheritHandles,
FALSE,//指定了当前进程中的可继承句柄是否可以被启动的新进程所继承
//_In_ DWORD dwCreationFlags,
0,//指定新进程的优先级和创建标志
//_In_opt_ LPVOID lpEnvironment,
NULL,//指定新进程使用的环境变量
//_In_opt_ LPCWSTR lpCurrentDirectory,
NULL,//指定新进程使用的当前目录
//_In_ LPSTARTUPINFOW lpStartupInfo,
&StartupInfo,//启动信息
//_Out_ LPPROCESS_INFORMATION lpProcessInformation
&ProcessInformation //进程相关信息
);
if (!rtn) {
printf("Create Process Field!");
}
else {
printf("dwProcessId:\t%d\n", ProcessInformation.dwProcessId);
printf("dwThreadId:\t%d\n", ProcessInformation.dwThreadId);
printf("hProcess:\t%d\n", ProcessInformation.hProcess);
printf("hThread:\t%d\n", ProcessInformation.hThread);
}
system("pause");
return 0;
}

退出进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//退出当前进程,参数为退出码
ExitProcess(0);
//打开一个进程并退出
void TerminateProcessDemo() {
HANDLE hProcess = OpenProcess(
//_In_ DWORD dwDesiredAccess,
PROCESS_ALL_ACCESS,//权限
//_In_ BOOL bInheritHandle,
FALSE,//返回的句柄是否可以继承
//_In_ DWORD dwProcessId
9940//打开进程的唯一标识符,进程ID
);
if (hProcess==INVALID_HANDLE_VALUE){
printf("Open Process Field!\n");
}else{
TerminateProcess(hProcess,9940);
}
}

遍历进程

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
void traversalProcessDemo() {
/*
#define TH32CS_SNAPHEAPLIST 0x00000001 堆 需要指定第二个参数中的进程ID
#define TH32CS_SNAPPROCESS 0x00000002 进程 不需要指定第二个参数中的进程ID
#define TH32CS_SNAPTHREAD 0x00000004 线程 需要指定第二个参数中的进程ID
#define TH32CS_SNAPMODULE 0x00000008 模块 需要指定第二个参数中的进程ID
*/
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
/*
DWORD dwSize; 本结构的尺寸
DWORD cntUsage; 当前的引用计数
DWORD th32ProcessID; 进程的ID
ULONG_PTR th32DefaultHeapID; 当前进程的默认堆的ID
DWORD th32ModuleID; 模块ID
DWORD cntThreads; 当前进程的线程总数
DWORD th32ParentProcessID; 父进程ID
LONG pcPriClassBase; 当前进程创建的线程的基本优先级
DWORD dwFlags; 标志位
WCHAR szExeFile[MAX_PATH]; 进程对应的文件名
*/
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
bool rtn = Process32First(hSnapshot, &pe32);
while (rtn){
wprintf(L"ProcessName:%s\n", pe32.szExeFile);
printf("ProcessID:%d\n", pe32.th32ProcessID);
printf("------------------------\n");
rtn = Process32Next(hSnapshot, &pe32);
}
}

线程相关基础

创建线程,等待线程

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
48
49
50
51
52
53
DWORD ThreadCallBackA(LPVOID lpThreadParameter) {
for (int i = 0; i < 100000; i++) {
printf("Thread A Output %d\n", i);
}
return 0;
}
DWORD ThreadCallBackB(LPVOID lpThreadParameter) {
for (int i = 0; i < 100000; i++) {
printf("Thread B Output %d\n", i);
}
return 0;
}
int main() {
//-------------以下为线程A------------------
DWORD lpThreadIdA=0;
HANDLE hThreadA = CreateThread(
//_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
NULL,//安全属性
//_In_ SIZE_T dwStackSize,
NULL,//堆栈的初始大小
//_In_ LPTHREAD_START_ROUTINE lpStartAddress,
(LPTHREAD_START_ROUTINE)ThreadCallBackA,//线程启动地址,函数地址,也可以理解为开启一个新的线程去调用该函数
//_In_opt_ __drv_aliasesMem LPVOID lpParameter,
NULL,//线程函数的参数
//_In_ DWORD dwCreationFlags,
NULL,//启动标记,0x0为直接运行,0x4(CREATE_SUSPENDED)为挂起运行
//_Out_opt_ LPDWORD lpThreadId
&lpThreadIdA
);
//等待线程
WaitForSingleObject(hThreadA, INFINITE);
//-------------以下为线程B------------------
DWORD lpThreadIdB = 0;
HANDLE hThreadB = CreateThread(
//_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
NULL,//安全属性
//_In_ SIZE_T dwStackSize,
NULL,//堆栈的初始大小
//_In_ LPTHREAD_START_ROUTINE lpStartAddress,
(LPTHREAD_START_ROUTINE)ThreadCallBackB,//线程启动地址,函数地址,也可以理解为开启一个新的线程去调用该函数
//_In_opt_ __drv_aliasesMem LPVOID lpParameter,
NULL,//线程函数的参数
//_In_ DWORD dwCreationFlags,
NULL,//启动标记,0x0为直接运行,0x4(CREATE_SUSPENDED)为挂起运行
//_Out_opt_ LPDWORD lpThreadId
&lpThreadIdB
);
WaitForSingleObject(hThreadB, INFINITE);
for (int i = 0; i < 100000; i++) {
printf("main Output %d\n", i);
}
return 0;
}

遍历线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void TraversalThreadDemo() {
DWORD dwProcessID = 10204;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID);
THREADENTRY32 te32;
te32.dwSize = sizeof(te32);
BOOL rtn = Thread32First(hSnapshot, &te32);
while (rtn) {
if (te32.th32OwnerProcessID == dwProcessID) {
printf("ThreadID: % d\n", te32.th32ThreadID);
printf("OwnerProcessID: % d\n", te32.th32OwnerProcessID);
printf("BasePri: % d\n", te32.tpBasePri);
printf("---------------------------------------\n");
}
rtn = Thread32Next(hSnapshot, &te32);
}
}

结束线程,挂起线程,恢复线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void TraversalThreadDemo() {
DWORD dwProcessID = 24848;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID);
THREADENTRY32 te32;
te32.dwSize = sizeof(te32);
BOOL rtn = Thread32First(hSnapshot, &te32);
while (rtn) {
if (te32.th32OwnerProcessID == dwProcessID) {
printf("ThreadID: % d\n", te32.th32ThreadID);
printf("OwnerProcessID: % d\n", te32.th32OwnerProcessID);
printf("BasePri: % d\n", te32.tpBasePri);
printf("---------------------------------------\n");
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);
//结束线程
TerminateThread(hThread, -1);
//挂起线程
//SuspendThread(hThread);
//恢复线程
//ResumeThread(hThread);
}
rtn = Thread32Next(hSnapshot, &te32);
}
}

完整代码:

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <stdio.h>
#include <Windows.h>
#include <tlhelp32.h>
int CreateProcessDemo()
{
/*
DWORD cb; 当前结构的大小,需要事先填充,防止后续新增字段导致结构体大小变更
LPWSTR lpReserved; 保留字段未使用
LPWSTR lpDesktop; 指定桌面名称
LPWSTR lpTitle; 控制台程序的窗口标题
DWORD dwX; 新窗口的位置信息和尺寸信息
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars; 新窗口控制台可以显示的行数和列数
DWORD dwYCountChars;
DWORD dwFillAttribute;指定控制台程序的背景颜色
DWORD dwFlags; 标志,指定当前结构的哪些成员是有效的
WORD wShowWindow; 窗口的显示方式是什么
WORD cbReserved2; 保留字段
LPBYTE lpReserved2; 保留字段
HANDLE hStdInput; 标准输入句柄
HANDLE hStdOutput; 标准输出句柄
HANDLE hStdError; 标准错误句柄
*/
STARTUPINFO StartupInfo{};
StartupInfo.cb = sizeof(StartupInfo);
PROCESS_INFORMATION ProcessInformation;
BOOL rtn = CreateProcess(
//_In_opt_ LPCWSTR lpApplicationName,
L"G:\\Tools\\Layer5.0SAINTSEC\\Layer.exe",//想要执行的程序路径
//_Inout_opt_ LPWSTR lpCommandLine,
NULL,//要传递给可执行模块的参数
//_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
NULL,//进程安全属性,如果是NULLL则使用默认的安全属性
//_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
NULL,//线程安全属性,如果是NULLL则使用默认的安全属性
//_In_ BOOL bInheritHandles,
FALSE,//指定了当前进程中的可继承句柄是否可以被启动的新进程所继承
//_In_ DWORD dwCreationFlags,
0,//指定新进程的优先级和创建标志
//_In_opt_ LPVOID lpEnvironment,
NULL,//指定新进程使用的环境变量
//_In_opt_ LPCWSTR lpCurrentDirectory,
NULL,//指定新进程使用的当前目录
//_In_ LPSTARTUPINFOW lpStartupInfo,
&StartupInfo,//启动信息
//_Out_ LPPROCESS_INFORMATION lpProcessInformation
&ProcessInformation //进程相关信息
);
if (!rtn) {
printf("Create Process Field!");
}
else {
printf("dwProcessId:\t%d\n", ProcessInformation.dwProcessId);
printf("dwThreadId:\t%d\n", ProcessInformation.dwThreadId);
printf("hProcess:\t%d\n", ProcessInformation.hProcess);
printf("hThread:\t%d\n", ProcessInformation.hThread);
}
system("pause");
return 0;
}
void TerminateProcessDemo() {
HANDLE hProcess = OpenProcess(
//_In_ DWORD dwDesiredAccess,
PROCESS_ALL_ACCESS,//权限
//_In_ BOOL bInheritHandle,
FALSE,//返回的句柄是否可以继承
//_In_ DWORD dwProcessId
9940//打开进程的唯一标识符,进程ID
);
if (hProcess==INVALID_HANDLE_VALUE){
printf("Open Process Field!\n");
}else{
TerminateProcess(hProcess,9940);
}
}
void TraversalProcessDemo() {
/*
#define TH32CS_SNAPHEAPLIST 0x00000001 堆 需要指定第二个参数中的进程ID
#define TH32CS_SNAPPROCESS 0x00000002 进程 不需要指定第二个参数中的进程ID
#define TH32CS_SNAPTHREAD 0x00000004 线程 需要指定第二个参数中的进程ID
#define TH32CS_SNAPMODULE 0x00000008 模块 需要指定第二个参数中的进程ID
*/
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
/*
DWORD dwSize; 本结构的尺寸
DWORD cntUsage; 当前的引用计数
DWORD th32ProcessID; 进程的ID
ULONG_PTR th32DefaultHeapID; 当前进程的默认堆的ID
DWORD th32ModuleID; 模块ID
DWORD cntThreads; 当前进程的线程总数
DWORD th32ParentProcessID; 父进程ID
LONG pcPriClassBase; 当前进程创建的线程的基本优先级
DWORD dwFlags; 标志位
WCHAR szExeFile[MAX_PATH]; 进程对应的文件名
*/
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
bool rtn = Process32First(hSnapshot, &pe32);
while (rtn){
wprintf(L"ProcessName:%s\n", pe32.szExeFile);
printf("ProcessID:%d\n", pe32.th32ProcessID);
printf("------------------------\n");
rtn = Process32Next(hSnapshot, &pe32);
}
}


DWORD ThreadCallBackA(LPVOID lpThreadParameter) {
for (int i = 0; i < 100000; i++) {
printf("Thread A Output %d\n", i);
}
return 0;
}
DWORD ThreadCallBackB(LPVOID lpThreadParameter) {
for (int i = 0; i < 100000; i++) {
printf("Thread B Output %d\n", i);
}
return 0;
}
int CreateThreadDemo() {
//-------------以下为线程A------------------
DWORD lpThreadIdA=0;
HANDLE hThreadA = CreateThread(
//_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
NULL,//安全属性
//_In_ SIZE_T dwStackSize,
NULL,//堆栈的初始大小
//_In_ LPTHREAD_START_ROUTINE lpStartAddress,
(LPTHREAD_START_ROUTINE)ThreadCallBackA,//线程启动地址,函数地址,也可以理解为开启一个新的线程去调用该函数
//_In_opt_ __drv_aliasesMem LPVOID lpParameter,
NULL,//线程函数的参数
//_In_ DWORD dwCreationFlags,
NULL,//启动标记,0x0为直接运行,0x4(CREATE_SUSPENDED)为挂起运行
//_Out_opt_ LPDWORD lpThreadId
&lpThreadIdA
);
//等待线程
WaitForSingleObject(hThreadA, INFINITE);
//-------------以下为线程B------------------
DWORD lpThreadIdB = 0;
HANDLE hThreadB = CreateThread(
//_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
NULL,//安全属性
//_In_ SIZE_T dwStackSize,
NULL,//堆栈的初始大小
//_In_ LPTHREAD_START_ROUTINE lpStartAddress,
(LPTHREAD_START_ROUTINE)ThreadCallBackB,//线程启动地址,函数地址,也可以理解为开启一个新的线程去调用该函数
//_In_opt_ __drv_aliasesMem LPVOID lpParameter,
NULL,//线程函数的参数
//_In_ DWORD dwCreationFlags,
NULL,//启动标记,0x0为直接运行,0x4(CREATE_SUSPENDED)为挂起运行
//_Out_opt_ LPDWORD lpThreadId
&lpThreadIdB
);
WaitForSingleObject(hThreadB, INFINITE);
for (int i = 0; i < 100000; i++) {
printf("main Output %d\n", i);
}
return 0;
}

void TraversalThreadDemo() {
DWORD dwProcessID = 24848;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID);
THREADENTRY32 te32;
te32.dwSize = sizeof(te32);
BOOL rtn = Thread32First(hSnapshot, &te32);
while (rtn) {
if (te32.th32OwnerProcessID == dwProcessID) {
printf("ThreadID: % d\n", te32.th32ThreadID);
printf("OwnerProcessID: % d\n", te32.th32OwnerProcessID);
printf("BasePri: % d\n", te32.tpBasePri);
printf("---------------------------------------\n");
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);
//结束线程
TerminateThread(hThread, -1);
//挂起线程
//SuspendThread(hThread);
//ResumeThread(hThread);
}
rtn = Thread32Next(hSnapshot, &te32);
}
}
int main() {
TraversalThreadDemo();
}