VM虚拟机逆向---[羊城杯 2021]Babyvm 复现【详解】

2023-11-07 18:20

本文主要是介绍VM虚拟机逆向---[羊城杯 2021]Babyvm 复现【详解】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 题目分析
  • 汇编脚本
    • 分析汇编
    • exp
  • 后言

前言

题目分析

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

在这里插入图片描述

&unk_804B0C0里面是opcode,sub_1C8里面有个mprotect,用了一个SMC加密。

我使用的是动态调试,因为是ELF文件,链接一下linux,进行动调,断点下在第九行就可以了,之后F7进入,sub_80487A8里面

选中,函数起始处一直到第一个retn的所有内容用U重定义下,然后C转换成代码就可以了。

在这里插入图片描述

这样就得到各个指令的实现了,接下来就是根据代码写脚本

汇编脚本

opcode = [0xA1, 0xC1, 0x00, 0xB1, 0x77, 0xC2, 0x4A, 0x01, 0x00, 0x00,0xC1, 0x01, 0xB2, 0x77, 0xC2, 0x19, 0x01, 0x00, 0x00, 0xC1,0x02, 0xB4, 0x77, 0xC2, 0xDD, 0x01, 0x00, 0x00, 0xC1, 0x03,0xB3, 0x77, 0xC2, 0x0F, 0x01, 0x00, 0x00, 0xC1, 0x04, 0xB2,0x77, 0xC2, 0x1B, 0x01, 0x00, 0x00, 0xC1, 0x05, 0xB4, 0x77,0xC2, 0x89, 0x01, 0x00, 0x00, 0xC1, 0x06, 0xB1, 0x77, 0xC2,0x19, 0x01, 0x00, 0x00, 0xC1, 0x07, 0xB3, 0x77, 0xC2, 0x54,0x01, 0x00, 0x00, 0xC1, 0x08, 0xB1, 0x77, 0xC2, 0x4F, 0x01,0x00, 0x00, 0xC1, 0x09, 0xB1, 0x77, 0xC2, 0x4E, 0x01, 0x00,0x00, 0xC1, 0x0A, 0xB3, 0x77, 0xC2, 0x55, 0x01, 0x00, 0x00,0xC1, 0x0B, 0xB3, 0x77, 0xC2, 0x56, 0x01, 0x00, 0x00, 0xC1,0x0C, 0xB4, 0x77, 0xC2, 0x8E, 0x00, 0x00, 0x00, 0xC1, 0x0D,0xB2, 0x77, 0xC2, 0x49, 0x00, 0x00, 0x00, 0xC1, 0x0E, 0xB3,0x77, 0xC2, 0x0E, 0x01, 0x00, 0x00, 0xC1, 0x0F, 0xB1, 0x77,0xC2, 0x4B, 0x01, 0x00, 0x00, 0xC1, 0x10, 0xB3, 0x77, 0xC2,0x06, 0x01, 0x00, 0x00, 0xC1, 0x11, 0xB3, 0x77, 0xC2, 0x54,0x01, 0x00, 0x00, 0xC1, 0x12, 0xB2, 0x77, 0xC2, 0x1A, 0x00,0x00, 0x00, 0xC1, 0x13, 0xB1, 0x77, 0xC2, 0x42, 0x01, 0x00,0x00, 0xC1, 0x14, 0xB3, 0x77, 0xC2, 0x53, 0x01, 0x00, 0x00,0xC1, 0x15, 0xB1, 0x77, 0xC2, 0x1F, 0x01, 0x00, 0x00, 0xC1,0x16, 0xB3, 0x77, 0xC2, 0x52, 0x01, 0x00, 0x00, 0xC1, 0x17,0xB4, 0x77, 0xC2, 0xDB, 0x00, 0x00, 0x00, 0xC1, 0x18, 0xB1,0x77, 0xC2, 0x19, 0x01, 0x00, 0x00, 0xC1, 0x19, 0xB4, 0x77,0xC2, 0xD9, 0x00, 0x00, 0x00, 0xC1, 0x1A, 0xB1, 0x77, 0xC2,0x19, 0x01, 0x00, 0x00, 0xC1, 0x1B, 0xB3, 0x77, 0xC2, 0x55,0x01, 0x00, 0x00, 0xC1, 0x1C, 0xB2, 0x77, 0xC2, 0x19, 0x00,0x00, 0x00, 0xC1, 0x1D, 0xB3, 0x77, 0xC2, 0x00, 0x01, 0x00,0x00, 0xC1, 0x1E, 0xB1, 0x77, 0xC2, 0x4B, 0x01, 0x00, 0x00,0xC1, 0x1F, 0xB2, 0x77, 0xC2, 0x1E, 0x00, 0x00, 0x00, 0xC1,0x20, 0x80, 0x02, 0x18, 0x00, 0x00, 0x00, 0x23, 0x10, 0xC1,0x21, 0x80, 0x02, 0x10, 0x00, 0x00, 0x00, 0x23, 0xF7, 0xC1,0x22, 0x80, 0x02, 0x08, 0x00, 0x00, 0x00, 0x23, 0xF7, 0xC1,0x23, 0xF7, 0xFE, 0x80, 0x02, 0x05, 0x00, 0x00, 0x00, 0x22,0x77, 0x10, 0x80, 0x02, 0x07, 0x00, 0x00, 0x00, 0x23, 0x80,0x02, 0x23, 0x77, 0xF1, 0x98, 0x31, 0x77, 0x10, 0x80, 0x02,0x18, 0x00, 0x00, 0x00, 0x23, 0x80, 0x02, 0x20, 0xB9, 0xE4,0x35, 0x31, 0x77, 0x10, 0x80, 0x02, 0x12, 0x00, 0x00, 0x00,0x22, 0x77, 0xA0, 0xC1, 0x24, 0x80, 0x02, 0x18, 0x00, 0x00,0x00, 0x23, 0x10, 0xC1, 0x25, 0x80, 0x02, 0x10, 0x00, 0x00,0x00, 0x23, 0xF7, 0xC1, 0x26, 0x80, 0x02, 0x08, 0x00, 0x00,0x00, 0x23, 0xF7, 0xC1, 0x27, 0xF7, 0xFE, 0x32, 0x20, 0x43,0x33, 0x77, 0x80, 0x02, 0x11, 0x00, 0x00, 0x00, 0x22, 0x35,0x37, 0x38, 0x77, 0x80, 0x02, 0x0D, 0x00, 0x00, 0x00, 0x23,0x77, 0x38, 0x39, 0x10, 0x32, 0x20, 0x43, 0x33, 0x77, 0x80,0x02, 0x11, 0x00, 0x00, 0x00, 0x22, 0x35, 0x37, 0x38, 0x77,0x80, 0x02, 0x0D, 0x00, 0x00, 0x00, 0x23, 0x77, 0x38, 0x39,0xC7, 0xC1, 0x28, 0x80, 0x02, 0x18, 0x00, 0x00, 0x00, 0x23,0x10, 0xC1, 0x29, 0x80, 0x02, 0x10, 0x00, 0x00, 0x00, 0x23,0xF7, 0xC1, 0x2A, 0x80, 0x02, 0x08, 0x00, 0x00, 0x00, 0x23,0xF7, 0xC1, 0x2B, 0xF7, 0xFE, 0x32, 0x20, 0x43, 0x33, 0x77,0x80, 0x02, 0x11, 0x00, 0x00, 0x00, 0x22, 0x35, 0x37, 0x38,0x77, 0x80, 0x02, 0x0D, 0x00, 0x00, 0x00, 0x23, 0x77, 0x38,0x39, 0x10, 0x32, 0x20, 0x43, 0x33, 0x77, 0x80, 0x02, 0x11,0x00, 0x00, 0x00, 0x22, 0x35, 0x37, 0x38, 0x77, 0x80, 0x02,0x0D, 0x00, 0x00, 0x00, 0x23, 0x77, 0x38, 0x39, 0xC8, 0x99]i = 0
while opcode[i] != 0x99:match opcode[i]:case 0x71:print(f"{i} push %d" % (opcode[i+1]))i += 5case 0x41:print(f"{i} add reg[1] reg[2]")i += 1case 0x42:print(f"{i} sub reg[1] reg[4]")i += 1case 0x43:print(f"{i} mul reg[1] reg[3]")i += 1case 0x37:print(f"{i} mov reg[1] reg[5]")i += 1case 0x38:print(f"{i} xor reg[1] reg[4]")i += 1case 0x39:print(f"{i} xor reg[1] reg[5]")i += 1case 0x35:print(f"{i} mov reg[5] reg[1]")i += 1case 0xF7:print(f"{i} add reg[9] reg[1]")i += 1case 0x44:print(f"{i} div reg[1] reg[5]")i += 1case 0x80:int_val = int.from_bytes(bytes(opcode[i + 2:i + 6]), 'little')print(f"{i} mov reg[?] {int_val}")i += 6case 0x77:print(f"{i} xor reg[1] reg[9]")i += 1case 0x53:print(f"{i} put reg[3]")i += 2case 0x22:print(f"{i} shr reg[1] reg[2]")i += 1case 0x23:print(f"{i} shl reg[1] reg[2]")i += 1case 0x76:print(f"{i} pop reg[3]")i += 5case 0x54:print(f"{i} get")i += 2case 0x30:print(f"{i} or reg[1] reg[2]")i += 1case 0x31:print(f"{i} and reg[1] reg[2]")i += 1case 0x32:print(f"{i} mov reg[3] %d" % (opcode[i+1]))i += 2case 0x09:print(f"{i} mov reg[1] 0x6FEBF967")i += 1case 0x10:print(f"{i} mov reg[9] reg[1]")i += 1case 0x33:print(f"{i} mov reg[4] reg[1]")i += 1case 0x34:print(f"{i} mov reg[2] %d" % (opcode[i+1]))i += 2case 0xFE:print(f"{i} mov reg[1] reg[9]")i += 1case 0x11:print(f"{i} print reg[1]")i += 1case 0xA0:print(f"{i} cmp reg[1] 0x6FEBF967")i += 1case 0xA1:print(f"{i} cmp len 44")i += 1case 0xB1:print(f"{i} mov reg[9] v[0]")i += 1case 0xB2:print(f"{i} mov reg[9] v[1]")i += 1case 0xA4:print(f"{i} mov v[%d] reg[1]" % (opcode[i + 1]))i += 4case 0xB3:print(f"{i} mov reg[9] v[2]")i += 1case 0xB4:print(f"{i} mov reg[9] v[3]")i += 1case 0xC1:print(f"{i} mov reg[1] s[%d]" % (opcode[i + 1]))i += 2case 0xC7:print(f"{i} cmp d[0] reg[1]")i += 1case 0xC8:print(f"{i} cmp d[1] reg[1]")i += 1case 0xC2:print(f"{i} cmp %d reg[1]" % (opcode[i+1]))i += 5

