首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C用于侧通道攻击的定时内存访问

C用于侧通道攻击的定时内存访问
EN

Stack Overflow用户
提问于 2014-05-20 22:50:03
回答 1查看 379关注 0票数 1

我正在上密码学课程,我要做一个关于侧通道攻击的报告。因此,我正在尝试自己实现一个。

我特别想跟踪本论文。然而,我在这样一个低层次的编程中遇到了一些问题。

我编写了一个简短的C程序来计时对变量的访问,以确定它是否已被访问(虽然在本例中,我是访问它的人,所以我知道前面的答案)。重点是将其概括为知道某个其他进程何时达到某种特定状态。

基本上,它通过10k的迭代来运行,并且在每一次概率为1/10的迭代中,都会访问一个指针。在每次迭代中,都会注册处理器访问指针所需的时间,然后将指针从缓存中清除出去。这些值被打印到文件中。

下面是我编写的代码(组装部分实际上来自我引用的文件):

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>

int probe(char *adrs) {
    volatile unsigned long time;

    asm __volatile__ (
            " mfence \n"
            " lfence \n"
            " rdtsc \n"
            " lfence \n"
            " movl %%eax, %%esi \n"
            " movl (%1), %%eax \n"
            " lfence \n"
            " rdtsc \n"
            " subl %%esi, %%eax \n"
            " clflush 0(%1) \n"
            : "=a" (time)
            : "c" (adrs)
            : "%esi", "%edx");
    return time;
}

void myfunc(void* buffer[]) {
    int nptrs;

    nptrs = backtrace(buffer, 10);
}

int main(int argc, char** argv) {
    srand(time(NULL));

    int r = rand(), i;
    struct timespec tim, tim2;
    tim.tv_sec = 0;
    tim.tv_nsec = 5000L;
    void* buffer[10];
    char letter = 'c';
    char* p = &letter;

    FILE *f = fopen("output.txt","w");
    if(f == NULL) printf("Error opening file!\n");

    myfunc(buffer);
    for(i=0; i < 10000; i++) {
        r = rand();
        nanosleep(&tim,&tim2);
        if(r%10 == 3) { // 3 is completely arbitrary; could be any value really
            myfunc(buffer);
            printf("%c ",letter);
        }
        fprintf(f,"%d,%d,%d\n", r%10 == 3, probe(buffer[0]),probe(p)); // print the timings to file, and whether the variable was accessed or not
    }

    return 0;
}

现在我的问题是:如果r% 10 == 3的话,这应该写到一个文件"1,x,y“中,如果r%10,x,y,而大x和y是"0,x,y”。我尝试在运行Debian (32位和64位)的两种不同的VM中运行,这两个VM都是用gcc 4.7.2编译的(只使用-g标记),我得到了不同的结果,没有一个是我想要的。

在32位VM中,“探测(缓冲区)”似乎有点工作,尽管并不总是这样。但是“探测(P)”总是返回低值(这给我绝对没有任何信息)。以下是输出的相关部分(完整的输出可用这里):

代码语言:javascript
复制
0,250,48
1,33,54
0,74,33
1,36,33
0,61,33
0,92,33
0,48,62
0,405,33

在64位VM中,这两个值几乎都在4000以上,与访问的指针无关。另一个相关的部分(以及完整的输出这里):

代码语言:javascript
复制
1,4341,4371
0,4320,4341
0,4495,4320

所以我的问题是:

  • 在32位VM中,为什么char*总是非常快访问?(“空”与“炭”不同吗?或者是其他原因)
  • 为何越南船民有不同的结果?
  • 在64位VM中,为什么这两个值都在4000左右?
EN

回答 1

Stack Overflow用户

发布于 2014-06-27 14:29:33

这是一个很有趣的问题。

char*和void*之间不应该有区别,唯一的区别是指针算法。然而,我认为,在32位到64位的时间里,你所看到的差异是由于架构的改变。64位在访问内存方面通常比32位慢,但是由于有更多的寄存器,它们通常不必访问内存那么多。以下是64位架构信息的链接,以及与32位结构的区别。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23771265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档