Intel x86_64 LBR & BTS功能

前言

上一篇讲述Intel CPUID指令介绍后,这篇来介绍Intel LBR & BTS 功能
Intel CPUID指令介绍

最近学习了intel x86_64 & ADM64 处理器的LBR(Last branch record)功能(记录分支跳转指令),简单来说就是记录CPU产出的跳转指令:包括call、ret、jmp、jxx(间接跳转)、中断、异常。利用这个功能,就可以保存每个分支跳转指令的起始地址和目的地址。这样就可以了解到当前CPU执行代码的流程情况。

举一个简单的例子jmp指令:

4004d3: eb 03    jmp 4004d8
当执行下面这条jmp指令时,那么将产生一个 from 4004d3 to 4004d8的跳转,那么产生的LBR记录项就是
{ From:4004d3 ,To:4004d8 } /* jmp指令 */

再举一个简单的例子关于call ,ret 指令:

int add(int a, int b)
{
	return (a+b);
}
 
int main(void)
{
	return add(1,2);
}
上述两个函数将会产生两条LBR记录项:
{From : main , to : add} /* call 指令*/
{From : add , to : main} /* ret 指令*/

在二进制安全中,有很多攻击都是hook控制流,比如隐藏进程,隐藏文件,隐藏tcp,提权等等,使正在运行的系统按照攻击者的流程运行下去,这样就和系统正常的控制转移过程将会不一样,比如在Linux系统上,由于攻击者hook掉一些函数,当用户使用ls、top、ps、netstat等命令时,那么将会过滤掉一些进程,文件,tcp连接等等,那么攻击者就会利用到这些进程、文件、tcp连接等,对系统危害极大。

CPU当前正在产生的分支、中断和异常等跳转指令不但对于调试,跟踪代码有用,同时也提供一种方法来确定系统当前运行中的控制转移过程。我们根据这些跳转指令便能够分析出系统是否被攻击了。

备注:
分支跳转可以分成了两类,第一类是向前跳转,即call、jmp类型指令,第二类是后向跳转,也就是ret型指令。劫持控制流就是控制RIP指针,而RIP指针只能通过上述的两类指令进行修改,所以控制流劫持的攻击手段也都是针对于这些指令做文章。

在 x86_64 架构中,RIP 寄存器是指令指针寄存器(Instruction Pointer Register)的缩写,它存储了当前正在执行的指令的内存地址。当 CPU 执行一条指令时,它会将 RIP 设置为下一条指令的地址,以便在执行完当前指令后继续执行下一条指令。

在安全领域中,RIP 寄存器通常用于执行代码注入和ROP攻击(Return-oriented Programming,基于返回的编程攻击)等漏洞利用技术。

代码注入是一种攻击技术,攻击者通过将恶意代码注入到目标进程的内存中,从而实现对目标进程的控制。攻击者可以使用 RIP 寄存器来控制代码的执行流程,以便跳转到注入的恶意代码。

ROP攻击是一种利用现有代码段中的代码片段来构造恶意代码执行路径的攻击技术。攻击者可以使用 RIP 寄存器来控制代码执行的流程,以便跳转到目标地址并执行恶意代码。

一、DEBUGCTL MSR

1.1 MSR寄存器简介

MSR(Model Specific Register)是x86架构中的概念,指的是在x86架构处理器中,一系列用于控制CPU运行、功能开关、调试、跟踪程序执行、监测CPU性能等方面的寄存器。
不同的CPU型号或不同的CPU厂商(Intel&AMD),它的MSR寄存器可能是不一样的,它会根据具体的CPU型号的变化而变化,每款新的CPU都有可能引入新的MSR寄存器。

Intel提供了RDMSR,WRMSR这两条指令,通过调用这两条指令来读取,写入相应的 MSR寄存器的值。
这两条指令必须在 privilege level 0(linux中的内核态)或实模式下执行:
在这里插入图片描述
在这里插入图片描述
linux 内核提供了两个接口,位于arch/x86/include/asm/msr.h文件中:
rdmsrl(msr, val)
wrmsrl(msr, val)
有关MSR寄存器的介绍可以参考intel vol4 chapter2,Intel vol4都是在描述MSR寄存器。

