1 进程的创建过程
打开系统 --> 双击要运行的措施 --> EXE开始执行
法式一:
当系统启动后,创建一个进程:Explorer.exe(也就是桌面进程)
法式二:
当用户双击某一个EXE时,Explorer 进程使用CreateProcess函数创建被双击的EXE,也就是说,我们在桌面上双
击创建的进程都是Explorer进程的子进程.
CreateProcess BOOL CreateProcess( LPCTSTR lpApplicationName, // name of executable module LPTSTR lpCommandLine, // command line string LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD BOOL bInheritHandles, // handle inheritance option DWORD dwCreationFlags, // creation flags LPVOID lpEnvironment, // new environment block LPCTSTR lpCurrentDirectory, // current directory name LPSTARTUPINFO lpStartupInfo, // startup information LPPROCESS_INFORMATION lpProcessInformation // process information ); 1 创建内查东西 2 分配4GB的虚拟空间(Windows 32位) 3 创建进程的主线程当进程的空间创建完毕,EXE与导入表中的DLL都正确加载完毕后,会创建一个线程。
当线程得到CPU的时候,措施就正开始指向了,EIP的初始值设定为:ImageBase+OEP。
HANDLE CreateThread( PSECURITY_ATTRIBUTES psa, DWORD cbStack, PTHREAD_START_ROUTINE pfnStartAddr, PVOID pvParam, DWORD fdwCreate, PDWORD pdwThreadID);当进程创建告成后,会将进程句柄、主线程句柄、进程ID以及主线程ID存储不才面布局中:
typedef struct _PROCESS_INFORMATION { HANDLE hProcess; //进程句柄 HANDLE hThread; //主线程句柄 DWORD dwProcessId; //进程ID DWORD dwThreadId; //线程ID } PROCESS_INFORMATION;也就是,CreateProcess的最后一个 OUT 参数
到此,整个进程创建结束了.
关于句柄和ID1、都是系统分配的一个编号,句柄是客户措施使用 ID主要是系统调理时使用.
2、挪用CloseHandle*进程或者线程句柄的时候,只是让内核计数器减少一个,并不是终止进程或者线程.进程或线程将继续运行,直到它本身终止运行。
3、进程ID与线程ID 是不成能不异。但不要通过进程或者线程的ID来操纵进程或者线程,因为,,这个编号是会反复使用的,也就是说,当你通过ID=100这个编号去访谒一个进程的时候,它已经结束了,而且系统将这个编号赋给了此外一个进程或者线程.
VOID ExitProcess(UINT fuExitCode) //进程本身挪用 BOOL TerminateProcess(HANDLE hProcess, UINT fuExitCode); //终止其他进程 ExitThread //终止进程中的所有线程,进程也会终止
2.2 获取进程的退出码:BOOL GetExitCodeProcess(HANDLE hProcess,PDWORD pdwExitCode);
进程终止时相关操纵:
1、进程中残剩的所有线程全部终止运行
2、进程指定的所有用户东西均被释放,所有内查东西均被*
3、进程内查东西的状态酿成收到通知的状态
4、进程内查东西的使用计数递减1
进程A中的代码:
char szBuffer[256] = {0}; char szHandle[8] = {0}; //若要创建能担任的句柄,父进程必需指定一个SECURITY_ATTRIBUTES布局并对它进行初始化 //三个成员的意义:巨细、默认安适属性、是否可以担任 SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; //创建一个可以被担任的内查东西 HANDLE g_hEvent = CreateEvent(&sa, TRUE, FALSE, NULL); //组织命令行参数 sprintf(szHandle,"%x",g_hEvent); sprintf(szBuffer,"C:/z2.exe %s",szHandle); //界说创建进程需要用的布局体 STARTUPINFO si = {0}; PROCESS_INFORMATION pi; si.cb = sizeof(si); //创建子进程 BOOL res = CreateProcess( NULL, szBuffer, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); //设置事件为已通知 SetEvent(g_hEvent); //*句柄 内查东西是否会被销毁? CloseHandle(g_hEvent);进程B中的代码:
char szBuffer[256] = {0}; memcpy(szBuffer,argv[1],8); DWORD dwHandle = 0; sscanf(szBuffer,"%x",&dwHandle); printf("%s\n",argv[0]); printf("%x\n",dwHandle); HANDLE g_hEvent = (HANDLE)dwHandle; printf("开始期待.....\n"); WaitForSingleObject(g_hEvent, INFINITE); //当事件酿成已通知时 DWORD dwCode = GetLastError(); printf("等到动静.....%x\n",dwCode); getchar(); 4 以挂起方法创建进程 4.1 以挂起的方法创建进程,不雅察看创建后的功效 STARTUPINFO ie_si = {0}; PROCESS_INFORMATION ie_pi; ie_si.cb = sizeof(ie_si); TCHAR szBuffer[256] = "C:\\notepad.exe"; CreateProcess( NULL, szBuffer, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &ie_si, &ie_pi ); //恢复执行 ResumeThread(ie_pi.hThread); 4.2 以挂起的方法创建进程,获取进程的ImageBase和AddressOfEntryPoint STARTUPINFO ie_si = {0}; PROCESS_INFORMATION ie_pi; ie_si.cb = sizeof(ie_si); //以挂起的方法创建进程 TCHAR szBuffer[256] = "C:\\ipmsg.exe"; CreateProcess( NULL, // name of executable module szBuffer, // command line string NULL, NULL, FALSE, // handle inheritance option CREATE_SUSPENDED, // creation flags NULL, // new environment block NULL, // current directory name &ie_si, // startup information &ie_pi // process information ); CONTEXT contx; contx.ContextFlags = CONTEXT_FULL; GetThreadContext(ie_pi.hThread, &contx); //获取入口点 DWORD dwEntryPoint = contx.Eax; //获取ImageBase char* baseAddress = (CHAR *) contx.Ebx+8; memset(szBuffer,0,256); ReadProcessMemory(ie_pi.hProcess,baseAddress,szBuffer,4,NULL); ResumeThread(ie_pi.hThread);