终止进程
终止进程会导致以下情况:
- 进程打开的所有对象句柄均已关闭。
- 进程中的所有线程均终止其执行。
- 进程对象的状态被发出信号,满足了一直在等待进程终止的所有线程。
- 进程中所有线程的状态都将发出信号,满足所有一直在等待线程终止的线程。
- 流程的终止状态从STILL_ACTIVE更改为流程的退出值。
ExitProcess
终止当前进程及其所有线程。
ExitProcess是结束进程的首选方法。VOID ExitProcess(
UINT uExitCode // exit code for all threads
);
此功能提供了干净的进程关闭。
这包括调用所有附加的动态链接库(DLL)的入口点函数,该值指示该进程正在从DLL分离。
如果某个进程通过调用TerminateProcess终止,则不会通知该进程所连接的DLL进程终止。
所有附加的DLL执行完任何进程终止值后,此函数将终止当前进程TerminateProcess
终止指定的进程及其所有线程。
TerminateProcess函数用于无条件地导致进程退出。仅在极端情况下使用。BOOL TerminateProcess(
HANDLE hProcess, // 进程句柄,句柄必须具有PROCESS_TERMINATE访问权限。
UINT uExitCode // 指定该进程以及由于此调用而终止的所有线程的退出码。
// 使用GetExitCodeProcess函数检索进程的退出值。
// 使用GetExitCodeThread函数检索线程的退出值
);
如果使用TerminateProcess而不是ExitProcess,则可能损害由动态链接库(DLL)维护的全局数据的状态。
TerminateProcess导致进程中的所有线程终止,并导致进程退出,但未通知该进程所连接的DLL正在终止。
调用示例:DWORD dwPid = 0;
GetWindowThreadProcessId(hWnd, &dwPid);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
TerminateProcess(hProcess, -1);
获取进程模块名
GetModuleBaseName
DWORD GetModuleBaseName(
HANDLE hProcess, // 进程句柄
HMODULE hModule, // 模块句柄
LPTSTR lpBaseName, // 接收基名称的缓冲区
DWORD nSize // 缓冲区大小
);
获取进程id(pid), 线程id(tid)
GetCurrentProcessId
返回当前进程的pid。无参数
DWORD GetCurrentProcessId();
GetWindowThreadProcessId
获取创建指定窗口的tid和pid
DWORD dwPid = 0;
DWORD ndThreadId = GetWindowThreadProcessId(hwnd, &dwPid);
tid, pid = GetWindowThreadProcessId(hwnd)
获取进程句柄(hProcess)
GetCurrentProcess
返回当前进程的句柄
注: 其实当前进程句柄直接用(HANDLE)-1
这个伪句柄即可, 代表是当前进程句柄. 没必要调用这个函数
OpenProcess
OpenProcess根据指定的pid获取hProcess,打开一个已存在的进程对象,并返回进程的句柄。
HANDLE OpenProcess(
DWORD dwDesiredAccess; // 想得到的访问权限,一般是 PROCESS_ALL_ACCESS 等
BOOL bInheritHandle; // 指定返回的句柄是否可以被继承
DWORD dwProcessId; // 指定要打开的进程的 PID 等
);
hProcess = OpenProcess(reqdAccess, bInherit , pid )
返回值:
- 如果函数成功,则返回值是指定进程的进程句柄hProcess。
- 如果函数失败,则返回值为NULL。
调用示例:HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwpid);
参数:
- dwDesiredAccess: 对于支持安全检查的操作系统,将针对目标进程的任何安全描述符检查此访问。
除STANDARD_RIGHTS_REQUIRED访问标志外,还可以指定以下访问标志的任意组合:
- PROCESS_ALL_ACCESS 指定进程对象的所有可能访问标志。
- PROCESS_CREATE_PROCESS 在内部使用。
- PROCESS_CREATE_THREAD 允许使用CreateRemoteThread函数中的进程句柄在进程中创建线程。
- PROCESS_DUP_HANDLE 允许使用进程句柄作为DuplicateHandle函数中的源进程或目标进程来复制句柄。
- PROCESS_QUERY_INFORMATION 允许使用GetExitCodeProcess和GetPriorityClass函数中的进程句柄从进程对象中读取信息。
- PROCESS_SET_INFORMATION 允许使用SetPriorityClass函数中的进程句柄来设置进程的优先级。
- PROCESS_TERMINATE 允许使用TerminateProcess函数中的进程句柄终止进程。
- PROCESS_VM_OPERATION 允许使用VirtualProtectEx和WriteProcessMemory函数中的进程句柄来修改进程的虚拟内存。
- PROCESS_VM_READ 允许使用ReadProcessMemory函数中的进程句柄从进程的虚拟内存中读取。
- PROCESS_VM_WRITE 允许使用WriteProcessMemory函数中的进程句柄写入进程的虚拟内存。
- SYNCHRONIZE Windows NT:允许在任何等待函数中使用进程句柄等待进程终止。
- bInheritHandle: 指定返回的句柄是否可以由当前进程创建的新进程继承。如果为TRUE,则句柄是可继承的。
- dwProcessId: 指定要打开的进程的进程标识符。
枚举指定进程的模块
EnumProcessModules
枚举指定进程的模块
BOOL EnumProcessModules(
HANDLE hProcess, // 进程句柄
HMODULE * lphModule, // 接收模块句柄的数组
DWORD cb, // 数组大小
LPDWORD lpcbNeeded // 接收返回的字节数
);
写进程内存
WriteProcessMemory
在指定的进程中写入内存。要写入的整个区域必须是可访问的,否则操作将失败。
BOOL WriteProcessMemory(
HANDLE hProcess, // 内存被写入的进程的句柄
LPVOID lpBaseAddress, // 开始写的地址
LPVOID lpBuffer, // 存放要写入的数据的缓冲区地址
DWORD nSize, // 要写入的字节数
LPDWORD lpNumberOfBytesWritten // 实际写入到缓冲区的字节数的指针。如果为空,则忽略该参数。
);
调用示例:
DWORD dwDllBase = (DWORD)GetModuleHandleA(DmDLLNAME);
byte buf[1] = {1};
WriteProcessMemory((HANDLE)-1, (void*)(dwDllBase + 1078240), buf, 1, NULL);
读进程内存
ReadProcessMemory
读取指定进程中的内存。要读取的整个区域必须是可访问的,否则操作将失败。
BOOL ReadProcessMemory(
HANDLE hProcess, // 读取内存的进程的句柄
LPCVOID lpBaseAddress, // 开始读的地址
LPVOID lpBuffer, // 存放读取数据的缓冲区地址
DWORD nSize, // 要读取的字节数
LPDWORD lpNumberOfBytesRead // 实际读取到缓冲区的字节数的指针。如果为空,则忽略该参数。
);