REVERSE-COMPETITION-HGAME2022-Week4

REVERSE-COMPETITION-HGAME2022-Week4

    • ( WOW )
    • server
    • ezvm
    • hardasm

( WOW )

32位exe,ida打开
观察伪代码逻辑,上面的红框中,输入经过加密,密文放入Buf2中,然后Buf2和已知的密文res比较
比较完,打印"win"或者"error"
发现下面还有一部分对Buf2处理的代码逻辑,而且几乎和上面对输入加密的结构是一样的
于是猜测下面的红框中就是解密逻辑
wow-main
起调试,随便构造一个长度为32的输入
在调用memcmp前下断,将内存中Buf2的数据patch成已知的密文res
进行下面对Buf2的解密,解密后的input即为flag
wow-flag

server

64位exe,用ida7.7打开
(52pojie上有最新的全插件绿色版ida7.7可供下载)
从main函数中知道监听本地的9090端口
回调函数为main_HttpHandleFunc,调试发现,输入经过main_encrypt处理后,与已知的res比较
server-main
进入main_encrypt函数,伪代码看不出什么,玄机在汇编指令
可以发现main_encrypt的前半部分实际上是个RSA加密,并且已知p,q,e
server-rsa
输入经rsa加密后,将十进制密文的每一个数字转成字符存入rsa_cipher中
然后进行后半部分的两轮异或运算,异或后的结果与已知的res比较
server-xor
这里举一个例子来理解后半部分的两轮异或运算,以便能够更好地逆向

# -*- coding:utf-8 -*-
import gmpy2
num1=92582184765240663364795767694262273105045150785272129481762171937885924776597#p
num2=107310528658039985708896636559112400334262005367649176746429531274300859498993#q
num1_mul_num2=num1*num2#n
num3=950501#e
my_in_s="hgame{abcdefghijklmnopqrstuvwxy}"#构造的输入
my_in=0x6867616d657b6162636465666768696a6b6c6d6e6f707172737475767778797d
my_in_cipher=gmpy2.powmod(my_in,num3,num1_mul_num2)#rsa加密
my_in_cipher_s=str(my_in_cipher)
print("RSA加密后的十进制密文:")
print(my_in_cipher_s)
print("RSA加密后的十进制密文长度:")
print(len(my_in_cipher_s))
#模拟main_encrypt中后半部分的两轮异或运算
res=[]
for i in range(len(my_in_cipher_s)-1):res.append(ord(my_in_cipher_s[i]))
print("十进制密文的每一个数字转成字符:")
print(res)
v22=102
index=0
while index<153:tmp=res[index]res[index]^=v22v22=tmpindex+=1
print("第一轮异或运算结果:")
print(res)
index=0
while index<153:tmp=res[index]res[index]^=v22v22=tmpindex+=1
print("第二轮异或运算结果:")
print(res)
# RSA加密后的十进制密文:
# 2315576653393559402200063691755666172531457200527539170715551199511112051176056764826673635703056993058028383465485142593456001504496707046294726739445446
# RSA加密后的十进制密文长度:
# 154
# 十进制密文的每一个数字转成字符:(后面用cipher表示)
# [50, 51, 49, 53, 53, 55, 54, 54, 53, 51, 51, 57, 51, 53, 53, 57, 52, 48, 50, 50, 48, 48, 48, 54, 51, 54, 57, 49, 55, 53, 53, 54, 54, 54, 49, 55, 50, 53, 51, 49, 52, 53, 55, 50, 48, 48, 53, 50, 55, 53, 51, 57, 49, 55, 48, 55, 49, 53, 53, 53, 49, 49, 57, 57, 53, 49, 49, 49, 49, 50, 48, 53, 49, 49, 55, 54, 48, 53, 54, 55, 54, 52, 56, 50, 54, 54, 55, 51, 54, 51, 53, 55, 48, 51, 48, 53, 54, 57, 57, 51, 48, 53, 56, 48, 50, 56, 51, 56, 51, 52, 54, 53, 52, 56, 53, 49, 52, 50, 53, 57, 51, 52, 53, 54, 48, 48, 49, 53, 48, 52, 52, 57, 54, 55, 48, 55, 48, 52, 54, 50, 57, 52, 55, 50, 54, 55, 51, 57, 52, 52, 53, 52, 52]
# 第一轮异或运算结果:(后面用round_1表示)
# [84, 1, 2, 4, 0, 2, 1, 0, 3, 6, 0, 10, 10, 6, 0, 12, 13, 4, 2, 0, 2, 0, 0, 6, 5, 5, 15, 8, 6, 2, 0, 3, 0, 0, 7, 6, 5, 7, 6, 2, 5, 1, 2, 5, 2, 0, 5, 7, 5, 2, 6, 10, 8, 6, 7, 7, 6, 4, 0, 0, 4, 0, 8, 0, 12, 4, 0, 0, 0, 3, 2, 5, 4, 0, 6, 1, 6, 5, 3, 1, 1, 2, 12, 10, 4, 0, 1, 4, 5, 5, 6, 2, 7, 3, 3, 5, 3, 15, 0, 10, 3, 5, 13, 8, 2, 10, 11, 11, 11, 7, 2, 3, 1, 12, 13, 4, 5, 6, 7, 12, 10, 7, 1, 3, 6, 0, 1, 4, 5, 4, 0, 13, 15, 1, 7, 7, 7, 4, 2, 4, 11, 13, 3, 5, 4, 1, 4, 10, 13, 0, 1, 1, 0]
# 第二轮异或运算结果:(后面用round_2表示)
# [96, 85, 3, 6, 4, 2, 3, 1, 3, 5, 6, 10, 0, 12, 6, 12, 1, 9, 6, 2, 2, 2, 0, 6, 3, 0, 10, 7, 14, 4, 2, 3, 3, 0, 7, 1, 3, 2, 1, 4, 7, 4, 3, 7, 7, 2, 5, 2, 2, 7, 4, 12, 2, 14, 1, 0, 1, 2, 4, 0, 4, 4, 8, 8, 12, 8, 4, 0, 0, 3, 1, 7, 1, 4, 6, 7, 7, 3, 6, 2, 0, 3, 14, 6, 14, 4, 1, 5, 1, 0, 3, 4, 5, 4, 0, 6, 6, 12, 15, 10, 9, 6, 8, 5, 10, 8, 1, 0, 0, 12, 5, 1, 2, 13, 1, 9, 1, 3, 1, 11, 6, 13, 6, 2, 5, 6, 1, 5, 1, 1, 4, 13, 2, 14, 6, 0, 0, 3, 6, 6, 15, 6, 14, 6, 1, 5, 5, 14, 7, 13, 1, 0, 1]

