C++逆向分析之条件语句和循环语句

news2024/9/22 17:22:11

一.C++逆向条件结构基础入门

大家写过相关的算法吗?

加密代码中会涉及循环和分支,你要识别算法,首先就是需要将它的算法处理流程识别出来。当我们还原出等价的高级代码之后,就没有逆向分析人员的事情了,因为接下来涉及到密码学、数学相关人员的工作,逆向人员把加密的代码还原出来后就应该扔给研究密码学的数学家,他们负责玩数学对抗,而逆向关注的是编译原理和代码还原。同时,逆向还涵盖了识别对象、识别算法、识别优化、识别虚函数对象的继承关系等等,这里主要结合项目相关的加密和解密进行讲解。接着作者准备穿插着VC++6.0和VS2019两个版本进行讲解。

1.单分支结构分析

第一步,通过VC++6.0编写一个最简单的程序,创建工程名称为“RE_SF”。

在这里插入图片描述
在这里插入图片描述

运行结果如下图所示,可以看到“Hello World”。

在这里插入图片描述

第二步,编写单分支结构的相关代码。

#include "stdafx.h"

int main(int argc, char* argv[])
{
	if (argc > 8 )
	{
		printf("argc > 8\r\n");
	}
	return 0;
}

接着选择“Win32 Release”编译运行代码。

在这里插入图片描述

第三步,接着用OD软件打开EXE文件。

此时创建的工程目录分布如下图所示。

在这里插入图片描述

OllyDbg打开之后显示如下图所示的界面,程序入口地址是0x00401051。

  • 程序入口:0x00401051

在这里插入图片描述

第四步,首先我们需要定位main函数,其方法非常简单,找到有三个PUSH的下面就是main函数,因为main函数有三个参数(argc、argv[],、envp[])。接着按F2下断点。

  • 主函数:0x00401100

在这里插入图片描述

继续按下F7跟进,会看到一个单分支结构。那么,单分支结构它有什么特点呢?

  • 进入主函数:0x00401000

在这里插入图片描述

第五步,先给大家普及单分支语句的代码定式基础知识。

在高级语言中单分支代码定式如下:

//程序语言
if(...)
{
    ...
}

//代码定式
IF_BEGIN:
    jxx IF_END
        ...
    IF_END:
        ...

为什么需要记住这个代码定式呢?

因为对于流程控制的识别,我们关键是要找到IF语句的作用域(上界和下界),上界在jxx的位置,称之为IF_BEGIN。接着有个jxx条件跳转,跳转到目标且没有其他的特征,这种就称之为单分支的代码定式。

回到我们的汇编代码,拿到这个代码之后,发现存在一个箭头指向跳转目标,这样就出现了IF模块的上界和下界,条件判断作为IF的上界,条件跳转的目标作为IF下界,通过这种套路方式来还原代码。

在这里插入图片描述

第六步,分析嵌套的单分支语句。

假设我们的判断中再嵌套一层或增加一个分支,又该怎么判断呢?对于我们还原代码的人来说,不用管它,你把上下界圈出来,然后递归解决。所有流程问题只要找到上下界,剩下的问题就变成了顺序结构,再看着代码一条条还原即可。

在这里插入图片描述

#include "stdafx.h"
#include <stdlib.h>

int main(int argc, char* argv[])
{
	if (argc > 8 )
	{
		printf("argc > 8\r\n");
		if (argc < 80)
		{
			printf("argc < 80\r\n");
		}
	}

	system("pause");
	return 0;
}

接着运行程序生成新的EXE程序,然后通过OD软件打开分析,给主函数下个断点然后进入主函数显示如下图所示的界面。

  • 主函数内容:0x00401000

在这里插入图片描述

第七步,同样的方法将两层单分支语句的上下界圈出来。

我们发现这两个判断的下界重合了,都是跳转到0x00401029位置,这就明显是个嵌套。

在这里插入图片描述

总结下IF语句的特点:

  • 观察它的条件跳(上下界)
  • 条件跳的目标上面的代码没有其他特征,即“ADD ESP, 4"

那么,怎么还原出高级代码呢?

第八步,通过汇编代码还原出高级代码。

