win32创建进程

本文详细阐述了进程和线程的基本概念,包括进程的虚拟内存布局、创建过程及注入思路。解释了进程如何分配4GB虚拟地址空间,并重点介绍了创建进程的具体步骤。

一、定义

进程是空间上的概念,提供程序所需要的数据,代码等,是静止的。线程提供执行主体,负责使用资源。每个进程提供4GB虚拟地址空间,但是高2G是给内核程序使用的,是共同使用的空间(每个进程高2G都一样),低2GB是各自的空间。其中前(10000)64KB的虚拟内存是不使用的,所以实际上用户进程空间只有2GB。

实际上刚开始进程没有真正的空间,只有你申请了才有,所以叫虚拟内存空间。

进程之内是各个模块,每个模块都有其代码和数据。进程之内是各个PE文件组成,每个PE文件中有各自的内存。

每一个进程都不是凭空创建的,而是由其它进程创建的,第一个进程是由操作系统创建的。

Q:为什么前64KB一般不使用?

A:因为这是空指针赋值区,从来没有被分配和使用,操作系统也不用。

Q:给内核使用的高2GB,为什么是公用的?

A:大家都用的,内核空间,所以是公用的。

64KB禁入区:操作系统和用户都没有去用的空间。

二、创建进程过程

 

1.映射EXE文件:第一步就是将该exe文件放在内存中,如上文A.exe,每个exe内部都有说明,自己存放的位置。

2.每个进程都有一个EPROCESS(结构体)对象,它被放在内核区。

3.映射系统DLL:ntdll.dll被放在用户区。

4.创建进程的时候必然会自动创建一个线程,创建在内核区,如上图。

5.运行A.exe,除开ntdll.dll外,将系统中其它dll也放在用户空间中。

6.线程开始执行。

注:每个进程至少有一个线程。

调用程序的函数:

BOOL CreateProcess(
 LPCTSTR lpApplicationName, // 应用程序名称
 LPTSTR lpCommandLine, // 命令行字符串
 LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程的安全属性
 LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程的安全属性
 BOOL bInheritHandles, // 是否继承父进程的属性
 DWORD dwCreationFlags, // 创建标志
 LPVOID lpEnvironment, // 指向新的环境块的指针
 LPCTSTR lpCurrentDirectory, // 指向当前目录名的指针
 LPSTARTUPINFO lpStartupInfo, // 传递给新进程的信息
 LPPROCESS_INFORMATION lpProcessInformation // 新进程返回的信息
);
CreateProcess(
szChildProcssName,     //对象名称
szCommandLine,     //命令行
NULL,     //不继承进程句柄
NULL,     //不继承线程句柄
FALSE,    //不被子进程继承句柄
0,     //没有创建标志
NULL,     //使用父进程环境变量
NULL,     //使用父进程目录作为当前目录,可以自己设置目录
&si,     //STARTUPINFOW结构体详细信息
&pi)     //PROCESS_INFORMATION 结构体进程信息

第一个参数:进程名(路径+程序名)

第二个参数:传的命令行参数

当将命令行参数传入进程时,通过进程中argv参数可以获取到传入的参数,供程序使用。

倒数第二个参数:启动的相关信息;决定新进程的主窗体如何显示的STARTUPINFO结构体

①结构体数组中

  • 第一个参数:结构体大小(当扩展结构体数组时,第一个参数方便更改大小)。
  • dwX、dwY表示创建的进程位置。
  • dwXSize、dwYSize表示创建的窗口长宽。
  • 注:这个结构体指针参数是必选的。

②结构体使用例:

STARTUPINFO si;

ZeroMemory(&si, sizeof(si));          //给结构体赋值0

si.cb = sizeof(si);

③谁来启动当前进程,也就是说父进程会向子进程内部结构体传值。一般来说双击此进程的话是explorer进程传值。

最后一个参数:

①结构体数组信息:

  • 第一个参数:进程句柄
  • 第二个参数:线程句柄
  • 第三个参数:进程id
  • 第四个参数:线程id

②结构体使用例:

PROCESS_INFORMATION pi;

ZeroProcess(&pi, sizeof(pi));

③该结构体四个参数是函数输出的参数。

GetLastError():因为不是所有win32 api都有函数返回值,所以此函数返回上一个函数报错的int值,可以根据报错的int值到tools->Error Lookup中去查找详细原因。

三、注入思路

将上述标红的第五步中的dll替换成其它程序代码和数据,这样在任务管理区上显示的是原线程,但是执行程序效果确实替换的程序。如果设定原进程为services.exe ,这样在任务管理器中也不能删除注入的程序。

原程序很可能有代码检测程序,而这些程序一般封装在dll中,向上面这样注入替换的dll,那么原dll就不会被放进用户内存,所以代码检测会失效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值