第四章 进程
进程:一个正在运行的程序的一个实例。
构成:进程内核对象(用来管理进程);进程地址空间(包含可执行文件的代码和数据)。
当系统创建一个进程的时候,会自动为进程创建第一个线程,这称为主线程。
4.1 编写第一个windows程序
windows支持两种类型的应用程序:图形用户界面程序;控制台用户界面程序。
链接器会将应用程序的正确类型嵌入最终生成的可执行文件。/SUBSYSTEM:CONSOLE /SUBSYSTEM:WINDOWS
操作系统的加载程序(loader)检查可执行文件映像的文件头,并获取这个子系统值:如是CUI程序则创建控制台窗口,GUI则继续加载程序。
两种入口点函数:Int WINAPI _tWinMain(HINSTANCE hIntanceExe,HINSTANCE,PTSTR pszCmdLine,int nCmdShow);
int _tmain(int argc,TCHAR *argv[],TCHAR *envp[]);
(w)WinMain 的 hInstanceExe 参数的实际值是一个内存基地址;系统将可执行文件的映像加载到进程地址空间中的这个位置。
可执行文件的映像具体加载到哪一个基地址,是由链接器决定的。不同的链接器使用不同的默认基地址。运行win98时,0x00400000是可执行文件的映像能加载到的最低的一个地址。
链接器开关:/BASE:address 可以更改要将应用程序加载到哪个基地址。
HMODULE GetModuleHandle(PCTSTR pszModule);
单词:module,handle
该函数返回一个句柄/基地址:可执行文件被加载到进程地址空间的位置。成功则返回可执行文件映像加载到的基地址。
参数:已在主调进程的地址空间中加载的一个可执行文件或DLL文件的名称。
传入 NULL,则返回主调进程的可执行文件的基地址。
如何知道代码正在什么模块中运行:
1.利用伪变量 _ImageBase,它指向当前正在运行的模块的基地址。
_ImageBase:可执行文件被映射到应用程序内存中的位置。
2.调用 GetModuleHandleEx
GetModuleHandle 函数的两大重要特征:1它只检查主调进程的地址空间;2传入NULL时,返回进程地址空间中的可执行文件的基地址,即使调用GetModuleHandle(NULL)的代码是在一个DLL文件中。