一、定义
进程是空间上的概念,提供程序所需要的数据,代码等,是静止的。线程提供执行主体,负责使用资源。每个进程提供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就不会被放进用户内存,所以代码检测会失效。
本文详细阐述了进程和线程的基本概念,包括进程的虚拟内存布局、创建过程及注入思路。解释了进程如何分配4GB虚拟地址空间,并重点介绍了创建进程的具体步骤。

438

被折叠的 条评论
为什么被折叠?



