Linux 内存访问错误系统操作(信号处理程序)
在本文之后,我一直尝试在amd64中使用Linux 内存访问错误系统操作(信号处理程序),linux,assembly,x86-64,system-calls,Linux,Assembly,X86 64,System Calls,在本文之后,我一直尝试在amd64中使用sys\u rt\u sigaction,但在发送信号时总是出现内存访问错误struct sigaction在使用C/C++函数sigaction时工作 sys\u rt\u sigaction调用有什么问题 C/C++与ASM代码: 发送信号 在x86-64 linux中,必须提供sau恢复程序,但您还没有这样做 委员会: 为您提供以下服务: kact.sa_flags = act->sa_flags | SA_RESTORER; kac
sys\u rt\u sigaction
,但在发送信号时总是出现内存访问错误struct sigaction在使用C/C++函数sigaction
时工作
sys\u rt\u sigaction
调用有什么问题
C/C++与ASM代码:
发送信号
在x86-64 linux中,必须提供
sau恢复程序
,但您还没有这样做
委员会:
为您提供以下服务:
kact.sa_flags = act->sa_flags | SA_RESTORER;
kact.sa_restorer = &restore_rt;
使用更新后的代码,您确实有一个恢复程序,但您有两个问题:它已损坏,并且您传递的代码错误。查看上述C库源代码,您可以:
此外,由于函数序言,不能将C++函数作为恢复器。此外,不支持从信号处理程序调用
printf
(但在这里有效)。最后,正如David Wohlferd指出的,你的打击者是错误的。总而言之,以下可能是一个返工版本:
#include<stdio.h>
#include<unistd.h>
#include<time.h>
void handler(int){
const char msg[] = "handler\n";
write(0, msg, sizeof(msg));
}
extern "C" void restorer();
asm volatile("restorer:mov $15,%rax\nsyscall");
struct kernel_sigaction {
void (*k_sa_handler) (int);
unsigned long sa_flags;
void (*sa_restorer) (void);
unsigned long sa_mask;
};
struct kernel_sigaction act{handler};
timespec ts{10,0};
int main(){
act.sa_flags=0x04000000;
act.sa_restorer=&restorer;
asm volatile("\
mov $13,%%rax\n\
mov %0,%%rdi\n\
mov %1,%%rsi\n\
mov %2,%%rdx\n\
mov $8,%%r10\n\
syscall\n\
"::"i"(7),"p"(&act),"p"(0):"rax","rcx", "rdi","rsi","rdx","r8", "r9", "r10", "r11");
nanosleep(&ts,0);
}
#包括
#包括
#包括
无效处理程序(int){
const char msg[]=“处理程序\n”;
写入(0,msg,sizeof(msg));
}
外部“C”无效恢复程序();
asm volatile(“恢复者:mov$15,%rax\nsyscall”);
结构内核操作{
无效(*k_sa_handler)(int);
未签名的长萨乌旗;
无效(*sa_恢复人)(无效);
无符号长萨乌面具;
};
结构内核_sigactionact{handler};
timespects{10,0};
int main(){
act.sa_标志=0x04000000;
行为恢复人=&恢复人;
asm volatile(“\
mov$13,%%rax\n\
mov%0,%%rdi\n\
mov%1,%%rsi\n\
mov%2,%%rdx\n\
mov$8,%%r10\n\
系统调用\n\
“:“i”(7),“p”(&act),“p”(0):“rax”,“rcx”,“rdi”,“rsi”,“rdx”,“r8”,“r9”,“r10”,“r11”);
纳米睡眠(&ts,0);
}
很明显,这仍然是一个黑客问题,你不应该这样做。嗨,非常感谢你的帮助:D在发布这个问题之前,我已经尝试过使用
恢复程序
,在很多方面都有相同的结果:(可能除了恢复程序
,还缺少其他东西?我怀疑与掩码
或标志
有关,但从未找到什么。我无法对未显示的代码进行评论。您确实需要一个恢复程序,否则您将点击该默认值
。可能是您在使用该恢复程序时编写了错误的代码。好的,我知道了。)在暂停之后,为了让大脑休息,我会继续工作,呵呵:谢谢,内核可能会对它们进行重击。所有的文档都说,除了rcx
更改和添加的r11
重击之外,在用户空间中也适用相同的约定。至少在我的系统上,这个值似乎保留了下来,但比抱歉更好:)事实上,我得到了纠正。我删除了最后两条注释。当我阅读ABI中的异常部分(之前)时,我假设是寄存器保存的常规约定(异常)——RCX和R11(以及用于返回值的RAX)ABI有点模棱两可,但在查看Linux内核源代码后,很明显,常规用户土地调用约定中所有其他调用方保留的寄存器(易失性寄存器)似乎都适用。Linux的syscall
clobber rcx和r11不是吗?确实适用,这一点很好。
kill -7 `pidof bin`
/* x86-64 should always use SA_RESTORER. */
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
put_user_ex(ksig->ka.sa.sa_restorer, &frame->pretcode);
} else {
/* could use a vstub here */
err |= -EFAULT;
}
kact.sa_flags = act->sa_flags | SA_RESTORER;
kact.sa_restorer = &restore_rt;
/* The difference here is that the sigaction structure used in the
kernel is not the same as we use in the libc. Therefore we must
translate it here. */
#include<stdio.h>
#include<unistd.h>
#include<time.h>
void handler(int){
const char msg[] = "handler\n";
write(0, msg, sizeof(msg));
}
extern "C" void restorer();
asm volatile("restorer:mov $15,%rax\nsyscall");
struct kernel_sigaction {
void (*k_sa_handler) (int);
unsigned long sa_flags;
void (*sa_restorer) (void);
unsigned long sa_mask;
};
struct kernel_sigaction act{handler};
timespec ts{10,0};
int main(){
act.sa_flags=0x04000000;
act.sa_restorer=&restorer;
asm volatile("\
mov $13,%%rax\n\
mov %0,%%rdi\n\
mov %1,%%rsi\n\
mov %2,%%rdx\n\
mov $8,%%r10\n\
syscall\n\
"::"i"(7),"p"(&act),"p"(0):"rax","rcx", "rdi","rsi","rdx","r8", "r9", "r10", "r11");
nanosleep(&ts,0);
}