pwn学习笔记(12)--Chunk Extend and Overlapping

news2024/11/14 3:55:40

pwn学习笔记(12)–Chunk Extend and Overlapping

​ chunk extend 是堆漏洞的一种常见利用手法,通过 extend 可以实现 chunk overlapping(块重叠) 的效果。这种利用方法需要以下的时机和条件:

  • 程序中存在基于堆的漏洞
  • 漏洞可以控制 chunk header 中的数据

1、对inuse的fastbin进行extend:

 int main(void)
{
    void *ptr,*ptr1;

    ptr=malloc(0x10);//分配第一个0x10的chunk
    malloc(0x10);//分配第二个0x10的chunk

    *(long long *)((long long)ptr-0x8)=0x41;// 修改第一个块的size域

    free(ptr);
    ptr1=malloc(0x30);// 实现 extend,控制了第二个块的内容
    return 0;
}

​ 首先进行两次malloc,之后看看heap的状态:

In file: /mnt/hgfs/sharedict/ChunkExtend/extend.c
    3     void *ptr,*ptr1;
    4 
    5     ptr=malloc(0x10);//分配第一个0x10的chunk
    6     malloc(0x10);//分配第二个0x10的chunk
    78     *(long long *)((long long)ptr-0x8)=0x41;// 修改第一个块的size域
    9 
   10     free(ptr);
   11     ptr1=malloc(0x30);// 实现 extend,控制了第二个块的内容
   12     return 0;
   13 }
─────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffde30 —▸ 0x555555758010 ◂— 0x0
01:0008│     0x7fffffffde38 ◂— 0x0
02:0010│ rbp 0x7fffffffde40 —▸ 0x5555555546e0 (__libc_csu_init) ◂— push   r15
03:0018│     0x7fffffffde48 —▸ 0x7ffff7a2d840 (__libc_start_main+240) ◂— mov    edi, eax
04:0020│     0x7fffffffde50 ◂— 0x1
05:0028│     0x7fffffffde58 —▸ 0x7fffffffdf28 —▸ 0x7fffffffe2ac ◂— '/mnt/hgfs/sharedict/ChunkExtend/test'
06:0030│     0x7fffffffde60 ◂— 0x1f7ffcca0
07:0038│     0x7fffffffde68 —▸ 0x55555555468a (main) ◂— push   rbp
───────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────
 ► f 0   0x5555555546aa main+32
   f 1   0x7ffff7a2d840 __libc_start_main+240
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x555555758020
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x555555758040
Size: 0x20fc1

pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty

​ 有地址的话,就去读一下两个堆的内容:

pwndbg> x/30gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000021		<======Chunk1
0x555555758010: 0x0000000000000000  0x0000000000000000
0x555555758020: 0x0000000000000000  0x0000000000000021		<======Chunk2
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000020fc1		<======Top Chunk
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000000  0x0000000000000000
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000000
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000000
0x5555557580e0: 0x0000000000000000  0x0000000000000000

​ 下一步开始释放,看一看修改chunk1的size域大小:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0x41

Top chunk | PREV_INUSE
Addr: 0x555555758040
Size: 0x20fc1

pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty

​ 发现chunk2被修改后增大了的chunk1给那占了,heap里就只有一个Chunk了,看看内存:

pwndbg> x/30gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000041			<======原Chunk1
0x555555758010: 0x0000000000000000  0x0000000000000000
0x555555758020: 0x0000000000000000  0x0000000000000021			<======原Chunk2
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000020fc1			<======Top Chunk
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000000  0x0000000000000000
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000000
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000000
0x5555557580e0: 0x0000000000000000  0x0000000000000000

​ 除去chunk1的size域变化了以外,似乎没有其他变化,但是,逻辑上来说,现在的堆里只有一个chunk了,之后free掉chunk1看看:

pwndbg> heap
Free chunk (fastbins) | PREV_INUSE
Addr: 0x555555758000
Size: 0x41
fd: 0x00

Top chunk | PREV_INUSE
Addr: 0x555555758040
Size: 0x20fc1

pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x555555758000 ◂— 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty

​ 之后读取下内存:

