1 进程的创建过程

打开系统 --> 双击要运行的程序 --> EXE开始执行

步骤一:

当系统启动后,创建一个进程:Explorer.exe(也就是桌面进程)

步骤二:

当用户双击某一个EXE时,Explorer 进程使用CreateProcess函数创建被双击的EXE,也就是说,我们在桌面上双

击创建的进程都是Explorer进程的子进程.

CreateProcess

  1. BOOL CreateProcess(
  2. LPCTSTR lpApplicationName, // name of executable module
  3. LPTSTR lpCommandLine, // command line string
  4. LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
  5. LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
  6. BOOL bInheritHandles, // handle inheritance option
  7. DWORD dwCreationFlags, // creation flags
  8. LPVOID lpEnvironment, // new environment block
  9. LPCTSTR lpCurrentDirectory, // current directory name
  10. LPSTARTUPINFO lpStartupInfo, // startup information
  11. LPPROCESS_INFORMATION lpProcessInformation // process information
  12. );

1 创建内核对象

2 分配4GB的虚拟空间(Windows 32位)

3 创建进程的主线程

当进程的空间创建完毕,EXE与导入表中的DLL都正确加载完毕后,会创建一个线程。

当线程得到CPU的时候,程序就正开始指向了,EIP的初始值设定为:ImageBase+OEP。

  1. HANDLE CreateThread(
  2. PSECURITY_ATTRIBUTES psa,
  3. DWORD cbStack,
  4. PTHREAD_START_ROUTINE pfnStartAddr,
  5. PVOID pvParam,
  6. DWORD fdwCreate,
  7. PDWORD pdwThreadID);

当进程创建成功后,会将进程句柄、主线程句柄、进程ID以及主线程ID存储在下面结构中:

  1. typedef struct _PROCESS_INFORMATION
  2. {
  3. HANDLE hProcess; //进程句柄
  4. HANDLE hThread; //主线程句柄
  5. DWORD dwProcessId; //进程ID
  6. DWORD dwThreadId; //线程ID
  7. } PROCESS_INFORMATION;

也就是,CreateProcess的最后一个 OUT 参数

到此,整个进程创建结束了.

关于句柄和ID

1、都是系统分配的一个编号,句柄是客户程序使用 ID主要是系统调度时使用.

2、调用CloseHandle关闭进程或者线程句柄的时候,只是让内核计数器减少一个,并不是终止进程或者线程.进程或线程将继续运行,直到它自己终止运行。

3、进程ID与线程ID 是不可能相同。但不要通过进程或者线程的ID来操作进程或者线程,因为,这个编号是会重复使用的,也就是说,当你通过ID=100这个编号去访问一个进程的时候,它已经结束了,而且系统将这个编号赋给了另外一个进程或者线程.

2 进程终止

2.1 进程终止的三种方式:

  1. VOID ExitProcess(UINT fuExitCode) //进程自己调用
  2. BOOL TerminateProcess(HANDLE hProcess, UINT fuExitCode); //终止其他进程
  3. ExitThread //终止进程中的所有线程,进程也会终止

2.2 获取进程的退出码:

  1. BOOL GetExitCodeProcess(HANDLE hProcess,PDWORD pdwExitCode);

进程终止时相关操作:

1、进程中剩余的所有线程全部终止运行

2、进程指定的所有用户对象均被释放,所有内核对象均被关闭

3、进程内核对象的状态变成收到通知的状态

4、进程内核对象的使用计数递减1

3 句柄的继承

3.1 命令行参数的使用

  1. char szBuffer[256] = {0};
  2. memcpy(szBuffer,argv[1],8);
  3. DWORD dwHandle = 0;
  4. sscanf(szBuffer,"%x",&dwHandle);
  5. printf("%s\n",argv[0]);
  6. printf("%x\n",dwHandle);
  7. getchar();

3.2 句柄的继承

