首页 > 系统相关 >滴水逆向笔记系列-win32总结7-57.进程创建-58.挂起方式创建进程

滴水逆向笔记系列-win32总结7-57.进程创建-58.挂起方式创建进程

时间:2024-03-17 17:22:43浏览次数:22  
标签:58 创建 si 句柄 进程 sa NULL ie

第五十七课 win32 进程创建

1.进程创建的过程

父进程创建子进程,父进程挂了子进程不会挂

0x00 程序、imagebuffer、进程的关系

程序就是一个普通的二进制文件;imagebuffer就是程序拉伸到内存后的二进制文件,但是没有线程去执行他,进程则是有线程去运行这个imagebuffer

0x01 过程

image.png

image.png

0x02 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								
);	

a.创建内核对象

image.png
句柄表:第一列就是句柄,相当于内核对象地址的编号,第二列就是内核对象的真正地址,第三列表示是否可继承

b.分配4GB虚拟内存空间

image.png

c.创建进程的主线程

image.png

2.示例代码

VOID TestCreateProcessByCmdline()					
{					
	STARTUPINFO si = {0};   				
    PROCESS_INFORMATION pi;				
					
	si.cb = sizeof(si);				
					
	TCHAR szCmdline[] =TEXT("c://program files//internet explorer//iexplore.exe http://www.ifeng.com");				
					
	BOOL res = CreateProcess(				
		NULL, 			
		szCmdline, 			
		NULL, 			
		NULL, 			
		FALSE, 			
		CREATE_NEW_CONSOLE, 			
		NULL, 			
		NULL, &si, &pi); 	
    
    printf("%x %x %x %x\n",pi.dwProcessId,pi.dwThreadId,pi.hProcess,pi.hThread);
}					

STARTUPINFO结构(倒数第二参数)

用来设定要创建的应用程序的属性,比如可以指定新创建的控制台程序的标题等待。
一般情况,只要为第一个成员赋值就可以了.
si.cb = sizeof(si);

typedef struct _STARTUPINFO			
{			
   DWORD cb;			
   PSTR lpReserved;			
   PSTR lpDesktop;			
   PSTR lpTitle;			
   DWORD dwX;			
   DWORD dwY;			
   DWORD dwXSize;			
   DWORD dwYSize;			
   DWORD dwXCountChars;			
   DWORD dwYCountChars;			
   DWORD dwFillAttribute;			
   DWORD dwFlags;			
   WORD wShowWindow;			
   WORD cbReserved2;			
   PBYTE lpReserved2;			
   HANDLE hStdInput;			
   HANDLE hStdOutput;			
   HANDLE hStdError;			
} STARTUPINFO, *LPSTARTUPINFO;			

PROCESS_INFORMATION结构(倒数第一参数)

typedef struct _PROCESS_INFORMATION					
{					
   HANDLE hProcess;				//进程句柄	
   HANDLE hThread;				//主线程句柄	
   DWORD dwProcessId;				//进程ID	
   DWORD dwThreadId;				//线程ID	
} PROCESS_INFORMATION;

关于句柄和ID

1、都是系统分配的一个编号,句柄是客户程序使用 ID主要是系统调度时使用.
2、调用CloseHandle关闭进程或者线程句柄的时候,只是让内核计数器减少一个,并不是终止进程或者线程.进程或线程将继续运行,直到它自己终止运行。
3、进程ID与线程ID 是不可能相同。但不要通过进程或者线程的ID来操作进程或者线程,因为,这个编号是会重复使用的,也就是说,当你通过ID=100这个编号去访问一个进程的时候,它已经结束了,而且系统将这个编号赋给了另外一个进程或者线程.

3.进程终止

终止进程的三种方式:

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

获取进程的退出码:

BOOL GetExitCodeProcess(HANDLE hProcess,PDWORD pdwExitCode);

进程终止时相关操作:

1、进程中剩余的所有线程全部终止运行
2、进程指定的所有用户对象均被释放,所有内核对象均被关闭
3、进程内核对象的状态变成收到通知的状态
4、进程内核对象的使用计数递减1

4.句柄的继承

让不同进程间拥有相同的内核对象
进程A的代码

#include <windows.h>
#include <stdio.h>

int main(int argc,char* argv[])
{
	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);
	return 0;
}

进程B的代码

#include <windows.h>
#include <stdio.h>

int main(int argc,char* argv[])
{
    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();				
}

这是直接运行进程A的exe的结果,他会直接执行进程B z2.exe,因为进程A创建子进程并且使用命令C:/z2.exe,所以z2.exe才会被执行
image.png
如果在进程A的SetEvent(g_hEvent);打个断点
image.png
这就是最终想演示的结果,跨进程共用一个内核对象
image.png

总结

