零基础逆向工程39_Win32_13_进程创建_句柄表_挂起方式创建进程
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_进程创建_句柄表_挂起方式创建进程的更多相关文章
- 零基础逆向工程25_C++_02_类的成员权限_虚函数_模板
1 类的成员权限 1.1 小结: 1.对外提供的函数或者变量,发布成public的 但不能随意改动. 2.可能会变动的函数或者变量,定义成private的 这样编译器会在使用的时候做检测. 3.只有结 ...
- 零基础逆向工程23_PE结构07_重定位表_IAT表(待补充)
重定位表 待补充 IAT表 待补充
- 零基础逆向工程20_PE结构04_任意节空白区_新增节_扩大节添加代码
向代码节添加代码实现 作者经过一周不断的失败,再思考以及无数次调试终于实现. 思路:八个步骤 1. 文件拷到文件缓冲区(FileBuffer) //图示见(零基础逆向工程18之PE加载过程) 2. 文 ...
- 【布艺DIY】 零基础 做包包 2小时 就OK!_豆瓣
[布艺DIY] 零基础 做包包 2小时 就OK!_豆瓣 [布艺DIY] 零基础 做包包 2小时 就OK!
- EPROCESS 进程/线程优先级 句柄表 GDT LDT 页表 《寒江独钓》内核学习笔记(2)
在学习笔记(1)中,我们学习了IRP的数据结构的相关知识,接下来我们继续来学习内核中很重要的另一批数据结构: EPROCESS/KPROCESS/PEB.把它们放到一起是因为这三个数据结构及其外延和w ...
- win32进程概念之句柄表,以及内核对象.
句柄表跟内核对象 一丶什么是句柄表什么是内核对象. 1.句柄表的生成 我们知道.我们使用CreateProcess 的时候会返回一个进程句柄.以及线程句柄. 其实在调用CreateProcess的时候 ...
- 零基础逆向工程36_Win32_10_互斥体_互斥体与临界区的区别
1 引言 讲了第二个内核对象,互斥体.前面已经学过一个内核对象,线程.这节讲两个函数,WaitForSingleObject()和WaitForMultipleObjects().因此这两个函数是根据 ...
- 零基础逆向工程28_Win32_02_事件_消息_消息处理函数
1 第一个图形界面程序 步骤1:创建Windows应用程序 选择空项目 步骤2:在新建项窗口中选C++代码文件 创建一个新的cpp文件 步骤3:在新的cpp文件中添加:#include <Win ...
- salesforce零基础学习(一百一十一)custom metadata type数据获取方式更新
本篇参考: https://developer.salesforce.com/docs/atlas.en-us.234.0.apexref.meta/apexref/apex_methods_syst ...
随机推荐
- umask码和文件权限
umask是chmod配套的,总共为4位(gid/uid,属主,组权,其它用户的权限),不过通常用到的是后3个,例如你用chmod 755 file(此时这文件的权限是属主读(4)+写(2)+执行(1 ...
- Nginx02---指令集实现静态文件服务器
location 实现静态服务器,就是root和alias命令,他们位于location文件块中,详细:https://www.jianshu.com/p/4be0d5882ec5 root root ...
- docker上安装eslaticsearch
一 elasticsearch安装 1 查找镜像: docker search elasticsearch 可以看到如下截图; 2 拉取镜像 docker pull elasticsearch 我并没 ...
- Centos6.8 yum安装LNMP
1.Centos6系统库中默认是没有nginx的rpn包的,所以我们需要先更新下rpm依赖库 (1):使用yum安装nginx,安装nginx库 rpm -Uvh http://nginx.org/p ...
- BZOJ 3083 遥远的国度 树链剖分+脑子
唉..又调了半天QWQ..为何读入挂了.....莫非读入是反着的????据ywy学长所言如是...OvO震惊 这啥骚题啊...还要换根...不过清明讲过...(然鹅我现在才做... 先随便选个点(比如 ...
- Tomcat-猫
第1章 Tomcat简介 Tomcat 是一个web服务器 ,类似nginx,apache的http Nginx http 只能处理html等静态文件jpg() 网页分为静态网页(以.html 或 ...
- SoapUI性能测试
之前没发现SoapUI可以做性能测试,自己写了两个简单的例子,体验一下它的测试功能. 一.使用控件顺序执行 测试的框架如上图所示,一个TestCase包含Test Steps(具体的测试步骤),Loa ...
- args 、kwargs不定参数通过列表、元组、字典传递
*args .**kwargs是不定参数的表达方法,一般用于函数形参.*args .**kwargs 作为传递参数的函数,在使用过程中,可对*args .**kwargs多个输入,但是效率或者比较麻烦 ...
- python文件引用其他文件中的变量
问题: 然后再另一个文件中引用该变量 报错:Cannot find reference 'User_Agent' in '__init__.py' less... (Ctrl+F1) 正确写法: fr ...
- eclipse 快捷键使用日志
Ctrl+Shift+F 格式化代码 Ctrl+Shift+O 快速导入资源包 Ctrl+m 最大化/最小化当前窗口(全屏/还原)