打印出来:

0 cmp len 44
1 mov reg[1] s[0]
3 mov reg[9] v[0]
4 xor reg[1] reg[9]
5 cmp 74 reg[1]
10 mov reg[1] s[1]
12 mov reg[9] v[1]
13 xor reg[1] reg[9]
14 cmp 25 reg[1]
19 mov reg[1] s[2]
21 mov reg[9] v[3]
22 xor reg[1] reg[9]
23 cmp 221 reg[1]
28 mov reg[1] s[3]
30 mov reg[9] v[2]
31 xor reg[1] reg[9]
32 cmp 15 reg[1]
37 mov reg[1] s[4]
39 mov reg[9] v[1]
40 xor reg[1] reg[9]
41 cmp 27 reg[1]
46 mov reg[1] s[5]
48 mov reg[9] v[3]
49 xor reg[1] reg[9]
50 cmp 137 reg[1]
55 mov reg[1] s[6]
57 mov reg[9] v[0]
58 xor reg[1] reg[9]
59 cmp 25 reg[1]
64 mov reg[1] s[7]
66 mov reg[9] v[2]
67 xor reg[1] reg[9]
68 cmp 84 reg[1]
73 mov reg[1] s[8]
75 mov reg[9] v[0]
76 xor reg[1] reg[9]
77 cmp 79 reg[1]
82 mov reg[1] s[9]
84 mov reg[9] v[0]
85 xor reg[1] reg[9]
86 cmp 78 reg[1]
91 mov reg[1] s[10]
93 mov reg[9] v[2]
94 xor reg[1] reg[9]
95 cmp 85 reg[1]
100 mov reg[1] s[11]
102 mov reg[9] v[2]
103 xor reg[1] reg[9]
104 cmp 86 reg[1]
109 mov reg[1] s[12]
111 mov reg[9] v[3]
112 xor reg[1] reg[9]
113 cmp 142 reg[1]
118 mov reg[1] s[13]
120 mov reg[9] v[1]
121 xor reg[1] reg[9]
122 cmp 73 reg[1]
127 mov reg[1] s[14]
129 mov reg[9] v[2]
130 xor reg[1] reg[9]
131 cmp 14 reg[1]
136 mov reg[1] s[15]
138 mov reg[9] v[0]
139 xor reg[1] reg[9]
140 cmp 75 reg[1]
145 mov reg[1] s[16]
147 mov reg[9] v[2]
148 xor reg[1] reg[9]
149 cmp 6 reg[1]
154 mov reg[1] s[17]
156 mov reg[9] v[2]
157 xor reg[1] reg[9]
158 cmp 84 reg[1]
163 mov reg[1] s[18]
165 mov reg[9] v[1]
166 xor reg[1] reg[9]
167 cmp 26 reg[1]
172 mov reg[1] s[19]
174 mov reg[9] v[0]
175 xor reg[1] reg[9]
176 cmp 66 reg[1]
181 mov reg[1] s[20]
183 mov reg[9] v[2]
184 xor reg[1] reg[9]
185 cmp 83 reg[1]
190 mov reg[1] s[21]
192 mov reg[9] v[0]
193 xor reg[1] reg[9]
194 cmp 31 reg[1]
199 mov reg[1] s[22]
201 mov reg[9] v[2]
202 xor reg[1] reg[9]
203 cmp 82 reg[1]
208 mov reg[1] s[23]
210 mov reg[9] v[3]
211 xor reg[1] reg[9]
212 cmp 219 reg[1]
217 mov reg[1] s[24]
219 mov reg[9] v[0]
220 xor reg[1] reg[9]
221 cmp 25 reg[1]
226 mov reg[1] s[25]
228 mov reg[9] v[3]
229 xor reg[1] reg[9]
230 cmp 217 reg[1]
235 mov reg[1] s[26]
237 mov reg[9] v[0]
238 xor reg[1] reg[9]
239 cmp 25 reg[1]
244 mov reg[1] s[27]
246 mov reg[9] v[2]
247 xor reg[1] reg[9]
248 cmp 85 reg[1]
253 mov reg[1] s[28]
255 mov reg[9] v[1]
256 xor reg[1] reg[9]
257 cmp 25 reg[1]
262 mov reg[1] s[29]
264 mov reg[9] v[2]
265 xor reg[1] reg[9]
266 cmp 0 reg[1]
271 mov reg[1] s[30]
273 mov reg[9] v[0]
274 xor reg[1] reg[9]
275 cmp 75 reg[1]
280 mov reg[1] s[31]
282 mov reg[9] v[1]
283 xor reg[1] reg[9]
284 cmp 30 reg[1]
289 mov reg[1] s[32]
291 mov reg[?] 24
297 shl reg[1] reg[2]
298 mov reg[9] reg[1]
299 mov reg[1] s[33]
301 mov reg[?] 16
307 shl reg[1] reg[2]
308 add reg[9] reg[1]
309 mov reg[1] s[34]
311 mov reg[?] 8
317 shl reg[1] reg[2]
318 add reg[9] reg[1]
319 mov reg[1] s[35]
321 add reg[9] reg[1]
322 mov reg[1] reg[9]
323 mov reg[?] 5
329 shr reg[1] reg[2]
330 xor reg[1] reg[9]
331 mov reg[9] reg[1]
332 mov reg[?] 7
338 shl reg[1] reg[2]
339 mov reg[?] 2565961507
345 and reg[1] reg[2]
346 xor reg[1] reg[9]
347 mov reg[9] reg[1]
348 mov reg[?] 24
354 shl reg[1] reg[2]
355 mov reg[?] 904182048
361 and reg[1] reg[2]
362 xor reg[1] reg[9]
363 mov reg[9] reg[1]
364 mov reg[?] 18
370 shr reg[1] reg[2]
371 xor reg[1] reg[9]
372 cmp reg[1] 0x6FEBF967
373 mov reg[1] s[36]
375 mov reg[?] 24
381 shl reg[1] reg[2]
382 mov reg[9] reg[1]
383 mov reg[1] s[37]
385 mov reg[?] 16
391 shl reg[1] reg[2]
392 add reg[9] reg[1]
393 mov reg[1] s[38]
395 mov reg[?] 8
401 shl reg[1] reg[2]
402 add reg[9] reg[1]
403 mov reg[1] s[39]
405 add reg[9] reg[1]
406 mov reg[1] reg[9]
407 mov reg[3] 32
409 mul reg[1] reg[3]
410 mov reg[4] reg[1]
411 xor reg[1] reg[9]
412 mov reg[?] 17
418 shr reg[1] reg[2]
419 mov reg[5] reg[1]
420 mov reg[1] reg[5]
421 xor reg[1] reg[4]
422 xor reg[1] reg[9]
423 mov reg[?] 13
429 shl reg[1] reg[2]
430 xor reg[1] reg[9]
431 xor reg[1] reg[4]
432 xor reg[1] reg[5]
433 mov reg[9] reg[1]
434 mov reg[3] 32
436 mul reg[1] reg[3]
437 mov reg[4] reg[1]
438 xor reg[1] reg[9]
439 mov reg[?] 17
445 shr reg[1] reg[2]
446 mov reg[5] reg[1]
447 mov reg[1] reg[5]
448 xor reg[1] reg[4]
449 xor reg[1] reg[9]
450 mov reg[?] 13
456 shl reg[1] reg[2]
457 xor reg[1] reg[9]
458 xor reg[1] reg[4]
459 xor reg[1] reg[5]
460 cmp d[0] reg[1]
461 mov reg[1] s[40]
463 mov reg[?] 24
469 shl reg[1] reg[2]
470 mov reg[9] reg[1]
471 mov reg[1] s[41]
473 mov reg[?] 16
479 shl reg[1] reg[2]
480 add reg[9] reg[1]
481 mov reg[1] s[42]
483 mov reg[?] 8
489 shl reg[1] reg[2]
490 add reg[9] reg[1]
491 mov reg[1] s[43]
493 add reg[9] reg[1]
494 mov reg[1] reg[9]
495 mov reg[3] 32
497 mul reg[1] reg[3]
498 mov reg[4] reg[1]
499 xor reg[1] reg[9]
500 mov reg[?] 17
506 shr reg[1] reg[2]
507 mov reg[5] reg[1]
508 mov reg[1] reg[5]
509 xor reg[1] reg[4]
510 xor reg[1] reg[9]
511 mov reg[?] 13
517 shl reg[1] reg[2]
518 xor reg[1] reg[9]
519 xor reg[1] reg[4]
520 xor reg[1] reg[5]
521 mov reg[9] reg[1]
522 mov reg[3] 32
524 mul reg[1] reg[3]
525 mov reg[4] reg[1]
526 xor reg[1] reg[9]
527 mov reg[?] 17
533 shr reg[1] reg[2]
534 mov reg[5] reg[1]
535 mov reg[1] reg[5]
536 xor reg[1] reg[4]
537 xor reg[1] reg[9]
538 mov reg[?] 13
544 shl reg[1] reg[2]
545 xor reg[1] reg[9]
546 xor reg[1] reg[4]
547 xor reg[1] reg[5]
548 cmp d[1] reg[1]