还原代码需要进行反条节操作,并且学会查询相关指令。比如JLE、JGE是什么意思呢?

  • JLE(jump if less or equal,or not greater):汇编语言中的条件转移指令,小于或等于则条件转移
  • JGE:大于或等于转移指令

注意,在还原的时候需要做反条件操作。那么,什么叫反条件呢?具体解释如下:

  • JLE:小于等于跳转 --> 代码还原就是“不小于等于”,即:大于跳转
  • JGE:大于等于跳转 --> 代码还原就是“不大于等于”,即:小于跳转

反条件
因为当我们满足这个条件的时候它会跳转到另一个地方(结束地方),它没有执行具体的代码;所以如果我们想要执行模块中的代码,就需要反条件处理。即汇编的语义和高级语言的语义是反的,高级语言的语义是满足条件则执行语句块,而汇编的语义是满足条件不执行语句块。

接着我们继续看触发跳转的代码,它是通过CMP比较来触发的。

  • CMP ESI, 8
    ESI是通过参数传递过来的,然后和8进行不小于等于的比较
  • CMP ESI, 50
    ESI和50进行不大于等于的比较

在这里插入图片描述

此时,我们再将单分支步骤简单归纳如下:

  • (1) 通过反汇编代码序列,匹配代码定式;
  • (2) 如果是单分支if结果,则将条件转义指令jxx做反条件还原

第九步,接着我们换个工具用VS2019打开我们的代码,生成新的Release版本。

在这里插入图片描述

然后删除本地的Release资源,生成一个新的Release方案。

在这里插入图片描述

第十步,用IDA Pro打开可执行EXE程序进行分析。

同样,使用IDA也是可以进行逆向分析的,打开新生成的逆向分析工具如下所示。

在这里插入图片描述

右键选择“Text View”查看源代码。

在这里插入图片描述

找到main函数,然后点击“_main”位置高亮显示。

在这里插入图片描述

按下“N”键可以对函数进行重命名,如下图所示。

在这里插入图片描述

注意,前面分享的识别方法和编译器版本、编程语言(C++、VB)等都没有关系,它是编译原理的问题。接着我们重点还是回归到代码上去,点击“loc_401039”函数高亮,同样的方法划分出这个单分支的上界和下界,并且嵌套了一个单分支,最终还原出源代码。

在这里插入图片描述

所以,不论使用VC++6.0或VS编译工具,还是使用IDA或OD分析工具,它们还原代码的原理及方法都是一样的。在实际项目中,不论你用什么分析工具,最终能分析出结果就好。


2.双分支结构分析

第一步,编写双分支代码。

在这里插入图片描述

第二步,普及双分支语句的代码定式基础知识。

在高级语言中双分支代码定式如下。该代码序列关键是发现jxx后,需要检查目标看看下面有没有一个jmp指令,如果有个jmp且是往下跳的,if-else就成立了。

//程序语言
if(...) 
{
    ...
}
else 
{
	...
}

//代码定式
IF_BEGIN:
jxx ELSE_BEGIN
    ...
IF_END:
    jmp ELSE_END
ELSE_BEGIN:
    ...
ELSE_END:
    ...

第三步,接着生成新的exe文件,用OD打开分析。

同样的方法进入主函数,然后F7单步步入0x00401000位置,如下图所示。

在这里插入图片描述

核心代码及其跳转如下图所示。

  • JLE --> 0x0040100E:PUSH操作
  • JMP --> 0x00401013:CALL操作

在这里插入图片描述

双分支结构特点:

  • jxx的目标处上一行指令为jmp,而且是往高地址去的jmp(往下跳)。如果是循环,后面会讲到它可能往上跳。

确定上下界之后,生成如下图所示的if模块和else模块,同样的反条件处理还原代码。

在这里插入图片描述

注意,这里有一个小小的优化,编译原理中的代码外提。它是什么意思呢?

假设有个节点A,现在有了流程分支B1和B2,B1完成后执行C,B2完成后也会执行C。编译器为了减小代码的节点,因为代码节点越多,代码越长,就做了等价流程的代码外提优化,从而汇总到C,少了一个节点。

  • 编译器会视情况减少节点的优化
  • 编译器也会增加节点来减小路径的优化

在这里插入图片描述

