有什么方法可以找出机器指令的地址,这是由一些信号中断? 假设我们处于由sigaction()
build立的处理程序,并且具有对传递的siginfo_t
和ucontext_t
所有访问权限。 据我看到,手册没有提到这一点。
不便携式。 但是这是为x86_64:
结构体ucontext_t
包含寄存器REG_RIP
的值,它应该包含你所寻找的值。 这是第一条指令,从sighandler返回后将被执行。
其他体系结构应该具有类似的寄存器(x86_32上的EIP等)。
让我们看看下面的例子为Linux和x86 architure
#include<stdio.h> #define __USE_GNU #include<signal.h> #include<ucontext.h> void myhandle(int mysignal, siginfo_t *si, void* arg) { ucontext_t *context = (ucontext_t *)arg; printf("Address from where crash happen is %x \n",context->uc_mcontext.gregs[REG_RIP]); context->uc_mcontext.gregs[REG_RIP] = context->uc_mcontext.gregs[REG_RIP] + 0x04 ; } int main(int argc, char *argv[]) { struct sigaction action; action.sa_sigaction = &myhandle; action.sa_flags = SA_SIGINFO; sigaction(11,&action,NULL); printf("Before segfault\n"); int *a=NULL; int b; b =*a; // Here crash will hapen printf("I am still alive\n"); return 0; }
现在编译并运行,看看discompiled instrustion集。
jeegar@jeegar:~/stackoverflow$ gcc -g test1.c -o test1.o jeegar@jeegar:~/stackoverflow$ ./test1.o Before segfault Signal is 11 Address from where crash happen is 40065b I am still alive jeegar@jeegar:~/stackoverflow$ objdump -S test1.o
这里在对象转储
printf("Before segfault\n"); 400645: bf a8 07 40 00 mov $0x4007a8,%edi 40064a: e8 21 fe ff ff callq 400470 <puts@plt> int *a=NULL; 40064f: 48 c7 45 f0 00 00 00 movq $0x0,-0x10(%rbp) 400656: 00 int b; b =*a; // Here crash will hapen 400657: 48 8b 45 f0 mov -0x10(%rbp),%rax 40065b: 8b 00 mov (%rax),%eax 40065d: 89 45 fc mov %eax,-0x4(%rbp) printf("I am still alive\n"); 400660: bf b8 07 40 00 mov $0x4007b8,%edi 400665: e8 06 fe ff ff callq 400470 <puts@plt>
在40065b地址哪台机器代码在那里,你的代码的哪一行已经完成了。
在这里,我已经给你和示例代码,在发生分割和系统的Seg故障信号一个处理程序将被调用,在那里我已经取得了最后一个执行机器周期的地址,并打印该地址。 为了使地址变化,我还显示了该代码的对象转储和分割线条的机器指令匹配。
我想这是你想要的。