当前位置: 首页 > news >正文

PE解释器之PE文件结构

        PE文件是由许许多多的结构体组成的,程序在运行时就会通过这些结构快速定位到PE文件的各种资源,其结构大致如图所示,从上到下依次是Dos头、Nt头、节表、节区和调试信息(可选)。其中Dos头、Nt头和节表在本文中统称为PE文件头(因为SizeOfHeaders就是这三个头的总大小)、节区则称为节,所以也可以说PE文件是由PE文件头和节组成。
  PE文件头保存着整个PE文件的索引信息,可以帮助PE装载器定位资源,而节则保存着整个PE文件的所有资源。正因为如此,所以存在着这样的说法:头是节的描述,节是头的具体化。

一:IMGAGE_DOS_HEADER

typedef struct _IMAE_DOS_HEADER {       WORD e_magic;        **重要成员 相对该结构的偏移0x00**WORD e_cblp;WORD e_cp;WORD e_crlc;WORD e_cparhdr;WORD e_minalloc;WORD e_maxalloc;WORD e_ss;WORD e_sp;WORD e_csum;WORD e_ip;WORD e_cs;WORD e_lfarlc;WORD e_ovno;WORD e_res[4];WORD e_oemid;WORD e_oeminfo;WORD e_res2[10];LONG e_lfanew;        **重要成员 相对该结构的偏移0x3C**
} IMAGE_DOS-HEADER, *PIMAGE_DOS_HEADER;

        当我们用16进制编辑器打开一个PE文件时,就会发现所有PE文件的前两个字节都是MZ,用十六进制表示是4D 5A,这两个字母就是Mark Zbikowski的姓名缩写,他是最初的MS-DOS设计者之一。如果把PE文件的这两个字节修改成其他数据,运行该PE文件就会无法正常运行(跳出黑窗口打印Program too big to fit in memory然后闪退,有兴趣的朋友可以尝试下)。这里可以证明当PE文件运行时,首先就会检测这两个字节,如果不是MZ则会退出运行。

        在该结构体中另一个重要成员就是最后一个成员e_lfanew。该成员的大小是LONG类型4个字节。之所以说它重要是因为它保存着IMAGE_NT_HEADERS32这个结构体在PE文件中的偏移地址,PE文件运行时只有通过该成员才能定位到PE签名(也就是IMAGE_NT_HEADERS32结构体的起始位置)。

二:IMAGE_DOS_STUB (了解)

        在IMAGE_DOS_HEADER结构体后面紧跟着就是IMAGE_DOS_STUB程序,它是运行在MS-DOS下的可执行程序,当可执行文件运行于MS-DOS下时,这个程序会打印This program cannot be run in DOS mode这条消息。用户可以自己更改该程序,MS-DOS程序当前是可有可无的,如果你想使文件大小尽可能的小可以省掉MS-DOS程序,同时把前面的参数都清0。

三:IMAGE_NT_HEADERS32

        

