2

I'm reversing a program that uses a lot of BREAK/int 3 (Linux). I guess that the code contains something like:

void sigtrap_func(int sig) { (some stuff..) }

int main()
{
  signal(SIGTRAP, sigtrap_func);
  (some stuff)
  asm("int 3");
  (and so on)
  asm("int 3");

etc..

I replaced all SIGTRAP by NOPs and the program behave differently than with them. So, I'm sure that something is done inside the sigtrap function.

How can I find this function just with the assembler ?

2 Answers 2

6

That's where strace comes in handy. If i make your program compilable and compile it:

$cat trap.c
#include <signal.h>
void sigtrap_func(int sig) { puts("trap"); }

int main()
{
  signal(SIGTRAP, sigtrap_func);
}
$ cc -o trap trap.c

and then run it with strace, i'll get a list of all system calls the program executes:

$strace -i ./trap 
[      31076ad057] execve("./trap", ["./trap"], [/* 32 vars */]) = 0
... stuff omitted that loads dynamic libraries
[      3107632abe] rt_sigaction(SIGTRAP, {0x400504, [TRAP], SA_RESTORER|SA_RESTART, 0x31076329a0}, {SIG_DFL, [], 0}, 8) = 0
[      31076ad038] exit_group(0)        = ?

You see that rt_sigaction (the system call that implements signal()) gets called at 0x3107632abe, and sets the handler function to 0x31076329a0. Now is the time to start gdb, and set breakpoints there (beware of ASLR though!).

1

Just like in your sample program, the signal handlers are installed using a signal (or sigaction) function. So you just need to find the call to that function and see what argument is passed to it. That argument will be the address of the signal handler.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.