第四步,采用同样的方法用IDA工具分析还原代码,其效果也一样。

在这里插入图片描述

在这里插入图片描述

接着你可能会疑问这两个PUSH是干啥呢?**

  • push offset aArgc8 ; “argc > 8\r\n”
  • push offset aArgc8_0 ; “argc <= 8\r\n”

C语言中没有标准的高级语法对应汇编中的PUSH操作,说明它有代码优化了,就是代码外提操作。它们有个公共的函数调用被提到下面去了,就是下图所示的两行代码,这个时候我们要把它放回去方便还原。

在这里插入图片描述

接着我们复制汇编代码至C语言中进行还原,方便大家理解。代码如下,此时增加了if和else的上下界,但发现两个push无法还原。

在这里插入图片描述

同时将代码外提部分分别放到if和else模块中,就能实现最终代码还原,如下图所示。最后删除掉多余的汇编注释即可。

在这里插入图片描述

继续还原条件判断内容,JLE小于等于换成大于8就好。在真实环境中,还会遇到双分支中有循环或条件嵌套的问题,不要担心,找到上下界继续分析即可。

#include "stdafx.h"
#include <stdlib.h>

int main(int argc, char* argv[])
{

//.text:00401000                 cmp     [esp+argc], 8
//.text:00401005                 jle     short loc_40100E
	if (argc > 8)
	{
//.text:00401007                 push    offset aArgc8   ; "argc > 8\r\n"
//.text:0040100C                 jmp     short loc_401013
//.text:00401013                 call    sub_4010C6
		printf("argc > 8\r\n");
//.text:00401018                 add     esp, 4
	}
//.text:0040100E ; ---------------------------------------------------------------------------
//.text:0040100E
	else
	{
//.text:0040100E loc_40100E:                             ; CODE XREF: _main+5↑j
//.text:0040100E                 push    offset aArgc8_0 ; "argc <= 8\r\n"
//.text:00401013                 call    sub_4010C6
		printf("argc <= 8\r\n");
//.text:00401018                 add     esp, 4
	}
//.text:00401013
//.text:00401013 loc_401013:                             ; CODE XREF: _main+C↑j
//.text:0040101B                 push    offset aPause   ; "pause"
	system("pause");
	return 0;
}

二.C++逆向循环结构基础入门

1.do-while结构分析

循环包括do-while、while和for三种,你会觉得哪一种消息最高呢?do-while是三种循环中效率最高的,由于其无条件先执行一次,所以大家很少使用,但其效率很高。

基本语法
先执行,再判断。先执行一遍循环操作,若符合条件,循环操作继续执行,否则退出循环。

do{
    循环操作语句;
}whlie(循环条件);

在这里插入图片描述

第一步,我们编写一个1加到100的循环代码,这次直接使用Debug版本。

#include "stdafx.h"
#include <stdlib.h>

int main(int argc, char* argv[])
{
	int n = 1;
	int nSum = 0;

	//do-while 执行一次
	do {
		nSum = nSum + n;
		n++;
	} while(n <= 100);
	
	printf("%d", nSum);
	system("pause");
	return 0;
}

第二步,通过OD打开运行的EXE程序“RE_XH.exe”。

  • 程序入口地址:0x00401260

在这里插入图片描述

第三步,往下查找代码,发现3个PUSH后(参数)就是主函数,然后F2添加断点并F7步入主函数。

  • 主函数:CALL RE_XH.00401005

在这里插入图片描述

在这里插入图片描述

第四步,分析汇编代码。

这里存在一个JLE跳转,如果条件跳往上跳就是do-while循环。

在这里插入图片描述

循环肯定会往上走,否则构成不了循环,它需要反复执行同一代码段。如果跳转的目标没有检查条件,就是do-while循环。简单总结下识别do-while循环步骤:

  • 识别代码定式
  • 如果是do循环,则按jxx同条件还原等价高级代码

注意,同条件的就只有do-while结构。在do-while循环中,它跟汇编的语义是一样的,只有当条件满足则流程更新到循环的起始地点,所以它是正条件还原。而前面的if-else判断都是反条件

//程序语言
do
{
    ...
}while(xxx);

//代码定式
DO_BEGIN:
    ...
    jxx DO_BEGIN
