基于可变窗口的细粒度代码加密方法及其代码的运行方法

专利2024-12-22  41



1.本发明属于软件安全及网络安全技术领域,涉及一种提高代码加解密粒度的方法,特别涉及一种基于可变窗口的细粒度代码加密方法及其代码的运行方法。


背景技术:

2.代码加密是常用的软件保护技术,根据加密对象的不同可以分为面向源代码的加密和面向二进制文件的加密。源代码加密(source code encryption)常用于python、php、javascript等脚本语言,只对程序的代码进行加密处理,重点降低代码的可读性。为了对抗分析,通常可使用取消临时变量、使用没有含义的变量名、常量动态生成等方法;在结构上也可以借助等价变换混淆代码的结构,例如切换循环语句、加入无效跳转、递归转化等方法进一步降低代码被识别的可能。
3.不同于脚本语言,c++、rust、golang等编写的程序需要编译后执行,此时采用源代码加密收效甚微,因为代码经过编译器生成的机器码变化不足。二进制文件加密(binary file encryption)即是对生成的可执行文件进行加密保护,其直接面向可执行文件进行处理。由于文件的执行需要遵循操作系统的设计规则,即首先由文件加载器负责载入程序,然后需要寻找程序的入口点(entry point),最后才开始执行相关代码。所以二进制文件加密的核心原理便是先对程序的机器码进行加密,再通过代码注入的方式,植入相关的解释器;在程序运行后,对注入的代码进行解释执行,在不破坏程序语义的前提下,完成在程序执行入口点代码前实现数据解密等操作,还原真正执行的代码,保证程序的正常运行。
4.虽然二进制文件加密可以有效对抗静态分析,但常用的做法是只进行一次加密,即无法进行持续性的对抗,面对诸如动态调试(dynamic debugging)和内存转储(memory dump)等动态分析方法时效果不明显。对于逆向工程(reverse engineering)而言,在并不关心具体函数的实现前提下,使用内存转储可以用来直接获取内存数据,即使这是个黑盒(black box),例如加密前的数据和解密后的数据,并在后续进行离线分析。但在实际分析过程中,攻击者还需要知道在何时对何处数据进行转储,如果时机把握不好,则不能得到正确的数据;如果地址不进行筛选,则会得到大量无用的数据,增加后续处理难度。因此,在代码加密的过程中,需要着重提高代码的加密粒度,尽可能减少在同一时间暴露的代码量,如此便能给攻击者带来极大的困难。
5.在学术界,曾有相关的团队提出这种细化代码加密粒度的方法。wu等人(wu m,zhang y,mi x.binary protection using dynamic fine-grained code hiding and obfuscation[c]//proceedings of the 4th international conference on information and network security.2016:1-8.)提出了基于基本块的代码加密保护方法dynfcho,其优势在于隐藏程序的控制流,这同时也是一种代码虚拟化的框架,通过附加的组件实现所有的功能,同时融合了代码混淆等技术。lee等人(lee j y,suk j h,lee d h.vodka:virtualization obfuscation using dynamic key approach[c]//international workshop on information security applications.springer,cham,
2018:131-145.)也提出了一种基于基本块的虚拟代码保护方法vodka,该方法同时重点关注反调试和反动态二进制插桩,有效遏制了攻击者的可调试范围。但该方法也只能对基本块进行加密,粒度没有进一步提高,实际加密时面对不同情况处理灵活性不足,且在程序运行解密后,没有进行二次加密,即没有和反调试模块进行有效的配合。suk等人(suk j h,lee d h.vcf:virtual code folding to enhance virtualization obfuscation[j].ieee access,2020,8:139161-139175.)则提出了另一种基于折叠的代码加密保护技术vcf,同样基于二进制文件加密,通过折叠暂时不执行的代码,再在运行时解密,能有效保护代码被分析的可能性。但其保护的粒度同样太粗,若采用内存转储即可进行离线分析,等虚拟指令被解压出来就可以进行内存转储,同时在方法实现过程中,当程序执行碰到call/jmp/ret等产生控制流跳转的汇编指令就需要特殊处理,运行效率和算法设计也有待改进。
[0006]
这些研究基本都把基本块作为最小的代码加密单位,但实际上粒度可以更小。例如对基本块进行切分,将得到的子基本块采用随机存储,但在执行时依然采用顺序连接的方法,通过不断跳转实现基本块语义的等价。此外在进行代码加密的过程中,引入程序自修改技术,可进一步提高程序的理解性。程序自修改技术(self modifying code)是一种能在程序在运行期间修改自身指令的技术,计算机病毒和木马通常借助这种技术对抗静态分析,逃避杀毒软件的查杀。这种自己修改自己的代码,是程序自我保护的一种机制,能使反汇编器和调试器失效,因为反汇编得到的代码并非执行过程中的代码,所以即使代码看起来不合逻辑难以理解,但是实际运行起来却具有一定的语义。这些方法可以进一步提高加密方法的强度,在充分考虑这些技术实现的前提下,可以通过调整一定的策略,细化加密的粒度,有效对抗攻击者的分析。