pwndbg> x/30gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000041
0x555555758010: 0x0000000000000000  0x0000000000000000
0x555555758020: 0x0000000000000000  0x0000000000000021
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000020fc1
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000000  0x0000000000000000
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000000
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000000
0x5555557580e0: 0x0000000000000000  0x0000000000000000

​ 下一步是重头戏,试想,如果原chunk1的size域没有真正变化,那么我们进行malloc一个0x30大小的堆块的时候,就不会分配到这个地址上,而是从Top Chunk里拆分,那么事实上是怎么样的呢?实践出真知,看一下吧:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0x41

Top chunk | PREV_INUSE
Addr: 0x555555758040
Size: 0x20fc1

pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> x/30gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000041
0x555555758010: 0x0000000000000000  0x0000000000000000
0x555555758020: 0x0000000000000000  0x0000000000000021
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000020fc1			<======Top Chunk
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000000  0x0000000000000000
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000000
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000000
0x5555557580e0: 0x0000000000000000  0x0000000000000000

​ 显然,Top Chunk并未被拆分,这里确定了,似乎malloc(0x30)得到的堆块是原Chunk1的地址,这里说明了,这里的原chunk1因为size域被修改了之后成为了一个新的更大的堆块,这里也就造成了所谓的堆重叠了,chunk1因为修改了size域后,生成的那个新的chunk和chunk2部分重叠了,这也就导致了,有的对原chunk1的修改可以修改到chunk2的地方,如果chunk2保留了指针,那就可以对chunk2进行伪造,可以结合类似off by one和UAF形成很多种利用方式。

2、对inuse的smallbin进行extend:

//gcc -g 2.c
//注意把之前那个a.out给删掉
int main()
{
    void *ptr,*ptr1;

    ptr=malloc(0x80);//分配第一个 0x80 的chunk1
    malloc(0x10); //分配第二个 0x10 的chunk2
    malloc(0x10); //防止与top chunk合并

    *(long *)((long)ptr-0x8)=0xb1;
    free(ptr);
    ptr1=malloc(0xa0);
}

​ 首先进行三次分配,其中,第三次分配是防止extend后,chunk与topchunk进行合并,无需关注。先看看经过三次malloc之后的堆空间是啥样的:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0x91

Allocated chunk | PREV_INUSE
Addr: 0x555555758090
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5555557580b0
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x5555557580d0
Size: 0x20f31

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> x/40gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000091			<======Chunk1
0x555555758010: 0x0000000000000000  0x0000000000000000
0x555555758020: 0x0000000000000000  0x0000000000000000
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000000
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000000  0x0000000000000021			<======Chunk2
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000021			<======Chunk3
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000020f31			<======Top Chunk
0x5555557580e0: 0x0000000000000000  0x0000000000000000
0x5555557580f0: 0x0000000000000000  0x0000000000000000
0x555555758100: 0x0000000000000000  0x0000000000000000
0x555555758110: 0x0000000000000000  0x0000000000000000
0x555555758120: 0x0000000000000000  0x0000000000000000
0x555555758130: 0x0000000000000000  0x0000000000000000

​ 估摸一下,chunk1的大小似乎有点大,导致free掉的chunk1并不会进入fastbin,而是进入smallbin,那么修改了size域后,原本三个chunk在gdb里的heap指令下依旧少了一个:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0xb1

Allocated chunk | PREV_INUSE
Addr: 0x5555557580b0
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x5555557580d0
Size: 0x20f31

pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> x/40gx 0x555555758000
0x555555758000: 0x0000000000000000  0x00000000000000b1			<======Chunk1
0x555555758010: 0x0000000000000000  0x0000000000000000
0x555555758020: 0x0000000000000000  0x0000000000000000
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000000
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000000  0x0000000000000021			<======Chunk2
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000021			<======Chunk3
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000020f31			<======Top Chunk
0x5555557580e0: 0x0000000000000000  0x0000000000000000
0x5555557580f0: 0x0000000000000000  0x0000000000000000
0x555555758100: 0x0000000000000000  0x0000000000000000
0x555555758110: 0x0000000000000000  0x0000000000000000
0x555555758120: 0x0000000000000000  0x0000000000000000
0x555555758130: 0x0000000000000000  0x0000000000000000