分析汇编

前三十二个字节就是取 数据 异或得出来的;

后 十二个字节就很复杂了,可以考虑直接爆破。

exp

前三十二个:

print(chr(0x7b ^ 74) + chr(0x2f ^ 25) + chr(0xe8 ^ 221) + chr(0x37 ^ 15) + chr(0x2f ^ 27) + chr(0xe8 ^ 137) + chr(0x7b ^ 25) + chr(0x37 ^ 84) + chr(0x7b ^ 79) + chr(0x7b ^ 78) + chr(0x37 ^ 85) + chr(0x37 ^ 86) + chr(0xe8 ^ 142) + chr(0x2f ^ 73) + chr(0x37 ^ 14) + chr(0x7b ^ 75) + chr(0x37 ^ 6) + chr(0x37 ^ 84) + chr(0x2f ^ 26) + chr(0x7b ^ 66) + chr(0x37 ^ 83) + chr(0x7b ^ 31) + chr(0x37 ^ 82) + chr(0xe8 ^ 219) + chr(0x7b ^ 25) + chr(0xe8 ^ 217) + chr(0x7b ^ 25) + chr(0x37 ^ 85) + chr(0x2f ^ 25) + chr(0x37 ^ 0) + chr(0x7b ^ 75) + chr(0x2f ^ 30))