技术实现要素:

[0007]
本发明的目的在于提供一种基于可变窗口的细粒度代码加密方法及其代码的运行方法,该加密方法基于可变窗口,细化了加解密的粒度,能有效对抗内存转储等动态分析方法,且窗口大小支持自定义,具有良好的适应性。
[0008]
可变窗口在本发明中指一种更细粒度的加密单位,其基于汇编语句,由若干条汇编语句组成,窗口的长度由汇编语句的机器码长度决定,其长度一般小于程序中基本块的平均长度。
[0009]
本发明采用的技术方案如下:
[0010]
一种基于可变窗口的细粒度代码加密方法,所述方法包括:
[0011]
基于目标程序中指令语句的机器码长度,设置窗口大小;
[0012]
针对窗口pi中每一指令语句的机器码,使用密钥ki进行加密,并根据窗口pi中指令语句的机器码长度以及所述指令语句的类型,将所述窗口pi滑动至一新窗口,其中i为窗口序号;
[0013]
直至对所述目标程序处理完毕之后,得到初始加密程序;
[0014]
将解释器植入初始加密程序,并适应性修改所述初始加密程序的元数据之后,得到所述目标程序的加密程序,其中,所述解释器的内容包括:所诉窗口大小和所述密钥ki。
[0015]
进一步地,所述根据窗口pi中指令语句的机器码长度以及所述指令语句的类型,将所述窗口pi滑动至一新窗口,包括:
[0016]
针对窗口pi,获取每一所述提取到的指令语句的机器码数量;
[0017]
将各所述提取到的指令语句的机器码数量相加,得到数值m;
[0018]
若所述窗口中指令语句的类型不包含跳转语句,则将所述窗口pi滑动m步,得到新窗口;
[0019]
或,
[0020]
针对窗口pi,获取每一所述提取到的指令语句的机器码数量;
[0021]
将各所述提取到的指令语句的机器码数量相加,得到数值m;
[0022]
若所述窗口中指令语句的类型包含跳转语句,则获取所述跳转语句的目标语句,将所述目标语句的首个机器码作为新窗口的首个机器码,且结合所述数值m,以构建新窗口;
[0023]
将所述窗口pi滑动至新窗口。
[0024]
进一步地,所述元数据包括:程序镜像大小和入口点地址。
[0025]
一种面向上述任一加密程序的代码运行方法,所述方法包括:
[0026]
基于所述解释器,提取所述窗口大小;
[0027]
执行窗口pi中的机器码时,分别提取指令语句以及基于所述解释器提取所述密钥ki,并使用所述密钥ki对该提取到的指令语句中的每一机器码解密;
[0028]
基于解密后的机器码执行所述指令语句之后,使用所述密钥ki对该提取到的指令语句中的每一机器码加密后,根据所述指令语句的指令,将所述窗口pi滑动至一新窗口;
[0029]
直至所述加密程序执行完毕,得到代码运行结果。
[0030]
进一步地,基于解密后的机器码执行所述指令语句之后,使用所述密钥ki对该提取到的指令语句中的每一机器码加密后,根据所述指令语句的指令,将所述窗口pi滑动至一新窗口,包括:
[0031]
基于解密后的机器码,依次执行窗口pi内所有的指令语句;
[0032]
使用所述密钥ki对该提取到的指令语句中的每一机器码加密;
[0033]
根据窗口pi中指令语句的机器码长度,将所述窗口pi滑动至新窗口;
[0034]
或,
[0035]
基于解密后的机器码,依次执行窗口pi内的指令语句,直至执行完跳转语句;
[0036]
使用所述密钥ki对窗口pi中每一提取到的指令语句中的机器码加密;
[0037]
获取所述跳转语句的目标语句,将所述目标语句的首个机器码作为新窗口的首个机器码,并结合所述窗口大小,构建新窗口;
[0038]
将所述窗口pi滑动至所述新窗口。
[0039]
一种基于可变窗口的细粒度代码加密装置,包括:
[0040]
窗口大小设置模块,用于基于目标程序中指令语句的机器码长度,设置窗口大小;
[0041]
窗口加密模块,用于针对窗口pi中每一指令语句的机器码,使用密钥ki进行加密,并根据窗口pi中指令语句的机器码长度以及所述指令语句的类型,将所述窗口pi滑动至一新窗口,其中i为窗口序号;直至对所述目标程序处理完毕之后,得到初始加密程序;
[0042]
程序生成模块,用于将解释器植入初始加密程序,并适应性修改所述初始加密程序的元数据之后,得到所述目标程序的加密程序,其中,所述解释器的内容包括:所诉窗口大小和所述密钥ki。
[0043]
一种基于可变窗口的细粒度代码运行装置,包括:
[0044]
窗口大小提取模块,用于基于所述解释器,提取所述窗口大小;
[0045]
窗口解密模块,用于执行窗口pi中的机器码时,分别提取指令语句以及基于所述解释器提取所述密钥ki,并使用所述密钥ki对该提取到的指令语句中的每一机器码解密;
[0046]
加密与滑动模块,用于基于解密后的机器码执行所述指令语句之后,使用所述密钥ki对该提取到的指令语句中的每一机器码加密后,根据所述指令语句的指令,将所述窗口pi滑动至一新窗口;
[0047]
结果生成模块,用于直至所述加密程序执行完毕,得到代码运行结果。
[0048]
一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现上述任一方法。
[0049]
一种计算机设备,所述计算机设备包括存储器和处理器,所述存储器中存储有计算机程序,所述计算机程序由所述处理器加载并执行,以实现上述任一方法。
[0050]
一种计算机程序产品,当所述计算机程序产品在计算机设备上运行时,使得计算机设备执行上述任一方法。
[0051]
与现有技术相比,本发明的有益效果:
[0052]
近些年,随着网络攻击的普遍和盗版环境的传播,软件被攻击者分析是不可避免的,软件安全和数据安全问题得到越来越多的关注。但在代码加密过程中,加密的强度没有得到显著提高,传统的方法均是以基本块为粒度进行数据加密,或借助自修改代码技术对整个代码进行一次性加密,而加密的粒度将决定内存转储的次数和攻击者的分析难度。
[0053]
本发明在充分学习相关研究和实验测试后,结合实际应用场景,创新性得提出了一种基于可变窗口的细粒度代码加密方法。可变窗口机制保证了数据的机密性,在程序运行过程中可以做到多次成功加解密,保证了指令只有在当前窗口内才能被正确解密,且解密宽度不一定等于窗口的大小,即使攻击者在得到窗口大小的情况下也无法进行解密还原,有效提高了攻击者的分析成本。
附图说明
[0054]
图1为本发明的操作流程图;
[0055]
图2为本发明在运行过程中的执行流程图;
[0056]
图3为本发明实施例一的流程图a;
[0057]
图4为本发明实施例一的流程图b。
[0058]
图5为本发明实施例一的流程图c。
具体实施方式
[0059]
下面将结合附图,对本发明实施方式中的技术方案进行清楚、完整地描述,显然,所描述的实施方式仅仅是本发明特定实施方式,而不是全部的实施方式。基于本发明中的实施方式,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施方式,都属于本发明保护的范围。
[0060]
本发明主要目标是对指令进行加密,并实现运行时代码加解密,细化加解密粒度,同时能有效对抗动态分析方法,窗口具有以下两大特征。
[0061]
1)窗口的移动具有方向性,窗口可以移动,每次移动的距离可以固定也可以不一致。
[0062]
2)窗口的窗口大小不固定,窗口大小变化有最大和最小值。
[0063]
为了体现这两大特征,结合加密的需要,发明内部将整个加密模型为四种状态,分别是解密、执行、加密和移动。首先当程序执行到相关的指令区域时,解释器根据当前窗口的所在位置,对执行指令的区域进行数据解密,解密范围为整个窗口内的数据;解密完成后执行相关指令;执行完后再次对窗口内部的指令进行加密,使其和解密前的数据保持一致;当窗口内指令均执行完则移动窗口,对下一个区域内的指令进行重复操作,移动的距离由执行指令的长度决定。
[0064]
本发明方法操作流程如图1所示。首先在程序执行前设定号窗口大小,不同的窗口大小将决定加密的粒度;其次进行二进制文件的代码加密,完成对数据保护;之后植入解释器,同时修改程序的元数据,使程序能正常运行。
[0065]
本发明在运行过程中的执行流程如图2所示。在程序运行时,首先进行指令定位,确认当前执行指令的地址;其次进行解密操作,使数据被解密,并执行代码;之后解释器会判断当前的代码是否在窗口内部,如果没超过范围则继续执行相关代码;如果超过范围,则说明窗口内部指令全部执行完毕,进行二次加密的过程,加密完成后移动窗口,进行下一段代码的解密执行,如此循环,直到所有代码执行完毕,程序自动退出。
[0066]
在密钥生成部分,本发明使用内存完整性校验的方式对函数代码进行检测,用于产生密钥,并对指令进行加密保护。由于函数的起始和结束地址可以静态确定,运行时不会发生变化,且内容也固定,所以静态加密和运行时解密两过程保持一致。
[0067]
下面以一实施例进行具体说明。
[0068]
本实例以可变窗口的大小为4(单位:字节)为例对本发明进行详细说明。如图3所示,图中的字母显示的分别是指令的机器码,统一颜色的代表同一条指令,即分别有ab、cde、fg、h和i共5条指令。其中ab、cde、fg、i代表顺序执行指令,h代表无条件跳转指令,从h处直接跳转到c处。5条指令的长度分别是2、3、2、1、1(单位:字节)。由斜线框包围的阴影部分表示的是当前窗口的位置,即此时窗口的起点位置是a,包含abcd共4字节。程序从ab指令开始执行代码。
[0069]
当程序开始执行后,需要进行指令定位,寻找到当前窗口的位置,并判断当前执行指令的位置是否在窗口内部。在图3的情况下,由于ab指令完全处在窗口内部,且需要执行,所以解释器需要解密ab指令的数据。解释器在得到加密密钥k1后,进行数据解密,此时解密的长度不是由指令本身的长度决定,而是由滑动窗口的大小决定,即解释器使用密钥k1,对一共4字节长度的数据进行解密,得到a

