第二章 Win32程序运行原理

来源:互联网 发布:网络推广部门组建 编辑:程序博客网 时间:2024/05/19 23:25

2.1 CPU的保护模式和Windows系统

      80386处理器有三种工作模式:实模式、保护模式和虚拟86模式。windows系统运行在保护模式下。

2.1.1 Windows的多任务实现

     在Windows下,"任务"被"进程"取代,进程就是正在运行的应用程序的实例.但是点有CPU执行时间片的是线程。 Windows下每个进程被给予它自己的私有地址空间,当进程内线程运行时,该线程仅仅能够访问属于它的进程的内存。

2.1.2 虚拟内存

    在保护模式下,32位的Windows系统可寻址4GB的地址空间。机器上大小不可能是4GB,Windows使用虚拟内存技术将磁盘空间当作内存空间来使用。 各进程的地址空间被分成了用户空间和系统空间两部分.用户空间就是进程的私有地址空间.系统空间部分放置操作系统的代码,包括内核代码、设备驱动代码、设备缓冲区等.系统空间部分在所有的进程中是共享的。

2.2  内核对象

    内核对象是系统提供的用户模式下代码与内核模式下代码进行交互的基本接口。

2.2.1  对象句柄

    内核对象的数据结构仅能够从内核模式访问,应用程序必须使用API函数访问内核对象。调用函数创建内核对象时,函数会返回标识此内核对象的句柄。

2.2.2  使用计数

    内核对象是进程内的资源,使用计数属性指明进程对特定内核对象的引用次数,当引用次数为0时,系统就会关闭资源。

2.3  进程的创建

2.3.2   应用程序的启动过程

     操作系统运行初期并不是调用main函数,而是去调用C/C++运行期函数,控制台程序中运行期函数调用程序入口函数main,Win32的程序启动过程就是进程创建的过程,操作系统调用CreateProcess来创建新的进程,系统接着为新进程创建一个主线程,这个主线程通过执行C/C++运行期启动代码开始运行,C/C++运行期启动代码又会调用main函数,系统在创建新进程时会为新进程指定一个STARTUPINFO类型的变量。这些信息将影响新的进程中主线程的主窗口的显示。该结构定义如下:

typedef struct _STARTUPINFO { // si
    DWORD    cb; //结构长度
    LPTSTR    lpReserved; //保留
    LPTSTR    lpDesktop;   //指定桌面名称 ,保留
    LPTSTR    lpTitle;           //如果为控制台进程则为显示的标题
    DWORD    dwX;             //窗口横坐标
    DWORD    dwY;             //窗口纵坐标
    DWORD    dwXSize;     //窗口宽度
    DWORD    dwYSize;     //窗口高度
    DWORD    dwXCountChars;       //控制台窗口字符行数 
    DWORD   dwYCountChars;        
    DWORD   dwFillAttribute;             //控制台窗口填充模式
    DWORD   dwFlags;                       //创建标记
    WORD      wShowWindow;           //窗口显示标记,如同ShowWindow中的标记
    WORD      cbReserved2; //保留参数
    LPBYTE    lpReserved2; //保留参数
    HANDLE   hStdInput;        //标准输入句柄
    HANDLE   hStdOutput;     //标准输出句柄
    HANDLE   hStdError;        //标准错误句柄
} STARTUPINFO, *LPSTARTUPINFO;

一个进程可以通过GetStartupInfo函数来取得父进程创建自己时使用的STARTUPINFO结构,如下所示:

STARTUPINFO   si={sizeof(si)};

::GetStartupInfo(&si);

2.3.3   CreateProcess函数

    函数用法如下:

   CreateProcessA(                                                            
    LPCSTR lpApplicationName,                                       //可执行文件的名称
    LPSTR lpCommandLine,                                              //传递给执行模块的参数
    LPSECURITY_ATTRIBUTES lpProcessAttributes,  //进程安全性,NULL为默认
    LPSECURITY_ATTRIBUTES lpThreadAttributes,    //线程安全性,NULL为默认
    BOOL bInheritHandles,                                                //指定当前的可继承句柄是否可被新进程继承
    DWORD dwCreationFlags,                                          //指定新进程的优先级
    LPVOID lpEnvironment,                                               //指定环境变量
    LPCSTR lpCurrentDirectory,                                     //新进程使用的当前目录
    LPSTARTUPINFOA lpStartupInfo,                            
    LPPROCESS_INFORMATION lpProcessInformation    //返回新进程的标志信息,如ID号,句柄等
    );

下面代码启动了Windows自带的记事本程序

STARTUPINFO si={sizeof(si)};

PROCESS_IdNFORMATION pi;

char* szCommandLine = "notepad";

::CreateProcess(NULL,szCommandLine,NULL,NULL,FALSE,NULL,NULL,NULL,&si,&pi);

2.4  进程控制

2.4.1  获取系统进程

    使用函数Createtoolhelp32Snapshot获取系统内进程快照,然后使用Process32First函数和Process32Next函数遍历快照中记录的列表。该函数的头文件为tlhelp32.h

原创粉丝点击