对于不了解Linux的人们,sigalstack
用于创建备用堆栈,您可以阅读有关更多内容here。但是,基本思想可以总结如下:
分配用于备用信号的内存区域 堆栈。
使用sigaltstack()
通知系统存在和存在
备用信号堆栈的位置。
使用sigaction(2)建立信号处理程序时,通知
信号处理程序应在备用系统上执行的系统
通过指定SA_ONSTACK
标志来表示信号栈。
我基本上是用这种方式来测试内存清零功能的。
#ifndef _WIN32
#define MEMZERO_STACK_SIZE (SIGSTKSZ + sizeof(secret))
#else
#define MEMZERO_STACK_SIZE sizeof(secret) // Maybe we need to add something here?!
#endif
// The secret that we write out to the stack.
static const char secret[24] = {
0x4e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x67, 0x6f,
0x6e, 0x6e, 0x61, 0x20, 0x67, 0x69, 0x76, 0x65,
0x20, 0x79, 0x6f, 0x75, 0x20, 0x75, 0x70, 0x2c,
};
static char stack_buf[MEMZERO_STACK_SIZE];
#ifndef _WIN32
// Verify that we are on the custom stack.
static void assert_on_stack(void) {
stack_t current_stack;
assert(0 == sigaltstack(NULL, ¤t_stack));
assert(SS_ONSTACK == (current_stack.ss_flags & SS_ONSTACK));
}
// Call the provided signal handler on a custom stack.
static void call_on_stack(void (*fn)(int)) {
const stack_t stack = {
.ss_sp = stack_buf,
.ss_size = sizeof(stack_buf),
};
const struct sigaction action = {
.sa_handler = fn,
.sa_flags = SA_ONSTACK,
};
stack_t old_stack;
struct sigaction old_action;
// Setup the stack and signal handler.
assert(0 == sigaltstack(&stack, &old_stack));
assert(0 == sigaction(SIGUSR1, &action, &old_action));
// Raise a signal. This will only return after the signal handler has returned.
assert(0 == raise(SIGUSR1));
// Restore the previous state, disable our alt stack.
sigaction(SIGUSR1, &old_action, NULL);
sigaltstack(&old_stack, NULL);
}
#endif
static char *memzero_test() {
char buf[sizeof(secret)];
char *result;
assert_on_stack();
memcpy(buf, secret, sizeof(secret));
result = memmem(stack_buf, MEMZERO_STACK_SIZE, buf, sizeof(buf));
memset(buf, 0, sizeof(buf));
return result;
}
static void memzero_test_correctness_signal_handler(int arg)
{
// Removed for brevity. It calls memzero_test here, and basically
// when this function finishes execution a signal is sent to the
// call_on_stack function.
char *buf = memzero_test();
if (memcmp(buf, secret, sizeof(secret)) != 0) {
printf("Test passed\n");
} else {
printf("Test failed\n");
}
}
call_on_stack(memzero_test_correctness_signal_handler);
因此,我也想在Windows中进行测试,但是Windows当然不支持这些GNU C库特定的数据类型和常量。因此,我需要另一种方法来重写它,更具体地说,创建一个自定义堆栈,在其上执行一个函数,并通知函数何时完成以清除它。有任何想法在Windows中如何做到吗?
答案 0 :(得分:2)
在Windows中运行多个堆栈的受支持方法是fibers。
但是,我不确定这是否适合您的任务。如果您想在收到事件时擦除秘密,请从事件处理程序中调用SecureZeroMemory。