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

PHP动态网站开发期末考试/网址导航大全

PHP动态网站开发期末考试,网址导航大全,做网站购买域名之后,无锡响应式网站建设脱壳修复是指在进行加壳保护后的二进制程序脱壳操作后,由于加壳操作的不同,有些程序的导入表可能会受到影响,导致脱壳后程序无法正常运行。因此,需要进行修复操作,将脱壳前的导入表覆盖到脱壳后的程序中,以…

脱壳修复是指在进行加壳保护后的二进制程序脱壳操作后,由于加壳操作的不同,有些程序的导入表可能会受到影响,导致脱壳后程序无法正常运行。因此,需要进行修复操作,将脱壳前的导入表覆盖到脱壳后的程序中,以使程序恢复正常运行。一般情况下,导入表被分为IAT(Import Address Table,导入地址表)和INT(Import Name Table,导入名称表)两个部分,其中IAT存储着导入函数的地址,而INT存储着导入函数的名称。在脱壳修复中,一般是通过将脱壳前和脱壳后的输入表进行对比,找出IAT和INT表中不一致的地方,然后将脱壳前的输入表覆盖到脱壳后的程序中,以完成修复操作。

数据目录表的第二个成员指向导入表,该指针在PE开头位置向下偏移0x80h处,此处PE开始位置为0xF0h也就是说导入表偏移地址应该在0xf0+0x80h=170h如下图中,导入表相对偏移为0x21d4h

这个地址的读取同样可以使用PeView工具得到,通过输入DataDirectory读者可看到如下图所示的输出信息,其中第二行则是导入表的地址。

这里的0x21d4是一个RVA地址,需要将其转换为磁盘文件FOA偏移才能定位到导入表在文件中的位置,使用RvaToFoa命令可快速完成计算,转换后的文件偏移为0x11d4

此处我们也可以通过使用虚拟偏移地址减去实际偏移地址来得到这个参数,由于0x21d4位于.rdata节,此时的rdata虚拟偏移是0x2000而实际偏移则是0x1000通过使用2000h-1000h=1000h,接着再通过0x21d4h-0x1000h=11D4h同样可以得到相对FOA文件偏移。

我们通过使用WinHex工具跳转到11d4位置处,读者此时能看到如下图所示的地址信息。

如上图就是导入表中的IID数组,每个IID结构包含一个装入DLL的描述信息,现在有三个导入DLL文件,则第四个是一个全部填充为0的结构,标志着IID数组的结束,每一个结构有五个四字节构成,该结构体定义如下所示;

