什么是 __sighandler_t 结构和 SIGTRAP 信号处理程序的目的

逆向工程 艾达 反调试 结构
2021-06-20 18:56:38

我正在反转一个 ELF x86 二进制文件,它显然具有反反转/反调试保护,而 ELF 做的第一件事就是调用带有 SIGTRAP 值的 sys_signal :

.text:08048063                 mov     eax, 48         ; sys_signal
.text:08048068                 mov     ebx, 5          ; SIGTRAP
.text:0804806D                 mov     ecx, offset sub_80480E2
.text:08048072                 int     80h             ; LINUX - sys_signal
.text:08048074                 jmp     short loc_8048077

我有三个问题:

  • 首先,我认为这样做的目的是为 SIGTRAP 信号创建一个处理程序是否正确,可能是为了防止任何调试器使用
  • 其次,如果这是创建一个 SIGTRAP 处理程序,我应该根据这个 x86 系统调用表找到一个__sighandler_tat 如何设置 IDA 以便将其识别为 __sighandler_t 结构?sub_80480E2
  • 第三,我找不到有关此结构的任何详细信息。它的成分是什么?

我在signal.h这些行中发现

/* Type of a signal handler.  */
typedef void (*__sighandler_t) (int);

__sighandler_t 只是一个函数的指针吗?

谢谢 !如果我不清楚或者我忘记了有用的信息,请随时告诉我。

1个回答

首先,我认为这样做的目的是为 SIGTRAP 信号创建一个处理程序是否正确,可能是为了防止任何调试器使用

当引发 SIGTRAP 时,通常signal会调用参数中给出的处理程序如果您附加了调试器,则不会调用此函数。如果您的处理程序从未被调用,您可以假设附加了调试器。

这是一个简单的例子:

#include <signal.h>
#include <stdio.h>

void on_trap(int n)
{
        puts("on_trap");
}

void callme(void)
{
        puts("hello");
        __asm__ volatile("int $0x03");
        puts("bye");
}

int main(void)
{
        signal(SIGTRAP, on_trap);
        callme();
        return 0;
}

正常运行:

$ ./antidebug
hello
on_trap
bye

使用 gdb:

gdb -q antidebug
Reading symbols from antidebug...(no debugging symbols found)...done.
(gdb) r
Starting program: /tmp/antidebug
hello

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000000008001174 in callme ()
(gdb) c
Continuing.
bye

其次,如果这是创建一个 SIGTRAP 处理程序,根据这个 x86 系统调用表,我应该在 sub_80480E2 找到一个 __sighandler_t。如何设置 IDA 以便将其识别为 __sighandler_t 结构?

sighandler_t 是函数指针的 typedef,而不是结构。如果要将内存区域定义为结构体,可以使用快捷方式ALT+Q

第三,我找不到有关此结构的任何详细信息。它的成分是什么?

sub_80480E2包含代码,如前所述这不是结构而是函数指针。想象一下,您有系统调用sigaction,您可以简单地查看手册页以查看结构定义。但是 IDA Pro 拥有标准库中的大部分结构定义。

__sighandler_t 只是一个函数的指针吗?

是的。