进程A中的代码:

  1. char szBuffer[256] = {0};
  2. char szHandle[8] = {0};
  3. //若要创建能继承的句柄,父进程必须指定一个SECURITY_ATTRIBUTES结构并对它进行初始化
  4. //三个成员的意义:大小、默认安全属性、是否可以继承
  5. SECURITY_ATTRIBUTES sa;
  6. sa.nLength = sizeof(sa);
  7. sa.lpSecurityDescriptor = NULL;
  8. sa.bInheritHandle = TRUE;
  9. //创建一个可以被继承的内核对象
  10. HANDLE g_hEvent = CreateEvent(&sa, TRUE, FALSE, NULL);
  11. //组织命令行参数
  12. sprintf(szHandle,"%x",g_hEvent);
  13. sprintf(szBuffer,"C:/z2.exe %s",szHandle);
  14. //定义创建进程需要用的结构体
  15. STARTUPINFO si = {0};
  16. PROCESS_INFORMATION pi;
  17. si.cb = sizeof(si);
  18. //创建子进程
  19. BOOL res = CreateProcess(
  20. NULL,
  21. szBuffer,
  22. NULL,
  23. NULL,
  24. TRUE,
  25. CREATE_NEW_CONSOLE,
  26. NULL,
  27. NULL, &si, &pi);
  28. //设置事件为已通知
  29. SetEvent(g_hEvent);
  30. //关闭句柄 内核对象是否会被销毁?
  31. CloseHandle(g_hEvent);

进程B中的代码:

  1. char szBuffer[256] = {0};
  2. memcpy(szBuffer,argv[1],8);
  3. DWORD dwHandle = 0;
  4. sscanf(szBuffer,"%x",&dwHandle);
  5. printf("%s\n",argv[0]);
  6. printf("%x\n",dwHandle);
  7. HANDLE g_hEvent = (HANDLE)dwHandle;
  8. printf("开始等待.....\n");
  9. WaitForSingleObject(g_hEvent, INFINITE); //当事件变成已通知时
  10. DWORD dwCode = GetLastError();
  11. printf("等到消息.....%x\n",dwCode);
  12. getchar();

4 以挂起方式创建进程

4.1 以挂起的方式创建进程,观察创建后的结果

  1. STARTUPINFO ie_si = {0};
  2. PROCESS_INFORMATION ie_pi;
  3. ie_si.cb = sizeof(ie_si);
  4. TCHAR szBuffer[256] = "C:\\notepad.exe";
  5. CreateProcess(
  6. NULL,
  7. szBuffer,
  8. NULL,
  9. NULL,
  10. FALSE,
  11. CREATE_SUSPENDED,
  12. NULL,
  13. NULL,
  14. &ie_si,
  15. &ie_pi
  16. );
  17. //恢复执行
  18. ResumeThread(ie_pi.hThread);

4.2 以挂起的方式创建进程,获取进程的ImageBase和AddressOfEntryPoint

  1. STARTUPINFO ie_si = {0};
  2. PROCESS_INFORMATION ie_pi;
  3. ie_si.cb = sizeof(ie_si);
  4. //以挂起的方式创建进程
  5. TCHAR szBuffer[256] = "C:\\ipmsg.exe";
  6. CreateProcess(
  7. NULL, // name of executable module
  8. szBuffer, // command line string
  9. NULL,
  10. NULL,
  11. FALSE, // handle inheritance option
  12. CREATE_SUSPENDED, // creation flags
  13. NULL, // new environment block
  14. NULL, // current directory name
  15. &ie_si, // startup information
  16. &ie_pi // process information
  17. );
  18. //获取外壳程序的入口点
  19. CONTEXT contx;
  20. contx.ContextFlags = CONTEXT_FULL;
  21. GetThreadContext(ie_pi.hThread, &contx); //将ipmsg.exe的线程句柄写到contx中
  22. //获取入口点
  23. DWORD dwEntryPoint = contx.Eax;
  24. //获取ImageBase
  25. char* baseAddress = (CHAR *) contx.Ebx+8;
  26. memset(szBuffer,0,256);
  27. ReadProcessMemory(ie_pi.hProcess,baseAddress,szBuffer,4,NULL); //参数:要读的进程,从哪里开始读,存放到哪里,大小是多少,[out]真正读了多少个字节
  28. ResumeThread(ie_pi.hThread);

