zoukankan      html  css  js  c++  java
  • 零基础逆向工程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
    ",argv[0]);
    printf("%x
    ",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
    ",argv[0]);
    printf("%x
    ",dwHandle);
    HANDLE g_hEvent = (HANDLE)dwHandle;
    
    printf("开始等待.....
    ");
    WaitForSingleObject(g_hEvent, INFINITE);	//当事件变成已通知时
    DWORD dwCode = GetLastError();
    printf("等到消息.....%x
    ",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);		
    
  • 相关阅读:
    将Word,PDF文档转化为图片
    图像识别
    ckeditor_4.5.10_full,ckfinder_aspnet_2.6.2,插件使用
    检索COML类工厂中 CLSID为 {00024500-0000-0000-C000-000000000046}的组件时失败,原因是出现以下错误: 80070005" 《终结篇》
    wireshark抓包图解 TCP三次握手/四次挥手详解
    经常开发出现bug的同事,
    简单理解Socket
    eclipse下如何配置tomcat
    Windows 7系统安装MySQL5.5.21图解
    Tomcat7.0.22在Windows下详细配置过程
  • 原文地址:https://www.cnblogs.com/flatcc/p/7892135.html
Copyright © 2011-2022 走看看