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 参数

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

关于句柄和ID

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

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

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

2 进程终止

2.1 进程终止的三种方式:

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

2.2 获取进程的退出码:

BOOL GetExitCodeProcess(HANDLE hProcess,PDWORD pdwExitCode);

进程终止时相关操作:

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

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

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

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

3 句柄的继承

3.1 命令行参数的使用

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);
getchar();

3.2 句柄的继承

进程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); //将ipmsg.exe的线程句柄写到contx中 //获取入口点
DWORD dwEntryPoint = contx.Eax; //获取ImageBase
char* baseAddress = (CHAR *) contx.Ebx+8; memset(szBuffer,0,256); ReadProcessMemory(ie_pi.hProcess,baseAddress,szBuffer,4,NULL); //参数:要读的进程,从哪里开始读,存放到哪里,大小是多少,[out]真正读了多少个字节 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. 解决织梦手机网站M文件夹动态游览不生成html

    今天的做手机网站的时候,发现dede织梦M文件夹下会生成index.html.对于手机网站来说,太麻烦了.每次更新手机网站首页都要把index.html删除掉重新生成. 然而织梦不支持手机网站首页动态 ...

  2. P1742 最小圆覆盖

    \(\color{#0066ff}{题目描述}\) 给出N个点,让你画一个最小的包含所有点的圆. \(\color{#0066ff}{输入格式}\) 先给出点的个数N,2<=N<=1000 ...

  3. 14.Diameter of Binary Tree(二叉树的直径)

    Level:   Easy 题目描述: Given a binary tree, you need to compute the length of the diameter of the tree. ...

  4. CodeForces - 893C-Rumor(并查集变式)

    Vova promised himself that he would never play computer games... But recently Firestorm - a well-kno ...

  5. 如何避免遗漏bug

    bug遗漏,我想这个是很多公司很多人头痛的一个问题.众所周知,bug是不可能被完全消灭的,当然也就意味着在发布前不能被全部找出来.于是乎当项目发布后,或多或少都会出现bug遗漏的现象,即使发布初期没有 ...

  6. UDP通讯模型简单示例

    1. UDP通讯模型 2. 服务器端 ① 创建一个socket,用函数socket() ② 绑定IP地址.端口等信息到socket上,用函数bind() ③ 循环接收数据,用函数recvfrom() ...

  7. Problem09 求完数

    题目:一个数如果恰好等于它的因子之和,这个数就称为"完数". 分析:例如6=1+2+3. 编程找出1000以内的所有完数. 假如整数n除以m,结果是无余数的整数,那么我们称m就是n ...

  8. thinkPHP5.0使用form表单提交数据和删除文章,不用TP的提示页面,使用弹出提示信息

    form表单提交数据和删除文章时,TP的默认信息提示页面的看起来不是很好看,想要实现弹窗提示怎么做呢? 前端:可以使用前端的一个知识--iframe,iframe元素会创建包含另外一个文档的内联框架: ...

  9. Yii2 urles

    public function rules(){ return [ //必须填写 ['email, username, password,agree,verifyPassword,verifyCode ...

  10. 数据结构---Java---有序数组

    [自定义有序数组] 查找算法: 线性查找算法:依次对比查询: 二分查找算法:必须是有序: insert:要插入的value与数组中每个元素进行比较,当有值>value时,此处的index之后的元 ...