win32之进程概念

一丶简介

  学习WindowsAPI. 之前.我们必须理解什么是进程. 在windows环境下.进程就是一个运行起来的exe程序

进程提供了数据以及资源. 但是怎么使用不管.而是由线程去管. 

进程可以抽象为一栋房子. 而房子里面提供了日用品. 怎么使用它是不管的.

进程由很多DLL组成.我们可以拖动exe文件到win32dbg中查看.  快捷键 ALT + E 键.查看模块.

进程使用的内存空间是用户模式的内存空间.

什么是用户模式空间?

   在windows中.进程的空间都是虚拟空间. 低2G空间是用户使用的. 高2G则是内核中使用. 而且是所有进程共享的.只有ring 3也就是用户模式的exe空间是独立的.

而高2G空间中.又分为高低64k空间. 这段内存是不能使用的.

例如下图:

我们使用快捷键ALT + M键可以看到.进程的资源.以及地址起始位置.

二丶探究原理跟本质.进程是如何创建的.

1.双击原理

  我们一个进程可以使用鼠标双击来创建.但是并不是你鼠标创建的.而是由桌面管理器来创建的. 在windows任务管理器中 (ctrl + alt + del  / ctrl + shift + esc 调出)

如下图:

而它创建的时候.是通过API  CreateProcess  进行创建的.

2.原理.CreateProcess做了什么事情.

1.映射exe内存. 当调用CreateProcess的时候. 此时会把我们的exe映射到用户模式的虚拟内存中.

2.创建内核对象 EPROCESS 关于这点.熟悉内核驱动的应该知道.内核中EPROCESS是进程. ETHREAD是线程.不过如果不懂了解即可.

3.映射系统DLL 映射NTDLL. ntdll是系统dll每个进程都必须有这个ntdll.

4.创建ETHREAD 线程来执行代码. 我们知道进程只是提供资源数据代码而已. 但是怎么执行.是由线程来执行的. 通常我们会说主线程.

5.系统启动

  5.1映射DLL 为什么还要映射.因为你程序需要的dll加载了.可是dll可能还是使用其他的dll.所以为了程序的执行.也一并加载进来.

  5.2线程开始执行.这个时候就是开始执行我们代码了.

三丶进程创建CreateProcess解析

通过上面的原理我们知道了系统会调用CreateProcess进行创建进程.

PS: 在windows系统中.我们使用API的时候其实是 A版本跟W版本. 例如CreateProcessA 但是为了兼容性.windows直接封装了宏. CreateProcess.表示A 版下调用的就是CreateProcessA. W版本则是W版本.

BOOL CreateProcessA(
  LPCSTR                lpApplicationName,                //要创建的进程名称 完整路径+exe
  LPSTR                 lpCommandLine,                    //命令行参数.
  LPSECURITY_ATTRIBUTES lpProcessAttributes,   //是否进行继承进程句柄
  LPSECURITY_ATTRIBUTES lpThreadAttributes,    //是否进行继承线程句柄
  BOOL                  bInheritHandles,                    //是否进行继承句柄
  DWORD                 dwCreationFlags,                 //程序创建的标志.
  LPVOID                lpEnvironment,                     //父进程环境变量
  LPCSTR                lpCurrentDirectory,               //父进程当前目录.自己可以设置
  LPSTARTUPINFOA        lpStartupInfo,                //启动信息结构体.
  LPPROCESS_INFORMATION lpProcessInformation//进程信息结构体
);

在这里主要参数是1 2 9 10参数

1.LpApplicationName   这个就是我们要创建的进程的路径.

2.lpCommandLine        这个就是命令行参数.如果我们要启动的程序带有命令行启动.那么这里填写参数即可.

9. lpStartupInfo            启动信息结构体. 这个结构体里面存储了要创建进程的一些信息.传入参数.我们可以指定.但是一般进程都有自己启动信息所以一般不设置.其中有一个成员比较重要.

10 lpProcessInfomation 进程信息结构体. 传出参数. 当我们创建进程完毕后.会得到进程的句柄.线程句柄. 进程id,线程id. 这个是个传出参数.表示返回值.

启动信息结构体解析.

typedef struct _STARTUPINFOA {
  DWORD  cb;                                      表示当前结构体的大小 重要成员
  LPSTR  lpReserved;
  LPSTR  lpDesktop;
  LPSTR  lpTitle;
  DWORD  dwX;                                   创建进程的x位置.y位置大小...
  DWORD  dwY;
  DWORD  dwXSize;
  DWORD  dwYSize;
  DWORD  dwXCountChars;
  DWORD  dwYCountChars;
  DWORD  dwFillAttribute;
  DWORD  dwFlags;
  WORD   wShowWindow;
  WORD   cbReserved2;
  LPBYTE lpReserved2;
  HANDLE hStdInput;
  HANDLE hStdOutput;
  HANDLE hStdError;
} STARTUPINFOA, *LPSTARTUPINFOA;

