07_代码间的段间跳转

前言

在上一节中,我们验证了数据段的访问规则(max(CPL, RPL) <= DPL)。CPU借助这套机制,禁止Ring 3用户态程序越权读取Ring 0内核数据。

但在底层安全攻防中,攻击者的思路更加灵活:既然我不能直接读写内核数据,那我能不能把代码的执行流(EIP)直接跳转到内核的代码段里,让CPU以Ring 0的特权级去帮我执行恶意代码呢?

本节将深入讨论代码段的跨段跳转规则与底层执行流程。我们将会发现,CPU硬件在设计之初就想到了这种提权手段。通过引入一致代码段与非一致代码段的概念,构建了一套执行流的隔离。


一、执行流跳转的本质:指令分类与底层流程

在汇编层面,能够改变EIP的指令有很多,但在保护模式下,它们被划分为两个层级:

  1. 段内跳转(短跳转/近跳转):例如JMP、CALL、JCC、RET。这类指令仅改变EIP寄存器。因为不涉及CS(代码段寄存器)的更换,所以不会引发特权级(CPL)的变化,属于同层级的跳转。
  2. 段间跳转(长跳转/远跳转):例如JMP FAR、CALL FAR、RETF、INT等。这类指令会同时修改CS和EIP寄存器,这意味着执行流想要跨越当前的物理段。

当我们执行一条远调用指令(例如CALL FAR 0x4B:0x12345678)时,CPU在底层的标准执行流程如下:

  1. 段选择子拆分:将0x4B拆分为Index=9, TI=0, RPL=3。
  2. 查表与权限检查:通过GDT表找到对应的代码段描述符。CPU开始进行严格的特权级检查(对比当前CPL、选择子RPL与目标代码段的DPL)。
  3. 地址计算:权限检查通过后,获取目标代码段的Base(基址),加上指令提供的偏移地址(0x12345678),最终跳转到线性地址进行执行。

那么,特权级检查应该遵循什么规则?这完全取决于目标代码段的属性分类。


二、一致代码段与非一致代码段

与数据段单一的保护规则不同,CPU将代码段分类为两种类型。

1. 非一致代码段(普通代码段)

绝大多数的操作系统核心代码段(包括Windows 内核)都属于非一致代码段。它的设计理念是绝对的物理隔离。

  • 访问规则:仅允许同级访问,严格禁止不同特权级之间的相互跨越(内核态不可直接调用用户态,用户态也不可直接调用内核态)。
  • 权限公式:必须严格满足CPL == DPL且RPL <= DPL。

2. 一致代码段(共享代码段)

一致代码段的设计初衷,是为了提供一些允许低权限进程调用的底层共享系统函数。规则如下:

  • 向下保护:高特权级程序不能跳转到低特权级的代码段(防止高权限降级或乱入)。
  • 向上开放:低特权级程序(如Ring 3)可以跳转到高特权级(如Ring 0)的一致代码段中执行。
  • 权限公式:仅需满足CPL >= DPL。
  • 注意: 直接对代码段进行JMP FAR或CALL FAR操作,无论目标是一致还是非一致代码段,当前特权级(CPL)都不会发生改变,也就是说普通的远跳转指令永远不能用于系统提权。

三、代码实验与核心验证

  • 实验前置知识:裸函数(Naked Function)

在构造远跳转的跳板函数时,我们必须使用MSVC提供的 __declspec(naked) 关键字。因为编译器默认会为函数生成push ebp等栈操作指令,而远调用返回时必须使用特殊的retf指令。使用裸函数可以完全接管生成的汇编代码,避免栈失衡程序崩溃。

