C++ 黑客编程揭秘与防范(第3版)
上QQ阅读APP看书,第一时间看更新

1.2.1 DOS程序与Windows程序执行流程对比

Windows下的窗口应用程序都是基于消息机制的,操作系统与应用程序之间、应用程序与应用程序之间,大部分都是通过消息机制进行通信、交互的。要真正掌握Windows应用程序内部对消息的处理,必须分析实际的源代码。在编写一个基于消息的Windows应用程序前,先来比较DOS程序和Windows程序在执行时的流程。

1.DOS程序执行流程

在DOS下将编写完的程序进行执行,在执行时有较为清晰的流程。比如用C语言编写程序后,程序执行时的大致流程如图1-6所示。

图1-6 传统DOS程序执行流程

在图1-6中可以看出,DOS程序的流程是按照代码的顺序(这里的顺序并不是指程序控制结构中的顺序、分支和循环的意思,而是指程序运行的逻辑有明显的流程)和流程依次执行。大致步骤为:DOS程序从main()主函数开始执行(其实程序真正的入口并不是main()函数);执行的过程中按照代码编写流程依次调用各个子程序;在执行的过程中会等待用户的输入等操作;当各个子程序执行完成后,最终会返回main()主函数,执行main()主函数的return语句后,程序退出(其实程序真正的出口也并不是main()函数的return语句)。

2.Windows程序执行流程

DOS程序的执行流程比较简单,但是Windows应用程序的执行流程就比较复杂了。DOS是单任务的操作系统。在DOS中,通过输入命令,DOS操作系统会将控制权由Command.com转交给DOS程序从而执行。而Windows是多任务的操作系统,在Windows下同时会运行若干个应用程序,那么Windows就无法把控制权完全交给一个应用程序。Windows下的应用程序是如何工作的?首先看一下Windows应用程序内部的大致结构图,如图1-7所示。

图1-7 Windows应用程序执行原理图

图1-7可能看起来比较复杂,其实Windows应用程序的内部结构比该示意图更复杂。在实际开发Windows应用程序时,需要关注的部分主要是“主程序”和“窗口过程”两部分。但是从图1-7来看,主程序和窗口过程没有直接的调用关系,而在主程序和窗口过程之间有一个“系统程序模块”。“主程序”的功能是用来注册窗口类、获取消息和分发消息。而“窗口过程”中定义了需要处理的消息,“窗口过程”会根据不同的消息执行不同的动作,而不需要程序处理的消息则会交给默认的系统过程进行处理。

在“主程序”中,RegisterClassEx()函数会注册一个窗口类,窗口类中的字段中包含了“窗口过程”的地址信息,也就是把“窗口类”的信息(包括“窗口过程的地址信息”)告诉操作系统。然后“主程序”不断通过调用GetMessage()函数获取消息,再交由DispatchMessge()函数来分发消息。消息分发后并没有直接调用“窗口过程”让其处理消息,而是由系统模块查找该窗口指定的窗口类,通过窗口类再找到窗口过程的地址,最后将消息送给该窗口过程,由窗口过程处理消息。