简介

  • 初步学习C语言或者C++语言,再加上一点操作系统的知识就可以初步学习一下Windows高级编程
  • 学习Windows高级编程也算是了解一下Windows开发,学到一定程度之后就可以真正能跑去学逆向了。

Visual Studio介绍

  • Visual Studio就是Windows应用程序开发的一个IDE。基本上Windows程序的开发使用该IDE是非常方便的。这个IDE算是比较大的一个IDE。

解决方案

  • 接下来介绍一下这个软件最基本的使用过程。我们先看视图中解决方案资源管理器,我们点击解决方案资源管理器这边,左边就会弹出解决方法资源管理器。
  • 对于解决方案资源管理器,我们只需要知道它最重要的一个就是,它管理着很多项目。

image-20250525215415636

项目

  • 项目可以理解就是我们要做的一个程序,它里面是头文件、C文件的一些集合,这里我们先来新建一个项目

image-20250525220111353

image-20250525220140511

  • 此时就会跳转到这个窗口,这边有一个创建新解决方案,选择这个选项和合适的位置,点击创建即可
  • 如果我们想要自定义这个解决方案的名字我们就可以取消勾选将解决方案和项目放在同一目录中(如第二张图片)

image-20250525220247928

image-20250525220853528

  • 创建好一个项目后我们就会发现,解决方案下面存放着我们新建的项目1

image-20250525220450696

  • 此时我们在该解决方案中再创建一个项目2,发现我们的解决方案中能管理多个项目,之后就是一个头文件

image-20250525220639825

  • 所以我们画一个简单的图表示一下解决方案、项目、头文件、源文件的关系

image-20250525221038689

  • 此时我们在这个对应文件夹中能看到文件项目中的文件目录。

image-20250525221149138

  • 如果是不选择将解决方案和项目放在同一目录中,我们的项目文件就会出现如下图所示的一堆文件,已经对应的项目文件夹。是俩个图的对比,其中这俩个图的上一级目录如上图所示,在本级目录中的一些文件有所不同。
  • 相同点就是在于都存在.sln文件,这个文件被称为解决方案文件,这个文件主要就是存放着各个项目的信息。

image-20250525221608241

  • 我们要创建一个新的项目,还可以直接在解决方案这边右键创建,如下图所示

image-20250525222050718

  • 在创建项目中,VS给我们提供了很多项目模版,我们在学习Windows核心编程的时候主要就是创建这四种类型的项目文件。
  • 其它文件在Windows高级编程不是特别重要,也不是经常使用。

image-20250525223431481

启动项目

  • 当我们写好一个程序时,我们就可以使用这个按钮编译我们写好的程序,并且会自动运行。

image-20250525224312480

  • 但是当一个解决方案中有多个项目,我们就会发现,在编译好其中一个项目之后,运行程序时运行的是另一个已经编译好的文件。(其实编译的也不是我们这个项目的文件,其实是编译启动项目的文件)
  • 比如下图,我们编译的是111,但是运行的hello world,这个主要就是与我们的启动项目有关,每个解决方案只能有一个启动项目

image-20250525224425121

  • 我们可以使用如下操作进行启动项目的设置

image-20250525224600788

  • 设置完后再进行编译运行操作就没啥问题了

image-20250525224754306

Windows应用程序的分类

  • Windows应用程序一般就分为三大类:
    1. 控制台程序Console:DOS程序,本身没有窗口,通过Windows DOS窗口执行。入口函数:main
    2. 窗口程序:拥有自己的窗口,可以与用户交互。入口函数:WinMain
    3. 库程序:存放代码、数据的程序,执行文件可以从中取出代码执行和获取数据。其中库程序又分为静态库程序动态库程序
      • 静态库程序:扩展名Lib,在编译链接程序时,将代码放入到执行文件中。无入口函数
      • 动态库程序:扩展名dll,在执行文件执行时从中获取代码。入口函数:DllMain

控制台程序

  • 我们先来创建一个控制台程序

image-20250525223601596

image-20250525223618138

  • 创建好后这个解决方案就会出现一个这个控制台程序的项目。

image-20250525223705240

  • 接下来就是给这个项目添加一些文件,点击项目这边,然后添加,新建项。

image-20250525223922240

  • 操作完上面的此时就会弹出这个窗口,这样就可以选择我们要添加的文件了。

image-20250525224003654

  • 我们运行时在终端输出一些信息等,这种程序其实就是控制台程序

image-20250525224856718

  • 当我们编译好后的程序,这里的项目文件就会生成这些文件夹

image-20250525225054348

窗口程序

  • 窗口程序是Windows操作系统的一个比较重要的地方,windows区别于Linux就是图形化界面。所以这个是比较核心的一个点。
  • 我们先来创建一个基于窗口程序的项目。

image-20250525225250487

image-20250525225408301

  • 创建好这个项目后我们先来查看一下这个项目的一些相关文件。我们能看到创建完后我们的头文件和源文件一开始就会保护这些文件。
  • 这里我们要注意一下,我们的控制台程序的主函数是叫main函数,而我们的这个应用窗口程序的主函数叫WinMain这个函数。这些代码看不懂,没啥关系,之后会慢慢学。

image-20250525225517489

  • 接下来我们选择这个项目为启动项目,编译运行一下这个项目,运行之后我们就会得到如下的窗口。

image-20250525225733861

