[笔记]Windows核心编程《三》进程

简介: Windows核心编程《三》进程

系列文章目录



[笔记]Windows核心编程《一》错误处理、字符编码

[笔记]Windows核心编程《二》内核对象

[笔记]Windows核心编程《三》进程

[笔记]Windows核心编程《四》作业

[笔记]快乐的LInux命令行《五》什么是shell

[笔记]Windows核心编程《五》线程基础

[笔记]Windows核心编程《六》线程调度、优先级和关联性

[笔记]Windows核心编程《七》用户模式下的线程同步

[笔记]Windows核心编程《八》用内核对象进行线程同步

[笔记]Windows核心编程《九》同步设备I/O和异步设备I/O

[笔记]Windows核心编程《十一》Windows线程池

[笔记]Windows核心编程《十二》纤程

[笔记]Windows核心编程《十三》windows内存体系结构

[笔记]Windows核心编程《十四》探索虚拟内存

[笔记]Windows核心编程《十五》在应用程序中使用虚拟内存

[笔记]Windows核心编程《十六》线程栈

[笔记]Windows核心编程《十七》内存映射文件

[笔记]Windows核心编程《十八》堆栈

[笔记]Windows核心编程《十九》DLL基础

[笔记]Windows核心编程《二十》DLL的高级操作技术

[笔记]Windows核心编程《二十一》线程本地存储器TLS

[笔记]Windows核心编程《二十二》注入DLL和拦截API

[笔记]Windows核心编程《二十三》结构化异常处理


文章目录



   系列文章目录

   进程

       进程必须有一个线程

       进程销毁

           主线程的入口点函数返回 return(推荐)

           调用ExitProcess 强制退出(不推荐)

           在另一个进程调用TerminalProcess(不推荐)

       链接器子系统开关

           /Subsystem:console 控制台程序 入口

           /Subsystem:Windows GUI程序 入口

       main函数运行生命周期

           C运行时库函数

           main函数运行生命周期

       exit(0),ExitProcess,和TerminateProcess

   获得系统

   CreateProcess函数

       函数

       运行流程

       NtCreateProcess函数

   总结


进程


进程必须有一个线程

PrimaryThread 主线程


进程销毁

主线程的入口点函数返回 return(推荐)

进程的所有线程自然死亡(几乎不出现)

要么进程所有线程都调用ExitThread


调用ExitProcess 强制退出(不推荐)

在进程的一个子线程中调用ExitProcess,

缺陷:

ExitProcess 后的代码会无法执行,会有资源没有释放,因为c/c++运行库也许不能执行正确的清理工作,包括全局对象的析构和本地对象的析构。


在另一个进程调用TerminalProcess(不推荐)

在另一个进程的任意线程中调用TerminalProcess,传入被终止的进程handle。

缺陷:

被终止进程得不到终止的通知,进程得不到正确清理,也不能阻止它被强行终止,但是操作系统会在终止后彻底清理的,确保不会泄露任何操作系统资源(进程的 内存,文件,内核对象计数,用户对象,GDI对象都会被销毁)。


链接器子系统开关


将子系统的正确类型嵌入最终生成的可执行文件。

visitual studio中设置子系统方式:属性-》链接器-》子系统


/Subsystem:console 控制台程序 入口

_tmain(Main):处理ascii字符和字符串的CUI程序(控制台程序)

对应嵌入可执行文件的启动函数 mainCRTStartup


_tmain(wMain):处理Unicode字符和字符串的CUI程序(控制台程序)

对应嵌入可执行文件的启动函数 wMainCRTStartup


/Subsystem:Windows GUI程序 入口

_tWinMain(WinMain):处理ascii字符和字符串的GUI程序(图形化程序)

对应嵌入可执行文件的启动函数 WinMainCRTStartup


_tWinMain(wWinMain):处理Unicode字符和字符串的GUI程序(图形化程序)

对应嵌入可执行文件的启动函数 wWinMainCRTStartup


main函数运行生命周期

C运行时库函数

这些C运行时库函数,主要完成以下任务:


   获取进程命令行指针;

   获取进程环境变量指针;

   初始化C/C++运行时库的全局变量,如果你包含了头Stdlib.h,那么你就可以访问这些变量!//errno这就是一个全局变量。_enrion这是环境变量指针

   初始化malloc函数的内存堆;

   为C++全局类,调用构造函数。


malloc 函数,不要轻易使用,因为这个函数一般来说,最终会调用windows API函数,我们直接调用virtualAlloc windowsAPI函数,效率会高!


main函数运行生命周期

Kenerl 调用XXXCRTStartup函数;