k1、b

k1、c

k1、d

k1。
[0070]
解密完成后,解释器按顺执行当前窗口内部的指令序列。因为此时ab指令解密成功,所以ab指令可以执行,当ab指令执行完成后,解释器判断下一条指令是否需要执行。由于此时cde指令中,e处于当前窗口的外部,导致一条完整的指令被窗口截断,且解密cde指令也没有使用到正确的密钥k2,即c

k1、d

k1为错误数据,解密失败,无法顺利执行cde指令。控制器在得到相关信息后,将进行错误控制,判断此时窗口内部的所有指令已执行完毕,进入重加密阶段。
[0071]
由于此时整个窗口内执行完毕,解释器首先将窗口内的数据进行重加密,恢复成
解密前的数据,此时使用的密钥ki和先前执行代码时使用的解密密钥保持一致,即窗口内的数据恢复成abcd。使用同一密钥能有效降低不同密钥的存储难度,以及面对循环结构难以处理的情景,不会出现解密一次后,后续的解密失败。
[0072]
加密完成后,为了执行cde指令,窗口需要进行移动,使其完整包含cde指令,并使用正确的密钥。如图4所示,此时控制器根据当前窗口内执行完的指令长度,得到窗口移动的距离,由于此时只执行了ab指令,指令长度是2,所以窗口会向前移动2字节,即移动到cde指令的起始地址。
[0073]
此时由于cde指令均在窗口内部,所以执行情况和图3一致,进行第二轮的解密、执行、加密和移动过程。解释器在获取到cde指令对应的密钥k2后,解密数据得到c