得到:16584abc45baff901c59dde3b1bb6701

后十二个:

第 33 34 35 36

start = 0x20202020while start <= 0xffffffff:s = startreg9 = ss >>= 5s ^= reg9reg9 = ss <<= 7s &= 2565961507s ^= reg9reg9 = ss <<= 24s &= 904182048s ^= reg9reg9 = ss >>= 18s ^= reg9if s == 1877735783:print(start)exit(0)else:start += 1

爆破后结果是:1630680372 转换为ascii码 ‘a254’

第 37 38 39 40

#include <cstdio>int main(){unsigned int record, reg1, reg2, reg3, reg4, reg5, reg6, unknown2;for(unsigned int unknown2=0x20202020;unknown2<0xffffffff;unknown2+=1){record = unknown2;reg1 = unknown2;reg3 = 32;reg1 *= reg3;reg4 = reg1;reg1 ^= unknown2;reg2 = 17;reg1 >>= reg2;reg6 = reg1;reg1 = reg6;reg1 ^= reg4;reg1 ^= unknown2;reg2 = 13;reg1 <<= reg2;reg1 ^= unknown2;reg1 ^= reg4;reg1 ^= reg6;unknown2 = reg1;reg3 = 32;reg1 *= reg3;reg4 = reg1;reg1 ^= unknown2;reg2 = 17;reg1 >>= reg2;reg6 = reg1;reg1 = reg6;reg1 ^= reg4;reg1 ^= unknown2;reg2 = 13;reg1 <<= reg2;reg1 ^= unknown2;reg1 ^= reg4;reg1 ^= reg6;unknown2 = record;if(reg1 == 0x0CF1304DC){printf("%u\n", record);break;}}
}