HANDLE g_hEvent = CreateEvent(&sa, TRUE, FALSE, NULL);表示创建一个可以被继承的对象,重点在第一个参数
BOOL res = CreateProcess(NULL, szBuffer, NULL, NULL, TRUE,CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);表示创建子进程,并设置子进程可以进程父进程的句柄表
一个是表示可以被继承(通过句柄表的第三列值0和1表示是否可以被继承)
一个是要不要继承,要的话在创建子进程的时候就会把可以继承的内核对象复制一份句柄表
image.png
image.png
image.png

第五十八课 win32 挂起方式创建进程

1.继承进程句柄和线程句柄(第三四个参数)

示例代码

进程A代码:

#include <windows.h>
#include <stdio.h>

int main(int argc,char* argv[])
{
    char szBuffer[256] = {0};								
    char szHandle[8] = {0};								
    								
    SECURITY_ATTRIBUTES ie_sa_p;								
    ie_sa_p.nLength = sizeof(ie_sa_p);								
    ie_sa_p.lpSecurityDescriptor = NULL;								
    ie_sa_p.bInheritHandle = TRUE; 								
    								
    SECURITY_ATTRIBUTES ie_sa_t;								
    ie_sa_t.nLength = sizeof(ie_sa_t);								
    ie_sa_t.lpSecurityDescriptor = NULL;								
    ie_sa_t.bInheritHandle = TRUE; 								
    //创建一个可以被继承的内核对象,此处是个进程								
    STARTUPINFO ie_si = {0};   								
    PROCESS_INFORMATION ie_pi;								
    ie_si.cb = sizeof(ie_si);								
    								
    TCHAR szCmdline[] =TEXT("c://program files//internet explorer//iexplore.exe");								
    CreateProcess(								
    	NULL, 							
    	szCmdline, 							
    	&ie_sa_p, 							
    	&ie_sa_t, 							
    	TRUE, 							
    	CREATE_NEW_CONSOLE, 							
    	NULL, 							
    	NULL, &ie_si, &ie_pi); 							
    								
    //组织命令行参数								
    sprintf(szHandle,"%x %x",ie_pi.hProcess,ie_pi.hThread);								
    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); 							
}

进程B代码

#include <windows.h>
#include <stdio.h>

int main(int argc,char* argv[])
{
    DWORD dwProcessHandle = -1;						
    DWORD dwThreadHandle = -1;						
    char szBuffer[256] = {0};
    						
    memcpy(szBuffer,argv[1],8);						
    sscanf(szBuffer,"%x",&dwProcessHandle);						
    						
    memset(szBuffer,0,256);						
    memcpy(szBuffer,argv[2],8);						
    sscanf(szBuffer,"%x",&dwThreadHandle);						
    						
    printf("获取IE进程、主线程句柄\n");						
    Sleep(2000);						
    //挂起主线程						
    printf("挂起主线程\n");						
    ::SuspendThread((HANDLE)dwThreadHandle);						
    						
    Sleep(5000);						
    						
    //恢复主线程						
    ::ResumeThread((HANDLE)dwThreadHandle);						
    printf("恢复主线程\n");						
    						
    Sleep(5000);						
    						
    //关闭ID进程						
    ::TerminateProcess((HANDLE)dwProcessHandle,1);						
    ::WaitForSingleObject((HANDLE)dwProcessHandle, INFINITE);						
    						
    printf("ID进程已经关闭.....\n");	
}

实现功能

在A进程中创建一个进程(比如浏览器进程IE),并设定该子进程的进程内核句柄与主线程内核句柄为可继承
在A进程中再创建一个进程B,在B中对IE进程控制

代码解释

进程A:

  • CreateProcess(NULL, szCmdline, &ie_sa_p, &ie_sa_t, FALSE, CREATE_NEW_CONSOLE, NULL,NULL, &ie_si, &ie_pi); 创建IE浏览器子进程,&ie_sa_p, &ie_sa_t表示进程句柄和线程句柄均可被继承,在句柄表里大概是这样子image.png,然后FALSE表示ie子进程不想继承进程A的句柄表
  • 再通过这两段代码sprintf(szHandle,"%x %x",ie_pi.hProcess,ie_pi.hThread); sprintf(szBuffer,"C:/z2.exe %s",szHandle);拼接好进程B想运行的命令,其实就是想把IE浏览器的进程句柄和线程句柄传给进程B,用命令写出来后进程B可以通过argv[1]接收到IE浏览器的进程句柄和线程句柄
  • 最后创建进程BCreateProcess(NULL, szBuffer, NULL,NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);TRUE表示进程B想要继承进程A的句柄表,