关于这个结构.我们只需要知道第一个成员. 因为第一个成员必须我们给定.(其他也可以.但不是必须) 给定的是使用的当前结构体的大小.因为在windows程序中.很有可能扩展.为了扩展性.所以给一个成员指定一下.等以后结构体修改了.那么我们成员多大.windows就知道使用多大的结构体了.

进程信息结构体

typedef struct _PROCESS_INFORMATION {
  HANDLE hProcess;                                       返回的进程句柄
  HANDLE hThread;                                        返回的线程句柄
  DWORD  dwProcessId;                                 返回的进程ID
  DWORD  dwThreadId;                                  返回的线程ID
} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;

其中重要了就这些成员了.

介绍几个常用的API函数.

ZeroMemory(清零的地址,清零地址的大小) ; 这个API是使内存进行清零. 我们创建启动信息结构体的时候需要进行初始化使用.

CloseHandle(句柄) 关闭句柄. 当CreateProcess创建进程完毕后会返回进程信息结构体. 里面的句柄如果不适用我们需要使用CloseHandle进行关闭.

四丶详细代码.

#include <Windows.h>


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    
    TCHAR wszStartUpFileName[] = TEXT("D:\\calc.exe");  //要启动的程序路径
    TCHAR wszStartUpFileCommandLine[] = TEXT("");       //命令行参数
    
    STARTUPINFO si;                                                       //启动信息结构体
    PROCESS_INFORMATION pi;                                      //进程信息结构体
    ZeroMemory(&si, sizeof(si));                                      //清零
    ZeroMemory(&pi, sizeof(pi));

    si.cb = sizeof(si);                                                      //启动信息结构体赋值为当前结构体大小

    CreateProcess(                                                          //创建进程
        wszStartUpFileName,
        wszStartUpFileCommandLine,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        &si,
        &pi
    );

    CloseHandle(pi.hProcess);                                         //不使用的句柄关闭
    CloseHandle(pi.hThread);
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏LuckQI

Linux学习桌面系统生成快捷方式与普通用户权限

说了这么多其实还是建议如果有环境的话,程序员还是在Linux环境下开发的好。虽然刚开始有点难,但是后面会发现有很多好处。那么我们在Linux系统下开发首先会遇到...

10600
来自专栏24K纯开源

Premiere Pro & After Effects插件开发调试方法

      在给Adobe Premiere Pro(PR)和Adobe After Effects(AE)插件开发时,对于实时调试插件有着很强的需求。除了业务...

29470
来自专栏Small Code

VSCode Markdown PDF 导出成PDF报 phantomjs binary does not exist 错误的解决办法

问题 VSCode 是微软推出的一款开源的代码编辑器,从 sublime text 转过来后感觉还不错,昨天在用他写 Markdown 文件时想着直接导出 PD...

48280
来自专栏张善友的专栏

.NET Web 自动化测试工具

Inspired by Watir development of WatiN started in December 2005 to make a simila...

21390
来自专栏张善友的专栏

ASP.NET2.0应用中定制安全凭证

阅读提要 在缺省状况下,你只能使用Visual Studio 2005的一个本机实例来管理与ASP.NET 2.0一同发行的SQL Server数据库中的安全凭...

19790
来自专栏逸鹏说道

初识SignalR~仿QQ即时聊天(群发,单发)(Web,WPF等Demo演示)【上】

官方demo:http://www.asp.net/signalr/overview/getting-started/tutorial-getting-star...

45560
来自专栏小白课代表

编程 | VC++ 6.0 (WIN10可用)安装教程

39630
来自专栏GuZhenYin

Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)

前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于SignalR Core的文章了. 先介绍一下Si...

38690
来自专栏FreeBuf

Office文档嵌入对象点击执行的社工技巧

Microsoft Office相信大家都用过。Office在文档中嵌入对象极大的方便了我们的日常使用,但同时也为我们带来了众多安全问题。可以说,Office文...

19260
来自专栏walterlv - 吕毅的博客

自动将 NuGet 包的引用方式从 packages.config 升级为 PackageReference

发布于 2018-04-24 10:03 更新于 2018-06...

17720

扫码关注云+社区

领取腾讯云代金券