零基础逆向工程39_Win32_13_进程创建_句柄表_挂起方式创建进程的更多相关文章

  1. 零基础逆向工程25_C++_02_类的成员权限_虚函数_模板

    1 类的成员权限 1.1 小结: 1.对外提供的函数或者变量,发布成public的 但不能随意改动. 2.可能会变动的函数或者变量,定义成private的 这样编译器会在使用的时候做检测. 3.只有结 ...

  2. 零基础逆向工程23_PE结构07_重定位表_IAT表(待补充)

    重定位表 待补充 IAT表 待补充

  3. 零基础逆向工程20_PE结构04_任意节空白区_新增节_扩大节添加代码

    向代码节添加代码实现 作者经过一周不断的失败,再思考以及无数次调试终于实现. 思路:八个步骤 1. 文件拷到文件缓冲区(FileBuffer) //图示见(零基础逆向工程18之PE加载过程) 2. 文 ...

  4. 【布艺DIY】 零基础 做包包 2小时 就OK!_豆瓣

    [布艺DIY] 零基础 做包包 2小时 就OK!_豆瓣 [布艺DIY] 零基础 做包包 2小时 就OK!

  5. EPROCESS 进程/线程优先级 句柄表 GDT LDT 页表 《寒江独钓》内核学习笔记(2)

    在学习笔记(1)中,我们学习了IRP的数据结构的相关知识,接下来我们继续来学习内核中很重要的另一批数据结构: EPROCESS/KPROCESS/PEB.把它们放到一起是因为这三个数据结构及其外延和w ...

  6. win32进程概念之句柄表,以及内核对象.

    句柄表跟内核对象 一丶什么是句柄表什么是内核对象. 1.句柄表的生成 我们知道.我们使用CreateProcess 的时候会返回一个进程句柄.以及线程句柄. 其实在调用CreateProcess的时候 ...

  7. 零基础逆向工程36_Win32_10_互斥体_互斥体与临界区的区别

    1 引言 讲了第二个内核对象,互斥体.前面已经学过一个内核对象,线程.这节讲两个函数,WaitForSingleObject()和WaitForMultipleObjects().因此这两个函数是根据 ...

  8. 零基础逆向工程28_Win32_02_事件_消息_消息处理函数

    1 第一个图形界面程序 步骤1:创建Windows应用程序 选择空项目 步骤2:在新建项窗口中选C++代码文件 创建一个新的cpp文件 步骤3:在新的cpp文件中添加:#include <Win ...

  9. salesforce零基础学习(一百一十一)custom metadata type数据获取方式更新

    本篇参考: https://developer.salesforce.com/docs/atlas.en-us.234.0.apexref.meta/apexref/apex_methods_syst ...

随机推荐

  1. Java——事务

    一.事务(Transaction) 1. 在开发中我们的一个业务往往需要同时操作多个表,这些操作往往是不可分割,业务中的对数据库的多次操作,要么同时成功,要么全都失败. 2.注意:我们在同一个事务中使 ...

  2. loj #6261 一个人的高三楼 FFT + 组合数递推

    \(\color{#0066ff}{ 题目描述 }\) 一天的学习快要结束了,高三楼在晚自习的时候恢复了宁静. 不过,\(HSD\) 桑还有一些作业没有完成,他需要在这个晚自习写完.比如这道数学题: ...

  3. P2866 [USACO06NOV]糟糕的一天Bad Hair Day

    题意:给你一个序列,问将序列倒过来后,对于每个点,在再碰到第一个比它大的点之前,有多少比它小的? 求出比它小的个数的和 样例: 610374122 output: 5 倒序后:2    12    4 ...

  4. 10.20 olinr

    感谢olinr提供md文件 免得我整理格式了 1.求助 (help.cpp/c/pas) [问题背景] 马上就要noip了,lrt同志\(\displaystyle\begin{vmatrix}\te ...

  5. Jenkins+Git+Maven+Nexus+Tomcat

    https://www.jianshu.com/p/d24e64559440 https://blog.csdn.net/u013322876/article/details/72637854 htt ...

  6. PXE刷机,存储节点失败

    最近刚刚帮客户对一台满配的X6-2刷机初始化,尝试了下PXE方式,但刷完机后,发现计算节点的imagehistory输出的状态都是成功的,而所有的存储节点状态都为failure,具体如下: [root ...

  7. IIS Express被局域网访问

    在 文件夹 C:\Users\administrator\Documents\IISExpress\config 下面 applicationhost.config 文件里 找到相应的项目 如 < ...

  8. dedecms中模板函数

    下面来解说下DEDECMS织梦CMS模板里面的函数说明 在文件include/inc_function.php里面 1 2 GetCurUrl() 获贴切前的脚本的URL 1 2 GetAlabNum ...

  9. 权限知识中的AIX ACL

    Aix ACL是对标准权限位的扩展.通过修改分配给个人或组的标准权限,对每个文件或目录进行更精细的控制. 对每个组或用户,有3种权限分配情况: PERMIT : 准许对文件或目录的特定权限. DEMY ...

  10. Mysql5.7.20源码编译安装

    一.下载源码包 1.1 下载mysql源码包 MySQL源码,网址为:https://dev.mysql.com/downloads/mysql/ : 1.2 下载boost 下载网址为:http:/ ...