首页 > 系统相关 >windows加载PE文件的流程

windows加载PE文件的流程

时间:2024-09-08 19:37:11浏览次数:11  
标签:文件 操作系统 windows 虚拟地址 DLL PE 加载

  1. 读取PE文件
    当一个PE文件被执行时,Windows的创建进程函数(CreateProcess)首先被调用,负责为新进程创建虚拟地址空间。
    操作系统从磁盘读取PE文件,将其头部内容(DOS头、PE头和节表)载入内存,以获取该文件的结构和装载信息。

  2. 检查PE文件有效性
    操作系统首先会检查PE文件的合法性,比如验证DOS头中的 "MZ" 签名,接着检查PE头中的 "PE\0\0" 签名。
    如果文件不符合PE格式要求,操作系统会中止加载并返回错误。

  3. 分配虚拟地址空间
    根据PE头部的信息,操作系统会为进程分配所需的虚拟地址空间。其中包括程序的代码段、数据段、堆栈等。
    装载基地址:PE文件头中包含一个“装载基地址”(ImageBase),指明程序希望被加载到哪个虚拟地址。如果该地址不可用(例如,冲突),则需要重定位。
    操作系统使用分页内存管理机制来为程序分配虚拟内存区域,但此时并不会将所有PE文件的内容都立即加载到物理内存中。

  4. 加载各个段到虚拟内存
    根据节表(Section Table)的描述,操作系统会将PE文件中的不同段(如代码段、数据段等)映射到进程的虚拟地址空间中:
    代码段(.text)通常是只读和可执行的。
    数据段(.data)是读写区域,存放全局变量和已初始化的数据。
    未初始化数据段(.bss)通常被操作系统初始化为0。
    导入表(.idata)、导出表(.edata)等特殊段也会映射到内存中,用于动态链接库的管理。
    操作系统在加载时会将这些段映射到虚拟地址空间中,并且可能使用惰性加载(Lazy Loading)策略,即只有在段被实际访问时才会将其加载到物理内存中。

  5. 动态链接库(DLL)的加载与解析
    如果PE文件有导入表(Import Table),它会列出该可执行文件所依赖的DLL文件及其函数。
    操作系统会读取导入表中的每一个DLL名称,并尝试加载这些DLL文件。未加载的DLL文件将被操作系统载入到当前进程的虚拟地址空间中。
    接着,操作系统会解析导入表中所引用的每个函数符号,并将它们映射到正确的内存地址上。如果函数是延迟绑定的(如使用 LoadLibrary 和 GetProcAddress 动态加载),则它们会在第一次被调用时加载。

  6. 地址重定位(Relocation)
    如果PE文件的装载基地址被操作系统占用,操作系统会将PE文件加载到不同的地址空间。此时需要进行重定位,即调整PE文件中的指针和地址,使其指向新的基地址。
    重定位信息存储在PE文件中的重定位表(Relocation Table)中,操作系统会根据该表修正所有与基地址相关的地址。

  7. 执行TLS回调函数
    如果PE文件使用了线程局部存储(TLS),在加载过程中,操作系统会调用TLS回调函数。这些回调函数通常用于在进程或线程初始化时执行特定的任务,如全局变量初始化等。

  8. 设置初始栈和堆
    操作系统为进程分配堆栈和堆。堆栈用于保存函数调用信息和局部变量,堆用于动态内存分配。
    栈空间初始分配较小,随着函数调用的深入,栈空间会动态增加。

  9. 跳转到入口点执行
    PE文件的PE头中有一个入口点(Entry Point),它是程序的主执行代码的起始地址。
    操作系统通过加载器跳转到入口点并开始执行程序。对于普通应用程序,入口点通常是 main() 函数;对于DLL文件,则是 DllMain() 函数。

  10. 运行程序的主逻辑
    从入口点开始,程序的执行逻辑正式运行,执行代码、访问数据,并与操作系统、其他进程或设备进行交互。
    如果程序请求内存或与外部设备交互,会通过系统调用来请求操作系统的服务。
    三、进程结束和卸载
    当进程完成后,程序会通过系统调用 ExitProcess() 或 exit() 通知操作系统结束运行。
    操作系统会清理该进程分配的虚拟地址空间,释放物理内存,并将该进程的所有资源(包括文件句柄、内存等)返还给系统。
    如果是DLL文件,操作系统会根据需要调用 FreeLibrary() 函数卸载不再使用的DLL,并清理与该DLL相关的资源。