静态库程序

  • 不论是静态库程序还是动态库程序,在原理上都是和Linux相同的。只不过在实现上有不同就是了。
  • 接下来我们就先来添加一个静态库

image-20250526005329605

image-20250526005337520

  • 新建完之后我们会发现我们新建的这个项目有如下这些文件
  • 我们会看到这里我们并没有主函数,说明静态库程序并没有主函数。

image-20250526005429329

  • 我们编译运行这个程序后会发现该程序会弹出一个报错框,但是这个静态库会被编译好,编译成.lib后缀的文件。

image-20250526005632048

动态库程序

  • 接下来我们查看动态库程序,我们就直接新建一个动态链接库的项目

image-20250526005809948

image-20250526005834764

  • 创建好后会看到如下代码,查看代码我们会发现一个DllMain这个函数名,这个就是我们这个dll文件的主函数,也就是入口函数。

image-20250526005922754

  • 这个时候我们编译运行一下,发现还是弹出一个错误的框
  • 我们发现这个程序已经被编译成了.dll文件,但是我们还是无法运行这个程序
  • 这就是动态库的一个比较关键的一个地方,它可以运行,但是它不能独立运行,它是依赖其他程序运行的。这个

image-20250526010059287

开发工具

编译、链接工具

  • VS这个开发工具会像这样,我们点击按钮,它就会自动将我们的程序编译和链接好。链接的具体过程并没有向我们展示。
  • 这里就简单介绍一下VS编译和链接使用的相关工具。
  • 编译器这边使用的是CL.exe文件,主要将源代码编译成目标代码.obj文件

image-20250526011417136

  • 还有链接器LINK.exe,将目标代码、库链接生成最终文件

image-20250526011536220

  • 还有一个就是资源编译器RC.exe,将.rc资源编译,最终通过链接器存入最终文件。

image-20250526011644125

库文件、头文件

  • 对于我们一开始学C语言,最经常使用的就是stdio.h这个库文件。而现在我们学习的是windows高级编程,是开发Windows上的一些应用程序。所以我们使用的库就是windows中特有的库。
  • windows高级编程中,以下几个Windows库是最经常使用的。
    • kernel32.dll提供了核心的API,例如进程、线程、内存管理
    • user32.dll提供了窗口、消息等API
    • gdi32.dll绘图相关的API
    • 它们的路径都在C:\Windows\System32这里

image-20250526012333575

image-20250526012429481

image-20250526012357396

  • 我们要使用上面的库文件,在使用前必须进行声明,而Windows中的一些头文件已经声明好了。我们此时只要#include就行了。

  • 介绍一下Windows中比较重要的头文件

    • windows.h:所有windows头文件的集合(我们一般就include这个头文件即可)
    • windef.h:Windows数据类型
    • winbase.h:kernel32的API
    • wingdi.h:gdi32的API
    • winuser.h:user32的API
    • winnt.h:UNICODE字符集支持
    • 路径大概就在这里C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um

窗口程序基本函数

  • 在windows开发窗口程序的过程中主要有几个比较常见也比较基本的函数。我们开发的时候是跑不掉的。
  • 现在我们就先来介绍一下这几个函数,之后我们在开发的时候就会比较熟悉了。剩下的函数看着开发手册学就行了。
  • 第一个比较基本的函数就是WinMain函数
    • 重要概念:句柄,对于初学我们将句柄理解为用来找到内存的东西,但是句柄并不是指针。
    • hInstance:当前程序实例句柄,能找到当前进程所占据的内存
    • hPrevInstance(这个参数已经被废除,只有在16位的时候有用)
    • LPSTR lpCmdLineLPSTR就是char *的别名,所以这边我们应该传入一个字符串命令,类似与Main函数中的argvargc
    • int nCmdShow:只要的作用就是显示窗口,选项有如下图所示,最大化显示、最小化显示、原样窗口显示
1
2
3
4
5
6
int WINAPI WinMain(
HINSTANCE hInstance, // 当前程序的实例句柄
HINSTANCE hPrevInstance, // 当前程序前一个实例句柄
LPSTR lpCmdLine, // 命令行参数字符串
int nCmdShow // 窗口的显示方式
);
  • 第二个比较基本的函数就是MessageBox这个弹出消息提示框的函数。
    • HWND hWnd:父窗口的句柄,就像下图中我们这个提示框的父窗口就是记事本
    • LPCTSTR lpText:显示提示框中的文字,相当于下图中的是否要将....
    • LPCTSTR IpCaption:显示在标题栏中的文字,相当于下图中的记事本
    • UINT uType:弹出的框只有确定或者有保存、取消或者有保存、不保存、取消,还有弹窗的一些图标按照一些宏定义和或的型式即可。
1
2
3
4
5
6
int MessageBox(
HWND hWnd, //父窗口句柄
LPCTSTR IpText, // 显示在消息框中的文字
LPCTSTR IpCaption, // 显示在标题栏中的文字
UINT uType // 消息框中的按钮、图标显示类型
); // 返回点击的按钮ID
  • 提示框的主要效果就是像这样

image-20250526014828491

  • 接下来编写MessageBox版本的Hello world,编译运行的结果也在下面
1
2
3
4
5
6
7
8
#include<stdio.h>
#include<windows.h>
int main()
{

MessageBox(0, L"Hello World!", L"Windows高级编程", 0);
return 0;
}

image-20250526020104717