XXXCRTStartup函数调用main函数;

main函数退出;

exit函数被调用(真正调用的是crt0dat.c中的)

static void __cdecl doexit (
        int code,
        int quick,
        int retcaller
        )

这个函数主要做以下事情:

1.调用_onexit函数注册的所有函数;

2.调用C++销毁函数销毁所有的全局和静态类对象;

3.如果_CRTDBG_LEAK_CHECK_DF标志被设置,那么调用CrtDumpMemoryLeaks函数,列出泄露内存。

4.调用ExitProcess函数,系统杀死当前进程!


exit(0),ExitProcess,和TerminateProcess


获得系统


GetVersion() 获得版本号

#include <windows.h>
#include <stdio.h>
#include <VersionHelpers.h> 
void main()
{
    DWORD dwVersion = 0; 
    DWORD dwMajorVersion = 0;
    DWORD dwMinorVersion = 0; 
    DWORD dwBuild = 0;
    LPOSVERSIONINFOW lpVersionInformation;
    dwVersion = GetVersion();//GetVersionEx(lpVersionInformation);
    if (IsWindowsXPOrGreater()) {
        printf("Yes\n");
    };
  printf("%0x\n",dwVersion);
    // Get the Windows version.
  //一个子就是WORD;
  WORD Version=LOWORD(dwVersion);
  //dwVersion中,其地位字,
    dwMajorVersion = (DWORD)(LOBYTE(Version));
  //Version字的低字节代表大版本号
    dwMinorVersion = (DWORD)(HIBYTE(Version));
  //Version字的高字节代表小版本号
    // Get the build number.
    if (dwVersion < 0x80000000)              
        dwBuild = (DWORD)(HIWORD(dwVersion));
  //dwVersion的高位字,表示build号。
    printf("Version is %d.%d (%d)\n", 
                dwMajorVersion,
                dwMinorVersion,
                dwBuild);
  getchar();
}

CreateProcess函数


函数

BOOL CreateProcess
(
  LPCTSTR lpApplicationName,
  LPTSTR lpCommandLine,
  LPSECURITY_ATTRIBUTES lpProcessAttributes,
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  BOOL bInheritHandles,
  DWORD dwCreationFlags,
  LPVOID lpEnvironment,
  LPCTSTR lpCurrentDirectory,
  LPSTARTUPINFO lpStartupInfo,
  LPPROCESS_INFORMATIONlpProcessInformation
);

参数解释

运行流程

当一个应用程序调用(或最终结束于)某个进程创建函数,比如CreateProcess 、CreateProcessAsUser、CreateProcessWithTokenW或CreateProcessWithLogonW时,一个Windows子系统进程就被创建起来了


   创建一个Windows进程的过程,是由操作系统的三个部分执行一系列步骤来完成的,这三个部分是:


       客户方的windows库Kernel32.dll(在CreateProcessAsUser、 CreateProcessWithTokenW.或CreateProcessWithLogonW的情况下时,部分工作是由Advapi32.dl先做的)

       Windows执行体.

       Windows子系统进程(Csrss)。

       下面的列表概括了在利用Windows的CreateProcess函数来创建一个进程时所涉及的主要阶段:


   验证参数,转换Windows子系统标志和选项为对应的原生形式:解析、验证和转换属性列表为其原生形式。

   打开将要在该进程中执行的映像文件(.exe)。

   创建Windows执行体进程对象。

   创建初始线程(栈、执行环境,以及Windows执行体线程对象)。

   进行创建之后的、Windows子系统特有的进程初始化。

   开始执行初始线程(除非指定了CREATE SUSPENDED标志)。

   在新进程和线程的环境中,完成地址空间的初始化(比如加载必要的DL),并开始执行程序。


图5.6显示了Windows在创建一个进程时所遵从的步骤的总体情况:

图片.png


NtCreateProcess函数

CreateUserProcess的更底层实现是该函数


总结


1.使用

C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools

有一些工具 包括GuidGen.exe