​ 下一步,free掉chunk1:

pwndbg> heap
Free chunk (unsortedbin) | PREV_INUSE
Addr: 0x555555758000
Size: 0xb1
fd: 0x7ffff7dd1b78
bk: 0x7ffff7dd1b78

Allocated chunk
Addr: 0x5555557580b0
Size: 0x20

Top chunk | PREV_INUSE
Addr: 0x5555557580d0
Size: 0x20f31

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x555555758000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x555555758000
smallbins
empty
largebins
empty
pwndbg> x/40gx 0x555555758000
0x555555758000: 0x0000000000000000  0x00000000000000b1			<======Chunk1
0x555555758010: 0x00007ffff7dd1b78  0x00007ffff7dd1b78
0x555555758020: 0x0000000000000000  0x0000000000000000
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000000
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000000  0x0000000000000021			<======Chunk2
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x00000000000000b0  0x0000000000000020			<======Chunk3
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000020f31			<======Top Chunk
0x5555557580e0: 0x0000000000000000  0x0000000000000000
0x5555557580f0: 0x0000000000000000  0x0000000000000000
0x555555758100: 0x0000000000000000  0x0000000000000000
0x555555758110: 0x0000000000000000  0x0000000000000000
0x555555758120: 0x0000000000000000  0x0000000000000000
0x555555758130: 0x0000000000000000  0x0000000000000000

​ 这里发现了一个点需要注意,就是free掉size域修改了之后的那个chunk1之后,chunk3的size域的最低为,也就是p位,变成了0,这也就说明,chunk1没有放在fastbin里,上面也看到了,被放在了unsortedbin里。

​ 那么为啥会被放入unsortedbin内而不是smallbin呢?估计有一下几种可能:

  • 当一个较大的chunk被分割成两半后,如果剩下的部分大于MINSIZE,就会被放到unsortedbin中。
  • 释放一个不属于fastbin的chunk,并且该chunk不和top chunk紧邻时,该chunk就会被放到unsorted bin 中,当第二次分配的时候,没有在unsortedbin中找到合适的,才会被放入到其对应的bin中。

​ 之后进行分配,分配0xa0大小的堆块,就会发现,原chunk1的地址依旧拿去用了:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0xb1

Allocated chunk | PREV_INUSE
Addr: 0x5555557580b0
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x5555557580d0
Size: 0x20f31

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> x/40gx 0x555555758000
0x555555758000: 0x0000000000000000  0x00000000000000b1
0x555555758010: 0x00007ffff7dd1b78  0x00007ffff7dd1b78
0x555555758020: 0x0000000000000000  0x0000000000000000
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000000
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000000  0x0000000000000021
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x00000000000000b0  0x0000000000000021
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000020f31
0x5555557580e0: 0x0000000000000000  0x0000000000000000
0x5555557580f0: 0x0000000000000000  0x0000000000000000
0x555555758100: 0x0000000000000000  0x0000000000000000
0x555555758110: 0x0000000000000000  0x0000000000000000
0x555555758120: 0x0000000000000000  0x0000000000000000
0x555555758130: 0x0000000000000000  0x0000000000000000

3、对free的smallbin进行extend:

//gcc -g 3.c
int main()
{
    void *ptr,*ptr1;

    ptr=malloc(0x80);//分配第一个0x80的chunk1
    malloc(0x10);//分配第二个0x10的chunk2

    free(ptr);//首先进行释放,使得chunk1进入unsorted bin

    *(long *)((long)ptr-0x8)=0xb1;
    ptr1=malloc(0xa0);
}

​ 首先是两次malloc:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0x91

Allocated chunk | PREV_INUSE
Addr: 0x555555758090
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x5555557580b0
Size: 0x20f51

pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> x/30gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000091			<======Chunk1
0x555555758010: 0x0000000000000000  0x0000000000000000
0x555555758020: 0x0000000000000000  0x0000000000000000
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000000
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000000  0x0000000000000021			<======Chunk2
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000020f51			<======Top Chunk
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000000
0x5555557580e0: 0x0000000000000000  0x0000000000000000