1.2 IA32_DEBUGCTL MSR 寄存器

IA32_DEBUGCTL 寄存器其地址为 01D9H(不同的CPU family名字可能会不一样,比如MSR_DEBUGCTLA, MSR_DEBUGCTLB),可以用来调试,跟踪中断、LBR、BTS等等。
下面介绍几个较重要的位:
(1)bit0: LBR (last branch/interrupt/exception) flag 。该位被设置后,处理器开始记录跟踪
处理器产生的最近的分支、中断和/或异常,并储存在 LBR stack MSRs中。
(2)bit1: BTF (single-step on branches) flag 。该位被设置后,处理器将EFLAGS寄存器中的TF标志视为:TF as single-step on branches instead of single-step on instructions。(x86_64的gdb单步调试功能就是用EFLAGS寄存器中的TF位—single-step on instructions 来实现的,后面会写一篇x86_64的gdb单步调试跟踪原理的文章)
(3)bit6: TR (trace message enable) flag。该位被设置后,当处理器检测到一个已经产生的分支,中断,或异常;它将这个分支记录作为 branch trace message(BTM)发送到系统总线上。
(4)bit7: BTS (branch trace store) flag。该位被设置后,BTS能够将BTMS保存到DS save area的内存驻留BTS buffer中。
(5)bit8: BTINT (branch trace interrupt) flag。该位被设置后,当BTS缓冲区满时,BTS会产生一个中断。
(6)bit9: BTS_OFF_OS (branch trace off in privileged code) flag。该位被设置后,如果CPL为0,则跳过BTS或BTM,即:在内核态不启用bts功能。
(7)bit10:BTS_OFF_USR (branch trace off in user code) flag。该位被设置后,如果CPL大于0,则跳过BTS或BTM。即:在用户态不启用bts功能。

因此可以通过这两bit BTS_OFF_OS/BTS_OFF_USR 来设置是获取用户态的分支跳转指令还是内核态的分支跳转指令。

CPL:Current Privilege Level,该值为0代表最高优先级,该值为3代表最低优先级,linux 中,0为内核态,3为用户态。

1.3 LBR

前面已经说过, IA32_DEBUGCTL MSR 寄存器的bit0被设置后,处理器开始自动记录 产生的分支,中断,异常等branch records,并存储在 LBR stack MSRs中。下面来介绍下 LBR stack与 TOS Pointer
(1)Last Branch Record (LBR) Stack :LBR由N对msr寄存器组成(N是LBR堆栈大小,如下表所示),msr存储了最近分支的源地址和目的地址。
(2)Last Branch Record Top-of-Stack (TOS) Pointer:TOS Pointer MSR中最低有效的M位包含了一个指向LBR堆栈中MSR的M位指针,该指针包含了记录的最近的分支、中断或异常。

在使用LBR stack记录分支信息时,TOS寄存器指示stack当前位置. 从而可以从LBR stack中正确读取分支记录.

从下表可以看出,LBR堆栈中msr的个数和TOS指针值的有效范围对于不同的处理器家族中会有所不同。
在这里插入图片描述
LBR msr是64位的寄存器。在64位模式下, last branch records存储完整地址。32位模式下,高32位置0,低32为存储最近分支记录。
MSR_LASTBRANCH_0_FROM_IP — (N-1) MSR address 存储分支记录源地址
MSR_LASTBRANCH_0_TO_IP — (N-1) MSR address 存储分支记录目的地址
在这里插入图片描述
LBR的简单使用:
(1)查询LBR stack存储格式 :IA32_PERF_CAPABILITIES MSR (调用rdmsrl)
在这里插入图片描述
(2)开启LBR功能,设置 IA32_DEBUGCTL MSR寄存的 bit0 = 1 (调用wrmsrl)
在这里插入图片描述
(3) 读取TOS指针位置 (调用rdmsrl)
读取 MSR_LASTBRANCH_TOS 寄存器 ,请参考 Intel vol4
(4) 读取LBR stack寄存器 (调用rdmsrl)
读取 MSR_LASTBRANCH_x_FROM_IP / MSR_LASTBRANCH_x_TO_IP 寄存器 ,请参考 Intel vol4