相关文章
|
16天前
|
消息中间件 存储 缓存
【嵌入式软件工程师面经】Linux系统编程(线程进程)
【嵌入式软件工程师面经】Linux系统编程(线程进程)
27 1
|
4天前
|
Python Windows
在 Windows 平台下打包 Python 多进程代码为 exe 文件的问题及解决方案
在使用 Python 进行多进程编程时,在 Windows 平台下可能会出现将代码打包为 exe 文件后无法正常运行的问题。这个问题主要是由于在 Windows 下创建新的进程需要复制父进程的内存空间,而 Python 多进程机制需要先完成父进程的初始化阶段后才能启动子进程,所以在这个过程中可能会出现错误。此外,由于没有显式导入 Python 解释器,也会导致 Python 解释器无法正常工作。为了解决这个问题,我们可以使用函数。
13 5
|
3天前
|
缓存 数据安全/隐私保护 虚拟化
windows端口被占用,无法通过netstat找到进程,占用的端口又不能修改,该怎么办?
项目运行时服务器8080端口被占用,常规`netstat`命令找不到占用进程。解决方法包括:1) 强制关机重启释放端口;2) 使用`netstat -anobq`或Windows 10的`Get-NetTCPConnection` PowerShell命令查找BOUND状态的进程;3) 调整Windows动态端口范围,避免冲突。注意,强制关机可能影响数据安全。
31 2
|
5天前
|
Java 程序员
Java多线程编程是指在一个进程中创建并运行多个线程,每个线程执行不同的任务,并行地工作,以达到提高效率的目的
【6月更文挑战第18天】Java多线程提升效率,通过synchronized关键字、Lock接口和原子变量实现同步互斥。synchronized控制共享资源访问,基于对象内置锁。Lock接口提供更灵活的锁管理,需手动解锁。原子变量类(如AtomicInteger)支持无锁的原子操作,减少性能影响。
18 3
|
7天前
|
编解码 Windows
FFmpeg开发笔记(二十九)Windows环境给FFmpeg集成libxvid
XviD是开源MPEG-4视频编码器,与DivX相似但后者非开源。早期MP4常使用XviD或DivX编码,现已被H.264取代。在Windows上集成FFmpeg的XviD编解码库libxvid,需访问<https://labs.xvid.com/source/>下载源码,解压后在MSYS环境中配置、编译和安装。之后重新配置FFmpeg,启用libxvid并编译安装。详细步骤包括configure命令、make和make install。成功后,通过`ffmpeg -version`检查是否启用libxvid。更多音视频开发技术可参考《FFmpeg开发实战:从零基础到短视频上线》。
36 0
FFmpeg开发笔记(二十九)Windows环境给FFmpeg集成libxvid
|
15天前
|
安全 开发者 Python
Python中的多线程与多进程编程
Python作为一种广泛使用的编程语言,在处理并发性能时具有独特的优势。本文将深入探讨Python中的多线程与多进程编程技术,分析其原理和应用,帮助读者更好地理解并发编程在Python中的实现与优化。
|
25天前
|
安全 Java 程序员
深入理解Java并发编程:从基础到高级深入理解操作系统中的进程调度策略
【5月更文挑战第29天】 Java并发编程是Java开发中不可忽视的一部分,它涉及到多线程、同步、锁等概念。本文将带你从Java并发编程的基础概念出发,逐步深入到高级应用,让你全面掌握Java并发编程的技巧。
|
19天前
|
存储 Unix Linux
Linux多进程编程详解
进程反应了进程执行的变化。 进程的状态分为三种 ,`运行态`,`阻塞态`,`就绪态` 在五态模型中分为以下几种,新建态,就绪态,运行态,阻塞态,终止态。 运行态:进程占用处理器正在运行。 就绪态:进程已具备运行的条件,等待系统分配处理器运行。 阻塞态 :又称为等待(`wait`)态,或睡眠(`sleep`)态,指进程不具备运行条件,正在等待事件的完成。 新建态:进程已被创建,还未加入就绪队列。
9 0
Linux多进程编程详解
|
1月前
|
算法 Linux Windows
FFmpeg开发笔记(十七)Windows环境给FFmpeg集成字幕库libass
在Windows环境下为FFmpeg集成字幕渲染库libass涉及多个步骤,包括安装freetype、libxml2、gperf、fontconfig、fribidi、harfbuzz和libass。每个库的安装都需要下载源码、配置、编译和安装,并更新PKG_CONFIG_PATH环境变量。最后,重新配置并编译FFmpeg以启用libass及相关依赖。完成上述步骤后,通过`ffmpeg -version`确认libass已成功集成。
46 1
FFmpeg开发笔记(十七)Windows环境给FFmpeg集成字幕库libass
|
28天前
|
编解码 5G Linux
FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器
AVS3是中国首个8K及5G视频编码标准,相比AVS2和HEVC性能提升约30%。解码器libuavs3d支持8K/60P视频实时解码,兼容多种平台。《FFmpeg开发实战》书中介绍了在Windows环境下如何集成libuavs3d到FFmpeg。集成步骤包括下载源码、使用Visual Studio 2022编译、调整配置、安装库文件和头文件,以及重新配置和编译FFmpeg以启用libuavs3d。
41 0
FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器

热门文章

最新文章