​ 之后直接free掉chunk1:

pwndbg> heap
Free chunk (unsortedbin) | PREV_INUSE
Addr: 0x555555758000
Size: 0x91
fd: 0x7ffff7dd1b78
bk: 0x7ffff7dd1b78

Allocated chunk
Addr: 0x555555758090
Size: 0x20

Top chunk | PREV_INUSE
Addr: 0x5555557580b0
Size: 0x20f51

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x555555758000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x555555758000
smallbins
empty
largebins
empty
pwndbg> x/30gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000091			<======Chunk1
0x555555758010: 0x00007ffff7dd1b78  0x00007ffff7dd1b78
0x555555758020: 0x0000000000000000  0x0000000000000000
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000000
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000090  0x0000000000000020			<======Chunk2
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000020f51			<======Top Chunk
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000000
0x5555557580e0: 0x0000000000000000  0x0000000000000000

​ 这里还是能看出来存在两个chunk的,当修改了size域大小后:

pwndbg> heap
Free chunk (unsortedbin) | PREV_INUSE
Addr: 0x555555758000
Size: 0xb1
fd: 0x7ffff7dd1b78
bk: 0x7ffff7dd1b78

Top chunk | PREV_INUSE
Addr: 0x5555557580b0
Size: 0x20f51

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x555555758000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x555555758000
smallbins
empty
largebins
empty
pwndbg> x/30gx 0x555555758000
0x555555758000: 0x0000000000000000  0x00000000000000b1
0x555555758010: 0x00007ffff7dd1b78  0x00007ffff7dd1b78
0x555555758020: 0x0000000000000000  0x0000000000000000
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000000
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000090  0x0000000000000020
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000020f51
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000000
0x5555557580e0: 0x0000000000000000  0x0000000000000000

​ 原本的三个chunk变成了两个,并且chunk2还是allocated状态,重叠之后,chunk1是free状态,所以整个chunk依旧是free状态。之后malloc(0xa0)试试:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0xb1

Top chunk | PREV_INUSE
Addr: 0x5555557580b0
Size: 0x20f51

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> x/30gx 0x555555758000
0x555555758000: 0x0000000000000000  0x00000000000000b1
0x555555758010: 0x00007ffff7dd1b78  0x00007ffff7dd1b78
0x555555758020: 0x0000000000000000  0x0000000000000000
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000000
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000090  0x0000000000000020
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000020f51
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000000
0x5555557580e0: 0x0000000000000000  0x0000000000000000

4、extend前向overlapping:

//gcc -g 4.c
int main()
{
    void *ptr,*ptr1;

    ptr=malloc(0x10);//分配第1个 0x80 的chunk1
    malloc(0x10); //分配第2个 0x10 的chunk2
    malloc(0x10); //分配第3个 0x10 的chunk3
    malloc(0x10); //分配第4个 0x10 的chunk4    
    *(long *)((long)ptr-0x8)=0x61;
    free(ptr);
    ptr1=malloc(0x50);
}

​ 还是老样子,进行4次malloc,看下heap和bin以及chunk的内容:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x555555758020
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x555555758040
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x555555758060
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x555555758080
Size: 0x20f81

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> x/30gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000021			<======Chunk1
0x555555758010: 0x0000000000000000  0x0000000000000000
0x555555758020: 0x0000000000000000  0x0000000000000021			<======Chunk2
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000021			<======Chunk3
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000021			<======Chunk4
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000020f81			<======Top Chunk
0x555555758090: 0x0000000000000000  0x0000000000000000
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000000
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000000
0x5555557580e0: 0x0000000000000000  0x0000000000000000

​ 之后修改size域:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0x61

Allocated chunk | PREV_INUSE
Addr: 0x555555758060
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x555555758080
Size: 0x20f81

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> x/30gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000061
0x555555758010: 0x0000000000000000  0x0000000000000000
0x555555758020: 0x0000000000000000  0x0000000000000021
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000021
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000021
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000020f81
0x555555758090: 0x0000000000000000  0x0000000000000000
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000000
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000000
0x5555557580e0: 0x0000000000000000  0x0000000000000000