DO_END:
    ...

2.while结构分析

基本语法
先判断,再执行。

whlie(循环条件){
    循环操作语句;
}

在这里插入图片描述

第一步,我们编写一个1加到100的循环代码。

#include "stdafx.h"
#include <stdlib.h>

int main(int argc, char* argv[])
{
	int n = 1;
	int nSum = 0;

	while (n <= 100)
	{
		nSum = nSum + n;
		n++;
	} 
	
	printf("%d", nSum);
	system("pause");
	return 0;
}

第二步,分析while循环的代码定式。
注意,该循环的Debug版本和Release版本存在差异,接下来会对比分析。我们先给出代码定式,如下所示。

//程序语言
while(xxx)
{
    ...
}

//代码定式
WHILE_BEGIN:
    jxx WHILE_END
        ...
    jmp WHILE_BEGIN
WHILE_END:
    ...

while循环的条件跳是往上跳的,它需要反复执行同一代码段。

第三步,通过OD打开运行的EXE程序“RE_XH.exe”。

  • 程序入口地址:0x00401260

在这里插入图片描述

第四步,往下查找代码,发现3个PUSH后(参数)就是主函数,然后F2添加断点并F7步入主函数。

  • 主函数:CALL RE_XH.00401005

在这里插入图片描述

第五步,分析汇编代码。
这里存在一个JG跳转,它有点像if语句,下面还有一个JMP,有点像if-else指令,但是它的跳转是地址减量跳或往上跳,所以它是循环。

在这里插入图片描述

这时会发现while循环比刚才的多了一个跳转。我们会过计算机组成原理,当处理器执行跳转指令时,流水线会暂时挂起失效,本来流水线在取指令时已经准备预读后面的代码了,结果在译码过程中是个跳转,后面的代码预读就会出错,然后做流水线清理工作。所以,while循环有两跳对流水线的伤害比do-while大。

第六步,接着我们用高版本VS2019编译一个Release版本,并用IDA进行分析,看看高版本有什么优化。

在这里插入图片描述

查看Text View,我们定位到main函数之后,看看它做的优化。它把循环的起点对齐到十六进制10的倍数地址,中间会用nop进行空指令填充。同时,它的汇编循环体变成了do-while循环。

在这里插入图片描述

注意,前面的VC++ Debug版本用IDA工具打开如下图所示。上图和下图同样都是while循环,但低版本可以看到JG(往下跳)和JMP(往上跳)两个跳转,典型的while循环;而高版本的却修改成了do-while循环的形式。

在这里插入图片描述

问题1:由于do-while循环会执行一次循环体,难道它不担心编译器出错吗?
其实它比较的数值是常量,常量可以在编译期间预置其结果的,其实编译器在第一次的判断时先进行了一次常量传播,令n等于1,即判断的是 while(1<=100),比较1和100的关系条件必成立。

问题2:那么,如果将100替换成变量,编译器还能识别吗?或者会报错?
此时的编译器会将其进行转换,变成如下图所示的形式再执行do-while循环。其中if(n<=argc)条件判断嵌套一个循环。

在这里插入图片描述

对应的汇编代码如下,其中“jl short loc_401016”往下跳,还原成一个单分支,循环里面还有一个跳转“jle short loc_40100F”往上跳,满足do-while循环,最终还原成if加do-while,或者你知道有这个优化,直接还原成带变量的while循环也可以。

在这里插入图片描述

但需要注意,能不能把do-while直接还原成while循环,还需要看看这两个条件有没有相关性。如果有相关性才能还原,比如外层判断是文件的打开状态,while是迭代n值,这种情况不能还原。下图可以看到if和循环都是EAX参数比较,所以具有相关性。

在这里插入图片描述


3.for结构分析

下面开始分析for循环结构。

for(表达式1;表达式2;表达式3;)
{
	语句;
}

第一步,我们编写一个for循环代码。

#include "stdafx.h"
#include <stdlib.h>

int main(int argc, char* argv[])
{
	int nSum = 0;

	for (int n = 1; n<=argc; n++)
	{
		nSum = nSum + n;
	} 
	
	printf("%d", nSum);
	system("pause");
	return 0;
}

