0x0000000008001946: mov 0xa8(%rdx),%rax
0x000000000800194d: lea 0x28(%rdx),%rsi
0x0000000008001951: lea 0x2(%rax),%rdi
0x0000000008001955: add $0xe,%rax
0x0000000008001959: mov %rax,0xa8(%rdx)
0x0000000008001960: jmpq 0x8001ee0
以上是信号处理程序的完整反汇编,它通常由我正在研究的程序设置,即程序注册信号处理程序并通过SIGILL使用操作码引发 a 立即调用它ud2。
信号处理程序在这里注册:
0x8001965: push %rbx
0x8001966: xor %eax,%eax
0x8001968: mov $0x26,%ecx
0x800196d: sub $0xa0,%rsp
0x8001974: lea 0x8(%rsp),%rdi
0x8001979: rep stos %eax,%es:(%rdi)
0x800197b: lea -0x3c(%rip),%rax # 0x8001946
0x8001982: lea 0x10(%rsp),%rdi
0x8001987: movl $0x8000004,0x90(%rsp)
0x8001992: mov %rax,0x8(%rsp)
0x8001997: callq 0x8000f60 <sigfillset@plt>
0x800199c: xor %edx,%edx
0x800199e: test %eax,%eax
0x80019a0: jne 0x80019bb
0x80019a2: lea 0x8(%rsp),%rbx
0x80019a7: xor %edx,%edx
0x80019a9: mov $0x4,%edi
0x80019ae: mov %rbx,%rsi
0x80019b1: callq 0x8000f90 <sigaction@plt>
哪里0x8001946是处理程序的地址,在第一个代码块之前被反汇编。
我的问题是关于信号处理程序的第一条指令,它似乎毫无意义,我无法调试它,因为我不能在上面放置断点:
0x0000000008001946: mov 0xa8(%rdx),%rax
%rdx由 ABI 定义为传递给函数的第三个参数,并且由is a (强制转换结构)sigaction的第三个参数定义,但是 a 的定义中没有索引,这让我相信它是别的东西。sa_sigactionvoid *ucontext_t0xa8struct ucontext_t
我认为%rdx在ud2调用指令之前它可能是一个集合:
0x0000000008000fde: test %al,%al
0x0000000008000fe0: mov $0x2,%edx
0x0000000008000fe5: je 0x8001028
0x0000000008000fe7: movslq %ebx,%rdi
0x0000000008000fea: mov %rbp,%rsi
0x0000000008000fed: callq 0x8001190
但是在调用0x80001190(错误)之前,%rdx只包含$0x2. 所以我更糊涂了。
任何人都可以阐明%rdx在引发0x8001946a 之后可能包含的SIGILL内容,并将信号传递给在该地址定义的自定义处理程序?