11.PE文件之导出表(IMAGE_EXPORT_DIRECTORY)
目录
导出表定位以及解析(手动)
代码定位导出表并打印其数据
通过函数名查找导出函数地址
通过导出函数序号查找函数地址
移动导出表
PE中的导出表通常存在于动态链接库文件里.有些EXE也会存在导出表.导出表的主要作用是将PE中存在的函数引出到外部,以便其他人可以使用这些函数,实现代码的重用.导出表的存在可以让程序的开发者很容易清楚PE中到底有多少可以使用的函数.
Windows装载器在进行PE装载时,将与进程相关的DLL加载到对应虚拟地址空间.会根据导入表中登记的与该动态链接库相关的由INT指向的名称或编号来遍历DLL所在虚拟地址空间,通过函数名或编号查找导出表结构,从而确定该导出函数在虚拟地址空间中的起始地址VA,并将VA覆盖导入表的IAT相关项.
导出数据所在的节通常被命名为.edata,它包含了一些可被其他EXE程序访问的符号的相关信息,比如导出函数和资源等.这些符号通常出现在DLL中,但DLL也可以包含导入符号,而且在某些EXE中也可以有导出符号.
导出表定位以及解析(手动)
IMAGE_EXPORT_DIRECTORY
结构及成员含义如下:
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directorytypedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; // 未使用 DWORD TimeDateStamp; // 时间戳 WORD MajorVersion; // 未使用 WORD MinorVersion; // 未使用 DWORD Name; // 指向该导出表的文件名字符串RVA DWORD Base; // 导出函数的起始序号 DWORD NumberOfFunctions; // 所有导出函数的个数 DWORD NumberOfNames; // 以函数名字导出的函数个数 DWORD AddressOfFunctions; // 导出函数地址表RVA DWORD AddressOfNames; // 导出函数名称表RVA DWORD AddressOfNameOrdinals; // 导出函数序号表RVA
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
定位导出表:
IMAGE_OPTIONAL_HEADER -> DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT(0)].VirtualAddress + ImageBase.(如果在文件中解析只需将RVA转换为FOA加上当前文件首地址即可定位导出表).
通过WinHex工具查看PE文件默认属性
上述解析得知:
内存对齐 = 1000h
文件对齐 = 200h
导出表RVA = 0x00116640
转换为FOA = 0x000C8E40(RVA与FOA转换讲解)
成员含义:
Characteristics;// 未使用
TimeDateStamp;// 时间戳
MajorVersion;// 未使用
MinorVersion;// 未使用
Name;// 指向该导出表的文件名字符串,该值为RVA
Base;// 导出函数起始序号.(默认导出序号从1开始,但是通过xxx.def文件可自定义函数导出序号).
NumberOfFunctions;// 所有导出函数的个数.该值并不一定是真正导出函数个数.计算公式为:导出最大序号 - 导出最小序号 + 1.
这个DLL我自己编写测试的.实际导出函数为4个.序号为2,4,5,6.(6 - 2 + 1就是NumberOfFunctions结果).
NumberOfNames;// 以函数名字导出的函数个数.(通过xxx.def文件可以定义函数不导出名字).
测试DLL .def定义如下:
LIBRARYEXPORTSAdd @2Sub @6Mul @4 NONAMEDiv @5
AddressOfFunctions;// 导出函数地址表,该值为RVA,该成员相当于指向元素大小为4字节的数组,元素个数由NumberOfFunctions提供,每项元素为导出函数地址的RVA(加上ImageBase才是函数真正的地址).
AddressOfNames;// 导出函数名称表,该值为RVA,该成员相当于指向元素大小为4字节的数组,元素个数由 NumberOfNames提供,每项元素为导出函数名的RVA.
AddressOfNameOrdinals;// 导出函数序号表,该值为RVA,该成员相当于指向元素大小为2字节的数组,元素个数由 NumberOfNames提供,元素值加上Base为函数导出序号.通过函数名查找函数地址需要通过此值.
上述解析全解如下图:
导出表相对简单,只需要了解三张表结构以及含义很容易理解其对应关系.
代码定位导出表并打印其数据
读取文件代码
PVOID FileToMem(IN PCHAR szFilePath, OUT LPDWORD dwFileSize)
{//打开文件FILE* pFile = fopen(szFilePath, "rb");if (!pFile){printf("FileToMem fopen Fail \r\n");return NULL;}//获取文件长度fseek(pFile, 0, SEEK_END); //SEEK_END文件结尾DWORD Size = ftell(pFile);fseek(pFile, 0, SEEK_SET); //SEEK_SET文件开头//申请存储文件数据缓冲区PCHAR pFileBuffer = (PCHAR)malloc(Size);if (!pFileBuffer){printf("FileToMem malloc Fail \r\n");fclose(pFile);return NULL;}//读取文件数据fread(pFileBuffer, Size, 1, pFile);//判断是否为可执行文件if (*(PSHORT)pFileBuffer != IMAGE_DOS_SIGNATURE){printf("Error: MZ \r\n");fclose(pFile);free(pFileBuffer);return NULL;}if (*(PDWORD)(pFileBuffer + *(PDWORD)(pFileBuffer + 0x3C)) != IMAGE_NT_SIGNATURE){printf("Error: PE \r\n");fclose(pFile);free(pFileBuffer);return NULL;}if (dwFileSize){*dwFileSize = Size;}fclose(pFile);return pFileBuffer;
}
输出文件代码
VOID MemToFile(IN PCHAR szFilePath, IN PVOID pFileBuffer, IN DWORD dwFileSize)
{//打开文件FILE* pFile = fopen(szFilePath, "wb");if (!pFile){printf("MemToFile fopen Fail \r\n");return;}//输出文件fwrite(pFileBuffer, dwFileSize, 1, pFile);fclose(pFile);
}
定位并输出导出表数据
VOID PrintExportInfo()
{//读取文件二进制数据DWORD dwFileSize = 0;PCHAR pFileBuffer = FileToMem(FILE_PATH_IN, &dwFileSize);if (!pFileBuffer){return;}//定位结构PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_NT_HEADERS pNth = (PIMAGE_NT_HEADERS)(pFileBuffer + pDos->e_lfanew);PIMAGE_FILE_HEADER pFil = (PIMAGE_FILE_HEADER)((PUCHAR)pNth + 4);PIMAGE_OPTIONAL_HEADER pOpo = (PIMAGE_OPTIONAL_HEADER)((PUCHAR)pFil + IMAGE_SIZEOF_FILE_HEADER);//判断该PE文件是否有导出表if (!pOpo->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress){printf("该PE文件不存在导出表 \r\n");return;}PIMAGE_EXPORT_DIRECTORY pExp = (PIMAGE_EXPORT_DIRECTORY)(pFileBuffer + RvaToFoa(pFileBuffer, pOpo->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress));//基本导出表信息printf("IMAGE_EXPORT_DIRECTORY.Characteristics -> [0x%08x] \r\n", pExp->Characteristics);printf("IMAGE_EXPORT_DIRECTORY.TimeDateStamp -> [0x%08x] \r\n", pExp->TimeDateStamp);printf("IMAGE_EXPORT_DIRECTORY.MajorVersion -> [0x%04x] \r\n", pExp->MajorVersion);printf("IMAGE_EXPORT_DIRECTORY.MinorVersion -> [0x%04x] \r\n", pExp->MinorVersion);printf("IMAGE_EXPORT_DIRECTORY.Name -> [%s] \r\n", pFileBuffer + RvaToFoa(pFileBuffer, pExp->Name));printf("IMAGE_EXPORT_DIRECTORY.Base -> [0x%08x] \r\n", pExp->Base);printf("IMAGE_EXPORT_DIRECTORY.NumberOfFunctions -> [0x%08x] \r\n", pExp->NumberOfFunctions);printf("IMAGE_EXPORT_DIRECTORY.NumberOfNames -> [0x%08x] \r\n", pExp->NumberOfNames);//函数地址表printf("IMAGE_EXPORT_DIRECTORY.AddressOfFunctions -> [0x%08x] \r\n", pExp->AddressOfFunctions);LPDWORD pAddFunc = (LPDWORD)(pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfFunctions));for (size_t i = 0; i < pExp->NumberOfFunctions; i++){printf("AddressOfFunctions[%d] -> [0x%08x] \r\n", i, pAddFunc[i]);}//函数名称表printf("IMAGE_EXPORT_DIRECTORY.AddressOfNames -> [0x%08x] \r\n", pExp->AddressOfNames);LPDWORD pAddName = (LPDWORD)(pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfNames));for (size_t i = 0; i < pExp->NumberOfNames; i++){printf("AddressOfNames[%d] -> [%s] \r\n", i, pFileBuffer + RvaToFoa(pFileBuffer, pAddName[i]));}//函数序号表printf("IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals -> [0x%08x] \r\n", pExp->AddressOfNameOrdinals);LPWORD pAddOrdi = (LPWORD)(pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfNameOrdinals));for (size_t i = 0; i < pExp->NumberOfNames; i++){printf("AddressOfNameOrdinals[%d] -> [0x%04x] \r\n", i, pAddOrdi[i]);}//PE工具解析如下pAddFunc = (LPDWORD)(pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfFunctions));pAddName = (LPDWORD)(pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfNames));pAddOrdi = (LPWORD)(pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfNameOrdinals));size_t i, j;BOOL bFlag = FALSE;for (i = 0; i < pExp->NumberOfFunctions; i++){//函数地址表中值为空直接跳过本次循环if (pAddFunc[i] == NULL){printf("Ordinal[%04x] RVA[0x%08x] Name[NULL] \r\n", i + pExp->Base, pAddFunc[i]);continue;}//判断导出方式bFlag = FALSE;for ( j = 0; j < pExp->NumberOfNames; j++){if (pAddOrdi[j] == i){//通过函数名导出bFlag = TRUE;printf("Ordinal[%04x] RVA[0x%08x] Name[%s] \r\n", pAddOrdi[j] + pExp->Base, pAddFunc[pAddOrdi[j]], pFileBuffer + RvaToFoa(pFileBuffer, pAddName[j]));break;}}if (!bFlag){//通过序号导出printf("Ordinal[%04x] RVA[0x%08x] Name[NULL] \r\n", i + pExp->Base, pAddFunc[i]);}}}
通过函数名查找导出函数地址
- 通过导出表结构定位函数名称表(RVA),通过函数名称表中的值(RVA)定位导出函数名,函数名称表可以看作4字节数组,通过遍历数组查找是否有对应函数名.
- 如果函数名称表中查找到对应函数名,将函数名称表中索引值作为下标去函数序号表中查找对应值.
- 函数序号表中的值作为函数地址表中的下标即可得到导出函数地址(RVA).
//通过函数名查找导出函数地址
PVOID GetFunctionAddrByName(PCHAR pFileBuffer, PCHAR szName)
{//定位结构PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_NT_HEADERS pNth = (PIMAGE_NT_HEADERS)(pFileBuffer + pDos->e_lfanew);PIMAGE_FILE_HEADER pFil = (PIMAGE_FILE_HEADER)((PUCHAR)pNth + 4);PIMAGE_OPTIONAL_HEADER pOpo = (PIMAGE_OPTIONAL_HEADER)((PUCHAR)pFil + IMAGE_SIZEOF_FILE_HEADER);//判断该PE文件是否有导出表if (!pOpo->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress){printf("该PE文件不存在导出表 \r\n");return;}PIMAGE_EXPORT_DIRECTORY pExp = (PIMAGE_EXPORT_DIRECTORY)(pFileBuffer + RvaToFoa(pFileBuffer, pOpo->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress));//定位地址表,名称表,序号表LPDWORD pAddFunc = (LPDWORD)(pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfFunctions));LPDWORD pAddName = (LPDWORD)(pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfNames));LPWORD pAddOrdi = (LPWORD)(pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfNameOrdinals));for (size_t i = 0; i < pExp->NumberOfNames; i++){if (strcmp(szName,(PCSTR)(pFileBuffer + RvaToFoa(pFileBuffer, pAddName[i]))) == 0){//此值+ImageBase为真正函数地址return pAddFunc[pAddOrdi[i]];}}return NULL;
}
通过导出函数序号查找函数地址
- 查询序号 - IMAGE_EXPORT_DIRECTORY.Base = Index
- Index作为函数地址表中的下标即可得到导出函数地址.
//通过导出函数序号查找函数地址
PVOID GetFunctionAddrByOrdinals(PCHAR pFileBuffer, DWORD dwOrdinal)
{//定位结构PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_NT_HEADERS pNth = (PIMAGE_NT_HEADERS)(pFileBuffer + pDos->e_lfanew);PIMAGE_FILE_HEADER pFil = (PIMAGE_FILE_HEADER)((PUCHAR)pNth + 4);PIMAGE_OPTIONAL_HEADER pOpo = (PIMAGE_OPTIONAL_HEADER)((PUCHAR)pFil + IMAGE_SIZEOF_FILE_HEADER);//判断该PE文件是否有导出表if (!pOpo->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress){printf("该PE文件不存在导出表 \r\n");return;}PIMAGE_EXPORT_DIRECTORY pExp = (PIMAGE_EXPORT_DIRECTORY)(pFileBuffer + RvaToFoa(pFileBuffer, pOpo->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress));//定位地址表,名称表,序号表LPDWORD pAddFunc = (LPDWORD)(pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfFunctions));//判断序号是否正常if (dwOrdinal - pExp->Base > pExp->NumberOfFunctions){return NULL;}return pAddFunc[dwOrdinal - pExp->Base];
}
移动导出表
- 新增节用来存储新导入表
- 复制默认导出表数据到新增节起始位置,并修正IMAGE_OPTION_HEADER目录项中VirtualAddress
- 修正导出表结构中Name成员(RVA)
- 复制导出函数地址表.直接复制即可,并修正AddressOfFunctions.
- 复制导出函数名称表.修正AddressOfNames.通过NumberOfNames循环拷贝默认函数名并修正其对应RVA.
- 复制导出函数序号表.直接复制即可,并修正AddressOfNameOrdinals.
VOID MoveExportTable()
{//读取文件二进制数据DWORD dwFileSize = 0;PCHAR pFileBuffer = FileToMem(FILE_PATH_IN, &dwFileSize);if (!pFileBuffer){return;}//新增节存储导出表pFileBuffer = AddNewSection(pFileBuffer, 0x2000, &dwFileSize);//定位结构PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_NT_HEADERS pNth = (PIMAGE_NT_HEADERS)(pFileBuffer + pDos->e_lfanew);PIMAGE_FILE_HEADER pFil = (PIMAGE_FILE_HEADER)((PUCHAR)pNth + 4);PIMAGE_OPTIONAL_HEADER pOpo = (PIMAGE_OPTIONAL_HEADER)((PUCHAR)pFil + IMAGE_SIZEOF_FILE_HEADER);PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((PUCHAR)pOpo + pFil->SizeOfOptionalHeader);//判断该PE文件是否有导出表if (!pOpo->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress){printf("该PE文件不存在导出表 \r\n");return;}PIMAGE_EXPORT_DIRECTORY pExp = (PIMAGE_EXPORT_DIRECTORY)(pFileBuffer + RvaToFoa(pFileBuffer, pOpo->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress));//导出地址表,名称表,序号表大小DWORD dwSizeOfAddrFunc = 4 * pExp->NumberOfFunctions;DWORD dwSizeOfAddrName = 4 * pExp->NumberOfNames;DWORD dwSizeOfAddrOrdi = 2 * pExp->NumberOfNames;//修复可选PE头中目录项指向PUCHAR pCurrent = pFileBuffer + pSec[pFil->NumberOfSections - 1].PointerToRawData;pOpo->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = FoaToRva(pFileBuffer, pCurrent - pFileBuffer);//拷贝导出表结构PIMAGE_EXPORT_DIRECTORY pNewExp = (PIMAGE_EXPORT_DIRECTORY)pCurrent;memcpy(pCurrent, pExp, sizeof(IMAGE_SECTION_HEADER));pCurrent += sizeof(IMAGE_SECTION_HEADER);//拷贝导出表结构中Name成员 DWORD dw = RvaToFoa(pFileBuffer, pExp->Name);dw += (DWORD)pFileBuffer;PUCHAR pOldDllName = pFileBuffer + RvaToFoa(pFileBuffer, pExp->Name);DWORD dwDllNameLength = strlen(pOldDllName);memcpy(pCurrent, pOldDllName, dwDllNameLength);//修复导出表结构中Name指向pNewExp->Name = FoaToRva(pFileBuffer, pCurrent - pFileBuffer);pCurrent = pCurrent + dwDllNameLength + 1;//拷贝地址表数据PUCHAR pOldAddrFunc = pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfFunctions);memcpy(pCurrent, pOldAddrFunc, dwSizeOfAddrFunc);//修复导出表结构中AddressOfFunctions指向pNewExp->AddressOfFunctions = FoaToRva(pFileBuffer, pCurrent - pFileBuffer);pCurrent += dwSizeOfAddrFunc;//拷贝名称表数据PDWORD pOldAddrName = pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfNames);memcpy(pCurrent, pOldAddrName, dwSizeOfAddrName);//修复导出表结构中AddressOfNames指向pNewExp->AddressOfNames = FoaToRva(pFileBuffer, pCurrent - pFileBuffer);//指向当前导出名称表PDWORD pNewAddrName = pCurrent;pCurrent += dwSizeOfAddrName;for (size_t i = 0; i < pExp->NumberOfNames; i++){//遍历并修复导出表名称表的指向//默认函数地址表中RVA转FOA并获取文件中地址PUCHAR pOldNameAddr = pFileBuffer + RvaToFoa(pFileBuffer, pOldAddrName[i]);//获取函数名长度DWORD dwFunNameSize = strlen(pOldNameAddr) + 1;//拷贝函数名memcpy(pCurrent, pOldNameAddr, dwFunNameSize);//修正新导出名称表中地址pNewAddrName[i] = FoaToRva(pFileBuffer, pCurrent - pFileBuffer);pCurrent += dwFunNameSize;}//拷贝序号表数据PUCHAR pOldAddrOrdi = pFileBuffer + RvaToFoa(pFileBuffer, pExp->AddressOfNameOrdinals);memcpy(pCurrent, pOldAddrOrdi, dwSizeOfAddrOrdi);//修复导出表结构中AddressOfNameOrdinals指向pNewExp->AddressOfNameOrdinals = FoaToRva(pFileBuffer, pCurrent - pFileBuffer);pCurrent += dwSizeOfAddrOrdi;//将二进制数据输出到文件MemToFile(FILE_PATH_OUT, pFileBuffer, dwFileSize);
}
查看移动后导出表位置
移动后解析数据无误
获取函数地址成功
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- DDR SDRAM 学习笔记 —— TDQS
DDR SDRAM 学习笔记 —— TDQS 器件类型:根据 JESD79-4B,DDR4 SDRAM x4/x8 引脚图可知,只有 x8 device才有 TDQS 引脚。 应用场景:一般应用于 x4 / x8 内存条混插的场景。 作用:在 Datasheet 中,Pinout …...
2024/5/2 20:05:19 - golang:reflect(反射)基本使用
reflect获取type: package mainimport ("fmt""reflect" )type Node struct {val intnext *Node }func reflectOfType(x interface{}) {t : reflect.TypeOf(x)//typefmt.Printf("type:%v \n", t)//type分为name和kind,kind是底层数据…...
2024/5/2 20:05:15 - 21天leetcode打卡第三天
下面展示一些 路径交叉。 给你一个整数数组 distance 。从 X-Y 平面上的点 (0,0) 开始,先向北移动 distance[0] 米,然后向西移动 distance[1] 米,向南移动 distance[2] 米,向东移动 distance[3] 米,持续移动。也就是说…...
2024/5/2 20:05:11 - 常用环境命令
常用环境命令登录远程服务器方式一:使用Windows自带的Windows PowerShell方式二:使用Git软件创建环境名查看环境列表激活环境安装requirements.txt登录远程服务器 方式一:使用Windows自带的Windows PowerShell 命令:ssh rejul17…...
2024/5/2 20:05:08 - 数据库原理及应用(五)SQL
SQL的功能分类: 数据定义功能DDL(定义模式、内模式、外模式) 数据操纵功能DML(增删改查等功能) 数据控制功能DCL(完整性校验) SQL的特点 1.SQL具有自含式和嵌入式两种(自含式可以独…...
2024/5/4 17:07:57 - 软件测试体系学习及构建(13)-测试基础之测试工程师的基本要求
(13)-测试基础之测试工程师的基本要求1 软性能力1.1 沟通表达能力1.2 逻辑思维能力1.3 原则和立场1.4 情绪管理1.5 抗压性1.6 学习成长1.7 时间管理1.8 问题分析排查能力1.9 客户导向1.10 质量意识1.11 制定计划能力1.12 团队合作1.13 风险意识2 技术能力…...
2024/5/5 20:38:06 - HDFS写数据流
#FSDataInputStream封装了DFSInputStream 大部分的HDFS程序对文件操作采用的是“一次写多次读取”的模式。 1.HDFS客户端先向DFSInputStream发起创建文件请求,创建输出流。DFSInputStream对想象中的Create()函数创建一个文件。 2.Distribu…...
2024/5/2 19:38:20 - Nginx配置RTMP 宝塔面板无法进入phpMyAdmin
因为要用rtmp,所以重装了Nginx,导致Nginx的配置丢失了。 而且rtmp占用了原本phpMyAdmin的1935端口,修改过后也没用。 服务器内查询端口,没有发现修改过后的端口。 原本的配置是 user www www; worker_processes auto; error_l…...
2024/5/5 23:24:14 - 二分查找算法的经典题目
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结前言 二分查找算法可以很快地找出数组中的某个元素或者是某个边界。 一、经典题目…...
2024/5/5 20:55:42 - PyTorch深度学习实践(线性回归、逻辑回归)
线性回归(Linear Regression): 逻辑回归(Logistic Regression)...
2024/5/2 20:04:48 - 静态路由实验
静态路由/负载均衡 静态路由:手写路由表 1.新建拓扑(如图1.1) . 图1.1 2.开启设备,配置PC设备及R1-R4四台路由器接口IP(如图1.2,1.3) 图1.2 例R1: [R1-GigabitEthernet0/0/0]ip address …...
2024/5/5 22:27:37 - 七.激光SLAM框架学习之A-LOAM框架---速腾Robosense-16线雷达室内建图
这一章暂时不更之前定的计划,目前时间没那么多,那个太花时间了。 1.雷达测试: 首先安装好雷达在平台上,供电准备好,雷达网口接终端,雷达本机ip是192.168.1.200,终端ip要配置成192.168.1.102&a…...
2024/5/2 20:04:39 - 循环链表的拼接
两个循环链表拼接成一个链表 两个循环链表testA和testB,first1和first2分别是指向循环链表的头指针,编写算法函数merge(Node *first1, Node *first2),其功能是将循环链表testB链接到循环链表testA之后,使链接后的链表仍是循环链表。输出的参考样张如下所示 思路&a…...
2024/5/2 20:04:35 - ubuntu 安装软件时候使用的指令
建议使用 aptitude 而不是apt-get...
2024/5/2 20:04:31 - 线程与进程是什么?
线程与进程的主要区别是:(同一进程中的)线程在共享的内存空间中运行,而进程在不同的内存空间中运行;线程使用wait(),notify(),notifyAll()等方法直接与其他线程(同一进程)…...
2024/5/2 20:04:27 - Kafka生产者发送数据
往kafka发送消息,提供三种构造函数形参: -- ProducerRecord(topic, partition, key, value) -- ProducerRecord(topic, key, value) -- ProducerRecord(topic, value)注: <1> 若指定Partition ID,则PR被发送至指定Partition; <2>…...
2024/5/2 20:04:23 - Java EE实用教程( 第 3 版 )编程实现教材82页【实例3.12】,熟悉sort标签的用法
编程实现教材82页【实例3.12】,熟悉sort标签的用法效果图index.jsp<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <html> <h…...
2024/5/2 20:04:19 - 开启状态界面、咋不博学监控、rewrite、if
nginx特别篇2nginx开启状态界面状态页面监控与配置配置zabbix页面rewriteif基于浏览器实现分离案例防盗链案例nginx 开启状态界面 开启status: location /status {stub_status on;allow 172.16.0.0/16;deny all; }示例: [rootlocalhost ~]# vim /usr…...
2024/5/2 20:04:15 - 剑指 offer day15-17
257. 二叉树的所有路径 题目: 给你一个二叉树的根节点 root ,按任意顺序 ,返回所有从根节点到叶子节点的路径。 题解: constructPaths函数: 1.参数:当前节点,当前路径,以及最终…...
2024/5/2 20:04:12 - reg.exec()在正则表达式中
reg.exec() 的作用是专门在正则中查找字符串中所有敏感词的内容和位置的函数。找到一个敏感词,就会返回一个数组: 数组:[ 0: "敏感词的内容", index: 敏感词的下标位置i ][\u4e00-\u9fa5]匹配中文字符,代表一个汉字。 <script…...
2024/5/2 20:04:08
最新文章
- MyBatisPlus @TableLogic实现全局自动逻辑删除
一、背景 有一天,小王在编写代码时实现了一个删除操作,但由于测试场景覆盖不全,上线后不慎删除了系统中的部分业务数据。幸运的是,系统已经开启了binlog日志功能,使得我们能够根据日志来恢复这些误删的数据。这一事故…...
2024/5/5 23:44:36 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - Redis之缓存穿透、击穿、雪崩
一、缓存穿透 缓存穿透是指在使用缓存系统时,特定的查询在缓存和数据库中都找不到结果,导致每次查询都要访问数据库,从而增加数据库的压力,降低系统的性能,若黑客利用此漏洞进行攻击可能压垮数据库。 当一个查询请求经…...
2024/5/4 2:50:43 - Docker Desktop+WSL2安装到自定义路径
现在大多数软件实在太“流氓”了,在安装过程中,根本不让你选择安装路径,默认安装到$HOME下(windows C盘),随着软件的使用增多,可能磁盘空间不够,这个时候就想着,看看某些…...
2024/5/4 9:55:38 - Kafka架构概述
Kafka的体系结构 Kafka是由Apache软件基金会管理的一个开源的分布式数据流处理平台。Kafka具有支持消息的发布/订阅模式、高吞吐量与低延迟、持久化、支持水平扩展、高可用性等特点。可以将Kafka应用于大数据实时处理、高性能数据管道、流分析、数据集成和关键任务应用等场景。…...
2024/5/5 8:31:13 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/4 23:54:56 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/5/4 23:54:56 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/5/4 23:54:56 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/4 23:55:17 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/5/4 23:54:56 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/5/4 23:55:05 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/5/4 23:54:56 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/5/4 23:55:16 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/5/4 23:54:56 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/5/4 18:20:48 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/5/4 23:54:56 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/5/4 23:55:17 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/5/4 23:55:06 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/5/4 23:54:56 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/4 23:55:06 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/5/5 8:13:33 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/5/4 23:55:16 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/5/4 23:54:58 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/4 23:55:01 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/5/4 23:54:56 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57