运行结果:1647326819 转换成ascii: b06c

第41 42 43 44

#include <cstdio>int main(){unsigned int record, reg1, reg2, reg3, reg4, reg5, reg6, unknown2;for(unsigned int unknown2=0x20202020;unknown2<0xffffffff;unknown2+=1){record = unknown2;reg1 = unknown2;reg3 = 32;reg1 *= reg3;reg4 = reg1;reg1 ^= unknown2;reg2 = 17;reg1 >>= reg2;reg6 = reg1;reg1 = reg6;reg1 ^= reg4;reg1 ^= unknown2;reg2 = 13;reg1 <<= reg2;reg1 ^= unknown2;reg1 ^= reg4;reg1 ^= reg6;unknown2 = reg1;reg3 = 32;reg1 *= reg3;reg4 = reg1;reg1 ^= unknown2;reg2 = 17;reg1 >>= reg2;reg6 = reg1;reg1 = reg6;reg1 ^= reg4;reg1 ^= unknown2;reg2 = 13;reg1 <<= reg2;reg1 ^= unknown2;reg1 ^= reg4;reg1 ^= reg6;unknown2 = record;if(reg1 == 0x283B8E84){printf("%u\n", record);break;}}
}

运行结果:1684222515 转换成ascii码:dc23

全部拼接起来就是:16584abc45baff901c59dde3b1bb6701a254b06cdc23