typedef struct _IMAGE_NT_HEADERS {DWORD                   Signature;         **重要成员 PE签名 相对该结构的偏移0x00**IMAGE_FILE_HEADER       FileHeader;        **重要成员 结构体 相对该结构的偏移0x04**IMAGE_OPTIONAL_HEADER32 OptionalHeader;    **重要成员 结构体 相对该结构的偏移0x18**
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

        这个结构体是整个PE文件的核心,它是由一个Signature、一个IMAGE_FILE_HEADER结构体、一个IMAGE_OPTIONAL_HEADER32结构体组成的。所以从整体看来这个结构比较简单,但实际上其内部结构较为复杂,我将会在下方对两个结构体进行详细的介绍。
  Signature
  也称作PE签名,这个成员和DOS头的MZ标记一样都是一个PE文件的标准特征,只不过这个成员是DWORD类型大小为4字节,如果把这个PE签名修改后,程序也是不会正常运行的(跳出黑窗口打印This program cannot be run in DOS mode然后闪退,可能是因为修改PE签名后无法识别后续内容的关系吧)。

        如果把MZ标志和PE签名同时改变的话,其效果和只修改MZ是一样的,可见程序在载入时是先检测MZ标志然后才检测PE签名的。

四:IMAGE_FILE_HEADER

typedef struct _IMAGE_FILE_HEADER {WORD  Machine;                    **        机器号     相对该结构的偏移0x00**WORD  NumberOfSections;           **重要成员 节区数量   相对该结构的偏移0x02**DWORD TimeDateStamp;              **        时间戳     相对该结构的偏移0x04**DWORD PointerToSymbolTable;       **        符号表偏移  相对该结构的偏移0x08**DWORD NumberOfSymbols;            **        符号表数量  相对该结构的偏移0x0C**WORD  SizeOfOptionalHeader;       **重要成员 可选头大小  相对该结构的偏移0x10**WORD  Characteristics;            **重要成员 PE文件属性  相对该结构的偏移0x12**
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

Machine:
  所表示的是计算机的体系结构类型,也就是说这个成员可以指定该PE文件能够在32位还是在64位CPU上执行。如果强行更改该数值程序就会报错。该成员可以是以下的数值:

NumberOfSections:
  它的含义就是当前PE文件的节区数量,虽然它是大小是两个字节,但是在windows加载程序时会将节区的最大数量限制为96个。

TimeDateStamp:
  它的含义是时间戳,用于表示该PE文件创建的时间,时间是从国际协调时间也就是1970年1月1日00:00起开始计数的,计数单位是秒。例如0x5CFBB225的计算方法如下:

通过计算,从1970年到2024年一共有*个闰年(通过闰年计算器获得),到1月有*天。秒:0x5CFBB225 % 60 = 33
分:0x5CFBB225 / 60 % 60 = 3
时:0x5CFBB225 / 3600 % 24 = 13
日:0x5CFBB225 / 3600 / 24 - (365 * 49 + 12) - 151 + 1 = 1
月:(0x5CFBB225 / 3600 / 24 - (365 * 49 + 12)) / 30 + 1 = 1
年:0x5CFBB225 / 3600 / 24 / 365 + 1970 = 2024
结果为:2024年1月1日 13:03:33

SizeOfOptionalHeader
  它存储该PE文件的可选PE头的大小,在32位PE文件中可选头大小为0xE0,64位可选头大小为0xF0。正因为如此,所以就必须通过该成员来确定可选PE头的大小。
  Characteristics
  它描述了PE文件的一些属性信息,比如是否可执行,是否是一个动态连接库等。该值可以是一个也可以是多个值的和,具体定义如下:

五:IMAGE_OPTIONAL_HEADER32

typedef struct _IMAGE_OPTIONAL_HEADER {WORD                 Magic;                        **魔术字                     偏移0x00BYTE                 MajorLinkerVersion;           **链接器主版本                偏移0x02BYTE                 MinorLinkerVersion;           **链接器副版本                偏移0x03DWORD                SizeOfCode;                   **所有含代码的节的总大小       偏移0x04DWORD                SizeOfInitializedData;        **所有含初始数据的节的总大小    偏移0x08DWORD                SizeOfUninitializedData;      **所有含未初始数据的节的总大小  偏移0x0C    DWORD                AddressOfEntryPoint;          **程序执行入口地址             偏移0x10   重要DWORD                BaseOfCode;                   **代码节的起始地址             偏移0x14DWORD                BaseOfData;                   **数据节的起始地址             偏移0x18DWORD                ImageBase;                    **程序首选装载地址             偏移0x1C   重要DWORD                SectionAlignment;             **内存中节区对齐大小           偏移0x20   重要DWORD                FileAlignment;                **文件中节区对齐大小           偏移0x24   重要WORD                 MajorOperatingSystemVersion;  **操作系统的主版本号           偏移0x28WORD                 MinorOperatingSystemVersion;  **操作系统的副版本号           偏移0x2AWORD                 MajorImageVersion;            **镜像的主版本号               偏移0x2CWORD                 MinorImageVersion;            **镜像的副版本号               偏移0x2EWORD                 MajorSubsystemVersion;        **子系统的主版本号             偏移0x30WORD                 MinorSubsystemVersion;        **子系统的副版本号             偏移0x32DWORD                Win32VersionValue;            **保留,必须为0               偏移0x34DWORD                SizeOfImage;                  **镜像大小                    偏移0x38   重要DWORD                SizeOfHeaders;                **PE头大小                    偏移0x3C   重要DWORD                CheckSum;                     **校验和                      偏移0x40WORD                 Subsystem;                    **子系统类型                   偏移0x44WORD                 DllCharacteristics;           **DLL文件特征                  偏移0x46DWORD                SizeOfStackReserve;           **栈的保留大小                 偏移0x48DWORD                SizeOfStackCommit;            **栈的提交大小                 偏移0x4CDWORD                SizeOfHeapReserve;            **堆的保留大小                 偏移0x50DWORD                SizeOfHeapCommit;             **堆的提交大小                 偏移0x54DWORD                LoaderFlags;                  **保留,必须为0                偏移0x58DWORD                NumberOfRvaAndSizes;          **数据目录的项数               偏移0x5CIMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

下方只对一些相对重要的成员进行讲解:
  Magic
  这个无符号整数指出了镜像文件的状态,此成员可以是以下的值:

AddressOfEntryPoint
  该成员保存着文件被执行时的入口地址,它是一个RVA。如果想要在一个可执行文件中附加了一段代码并且要让这段代码首先被执行,就可以通过更改入口地址到目标代码上,然后再跳转回原有的入口地址。

  ImageBase
  该成员指定了文件被执行时优先被装入的地址,如果这个地址已经被占用,那么程序装载器就会将它载入其他地址。当文件被载入其他地址后,就必须通过重定位表进行资源的重定位,这就会变慢文件的载入速度。而装载到ImageBase指定的地址就不会进行资源重定位。
  对于EXE文件来说,由于每个文件总是使用独立的虚拟地址空间,优先装入地址不可能被其他模块占据,所以EXE总是能够按照这个地址装入,这也意味着EXE文件不再需要重定位信息。对于DLL文件来说,由于多个DLL文件全部使用宿主EXE文件的地址空间,不能保证优先装入地址没有被其他的DLL使用,所以DLL文件中必须包含重定位信息以防万一。因此,在前面介绍的 IMAGE_FILE_HEADER 结构的 Characteristics 成员中,DLL 文件对应的IMAGE_FILE_RELOCS_STRIPPED位总是为0,而EXE文件的这个标志位总是为1。

  SectionAlignment
  该成员指定了文件被装入内存时,节区的对齐单位。节区被装入内存的虚拟地址必须是该成员的整数倍,以字节为单位,并且该成员的值必须大于等于FileAlignment的值。该成员的默认大小为系统的页面大小。
  FileAlignment
  该成员指定了文件在硬盘上时,节区的对齐单位。节区在硬盘上的地址必须是该成员的整数倍,以字节为单位,并且该成员的值必须大于等于FileAlignment的值。该值应为200h到10000h(含)之间的2的幂。默认为200h。如果SectionAlignment的值小于系统页面大小,则FileAlignment的值必须等于SectionAlignment的值。

  SizeOfImage
  该成员指定了文件载入内存后的总体大小,包含所有的头部信息。并且它的值必须是SectionAlignment的整数倍。
  SizeOfHeaders
  该成员指定了PE文件头的大小,并且向上舍入为FileAlignment的倍数,值的计算方式为:

SizeOfHeaders = (e_lfanew/*DOS头部*/ + 4/*PE签名*/ +sizeof(IMAGE_FILE_HEADER) +SizeOfOptionalHeader + /*NT头*/sizeof(IMAGE_SECTION_HEADER) * NumberOfSections) / /*节表*/FileAlignment  *FileAlignment +FileAlignment;    /*向上舍入 一般该结果不可能是FileAlignment的整数倍,所以直接加上FileAlignment还是没问题的 */

 NumberOfRvaAndSizes
  该成员指定了可选头中目录项的具体数目,由于以前发行的Windows NT的原因,它只能为10h。

六:IMAGE_SECTION_HEADER

#define IMAGE_SIZEOF_SHORT_NAME              8typedef struct _IMAGE_SECTION_HEADER {BYTE  Name[IMAGE_SIZEOF_SHORT_NAME];         **节区名                 偏移0x00union {DWORD PhysicalAddress;DWORD VirtualSize;                         **节区的虚拟大小          偏移0x08      重要} Misc;                                     DWORD VirtualAddress;                        **节区的虚拟地址          偏移0x0C      重要  DWORD SizeOfRawData;                         **节区在硬盘上的大小       偏移0x10      重要DWORD PointerToRawData;                      **节区在硬盘上的地址       偏移0x14      重要DWORD PointerToRelocations;                  **指向重定位项开头的地址   偏移0x18DWORD PointerToLinenumbers;                  **指向行号项开头的地址     偏移0x1CWORD  NumberOfRelocations;                   **节区的重定位项数         偏移0x20WORD  NumberOfLinenumbers;                   **节区的行号数            偏移0x22DWORD Characteristics;                       **节区的属性              偏移0x24       重要
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

 Name
  这是一个8字节的ASCII字符串,长度不足8字节时用0x00填充,该名称并不遵守必须以"\0"结尾的规律,如果不是以"\0"结尾,系统会截取8个字节的长度进行处理。可执行文件不支持长度超过8字节的节名。对于支持超过字节长度的文件来说,此成员会包含斜杠(/),并在后面跟随一个用ASCII表示的十进制数字,该数字是字符串表的偏移量。
  Misc.VirtualSize
  这个成员在一个共用体中,这个共用体中还有另外一个成员,由于用处不大我们就不讲解了,主要讲解VirtualSize的含义。这个成员指定了该节区装入内存后的总大小,以字节为单位,如果此值大于SizeOfRawData的值,那么大出的部分将用0x00填充。这个成员只对可执行文件有效,如果是obj文件此成员的值为0。
  VirtualAddress
  指定了该节区装入内存虚拟空间后的地址,这个地址是一个相对虚拟地址(RVA),它的值一般是SectionAlignment的整数倍。它加上ImageBase后才是真正的虚拟地址。
  SizeOfRawData
  指定了该节区在硬盘上初始化数据的大小,以字节为单位。它的值必须是FileAlignment的整数倍,如果小于Misc.VirtualSize,那么该部分的其余部分将用0x00填充。如果该部分仅包含未初始化的数据,那么这个值将会为零。
  PointerToRawData
  指出零该节区在硬盘文件中的地址,这个数值是从文件头开始算起的偏移量,也就是说这个地址是一个文件偏移地址(FOA)。它的值必须是FileAlignment的整数倍。如果这个部分仅包含未初始化的数据,则将此成员设置为零。
  Characteristics

        该成员指出了该节区的属性特征。其中的不同数据位代表了不同的属性,这些数据位组合起来就是这个节的属性特征        

总表:

 

相关文章:

PE解释器之PE文件结构

PE文件是由许许多多的结构体组成的,程序在运行时就会通过这些结构快速定位到PE文件的各种资源,其结构大致如图所示,从上到下依次是Dos头、Nt头、节表、节区和调试信息(可选)。其中Dos头、Nt头和节表在本文中统称为PE文件头(因为SizeOfHeaders…...

Android—— MIPI屏调试

一、实现步骤 1、在kernel/arch/arm/boot/dts/lcd-box.dtsi文件中打开&dsi0节点,关闭其他显示面板接口(&edp_panel、&lvds_panel) --- a/kernel/arch/arm/boot/dts/lcd-box.dtsib/kernel/arch/arm/boot/dts/lcd-box.dtsi-5,14 …...

BLE协议—协议栈基础

BLE协议—协议栈基础 BLE协议栈基础通用访问配置文件层(Generic Access Profile,GAP)GAP角色设备配置模式和规程安全模式广播和扫描 BLE协议栈基础 蓝牙BLE协议栈包含三部分:主机、主机接口层和控制器。 主机:逻辑链路…...

yolov8知识蒸馏代码详解:支持logit和feature-based蒸馏

文章目录 1. 知识蒸馏理论2. yolov8 蒸馏代码应用2.1 环境配置2.2 训练模型(1) 训练教师模型(2) 训练学生模型baseline(3) 蒸馏训练3. 知识蒸馏代码详解3.1 蒸馏参数设置3.2 蒸馏损失代码讲解3.2.1 Feature based loss3.2.1 Logit loss3.3 获取蒸馏的feature map及channels...

03-微服务-Ribbon负载均衡

Ribbon负载均衡 1.1.负载均衡原理 SpringCloud底层其实是利用了一个名为Ribbon的组件,来实现负载均衡功能的。 那么我们发出的请求明明是http://userservice/user/1,怎么变成了http://localhost:8081的呢? 1.2.源码跟踪 为什么我们只输入…...

2023新年总结与展望

2023年总结 对Spring Cloud微服务更加熟悉,对consul、kafka、gateway的熟悉和掌握更近一步对docker和虚拟化部署更加熟悉对PostgreSQL数据库和JPA更加熟悉对clickhouse数据库和大数据分析更加熟悉对netty和socket网络通信更加熟悉 2024年flag 继续深入研究和学习…...

论文阅读——SG-Former

SG-Former: Self-guided Transformer with Evolving Token Reallocation 1. Introduction 方法的核心是利用显著性图,根据每个区域的显著性重新分配tokens。显著性图是通过混合规模的自我关注来估计的,并在训练过程中自我进化。直观地说,我们…...

常用环境部署(十三)——GitLab整体备份及迁移

一、GitLab备份 注意:由于我的GitLab是docker安装的,所以我的操作都是在容器内操作的,大家如果不是用docker安装的则直接执行命令就行。 1、Docker安装GitLab 链接:常用环境部署(八)——Docker安装GitLab-CSDN博客 2、GitLab备…...

海外数据中心代理与住宅代理:优缺点全面对比

数据中心代理和住宅代理是为了匿名而开发的,通过替换网站眼中您自己的 IP 地址。然而,它们在价格、功能、性能或最佳用例方面存在一些差异。那么,这些代理类型到底有什么相似点和不同点呢? 一、什么是数据中心代理? 1…...

springboot实现OCR

1、引入依赖 <dependency><groupId>net.sourceforge.tess4j</groupId><artifactId>tess4j</artifactId><version>4.5.4</version> </dependency> 2、config Configuration public class TessOcrConfiguration {Beanpublic …...

【Scala 】注解

在 Scala 中&#xff0c;你可以使用注解来为类、方法或字段添加元数据&#xff0c;影响它们的行为。Scala 的注解使用与 Java 类似&#xff0c;但是 Scala 也支持自定义注解。 文章目录 注解的常见使用方法自定义注解 注解的常见使用方法 以下是一些 Scala 中常见的注解以及它…...

数通基础知识总结

1. 基础概念 1.1. 通信基本原理 通信基本原理涉及信息的生成、编码、传输和解码的过程。在实际应用中&#xff0c;例如电话通信&#xff0c;信息通过话筒转换成模拟信号&#xff0c;经过传输线路传递到接收端&#xff0c;再由耳机解码还原为可理解的信息。 1.2. 信道和信号 …...

机器学习深度学习面试笔记

机器学习&深度学习面试笔记 机器学习Q. 在线性回归中&#xff0c;如果自变量之间存在多重共线性&#xff0c;会导致什么问题&#xff1f;如何检测和处理多重共线性&#xff1f;Q. 什么是岭回归(Ridge Regression)和Lasso回归(Lasso Regression)&#xff1f;它们与普通线性回…...

安卓和Android是两种不同的操作系统?

实际上&#xff0c;安卓和Android并不是同一种操作系统&#xff01; Android是由Google开发并维护更新的一款操作系统&#xff0c;目前仅能运行在Pixel手机上。 Google Pixel 与 iPhone手机&#xff1a;哪个更好&#xff1f;Google Pixel 与 Apple iPhone哪个手机才是性价比最…...

Java学习——设计模式——结构型模式2

文章目录 结构型模式装饰者模式桥接模式外观模式组合模式享元模式 结构型模式 结构型模式主要涉及如何组合各种对象以便获得更好、更灵活的结构。虽然面向对象的继承机制提供了最基本的子类扩展父类的功能&#xff0c;但结构型模式不仅仅简单地使用继承&#xff0c;而更多地通过…...

什么是Maven ??? (以及关于依赖,中央仓库,国内源)

文章目录 什么是 Maven创建第一个 Maven 项目依赖管理Maven 的仓库Maven 如何设置国内源 什么是 Maven Maven &#xff1a;用于构建和管理任何基于java的项目的工具。**说白了就是管理 Java项目 的工具。**我们希望我们已经创建了一些东西&#xff0c;可以使Java开发人员的日常…...

c++期末考题笔试来咯

最后一道大题题目再现 写一个person类&#xff0c;有姓名&#xff0c;性别&#xff0c;年龄。然后在此基础上派生出教师类和学生类。教师类增加了以下数据&#xff1a;工号&#xff0c;职称&#xff0c;工资。学生类增加了以下数据成员&#xff1a;学号&#xff0c;专业&#…...

目标检测篇:如何根据xml标注文件生成类别classes的json文件

1. 介绍 之前在做目标检测任务的时候&#xff0c;发现很多的数据集仅有数据(只有图片标注的xml文件)&#xff0c;没有关于类别的json文件&#xff0c;为了以后方便使用&#xff0c;这里记录一下 一般来说&#xff0c;yolo标注的数据集&#xff0c;只有第一个是数字类别&#x…...

spring见解2基于注解的IOC配置

3.基于注解的IOC配置 学习基于注解的IOC配置&#xff0c;大家脑海里首先得有一个认知&#xff0c;即注解配置和xml配置要实现的功能都是一样的&#xff0c;都是要降低程序间的耦合。只是配置的形式不一样。 3.1.创建工程 3.1.1.pom.xml <?xml version"1.0" en…...

Uncaught TypeError: Cannot read property ‘snj‘ of null

项目场景&#xff1a; 项目相关背景&#xff1a; 调试项目时&#xff0c;控制台出现红色报错信息 问题描述 问题&#xff1a; 调试项目时&#xff0c;控制台出现如下所示的报错信息&#xff1a; Uncaught TypeError: Cannot read property snj of nullat T.Inj.Ya [as Inj…...

Jenkins基础教程

目录 第一章、快速了解Jenkins1.1&#xff09;Jenkins中一些概念介绍1.2&#xff09;Jenkins和maven用途上的区别1.3&#xff09;为什么使用Jenkins1.4&#xff09;学习过程中的疑问 第二章、安装Jenkins2.1&#xff09;安装之前的准备2.2&#xff09;Windows中Jenkins下载安装…...

嵌入式C语言--WatchDog最全概念

嵌入式C语言–WatchDog最全概念 嵌入式C语言--WatchDog最全概念 嵌入式C语言--WatchDog最全概念一. 什么是Watchdog1&#xff09;什么是“被狗咬”2&#xff09;什么是喂狗 二. 基本思想三. 作用四. 监视目标1) 监视一个进程2&#xff09;监视一个操作系统 五. 系统初始化时关闭…...

数据结构【树篇】(二)

数据结构【树篇】(二&#xff09; 文章目录 数据结构【树篇】(二&#xff09;前言为什么突然想学算法了&#xff1f;为什么选择码蹄集作为刷题软件&#xff1f; 目录树(一)、树的存储(二)、树和森林的遍历——并查集(三)、并查集的优化 结语 前言 为什么突然想学算法了&#xf…...

2024上海城博会|上海国际城市与建筑博览会-官 网

2024上海城博会|上海国际城市与建筑博览会 时间&#xff1a;2024年10月30日-11月1日 地点&#xff1a;上海世博展览馆 主办单位&#xff1a;联合国人居署 上海市住房和城乡建设管理委员会 协办单位&#xff1a;上海世界城市日事务协调中心 展会介绍 上海国际城市与建筑博览…...

Dockerfile - 基于 SpringBoot 项目自定义镜像(项目上线全过程)

目录 一、Dockerfile 自定义项目镜像 1.1、创建 SpringBoot 项目并编写 1.2、打包项目&#xff08;jar&#xff09; 1.3、编写 Dockerfile 文件&#xff0c;构建镜像 1.4、运行镜像并测试 一、Dockerfile 自定义项目镜像 1.1、创建 SpringBoot 项目并编写 a&#xff09;简…...

论文查重降重写成大白话可以吗

大家好&#xff0c;今天来聊聊论文查重降重写成大白话可以吗&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 论文查重降重&#xff1a;用大白话解析 一、引言 写论文是每个…...

【WPF.NET开发】WPF中的命令

本文内容 什么是命令WPF 中的简单命令示例WPF 命令中的四个主要概念命令库创建自定义命令 命令是 Windows Presentation Foundation (WPF) 中的一种输入机制&#xff0c;与设备输入相比&#xff0c;它提供的输入处理更侧重于语义级别。 示例命令如许多应用程序均具有的“复制…...

怎么将epub转换成txt文件?

怎么将epub转换成txt文件&#xff1f;在当前时代&#xff0c;各种各样的电子书是很多人都喜欢接触并阅读的&#xff0c;但很少有人知道电子书格式的不同&#xff0c;其中就包括epub和txt格式&#xff0c;这两种格式虽然都可以展示文本但能达到的效果完全不一样&#xff0c;在某…...

Java单词排序

【问题描述】 编写一个程序&#xff0c;从一个文件中读入单词&#xff08;即&#xff1a;以空格分隔的字符串&#xff09;&#xff0c;并对单词进行排序&#xff0c;删除重复出现的单词&#xff0c;然后将结果输出到另一个文件中。 【输入形式】从一个文件sort.in中读入单词。 …...

Moonsong Labs与Web3演变

作者&#xff1a;Derek Yoo 创建Moonsong Labs的理由 我们创建了Moonsong Labs&#xff0c;其使命是创建推动Web3采用的软件基础设施协议。我们的动力来自这样一个观念&#xff0c;即Web3使人类相互交往更加透明、高效和公正。这无疑是一个值得努力实现的目标&#xff0c;但更…...

成都今日各区疫情情况/ seo won

BossAnim 项目地址&#xff1a;Alex-Cin/BossAnim简介&#xff1a;仿 boss 直聘&#xff0c;查看用户头像博客地址 http://www.jianshu.com/p/eadd1a764720BossAnim 博客地址 http://www.jianshu.com/p/eadd1a764720...

wordpress 导出pdf文件大小/百度极简网址

(注&#xff1a;知识浩瀚&#xff0c;本人能力有限&#xff0c;多有不足&#xff0c;望各位多多指点&#xff0c;不足之处请指出&#xff0c;俺好随时改进&#xff0c;小的无以为报&#xff0c;在此鞠躬致谢…) 1.winR键 打开运行窗口 输入 regedit 打开注册表。 2.按&#x…...

wordpress生成sitemap/广告营销的经典案例

使用EEPROM实现LED状态保存与恢复 当定义和使用变量时,代码中生成的数据仅在Arduino开启时才持续存在。 如果重置或关闭Arduino的电源,则存储的数据将消失。如果要保留数据以备将来使用,则需要使用Arduino EEPROM。 即使Arduino重置或电源关闭,它也会存储变量的数据。 EE…...

武进网站建设价格/技术教程优化搜索引擎整站

有时候数组要转为对象操作&#xff0c;用对象的指向操作符&#xff0c;有两种方法 方法一&#xff1a; $arr[a>10,b>100,c>Hello];$obj(Object)$arr;echo output:.$obj->c;方法二&#xff1a;$arr[a>10,b>100,c>Hello];$arr0 json_encode($arr);$arr1 j…...

如何给网站添加音乐/seo技术分享博客

对一个dynamic工程&#xff0c;一般都是手动添加服务器&#xff0c;然后进行开发。有时候也可以利用eclipse的tomcat插件&#xff0c;使用起来还是挺方便的&#xff0c;只是配置的时候需要注意一些项目的配置&#xff0c;否则tomcat插件找不见运行时需要的classes文件等&#x…...

成都市网站建设费用及企业/sem扫描电镜是测什么的

Spark SQL是Apache Spark最广泛使用的一个组件&#xff0c;它提供了非常友好的接口来分布式处理结构化数据&#xff0c;在很多应用领域都有成功的生产实践&#xff0c;但是在超大规模集群和数据集上&#xff0c;Spark SQL仍然遇到不少易用性和可扩展性的挑战。为了应对这些挑战…...