LBR的优点:分支记录存储在寄存器中,几乎没有性能开销。
LBR的缺点:寄存器组数量有限,这样我们保存的分支记录也有限。

1.4 BTS

上面提到LBR获取的分支、中断和异常的记录,会保存在LBR Stack MSR中。通过设置TR标志将这些记录作为BTMS发送到系统总线上。BTS机制提供了一个额外功能可以将分支记录保存在 memory-resident BTS 缓冲区中,该缓冲区是DS save area的一部分。(BTMS:当处理器检测到一个分支、异常或中断时,它在系统总线上发送一个分支记录作为BTM。监视系统总线的调试设备可以读取这些消息。)

BTS的优点:用系统DRAM来存储更多的指令和事件,仅受目标系统上的内存量限制。
LBR的缺点:由于用内存存储消息,性能开销较大。

1.5 PEBS

PEBS,全称Processor Event Based Sampling(也可以叫Precise Event-Based Sampling),详细介绍可参考Intel vol3 19.6.2.4 小节。主要用来性能监控(Performance monitoring),使用调试存储机制和性能监视中断来存储处理器的一组体系结构状态信息(8个通用寄存器、EIP寄存器和EFLAGS寄存器的状态),该信息提供了在导致 event 的指令之后执行的指令的体系结构状态。

这里简单介绍下perf ,perf是一款Linux性能分析工具。通过perf,应用程序可以利用PMU、tracepoint和内核中的计数器来进行性能统计。它不但可以分析制定应用程序的性能问题(per thread),也可以用来分析内核的性能问题。

event是perf工作的基础,perf提供两种工作模式:采样模式(sampling)和计数模式(count)。

skid问题:当perf工作在采样模式(sampling)时,由于采样事件发生时和实际处理采样事件之间有时间上的delay,以及CPU流水线和乱序执行等因素,所以得到的指令地址IP(Instruction Pointer)并不是当时产生采样事件的IP。为了改善这种状况,使IP值更加准确,Intel使用PEBS(Processor Event-Based Sampling),而AMD则使用IBS(Instruction-Based Sampling)。

the skids的问题可以通过处理器本身将指令指针(以及其他信息)存储在内存中指定的缓冲区中来缓解,这需要硬件的支持。以PEBS为例:每次采样事件发生时,会先把采样数据存到一个缓冲区中(PEBS buffer),当缓冲区内容达到某一值时,再一次性处理,这样可以很好地解决skid问题。

使用PEBS的好处:
解决The skid 问题。
减少开销,因为Linux内核只在PEBS缓冲区被填满时才会涉及到,也就是说,直到有大量的样本可用时才会有中断。

总结:
PEBS is a feature of the PMU. PEBS is an extension of “sampling”.
在采集样本时,PMU将会收集更多的信息。例如,精确的指令计数器、寄存器或标志将被记录下来。

二、BTS and DS Save Area

2.1 Debug store (DS)

调用CPUID函数后,如果寄存器edx的第21位是1,表示处理器提供调试存储(DS)机制。
关于CPUID指令请参考我的这篇博客:Intel cpuid指令介绍
代码如下:

	//the processor provides the debug store (DS) mechanism
	#define DS_IS_SUPPORT (1<<21)
	
	unsigned int eax = 0;
	unsigned int ebx = 0;
	unsigned int ecx = 0;
	unsigned int edx = 0;
	
	cpuid(1, &eax, &ebx, &ecx, &edx);
	if(!(edx & DS_IS_SUPPORT)) {
		printk("Don't support DS buffer feature\n");
		return 0;
	}

The DS mechanism allows:
(1)BTMs将被保存在 memory-resident BTS buffer中。
(2)Processor event-based sampling (PEBS)也使用了DS save area提供的调试存储机制。PEBS的性能因微架构的不同而不同(PEBS主要用于处理器的性能监控)。
When CPUID.1:EDX[21] is set:
(3)IA32_MISC_ENABLE MSR 的 BTS_UNAVAILABLE标志位 和 PEBS_UNAVAILABLE 标志位 表示是否支持BTS和PEBS。