实验一:跳入Ring 0非一致代码段

  1. WinDbg构造段描述符
 kd> eq ffffffff80b99048 00CF9A00`0000FFFF
kd> dg 0x48
                                  P Si Gr Pr Lo
Sel    Base     Limit     Type    l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0048 00000000 ffffffff Code RE    0 Bg Pg P  Nl 00000c9a
  1. 代码实测
#include "stdafx.h"
#include <stdlib.h>
#include <Windows.h>

#pragma pack(push, 1)
struct FWORD_PTR 
{
	DWORD offset;
	WORD  selector;
};
#pragma pack(pop)


DWORD g_success = 0;

void __declspec(naked) TargetFunction()
{
	__asm
	{
		mov g_success, 1
		retf  
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	FWORD_PTR far_pointer;
	far_pointer.offset = (DWORD)TargetFunction;
	far_pointer.selector = 0x48;

	printf("[Action] Executing CALL FAR to Non-Conforming Segment...\n");

	__try 
	{
		__asm
		{
			call fword ptr [far_pointer]
		}
		if (g_success == 1) 
			printf("Execution Success!\n");
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		printf("[Result] CPU Intercepted! Access Violation (Crash).\n");
	}

	system("pause");
	return 0;
}

实验结果如下所示:
在这里插入图片描述
结论:程序触发异常。因为当前CPL(3) != DPL(0),非一致代码段严格的规则直接在硬件层面拒绝了越权调用。

实验二:跳入Ring 0一致代码段

  1. WinDbg构造段描述符
    我们与实验保持一致,将GDT表的第9个位置修改为Ring 0的一致代码段。如下所示:
kd> eq ffffffff80b99048 00CF9E00`0000FFFF
kd> dg 0x48
                                  P Si Gr Pr Lo
Sel    Base     Limit     Type    l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0048 00000000 ffffffff Code RE    0 Bg Pg P  Nl 00000c9e
  1. 代码实测
    我们只需更改裸函数TargetFunction,在这个裸函数增加只有Ring 0权限才能执行的内核内存读取指令。如下所示:
void __declspec(naked) TargetFunction()
{
    __asm
    {
        mov g_success, 1
        
        // 尝试读取系统内核空间高位地址 (GDT表基址)
        // 如果我们真的提权到了0环,这里代码顺利执行;
        // 如果依然是3环,硬件将触发内存访问违规
        mov eax, dword ptr ds:[0x80b99000] 
        
        retf
    }
}

实验结果如下所示:

在这里插入图片描述

结论:程序触发异常。虽然跳转符合CPL(3) >= DPL(0)成功进入了0环代码段,但一致代码段的特权级保持原则使得当前CPL,所以权限依然为在3环。当我们试图读取Ring 0的内核数据时,被硬件内存保护机制拦截。

内容概要:本文档系统性地介绍了2024年最新提出的两种智能优化算法——青蒿素优化算法与霜冰优化算法(RIME)的原理、实现方法及其性能对比分析,并提供了完整的Matlab代码实现。文档不仅聚焦于核心算法的仿真与验证,还整合了大量前沿科研资源,涵盖微电网优化、风电功率预测、无人机三维路径规划、电动汽车调度、图像融合、负荷预测、通信信号处理、电力系统故障恢复等多个高价值应用场景。所有案例均基于Matlab/Simulink平台进行建模与仿真,强调算法在复杂工程系统中的实际应用能力,旨在为科研人员提供一套从理论到代码再到应用的完整复现体系。; 适合人群:具备一定编程基础和科研背景的研究生、高校教师及工程技术人员,尤其适合从事智能优化算法研究、新能源系统优化、自动化控制、电力系统调度、无人机导航与路径规划等相关领域的研究人员。; 使用场景及目标:①用于高水平学术论文的复现与创新性研究,提升科研效率与成果产出;②应用于复杂工程系统的建模仿真与智能优化设计,如多能互补系统调度、无人机避障路径规划、微电网能量管理等;③作为智能优化算法的教学与学习资料,深入理解现代元启发式算法的设计思想与实现机制。; 阅读建议:建议读者结合文档中提供的Matlab代码与Simulink仿真模型,按照目录结构循序渐进地学习与实践,优先选择与自身研究方向契合的案例进行代码复现,重点关注算法参数设置、收敛曲线分析与多算法对比实验部分,以全面提升算法应用与科研创新能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值