k2、d

k2、e

k2、f

k2。顺利执行cde指令后,解释器同样根据下一条指令fg指令被当前窗口截断,无法执行的情况,判断当前窗口内的指令执行完毕,继续进行加密和移动过程。
[0074]
但当窗口内包含跳转指令时,情况会复杂得多。如图5所示,此时窗口内部包含fghi共4字节数据,且fg、h和i指令均在窗口内部,都能解密成功并执行。但h指令的执行将导致程序的控制流产生变化,直接无条件跳转到cde指令位置,而此时cde指令的数据已经被加密了,所以进行直接跳转会出现问题。
[0075]
因此在实现过程中,考虑到跳转指令的特殊性,本发明将call、ret、jmp等跳转指令的执行延后处理。这样就不需要在指令层考虑指令语义与执行的差异带来的影响,使窗口的移动完全取决于当前执行的指令地址。指令顺序执行,窗口发生移动;指令进行跳转,窗口的位置也会发生跳跃。而加密的数据在指令跳转前就已经完成,所以控制流转移指令也不会影响加解密的效果。即在图5所示的情景中,解释器判断h指令执行完后执行cde指令,而cde的位置位于窗口外部。所以解释器会先对窗口内部的数据进行重加密,然后窗口将跳跃到cde指令的起始地址,后续的执行情况则不再赘述。
[0076]
下面对发明的具体使用效果进行简要说明。在实验测试过程中,选择多个以密码和编码算法作为主要逻辑的程序作为测试对象,并选取其中的核心函数进行加密。这些测试样例包括base64、rc4、aes、md5,测试不同函数在不同窗口大小下的内存转储次数,用以量化攻击者的分析难度,实验得到的数据如表1所示。
[0077]
表1.不同实例和不同窗口大小下的内存转储次数
[0078]
窗口大小base64rc4aesmd561098833310197927528583788166244784969582096571062481855831539321223882029238928125241971224301916591864014124313750121035110
6010829927087257880762269
[0079]
当窗口大小可变时,面对攻击者常用的内存转储分析,攻击者需要转储每次被解密的指令。基于本发明提出的可变窗口模型,由于解密数据只存在于窗口内部,即使攻击者推测出了窗口大小,也无法获得每一次的解密长度。从表中数据可知,内存转储的次数和窗口大小成反比,当窗口较小时,每次解密的数据少,转储的次数多;当窗口逐渐增大时,每次解密的字节增多,转储次数减少,安全性也随之降低。这是由于可变窗口大小可控,更具灵活性。因此,在实际对程序进行保护的过程中,需要结合文件的情况,对引入的开销进行评估,再进行窗口的调整。若不考虑程序自身的因素,将窗口大小设置为15字节时,其对程序的影响较小,此时平均的额外开销低,而平均内存转储次数是80字节的5倍多,可以兼顾执行效率和安全性。
[0080]
以上实施例仅用以说明本发明的技术方案而非对其进行限制,本领域的普通技术人员可以对本发明的技术方案进行修改或者等同替换,而不脱离本发明的精神和范围,本发明的保护范围应以权利要求书所述为准。