后言

这里最后面爆破卡了好久,最后俩个爆破脚本是大佬的,一直想着用python,应该早点想到要限制数据的大小的,unsigned int 通常表示非负整数,最大到0xFFFFFFFF。。。一直没留意,爆破不出东西来。傻了。
来来回回写了大概五六题vm逆向,渐渐明白为什么没有人写详解了(wp点开全都只有exp),,,写怎么推导指令,,,还是多练,就明白了,()。

这篇关于VM虚拟机逆向---[羊城杯 2021]Babyvm 复现【详解】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/365458

相关文章

MySQL中的分组和多表连接详解

《MySQL中的分组和多表连接详解》:本文主要介绍MySQL中的分组和多表连接的相关操作,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录mysql中的分组和多表连接一、MySQL的分组(group javascriptby )二、多表连接(表连接会产生大量的数据垃圾)MySQL中的

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

SpringBoot3.4配置校验新特性的用法详解

《SpringBoot3.4配置校验新特性的用法详解》SpringBoot3.4对配置校验支持进行了全面升级,这篇文章为大家详细介绍了一下它们的具体使用,文中的示例代码讲解详细,感兴趣的小伙伴可以参考... 目录基本用法示例定义配置类配置 application.yml注入使用嵌套对象与集合元素深度校验开发

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