个人疑问:后面进程B是可以控制IE浏览器的,但是我们只继承了进程A的句柄表,难道IE浏览器进程被创建时&ie_sa_p, &ie_sa_t这样设置后,IE浏览器的进程句柄和线程句柄就写入了进程A的句柄表了吗
进程B:

  • 这段代码是为了接收IE浏览器的进程句柄和线程句柄memcpy(szBuffer,argv[1],8); scanf(szBuffer,"%x",&dwProcessHandle);
  • 后面的挂起主线程时,十秒内IE浏览器就是被挂起状态,我们可以看到十秒内浏览器是不能动的,恢复后的十秒内则可以,接着十秒后IE浏览器进程将被进程B关闭,由此可以看到进程B通过继承过来的IE浏览器的进程句柄和线程句柄在操控IE浏览器

2.lpCurrentDirectory(第六个参数)

示例代码

打印当前exe的目录
image.png
第三个参数如果为NULL则是父进程的目录,如果是C:\,则打印C:<br />image.png

3.dwCreationFlags(第六参数)

当他为CREATE_NEW_CONSOLE时,子进程会有自己的控制台窗口,NULL则反之

4.以CREATE_SUSPENDED挂起方式创建进程

以挂起的方式创建进程,获取进程的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, 					 // SD	
	NULL,  		             // SD				
	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);							
			

标签:58,创建,si,句柄,进程,sa,NULL,ie
From: https://www.cnblogs.com/xiaoxin07/p/18078810

相关文章

  • python疑难杂症(9)---python的数据类型字典(dict)的创建、访问、修改、删除等方法汇总
    在Python中,字典(Dictionary)是一种内置的数据烈性,是无序的数据结构,用于存储键值对(key-value)。字典中的每个元素由一个键(key)和一个对应的值(value)组成,键和值之间使用冒号(:)进行分隔,每个键值对之间使用逗号(,)进行分隔。字典中的键必须是唯一的,而值可以是任意类型的对象,字典可以用来存......
  • 什么是进程?
    什么是进程?什么是程序?程序是一种文件。程序包含一系列信息,这些信息描述了如何在运行时创建一个进程。程序一般包含如下内容:二进制格式标识:一般用于标识文件类型机器语言指令程序入口地址数据:程序中变量初始值以及程序使用的字面常量(如字符串)符号表及重定位表:描述程序中......
  • python--异常捕获+类的创建+类属性
    异常处理写法一try:可能会报错的代码print(‘不报错执行’)except:print(‘报错的时候执行’)写法二try:#可能报错的代码print(‘不报错执行1’)except:print(‘报错的时候执行’)else:print(‘不报错执行2’)写法三try:#可能报错的代码print(‘不......
  • C++文件操作实战:创建、写入、读取、修改文件一应俱全
     概述:此C++示例详解文件操作:创建、删除、判断存在、写入、读取和修改文件内容。清晰演示了常见文件处理方法及源代码实现。以下是一个简单的C++实例,演示如何进行文件操作,包括创建文件、删除文件、判断文件是否存在、向文件写入内容、读取文件内容以及修改文件内容。#include......
  • UG NX二次开发(C++)-创建样条曲线(二)-UF_MODL_create_spline使用
    系列文章目录第一章、UGNX二次开发(C++)-创建样条曲线(一)-UF_CURVE_create_spline使用第二章、UGNX二次开发(C++)-创建样条曲线(二)-UF_MODL_create_spline使用提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录系列文章目录第一章、[UGN......
  • 滴水逆向笔记系列-win32总结4-50.创建线程-51.线程控制_CONTEXT结构
    第五十课win32创建线程1.进程与线程程序就是在硬盘里还没跑起来的二进制文件,进程就是已经运行中的程序,一个进程至少有一个线程,比如一个正在举行的活动需要几十个人帮忙干活,进程就是那个活动,线程就是那几十个人一个线程启动是需要占用一个cpu的一个新线程也会创建一个新堆......
  • 2-01. 创建项目
    版本和模板选择老师的版本选择了unity2021.2.10f1c1,模板选择了2D核心模板,后期会升级到2DURP包管理打开PackageManager,移除JetBrainsRiderEditor、VersionControl、VisualScripting,更新VisualStudioEditor、Timeline、TestFramework项目相关代码代码仓库:htt......
  • 使用java创建新的进程
    使用jdk内置的工具importorg.apache.commons.io.IOUtils;importjava.nio.charset.Charset;publicclassTestProcess{publicstaticvoidmain(String[]args)throwsException{testExec();}privatestaticvoidtestExec()throwsException{......
  • 使用Anaconda创建Python指定版本的虚拟环境
    由于工作的需要和学习的需要,需要创建不同Python版本的虚拟环境。比如zdppy的框架,主要支持的是Python3.8的版本,但是工作中FastAPI主要使用的是3.11的版本,所以本地需要两套Python环境。决定使用Anaconda虚拟环境管理的能力,并记录下。首先,下载:https://www.anaconda.com/down......
  • 快速创建一个spring-boot-starter
    可以使用springspi和import两种方法1.导入starter依赖1.1.maven管理工具<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency>1.2.gradle管理工......