最新要闻
- 今日要闻!尿道结石怎么治疗才能除病根_尿道结石该怎么治疗
- 虚幻引擎5推出重磅新功能MetaHuman Animator:实现真人面部动作高速模拟
- 焦点速看:开放世界元宇宙游戏《仙剑世界》来了:万物皆可交互
- 焦点短讯!中华老字号!西安饭庄糕点礼盒19.9元冲量大促:一次买16枚
- 两女子高速上突然跳车:闻到汽油味、以为要爆炸
- 快讯:河北沧州2022年成人高考成绩查询入口已开通
- 今日观点!女生10年收集万瓶香水价值一套房:圈粉超47万
- 世界热文:捐100亿元建世界一流名校 曹德旺:大学没有教会年轻人动手能力
- 【天天快播报】汽车疯狂降价潮引担忧:狂欢之后会不会是淘汰潮?
- 环球观焦点:Intel 56核心刚出生就落伍!AMD Zen4撕裂者下半年来袭:96核心
- 【新视野】力压美国印度!中国富豪全球第一:钟睒睒蝉联首富 马化腾张一鸣紧随其后
- 石榴汁弄衣服上怎么洗才能不会变干(石榴汁弄衣服上怎么洗)
- 环球最资讯丨机箱中的海景房 乔思伯TK-1双曲面侧透游戏机箱579元:颜值爆表
- 成都比亚迪、特斯拉、宝马三车相撞 特斯拉和宝马车轮飞了
- 【世界速看料】新能源汽车充电时为何要交停车费 专家:可防止充电之后不挪窝
- 当前热点-全球首枚3D打印火箭!美国“人族一号”发射失败
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
天天播报:CSAPP-Bomb Lab
这个实验的逻辑是这样的
需要使用gdb debug 进入到phase_x的各个函数,但是单步调试step是进不去的(也不难理解,如果gdb可以直接进入那这个实验还有什么难点)
(资料图)
但是反汇编得到的结果是全部的内容,通过阅读反汇编代码,找到一些关键节点,通过gdb对二进制进行dubug添加breakpoint从而查看一些内容找到结果
objdump -d bomb > bomb.txt
打开反汇编代码,往下看发现了居然是按函数都分好了,真是万事开头难,开始真的不知道要怎么开始,所以有些事大胆往前走,前面或许不像你想的那么困难
read_line
内容放在%rax中,传到%rdi,对应input = read_line()
查询汇编中 $ 和 % 符号的作用发现了以下内容
DOS/Windows 下的汇编语言,这些汇编代码都是 Intel 风格的。但在 Unix 和 Linux 系统中,更多采用的还是 AT&T 格式,两者在语法格式上有着很大的不同
1. 在 AT&T 汇编格式中,寄存器名要加上 "%" 作为前缀 pushl %eax
2. 在 AT&T 汇编格式中,用 $前缀表示一个立即操作数 pushl $1
3. 目标操作数在源操作数的右边movl $1,%eax
4. 操作数的字长由操作符的最后一个字母决定 b,w,l
这里需要清楚test指令的用途
TEST 指令在两个操作数的对应位之间进行 AND 操作,并根据运算结果设置符号标志位、零标志位和奇偶标志位
ZF:零标志位。相关指令执行后结果为0那么ZF=1,结果不为0则ZF=0
所以如果%eax为0,那么zf就为1,反之zf为0
而je是在zf为1时跳转,即在%eax为0时进行跳转
je在zf为1时进行跳转,相等为什么等价于zf为1呢?、
cmp a b,当a和b相等时zf也为1,为什么两个数相等等价于0标志位为1呢?
答:cmp的比较方法是通过隐含的减法实现的,减法会使得一些标志位发生改变,条件跳转指令就是根据这些标志位来判断比较的结果
上面这些疑问是对于汇编语言本身的疑问,现在我们就单纯接受这些结论,考虑在这里的逻辑
这块的逻辑是调用strings_not_equal,如果strings_not_equal返回的是0就跳转到400ef7即炸弹拆除成功,否则跳转到40143a,即炸弹拆除失败
所以答案实际上是处在strings_not_equal这个函数中的,所以下面去找这个函数
这个函数的汇编代码还是比较长的,乍一看不知道看什么就迷茫了
这时候一个突破点是函数的返回值是通过eax寄存器传递的
所以到strings_not_equal可以找一下eax
当%eax为0时代表拆除成功,所以重点在上面那两个跳转
strings_not_equal
流程分析
调用string_length函数计算字符串长度,函数将长度放在%eax中,返回将将结果存储在%r12d中
再次调用string_length函数计算另一字符串长度,函数仍将结果放在%eax中,但是由于只有两个字符串,所以不需要将%eax的结果另外存储了
相当于提前定义了答案变量并设置默认值为1
res = 1
,返回1会引发爆炸比较两个字符串是否相等,首先计算了两个字符串的长度,然后比较两个字符串长度,如果两个字符串长度不相等那么一定不相同了,跳转到0x40139b处
而0x40139b处事将%edx放到%eax中,这个%eax就是存储函数的返回值
在标志位zf为0时会进行跳转,zf是是否为0的标志位,zf为0代表test结果不为0,因此%al不为0
phase_1实际应当的解题流程
按照bomb.c文件的代码,找到phase_1上方的read_line,下面mov语句
就是将读入的字符串放入到rdi寄存器中
之后去查找phase_1函数,对于红色框通过搜索test和je指令,可以发现这部分的结果事如果%eax为0则拆除成功,如果为1则拆除失败,而%eax的的值事通过
stirngs_not_equal()
得到的(这里了解到的是函数的返回值一般都放置在eax中);对于绿色框,实际是在定义一个答案字符串,我在看到这里时并没有想到这一点,这个答案字符串可能是放在这里的,也可能是放在strings_not_equal函数中的,具体情况还应当到函数中看过之后才可以确定,但是对这里必须有印象之后来到
strings_not_equal
函数内部,这个函数略有复杂,大红色框
将输入的字符串和答案字符串换了个位置,rdi存储的输入字符串,rsi那就是答案字符串了,所以也就印证了phase_1中的esi存储的就是答案字符串的位置,但是注意仅仅看到这里并不能确定答案字符串就处在esi的位置,起始位置要看从哪一位开始比较的,毕竟rsi只是个地址,比较的起始位置到此还不能确定
绿色框
这里是在比较字符串长度,这个不难理解,我们在判断两个字符串是否相等时也是首先判断字符串长度是否相等
橙色框
(%rbx)是间接寻址,rbx寄存器存储的是字符串在内存中的地址,现在将字符串取出来放到eax中,然后检查eax是否为0,ascii为0的字符是空字符(null),如果是空字符按它的结果直接返回0,但实际输入过程我们不可能输入空字符,所以这里对于解题没有什么作用,跳过即可
橙色框上方一句话将输入字符串rbx放入到eax中,橙色框的判断逻辑是如果输入字符串为0,那么test的结果是zf标志位变为1,从而满足je的跳转条件,跳转到将edx的值设置为0,之后跳转到40139b,将edx的值赋值给eax,然后程序返回
蓝色框
这部分按我的理解就是这个字符检查是否相等
解题的关键在于确定是从哪个位置开始遍历的,找到开始遍历的位置也就找到了答案字符串,注意蓝色框中的小红色框,上方的
movzbl (%rbx) %eax
就将输入字符串放到了eax中,而al是eax中的最低的那8位,与输入字符串进行比较的是0X0(%rbp)
,从这里就可以确定了答案字符串就是rbp中存储的那个内存地址,而具体的值还要回到phase_1那里去查看,发现是0x402400
下图是寻址方式和寄存器图示,是理解汇编代码的核心所在
phase_2流程
还是先找read_line找输入字符串
input保存在%rdi中
然后找phase_2函数
整体的跳转过程如下图所示,分别进行分析
首先是这里的函数调用
read_six_numbers
(红色框)于是进入read_six_numbers
,发现这里有两个重点通过gdb查看0x4025c3这个地址,内容是"%d %d %d %d %d %d",结合sscanf
,得知read_six_numbers
是从input中读取到6个数据,这里暂时没有分析这6个数据各自存储到了哪个寄存器,先尝试着向下分析回到phase_2函数(绿色框)
这里的比较非常重要,如果(%rsp)不等于1,那么就直接爆炸了,所以比较的最初条件是(%rsp)为1
橙色框
这部分的关键是
lea
指令,这个东西查询结果很混乱,怎么说的都有,根据实际表现,推测它的作用是lea a b
等价于&a -> b
,即将a的地址放入b中,所以lea 0x4(%rsp), %rbx
的结果是%rbx = M[R[%rsp] + 0x4],即寄存器rsp中存储的是一个基地址,R[%rsp]的意思是将寄存器存储的值取出来,即获得这个基地址,然后加上偏移量0x4,得到一个新地址,M[新地址]的意识是去内存中的这个地址取出这个数值,最后将这个数值的地址让rbx寄存器负责存储,所以rbx存储的就是那个新地址,即R[%rsp] + 0x4,同理让rbp存储R[%rsp]+0x18蓝色框
注意此时的前提是%rbx = &(R[%rsp] + 0x4), 即R[%rbx] = R[%rsp] + 0x4,通俗地说rbx这个寄存器实际存储的是一个地址,内存中这个地址存储的是我们要的数值
mov -0x4(%rbx), %eax
的效果是%eax = M[R[%rbx] - 0x4] = M[R[%rsp] + 0x4 - 0x4] = M[R[%rsp]] = (%rsp),即%eax = 1,而此时(%rbx) = M[R[%rbx]] = M[R[%rsp + 0x4]],实际表现是此时(%rbx)等于我们输入的第二个数据,相当于两个数据在内存中地址相差了4,通过gdb可以验证%eax和(%rbx)两个值综上,蓝色框实际做的是把1翻倍为2,然后与我们输入的第2个数据进行比较
黄色框
这部分会把rbx的值加上0x4,然后与rbp进行比较,直到两者相等时跳转到400f3c,可以看出如果发生该跳转,说明函数结束了,否则会再次跳转到蓝色框
可以发现,之后的过程一直是蓝色框和黄色框的跳转,黄色框像是一个边界判断,而蓝色框则进行的是数值的比较
蓝色框和黄色框中涉及到的寄存器有rbx和eax,rbx一直在+0x4,eax则负责数值的存储并且翻倍,gdb在0x400f29添加断点进行debug可以得到以下结果
所以内存中的存储形式是
总结:phase_2解题的关键在于看懂跳转流程,其中对于lea指令的理解非常重要
phase_1的答案是内存中存储的某个字符串,phase_2还按照这种思想去找是找不到的,因为它的答案是通过运算得出的
phase_3流程
- 读入数据
查看phase_3函数
跳转过程
红色框
首先根据sscanf和0x4025cf,可以得知输入数据应当为2个数通过gdb可以确定的是0x8(%rsp)就是我们输入数据的第一个值,0xc(%rsp)是输入数据的第二个值
蓝色框
根据蓝色框可以得知以下内容
cmp是比较后面的数据与前面数据的关系
第一个输入的数据必须小于等于7,否则直接爆炸
橙色框
这里跳转的地址是比例变址寻址,需要手动计算。这里我犯了一个错误,在计算后输出结果时,应当选择16进制输出,结果我是按照10进制输出的应当选择,
print /x
或x/x
疑问
jmpq *0x402470(,%rax,8)
实际情况是
M[0x402470 + r[rax] * 8]
的结果是一个地址,即内存中地址为0x402470 + r[rax] * 8
的位置存放了一个地址,到内存中这个地址取出来的数据是一个地址,实际跳转到的就是取出来这个数据的地址,但是前面还有个*号,这个*号起到了什么作用?这里跳转的结果是由我们输入的第一个数据决定的,第一个数据只需小于等于7即可,下表列出当第一个输入数据不同时所对应的跳转指令
第一个参数 | 0x402470+r[rax]*8 | 跳转指令 |
---|---|---|
0 | 0x402470 | jmpq 0x00400f7c |
1 | 0x402478 | jmpq 0x00400fb9 |
2 | 0x402480 | jmpq 0x00400f83 |
3 | 0x402488 | jmpq 0x00400f8a |
4 | 0x402490 | jmpq 0x00400f91 |
5 | 0x402498 | jmpq 0x00400f98 |
6 | 0x4024a0 | jmpq 0x00400f9f |
7 | 0x4024a8 | jmpq 0x00400fa6 |
黄色框
黄色框内的红色框即为第二个答案,放入到eax寄存器中
第一个参数 第二个参数 0 207(0xcf) 1 311(0x137) 2 707(0x2c3) 3 100(0x256) 4 389(0x185) 5 206(0xce) 6 682(0x2aa) 7 327(0x147) 紫色框
将第二个输入数据同eax中存放的答案进行比较
phase_4流程
红色框
读入数据包含2个数
蓝色框
第一个数据必须\(<= 14\)
绿色框
初始值
%edx = %rdx = 0xe%esi = %rsi = 0x0%edi = %rdi = 输入的第一个数据
开始调用函数
func4()
,该函数返回值必须为0,即%eax必须为0黄色框
第2个输入数据必须为0
把整体流程走了一遍,两个输入已经确定了后一个,现在还需要确定前一个,解决问题的关键在于绿色框中的func4函数
进入func4函数
红色框
这里的难点主要是一些运算,当然直接使用gdb是个偷懒的方法,可以直接获得ecx的值为0x7
之后会进行一个比较,edi中存储的是第一个输入的数据,当\(edi <= 7\)时会跳转到蓝色框
这里我们并不知道跳转或不跳转会发生什么,不妨尝试一下令\(edi <= 7\)并发生跳转
蓝色框
第一步把eax置为0,这正是phase_4中的合法值
之后比较edi和ecx,即0x7
当\(edi >= 7\)时发生跳转,结束该函数
此时的返回值已经是合法的了,如果直接返回即可解决问题
所以只需要让两次跳转全部发生即可,两次的条件分别为\(edi <= 7\) 和 \(edi >= 7\),全部满足的条件是\(edi == 7\)
所以可以确定最终答案为 7 0
phase_5流程
读入
读入字符串放入到%rdi中
phase_5函数
红色框
上方恰好有一个函数调用
string_length
,eax恰好是函数返回值这里eax必须等于6,否则直接爆炸,因此可以确定答案是一个长度为6的字符串
绿色框
这里只是将eax赋值为0,然后跳转到蓝色框
蓝色框
rax每次加1,直到等于6时跳出蓝色框,否则一直在重复执行
初始条件:
rbx是输入的字符串
rax = 0
因为6轮的代码是一样的,所以每一轮的处理逻辑都是相同的,我们只需要搞清楚第一轮是如何处理的,rax = 0时
M[R[rbx]] -> rcx
rcx -> M[r[rsp]]
M[r[rsp]] -> rdx
rdx & 0xf -> rdx
M[0x4024b0 + R[rdx]] -> rdx
rdx -> M[0x10 + R[rsp]]
精简一下的结果是:
M[R[rbx]] -> rdx
rdx & 0xf -> rdx
M[0x4024b0 + R[rdx]] -> 内存中某个位置
可以发现,这一段循环就是在把一些数据填充到内存中一些位置,如果我们看过橙色框中的内容,可以发现上述代码最终放入的内存地址在下方有出现过,
当rax等于0时,这一段循环最终将一个数据放入到了M[0x10 + R[rsp]]中,而查看橙色框可以发现,这个位置刚好为%rdi的起始数据,而我们知道%rdi正是
strings_not_equal
其中一个比较项strings_not_equal
中另一个比较项esi在橙色框中是给定的,现在的核心是搞清楚上述数据填充的规则,使其填入的恰好为esi的内容flyers
相同即可通过上述大体的分析,可以了解到这个循环大体上在做什么,以及我们的目标是什么,但是要搞清楚具体的操作逻辑,还是要仔细进行分析
首先将读入字符串的第一个字符放入ecx中
一个字符仅占1个字节,即8bit,所以ecx中仅低8bit是有效数据,所以这里使用了cl
之后把cl存储的这个字符内容放到rdx中
之后用
00001111
与edx进行按位与放入到edx中之后以0x4024b0作为基地址,以rdx的值作为偏移量,从内存中取出数据放入到edx中
最后将edx放入到目标位置
根据上述分析,现在可以做的是查看一下内存中0x4024b0这个地址存储的内容是什么
(gdb) x/s 0x4024b00x4024b0
:"maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?" 前面的字符串中包含了我们所需的所有字符,就像一个数组,我们要构造下标将需要的字符取出来
我们需要的字符串是
flyers
,即所需的下标依次为9,15,14,5,6,7而这些数字是通过字符的ascii与00001111进行按位与得到的,所以我们需要的ascii可以是ionefg,以下数据从左到右依次是它们的ascii码与00001111按位与的结果,字符,字符的ascii码
9 i 105
15 o 111
14 n 110
5 e 1016 f 1027 g 103
橙色框
这里的主要内容就是
strings_not_equal
,根据之前的实验,这个函数就是判断rdi和esi内容是否相同
总结:
从整体上来看,这道题解题的关键就在于搞懂蓝色框的内容
从细节上来看,难点在于,多个寄存器和寻址方式的使用,让人眼花缭乱同时由于对于各种寻址方式并不是什么确定,本身存在着自我怀疑,所以深入阅读有些困难,还是要有自信,分析之后可以发现有些内容你想的就是正确的,要坚定信心
phase_6流程
read_six_numbers
把输入的数据读入到寄存器中
1号框
首先把rsp存储数据减少0x50
之后把rsp的数据放入到r13中,可以验证得到它们存储的数据指向的内存区域存储的是第一个输入的数据
2号框
红色框中得到结论是rsp中存储的第一个输入数据的地址,所以eax的结果是第一个输入的数据,减去0x1后需要保证<=0x5,因此第一个输入的数据需要保证<=0x6
3号框
上次出现r12的位置是在绿色框的588行,赋值为0x0
加上0x1后判断是否等于0x6,显然不等于,于是向下继续
根据运算可以相继计算处ebx = 1,rax = 1
mov (%rsp, %rax, 4), %eax
在rax = 1时是将第2个输入的数据放入到eax之后比较eax和rbp的值,上次出现rbp的位置是在绿色框中的
mov %r13, %rbp
,即输入数据的第1个数据所以这里是在比较输入数据的第1个和第2个,这里必须保证两者不能相等
4号框
首先对ebx加1,蓝色框中ebx=1,所以这里等于2
然后判断ebx与5的大小关系,在ebx\(<=5\)时跳转回蓝色框,将rax赋值为ebx
这里不难相出是在做什么,ebx<=5实际代表的就是rax<=5,rax处在取数的代码中,所以这里的循环就是在判断6个数中的后面5个是否均不同于第1个
验证上述逻辑的判断
初始输入数据为 4 5 6 1 2 3
在40113e处添加断点,每次停下时检查%eax和(%rbp)的值,结果依次是
次数 %eax (%rbp) 1 0x5 0x4 2 0x6 0x4 3 0x1 0x4 4 0x2 0x4 5 0x3 0x4 14号框
r13上一次出现的结果是指向输入的第1个数据存储的地址
这里对地址加上4,效果是让其指向了第2个数据
然后跳转到绿色框中,再走一次上面的过程
也就是说还需要保证 第2个数据<=0x6和 第2个数据后面的数据均与第2个数据不同
对以上内容进行总结
上述是一个两重循环,对数据合法性进行了判定,应当满足的要求有两点
- 所有数据\(<=0x6\)
- 任意两个数据不相等
因此可以得知,正确答案就是一个从1,2,3,4,5,6这几个数的一种排列
显然后续过程就是对这种排列顺序进行一个约束
5号框
首先rsi存储输入数据的边界
r14上次出现的位置是在绿色框,被赋值为%rsp,即输入数据的第一个值,用rax进行存储
之后定义ecx为0x7
之后令edx为ecx,即0x7
之后用edx减去当前指向的数据,即rax指向的数据
之后将上一步的结果存储到内存中原数据的位置
之后令rax+4,即指向下一个数的位置
在rax没有到达rsi这个边界之前一直重复上述过程
所以,这一部分完成的事情是将各个输入数据修改为0x7减去各个数据
通过在0x40116f处添加断点可以确定这一点
6号框
将rsi(esi)置为0,跳转到粉色框
- 9号框
查看0x6032d0地址的内容
(gdb) x /12x 0x6032d00x6032d0
:0x000000010000014c0x00000000006032e00x6032e0 :0x00000002000000a80x00000000006032f00x6032f0 :0x000000030000039c0x00000000006033000x603300 :0x00000004000002b30x00000000006033100x603310 :0x00000005000001dd0x00000000006033200x603320 :0x00000006000001bb0x0000000000000000
这是一个链表的结果,前面一个链接着后面一个
- 7号框
这是一个循环,rdx指向一个链表空间,ecx存放的是输入的第一个数据(被7减之后的数据),eax从1开始
每次循环rdx向后移动一个空间,eax自增1,当eax等于ecx时循环结束
假设ecx=4,则最终rdx指向的就是
8号框
把rdx放到地址为rsp + rsi * 2 + 0x20的内存空间中
rsi增加4
之后的判断是在判断是否达到输入空间的终点
10和11是第一次的过程,当rsi增加4后,会把10和11的过程再进行一次
不过我们没有考虑9号框的判断语句,这里的判断第一个输入数据是否为1,如果为1,那么跳转到401183,把链表第一个空间的值放入edx,之后把这个值放入指定的内存空间,之后正常循环
观察它的循环结构,为1的时候是没办法处理的,因为上来就跳到第2个位置,所以相当于对1做的特判
7,8,9,10构成了一个循环,从9号框开始循环,8号框最终结束循环,循环结束的出口为0x4011ab。这段的效果就是,假设我们输入的第一个数据为3(被7减过的结果),那么就将链表第3个节点的地址放入到指定内存空间,假设原始输入为4 5 3 1 2 6,那么处理后数据为3 2 4 6 5 1,最终内存结构示意图如下
注意这里是根据我们输入的值,决定将链表中第几个节点的地址放入到指定内存空间,不是把我们输入的值放入指定内存空间
11号框是一个循环
第一次循环的初始条件是(具体数值我们采用上面的例子)
mov 0x20(%rsp), %rbx
: rbx是指定内存空间的第1个空间,结果是node3初始地址lea 0x28(%rsp), %rax
: rax值是指定内存空间的第2个空间的地址mov %rbx, %rcx
: rcx存储的值域rbx相同,为node3初始地址进入第一次循环
mov (%rax), %rdx
: rdx的值是第2个空间的值,即node2的初始地址mov %rdx, 0x8(%rcx)
: node3->next = node2add $0x8, %rax
: rax的值为第3个空间的地址mov %rdx, %rcx
: rcx的值是node2的初始地址
循环的结果是链表变为node3->node2->node4->node6->node5->node1
加上4011d2,就构成一个完整的链表了node3->node2->node4->node6->node5->node1->NULL
12号框进行了一次比较
rbx上次出现的位置在10号框下方,它的值相当于链表首地址
eax是链表第2个元素的值,(%rbx)是第1个元素的值,必须保证第1个元素大于第2个元素
13号框把rbx的值修改为链表第2个节点的地址,之后继续进行12号框,所以12号框和13号框构成一个循环,一共进行5次,效果是判断链表值是否递减
所以我们的目标是,通过输入值,使得排成的链表的值是递减的
我们并没有修改过链表的val域,所以它的值就是原始值
(gdb) x /12x 0x6032d00x6032d0
:0x000000010000014c0x00000000006032e00x6032e0 :0x00000002000000a80x00000000006032f00x6032f0 :0x000000030000039c0x00000000006033000x603300 :0x00000004000002b30x00000000006033100x603310 :0x00000005000001dd0x00000000006033200x603320 :0x00000006000001bb0x0000000000000000 按照值域大小对节点排序是:node3->node4->node5->node6->node1->node2
这里是一个反向的思维,我们希望最终排成的链表是这样的,而排成链表的形式是由我们输入的数据确定的,
由下面的图可知,我们排成的链表顺序,就是与输入数据的顺序是相同的,不过这里所说的输入数据,是指被7减过的数据
目标顺序是3 4 5 6 1 2,所以原始输入数据应当为4 3 2 1 6 5
关键词:
天天播报:CSAPP-Bomb Lab
全球快资讯丨Python工具箱系列(二十九)
视焦点讯!让业务容器化更安全便捷,阿里云容器镜像服务 ACR 推出免费制品中心
环球热点评!云服务器部署AI绘图记录
全球热资讯!pdf.js 使用
今日要闻!尿道结石怎么治疗才能除病根_尿道结石该怎么治疗
虚幻引擎5推出重磅新功能MetaHuman Animator:实现真人面部动作高速模拟
焦点速看:开放世界元宇宙游戏《仙剑世界》来了:万物皆可交互
焦点短讯!中华老字号!西安饭庄糕点礼盒19.9元冲量大促:一次买16枚
两女子高速上突然跳车:闻到汽油味、以为要爆炸
环球实时:阿里又开源一款数据同步工具 DataX,稳定又高效,好用到爆!
一周的时间搞一个疫苗预约系统
环球热消息:Apache Kafka JNDI注入(CVE-2023-25194)漏洞复现浅析
快讯:河北沧州2022年成人高考成绩查询入口已开通
当前时讯:【新华500】新华500指数(989001)23日低开高走涨0.88%
今日观点!女生10年收集万瓶香水价值一套房:圈粉超47万
世界热文:捐100亿元建世界一流名校 曹德旺:大学没有教会年轻人动手能力
【天天快播报】汽车疯狂降价潮引担忧:狂欢之后会不会是淘汰潮?
热推荐:【操作系统】面试题总结(持更)
天天简讯:权值(点分治)
当前速看:JavaScript学习笔记
环球最资讯丨WMS深入浅出
环球关注:剑指 Offer 17. 打印从 1 到最大的 n 位数(java解题)
环球观焦点:Intel 56核心刚出生就落伍!AMD Zen4撕裂者下半年来袭:96核心
【新视野】力压美国印度!中国富豪全球第一:钟睒睒蝉联首富 马化腾张一鸣紧随其后
石榴汁弄衣服上怎么洗才能不会变干(石榴汁弄衣服上怎么洗)
环球最资讯丨机箱中的海景房 乔思伯TK-1双曲面侧透游戏机箱579元:颜值爆表
成都比亚迪、特斯拉、宝马三车相撞 特斯拉和宝马车轮飞了
天天简讯:Go语言:利用 TDD 逐步为一个字典应用创建完整的 CRUD API
【世界播资讯】springcloud Stream整合rabbitmq消息驱动生产者踩坑
【天天报资讯】Vue之移动端viewport-vw适配
LevelDb-用户接口
世界视讯!Spring Cloud Alibaba微服务搭建(二)- 安装mysql
【世界速看料】新能源汽车充电时为何要交停车费 专家:可防止充电之后不挪窝
当前热点-全球首枚3D打印火箭!美国“人族一号”发射失败
明年底有望普及!PCIe 5.0 SSD尴尬了 买的人太少:性能残血、价格死贵
我和你本应该各自好各自坏是什么歌?我和你本应该各自好各自坏歌词
mirror男团中谁的人气最高?mirror男团年龄排序
亡羊补牢的亡是什么意思?亡羊补牢成语故事
班主任管理班级的策略与措施是什么?班主任教育随笔示范
《最终幻想16》新片段 宠物可以防止你迷路
看点:MS SQL服务器教程_编程入门自学教程_菜鸟教程-免费教程分享
卿卿日常李薇的真实身份是什么?卿卿日常郝葭死了吗?
质感旗舰!真我GT Neo5 SE未来感十足:纳米级光哑熔合工艺打造
女子不敢在隧道开车 交给无证男子驾驶 听到后果惊恐万分
196元暴涨至1910元 民宿回应五一价格翻十倍:先挂着 随时调整
最资讯丨专盯未成年?女孩添加“爱豆”QQ后被骗贷款3万4
连鸽两次 世界首枚3D打印火箭将再发射:这回能顺利吗?
全球热点!Python工具箱系列(二十八)
天天通讯!不知道
酝酿产智融合“化学反应” 浙江衢州集中签约多家研究院
天天日报丨“帝王座驾、以辇为尊” 比亚迪云辇系统官宣:或为底盘新技术
天天热文:早午餐合成一顿?医生提醒:细胞营养需求加大 更易长胖
即时看!警惕!义乌一女子险被电商“客服”骗走800万
当前观点:配可滑动中控屏、宾利同款B柱挂钩!极氪X内饰官图发布
每日看点!【数论与组合数学 3】Hensel 引理、原根
世界观察:Android使用SurfaceView实现签名板
每日聚焦:机器学习算法(三):基于horse-colic数据的KNN近邻(k-nearest neighbors)预测分类
全球微头条丨领域驱动设计DDD应用与最佳实践
环球观天下!Linux安装Redis教程
看热讯:小孩飞机票怎么收费
1000N连续旋转爆震 国内全新发动机点火成功:颠覆性优势
自爆卡车?奔驰EQE车库逆行:反怪特斯拉Model 3车主不让路
精选!男子在电竞酒店枕头下发现一窝老鼠 官方回应引网友吐槽:怎么能住
微头条丨8只海豚在美国海滩搁浅全部死亡 6只被安乐死
焦点速递!吉利全新SUV博越COOL官图发布:四出排气、1.5升发动机
要去海南旅游的老友们请注意,海南离岛免税购物,有新变化!
今日热闻!数据库系统原理之关系数据库
深入消息队列MQ,看这篇就够了!
全网最详细中英文ChatGPT-GPT-4示例文档-从0到1快速入门条目分类应用——官网推荐的48种最佳应用场景(附python/node.js/curl命令源
环球动态:以太网发明者鲍勃·梅特卡夫获图灵奖 计算机界的诺贝尔奖
又一股惨遭退市!市值暴跌99%
世界热议:《CS2》地图对比:起源2加持画质更明亮、细节丰富
去年净赚499亿元创纪录!保时捷2.7万名员工每人6.7万元奖金
Java八股文之基础篇
全球简讯:在 Arch Linux 中安装 GNOME 桌面所需步骤介绍
当你对 redis 说你中意的女孩是 Mia
环球时讯:琥珀手串会变色吗 琥珀手串会越戴越亮吗
环球看点!全球首个空中飞行出租车来了:巴黎开测 2024奥运会要用
【天天报资讯】抗早泄国产“伟哥”药物上市 市场有多大?专家称将翻倍增长 国内患者众多
全球首搭帝瓦雷音响!比亚迪腾势N7猎跑SUV亮相:运动低趴
当前速讯:鸡鸣寺游客爆满设反悔门引导离寺 网友神评:我佛果然慈悲 给反悔机会
全球今日报丨读C#代码整洁之道笔记04_重构C#代码识别代码坏味道
北方多地遭遇沙尘暴 PM爆表:气象台再发预警 还没退去
环球头条:流浪小狗乞求收养者一起带走玩具熊:画面让养狗人士泪目 为何被遗弃
今日关注:iPhone 14首发的车祸检测功能让人崩溃!苹果iOS 16.4将优化升级
世界热讯:读Java性能权威指南(第2版)笔记25_性能测试方法上
每日头条!LOL2023狗熊怎么出装(上单狗熊2023出装顺序)
精选!等了 11年 《CSGO2》电竞网游终于官宣:画质大升级 免费更新
天天简讯:使用C#开发微信公众号对接ChatGPT和DALL-E
今日关注:关于人工智能的思考,写在chatGPT爆火之时
Vue——initRender【八】
环球快讯:NVIDIA突然复活SLI!但不是你想的那样
每日看点!比尔·盖茨谈ChatGPT 赞其1980年以来最革命性技术进步
天天即时:爱子飞机上死亡:母亲怒告世界最大航司美国航空
谷歌的“GPT”终于憋出来了!但是 也不比百度强多少啊
当前热议!抖音救人一命!男子发头孢配酒视频获救:客服教科书式报警
头条:交700个税的工资多少_j700
今日讯!SEO优化:友情链接!真心换真心?
通过 poe 免费使用ChatGPT、GPT-4