IA32_MISC_ENABLE 是一个 MSR 寄存器 ,其地址是1A0H (参考intel 手册 vol4 chapter2)
在这里插入图片描述
可以在内核模块用 rdmsrl 指令查看处理器是否支持BTS和PEBS。


	#define MSR_MISC_ENABLE       	(0x1A0)
	#define MISC_BTS_UNAVAILABLE  	(1<<11)
	#define MISC_PEBS_UNAVAILABLE 	(1<<12)
	
	unsigned long long val_bts = 0 ;
	
	rdmsrl(MSR_MISC_ENABLE, val_bts);
	if(val_bts & MISC_BTS_UNAVAILABLE) {
		printk("Don't support BTS\n");
		return 0;
	}
	
	
	unsigned long long val_pebs = 0 ;
	
	rdmsrl(MSR_MISC_ENABLE, val_pebs);
	if(val_pebs & MISC_PEBS_UNAVAILABLE) {
		printk("Don't support PEBS\n");
		return 0;
	}

(4)IA32_DS_AREA MSR存在并指向 DS save area。

The debug store (DS) save area 是一个软件指定的内存区域,用于收集以下两种类型的信息:
(1)Branch records:当IA32_DEBUGCTL MSR寄存器设置了BTS标志后,每当检测到发生分支、中断或异常时,分支记录被存储在 DS save area的BTS缓冲区中。
(2)PEBS records:当为PEBS配置性能计数器时,在计数器发生溢出后,PEBS记录存储在DS保存区中的PEBS缓冲区中。该记录包含下一次导致计数器溢出的PEBS事件发生时处理器的体系结构状态(8个通用寄存器、EIP寄存器和EFLAGS寄存器的状态)。当记录状态信息时,计数器将自动重置为指定值,事件计数将再次开始。

The DS save area分为三个部分:buffer management area, BTS(branch trace store ) buffer, and PEBS(Processor event-based sampling) buffer。如下图所示:
在这里插入图片描述

2.2 buffer management area

用于定义BTS和PEBS的位置和大小缓冲区。其线性地址由IA32_DS_AREA MSR寄存器指定。
BTS buffer base:BTS缓冲区起始的线性地址(intel手册中很少看见虚拟地址,一般都是用线性地址表示)。
BTS index:CPU当前要写入的BTS记录的线性地址。刚开始时,BTS index就是指向BTS buffer base。
BTS absolute maximum:BTS缓冲区结束的线性地址。
BTS interrupt threshold:产生一个中断的BTS记录的线性地址,该地址必须指向BTS缓冲区基的偏移量,该偏移量是BTS记录 大小的倍数。此外,它必须有几个记录短于BTS绝对最大地址,以允许在处理器写入BTS绝对最大记录之前处理一个挂起中断。
简单来说:当BTS index=BTS interrupt threshold时,会产生中断,用于通知从BTS内存区读取分支信息。
(备注:CPU需要知道这块内存的起始地址、结束地址、以及当记录到第几个记录时候需要触发一个中断程序来负责将现有的BTS记录保存下来防止内存溢出)
在这里插入图片描述

PEBS buffer base:PEBS 缓冲区起始的线性地址。
PEBS index:CPU当前要写入的PEBS记录的线性地址。刚开始时, PEBS index就是指向 PEBS buffer base。
PEBS absolute maximum:PEBS 缓冲区结束的线性地址。
PEBS interrupt threshold:类似于BTS interrupt threshold。
PEBS counter reset value:当一个PEBS记录要写时要设置一个64位的计数器。此值允许在每次发生指定数量的事件时定期收集状态信息。

2.3 BTS buffer

Branch records:当IA32_DEBUGCTL MSR寄存器设置了BTS标志后,每当检测到发生分支、中断或异常时,分支记录被存储在 DS save area的BTS缓冲区中。
每条 Branch record记录如下图所示:
Last branch from:产生的分支、中断或异常指令的线性地址(分支指令的from地址)。
Last branch to :分支目标的线性地址中断或异常服务程序中的第一条指令地址分支指令的to地址)。
下图为每条分支记录的格式:
在这里插入图片描述