第二步,编译生成新的Debug版可执行程序。

在这里插入图片描述

第三步,通过IDA打开运行的EXE程序“RE_XH.exe”。

产出了三个跳转代码,如下图所示。

在这里插入图片描述

其代码定式如下所示,可以看到JMP、JG和JMP三个跳转。注意,for循环中FOR_STEP地址是低于BODY执行体的地址的。

在这里插入图片描述

第四步,分析汇编代码。

首先MOV进行初始化赋值1,接着JMP跳转到比较部分,比较不成立则JG直接跳出循环,否则执行循环体BODY内容,接着继续JMP跳转上去执行n++操作。

在这里插入图片描述

注意,由于Release版本都被编译器优化成了do-while循环,所以我们需要在Debug版下进行对比。

第五步,通过VS2019生成Release版本,然后用IDA打开代码对比。

在这里插入图片描述

IDA打开如下图所示,发现和do-while一样,高版本做了一点小处理,每次循环总次数增加了4(add eax,4),从而提升效率。

在这里插入图片描述

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

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

相关文章

54. QButtonGroup的基本使用

1. 说明 在使用QT开发小软件时,使用最多的控件也许就是Button按钮了,一般情况下在界面上添加了一个Button,都会为这个Button添加一个相应的信号槽相应其点击事件。那么,如果在软件的其中一个界面添加了很多个Button,比如自定义的侧边菜单栏里可能会放置很多Button控件,如…

mac电脑里面的 磁盘分区,容器,宗卷,宗卷组的理解和使用

在mac电脑里面我们一般都是使用宗卷&#xff0c;他和我们常见的pc机器硬盘的分区是有区别的。 对于物理硬盘来说 不管是分区还是宗卷&#xff0c;他们都是逻辑上面的概念。 分区 mac电脑里面的分区 和 pc电脑中的分区差不多&#xff0c; 他们都是针对的物理硬盘&#xff0c;…

Linux用户层I2C读取LSM6DSL陀螺仪记录

硬件外设开发板Lubancat V2/dev/i2c-3LSM6DSL陀螺仪i2c(7bit地址0x6a) 开发板配置I2C 开发板采用Lubancat-V2&#xff0c;运行Linux内核4.19 使用I2C3外设 因为i2c3外设的设备树默认没有启用&#xff0c;所以在 /boot/uEnv/uEnv.txt 打开&#xff0c;也即取消i2c3-m0注释 随…

LINUX网络编程:应用层和协议定制

目录 1.协议定制 2.序列化和反序列化 ​编辑 3.tcp为什么是全双工 4.Tcp保证接收数据的完整性 1.协议定制 定制协议就是通信双方都遵守的协定 加上 符合通信和业务处理的结构化数据&#xff0c;就是struct或class。 例&#xff1a;佩奇使用微信向乔治发送了【你好】&…

51单片机——实时时钟

1、DS1302介绍 DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时&#xff0c;且具有闰年补偿等多种功能 RTC(Real Time Clock)&#xff1a;实时时钟&#xff0c;是一种集成电路&#xff0c;通常称为时钟…

华为OD机试真题 - 最长的顺子 - 动态规划(Java/Python/JS/C/C++ 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Java/Python/JS/C/C++)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX…

【Linux修行路】进程通信——消息队列、信号量

目录 ⛳️推荐 一、消息队列 1.1 实现原理 1.2 消息队列接口 1.2.1 msgget——创建、获取一个消息队列 1.2.2 msgctl——释放消息队列、获取消息队列属性 1.2.3 msgsnd——发送数据 1.2.4 msgrcv——从消息队列中检索数据块 1.3 消息队列的指令操作 二、信号量 2.1 …

Java、python、php版 保险业务管理与数据分析系统 社会保险档案管理系统(源码、调试、LW、开题、PPT)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人 八年开发经验&#xff0c;擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等&#xff0c;大家有这一块的问题可以一起交流&…

700. 二叉搜索树中的搜索(迭代)

目录 一&#xff1a;题目&#xff1a; 三&#xff1a;结果 二&#xff1a;代码&#xff1a;: 一&#xff1a;题目&#xff1a; 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。 你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的…

Ubuntu 超详细保姆级安装教程(每步都有截图)