​ 之后free:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0x61

Allocated chunk | PREV_INUSE
Addr: 0x555555758060
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x555555758080
Size: 0x20f81

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> x/30gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000061
0x555555758010: 0x0000000000000000  0x0000000000000000
0x555555758020: 0x0000000000000000  0x0000000000000021
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000021
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000021
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000020f81
0x555555758090: 0x0000000000000000  0x0000000000000000
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000000
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000000
0x5555557580e0: 0x0000000000000000  0x0000000000000000

​ 之后重新malloc:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0x61

Allocated chunk | PREV_INUSE
Addr: 0x555555758060
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x555555758080
Size: 0x20f81

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> x/30gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000061
0x555555758010: 0x0000000000000000  0x0000000000000000
0x555555758020: 0x0000000000000000  0x0000000000000021
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000021
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000021
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000020f81
0x555555758090: 0x0000000000000000  0x0000000000000000
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000000
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000000
0x5555557580e0: 0x0000000000000000  0x0000000000000000

5、通过extend前向overlapping:

//gcc -g 5.c
int main(void)
{
    void *ptr1,*ptr2,*ptr3,*ptr4;
    ptr1=malloc(128);//smallbin1
    ptr2=malloc(0x10);//fastbin1
    ptr3=malloc(0x10);//fastbin2
    ptr4=malloc(128);//smallbin2
    malloc(0x10);//防止与top合并
    free(ptr1);
    *(int *)((long long)ptr4-0x8)=0x90;//修改pre_inuse域
    *(int *)((long long)ptr4-0x10)=0xd0;//修改pre_size域
    free(ptr4);//unlink进行前向extend
    malloc(0x150);//占位块
}

​ 经过五次malloc之后:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0x91

Allocated chunk | PREV_INUSE
Addr: 0x555555758090
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5555557580b0
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5555557580d0
Size: 0x91

Allocated chunk | PREV_INUSE
Addr: 0x555555758160
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x555555758180
Size: 0x20e81

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> x/54gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000091
0x555555758010: 0x0000000000000000  0x0000000000000000
0x555555758020: 0x0000000000000000  0x0000000000000000
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000000
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000000  0x0000000000000021
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000021
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000091
0x5555557580e0: 0x0000000000000000  0x0000000000000000
0x5555557580f0: 0x0000000000000000  0x0000000000000000
0x555555758100: 0x0000000000000000  0x0000000000000000
0x555555758110: 0x0000000000000000  0x0000000000000000
0x555555758120: 0x0000000000000000  0x0000000000000000
0x555555758130: 0x0000000000000000  0x0000000000000000
0x555555758140: 0x0000000000000000  0x0000000000000000
0x555555758150: 0x0000000000000000  0x0000000000000000
0x555555758160: 0x0000000000000000  0x0000000000000021
0x555555758170: 0x0000000000000000  0x0000000000000000
0x555555758180: 0x0000000000000000  0x0000000000020e81
0x555555758190: 0x0000000000000000  0x0000000000000000
0x5555557581a0: 0x0000000000000000  0x0000000000000000

​ free了chunk1之后,chunk2的p位已经变成0了:

pwndbg> heap
Free chunk (unsortedbin) | PREV_INUSE
Addr: 0x555555758000
Size: 0x91
fd: 0x7ffff7dd1b78
bk: 0x7ffff7dd1b78

Allocated chunk
Addr: 0x555555758090
Size: 0x20

Allocated chunk | PREV_INUSE
Addr: 0x5555557580b0
Size: 0x21

Allocated chunk | PREV_INUSE
Addr: 0x5555557580d0
Size: 0x91

