注意:本文为学习win32时所写,如有错漏,烦请指出,万分感谢
1、线程与进程是什么
①进程:所谓进程,是一个空间的概念,里面装的就是代码执行时所有所需要的资源
②线程:所谓线程,是一个动态的概念,简单来说就是跑起来的代码
所以,一个进程至少要有一个线程才是有意义的
2、进程如何创建的
分区:
空指针赋值区: 0x00000000~0x0000FFFF
用户模式区: 0x00010000~07FFEFFFF
64KB禁入区: 0x7FFF0000~0x7FFFFFFF
内核: 0x80000000~0xFFFFFFFF
我们点击的程序一般是由explorer.exe调用CreateProcess()创建的,过程如下
①、映射exe文件(将exe文件放到自己的内存)
②、创建内核对象EPROCESS在高2G
③、映射DLL文件(ntdll)
④、创建线程内核对象
⑤、系统启动线程(先映射DLL,再执行)
3、句柄是什么
我们知道,在windows上面,进程的低2G是属于自己的,高2G是属于内核的,是所有进程共享的,那么,每个进程在创建时,包括其中的线程,事件等创建时,都会建立一个内核对象在高2G,如果这时候我们要操作这些内核对象,直接将地址给进程的话,一旦地址出错,就会引发很严重的问题
所以,Windows的解决方案是成立一个句柄表,而内核对象的地址就存在句柄表中,我们要操作这些内核对象,就是要操作这些句柄
句柄表可以理解为有三列,其中第一列代表的是句柄能否被继承,第二列是句柄的ID,第三列就是句柄所对应的内核对象的地址
以下是学习时所写的代码
#include<stdio.h>
#include<windows.h>
DWORD CreateChildProcess(PTCHAR szChildProcssName, PTCHAR szCommandLine) {
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
/*
CreateProcess(
LPCTSTR lpApplicationName, //对象名称
LPTSTR lpCommandLine, //命令行参数
LPSECURITY_ATTRIBUTES lpProcessAttributes, //不允许自己的进程句柄被继承
LPSECURITY_ATTRIBUTES lpThreadAttributes, //不允许自己的线程句柄被继承
BOOL bInheritHandles, //不继承父进程可继承的句柄
DWORD dwCreationFlags, //没有创建标识
LPVOID lpEnvironment, //使用父进程环境变量
LPCTSTR lpCurrentDirectory, //使用父进程目录作为当前目录
LPSTARTUPINFO lpStartupInfo, //STARTUPINFO结构体详细信息
LPPROCESS_INFORMATION lpProcessInformation //PROCESS_INFORMATION结构体进程信息
)
DWORD dwCreationFlags:
CREATE_NEW_CONSOLE //创建新的控制台
CREATE_SUSPENDED //挂起的形式创建
*/
if (!CreateProcess(
szChildProcssName, //对象名称
szCommandLine, //命令行参数
NULL, //不允许自己的进程句柄被继承
NULL, //不允许自己的线程句柄被继承
FALSE, //不继承父进程可继承的句柄
CREATE_NEW_CONSOLE, //没有创建标识
NULL, //使用父进程环境变量
NULL, //使用父进程目录作为当前目录
&si, //STARTUPINFO结构体详细信息
&pi //PROCESS_INFORMATION结构体进程信息
)) {
printf("CreateChildProcess Error:%d\n", GetLastError());
return FALSE;
}
printf("ProcessId=%x\nThreadId=%x\nProcessHandle=%x\nThreadHandle=%x\n", pi.dwProcessId, pi.dwThreadId, pi.hProcess, pi.hThread);
SuspendThread(pi.hThread); //挂起线程
for(int i=0; i<10; i++){
Sleep(500);
printf("========\n");
}
char filePath[100];
GetModuleFileName(NULL, filePath, 100);
char workPath[100];
GetCurrentDirectory(100, workPath);
printf("模块路径:%s\n工作路径:%s\n", filePath, workPath);
ResumeThread(pi.hThread); //释放线程
//释放句柄
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return pi.dwProcessId;
}
int main(int argc, char* argv[])
{
/*
CHAR------>char
WCHAR----->wchar_t------->unsigned short
TCHAR----->一种宏,随着程序改变编码
PSTR------>char*
PWSTR----->WCHAR*
PTSTR----->一种宏,随着程序改变编码
*/
/*
int MessageBox(
窗口
HWND hWnd,
LPCTSTR TEXT,
LPCTSTR TITLE,
UINT uType,//窗口类型
)
*/
/*
TCHAR title[]=TEXT("title");
TCHAR text[]=TEXT("text");
MessageBox(0,text,title,MB_OK);
*/
/*
CreateEvent(
LPSECURITY_ATTRIBUTES, //安全描述符,不希望被继承填NULL,希望则要创建如下结构体
BOOL, //
BOOL, //
LPCTSTR, //对象名称
)
SECURITY_ATTRIBUTES sa,
ZeroMemory(&sa,sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE; //希望被继承
CreateEvent(sa,FALSE,FALSE);
*/
/*
TerminateProcess( //终止一个其他进程
HANDLE hprocess, //进程句柄
UINT uExitCode, //退出码,可以通过GetExitCodeProcess()查询到
)
OpenProcess(
Dword dwDesiredAccess, //希望拥有什么样的权力,具体查表
BOOL bInheritHandle, //是否允许子进程继承
DWORD deProcessId //进程PID
)
HANDLE hProcess;
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,0xECO);
if(!TerminateProcess(hprocess,1))
{
printf("fail to stop the process:%d\n", GetLastError());
}
*/
TCHAR szChildProcssName[] = TEXT("G://code/11.27/Debug/11.27.exe");
TCHAR szCommandLine[] = TEXT("1");
DWORD processid = CreateChildProcess(szChildProcssName, NULL);
/*
DWORD GetModuleFileName( //模块路径(自己在的地方)
HMODULE hModule, // 模块的句柄
LPTSTR lpFilename, // 模块的文件名(out)
DWORD nSize // 缓冲区的大小(in)
);
*/
char filePath[100];
GetModuleFileName(NULL, filePath, 100);
/*
DWORD GetCurrentDirectory( //工作目录(父进程的地方)
DWORD nBufferLength, // 缓冲区大小
LPTSTR lpBuffer // 缓冲区指针(out)
);
*/
char workPath[100];
int i = 100;
GetCurrentDirectory(100, workPath);
printf("模块路径:%s\n工作路径:%s\n", filePath, workPath);
//getchar();
return 0;
}