技术特征:
1.一种基于可变窗口的细粒度代码加密方法,所述方法包括:基于目标程序中指令语句的机器码长度,设置窗口大小;针对窗口p
i
中每一指令语句的机器码,使用密钥k
i
进行加密,并根据窗口p
i
中指令语句的机器码长度以及所述指令语句的类型,将所述窗口p
i
滑动至一新窗口,其中i为窗口序号;直至对所述目标程序处理完毕之后,得到初始加密程序;将解释器植入初始加密程序,并适应性修改所述初始加密程序的元数据之后,得到所述目标程序的加密程序,其中,所述解释器的内容包括:所诉窗口大小和所述密钥k
i
。2.如权利要求1所述的方法,其特征在于,所述根据窗口p
i
中指令语句的机器码长度以及所述指令语句的类型,将所述窗口p
i
滑动至一新窗口,包括:针对窗口p
i
,获取每一所述提取到的指令语句的机器码数量;将各所述提取到的指令语句的机器码数量相加,得到数值m;若所述窗口中指令语句的类型不包含跳转语句,则将所述窗口p
i
滑动m步,得到新窗口;或,针对窗口p
i
,获取每一所述提取到的指令语句的机器码数量;将各所述提取到的指令语句的机器码数量相加,得到数值m;若所述窗口中指令语句的类型包含跳转语句,则获取所述跳转语句的目标语句,将所述目标语句的首个机器码作为新窗口的首个机器码,且结合所述数值m,以构建新窗口;将所述窗口p
i
滑动至新窗口。3.如权利要求1所述的方法,其特征在于,所述元数据包括:程序镜像大小和入口点地址。4.一种面向权利要求1-3中任一加密程序的代码运行方法,所述方法包括:基于所述解释器,提取所述窗口大小;执行窗口p
i
中的机器码时,分别提取指令语句以及基于所述解释器提取所述密钥k
i
,并使用所述密钥k
i
对该提取到的指令语句中的每一机器码解密;基于解密后的机器码执行所述指令语句之后,使用所述密钥k
i
对该提取到的指令语句中的每一机器码加密后,根据所述指令语句的指令,将所述窗口p
i
滑动至一新窗口;直至所述加密程序执行完毕,得到代码运行结果。5.如权利要求4所述的方法,其特征在于,基于解密后的机器码执行所述指令语句之后,使用所述密钥k
i
对该提取到的指令语句中的每一机器码加密后,根据所述指令语句的指令,将所述窗口p
i
滑动至一新窗口,包括:基于解密后的机器码,依次执行窗口p
i
内所有的指令语句;使用所述密钥k
i
对该提取到的指令语句中的每一机器码加密;根据窗口p
i
中指令语句的机器码长度,将所述窗口p
i
滑动至新窗口;或,基于解密后的机器码,依次执行窗口p
i
内的指令语句,直至执行完跳转语句;使用所述密钥k
i
对窗口p
i
中每一提取到的指令语句中的机器码加密;获取所述跳转语句的目标语句,将所述目标语句的首个机器码作为新窗口的首个机器码,并结合所述窗口大小,构建新窗口;
将所述窗口p
i
滑动至所述新窗口。6.一种基于可变窗口的细粒度代码加密装置,包括:窗口大小设置模块,用于基于目标程序中指令语句的机器码长度,设置窗口大小;窗口加密模块,用于针对窗口p
i
中每一指令语句的机器码,使用密钥k
i
进行加密,并根据窗口p
i
中指令语句的机器码长度以及所述指令语句的类型,将所述窗口p
i
滑动至一新窗口,其中i为窗口序号;直至对所述目标程序处理完毕之后,得到初始加密程序;程序生成模块,用于将解释器植入初始加密程序,并适应性修改所述初始加密程序的元数据之后,得到所述目标程序的加密程序,其中,所述解释器的内容包括:所诉窗口大小和所述密钥k
i
。7.一种基于可变窗口的细粒度代码运行装置,包括:窗口大小提取模块,用于基于所述解释器,提取所述窗口大小;窗口解密模块,用于执行窗口p
i
中的机器码时,分别提取指令语句以及基于所述解释器提取所述密钥k
i
,并使用所述密钥k
i
对该提取到的指令语句中的每一机器码解密;加密与滑动模块,用于基于解密后的机器码执行所述指令语句之后,使用所述密钥k
i
对该提取到的指令语句中的每一机器码加密后,根据所述指令语句的指令,将所述窗口p
i
滑动至一新窗口;结果生成模块,用于直至所述加密程序执行完毕,得到代码运行结果。8.一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现如权利要求1-5中的任一方法。9.一种计算机设备,所述计算机设备包括存储器和处理器,所述存储器中存储有计算机程序,所述计算机程序由所述处理器加载并执行,以实现如权利要求1-5中的任一方法。10.一种计算机程序产品,当所述计算机程序产品在计算机设备上运行时,使得计算机设备执行如权利要求1-5中的任一方法。

技术总结
本发明提供了一种基于可变窗口的细粒度代码加密方法及其代码的运行方法,所述细粒度代码加密方法包括:基于目标程序中指令语句的机器码长度,设置窗口大小;针对窗口P


技术研发人员:贾晓启 黄庆佳 陈家宇 宋振宇 杜海超 周梦婷 王睿怡 解亚敏 张伟娟 唐静
受保护的技术使用者:中国科学院信息工程研究所
技术研发日:2022.06.16
技术公布日:2022/11/1
转载请注明原文地址: https://tieba.8miu.com/read-11082.html

最新回复(0)