文章目录 下载安装VMware检查网络适配器Ubuntu下载创建虚拟机启动虚拟机安装 VWware Tools安装 SSH 连接工具配置静态IP 下载安装VMware Desktop Hypervisor Solutions | VMware 官网下载速度慢的可以使用我百度网盘分享的链接来下载 百度网盘 | VMware 17.5.2 百度网盘没有…

vulnhub靶场-DC2

一、环境配置 1.下载地址&#xff1a;https://www.vulnhub.com/entry/dc-2,311/ 2.靶场配置&#xff1a;Nat模式 更改hosts文件&#xff0c;官网提示需要更改hosts文件才能访问到网站&#xff0c;否则访问不了 kali进入编辑模式vim&#xff0c;添加上自己的靶机ip地址保存即可…

Java进阶13讲__第八讲

集合&#xff1a;Collection&#xff0c;List&#xff0c;Set&#xff0c;Map 集合体系 集合结构 单列集合 1.Collection 1.初识Collection package cn.hdc.oop8.Collection;import java.util.ArrayList; import java.util.HashSet; import java.util.List;/*** 目标&#xf…

前端面试模拟:常见的3个JavaScript经典考题

在一次备受期待的前端开发高级岗位面试中&#xff0c;你紧张地走进了会议室&#xff0c;对面坐着的是一位经验丰富的技术面试官。窗外阳光明媚&#xff0c;屋内却有一丝令人紧张的静谧。 第一问&#xff1a;如何使用JavaScript实现事件委托&#xff1f; 面试官微微一笑&#xf…

实战项目:俄罗斯方块(一)

文章目录 &#x1f34a;自我介绍&#x1f34a;vt100 控制码1.概述2.数字格式①常用数字控制码②常用控制码 &#x1f34a;绘制方格 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff09;哦~ &#x1f34a;自我…

猫头虎分享:关于 Mac OS 系统 .DS_Store 文件的起源、作用及管理全指南

&#x1f42f;猫头虎分享&#xff1a;关于 Mac OS 系统 .DS_Store 文件的起源、作用及管理全指南 &#x1f42f; 猫头虎 分享&#xff1a;关于 Mac OS系统 .DS_Store 文件的起源和作用 今天猫头虎带您深入探讨 Mac OS 系统中的 .DS_Store 文件。作为一名开发者&#xff0c;您…

科研绘图系列:R语言差异基因四分图(Quad plot)

介绍 四分图(Quad plot)是一种数据可视化技术,通常用于展示四个变量之间的关系。它由四个子图组成,每个子图都显示两个变量之间的关系。四分图的布局通常是2x2的网格,每个格子代表一个变量对的散点图。 在四分图中,通常: 第一个子图显示变量A和B的关系。第二个子图显示…

足浴城消费系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;商品分类管理&#xff0c;商品信息管理&#xff0c;购买信息管理&#xff0c;会员卡申请管理&#xff0c;包厢信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;公告…

苍穹外卖项目前端DAY01

前端DAY01 1、基于脚手架创建前端工程 使用Vue CLI创建前端工程&#xff1a; 方式一&#xff1a;vue create 项目名称方式二&#xff1a;vue ui&#xff08;比较慢&#xff09; 2、vue基本使用方法 Vue的组件文件以.vue结尾&#xff0c;每个组件由三个部分组成&#xff1a; …

AJAX day-02 HTTP格式JSON格式

目录 一. 计算机网络 1.1 网络参考模型 1.2 各层重要对应的协议 1.3 DNS解析&#xff08;域名解析服务器&#xff09; 1.4 FTP&#xff08;文件传输协议&#xff09; 1.5 UDP&#xff08;用户数据报协议&#xff09; 1.6 TCP(传输控制协议) 1.7 IP(网际互连协议) 1.8 …

[Leetcode 46][Medium]-全排列-回溯(全排列问题)

目录 一、题目描述 二、整体思路 三、代码 一、题目描述 原题地址 二、整体思路 对于全排列问题&#xff0c;很明显要用回溯法。但是和组合问题不一样的是全排列问题是可以取先前遍历的元素的。因此需要另外新建一个状态数组来存储所有元素是否被访问过的状态。回溯时把状态…