0

Usually stacktraces (backtraces) are generated from point where special stacktrace generation function is called (like _Unwind_Backtrace here: Android NDK: getting the backtrace). Is it possible to generate stacktrace which also includes libc functions? For example, I would like to inspect stacktrace for "open" libc call when it's called from my program (without modifying libc library). I know that in Java it's possible to invoke some method which throws exception and get stacktrace in exception handler from point where exception was thrown. I would like to do something similar in C but I don't think it's possible as there even are no exceptions in C.

jozols
  • 560
  • 7
  • 22
  • suggest compile your program with (amongst others) the parameter `-ggdb` Then link your program with (amongst others) the parameter `-ggdb` Then run `gdb `. At any point (when stepping through your program, that you would like a back trace, enter 'bt'. Note, however, that unless you have the source files for your OS visible to `gdb`, that `gdb` can display VERY LITTLE info about the system files contents. – user3629249 Oct 27 '17 at 19:53

1 Answers1

1

For example, I would like to inspect stacktrace for "open" libc call when it's called from my program (without modifying libc library).

There are several use cases to consider:

  1. Direct calls from your program to open
  2. Indirect calls (e.g. you call getgroups, which opens /etc/nsswitch.conf)
  3. Calls to open that are not triggered by your program at all (e.g. dynamic loader opening libc.so

Your question suggests that you are only interested in case 1, which is trivial to solve: compile the code from which you want to intercept open with -Dopen=open_with_stacktrace, and link with a separate file:

// Compile without -Dopen=...
#include <stdlib.>
ssize_t open_with_stacktrace(const char *fname, int flags, int mode)
{
  // Do whatever to record the stack trace.
  return open(fname, flags, mode);
}

For case 2, you may use a function interposer via LD_PRELOAD.

For case 3, you'll have to use external tracer, such as GDB.

What I actually want is to implement security feature ...

You should have started with that. In general, you can't implement any meaningful security in the program itself, you have to use an external monitor.

You are trying to detect whether someone interposed open. But that someone could just as easily interpose your "checker" function, and make it always return "everything is fine" result.

You should consider using one of the sandboxing techniques instead.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • The thing is that I need to get it from code of program itself. What I actually want is to implement security feature which detects from program if somebody has altered/interposed calls to shared libraries (like libc) by checking stacktrace. I'm interested in both 1. and 2. case (if possible). Your suggestion for case 1 will not work because program will not be able to detect if open call inside open_with_stacktrace is actually hooked. – jozols Oct 28 '17 at 19:51
  • Yes, any check can by bypassed, but that doesn't mean checks shouldn't be present (for example, there exists protection for games and movies even all of them are eventually hacked if there is enough motivation). It still complicates life of reverse engineer. I don't think sandbox technique is useful for me and it's also too complicated as currently I just need one specific thing. – jozols Oct 29 '17 at 10:48