2.4 PEBS buffer

PEBS records:当为PEBS配置性能计数器后,在计数器发生溢出后(计数器从最大计数溢出到零时),PEBS硬件被激活。PEBS记录存储在DS保存区中的PEBS缓冲区中。该记录包含下一次导致计数器溢出的PEBS事件发生时处理器的体系结构状态(8个通用寄存器、EIP寄存器和EFLAGS寄存器的状态)。当记录状态信息时,计数器将自动重置为指定值,事件计数将再次开始。
这些寄存器的值是那些引起event的指令开始的值。
下图为每条PEBS记录的格式:
在这里插入图片描述
当计数器溢出时,CPU中断到固件中,固件又将计数器复制到PEBS缓冲区记录中。下图显示了每个记录的间接级别和内容:
在这里插入图片描述

2.5 Setting Up the DS Save Area

要用BTS缓冲区保存分支记录,必须首先在内存中设置DS保存区,如下面的步骤所述
(1) 在内存中创建DS缓冲区管理信息区域。
(2)将DS缓冲区管理区域的基本线性地址写入IA32_DS_AREA MSR中。
(3)在xAPIC(Advanced Programmable Interrupt Controller) LVT( local vector table)中设置性能 计数器条目。(有关APIC 和 LVT请参考 Intel vol3 chapter10)
(4)在IDT(Interrupt Descriptor Table)中为步骤3 设置的 性能计数器条目对应的向量建立一个中断处理程序。
(5)编写一个用来处理BTS溢出操作的中断服务程序。参考2.8节。

简单来说就是创建一个DS缓冲区,并将其地址写入一个MSR寄存器中,当BTS记录项接近溢出时,就会通过在 APCI LVT设置的性能计数器条目中存储的中断向量值去触发对应的中断程序,进而来处理内存溢出。
在这里插入图片描述

2.6 Setting Up the BTS Buffer

IA32_DEBUGCTL中的三个标志位用来控制分支记录的生成,并将它们存储在BTS缓冲区中。分别是TR、BTS和BTINT。
(1)TR标志用来生成BTMS。
(2)BTS标志确定btm是在系统总线上发送还是存储在BTS缓冲区。BTS不能同时发送到系统总线,又记录在BTS缓冲区中。
(3)BTINT标志允许在BTS缓冲区满时产生中断。
在这里插入图片描述

2.7 Setting Up CPL-Qualified BTS

如果处理器支持 CPL-qualified 上次分支记录机制,则分支记录的生成和存储分支记录在BTS缓冲区中由TR、BTS、BTS_OFF_OS、BTS_OFF_USR和BTINT决定。
在这里插入图片描述

2.8 Writing the DS Interrupt Service Routine

(PS:这一节完全按照intel 手册来翻译的,感觉翻译得很烂,将就看吧)
BTS 和 PEBS 共享相同的中断向量和中断服务程序(称为调试存储中断服务程序或DS ISR)。要处理BTS和PEBS中断:DS ISR中必须包含独立的处理程序例程。在编写DS ISR来处理BTS、PEBS中断时,请使用以下指导原则:
(1)DS中断服务程序(ISR)必须是内核驱动程序的一部分,并在当前的特权级别0上操作,以确保缓冲区存储区域的安全。
(2)由于BTS和PEBS共享相同的中断向量,DS ISR必须检查来自这些工具的所有可能的中断原因,并将控制权传递给适当的处理程序。
如果缓冲区索引匹配/超过指定的中断阈值,BTS和PEBS缓冲区溢出将是中断的来源。
(3)MP(Multiprocessor)系统中的每个处理器都必须有独立的保存区域、缓冲区和状态。
(4)在进入ISR后,应该禁用 branch trace messages and PEBS,以防止在访问DS保存区域期间出现竞争情况。这可以通过清除IA32_DEBUGCTL中的TR标志和MSR_PEBS_ENABLE MSR中的 precise event启用标志来实现。当退出ISR时,这些设置应该恢复到它们的原始值。
(5)当缓冲区已满且未选择循环模式时,处理器不会禁用 DS save area。在退出时,ISR必须保留并恢复当前DS设置。
(6)在读取到适当缓冲区中的数据后,直到当前索引进入缓冲区,但不包括当前索引,ISR必须将缓冲区索引重置到缓冲区的开头。否则,索引之前的所有内容在下一次ISR调用时看起来都像是新的条目。
(7)ISR必须清除性能计数器 LVT entry中的掩码位。
(8)如果ISR正在处理由于PEBS而溢出的PMI(performance monitoring interrupt),那么ISR必须重新启用计数器通过IA32_PERF_GLOBAL_CTRL 、IA32_PERF_GLOBAL_OVF_CTRL计数。