Allocated chunk | PREV_INUSE
Addr: 0x555555758160
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x555555758180
Size: 0x20e81

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x555555758000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x555555758000
smallbins
empty
largebins
empty
pwndbg> x/54gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000091			<======Chunk1
0x555555758010: 0x00007ffff7dd1b78  0x00007ffff7dd1b78
0x555555758020: 0x0000000000000000  0x0000000000000000
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000000
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000090  0x0000000000000020
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000021			<======Chunk2
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x0000000000000000  0x0000000000000091			<======Chunk3
0x5555557580e0: 0x0000000000000000  0x0000000000000000
0x5555557580f0: 0x0000000000000000  0x0000000000000000
0x555555758100: 0x0000000000000000  0x0000000000000000
0x555555758110: 0x0000000000000000  0x0000000000000000
0x555555758120: 0x0000000000000000  0x0000000000000000
0x555555758130: 0x0000000000000000  0x0000000000000000
0x555555758140: 0x0000000000000000  0x0000000000000000
0x555555758150: 0x0000000000000000  0x0000000000000000
0x555555758160: 0x0000000000000000  0x0000000000000021			<======Chunk4
0x555555758170: 0x0000000000000000  0x0000000000000000
0x555555758180: 0x0000000000000000  0x0000000000020e81			<======Top Chunk
0x555555758190: 0x0000000000000000  0x0000000000000000
0x5555557581a0: 0x0000000000000000  0x0000000000000000

​ 之后修改了chunk3的pre_inuse,也就是size的最低为P位为0,然后修改pre_size位为0xd8,

pwndbg> heap
Free chunk (unsortedbin) | PREV_INUSE
Addr: 0x555555758000
Size: 0x91
fd: 0x7ffff7dd1b78
bk: 0x7ffff7dd1b78

Allocated chunk
Addr: 0x555555758090
Size: 0x20

Allocated chunk | PREV_INUSE
Addr: 0x5555557580b0
Size: 0x21

Allocated chunk
Addr: 0x5555557580d0
Size: 0x90

Allocated chunk | PREV_INUSE
Addr: 0x555555758160
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x555555758180
Size: 0x20e81

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x555555758000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x555555758000
smallbins
empty
largebins
empty
pwndbg> x/54gx 0x555555758000
0x555555758000: 0x0000000000000000  0x0000000000000091			<======Chunk1
0x555555758010: 0x00007ffff7dd1b78  0x00007ffff7dd1b78
0x555555758020: 0x0000000000000000  0x0000000000000000
0x555555758030: 0x0000000000000000  0x0000000000000000
0x555555758040: 0x0000000000000000  0x0000000000000000
0x555555758050: 0x0000000000000000  0x0000000000000000
0x555555758060: 0x0000000000000000  0x0000000000000000
0x555555758070: 0x0000000000000000  0x0000000000000000
0x555555758080: 0x0000000000000000  0x0000000000000000
0x555555758090: 0x0000000000000090  0x0000000000000020
0x5555557580a0: 0x0000000000000000  0x0000000000000000
0x5555557580b0: 0x0000000000000000  0x0000000000000021			<======Chunk2
0x5555557580c0: 0x0000000000000000  0x0000000000000000
0x5555557580d0: 0x00000000000000d0  0x0000000000000090			<======Chunk3
0x5555557580e0: 0x0000000000000000  0x0000000000000000
0x5555557580f0: 0x0000000000000000  0x0000000000000000
0x555555758100: 0x0000000000000000  0x0000000000000000
0x555555758110: 0x0000000000000000  0x0000000000000000
0x555555758120: 0x0000000000000000  0x0000000000000000
0x555555758130: 0x0000000000000000  0x0000000000000000
0x555555758140: 0x0000000000000000  0x0000000000000000
0x555555758150: 0x0000000000000000  0x0000000000000000
0x555555758160: 0x0000000000000000  0x0000000000000021			<======Chunk4
0x555555758170: 0x0000000000000000  0x0000000000000000
0x555555758180: 0x0000000000000000  0x0000000000020e81			<======Top Chunk
0x555555758190: 0x0000000000000000  0x0000000000000000
0x5555557581a0: 0x0000000000000000  0x0000000000000000

​ 可以看出来,chunk3的pre_size域的大小刚好能够包含到完chunk1和chunk2。之后free掉了chunk3:

pwndbg> heap
Free chunk (unsortedbin) | PREV_INUSE
Addr: 0x555555758000
Size: 0x161
fd: 0x7ffff7dd1b78
bk: 0x7ffff7dd1b78

