用户态视角理解内核ROP利用:快速从shell到root的进阶
用户态视角理解内核ROP利用:快速从shell到root的进阶
一、摘要
本文仅限于快速从用户态向内核态入门,可能会有很多不严谨的地方,存在问题请及时告知感谢!本文旨在通过对比用户态 ROP 利用和内核 ROP 利用,揭示两者在利用手法上的相似性。通过分析用户态漏洞利用的流程,结合内核漏洞利用的特点,引导读者理解内核 ROP 利用的本质,从而更快地掌握内核漏洞利用技术。
本文主要是要为了帮助大部分人去克服学习内核利用Kernel_pwn前的枯燥无聊的前置知识的学习,虽然本文很长但是只需要跟着实际操作就可以快速学习完毕,本文直接以用户态和内核态的对比利用来讲解,在实际操作中讲解知识点,其实本文可以直接从这部分开始看:五、实战以强网杯2018 - core内核Pwn题
之后再回来看基础知识!学会如何进行Linux内核调试和驱动文件的漏洞挖掘!!!
无论是在内核还是用户态中,漏洞利用的本质是通过构造特定输入,触发程序的异常执行路径。其核心逻辑包含三个必要要素:
- 输入交互:必须存在外部可控的输入通道,例如网络数据包、文件内容或用户输入界面。
- 漏洞触发点:程序中存在未经验证的内存操作(存在栈溢出漏洞),导致控制流可能被劫持。
- 权限提升路径:通过修改关键数据结构(返回地址、函数指针等),建立从漏洞触发到目标代码执行的完整链路。
攻击的终极目标是控制程序执行流。当攻击者能够通过漏洞改写EIP/RIP寄存器或劫持函数指针时,即可强制程序跳转至指定内存区域(如Shellcode或ROP链),最终实现代码执行。
当内存屏障竖起高墙,黑客如何让代码在荒漠中开花?(ROP(Return-Oriented Programming)的本质是一场精密的指令拼图游戏——从程序的废墟中挖掘代码片段(gadgets),通过栈指针的精准操控,让这些孤立指令像多米诺骨牌般连锁触发,最终突破系统的桎梏!
二、概述:漏洞利用的通用思维框架
1. 用户态和内核态ROP的核心共性
对比维度 | 用户态ROP | 内核态ROP | 核心共性 |
---|---|---|---|
控制流劫持目标 | 劫持进程控制流(如覆盖栈返回地址) | 劫持内核控制流(驱动或内核存在可以利用漏洞) | 均需通过漏洞(溢出、UAF等)劫持控制流 |
Gadget来源 | 用户态程序或动态库(如libc、libc.so) | 内核镜像或内核模块(如vmlinux、.ko文件) | 复用现有代码片段(Gadgets),绕过DEP/NX |
内存布局操控 | 覆盖用户栈/堆内存(如返回地址、函数指针) | 篡改内核栈/堆内存(如内核结构体、任务栈) | 需精确控制内存布局以链式调用Gadgets |
权限与上下文 | 用户态权限(Ring 3),遵循用户空间调用约定 | 内核态权限(Ring 0),需适配内核特权级上下文 | 上下文敏感设计(如寄存器状态、传参方式) |
对抗保护机制 | 绕过用户态ASLR、Stack Canary | 绕过内核态KASLR、SMAP/SMEP(若启用) | 依赖信息泄露获取基址,绕过随机化与检测机制 |
漏洞利用入口 | 常见于应用层漏洞(如栈溢出、格式化字符串) | 多通过系统调用接口(如ioctl、syscall)触发漏洞 | 利用程序逻辑缺陷或内存错误实现初始控制流劫持 |
攻击目标 | 执行Shellcode、劫持应用逻辑 | 实现内核代码执行、关闭安全机制、Rootkit植入、提权 | 最终目标均为实现非授权代码执行或权限提升 |
缓解措施 | DEP/NX、ASLR、Stack Canary | KASLR、SMAP/SMEP、KPTI、内核代码签名 | 均需结合硬件与软件防护机制抵御ROP攻击 |
关键差异总结:
- 权限层级:用户态受限于Ring 3,内核态拥有Ring 0特权,可执行敏感指令(如CR3修改)。
- Gadget范围:内核态需从内核镜像中提取Gadgets,且需处理特权指令(如
swapgs
、sti
)。 - 缓解机制:内核态需额外对抗SMAP/SMEP(阻止用户态内存访问)和KPTI(隔离用户/内核页表)。
- 漏洞入口:用户态漏洞多由应用逻辑引发,内核态漏洞常通过驱动或系统调用触发。
2.用户态和内核态漏洞利用环境差异对比
维度 | 用户态 | 内核态 |
---|---|---|
交互方式 | 通过开放端口、命令行参数等进程间通信 | 依赖系统调用(syscall)、驱动IOCTL接口等底层交互 |
地址空间 | 每个进程拥有独立的虚拟地址空间(受MMU隔离保护) | 所有进程,全局共享的内核地址空间(无隔离性) |
权限级别 | Ring 3,仅能访问受限资源 | Ring 0,可直接操作硬件和系统关键数据结构 |
保护机制 | ASLR、NX、Stack Canary等用户层防护 | Stack Canary、KASLR、SMEP(禁止内核执行用户页)、SMAP(禁止内核访问用户页)等硬件级防护 |
提权目标 | 获取进程权限(如启动/bin/sh) | 突破权限隔离,获取root或SYSTEM级特权 |
攻击脚本 | Python脚本(依赖进程交互接口) | 需编写C/汇编代码直接操作内核数据结构 |
- 地址空间隔离性
- 用户态下,每个进程拥有独立的虚拟地址空间,通过MMU实现内存隔离。漏洞利用通常需要先泄露内存布局(如通过信息泄露漏洞绕过ASLR)。
- 内核态中,所有进程共享同一内核地址空间。攻击者可利用该特性直接修改全局数据结构(如进程凭证cred结构),但需规避KASLR对内核符号的随机化。
- 权限提升路径
- 用户态提权通常通过执行/bin/sh等程序获取当前进程权限,若目标进程本身具有高权限(如SUID程序),则可直接完成提权。
- 内核态攻击需修改当前进程的权限标识(如Linux中的
struct cred
的uid/gid字段),或劫持系统调用表等核心结构,使攻击代码获得Ring 0的执行权限。
- 防护机制对抗
- 用户态需组合使用ROP/JOP等代码复用技术绕过NX,利用堆喷(Heap Spray)对抗ASLR。
- 内核态需处理更严格的硬件防护:例如通过
swapgs
等指令绕过KPTI隔离,或构造ROP链规避SMEP/SMAP对用户空间内存的访问限制。
三、内核态的基础文件系统和内核基础讲解
(一),基础的内核文件说明
1. 内核映像文件(如 vmlinuz)
内核映像文件是 Linux 操作系统的核心,包含内核代码和基本驱动。启动时,它被加载到内存中,解压后执行,负责初始化硬件、设置内存管理,并为用户空间准备环境。
- bzImage: 这是可启动的压缩内核格式,“bz”代表“big zip”,允许内核文件超过传统 512 KB 限制,适合现代系统。
- vmlinux: 未压缩的内核映像,通常用于调试或分析。
- 启动过程: 内核加载后,初始化硬件(如 CPU、内存)、设置中断和设备驱动,然后挂载根文件系统。
2. Initrd/Initramfs
Initrd 和 Initramfs 是启动过程中的临时根文件系统,用于在挂载真实根文件系统前加载必需的驱动和工具。
- initrd(initial ramdisk):内核启动时加载的临时根文件系统,用于在挂载真正的根文件系统前加载必需的驱动模块。
- initramfs: Initrd 的改进版,使用 cpio 格式,直接解压到内存,无需挂载,提供更高效率和灵活性。
- 用途: 内核可能需要特定驱动(如磁盘控制器)才能访问真实根文件系统,Initramfs 提供临时环境加载这些驱动。
(二),了解Qemu模拟运行Linux内核的基本执行流程
QEMU 是一个开源模拟器,广泛用于虚拟化不同架构的操作系统。在启动 Linux 内核时,QEMU 通过 qemu-system-x86 命令初始化虚拟机环境。这一过程包括设置 CPU、内存和设备模拟,确保虚拟机能够运行目标操作系统。
- 通过QEMU启动内核以及加载文件系统:
内核加载与执行: QEMU 加载内核映像文件,通常为 bzImage(压缩的内核)或 vmlinux(未压缩的内核)。根据 QEMU 文档,用户可以通过 -kernel 选项指定内核文件路径。内核加载后,会自动解压(如果为 bzImage),然后开始执行,完成硬件初始化(如设置内存结构、加载驱动)。
- Initramfs 处理过程:
Initramfs(Initial RAM Filesystem)是 Linux 启动过程中的临时根文件系统,通常以 initramfs.cpio 格式存在。根据 Gentoo Wiki,其主要目的是为内核提供一个最小化的用户空间环境,以加载必要的驱动和挂载真实根文件系统。
- 加载与挂载: 内核检测到 Initramfs 文件后,将其解压并挂载为内存中的临时根文件系统(/)。这一过程通过 cpio 归档格式实现,内容包括基本的 shell、工具(如 busybox)和配置文件。
- 作用: Initramfs 特别适用于需要特殊驱动(如 RAID、LVM 或加密文件系统)的系统。例如,Debian Wiki 指出,Initramfs 允许在挂载真实根文件系统之前加载内核模块,增强了启动的灵活性。
- 解释补充: 用户提供的图表正确描述了这一阶段,但需要强调 Initramfs 是启动过程中的关键步骤,尤其在复杂存储配置下(如 USB 启动或加密分区)。
- 用户空间初始化
在 Initramfs 设置完成后,内核会启动 Initramfs 中的 /init 脚本,这是第一个用户空间进程。/init 脚本负责加载必要的内核模块(如 .ko 文件),挂载真实根文件系统,然后启动用户空间的初始化进程(如 systemd 或 shell),完成系统的全面初始化。,根据不同的构建方式shell脚本可以在不同位置。
- 最终整合后的流程如下表
阶段 | 主要动作 | 说明 |
---|---|---|
QEMU 启动内核文件 | 加载内核映像(如 bzImage),解压并执行 | 完成硬件初始化,准备后续步骤 |
Initramfs 处理 | 加载 initramfs.cpio,挂载为临时根文件系统 | 提供最小化环境,加载驱动和工具 |
用户空间初始化 | 执行 /init 脚本,挂载真实根,启动 systemd/shell | 完成系统初始化,进入用户 |
(三),LKMs(可装载内核模块,Loadable Kernel Modules)
1.LKMs 的文件格式:
在linux里面查看该文件:
ub20@ub20:~/KernelStu/RunQemu$ file ../CodeKernelDriver/hello.ko
../CodeKernelDriver/hello.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=6cc23340ffa46ada1c55861237166888e5676d
文件格式:Linux:采用 ELF(Executable and Linkable Format)格式,后缀通常是 .ko(kernel object)。
LKMs 文件与ELF的区别:
- 用户态程序:ELF 文件可以独立运行(如 ./binary),由用户态加载器解析并执行。
- LKMs:ELF 文件(.ko)不能独立运行,必须通过内核的模块加载机制(如 insmod)加载到内核空间,依赖内核符号表(如 printk、kmalloc)工作。
在不同操作系统上也有类似的机制: - Windows:类似功能的文件是 .exe 或 .dll(动态链接库),但内核模块通常以驱动形式存在(如 .sys)。
- macOS:使用 Mach-O 格式,但 macOS 的内核扩展(KEXT)机制与 LKMs 略有不同。
-
LKMs(可装载内核模块)是什么?
定义:LKMs 是 Linux 内核支持的一种机制,允许在内核运行时动态加载或卸载功能模块,而无需重新编译或重启整个内核。它们是内核代码的扩展,通常用于添加设备驱动程序、文件系统支持、网络协议或其他功能。
特点:- 动态性:可以在运行时加载(load)或卸载(unload),相比之下,静态编译进内核的代码需要重启系统才能生效。
- 模块化:将内核功能分解为独立模块,便于维护和扩展。
- 依赖内核:LKMs 不能独立运行,必须嵌入内核地址空间,作为内核的一部分执行。
-
与内核相关的Linux指令:
- insmod: 讲指定模块加载到内核中
- 特点:需要提供模块文件的完整路径,且不会自动处理模块的依赖关系。通常用在需要手动加载单个模块的场景。
- rmmod: 从内核中卸载指定模块
- 特点:只需要模块名称(不需要路径或 .ko 后缀),但如果模块正在被使用或有依赖关系,卸载会失败。
- lsmod: 列出已经加载的模块
- 特点:输出包括模块名、占用内存大小以及依赖关系,简单明了,常用于检查模块状态。
- modprobe: 添加或删除模块,modprobe 在加载模块时会查找依赖关系
- 比 insmod 和 rmmod 更智能,会根据 /lib/modules/ 下的模块依赖文件(通常由内核版本管理)自动加载依赖模块,是日常使用中最推荐的工具。
(四),以强网杯2018 - core内核Pwn题的文件为例:
例题:强网杯2018 - core
依然是十分经典的kernel pwn入门题,内核入门题的老演员了!
点击下载-core.7z
WP:【PWN.0x00】Linux Kernel Pwn I:Basic Exploit to Kernel Pwn in CTF - arttnba3’s blog
- 将压缩包解压出来之后可以得到这些文件
ub20@ub20:~/KernelStu/KernelVuln/Kernel_ROP_basic/give_to_player$ ls
bzImage core.cpio vmlinux start.sh
- bzImage:启动内核的压缩镜像。
- core.cpio:包含了完整的根文件系统。
- vmlinux:内核符号文件,有助于我们分析内核函数地址。
- start.sh:启动脚本,用于初始化环境。
- start.sh利用如下命令启动 QEMU 虚拟机,查看一下启动参数及保护机制:
qemu-system-x86_64 \
-m 64M \
-kernel ./bzImage \
-initrd ./core.cpio \
-append "root=/dev/ram rw console=ttyS0 oops=panic panic=1 quiet kaslr" \
-s \
-netdev user,id=t0, -device e1000,netdev=t0,id=nic0 \
-nographic \
这里的启动参数中包含:
- kaslr:开启内核地址空间布局随机化,但由于其他防护措施较弱(例如 NX 被禁用),依然为后续的 ROP 利用提供了突破口。
- 其它参数则确保虚拟机内的文件系统、网络及调试环境能正常工作。
- 解压这个文件可以看见整个文件系统的目录:
gunzip -c /home/ub20/KernelStu/KernelVuln/Kernel_ROP_basic/give_to_player/core.cpio | cpio -idmv
这就是解压出来的文件系统core.cpio,就是一个Linux操作系统的文件目录结构里面有构建好的基础工具:
ub20@ub20:~/KernelStu/KernelVuln/Kernel_ROP_basic/tmp$ tree -d
.
├── bin
├── etc # 系统配置文件(通常包含inittab、passwd等)
├── lib # 内核模块存储目录(注意权限位为755)
│ └── modules
│ └── 4.15.8 # 内核版本
│ └── kernel
│ ├── arch
│ │ └── x86
│ │ └── kvm
│ ├── drivers
│ │ ├── thermal
│ │ └── vhost
│ ├── fs
│ │ └── efivarfs
│ └── net
│ ├── ipv4
│ │ └── netfilter
│ ├── ipv6
│ │ └── netfilter
│ └── netfilter
├── lib64
├── proc # 进程信息虚拟文件系统
├── root
├── sbin
├── sys
├── tmp
└── usr├── bin└── sbin
解压后你会发现文件系统内的目录结构与标准 Linux 系统类似,主要目录包括:
- bin、sbin:基本命令与系统管理工具。
- etc:存放系统配置文件,如 passwd、inittab 等。
- lib/lib64:存放库文件及内核模块,其中
lib/modules/4.15.8/
目录下包含当前内核版本的模块。 - proc、sys:虚拟文件系统,分别提供进程与系统信息。
- usr:包含一些用户级工具。
- 查看解压后的
/init
脚本内容,可以看见他的初始化脚本加载了哪些内核文件,和进行了什么操作有什作用:
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs none /dev
/sbin/mdev -s
mkdir -p /dev/pts
mount -vt devpts -o gid=4,mode=620 none /dev/pts
chmod 666 /dev/ptmxcat /proc/kallsyms > /tmp/kallsyms# 将内核符号表导出到 /tmp/kallsyms 文件,用于调试和分析
echo 1 > /proc/sys/kernel/kptr_restrict# 限制非特权用户访问内核符号地址
echo 1 > /proc/sys/kernel/dmesg_restrict# 限制非特权用户访问内核日志ifconfig eth0 up
udhcpc -i eth0
ifconfig eth0 10.0.2.15 netmask 255.255.255.0
route add default gw 10.0.2.2 # 加载内核模块 core.ko
insmod /core.ko
poweroff -d 120 -f & # 在 120 秒后强制关机
setsid /bin/cttyhack setuidgid 1000 /bin/sh # 启动一个新的会话,并以 UID 1000 的用户身份运行 shellecho 'sh end!\n' # 打印 shell 结束信息
umount /proc
umount /sys# 立即强制关机
poweroff -d 0 -f
- 内核符号泄露:通过将
/proc/kallsyms
的内容复制到/tmp/kallsyms
,攻击者可以轻松获取内核中所有函数的地址,对于构造 ROP 链至关重要。 - 安全配置调整:写入
kptr_restrict
和dmesg_restrict
,将内核符号信息暴露出来,从而降低了利用难度。 - 模块加载:
insmod /core.ko
表明题目中真正存在漏洞的模块就是core.ko
,后续的漏洞挖掘与利用将围绕此模块展开。 - 调试与网络配置:配置网络及设置延时关机方便调试,有时需要手动去除定时关机以便反复利用。
- 内核模块保护检查
在解压出来的文件系统中成功找到了core.ko内核文件:
ub20@ub20:~/KernelStu/KernelVuln/Kernel_ROP_basic/tmp$ checksec --file=./core.ko
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
No RELRO Canary found NX disabled Not an ELF file No RPATH No RUNPATH 41 Symbols No 0 0 ./core.ko
分析输出可以看出:
- RELRO:未启用,模块内存保护较弱。
- Stack Canary:存在一定的栈保护,但并不足以完全抵抗溢出攻击。
- NX(不可执行位):被禁用,允许在堆栈上执行代码,这为构造 ROP 链提供了便利。
- 符号信息:包含 41 个符号,有助于定位漏洞代码和搭建攻击链。
四、驱动文件的动静逆向分析技术讲解
在深入分析驱动文件之前,掌握一些基础知识是至关重要的。本节将带领读者了解如何通过动静结合的方式对驱动文件进行逆向分析,重点讲解用户态与内核态的交互机制、关键内核函数的使用,以及如何通过调试工具对内核进行调试。
基础知识准备: 用户态与内核交互的关键系统调用 ioctl
在Linux系统中,用户态程序与内核态驱动之间的交互通常通过系统调用实现。ioctl
是一个非常重要的系统调用,用于设备控制。它允许用户态程序向内核态驱动发送特定的控制命令,从而实现设备的管理和配置。
在一般系统调用就是通过系统调用号来实现,比如64
位下read
的系统调用号为0
。
/usr/include/x86_64-linux-gnu/asm/unistd_64.h
和/usr/include/x86_64-linux-gnu/asm/unistd_32.h
可以查看 64 位和 32 位的系统调用号。
系统调用:ioctl
在 Linux
系统中,几乎所有设备都被视为文件,这使得通过标准的文件操作(如 open
、read
、write
和 close
)来访问设备变得简单。然而,某些操作超出了这些标准接口的能力,需要一个更灵活的机制来处理设备特定的功能,这就是 ioctl
的用武之地。
ioctl
** 的功能**
- 设备控制:通过
ioctl
,用户空间程序可以发送控制命令给设备驱动程序,进行设备特定的操作,比如设置设备参数、查询设备状态等。 - 扩展性:因为设备驱动是可扩展的,
ioctl
使得新设备可以通过定义新的请求码和操作接口来被支持,而不需要修改现有的系统调用。
函数原型
在 C 语言中,ioctl
的原型如下:
int ioctl(int fd, unsigned long request, ...);
fd
:文件描述符,通常是通过open()
函数获取的,用于指定要操作的设备。request
:请求的命令,通常是一个宏,定义了要执行的操作。...
:可选参数,具体取决于请求的类型,有时需要传递指向结构体的指针或其他参数。
使用ioctl
int fd = open("/dev/mydevice", 2);//在内核中攻击使用/proc/mydevice
ioctl(fd, request_code, data) ;
基础知识准备: 驱动文件中的关键函数init_module
init_module
是 Linux 内核模块加载时的入口函数,负责:
- 分配资源(内存、IO 端口等);
- 注册设备(如创建设备节点、分配设备号);
- 初始化硬件或数据结构。
了解 init_module
的实现可以帮助确定驱动的加载流程和初始化逻辑,并为后续的漏洞挖掘提供线索。
基础知识准备: Linux内核中常见的内核态函数
在内核驱动中,许多函数在系统稳定性与安全性上起着至关重要的作用。下面列举一些常见的函数:
- printk:用于内核日志输出,调试信息可通过
dmesg
查看。利用 printk 可观察到模块加载、错误提示等信息。 - copy_from_user / copy_to_user:这两个函数用于在内核与用户空间之间传递数据,往往是漏洞出现的重要接口,如缓冲区溢出、越界访问等问题可能出现在此。
- kmalloc / kfree:内核动态内存分配与释放函数,类似于用户态的 malloc/free,但因内存池和同步机制的不同,容易因错误使用引发内存泄漏或内存破坏。
- proc_create:在
/proc
文件系统中创建条目,常用于调试和状态监控,逆向过程中可借助该接口了解驱动的运行状态。
在 Linux 内核中,proc_create 是一个非常重要的函数,用于在 /proc 文件系统下创建新的文件条目。它通常用于内核模块或驱动程序开发,以便提供一种用户空间与内核空间交互的接口。下面我详细解释它的作用和用法。
struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops);
返回值: 返回一个指向 struct proc_dir_entry 的指针,表示创建的 proc 文件条目。如果创建失败,返回 NULL。
参数说明:
- const char name:
- 指定要创建的 proc 文件的名称。
- 例如,如果传入 “core”,则会在指定的父目录下创建 /proc/core 文件。
- 这个文件可以通过用户空间的工具(如 cat、echo)访问。
- umode_t mode:
- 指定文件的权限模式,通常用八进制表示(例如 0666)。
- 权限值遵循 Linux 文件权限规则:
- struct proc_dir_entry parent:
- 指定新文件的父目录,是一个 proc_dir_entry 结构体的指针。
- 如果传入 NULL,文件会创建在 /proc 根目录下。
- 如果传入其他值,则可以在子目录下创建文件。例如,如果 parent 指向 /proc/sys,新文件会出现在 /proc/sys/name。
- const struct file_operations proc_fops:
- 一个指向 file_operations 结构体的指针,定义了该 proc 文件支持的操作。
- 这个结构体包含函数指针,例如:
- .read: 定义读文件时的行为。
- .write: 定义写文件时的行为。
- .open: 文件打开时的回调。
- .release: 文件关闭时的回调。
- 通过这个参数,开发者可以自定义用户空间与内核交互的逻辑。
4.基础知识准备: 内核调试环境搭建与实践
例题:强网杯2018 - core
依然是十分经典的kernel pwn入门题,用他来进行内核调试
点击下载-core.7z
WP:【PWN.0x00】Linux Kernel Pwn I:Basic Exploit to Kernel Pwn in CTF - arttnba3’s blog
本部分将深入解析内核漏洞调试环境的构建方法,以强网杯2018核心赛题为例,演示完整的调试流程
编写C语言程序来调用驱动中的函数作为内核调试入口
我们使用以下C程序作为内核态数据探测工具,其核心功能是通过ioctl系统调用与内核模块交互,写了一个泄露内核Canary值的简单程序,编译好后直接传入虚拟机,之后执行即可获得,内核空间中Canary的值!仅本案例有效:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>void set_off_val(int fd, size_t off) {ioctl(fd, 0x6677889C, off
相关文章:
用户态视角理解内核ROP利用:快速从shell到root的进阶
用户态视角理解内核ROP利用:快速从shell到root的进阶 一、摘要 本文仅限于快速从用户态向内核态入门,可能会有很多不严谨的地方,存在问题请及时告知感谢!本文旨在通过对比用户态 ROP 利用和内核 ROP 利用,揭示两者在利用手法上的相似性。通过分析用户态漏洞利用的流程,结合…...
我又叕叕叕更新了~纯手工编写C++画图,有注释~
本次更新内容: 优化性能,朗读 提前申明:如果运行不了,请到主页查看RedpandaDevc++下载,若还是不行就卸了重装。 版本号:1.26.36 779行 24690字 最终结果预览 代码预览 //版本号 :v1.26.36 //最终归属权为作者(饼干帅成渣)所有 //禁止转载 //仅供学习,不得用于违法 #…...
【家政平台开发(37)】家政平台蜕变记:性能优化与代码重构揭秘
本【家政平台开发】专栏聚焦家政平台从 0 到 1 的全流程打造。从前期需求分析,剖析家政行业现状、挖掘用户需求与梳理功能要点,到系统设计阶段的架构选型、数据库构建,再到开发阶段各模块逐一实现。涵盖移动与 PC 端设计、接口开发及性能优化,测试阶段多维度保障平台质量,…...
基于springboot+vue的秦皇岛旅游景点管理系统
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9 系统展示 用户登录 旅游路…...
图像预处理-翻转与仿射变换
一.图像翻转 cv2.flip(img,flipcode) 参数 - flipcode : 指定翻转类型的标志,为0,表示沿x轴翻转,>0(默认1) 表示沿y轴翻转,为 <0(默认-1) 表示水平垂直翻转 OpenCV中,图片的镜像旋转以图像的中心为原点 impo…...
[ABC400F] Happy Birthday! 3 题解
考虑正难则反。问题转化为: 一个环上有 n n n 个物品,颜色分别为 c o l i col_i coli,每次操作选择两个数 i , j i, j i,j 使得 ∀ k ∈ [ i , j ] , c o l k c o l i ∨ c o l k 0 \forall k \in [i, j], col_k col_i \lor col_k …...
使用nuxt3+tailwindcss4+@nuxt/content3在页面渲染 markdown 文档
nuxt3tailwindcss在页面渲染 markdown 文档 页面效果 依赖 “nuxt/content”: “^3.4.0” “tailwindcss”: “^4.0.10” “nuxt”: “^3.16.2” “tailwindcss/vite”: “^4.0.10” tailwindcss/typography (这个是格式化 md 样式用的) 注意: 这里nuxt/content…...
畅游Diffusion数字人(23):字节最新表情+动作模仿视频生成DreamActor-M1
畅游Diffusion数字人(0):专栏文章导航 前言:之前有很多动作模仿或者表情模仿的工作,但是如果要在实际使用中进行电影级的复刻工作,仅仅表情或动作模仿还不够,需要表情和动作一起模仿。最近字节跳动提出了一个表情+动作模仿视频生成DreamActor-M1。 目录 贡献概述 核心动…...
多模态学习分析(MLA)驱动高中差异化教学策略研究
一、引言 1.1 研究背景 在当今时代,教育数字化转型的浪潮正席卷全球,深刻地改变着教育的面貌。这一转型不仅是技术的革新,更是教育理念、教学模式和教育管理的全面变革。随着互联网、大数据、人工智能等现代信息技术在教育领域的广泛应用&a…...
为什么ASCII的A是65[特殊字符]
为什么ASCII的A是65 1. ASCII是怎么来的 ASCII是1960年代美国标准协会制定的,目的是统一计算机字符编码。它们要在**7个比特位(0-127)**里,塞下所有英文字符,数字,标点和控制符。 2. 为什么A是65&#x…...
Python正则表达式实战技巧:如何高效处理文本匹配?
当你需要在Python中处理文本数据时,正则表达式绝对是你的瑞士军刀。无论是数据清洗、日志分析还是表单验证,掌握正则表达式都能让你事半功倍。今天我们就来聊聊Python中re模块的那些实用技巧和常见陷阱。 为什么正则表达式如此重要? 想象一…...
驱动学习专栏--写在前面
此专栏基于正点原子的文档【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.81 开发板为luckfox的rv1106开发板,之前参加过一个CM1相机的开源项目,与其吃灰不如作为一个学习的工具来发挥余热 所以文档中的一些东西需要对应的在rv1106平台上做修改ÿ…...
Java中的Map vs Python字典:核心对比与使用指南
一、核心概念 1. 基本定义 Python字典(dict) :动态类型键值对集合,语法简洁,支持快速查找。Java Map:接口,常用实现类如 HashMap、LinkedHashMap,需声明键值类型(泛型&…...
从零搭建微服务项目Pro(第0章——微服务项目脚手架搭建)
前言: 在本专栏Base第0章曾介绍一种入门级的微服务项目搭建,尽管后续基于此框架上实现了Nacos、Eureka服务注册发现、配置管理、Feign调用、网关模块、OSS文件存储、JSR参数校验、LogBack日志配置,鉴权模块、定时任务模块等,但由于…...
RAG创建向量数据库:docsearch = FAISS.from_texts(documents, embeddings)
RAG创建向量数据库:docsearch = FAISS.from_texts(documents, embeddings) 代码解释 docsearch = FAISS.from_texts(documents, embeddings) 这行代码主要作用是基于给定的文本集合创建一个向量数据库(这里使用 FAISS 作为向量数据库工具 )。具体说明如下: FAISS :FAISS …...
适配python3.9的 SORT算法
简单地更改了 sort.py 函数的接口,核心思想、处理操作并不改变。 源代码链接:https://github.com/abewley/sort import os import numpy as np import glob import time import argparse from filterpy.kalman import KalmanFilter from scipy.optimiz…...
记录Docker部署CosyVoice V2.0
#记录工作 CosyVoice 是由 FunAudioLLM 团队开发的一个开源多语言大规模语音生成模型,提供了从推理、训练到部署的全栈解决方案。 项目地址: https://github.com/FunAudioLLM/CosyVoice.git 该项目目前从v1.0版本迭代到v2.0版本,但是在Wind…...
源码编译 Galera、MySQL 5.7 Wsrep 和安装 MySQL 5.7 Galera集群
源码编译 Galera、MySQL 5.7 Wsrep 和安装 MySQL 5.7 Galera集群 说明1、源码编译 Galera1.1、安装依赖1.2、源码编译安装 openSSL1.2.1、下载源码1.2.2、编译安装 1.3、源码编译安装 Galera 31.3.1、下载源码1.3.2、注意1.3.3、编译安装 2、源码编译 MySQL-Wsrep2.1、安装依赖…...
【SLAM】ubuntu 18.04 下 OpenCV 3.2.0 的 opencv_example 运行闪退
本文首发于❄慕雪的寒舍 ubuntu 18.04 下 OpenCV 3.2.0 的 opencv_example 运行闪退问题探究。 1. 问题说明 在之前的ORB-SLAM3项目于ROS运行的博客中,提到过安装ROS时会自己安装一个OpenCV 3.2.0版本,所以最好不要安装其他版本的OpenCV,避…...
Linux网络编程——数据链路层详解,以太网、MAC地址、MTU、ARP、DNS、NAT、代理服务器......
目录 一、前言 二、以太网 二、以太网帧格式 三、 MAC地址 四、MTU 1、数据链路层的数据分片 2、MTU对UDP协议的影响 3、MTU对TCP协议的影响 五、ARP协议 1、什么是ARP 2、ARP的作用 3、ARP协议的工作流程 4、ARP缓存表 5、ARP请求报文 6、中间人 六、DNS&…...
Android7 Input(四)InputReader
概述 本文主要描述了Android Input框架中的InputReader的功能,InputReader模块的功能,总结成一句话就是InputReader获取输入设备的事件并将事件进行加工处理,然后传递给QueuedInputListener,最终QueuedInputListener将事件传递给…...
游戏报错?MFC140.dll怎么安装才能解决问题?提供多种MFC140.dll丢失修复方案
MFC140.dll 是 Microsoft Visual C 2015 运行库的重要组成部分,许多软件和游戏依赖它才能正常运行。如果你的电脑提示 "MFC140.dll 丢失" 或 "MFC140.dll 未找到",说明系统缺少该文件,导致程序无法启动。本文将详细介绍 …...
寻找最大美丽数
# 输入:nums1 [4,2,1,5,3], nums2 [10,20,30,40,50], k 2 # 输出:[80,30,0,80,50] import random class Solution:def findMaxSum(self, nums1, nums2, k):hash_table []sum1 0data []print(**31,\n,\t数据)for key,values in enumerate(nums1):da…...
[Linux]进程地址空间
前言 我们在学习C语言期间,经常可以提及到这些区域,有一个问题:这里的地址空间是内存吗?答案是这里的地址空间并不是内存。这里的地址空间是进程地址空间,下面我们就讲解进程地址空间。 这段空间中自下而上ÿ…...
dfs和bfs算法
DFS(深度优先搜索,Depth-First Search)和 BFS(广度优先搜索,Breadth-First Search)是图遍历或搜索算法中的两种基本方法。它们在探索图的节点时采用不同的策略,适用于不同的场景。 ### 深度优先…...
跨站请求是什么?
介绍 跨站请求(Cross-Site Request)通常是指浏览器在访问一个网站时,向另一个域名的网站发送请求的行为。这个概念在 Web 安全中非常重要,尤其是在涉及到“跨站请求伪造(CSRF)”和“跨域资源共享ÿ…...
【深度学习与大模型基础】第9章-条件概率以及条件概率的链式法则
简单理解条件概率 条件概率就是在已知某件事发生的情况下,另一件事发生的概率。用数学符号表示就是: P(A|B) 在B发生的前提下,A发生的概率。 计算机例子:垃圾邮件过滤 假设你写了一个程序来自动判断邮件是否是垃圾邮件…...
C++: 获取auto的实际类型
auto a "hello";auto* b "hello";auto& c "hello";上述 a, b, c 类型分别是什么? 在不使用 IDE 提供的 inlay hints 情况下, 可以编译期获取,然后运行时打印出来: 方法: 用 decltype(var)…...
谷歌开源代理开发工具包(Agent Development Kit,ADK):让多智能体应用的构建变得更简
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
揭开人工智能与机器学习的神秘面纱:开发者的视角
李升伟 编译 人工智能(AI)和机器学习(ML)早已不再是空洞的流行语——它们正在彻底改变我们构建软件、做出决策以及与技术互动的方式。无论是自动化重复性任务,还是驱动自动驾驶汽车,AI/ML都是现代创新的核…...
35.Java线程池(线程池概述、线程池的架构、线程池的种类与创建、线程池的底层原理、线程池的工作流程、线程池的拒绝策略、自定义线程池)
一、线程池概述 1、线程池的优势 线程池是一种线程使用模式,线程过多会带来调度开销,进而影响缓存局部性和整体性能,而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务,这避免了在处理短时间任务时创建与…...
【NumPy科学计算:高性能数组操作核心指南】
目录 前言:技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解关键技术模块技术选型对比 二、实战演示环境配置要求核心代码实现运行结果验证 三、性能对比测试方法论量化数据对比结果分析 四、最佳实践推荐方案 ✅常见错误 ❌调试技…...
软考 系统架构设计师系列知识点之杂项集萃(50)
接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(49) 第78题 著作权中,()的保护期不受限制。 A. 发表权 B. 发行权 C. 署名权 D. 展览权 正确答案:C。 所属知识点:旧版…...
实现定长的内存池
池化技术 所谓的池化技术,就是程序预先向系统申请过量的资源,然后自己管理起来,以备不时之需。这个操作的价值就是,如果申请与释放资源的开销较大,提前申请资源并在使用后并不释放而是重复利用,能够提高程序…...
定制一款国密浏览器(7):铜锁和BoringSSL
上一章简单介绍了一下国密算法,本章开始进入实战,进行国密算法的移植。算法的移植以铜锁为蓝本,移植到 BoringSSL 中。 BoringSSL 也是由 OpenSSL fork 而来,那能否修改 Chromium 的源码,使用铜锁库呢?这种方式我也考虑并尝试过,最后发现两者的接口差别太大,Chromium …...
Docker 安装CRMEB陀螺匠教程
首先下载代码到服务器中,打开终端,并切换到项目源码根目录: 通过 Docker compose 启动项目 第一次启动时需要拉取和打包相关镜像,所需时长视网络情况而定,需耐心等待。 配置反向代理 参考 Nginx 配置 Nginx 反向代…...
Java中的static都能用来修饰什么?
在Java编程语言中,static关键字是非常重要的修饰符,可以用于多种不同的地方。可用来修饰变量、方法、代码块以及类。 1.静态变量 定义:静态变量属于类本身,而不是类的任何特定实例(new出来的对象)。 特点&a…...
词法分析器设计实验
掌握生成词法分析器的方法,加深对词法分析原理的理解。掌握设计、编制并调试词法分析程序的思想和方法。本实验是高级语言程序设计、数据结构和编译原理中词法分析原理等知识的综合。 【实验内容及要求】完善以下代码(红色标注处)并加上注释(蓝色标注处) int Getsym…...
matlab求和∑函数方程编程?
matlab求和∑函数方程编程? 一 题目:求下列函数方程式的和 二:代码如下: >> sum_result 0; % 初始化求和变量 for x 1:10 % 设…...
Vue3.5 企业级管理系统实战(十四):动态主题切换
动态主题切换是针对用户体验的常见的功能之一,我们可以自己实现如暗黑模式、明亮模式的切换,也可以利用 Element Plus 默认支持的强大动态主题方案实现。这里我们探讨的是后者通过 CSS 变量设置的方案。 1 组件准备 1.1 修改 Navbar 组件 在 src/layo…...
Python中for循环及其相关函数range(), zip(), enumerate()等
一、Python中的for循环及其相关函数 Python的for循环是算法竞赛中最常用的迭代工具之一,因其简洁和灵活性非常适合快速实现逻辑。以下详细讲解for循环及相关函数在竞赛中的使用场景。 1. for循环基本语法 Python的for循环用于遍历可迭代对象(如列表、…...
数据结构与算法——链表OJ题详解(2)
文章目录 一、前言二、OJ续享2.1相交链表2.2环形链表12.2环形链表2 三、总结 一、前言 哦了兄弟们,咱们上次在详解链表OJ题的时候,有一部分OJ题呢up并没有整理完,这一个星期呢,up也是在不断的学习并且沉淀着,也是终于…...
免费送源码:Java+ssm+MySQL 基于PHP在线考试系统的设计与实现 计算机毕业设计原创定制
摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对在线考试等问题,对如何通过计算…...
Android之JNI详解
Android之JNI详解 简介创建项目注册动态注册静态注册 关键词解读基础数据类型引用java对象JNI引用与释放cmake配置文件 简介 JNI(Java Native Interface) 是 Java 提供的一种编程框架,用于在 Java 应用程序中调用和与用其他编程语言…...
React Hooks: useRef,useCallback,useMemo用法详解
1. useRef(保存引用值) useRef 通常用于保存“不会参与 UI 渲染,但生命周期要长”的对象引用,比如获取 DOM、保存定时器 ID、WebSocket等。 新建useRef.js组件,写入代码: import React, { useRef, useSt…...
Java基础知识
概念 请介绍全局变量和局部变量的区别 Java中的变量分为成员变量和局部变量,它们的区别如下: 成员变量: 1. 成员变量是在类的范围里定义的变量; 2. 成员变量有默认初始值; 3. 未被static修饰的成员变量也叫…...
体验智能体构建过程:从零开始构建Agent
1. 什么是智能体? 智能体(Agents)是一种能够感知环境、做出决策并采取行动来实现特定目标的自主实体。智能体的复杂程度各不相同,从简单的响应式智能体(对刺激直接做出反应)到更高级的智能体(能…...
如何从项目目标到成功标准:构建可量化、可落地的项目评估体系
引言 在项目管理领域,"项目成功"的定义往往比表面看起来更复杂。根据PMI的行业报告,67%的项目失败源于目标与成功标准的不匹配。当项目团队仅关注"按时交付"或"预算达标"时,常会忽视真正的价值创造。本文将通…...
大模型论文:Language Models are Few-Shot Learners(GPT3)
大模型论文:Language Models are Few-Shot Learners(GPT3) 文章地址:https://proceedings.neurips.cc/paper_files/paper/2020/file/1457c0d6bfcb4967418bfb8ac142f64a-Paper.pdf 一、摘要 我们证明了,扩大语言模型的规模在任务无关的 few…...