标签:文件,操作系统,windows,虚拟地址,DLL,PE,加载
From: https://www.cnblogs.com/jye159X/p/18403306

相关文章

  • Openwrt每分钟检查并自动挂载NTFS格式中文内容USB硬盘
    上一篇文章后我发现这硬盘连接并不是十分稳定,三天两头掉挂载,每次掉了都要再ctrlCV一遍代码还是蛮麻烦的,干脆多敲点面条字一次完事。编写代码注意:取用时请您自己修改代码中的uuid#!/bin/sh#定义硬盘的UUID和挂载点UUID="你硬盘的uuid"MOUNT_POINT="/mnt/usb"#使用b......
  • Pipeline流水线通过git拉取Jenkinsfile报错 error: RPC failed; result=22, HTTP code
    Pipeline流水线通过git拉取Jenkinsfile报错error:RPCfailed;result=22,HTTPcode=404在学习共享库时使用通过git拉取jenkinsfile时,报错在排查gitlab服务状态,网络通讯,防火墙规则以及Jenkins凭据均可以正常使用,最后发现的时在URL填写中缺少.git结尾所导致的,在了解后得知在......
  • Windows 11 登录后黑屏,只有一个可以移动的鼠标
    Windows11登录后黑屏,只有一个可以移动的鼠标,但是还能打开任务管理器,点击任务管理器顶部的“文件”>“运行新任务”按钮,按以下步骤操作:→输入:msconfig(按下Enter键)点击上面的“服务”勾选下面的“隐藏所有Microsoft服务”(请务必勾选)点击“全部禁用”。然后回到任务管......
  • 分布式系统中的Dapper与Twitter Zipkin:链路追踪技术的实现与应用
    目录一、什么是链路追踪?二、核心思想Dapper(一)Dapper链路追踪基本概念概要(二)Trace、Span、AnnotationsTraceSpanAnnotation案例说明(三)带内数据与带外数据带外数据带内数据数据的传递与集中(四)采样采样的目的采样率的调整采样机制的实现(五)存储为什么选择BigTab......
  • Swiper
    Swiper文章目录Swiper一.什么是Swiper?二.Swiper下载?三.使用步骤?1.解压2.引入相应项目3.引入文件4.复制代码四.HTML部分五.JS部分六.完整代码块一.什么是Swiper?Swiper是一款流行的、专为移动设备优化的滑动触摸插件,它使用JavaScript编写,旨在为网站和应用提供流畅......
  • 何为快速育种(Speed Breeding)?
    所谓“SpeedBreeding”(简称“SB”,额~),就是在环境可控的人工气候室中,通过改变光周期来加速植物的生长周期,从而起到加速育种的目的。快速育种:加速作物研究和育种的强大工具2017年7月9日,澳大利亚昆士兰大学LeeHickey团队领衔在预印本网站bioRxiv上发表了“SpeedBreeding”技术的......
  • LazyForEach:数据懒加载
    文章目录前言一、LazyForEach是什么?LazyForEach懒加载的原理和渲染过程使用限制二、使用步骤1.实现提供的一个IDataSource的接口2.将数据包装到对象中,实现一系列增删改查的方法3.ForEach替换为LazyForEach即可总结前言在HarmonyOS中,我们经常会遇到长列表加载的......
  • mathtype7.4最新永久免费安装版下载链接
    ......
  • 复制Monkeytype:如何创建一个高效的打字练习应用
    要想创建一个高效的打字练习应用,核心在于打造一个用户友好、功能全面且富有互动性的体验。Monkeytype作为一个备受欢迎的打字练习平台,为许多人提高打字速度和准确率提供了帮助。如何复制Monkeytype的成功经验,打造一个类似的高效打字练习应用呢?界面设计是关键。一个好的打字练习应......
  • Desthiobiotin-PEG3-Amine|cas:2237234-71-6|脱硫生物素-三聚乙二醇-胺
    基本信息中文名称:脱硫生物素-三聚乙二醇-胺英文名称:Desthiobiotin-PEG3-Amine结构式:CAS号:2237234-71-6分子式(Molecularformula):C18H36N4O5分子量(Molecularweigh):388.5存储时间:一年描述脱硫生物素-三聚乙二醇-胺(Desthiobiotin-PEG3-Amine)是一种化学合成的生物素衍生物......