Allocated chunk
Addr: 0x555555758160
Size: 0x20

Top chunk | PREV_INUSE
Addr: 0x555555758180
Size: 0x20e81

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x555555758000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x555555758000
smallbins
empty
largebins
empty

会发现,前面的三个chunk都被合并成了一个,这里主要是因为unlink的原因,导致了chunk3和前面的两个(主要是pre_size指定的大小范围内的)chunk发生了合并。之后再进行malloc,会分配走新的那个chunk1:

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x555555758000
Size: 0x161

Allocated chunk | PREV_INUSE
Addr: 0x555555758160
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x555555758180
Size: 0x20e81

pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PyTorch核心概念:从梯度、计算图到连续性的全面解析(三)

文章目录 Contiguous vs Non-Contiguous TensorTensor and ViewStrides非连续数据结构&#xff1a;Transpose( )在 PyTorch 中检查Contiguous and Non-Contiguous将不连续张量&#xff08;或视图&#xff09;转换为连续张量view() 和 reshape() 之间的区别总结 参考文献 Contig…

「IDE」集成开发环境专栏目录大纲

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「IDE」集成开发环境&#x1f4da;全部专栏「Win」Windows程序设计「IDE」集成开发环境「UG/NX」BlockUI集合「C/C」C/C程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「UG/NX」NX定…

Kafka经典面试题

1、kafka消息发送的流程&#xff1f; producer发送过程中启动两个线程 一个main线程 一个sender线程&#xff0c;在main线程中先创建一个双端队列&#xff08;RecordAccumlator、producerbatch&#xff09;&#xff0c;main将我们需要发送的东西经过拦截器&#xff0c;序列化&a…

手把手写深度学习(29):将DDP训练代码改成DeepSpeed

手把手写深度学习(0)&#xff1a;专栏文章导航 前言&#xff1a;deepspeed已经成为了大模型时代训练模型的常规武器&#xff0c;这篇博客以一个基于DDP的 Stable Diffusion模型训练为例&#xff0c;讲解如何从将DDP训练代码改成DeepSpeed。 目录 构建optimizer 构建scheduler…

信息收集系列(二):ASN分析及域名收集

内容预览 ≧∀≦ゞ 信息收集系列&#xff08;二&#xff09;&#xff1a;ASN分析及域名收集前言一、ASN 分析1. 获取 ASN 码2. 使用 ASNMap 获取 IP 范围3. 将 IP 范围转化为 IP 列表 二、关联域名收集1. 顶级域&#xff08;TLD&#xff09;收集测试方法 2. 根域名收集常用方法…

《数学分析》中不等式及补充

说明&#xff1a;此文章用于本人复习巩固&#xff0c;如果也能帮到大家那就更加有意义了。 注&#xff1a;1&#xff09;《数学分析》中的不等式及不等式的补充

HTML之图片和超链接的学习记录

图片 在HTML中&#xff0c;我们可以使用img标签来显示一张图片。对于img标签&#xff0c;我们只需要掌握它的三个属性&#xff1a;src、alt和title。 <img src"" alt"" title"" /> src用于指定图片所在的路径&#xff0c;这个路径可以是…

unity显示获取 年月日周几【日期】