typedef struct _IMAGE_IMPORT_DESCRIPTOR
{union{DWORD   Characteristics;DWORD   OriginalFirstThunk;} DUMMYUNIONNAME;DWORD   TimeDateStamp;DWORD   ForwarderChain;DWORD   Name;DWORD   FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

我们以第一个调用动态链接库为例,其地址与结构的说明如下所示:

  • 0000 22C0 => OrignalFirstThunk => 指向输入名称表INT的RVA
  • 0000 0000 => TimeDateStamp => 指向一个32位时间戳,默认此处为0
  • 0000 0000 => ForwardChain => 转向API索引,默认为0
  • 0000 244A => Name => 指向DLL名字的指针
  • 0000 209C => FirstThunk => 指向输入地址表IAT的RVA

每个IID结构的第四个字段指向的是DLL名称的地址,以第一个动态链接库为例,其RVA是0000 244A 将其减去1000h得到文件偏移144A,跳转过去看看,调用的是USER32.dll库。

上方提到的两个字段OrignalFirstThunkFirstThunk都可以指向导入结构,在实际装入中,当程序中的OrignalFirstThunk值为0时,则就要看FirstThunk里面的数据,FirstThunk常被叫做IAT它是在程序初始化时被动态填充的,而OrignalFirstThunk常被叫做INT,它是不可改变的,之所以会保留两份是因为,有些时候会存在反查的需求,保留两份是为了更方便的实现。

在上述流程中,我们找到了User32.dllOrignalFirstThunk,其地址为22C0,使用该值减去1000h 得到 12c0h,在偏移为12c0h处保存的就是一个IMAGE_THUNK_DATA32数组,他存储的内容就是指向 IMAGE_IMPORT_BY_NAME 结构的地址,最后一个元素以一串0000 0000作为结束标志,先来看一下IMAGE_THUNK_DATA32的定义规范。

typedef struct _IMAGE_THUNK_DATA32
{union{DWORD ForwarderString;DWORD Function;DWORD Ordinal;DWORD AddressOfData;} u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;

直接使用WinHex定位到12c0h地址处,此处就是OrignalFirstThunk中保存的INT的内容,如下图,除去最后一个结束符00000000以外,一共有19个四字节,则说明User32.dll中导入了19API函数。

再来看一下FirstThunk也就是IAT中的内容,由于User32FirstThunk字段默认值是209C,使用该值减去1000h即可得到109ch,此处就是IAT的内容,使用WinHex定位过去,可以发现两者内容时完全一致的。

接着我们以第一个导入RVA地址0000243Eh,用该值减去1000h得到143Eh,定位过去正好是EndDialog的字符串,同样的方式,第二个导入RVA地址0000242ch,用该值减去1000h得到142ch 定位过去正好是PostQuitMessage的字符串,如下图绿色部分所示。

如上图中我们已第二个函数PostQuitMessage为例,前两个字节0271h表示的是Hint值,后面的蓝色部分则是PostQuitMessage字符串,最后的0标志结束标志。

当程序被运行前,它的FirstThunk值与OrignalFirstThunk字段都指向同一片INT中,此处我们使用LyDebugger工具对程序进行内存转存,执行命令LyDebugger DumpMemory --path Win32Project.exe生成dump.exe文件,该文件则是内存中的镜像数据。

当程序运行后,OrignalFirstThunk字段不会发生变化,但是FirstThunk值的指向已经改变,系统在装入内存时会自动将FirstThunk指向的偏移转化为一个个真正的函数地址,并回写到原始空间中,定位到dump.exe文件FirstThunk 输入表RVA地址处209Ch查看,如下图;

接着定位到OrignalFirstThunk处,也就是22c0h,观察可发现,绿色的INT并没有变化,但是黄色的IAT则相应的发生了变化

我们以IAT中第一个0x75f8ab90为例,使用x64dbg跟进一下,则可知是载入内存后EngDialog的内存地址。

当系统装入内存后,其实只会用到IAT中的地址解析,输入表中的INT就已经不需要了,此地址每个系统之间都会不同,该地址是操作系统动态计算后填入的,这也是为什么会存在导入表这个东西的原因,就是为了解决不同系统间的互通问题。

有时我们在脱壳时,由于IAT发生了变化,所以程序会无法被正常启动,我们Dump出来的文件由于使用的是内存地址,导入表不一致所以也就无法正常运行,可以使用原始的未脱壳的导入表地址对脱壳后的文件导入表进行覆盖替换,以此来修复导入表错误。

要实现这段代码,读者可依次读入脱壳前与脱壳后的两个文件,通过循环的方式将脱壳前的导入表地址覆盖到脱壳后的程序中,以此来实现对导入表的修复功能,如下代码BuildIat则是笔者封装首先的一个修复程序,读者可自行体会其中的原理;

#include <stdio.h>
#include <Windows.h>
#include <TlHelp32.h>
#include <ImageHlp.h>
#pragma comment(lib,"Dbghelp")DWORD RvaToFoa(PIMAGE_NT_HEADERS pImgNtHdr, LPVOID lpBase, DWORD dwRva)
{PIMAGE_SECTION_HEADER pImgSecHdr;pImgSecHdr = ImageRvaToSection(pImgNtHdr, lpBase, dwRva);return dwRva - pImgSecHdr->VirtualAddress + pImgSecHdr->PointerToRawData;
}void BuildIat(char *pSrc, char *pDest)
{PIMAGE_DOS_HEADER pSrcImgDosHdr, pDestImgDosHdr;PIMAGE_NT_HEADERS pSrcImgNtHdr, pDestImgNtHdr;PIMAGE_SECTION_HEADER pSrcImgSecHdr, pDestImgSecHdr;PIMAGE_IMPORT_DESCRIPTOR pSrcImpDesc, pDestImpDesc;HANDLE hSrcFile, hDestFile;HANDLE hSrcMap, hDestMap;LPVOID lpSrcBase, lpDestBase;// 打开源文件与目标文件hSrcFile = CreateFile(pSrc, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hSrcFile == INVALID_HANDLE_VALUE)return;hDestFile = CreateFile(pDest, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hDestFile == INVALID_HANDLE_VALUE)return;// 分别创建两份磁盘映射hSrcMap = CreateFileMapping(hSrcFile, NULL, PAGE_READONLY, 0, 0, 0);hDestMap = CreateFileMapping(hDestFile, NULL, PAGE_READWRITE, 0, 0, 0);// MapViewOfFile 设置到指定位置lpSrcBase = MapViewOfFile(hSrcMap, FILE_MAP_READ, 0, 0, 0);lpDestBase = MapViewOfFile(hDestMap, FILE_MAP_WRITE, 0, 0, 0);pSrcImgDosHdr = (PIMAGE_DOS_HEADER)lpSrcBase;pDestImgDosHdr = (PIMAGE_DOS_HEADER)lpDestBase;printf("[+] 原DOS头: 0x%08X --> 目标DOS头: 0x%08X \n", pSrcImgDosHdr, pDestImgDosHdr);pSrcImgNtHdr = (PIMAGE_NT_HEADERS)((DWORD)lpSrcBase + pSrcImgDosHdr->e_lfanew);pDestImgNtHdr = (PIMAGE_NT_HEADERS)((DWORD)lpDestBase + pDestImgDosHdr->e_lfanew);printf("[+] 原NT头: 0x%08X --> 目标NT头: 0x%08X \n", pSrcImgNtHdr, pDestImgNtHdr);pSrcImgSecHdr = (PIMAGE_SECTION_HEADER)((DWORD)&pSrcImgNtHdr->OptionalHeader + pSrcImgNtHdr->FileHeader.SizeOfOptionalHeader);pDestImgSecHdr = (PIMAGE_SECTION_HEADER)((DWORD)&pDestImgNtHdr->OptionalHeader + pDestImgNtHdr->FileHeader.SizeOfOptionalHeader);printf("[+] 原节表头: 0x%08X --> 目标节表头: 0x%08X \n", pSrcImgSecHdr, pDestImgSecHdr);DWORD dwImpSrcAddr, dwImpDestAddr;dwImpSrcAddr = pSrcImgNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;dwImpDestAddr = pDestImgNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;printf("[-] 原始IAT虚拟地址: 0x%08X --> 目标IAT虚拟地址: 0x%08X \n", dwImpSrcAddr, dwImpDestAddr);dwImpSrcAddr = (DWORD)lpSrcBase + RvaToFoa(pSrcImgNtHdr, lpSrcBase, dwImpSrcAddr);dwImpDestAddr = (DWORD)lpDestBase + RvaToFoa(pDestImgNtHdr, lpDestBase, dwImpDestAddr);printf("[+] 导入表原始偏移: 0x%08X --> 导入表目的偏移: 0x%08X \n", dwImpSrcAddr, dwImpDestAddr);// 定位导入表pSrcImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)dwImpSrcAddr;pDestImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)dwImpDestAddr;printf("[*] 定位原始导入表地址: 0x%08X --> 定位目的导入表地址: 0x%08X \n\n\n", pSrcImpDesc, pDestImpDesc);PIMAGE_THUNK_DATA pSrcImgThkDt, pDestImgThkDt;// 循环遍历导入表,条件是两者都不为空while (pSrcImpDesc->Name && pDestImpDesc->Name){char *pSrcImpName = (char*)((DWORD)lpSrcBase + RvaToFoa(pSrcImgNtHdr, lpSrcBase, pSrcImpDesc->Name));char *pDestImpName = (char*)((DWORD)lpDestBase + RvaToFoa(pDestImgNtHdr, lpDestBase, pDestImpDesc->Name));pSrcImgThkDt = (PIMAGE_THUNK_DATA)((DWORD)lpSrcBase + RvaToFoa(pSrcImgNtHdr, lpSrcBase, pSrcImpDesc->FirstThunk));pDestImgThkDt = (PIMAGE_THUNK_DATA)((DWORD)lpDestBase + RvaToFoa(pDestImgNtHdr, lpDestBase, pDestImpDesc->FirstThunk));printf("\n [*] 链接库: %10s 原始偏移: 0x%08X --> 修正偏移: 0x%08X \n\n", pDestImpName, *pDestImgThkDt, *pSrcImgThkDt);// 开始赋值,将原始的IAT表中索引赋值给目标地址while (*((DWORD *)pSrcImgThkDt) && *((DWORD *)pDestImgThkDt)){DWORD dwIatAddr = *((DWORD *)pSrcImgThkDt);*((DWORD *)pDestImgThkDt) = dwIatAddr;printf("\t --> 源RVA: 0x%08X --> 拷贝地址: 0x%08X --> 修正为: 0x%08X \n", pSrcImgThkDt, pDestImgThkDt, dwIatAddr);pSrcImgThkDt++;pDestImgThkDt++;}pSrcImpDesc++;pDestImpDesc++;}UnmapViewOfFile(lpDestBase); UnmapViewOfFile(lpSrcBase);CloseHandle(hDestMap); CloseHandle(hSrcMap);CloseHandle(hDestFile); CloseHandle(hSrcFile);
}void Banner()
{printf(" ____        _ _     _    ___    _  _____  \n");printf("| __ ) _   _(_) | __| |  |_ _|  / \\|_   _| \n");printf("|  _ \\| | | | | |/ _` |   | |  / _ \\ | |  \n");printf("| |_) | |_| | | | (_| |   | | / ___ \\| |  \n");printf("|____/ \\__,_|_|_|\\__,_|  |___/_/   \\_\\_|   \n");printf("                                           \n");printf("IAT 修正拷贝工具 By: LyShark \n");printf("Usage: BuildIat [脱壳前文件] [脱壳后文件] \n\n\n");
}int main(int argc, char * argv[])
{Banner();if (argc == 3){// 使用原始的IAT表覆盖dump出来的镜像BuildIat(argv[1], argv[2]);}return 0;
}

代码的使用很简单,分别传入脱壳前文件路径,以及脱壳后的路径,则读者可看到如下图所示的输出信息,至此即实现了脱壳修复功能。

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/ff060496.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章:

2.9 PE结构:重建导入表结构

脱壳修复是指在进行加壳保护后的二进制程序脱壳操作后&#xff0c;由于加壳操作的不同&#xff0c;有些程序的导入表可能会受到影响&#xff0c;导致脱壳后程序无法正常运行。因此&#xff0c;需要进行修复操作&#xff0c;将脱壳前的导入表覆盖到脱壳后的程序中&#xff0c;以…...

MybatisPlus插件功能详细介绍 自动分页 通用分页实体

本课程全面讲解了Mybatis框架的使用&#xff0c;从快速入门到原理分析再到实战应用。每一个知识点都有案例进行演示学习&#xff0c;最终通过学习你将全面掌握&#xff0c;从而使Mybatis的开发更加的高效&#xff0c;系统学习 通过项目的开发大家应该能发现&#xff0c;单表的C…...

ES kibana 创建索引快速脚本

删除 DELETE my_test创建索引 创建自定义ngram分词器 PUT my_test {"settings": {"index.max_ngram_diff": "32","analysis": {"analyzer": {"code_analyzer": {"tokenizer": "code_tokenizer&q…...

2023年09月编程语言流行度排名

点击查看最新编程语言流行度排名&#xff08;每月更新&#xff09; 2023年09月编程语言流行度排名 编程语言流行度排名是通过分析在谷歌上搜索语言教程的频率而创建的 一门语言教程被搜索的次数越多&#xff0c;大家就会认为该语言越受欢迎。这是一个领先指标。原始数据来自…...

linux对一个文件夹中的所有文件重命名

在Linux中&#xff0c;你可以使用mv命令对一个文件夹下的所有文件进行重命名。下面是几种常见的用法&#xff1a; 方法1: 批量添加前缀或后缀&#xff1a; $ cd 目标文件夹路径 $ for file in *; do mv "$file" "前缀$file"; done # 添加前缀 $ for fil…...

Greenplum执行SQL卡住的问题

问题 今天社区群里面一位同学反映他的SQL语句执行会hang住&#xff0c;执行截图如下。 分析 根据提示信息&#xff0c;判断可能是网络有问题&#xff0c;或者是跟GP使用UDP包有关系。 此同学找了网络检查的人确定网络没有问题&#xff0c;于是猜测跟UDP包有关。 参考文章ht…...

Discourse 的系统日志

Discourse 提供了较为完善的日志查看方式。 用得最多的可能就是 Logster 的基于 Web 的 UI 了。 Logster Discourse 的错误日志面板用的是 logster&#xff0c;采集的是 Rails/Rack 的日志&#xff0c;正常应该用 Rails::Logger 但是 discourse 做了封装。 正常的访问地址为…...

【7z密码】如何给7z压缩包加密、解密?

7z压缩包是压缩率最大的格式&#xff0c;也有很多朋友会使用7z格式&#xff0c;那么7z压缩包如何进行加密、解密&#xff1f;今天给大家介绍详细教程。 7-zip加密 右键文件选择7-zip打开压缩软件进行压缩或者在打开7-zip软件找到需要压缩的文件&#xff0c;点击添加&#xff…...

InnoDB为什么使用B+Tree

分析&回答 1.B Tree的层数较少 B类树的一个很鲜明的特点就是数的层数比较少&#xff0c;而每层的节点非常多&#xff0c;树的每个叶子节点到根节点的距离都是相同的&#xff1b; 2. 减少磁盘IO&#xff1b; 树的每一个节点都是一个数据也&#xff0c;这样每个节点只需…...

【Spring Bean的生命周期实现方式】

文章目录 Spring Bean的生命周期实现方式实例化属性赋值初始化销毁Spring Bean的生命周期实现方式 Spring Bean的生命周期决定了一个Bean的整个生命周期,它分为四个阶段:实例化、属性赋值、初始化和销毁。 实例化 实例化通过构造器实例化和工厂方法实例化两种方式实现;构…...

腾讯云PK阿里云2核2G云服务器租用价格表

2核2G云服务器可以选择阿里云服务器或腾讯云服务器&#xff0c;腾讯云轻量2核2G3M带宽服务器95元一年&#xff0c;阿里云轻量2核2G3M带宽优惠价108元一年&#xff0c;不只是轻量应用服务器&#xff0c;阿里云还可以选择ECS云服务器u1&#xff0c;腾讯云也可以选择CVM标准型S5云…...

【美团3.18校招真题2】

大厂笔试真题网址&#xff1a;https://codefun2000.com/ 塔子哥刷题网站博客&#xff1a;https://blog.codefun2000.com/ 最多修改两个字符&#xff0c;生成字典序最小的回文串 提交网址&#xff1a;https://codefun2000.com/p/P1089 由于字符串经过修改一定为回文串&#x…...

一文带你快速入门『YOLOv8』

前言 本文是 YOLOv8 入门指南&#xff08;大佬请绕过&#xff09;&#xff0c;将会详细讲解安装&#xff0c;配置&#xff0c;训练&#xff0c;验证&#xff0c;预测等过程 YOLOv8 官网&#xff1a;ultralytics/ultralytics: NEW - YOLOv8 &#x1f680; in PyTorch > ONN…...

# 将PCL点云转换为Eigen向量进行运算

将PCL点云转换为Eigen向量进行运算 在处理点云数据时,我们常需要将PCL中的点云转换为Eigen向量,进行一些矩阵运算。这里介绍PCL点云到Eigen向量的两种转换方法。 点云转换为Eigen数组 对于一个PCL的点云,可以通过getArray4fMap()函数获取Eigen数组表示: // PCL点云 pcl::Po…...

elmentui表单重置及出现的问题

一、表单&#xff1a; 二、代码——拿官方的代码举例(做了一些小改动)&#xff1a; 改动&#xff1a;model绑定的字段&#xff0c;由form改为queryParams ref绑定的字段form改为queryFrom 注&#xff1a;model绑定的这个字段用来做数据双向绑定的 注&#xff1a;ref绑定的这…...

游戏平台加盟该怎么做?需要准备什么?

游戏平台加盟是一种合作模式&#xff0c;允许个人或企业以加盟商的身份参与游戏平台&#xff0c;并从中获得一定的权益和收益。以下是一些步骤和需要准备的事项&#xff0c;来考虑如何进行游戏平台加盟&#xff1a; 步骤&#xff1a; 研究市场和平台&#xff1a;了解游戏市场和…...

selenium中定位shadow-root,以及获取shadow-root内部的数据

通过shadow-root的父级定位到shadow-root,再通过语句进行操作 两种方法&#xff1a; 第一种&#xff0c;Python种JS实现 第二种&#xff0c;selenium实现 1.0 案例网站 参考某橘色网站 2.0 js语句定位 可在控制台进行测试 测试语句 document.querySelector("ali-ba…...

OpenCV(三十二):轮廓检测

1.轮廓概念介绍 在计算机视觉和图像处理领域中&#xff0c;轮廓是指在图像中表示对象边界的连续曲线。它是由一系列相邻的点构成的&#xff0c;这些点在边界上连接起来形成一个封闭的路径。 轮廓层级&#xff1a; 轮廓层级&#xff08;Contour Hierarchy&#xff09;是指在包含…...

接口自动化测试做线上巡检,如何避免数据污染

在接口自动化测试中&#xff0c;避免数据污染是非常重要的&#xff0c;特别是在线上环境中进行巡检。 1. 使用独立的测试环境&#xff1a;建议使用专门的测试环境来进行接口自动化测试&#xff0c;而不是直接在生产环境中进行。测试环境应该是一个独立的、与生产环境隔离的环境…...

C++ 指针

C 指针 学习 C 的指针既简单又有趣。通过指针&#xff0c;可以简化一些 C 编程任务的执行&#xff0c;还有一些任务&#xff0c;如动态内存分配&#xff0c;没有指针是无法执行的。所以&#xff0c;想要成为一名优秀的 C 程序员&#xff0c;学习指针是很有必要的。 正如您所知…...

SpringBoot集成kubernetes-client升级k8s后初始化失败问题

SpringBoot集成kubernetes-client升级k8s后初始化失败问题 1.问题描述 程序以前使用的k8s版本是1.16&#xff0c;fabric8.kubernetes-client的版本是4.10.2&#xff0c;springboot版本是2.3.5。由于环境切换&#xff0c;这次需要升级k8s的版本&#xff0c;现在将k8s版本升级到…...

MySQL 学习笔记

&#x1f600;&#x1f600;&#x1f600;创作不易&#xff0c;各位看官点赞收藏. 文章目录 MySQL 学习笔记1、DQL 查询语句1.1、基本查询1.2、函数查询1.2.1、单行函数1.2.2、聚合函数 1.3、复杂查询1.3.1、连接查询1.3.2、子查询 1.4、SQL 语句 执行顺序 2、DDL 定义语句2.1、…...

Docker 的常用命令

0 基本命令 概述 [root192 home]# docker --helpUsage: docker [OPTIONS] COMMANDA self-sufficient runtime for containersOptions:--config string Location of client configfiles (default "/root/.docker")-c, --context string Name of the context…...

嵌入式-电子电路四个基本定律

目录 1、欧姆定律 2、焦耳定律 3、基尔霍夫电流定律 4、基尔霍夫电压定律 1、欧姆定律 欧姆定律是关于导体两端电压与导体中电流关系的定律。具体表述为&#xff1a;在同一电路中&#xff0c;通过某段导体的电流跟这段导体两端的电压成正比&#xff0c;跟这段导体的电阻成反…...

【linux命令讲解大全】083.Linux 常用命令ispell , spell , atrm, chattr

文章目录 ispell补充说明语法参数 spell补充说明语法参数 atrm补充说明语法选项参数 实例 chattr补充说明语法选项 实例 从零学 python ispell 检查文件中出现的拼写错误。 补充说明 ispell命令用于检查文件中出现的拼写错误。 语法 ispell [参数] 参数 文件&#xff1a…...

JAVA实现SAP接口

JAVA实现SAP接口 环境spring-bootmaven 1.maven依赖 <dependency><groupId>com.github.virtualcry</groupId><artifactId>sapjco-spring-boot-starter</artifactId><version>3.1.4</version></dependency>2.配置文件 applic…...

华南理工大学811信号与系统考研分数线,招生人数,报考统计,考情分析,就业,真题,大纲,参考书,华工811

华南理工大学811信号与系统考研分数线&#xff0c;招生人数&#xff0c;报考统计&#xff0c;考情分析&#xff0c;就业&#xff0c;真题&#xff0c;大纲&#xff0c;参考书&#xff0c;华工811 华南理工大学811信号与系统考研分数线&#xff0c;招生人数&#xff0c;报考统…...

Android 字符串 占位符

在 Android 中&#xff0c;字符串中的 % 后面跟着的字符称为格式化占位符&#xff0c;用于指示在运行时将值插入到字符串中的位置&#xff0c;并指定插入的值的类型。常见的格式化占位符类型如下&#xff1a; %s&#xff1a;字符串占位符。它用于插入字符串值。 String name …...

vue页面添加水印(可用于H5,APP)

vue页面添加水印 背景实现新建vue组件使用效果 尾巴 背景 最近实现了一个小功能&#xff0c;就是给页面添加背景水印。实现思路就是定义一个宽高充满屏幕的组件&#xff0c;然后使用绝对定位并通过层级控制让水印显示在页面的最前端。 实现 代码相对简单&#xff0c;相信有点…...

下载git

1.官网下载可能会有访问失败 2.用其他的镜像源下载 快 准 狠 CNPM Binaries Mirror...