如何在英特尔SGX中注册自定义例外?

时间:2017-03-25 15:48:22

标签: c++ visual-studio sgx

我很难让我的自定义异常处理程序工作。

这是Enclave代码:

#include "Enclave_DivideZero_t.h"
#include "sgx_trts_exception.h"
#include "sgx_trts.h"
#include <string>

static char buf[200] = "Handler not called";

int divide_by_zero_handler(sgx_exception_info_t* info) {

    buf[0] = '1';
    return EXCEPTION_CONTINUE_EXECUTION;
}

void Enclave_DivideByZero() {
    Ocall_printf(buf);
    if (sgx_register_exception_handler(1, divide_by_zero_handler) == NULL) {
        Ocall_printf("register failed");
    } else {
        Ocall_printf("register success");
    }
    int a(1);
    int b(3/(a-a));
    (void) a;
    (void) b;
    Ocall_printf(buf);
}

我们使用buf来指示处理程序是否已实际执行。但是,输出是这样的:

Enclave created!
[Ocall printf] - Handler not called
[Ocall printf] - register success
[Ocall printf] - Handler not called <-- should be: "1andler not called" ("1andler" instead of "Handler")

此外,这里是App代码(即不受信任的代码)

#include "stdafx.h"
#include "sgx_urts.h"
#include "Enclave_DivideZero_u.h"
#define ENCLAVE_FILE _T("Enclave_DivideZero.signed.dll")
sgx_status_t createEnclave(sgx_enclave_id_t *eid) {
    sgx_status_t        ret   = SGX_SUCCESS;
    sgx_launch_token_t  token = {0};
    int                 updated = 0;    
    ret = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, eid, NULL);
    return ret;
}
void Ocall_printf( char* str) {
    printf("[Ocall printf] - %s\n", str);
}
int _tmain(int argc, _TCHAR* argv[]) {
    sgx_enclave_id_t eid;
    sgx_status_t res = createEnclave(&eid);
    if (res != SGX_SUCCESS) {
        printf("App: error-, failed to create enclave.\n");
        return -1;
    } else {
        printf("Enclave created!\n");
    }
    Enclave_DivideByZero(eid);
    return 0;
}

问题:从输出中可以看出,处理程序已成功注册,但未执行。

1-为什么注册不起作用?

2-我尝试使用App代码进行注册,为此我必须在edl中添加处理程序,问题是传递sgx_exception_info_t *info参数,不清楚它需要哪个标志(即[in, .. <'flags'>])。那么,在Enclave中定义它是否正确?

P.S。我用Prerelease模式运行代码。

[编辑] 我记录了我在新加坡交易所进行的项目+代码here

1 个答案:

答案 0 :(得分:0)

所以这个问题现在有点老了,但我卡在了同一个地方,所以也许有人仍然可以使用我的见解。

在 trts_veh.cpp 中,检查异常是否被处理,它在注释中说“将再次执行触发异常的指令”。正如您自己注意到的那样,这会导致异常处理循环。

但是,您可以自己增加 rip,因为它存储在指向 sgx_exception_info_t 的指针中,通过使用“info->cpu_context.rip += 2;”。将它添加到您的异常处理程序中应该可以解决问题。