这是我的代码,靠flush+reload来读取secret,但是输出一直都是array2[0],这是为什么
#include <cstdint>
#include <cstring>
#include <iostream>
#include <x86intrin.h>
using namespace std;
class Exp1 {
public:
unsigned int junk = 0;
uint8_t array2[4096 * 256]{}; // 用于存储不同字符的数组
uint8_t array3[256]{}; // 结果存储数组
uint64_t CACHE_HIT_THRESHOLD = 80; // 缓存命中阈值
const char *secret = "exp1{flush_reload_attack}"; // 要读取的秘密
// 用于计算 CACHE_HIT_THRESHOLD 的方法
void cal_threshold() {
uint64_t sum_hit = 0;
uint64_t sum_miss = 0;
uint64_t time;
//volatile uint8_t *addr;
// 计算缓未存命中时间
// addr = &array3[0];
for (int i = 0; i < 1000; i++) {
_mm_mfence();
_mm_lfence();
_mm_clflush(&array3[0]); // Flush 缓存
_mm_mfence();
_mm_lfence();
uint64_t start = __rdtscp(&junk); // 开始计时
_mm_lfence();
junk = array3[0];
_mm_lfence(); // 访问地址
uint64_t end = __rdtscp(&junk); // 结束计时
sum_miss += (end - start);
}
// 计算缓存命中时间
for (int i = 0; i < 1000; i++) {
_mm_mfence();
_mm_lfence();
uint64_t start = __rdtscp(&junk); // 开始计时
_mm_lfence();
junk = array3[0]; // 访问地址
_mm_lfence();
uint64_t end = __rdtscp(&junk); // 结束计时
sum_hit += (end - start);
}
// 平均时间计算
uint64_t avg_miss = sum_miss / 1000;
uint64_t avg_hit = sum_hit / 1000;
cout << "sum_miss: " << avg_miss << endl;
cout << "sum_hit: " << avg_hit << endl;
// 设定阈值
CACHE_HIT_THRESHOLD = (2*avg_hit + avg_miss) / 3;
// CACHE_HIT_THRESHOLD = avg_hit;
cout << "Calculated CACHE_HIT_THRESHOLD: " << CACHE_HIT_THRESHOLD << endl;
}
// 读取一个字节的内存值
void readMemoryByte(int malicious_x, uint8_t &value, int &score) {
int count = 1000;
int results[256] = {0}; // 统计每个字节的计数
// 预加载一个与攻击无关的数据地址
volatile uint8_t temp = 0;
for (int i = 0; i < 256; i++) {
_mm_mfence();
_mm_lfence();
_mm_clflush(&array3[i]); // 清除无关数据
}
for (int t = 0; t < count; t++) {
// 1. Flush 所有的 array2 缓存
for (int i = 0; i < 256; i++) {
_mm_mfence();
_mm_lfence();
_mm_clflush(&array2[i * 4096]);
}
// 访问一些不相关的内存地址
temp ^= array3[0];
// 2. Encode: 依据秘密信息访问 array2
_mm_mfence();
junk &= array2[secret[malicious_x] * 4096]; // 利用 secret 进行访问
_mm_mfence();
// 3. Reload: 通过访问时间判断哪个 array2 的位置在缓存中
for (int i = 0; i < 256; i++) {
_mm_mfence();
_mm_lfence();
uint64_t start = __rdtscp(&junk); // 计时开始
_mm_lfence();
junk = array2[i * 4096]; // 访问 array2
_mm_lfence();
uint64_t end = __rdtscp(&junk); // 计时结束
// 如果访问时间小于阈值,则认为该位置在缓存中
if ((end - start) < CACHE_HIT_THRESHOLD) {
results[i]++;
}
}
}
// 找出出现次数最多的字节
int max = -1;
int max_idx = -1;
for (int i = 0; i < 256; i++) {
if (results[i] > max) {
max = results[i];
max_idx = i; // 猜测的字节值
}
}
value = max_idx; // 将最有可能的字节值赋给 value
score = max; // 将命中次数赋给 score
}
// 构造函数:逐字节读取 secret
Exp1() {
int len = 0;
int score = 0;
uint8_t value = 0;
// 计算缓存命中和未命中的阈值
cal_threshold();
// 逐字节读取 secret
while (len < (int)strlen(secret)) {
readMemoryByte(len, value, score);
cout << "Reading secret value at secret[" << len << "] = " << value
<< " with a score of " << score << endl;
len++;
}
}
};
int main() {
Exp1 exp; // 实例化类,执行攻击
return 0;
}
相似问题