unity显示获取 年月日周几【日期】 public void ShowDate(Text txt){//txt.text DateTime now DateTime.Now; // 获取当前时间int year now.Year; // 获取年份int month now.Month; // 获取月份&#xff08;1-12&#xff09;int day now.Day; // 获取天数&#xff08;1-31&…

【区块链】深入理解智能合约 ABI

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 深入理解智能合约 ABI&#xff08;应用程序二进制接口&#xff09;一、ABI 基础…

鸿蒙ZRouter动态路由框架—生命周期管理能力

文章目录 基本使用(单个页面生命周期&#xff09;页面的全局生命周期监听工作流程图源码 ZRouter从1.1.0版本开始支持生命周期函数管理能力&#xff0c;主要有以下特点&#xff1a; 不影响你原有的生命周期业务逻辑&#xff0c;对NavDestination页面保持着零侵入性&#xff0c;…

代码随想录算法训练营第十九天|理论基础、77. 组合、216.组合总和III、17.电话号码的字母组合

理论基础 文章链接&#xff1a;代码随想录 视频讲解&#xff1a;带你学透回溯算法&#xff08;理论篇&#xff09;| 回溯法精讲&#xff01;_哔哩哔哩_bilibili关于回溯算法&#xff0c;我公众号里已经讲完了&#xff0c;并且将回溯算法专题整理成一本PDF&#xff0c;该PDF共…

uniapp的基本使用(easycom规范和条件编译)和uview组件的安装和使用

文章目录 1、uniapp1.uview组件安装2.uview-plus组件安装 2、条件编译3、easycom规范1.组件路径符合规范2.自定义easycom配置的示例 总结 1、uniapp UniApp的UI组件库&#xff0c;如TMUI、uViewUI、FirstUI、TuniaoUI、ThorUI等&#xff0c;这些组件库适用于Vue3和TypeScript&…

深入探索GDB调试技巧及其底层实现原理

本文分为两个大模块&#xff0c;第一部分记录下本人常用到的GDB的调试方法和技巧&#xff0c;第二部分则尝试分析GDB调试的底层原理。 一、GDB调试 要让程序能被调试&#xff0c;首先得编译成debug版本&#xff0c;当然release版本的也能通过导入符号表来实现调试&#xff0c…

Kubernetes的基本概念

Kubernetes是谷歌以Borg为前身,基于谷歌15年生产环境经验的基础上开源的一个项目,Kubernetes致力于提供跨主机集群的自动部署、扩展、高可用以及运行应用程序容器的平台。 一、资源对象概述 Kubernetes中的基本概念和术语大多是围绕资源对象(Resource Object)来说的,而资…

JavaWeb后端开发案例——苍穹外卖day01

day1遇到问题&#xff1a; 1.前端界面打不开&#xff0c;把nginx.conf文件中localhost:80改成81即可 2.前后端联调时&#xff0c;前端登录没反应&#xff0c;application.yml中默认用的8080端口被占用&#xff0c;就改用了8081端口&#xff0c;修改的时候需要改两个地方&…

(一)<江科大STM32>——软件环境搭建+新建工程步骤

一、软件环境搭建 &#xff08;1&#xff09;安装 Keil5 MDK 文件路径&#xff1a;江科大stm32入门教程资料/Keil5 MDK/MDK524a.EXE&#xff0c;安装即可&#xff0c;路径不能有中文。 &#xff08;2&#xff09;安装器件支持包 文件路径&#xff1a;江科大stm32入门教程资料…

软件开发的各类模型

目录 软件的生命周期 常见开发模型 瀑布模型 螺旋模型 增量模型、迭代模型 敏捷模型 Scrum模型 常见测试模型 V模型 W模型&#xff08;双V模型&#xff09; 软件的生命周期 软件的生命周期包括需求分析&#xff0c;计划&#xff0c;设计&#xff0c;编码&#xff0c;…

ElasticSearch学习笔记一:简单使用

一、前言 该系列的文章用于记录本人从0学习ES的过程&#xff0c;首先会对基本的使用进行讲解。本文默认已经安装了ES单机版本&#xff08;当然后续也会有对应的笔记&#xff09;&#xff0c;且对ES已经有了相对的了解&#xff0c;闲话少叙&#xff0c;书开正文。 二、ES简介 …

C++笔记---异常

1. 异常的概念 1.1 异常和错误 异常通常是指在程序运行中动态出现的非正常情况&#xff0c;这些情况往往是可以预见并可以在不停止程序的情况下动态地进行处理的。 错误通常是指那些会导致程序终止的&#xff0c;无法动态处理的非正常情况。例如&#xff0c;越界访问、栈溢出…

python opencv3

三、图像预处理2 1、图像滤波 为图像滤波通过滤波器得到另一个图像。也就是加深图像之间的间隙&#xff0c;增强视觉效果&#xff1b;也可以模糊化间隙&#xff0c;造成图像的噪点被抹平。 2、卷积核 在深度学习中&#xff0c;卷积核越大&#xff0c;看到的信息越多&#xff0…