我们可以发现
round_1[0]=102 xor cipher[0],round_1[1]=cipher[0] xor cipher[1],依次类推(这里的102是已知的
round_2[0]=52 xor round_1[0],round_2[1]=round_1[0] xor round_1[1],依次类推
这里的52实际上等于cipher[len(cipher)-1],也就是cipher的最后一个值
但是由于cipher是RSA加密后的密文,所以其实cipher[len(cipher)-1]是未知的
想要逆向两轮异或运算从而得到正确的RSA密文
需要爆破cipher[len(cipher)-1],范围是十进制数字字符

# -*- coding:utf-8 -*-
import gmpy2
from Crypto.Util.number import long_to_bytes
# res 相当于 round_2
res=[0x63,0x55,0x4,0x3,0x5,0x5,0x5,0x3,0x7,0x7,0x2,0x8,0x8,0xb,0x1,0x2,0xa,0x4,0x2,0xd,0x8,0x9,0xc,0x9,0x4,0xd,0x8,0x0,0xe,0x0,0xf,0xd,0xe,0xa,0x2,0x2,0x1,0x7,0x3,0x5,0x6,0x4,0x6,0x7,0x6,0x2,0x2,0x5,0x3,0x3,0x9,0x6,0x0,0xb,0xd,0xb,0x0,0x2,0x3,0x8,0x3,0xb,0x7,0x1,0xb,0x5,0xe,0x5,0x0,0xa,0xe,0xf,0xd,0x7,0xd,0x7,0xe,0x1,0xf,0x1,0xb,0x5,0x6,0x2,0xc,0x6,0xa,0x4,0x1,0x7,0x4,0x2,0x6,0x3,0x6,0xc,0x5,0xc,0x3,0xc,0x6,0x0,0x4,0xf,0x2,0xe,0x7,0x0,0xe,0xe,0xc,0x4,0x3,0x4,0x2,0x0,0x0,0x2,0x6,0x2,0x3,0x6,0x4,0x4,0x4,0x7,0x1,0x2,0x3,0x9,0x2,0xc,0x8,0x1,0xc,0x3,0xc,0x2,0x0,0x3,0xe,0x3,0xe,0xc,0x9,0x1,0x7,0xf,0x5,0x7,0x2,0x2,0x4]
p=92582184765240663364795767694262273105045150785272129481762171937885924776597
q=107310528658039985708896636559112400334262005367649176746429531274300859498993
n=p*q
e=950501
phin=(p-1)*(q-1)
d=gmpy2.invert(e,phin)
# i 相当于 cipher[len(cipher)-1],爆破的目标
for i in range(0x30,0x3a):tmp1=[res[0]^i] # tmp1 相当于 round_1for j in range(1,len(res)):tmp1.append(res[j]^tmp1[j-1])tmp2=[tmp1[0]^102]# tmp2 相当于 cipherfor j in range(1,len(tmp1)):tmp2.append(tmp1[j]^tmp2[j-1])wrong=0for m in tmp2: # cipher 中每个元素都必须是十进制数字字符if m<0x30 or m>0x39:wrong=1breakif wrong:continueif i==tmp2[len(tmp2)-1]:# 验证爆破的目标和还原出来的cipher[len(cipher)-1]是否相同cipher=""for k in tmp2:cipher+=chr(k)cipher_num=int(cipher)m=gmpy2.powmod(cipher_num,d,n)# RSA解密print(long_to_bytes(m))
# hgame{g0_and_g0_http_5erv3r_nb}

ezvm

vm,调试确定输入的长度应为32
对输入的处理逻辑为:输入的每个字符,左移1位,和一个值异或,然后比较
构造一个长度为32的输入,得到经程序处理后的结果
逆向对输入的处理逻辑,得到输入的每个字符左移1位后,要去异或的值的集合
最后由真正的密文爆破出flag

# -*- coding:utf-8 -*-
s="hgame{abcdefghijklmnopqrstuvwxy}"# 对输入的处理逻辑:输入的每个字符,左移1位,和一个值异或,然后比较print(hex((ord("h")<<1)^0x5e))# 0x8e
print(hex((ord("g")<<1)^0x46))# 0x88# my_res: 构造的输入s,经过程序处理后的结果
my_res=[0x8e,0x88,0xa3,0x99,0xc4,0xa5,0x8b,0xdb,0x97,0x96,0xfc,0xfb,0xe7,0x91,0xb1,0xef,0xb2,0xe3,0xcf,0xc4,0x85,0xde,0xc0,0xb4,0xa0,0xb6,0xdf,0xa2,0xad,0xd3,0x92,0xc1]
# 逆向对输入的处理逻辑,得到输入的每个字符左移1位后,要去异或的值的集合
xor_box=[]
for i in range(len(s)):tmp=(ord(s[i])<<1)&0xffxor_box.append(tmp^my_res[i])# res: 真正的密文
res=[0x8e,0x88,0xa3,0x99,0xc4,0xa5,0xc3,0xdd,0x19,0xec,0x6c,0x9b,0xf3,0x1b,0x8b,0x5b,0x3e,0x9b,0xf1,0x86,0xf3,0xf4,0xa4,0xf8,0xf8,0x98,0xab,0x86,0x89,0x61,0x22,0xc1]
flag=""
for i in range(len(res)):for j in range(32,128):if (j<<1)^xor_box[i]==res[i]:flag+=chr(j)
print(flag)
# hgame{Ea$Y-Vm-t0-PrOTeCT_cOde!!}

hardasm

近7000行的汇编指令,应该是有什么地方设计得很巧妙
起调试,构造一个长度为32的输入"hgame{abcdefghijklmnopqrstuvwxy}"
在如下位置下断点
asm-break
程序断下后,观察此时[rsp+70h+var_50]上的数据
可以发现,前6个数据均为非0的0xFF,而后面的数据均为0
这是因为我们构造的输入的前6个字符"hgame{“是正确的,而后面凑长度的字符是错误的
asm-stack
于是我们可以知道
可以通过[rsp+70h+var_50]上连续的0xFF的个数n,确定我们的输入前n个字符是正确的
那么怎么知道[rsp+70h+var_50]上连续的0xFF的个数n呢?我们需要能够打印的函数
程序最后会打印"success"或者"error”,我们可以利用这个打印函数
从框住的汇编指令处可以观察到,我们的目标数据地址是借rcx寄存器传入打印函数的
asm-print
于是我们patch程序,将[rsp+70h+var_50]借rcx传入打印函数,如下
(这里不知道怎么能直接实现lea rcx,[rsp+70h+var_50],如果有师傅知道,请在评论区留言,谢谢)
asm-patch
这样程序在最后就不会打印"success"或者"error",而会打印[rsp+70h+var_50]上的数据
将patch应用到程序后,再起调试,同样的输入,在调用打印函数printf后下断,观察打印出的内容
可以看到虽然没有打印出具体的字符(因为0xFF不可见),但是长度是正确的,为6
asm-printf
或者可以用python来确认

import subprocess
flag="hgame{abcdefghijklmnopqrstuvwxy}"
p = subprocess.Popen(["D:\\ctfdownloadfiles\\hardasm.exe"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.write(flag.encode())
p.stdin.close()
out = p.stdout.read()
print(len(out))
for c in out:print(hex(c))
# 6
# 0xff
# 0xff
# 0xff
# 0xff
# 0xff
# 0xff

最后就是依次爆破每个位置上的字符
根据程序打印出的连续的0xFF的个数来确定某位置上的字符是否正确

# -*- coding:utf-8 -*-
import subprocess
real_flag="hgame{"#绝对正确的前6个字符
cur_index=6#当前爆破的位置
while cur_index<32:for i in range(32,128):#当前爆破的位置上的字符real_flag_arr = [0] * 32for j in range(len(real_flag)):#正确的先复制一下real_flag_arr[j]=ord(real_flag[j])real_flag_arr[len(real_flag_arr)-1]=ord("}")#最后一个字符"}"固定for j in range(len(real_flag_arr)-2,cur_index,-1):#除了当前爆破的位置,其他位置上都设置为32real_flag_arr[j]=32real_flag_arr[cur_index]=i#设置当前爆破的位置上的字符real_flag_arr_s="".join(chr(k) for k in real_flag_arr)#输入到程序中的字符串p = subprocess.Popen(["D:\\ctfdownloadfiles\\hardasm.exe"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)p.stdin.write(real_flag_arr_s.encode())p.stdin.close()out = p.stdout.read()if len(out)>cur_index:#判断程序打印出的0xFF的个数是否增加,增加则说明当前爆破的位置上的字符设置的是正确的real_flag+=chr(i)cur_index+=1print(real_flag)break
# hgame{r
# hgame{ri
# hgame{rig
# hgame{righ
# hgame{right
# hgame{right_
# hgame{right_y
# hgame{right_yo
# hgame{right_you
# hgame{right_your
# hgame{right_your_
# hgame{right_your_a
# hgame{right_your_as
# hgame{right_your_asm
# hgame{right_your_asm_
# hgame{right_your_asm_i
# hgame{right_your_asm_is
# hgame{right_your_asm_is_
# hgame{right_your_asm_is_g
# hgame{right_your_asm_is_go
# hgame{right_your_asm_is_goo
# hgame{right_your_asm_is_good
# hgame{right_your_asm_is_good!
# hgame{right_your_asm_is_good!!
# hgame{right_your_asm_is_good!!}
# hgame{right_your_asm_is_good!!} 

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

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

相关文章

Python3 爬虫学习笔记 C03 【Ajax 数据爬取】

Python3 爬虫学习笔记第三章 —— 【Ajax 数据爬取】文章目录【3.1】Ajax 简介 【3.2】解析真实地址提取【3.1】Ajax 简介 Ajax — Asynchronous Javascript And XML&#xff08;异步 JavaScript 和 XML&#xff09;&#xff0c;是指一种创建交互式网页应用的网页开发技术。可…

REVERSE-COMPETITION-HWS-5TH-2022

REVERSE-COMPETITION-HWS-5TH-2022re1re2re3re1 64位exe&#xff0c;ida打开&#xff0c;来到main函数 输入的长度应为32&#xff0c;输入经过TEA加密&#xff0c;密文与已知的cipher进行比较 进入TEA函数&#xff0c;发现是魔改TEA&#xff0c;需一次性传入8个unsigned int&…

REVERSE-COMPETITION-DSCTF-2022

REVERSE-COMPETITION-DSCTF-2022catchmeFFunctionnothingbad_applefantastic_cpucatchme 安卓逆向&#xff0c;java层传递输入&#xff0c;调用native层的check方法 ida打开.so文件&#xff0c;没有直接找到check方法&#xff0c;JNI_OnLoad也看不出什么 Findcrypt查到AES的S盒…

01-单一职责原则(SPR)

1. 背景 类T负责两个不同的职责&#xff1a;职责P1&#xff0c;职责P2。当由于职责P1需求发生改变而需要修改类T时&#xff0c;有可能会导致原本运行正常的职责P2功能发生故障。 2. 定义 不要存在多于一个导致类变更的原因。通俗的说&#xff0c;即一个类只负责一项职责。 3.…

Python3 已经安装相关库,Pycharm 仍然报错 ModuleNotFoundError: No module named 'xxxxxx' 的解决办法

以 requests 库为例&#xff0c;打开 cmd&#xff0c;运行命令 pip install requests&#xff0c;即可安装 requests 库&#xff0c;由于我已经安装过&#xff0c;所以会提示 Requirement already satisfied 此时&#xff0c;我们使用 Pycharm 运行以下代码&#xff1a; impo…

Sharepoint学习笔记—Site Definition系列-- 3、创建ListDefinition

创建一个List Definition有多条途径&#xff0c;这里由于我们要基于前面的用户自定义Content Type来创建一个List Defintion&#xff0c;所以我们就需要使用到List Definition From Content Type模板。 这里先大致描述如何创建List Definition&#xff0c;然后重点介绍一下Li…

Sharepoint学习笔记—error处理-- The user does not exist or is not unique.

看到网上不少人遇到过这种类似的错误&#xff0c;而产生这种错误的原因也有多种&#xff0c;我产生此错误的背景是在试图通过ECMAscript对象模型把一个User添加到某个指定的Group中时遇到的。 问题1.当我试图把一个User添加到Sharepoint的某个指定的Group&#xff0c;…

Knockout学习笔记之二($root,$parent及$data的区别)

以下是我从Google上找到的一个例子&#xff0c;非常生动形象&#xff0c;我修改了部分代码&#xff0c;具体内容如下&#xff1a; 对于$root 与$parent的区别&#xff1a; $root refers to the view model applied to the DOM with ko.applyBindings;译&#xff1a;$root 是指…

GitHub 学生认证,申请 GitHub 学生包

GitHub 面对学生推出了学生认证服务&#xff0c;通过认证后就可以得到学生包&#xff0c;学生包大概有十几项优惠&#xff0c;包括 DATADOG Pro 帐户、免费两年的10台服务器&#xff0c;Icons8 3个月的带图标&#xff0c;照片&#xff0c;插图和音乐订阅服务、JETBRAINS 专业桌…

Python3 使用 pymysql 连接 MySQL 建表时出现 Warning3719 UTF8 警告

在学习 Python3 爬虫关系型数据库储存时&#xff0c;利用 pymysql 连接 MySQL 建表&#xff0c;测试用的代码如下&#xff0c;第一句 SQL 用于获取当前 MySQL 的版本信息&#xff0c;第二句 SQL 执行创建 spiders 数据库的操作&#xff0c;如果程序代码正确&#xff0c;将会输出…

完美解决 bash: hexo: command not found

背景介绍&#xff1a;有好几天没动过 Hexo 博客了&#xff0c;今天准备更新的时候输入 hexo s&#xff0c;报错 bash: hexo: command not found&#xff0c;这是啥情况&#xff1f;以前都好好的&#xff0c;想了一下&#xff0c;大概是这几天折腾各种 Python 库的原因&#xff…

Sharepoin学习笔记 —架构系列--02 Sharepoint的处理(Process)与执行模型(Trust Model) 1

Sharepoint210有四种执行模型: 1、完全信任执行模型(Full Trust) 2、Bin/CAS 执行模型 &#xff08;1与2都属于场解决方案&#xff09; 3、沙盒执行模型(Sand Box) 4、 混合执行方法&#xff08;Hybrid Approach&#xff09; Sharepoint最简单的处理模型就是一个完整的Asp.net应…

Python3 爬虫学习笔记 C10【数据储存系列 — MySQL】

Python3 爬虫学习笔记第十章 —— 【数据储存系列 — MySQL】文章目录【10.1】MySQL 基本操作语句数据库操作表操作表的结构表的数据【10.2】Python 连接 MySQL【10.3】创建表【10.4】插入数据【10.5】更新数据【10.6】删除数据【10.7】查询数据【10.8】实战训练 — 爬取CSDN博…

Sharepoin学习笔记—架构系列--03 Sharepoint的处理(Process)与执行模型(Trust Model) 2

上文我们了解了一个外部Http Request进入IIS 工作进程(W3WP)的处理与执行信任模型&#xff0c;这个阶段是Sharepoint的四种执行模型都必须经过的处理阶段&#xff0c;其中Sharepoint场解决方案与任何 ASP.NET 应用程序一样就是在 IIS 工作进程(w3wp)中运行的&#xff0c;所以上…

Python3 爬虫学习笔记 C11【数据储存系列 — MongoDB】

Python3 爬虫学习笔记第十一章 —— 【数据储存系列 — MongoDB】文章目录【11.1】关于 MongoDB【11.2】MongoDB 基本操作语句【11.3】连接 MongoDB【11.4】指定数据库【11.5】指定集合【11.6】插入数据【11.6】数据查询【11.7】数据计数【11.8】数据排序【11.9】数据偏移【11.…

Sharepoin学习笔记—架构系列--04 Sharepoint的四种执行模型 1

Sharepoint210有四种执行模型 1、完全信任执行模型(Full Trust) 2、Bin/CAS 执行模型 &#xff08;1与2都属于场解决方案&#xff09; 3、沙盒执行模型(Sand Box) 4、 混合执行方法 (Hybrid Approach) 下面分别来看看它们是怎么回事 一、场解决方案 场解决方案是在 Share…

Python3 爬虫学习笔记 C12【验证码对抗系列 — 图形验证码】

Python3 爬虫学习笔记第十二章 —— 【验证码对抗系列 — 图形验证码】文章目录【12.1】关于普通图形验证码【12.2】tesserocr 库识别验证码【12.3】pytesseract 库识别验证码【12.4】验证码处理【12.5】tesserocr 与 pytesserocr 相关资料【12.1】关于普通图形验证码 普通图形…

Sharepoin学习笔记—架构系列--05 Sharepoint的四种执行模型 2

上一篇我们看了场解决方案与沙盒方案两种执行模型&#xff0c;其中场解决方案包括有完全信任方式与Bin/CAS方式两种&#xff0c;这里让我们继续来看看最后一个执行模型&#xff0c;即混合模型(或混合模式)。 三、混合模式&#xff08;hybrid approaches&#xff09; 所谓混合模…

Python3 爬虫学习笔记 C13【验证码对抗系列 — 滑动验证码】

Python3 爬虫学习笔记第十三章 —— 【验证码对抗系列 — 滑动验证码】文章目录【13.1】关于滑动验证码【13.2】滑动验证码攻克思路【13.3】模拟登录 bilibili — 总体思路【13.4】主函数【13.5】初始化函数【13.6】登录函数【13.7】验证码元素查找函数【13.8】元素可见性设置函…

Sharepoin学习笔记—架构系列—06 Sharepoint服务(Services)与服务应用程序框架(Service Application Framework) 1

Sharepoint服务是Sharepoint的重要组成&#xff0c;可以说Sharepoint的许多网站功能都是基于这些服务构架起来的。这里把Sharepoint服务的相关要点总结一下。 1、什么是 SharePoint 服务&#xff1f; SharePoint 服务是一项 IT 服务&#xff0c;它是运行在后台&#xff0c;为调…