windows 进程

一、进程

    从内核的角度,进程可以理解成为一个内核对象,该内核对象保存了进程运行的所有数据。

    从二进制的角度,也可以认为进程是一个地址空间,包含了可执行文件和dll的代码和数据,以及内存的分配。

    从线程的角度,进程是数据容器,进程中所有的线程都共享进程的数据。

二、进程相关的数据结构

(1)EPROCESS (  内核态)

typedef struct _EPROCESS {
    KPROCESS Pcb;                 //本进程的KPROCESS结构
    ......
    PHANDLE_TABLE ObjectTable;    //本进程的句柄表
    PVOID VadRoot;                //指向代表本进程用户空间的数据结构
    HANDLE SectionHandle;         //指向为可执行程序映像创建的文件映射区句柄
    PPEB Peb;                     //指向用户空间的PEB
    ACCESS_MASK GrantedAccess;    //所允许的访问方式
    UCHAR ImageFileName[ 16 ];    //所执行程序映像的文件名
    UCHAR PriorityClass;          //本进程的优先级类别
    PVOID Win32Process;           //指向本进程的W32PROCESS结构
    LIST_ENTRY ThreadListHead;    //本进程的ETHREAD队列
    ......
} EPROCESS;</span></span>

(2)KPROCESS(内核态)

typedef struct _KPROCESS {
    DISPATCHER_HEADER Header;
    ULONG_PTR DirectoryTableBase[2];     //本进程页面映射表的物理地址
    ... ...
    LIST_ENTRY ReadyListHead;           // 本进程的就绪线程队列
    SCHAR BasePriority;                 //本进程的基本优先级
    LIST_ENTRY ProcessListEntry;        //挂入内核的进程队列
    ... ...
    ULONG KernelTime;
    ULONG UserTime;    
    SINGLE_LIST_ENTRY SwapListEntry; 
    LIST_ENTRY ThreadListHead;   
    ULONG_PTR StackCount;   
} KPROCESS, *PKPROCESS, *PRKPROCESS;</span></span>

(3)PEB(用户态)

typedef struct _PEB {
    ......
    HINSTANCE ImageBaseAddress; // 程序映像的起点 
    VOID *DllList;  
    PPROCESS_PARAMETERS *ProcessParameters;  //参数块
    ULONG KernelCallbackTable;     //用于从内核“回调”用户空间的函数 
    ULONG TlsBitmap;         //TLS位图
    LARGE_INTEGER TlsBitmapBits;  
    ULONG NumberOfProcessors;  
    ULONG NumberOfHeaps;  
    ULONG MaximumNumberOfHeaps;  
    ULONG ProcessHeaps;   
    ULONG OSMajorVersion;  
    ULONG OSMinorVersion;  
    USHORT OSBuildNumber;  
    USHORT OSCSDVersion;  
    ULONG OSPlatformId;
    ULONG GdiHandleBuffer[0x22];  
    ULONG PostProcessInitRoutine;  
    ULONG SessionId;  
} PEB, *PPEB; </span></span>

用户态windbg调试,查看这些数据结构,有很多种方法:

(a)通过!peb直接查看peb结构

(b)FS段寄存器指向当前的TEB结构,在TEB偏移0x30处是PEB指针,再用dt命令查看peb结构

三、进程入口函数和退出函数

(1)入口函数

    windows程序分为GUI(图形界面)和CUI(控制台)程序,GUI的入口函数为_tWinMain(......),CUI的入口函数为_tmain(......),在编译链接的过程中,会根据链接选项SubSystem的取值,来决定链接哪个入口函数,如果设置为/SUBSYSTEM:CONSOLE则会寻找_tmain, /SUBSYSTEM:WINDOWS则会寻找_tWinMain。

    值得注意的是,操作系统并不直接调用程序的入口函数,而是调用c/c++运行时库提供的运行时启动函数,如果是GUI程序,则调用_tWinMainCRTStartup,CUI则调用_tmainCRTStartup。c/c++提供的启动函数,会初始化c/c++运行时库,初始化c/c++运行时库的全局变量、内存分配函数和其他底层I/O例程使用的heap,调用所有全局和静态C++类对象的构造函数。

(2)退出函数

    入口函数退出后,启动函数将调用c运行时库函数exit,向其传递返回值。exit将完成一下任务:

    (a)调用_onexit函数调用所注册的任何一个函数;

    (b)调用所有全局和静态c++类对象的析构函数;

    (c)调用操作系统的ExitProcess函数,向其传入nMainRetVal。这会导致操作系统“杀死”我们的进程,并设置它的退出码。

    (d)在DEBUG生成中,如果定义了内存泄漏检查宏标志,则会生成内存泄漏报告。

四、进程的创建

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);</span>
     首先,创建内核对象。系统为新进程创建虚拟地址空间,将可执行文件或者dll的代码和数据加载到进程的地址空间。然后,主线程执行c/c++运行时的启动例程,最终会调用main系列函数。如果,系统成功创建了进程和主线程,createprocess则返回true。

(1)pszApplicationName, pszCommandline

   这两个参数,不能是常量字符串

(2)psaProcess, psaThread, bInheritHandles

   进程安全描述符和线程安全描述符

(3)fdwCreate

   标识了影响进程创建方式的标志

(4)pvEnvironment

(5)pszCurDir

(6)psiStartInfo(STARTUPINFO)

(7)ppiProcInfo(PROCESS_INFORMATION)

五、进程的退出

四种方式:

(1)主线程入口点函数返回

该线程创建的任何C++对象都由析构函数正确的销毁;

操作系统将正确的释放线程栈使用的内存;

系统将进程退出码设为入口点的返回值;

系统递减进程内核对象的使用计数;

(2)进程中另一个线程调用exitProcess函数

    会导致进程或者线程直接终止运行——再也不会返回当前函数调用。对于C、C++应用程序而言,会导致C/C++运行时库不会执行正确的清理操作;

(3)另一个进程中的线程调用TerminateProcess函数

    进程没有任何机会做清理操作,不过操作系统会接管,保证进程终止后绝对不泄漏任何东西。 TerminateProcess是异步的,需要调用WaitFor...Object来等待完成。

(4)进程中的所有线程都“自然死亡”

六、其他

(1)一些API

进程实例句柄:GetModuleHandle/GetModuleHandleEx

进程命令行:GetCommandLine,CommandLineToArgvW

进程环境变量:

GetEnvironmentStrings ,FreeEnvironmentStrings,GetEnvironmentVariable,

SetEnvironmentVariable,ExpandEnvironmentVariable  

进程当前所在目录和驱动器:GetCurrentDirectory,GetFullPathName

系统版本:GetVersionEx

进程错误模式:SetErrorMode(默认情况下,子进程会继承父进程的错误模式)

进程终止码:GetExitCodeProcess

(2)进程提权(UAC)

ShellExcuteEx

(3)当前权限上下文

GetTokenInformation

(4)枚举正在运行的进程

ToolHelp API中有Process32First, Process32Next, EnumPorcess等函数


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值