Java Stream流使用案例深入详解

《JavaStream流使用案例深入详解》:本文主要介绍JavaStream流使用案例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录前言1. Lambda1.1 语法1.2 没参数只有一条语句或者多条语句1.3 一个参数只有一条语句或者多

SpringBoot整合mybatisPlus实现批量插入并获取ID详解

《SpringBoot整合mybatisPlus实现批量插入并获取ID详解》这篇文章主要为大家详细介绍了SpringBoot如何整合mybatisPlus实现批量插入并获取ID,文中的示例代码讲解详细... 目录【1】saveBATch(一万条数据总耗时:2478ms)【2】集合方式foreach(一万条数

Python装饰器之类装饰器详解

《Python装饰器之类装饰器详解》本文将详细介绍Python中类装饰器的概念、使用方法以及应用场景,并通过一个综合详细的例子展示如何使用类装饰器,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录1. 引言2. 装饰器的基本概念2.1. 函数装饰器复习2.2 类装饰器的定义和使用3. 类装饰

MySQL 中的 JSON 查询案例详解

《MySQL中的JSON查询案例详解》:本文主要介绍MySQL的JSON查询的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 的 jsON 路径格式基本结构路径组件详解特殊语法元素实际示例简单路径复杂路径简写操作符注意MySQL 的 J

Python ZIP文件操作技巧详解

《PythonZIP文件操作技巧详解》在数据处理和系统开发中,ZIP文件操作是开发者必须掌握的核心技能,Python标准库提供的zipfile模块以简洁的API和跨平台特性,成为处理ZIP文件的首选... 目录一、ZIP文件操作基础三板斧1.1 创建压缩包1.2 解压操作1.3 文件遍历与信息获取二、进阶技