PE文件学习

在这里插入图片描述

一、介绍

PE文件,即Portable Executable文件,是一种标准的文件格式,主要用于微软的Windows操作系统上。这种格式被用来创建可执行程序(如.exe文件)、动态链接库(.DLL文件)、设备驱动(.SYS文件)、ActiveX(.OCX文件)以及其他类型的可执行模块。
PE文件格式设计得非常灵活和强大,它允许程序在不同版本的Windows上运行,从而实现了一定程度的可移植性。PE文件格式是Windows系统加载和执行程序的基础,它允许操作系统将文件加载到内存中并控制其执行环境,同时提供了调试、安全性和资源管理等功能。了解PE文件的结构对于开发人员、反病毒工程师、逆向工程师以及安全研究人员来说非常重要。

二、PE文件解析

2.1 DOS头

DOS部分包含DOS MZ文件头和DOS块。

DOS MZ文件头

DOS MZ文件头就是一个结构体IMAGE_DOS_HEADER,用于保持与MS-DOS的兼容性,其定义如下所示:

typedef struct _IMAGE_DOS_HEADER { // DOS .EXE headerWORD e_magic; // Magic number 2字节,魔术数,对于PE文件应该是“MZ”WORD e_cblp; // Bytes on last page of file 最后一页的字节数WORD e_cp; // Pages in file 页面数WORD e_crlc; // Relocations 重定位项数WORD e_cparhdr; // Size of header in paragraphs 头部段数WORD e_minalloc; // Minimum extra paragraphs needed 最小额外段数WORD e_maxalloc; // Maximum extra paragraphs needed 最大额外段数WORD e_ss; // Initial (relative) SS value 初始(SS)选择器WORD e_sp; // Initial SP value 初始(SP)WORD e_csum; // Checksum 校验和WORD e_ip; // Initial IP value 初始IPWORD e_cs; // Initial (relative) CS value 初始CS选择器WORD e_lfarlc; // File address of relocation table PE头部相对于DOS头部的偏移量WORD e_ovno; // Overlay number 重叠编号WORD e_res[4]; // Reserved words 储存保留字段WORD e_oemid; // OEM identifier (for e_oeminfo) OEM标识符WORD e_oeminfo; // OEM information; e_oemid specific OEM信息WORD e_res2[10]; // Reserved words 更多储存保留字段DWORD e_lfanew; // File address of new exe header PE签名相对于DOS头部的偏移量} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

总共64字节(0x40),它有很多成员,但我们并不需要去深入的理解每个成员的含义和作用,这是因为这个结构体是给16位平台看的,而我们现在的环境大部分都是32位和64位的,所以现在的平台不在需要这个完整的结构体了,只需要其中的两个成员e_magic和e_lfanew。
你可以尝试在16进制的编辑器中去编辑某个EXE文件的DOS MZ文件头,除了e_magic和e_lfanew两个成员,其他的以0x00填充,然后保存文件,你会发现修改后的文件还是可以正常运行的。保留这两个成员的原因是因为它们代表着所说的PE指纹,操作系统也是根据这个来识别是否是PE文件的,所以不能更改、删除(e_magic是一种标识,e_lfanew则表示PE文件头的位置)。

DOS块

DOS块就是夹在DOS MZ文件头和PE文件头之间的内容,这里面的内容可以根据自己的需要随意的修改和添加,并不会影响文件的正常运行。

2.2 PE头

PE头整体就是如下这个结构体:

typedef struct _IMAGE_NT_HEADERS {DWORD Signature; // PE标识IMAGE_FILE_HEADER FileHeader; // 标准PE头IMAGE_OPTIONAL_HEADER32 OptionalHeader; // 扩展PE头
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

第一个成员就是PE标识,该标识不能被破坏,因为操作系统在启动一个程序的时候会检测这个标识。

标准PE头

标准PE头是PE头的第二个成员,它是如下所示的结构体:

typedef struct _IMAGE_FILE_HEADER {WORD Machine; // 可以运行在什么样的CPU上WORD NumberOfSections; // 表示节的数量DWORD TimeDateStamp; // 编译器填写的时间戳DWORD PointerToSymbolTable; // 调试相关DWORD NumberOfSymbols; // 调试相关WORD SizeOfOptionalHeader; // 扩展PE头的大小WORD Characteristics; // 文件属性
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

总共20个字节(0x14),其第一个成员Machine表示可以运行在什么样的CPU上,如果它的值位0x0则表示可以运行在任意的CPU上,支持在Intel 386以及后续的型号CPU运行则值为0x14C,支持64位的CPU则值为0x8664。
第二个成员NumberOfSections表示当前PE文件中节的数量,也就是节表中有几个结构体;第三个成员TimeDateStamp表示编译器编译的时候插入的时间戳,与文件属性里面的创建时间和修改时间是无关的。
第四、第五个成员是调试相关的,暂时不去了解;第六个成员SizeOfOptionalHeader表示扩展PE头的大小,默认情况下32位PE文件对应值为0xE0,64位PE文件对应值为0xF0。
第七个成员Characterstics用来记录当前PE文件的一些属性,该成员是16位大小,用于标识PE文件的特性。每个位代表一个特定的标志,通过位操作可以检查文件是否具有某个特征。下面列出了一些常见的标志位:

  1. IMAGE_FILE_RELOCS_STRIPPED(0x0001): 重定位信息已被删除,通常出现在最终的可执行文件中。
  2. IMAGE_FILE_EXECUTABLE_IMAGE(0x0002):文件是可执行的。
  3. IMAGE_FILE_LINE_NUMS_STRIPPED(0x0004):源代码行号信息已被删除。
  4. IMAGE_FILE_LOCAL_SYMS_STRIPPED(0x0008):本地符号已被删除。
  5. IMAGE_FILE_AGGRESIVE_WS_TRIM(0x0010):文件使用激进的工作集修剪策略。
  6. IMAGE_FILE_LARGE_ADDRESS_AWARE(0x0020):应用程序能处理大于2GB的地址空间,在32位系统中启用此标志才能使用超过2GB的虚拟地址空间。
  7. IMAGE_FILE_BYTES_REVERSED_LO(0x0080):低字节顺序被反转。
  8. IMAGE_FILE_BYTES_32BIT_MACHINE(0x0100):文件是为32位机器编译的。
  9. IMAGE_FILE_DEBUG_STRIPPED(0x0200):调试信息已被删除。
  10. IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP(0x0400):文件可以从交换设备运行。
  11. IMAGE_FILE_NET_RUN_FROM_SWAP(0x0800):文件可以从网络运行。
  12. IMAGE_FILE_SYSTEM(0x1000):文件是一个系统文件。
  13. IMAGE_FILE_DLL(0x2000):文件是一个动态链接库(DLL)。
  14. IMAGE_FILE_UP_SYSTEM_ONLY(0x4000):文件只能在用户处理器上运行。
  15. IMAGE_FILE_BYTES_REVERSED_HI(0x8000):高字节顺序被反转。

在处理PE文件时,可以通过按位与(&)操作符检查Characteristics字段是否设置了某个标志。例如,要检查文件是否为可执行文件,可以使用Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE的结果是否非零。同样地,可以组合多个标志来同时检查多个条件,例如,检查文件是否既可执行又是动态链接库,可以使用Characteristics & (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL)。

扩展PE头

扩展PE头在32位和64位环境下是不一样的,这里只介绍32位扩展PE头。如下结构体就是32位的扩展PE头:

typedef struct _IMAGE_OPTIONAL_HEADER {WORD Magic; // PE32:10B PE32+:20BBYTE MajorLinkerVersion; // 链接器版本号BYTE MinorLinkerVersion; // 链接器版本号DWORD SizeOfCode; // 所有代码节的总和(文件对齐后的大小),编译器填的(没用)DWORD SizeOfInitializedData; // 包含所有已经初始化数据的节的总大小(文件对齐后的大小),编译器填的(没用)DWORD SizeOfUninitializedData; // 包含未初始化数据的节的总大小(文件对齐后的大小),编译器填的(没用)DWORD AddressOfEntryPoint; // 程序入口DWORD BaseOfCode; // 代码开始的基址,编译器填的(没用)DWORD BaseOfData; // 数据开始的基址,编译器填的(没用)DWORD ImageBase; // 内存镜像基址DWORD SectionAlignment; // 内存对齐DWORD FileAlignment; // 文件对齐WORD MajorOperatingSystemVersion; // 标识操作系统版本号,主版本号WORD MinorOperatingSystemVersion; // 标识操作系统版本号,次版本号WORD MajorImageVersion; // PE文件自身的版本号 WORD MinorImageVersion; // PE文件自身的版本号WORD MajorSubsystemVersion; // 运行所需子系统版本号WORD MinorSubsystemVersion; // 运行所需子系统版本号DWORD Win32VersionValue; // 子系统版本的值,必须为0DWORD SizeOfImage; // 内存中整个PE文件的映射的尺寸DWORD SizeOfHeaders; // 所有头加节表按照文件对齐后的大小,否则加载会出错DWORD CheckSum; // 校验和WORD Subsystem; // 子系统,驱动程序(1)、图形界面(2) 、控制台/DLL(3)WORD DllCharacteristics; // 文件特性DWORD SizeOfStackReserve; // 初始化时保留的栈大小 DWORD SizeOfStackCommit; // 初始化时实际提交的大小 DWORD SizeOfHeapReserve; // 初始化时保留的堆大小DWORD SizeOfHeapCommit; // 初始化时实践提交的大小 DWORD LoaderFlags; // 调试相关DWORD NumberOfRvaAndSizes; // 目录项数目IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; // 表,结构体数组
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

扩展PE头的成员有很多,但我们不需要每个都记住,大概了解一些即可,重点关注如下几个成员:
成员Magic标识当前PE文件是32位还是64位,32位时该值对应0x10B,64位时该值对应0x20B。
成员AddressOfEntryPoint表示当前程序入口的地址,这个成员要与成员ImageBase相加才能得出真正的入口地址,成员ImageBase用来表示内存镜像基址,也就是PE文件在内存中按内存对齐展开后的首地址。
成员SizeOfImage表示内存中整个PE文件映射的大小,可比实际的值大(内存对齐之后的大小,也就表示必须是SectionAlignment的整数倍)。
成员CheckSum表示校验和,是用来判断文件是否被修改的,它的计算方法就是文件的两个字节与两个字节相加,最终的值(不考录溢出情况)就是校验和。
成员DllCharacteristics,它用来表示DLL文件或可执行文件的某些高级属性;它的数据宽度是16位(2字节),以下是常见的标志位:

  1. RESERVED0(0x0001)和RESERVED1(0x0002):保留位,必须为0.
  2. IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE(0x0040):指示DLL支持ASLR(地址空间布局随机化)。这意味着DLL在每次加载时会被加载到不同的地址,从而增加攻击者预测其在内存中位置的难度,提高安全性。
  3. IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY(0x0080):指示所有针对此DLL的代码完整性检查都是强制性的。这可以防止未经授权的修改。
  4. IMAGE_DLLCHARACTERISTICS_NX_COMPAT(0x0100):指示DLL与DEP(数据执行保护)兼容。DEP是一种硬件功能,阻止在标记为不可执行的内存区域中执行代码,有助于防止缓冲区溢出攻击。
  5. IMAGE_DLLCHARACTERISTICS_NO_ISOLATION(0x0200):指示DLL不使用应用程序隔离,如AppContainer或Job Objects。
  6. IMAGE_DLLCHARACTERISTICS_NO_SEH(0x0400):指示DLL不使用SEH(结构化异常处理)。如果设置了这个标志,那么任何尝试从这个DLL中抛出异常的代码都会失败,并导致进程终止。
  7. IMAGE_DLLCHARACTERISTICS_NO_BIND(0x0800):指示加载器不应该绑定到这个DLL的导入。这通常用于延迟加载的DLL,以减少启动时间。
  8. IAMGE_DLLCHARACTERISTICS_APPCONTAINER(0x1000):指示DLL是为AppContainer环境设计的。AppContainer是Windows8及更高版本中的一种隔离技术。
  9. IMAGE_DLLCHARACTERISTICS_WDM_DRIVER(0x2000):指示DLL是一个WDM(Windows Driver Model)驱动程序。
  10. IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE(0x8000):指示DLL是为终端服务器环境设计的,它可以处理多个会话并行运行的情况。

最后一个成员DataDirectory,占用128个字节,为一个IMAGE_DATA_DIRECTORY structure结构体数组(16个)。

typedef struct _IMAGE_DATA_DIRECTORY {DWORD VirtualAddress;DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

这个结构体有两个成员,一个成员占用4个字节,也就是8个字节。这个数组有16个数据,也就是16*8=128字节。

2.3 PE节表

在PE中,节数据有几个,分别对应着什么类型以及其他相关的属性都是由PE节表来决定的,PE节表是一个结构体数组,结构体定义如下所示:

#define IMAGE_SIZEOF_SHORT_NAME 8
typedef struct _IMAGE_SECTION_HEADER {BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // ASCII字符串(节名),可自定义,只截取8个字节,可以8个字节都是名字union { // Misc,双字,是该节在没有对齐前的真实尺寸,该值可以不准确DWORD PhysicalAddress; // 真实宽度,这两个值是一个联合结构,可以使用其中的任何一个DWORD VirtualSize; // 一般是取后一个} Misc; DWORD VirtualAddress; // 在内存中的偏移地址,加上ImageBase才是在内存中的真正地址DWORD SizeOfRawData; // 节在文件中对齐后的尺寸DWORD PointerToRawData; // 节区在文件中的偏移DWORD PointerToRelocations; // 调试相关DWORD PointerToLinenumbers; // 调试相关 WORD NumberOfRelocations; // 调试相关 WORD NumberOfLinenumbers; // 调试相关 DWORD Characteristics; // 节的属性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

代码中的注释可以大致了解到每个成员的作用,其中有两个成员来描述节的大小,分别是没有对齐前的真实尺寸和对齐后的宽度,这时候会出现一种情况就是对齐前的真实尺寸大于对齐后的宽度,这就是存在全局变量没有赋予初始值导致的,在文件存储中全局变量没有赋予初始值也就不占空间,但是内存中是必须要赋予初始值的,这时候宽度就大了一些,所以在内存中节是谁大就按照谁去展开。
与其他结构体一样,PE节也有属性,这就是成员Characteristics,其数据宽度是32位(4字节),其每一数据位对应的属性如下所示:

//
// Section characteristics.
//
// IMAGE_SCN_TYPE_REG 0x00000000 // Reserved.
// IMAGE_SCN_TYPE_DSECT 0x00000001 // Reserved.
// IMAGE_SCN_TYPE_NOLOAD 0x00000002 // Reserved.
// IMAGE_SCN_TYPE_GROUP 0x00000004 // Reserved.
#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved.
// IMAGE_SCN_TYPE_COPY 0x00000010 // Reserved.#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.
#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.
// IMAGE_SCN_TYPE_OVER 0x00000400 // Reserved.
#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.
#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat.
// 0x00002000 // Reserved.
// IMAGE_SCN_MEM_PROTECTED - Obsolete 0x00004000
#define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 // Reset speculative exceptions handling bits in the TLB entries for this section.
#define IMAGE_SCN_GPREL 0x00008000 // Section content can be accessed relative to GP
#define IMAGE_SCN_MEM_FARDATA 0x00008000
// IMAGE_SCN_MEM_SYSHEAP - Obsolete 0x00010000
#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
#define IMAGE_SCN_MEM_16BIT 0x00020000
#define IMAGE_SCN_MEM_LOCKED 0x00040000
#define IMAGE_SCN_MEM_PRELOAD 0x00080000#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 //
#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 //
#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 //
#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 //
#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified.
#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 //
#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 //
#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 //
#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 //
#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 //
#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 //
#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 //
#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 //
#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 //
// Unused 0x00F00000#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.

一个EXE文件的16进制图例子
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/866076.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

每日一练:攻防世界:Hidden-Message

追踪UDP数据流,没有任何隐藏信息: WP: 观察流量包 每个流的唯一的区别就是UDP的源地址srcport的最后一位在变化 都提取出来就是二进制序列 用tshark提取一下 //使用tshark过滤出源端口,使用cut裁取端口的最后一位 tshark -r 8…

金融(基金)行业信创国产化特点及统一身份认证解决方案

金融业在政策支持及自主驱动下,金融信创取得快速发展。从2020年开始,三期试点已扩容至5000余家,进入全面推广阶段。而基金行业信创建设与银行、证券、保险这些试点行业相比,进展较为缓慢。 基金行业信创当前面临的问题 与多家基…

开源的基于图像识别本地实名认证系统(本项目不借助任何api) v1.0

前言: 本项目主要是代替昂贵的实名认证服务api或者sdk,目前仍然存在很多缺点 一、具体介绍 1.组成: 人脸识别服务器分为两部分: (1)、http服务端 server.py共有四个函数: DrawFaceinIdCard:用户上传身份证图片后,服务端会对身份证进行抠人像和ocr处理…

[2024]docker-compose实战 (1)前言

前言 本文用来记录使用docker-compose来实战搭建一个多项目的测试环境. 环境中包含nodejs, php, html, redis, MongoDB, mysql. 在本次部署流程中, 尽量保证原镜像的"干净简洁", 尽量不会往镜像中加入各种软件和插件, 所有的配置尽可能的在宿主机映射进去. 项目…

互联网摸鱼日报(2024-07-03)

互联网摸鱼日报(2024-07-03) 36氪新闻 A股创纪录分红2.23万亿,两亿投资者如何掘金? 小米OV背后的隐秘功臣:揭ODM巨头华勤发家史 看麻了:日本科学家盯上“活人皮” 抛弃可口可乐的年轻人正在爱上无糖茶饮料 6月新能源交付量&a…

基于改进高斯-拉普拉斯滤波器的一维时间序列平滑与降噪(MATLAB)

以图像处理为例,拉普拉斯算子是基于图像的二阶导数来找到边缘并搜索过零点,传统的拉普拉斯算子常产生双像素宽的边缘,对于较暗区域中的亮斑进行边缘检测时,拉普拉斯运算就会使其变得更亮。因此,与梯度算子一样&#xf…

尺度变换挑战:深入解析目标检测中的尺度变化问题

尺度变换挑战:深入解析目标检测中的尺度变化问题 目标检测是计算机视觉领域的一个核心任务,它旨在识别图像中的目标并确定它们的位置。然而,目标检测算法在实际应用中常常面临尺度变化问题,即目标在图像中的大小可能差异巨大&…

OpenCV——实现裁剪YOLO格式的图片目标并按图片名保存

import os import cv2def crop_image(image_path, label_path, output_folder):# 读取图片img cv2.imread(image_path)height, width, _ img.shape# 读取标签文件with open(label_path, r) as file:labels file.readlines()img_id 1# 遍历每个标签for label in labels:part…

如何提高实验室分析结果的准确性呢

要提高实验室分析结果的准确性,可以从以下几个方面着手: 1、选择合适的实验方法 不同的实验方法具有不同的优缺点,实验方法的准确度直接影响测定结果的准确度。因此,在选择实验方法时,需要根据实验目的、实验原理、实…

spring security + vue,登录功能

前端代码:https://gitee.com/forgot940629/vuelogin 后端代码:https://gitee.com/forgot940629/springbootloginv2 参考代码:https://github.com/PuZhiweizuishuai/SpringSecurity-JWT-Vue-Deom 基于前后端分离实现登录功能。登录成功后后端向…

Java for循环倒序输出

1.实现一个for循环的倒序输出 在Java中,要实现一个for循环的倒序输出,通常我们会使用数组或集合(如ArrayList)作为数据源,然后通过倒序遍历这个数组或集合来实现。下面,我将给出一个详细的示例&#xff0c…

Linux高并发服务器开发(十一)UDP通信和本地socket通信

文章目录 1 TCP和UDP的区别2 UDPAPI流程服务端流程客户端流程 代码服务端客户端 3 本地socket通信服务端客户端客户端代码 1 TCP和UDP的区别 2 UDP API 流程 服务端流程 客户端流程 代码 服务端 #include<sys/socket.h> #include<stdio.h> #include<arpa/in…

二叉树与堆相关的时间复杂度问题

目录 满二叉树与完全二叉树高度h和树中节点个数N的关系 向上调整算法&#xff1a; 介绍&#xff1a; 复杂度推导&#xff1a; 向下调整算法&#xff1a; 介绍&#xff1a; 复杂度推导&#xff1a; 向上调整建堆&#xff1a; 介绍&#xff1a; 复杂度推导&#xff1a;…

Redis 集群 三主三从 主节点之间数据不会同步说明

Redis 集群中有一个特性&#xff0c;它不使用强一致性模型&#xff0c;而是使用最终一致性。Redis 集群通过分区 (sharding) 的方式来存储数据&#xff0c;不同的键可能会被存储在不同的节点上。每个键通过一个哈希槽 (hash slot) 来决定应该被存储到哪个节点上。一个 Redis 集…

Java中怎么使用httpclick发送application/x-www-form-urlencoded请求并接收text/xml数据呢?

项目中遇到一个请求方式要求&#xff1a; 1 、POST 请求 2 、Content-Type: text/xml; charsetutf-8 项目是Java代码 使用的httpclick发送的请求&#xff0c;接下来让我看下如何实现&#xff0c;本部分只提供核心请求代码&#xff0c;之前分享过httpclick发送请求工具类&…

CPU的核心数和线程数

CPU的核心数和线程数 一、关系&#xff1a; 1、线程数可以模拟出不同的CPU核心数。 CPU的核心数指的是硬件上存在着几个核心&#xff0c;而线程数可以模拟出多个核心数的功能。线程数越多&#xff0c;越有利于同时运行多个程序&#xff0c;因为线程数等同于在某个瞬间CPU能同…

【C++】POCO学习总结(二十):交叉编译poco-1.12.5p2

1、版本说明 1.1 poco-1.13 截止2024-07-03&#xff0c;POCO的稳定版本最高为poco-1.13.3&#xff0c;注意从poco-13.0开始需要编译器支持C17&#xff0c;否则编译时报错。 常见报错有&#xff1a; 1&#xff09;std::string的append重载版本问题&#xff0c;报错信息如下 …

Golang 基于 archive/zip 包实现文件

这里写自定义目录标题 摘要引言Go语言简介archive/zip 包概述&#xff1a;环境准备基础概念&#xff1a;压缩的基本概念&#xff1a;解压缩的基本概念&#xff1a;ZIP格式的特点&#xff1a;ZIP文件的组成&#xff1a;使用ZIP的优点&#xff1a; 使用 archive/zip 包进行文件压…

利用Arcgis绘制克吕金插值图

工作中我们常用到克吕金插值图&#xff0c;下面简单介绍下使用Arcmap绘制克吕金插值图的方法及注意事项&#xff0c;希望能帮到大家。 一、准备工作 软件&#xff1a;Arcgis 数据&#xff1a;点图层、研究范围 二、操作步骤 1 添加数据 打开Arcmap&#xff0c;从添加位置将…

WIN32核心编程 - 进程操作(二) 遍历进程 - 进程通信

公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 遍历进程 CreateToolhelp32Snapshot EnumProcesses NtQuerySystemInformation 进程通信 clipboard FileMapping NamedPipe Mailslot 遍历进程 CreateToolhelp32Snapshot #include &l…