三、LBR & BTS功能简介

3.1 LBR简介

LBR (Last Branch Record) 是一项由 Intel 开发的 x86_64 处理器特性,它可以用于硬件级别的分支跟踪,有助于调试和性能分析。与BTS特性不同,LBR特性记录最近的分支跳转信息,而非所有分支跳转信息。这些信息可以用于分析程序的执行路径,查找性能瓶颈和调试问题。

LBR 特性包含了以下几个组件:
(1)LBR Stack: 一个可配置的堆栈,用于存储最近的分支跳转信息。LBR Stack 的大小可以根据需要进行配置,通常可以存储数十到数百条分支跳转信息。

(2)LBR Control Register: 一个特殊的控制寄存器,用于配置 LBR 特性。通过设置控制寄存器的值,可以启用或禁用 LBR,配置 LBR Stack 的大小和地址,以及设置其他 LBR 相关的参数。

(3)LBR Interrupts: LBR 特性可以生成中断,通知操作系统或调试器有新的分支跳转信息可用。可以通过设置中断描述符表 (IDT) 来处理这些中断。

使用 LBR 特性需要一定的硬件和软件支持。硬件方面,需要支持 Intel 64 架构的处理器,并且需要支持 LBR 特性。软件方面,需要支持 LBR 特性的调试器或性能分析工具,并且需要在操作系统内核中设置相应的中断描述符表和处理程序。

LBR (Last Branch Record) 特性是一项先进的硬件级别分支跟踪技术,用于记录最近的分支跳转信息。与BTS特性不同,LBR特性仅记录最近的分支跳转信息,而不是所有分支跳转信息。这使得LBR特性的开销比BTS特性更小,同时可以提供足够的信息来帮助分析程序的执行路径和性能瓶颈。

LBR 特性有几个特点:

(1)精度高:LBR特性记录的是最近的分支跳转信息,可以提供非常精确的分支跳转信息,用于分析程序的执行路径和性能瓶颈。

(2)低开销:与BTS特性相比,LBR特性的开销更小,因为它只记录最近的分支跳转信息。这使得LBR特性更适合在生产环境中使用。

(3)高灵活性:LBR特性可以通过设置不同的参数来满足不同的需求,例如可以配置LBR Stack的大小、地址和模式等。

3.2 BTS简介

BTS (Branch Trace Store) 是一项由 Intel 开发的 x86_64 处理器特性,用于硬件级别的分支跟踪,有助于调试和性能分析。BTS特性可以提供非常详细的分支跳转信息,包括跳转的源地址和目标地址。这些信息可以用于分析程序的执行路径和性能瓶颈。

BTS 特性包含以下几个组件:

(1)BTS Buffer: 一个可配置的缓冲区,用于存储程序的分支跳转信息。BTS Buffer 的大小可以根据需要进行配置,通常可以存储数百到数千条分支跳转信息。

(2)BTS Control Register: 一个特殊的控制寄存器,用于配置 BTS 特性。通过设置控制寄存器的值,可以启用或禁用 BTS,配置 BTS Buffer 的大小和地址,以及设置其他 BTS 相关的参数。

(3)BTS Interrupts: BTS 特性可以生成中断,通知操作系统或调试器有新的分支跳转信息可用。可以通过设置中断描述符表 (IDT) 来处理这些中断。

BTS 特性有几个特点:

(1)完整性:BTS特性记录的是所有的分支跳转信息,可以提供非常详细的分支跳转信息,用于分析程序的执行路径和性能瓶颈。

(2)灵活性:BTS特性可以通过设置不同的参数来满足不同的需求,例如可以配置BTS Buffer的大小、地址和模式等。

(3)中断支持:BTS特性可以生成中断,通知操作系统或调试器有新的分支跳转信息可用。可以通过设置中断描述符表 (IDT) 来处理这些中断。

使用 BTS 特性需要一定的硬件和软件支持。硬件方面,需要支持Intel 64架构的处理器,并且需要支持BTS特性。软件方面,需要支持BTS特性的调试器或性能分析工具,并且需要在操作系统内核中设置相应的中断描述符表和处理程序。

一些支持BTS特性的调试器或性能分析工具包括Intel VTune Profiler、gdb调试器、Perf工具等。这些工具可以使用BTS特性来记录程序的分支跳转信息,并帮助分析程序的执行路径和性能瓶颈。在调试和优化应用程序时,BTS特性是一个非常有用的工具,可以提供有关程序执行的深入洞察。

需要注意的是,由于BTS特性记录的是所有的分支跳转信息,因此它会产生大量的数据,可能会对系统性能造成一定的影响。为了避免这种问题,可以选择记录特定的模块或函数的分支跳转信息,或者使用其他分支跟踪技术,例如LBR特性。

3.3 两者的对比

LBR (Last Branch Record) 和 BTS (Branch Trace Store) 都是 x86_64 处理器的硬件级别分支跟踪技术,用于记录程序的分支跳转信息,以帮助分析程序的执行路径和性能瓶颈。它们具有一些相似之处,但也有一些不同之处。

以下是LBR和BTS之间的主要差异:
(1)记录方式:LBR特性记录的是最近的分支跳转信息,而BTS特性记录的是所有的分支跳转信息。因此,LBR特性可以提供更高的精度和更低的开销,但是BTS特性可以提供更完整的跟踪信息。

(2)存储方式:LBR特性使用一个堆栈来存储最近的分支跳转信息,而BTS特性使用一个缓冲区来存储所有的分支跳转信息。因此,LBR特性可以提供更快的访问速度和更小的存储开销,但是BTS特性可以存储更多的分支跳转信息。

(3)功能和配置:LBR特性的功能和配置比BTS特性简单。LBR特性只需要设置LBR控制寄存器和LBR堆栈的大小等少量参数即可使用。而BTS特性则需要更多的参数设置,包括BTS控制寄存器、BTS缓冲区的大小和地址等。

(4)软件支持:虽然LBR和BTS都是硬件级别的分支跟踪技术,但是它们需要不同的软件支持。许多调试器和性能分析工具支持LBR和BTS特性,但是它们需要不同的配置和处理程序。

总结

这篇文章主要介绍了intel 处理器的LBR和BTS的功能和使用。可以利用它们来进行安全领域的对抗,比如:当启用cpu分支跳转记录功能后,将产生的跳转指令收集保存起来,然后与操作系统的text段中的跳转指令进行对比,如果当前CPU产生的跳转指令不在操作系统的text段的跳转指令中,则有可能系统被黑客攻击了(系统被hook后,系统的控制转移将会发生改变,与正常情况的跳转过程将会不一样)。

我以ls命令,ext2文件系统为例子,展示隐藏文件的过程(ext4文件系统函数名会稍有变化,大家有兴趣的可以自己去翻阅源码)。
在这里插入图片描述

参考资料

https://blog.csdn.net/bin_linux96/article/details/104236808
https://nanxiao.me/perf-note-2/
https://stackoverflow.com/questions/14670586/what-is-the-overhead-of-using-intel-last-branch-record
https://bbs.csdn.net/topics/390084569
https://www.asset-intertech.com/resources/blog/2013/11/what-are-intel-lbr-bts-and-aet/
https://www.cnblogs.com/hetianlab/p/15214819.html
https://perf.wiki.kernel.org/index.php/Nehalem

linux内核源码 3.10.0
Intel官方手册 vol2
Intel官方手册 vol3
Intel官方手册 vol4

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值