11

In Android is dev/binder also for layers communication responsible. Is it possible to listen to messages? I know that they must be decoded than, but how can I get this messages. For example if an app send a message to became an Geolocation. I have also root on my android device.

Onik
  • 19,396
  • 14
  • 68
  • 91
Aprel
  • 1,089
  • 2
  • 14
  • 25

6 Answers6

4

Why, time and time again, do wrong answers get approved as right?

Jtrace - not to be confused with bin dump - requires no modification of Android what-so-ever. And it can snoop binder messages - with the restriction that you have to be jtrace'ing one of the end points.

Bindump uses debugfs, but that only shows endpoints. @Adrian - I'm afraid you got the wrong conclusion.

Jtrace traps sys calls going in and out - and then resolves the binder messages by inspecting process memory (using ptrace(2)). If you have ptrace(2) in your kernel (which you do, because debugserver foolishly needs it) and you are root, you can snoop messages. Again - you have to be on an endpoint.

And @Luminger - while on he subject - just because one can't find info, doesn't mean there isn't info. There's plenty of information on Binder on NewAndroidBook.com - besides the book, look at the Binder presentation link.

Technologeeks
  • 7,674
  • 25
  • 36
4

Short: Nope, it shouldn't be possible, even with root.

There isn't that much informations about Binder in detail on the net but there are some, especially about the security. Refer to this or to point 3.8 here. You may also read the source of the kernel driver and the source of openbinder.

Luminger
  • 2,144
  • 15
  • 22
  • 1
    Thanks. This was quite interesting. But can you tell me what is a reason for it. I want just listen to what an app sends to binder (in bytecode).Mayby with strace or something like that. – Aprel Feb 18 '12 at 15:57
  • 1
    It basically just works as every other linux api which is "personalized". You will just see what you are allowed to see, based on userid/groupid here. It just has good access control to ensure everything is fine =) – Luminger Feb 18 '12 at 17:46
  • ok i understood. And a little bit another question: for looking how apps and linux kernel communicate with each other(also if i only see a little part of this communication). What tool I can use to do it? – Aprel Feb 18 '12 at 18:04
  • You will be able to see most/everything with [strace]()http://en.wikipedia.org/wiki/Strace. strace intercepts all syscalls and prints the result and arguments. – Luminger Feb 18 '12 at 18:11
  • @Luminger I read 3.8 section but didn't see which part precluded snooping on binder. Can you elaborate? – Bob May 31 '17 at 15:06
  • @Luminger what about [this answer to this very same question](https://stackoverflow.com/a/14717859/4784683)? – Bob May 31 '17 at 15:07
3

You can decode most of the Binder transactions that go past using this version of strace: https://github.com/adetaylor/strace-android/tree/android

It has enhancements to decode the ioctl calls which are the way processes make requests to the Binder kernel driver. Make sure you use the android branch or you won't get the benefit of those changes.

You should be able to build this using an NDK standalone toolchain. See docs/STANDALONE-TOOLCHAIN.html within the Android NDK documentation.

Adrian Taylor
  • 4,054
  • 2
  • 24
  • 26
  • Great, but unfortunately I was unable to compile it with NDK, after fixing a bunch of compiler errors (header mismatches etc.), I was left with a linker error, at which point I have up. Do you have a prebuilt static binary somewhere? – domen Jun 10 '13 at 14:04
  • Doing it with codesourcery toolchain was much easier, no header fixups etc. I mostly followed instructions from: http://muzso.hu/2012/04/21/how-to-compile-strace-for-use-on-an-android-phone-running-an-arm-cpu Note that make-dist is the place to set variables, add `--host`, and if anything goes wrong comment out the `trap` to debug it easily. – domen Jun 10 '13 at 14:23
3

@Adrian, some good work w.r.t the problem has been done by other developer/researchers, so you could make use of their results.

First of all, I'd recommend to look at the great work of Jonathan Levin (a.k.a Technologeeks), namely his book on the Android internals that recently became free and could be accessed at the book's companion website: newandroidbook.com. From there you'll get links, description and usage examples to

  • bindump

    that is a simple derivative of the service command, which obtains a handle to the system service of choice, and then inspects its own entry in the /sys/kernel/debug/binder/proc directory. Because all the binder debug data is world readable, you can run this tool on unrooted devices as well.

  • jtrace, an augmented version of strace, whose one of the advantages over strace is

    binder message parsing (auto detected).

Another great work, done by Opersys (with Karim Yaghmour), that is definitely worth noting and looking at is

  • Binder Explorer

    This tool works as an app, or along with HTML GUI, to show a graphical view of connections in real time.

Onik
  • 19,396
  • 14
  • 68
  • 91
  • I looked at jtrace and it appears to be exactly what I want. But how did this guy snoop on binder messages without changing the binder code itself? – Bob Jun 06 '17 at 21:57
  • I read the guy's free PDF and the answer is that he enables debugfs which is effectively same outcome as recompiling libbinder: the "secure" binder traffic is output for all to see. Thanks for the answer. It just served to reinforce that snooping on binder is not possible without modification of android. – Bob Jun 07 '17 at 11:50
2

If you're up for installing a custom kernel, the binder driver code (drivers/staging/android/binder.c) has pretty good debugging features, including conditional messages and functions that can print binder transactions, etc.

Specifically, you'll get various kinds of debug messages in the kernel log by setting binder_debug_mask using the appropriate combination of the following enumerators:

BINDER_DEBUG_USER_ERROR
BINDER_DEBUG_FAILED_TRANSACTION
BINDER_DEBUG_DEAD_TRANSACTION
BINDER_DEBUG_OPEN_CLOSE
BINDER_DEBUG_DEAD_BINDER
BINDER_DEBUG_DEATH_NOTIFICATION
BINDER_DEBUG_READ_WRITE
BINDER_DEBUG_USER_REFS
BINDER_DEBUG_THREADS
BINDER_DEBUG_TRANSACTION
BINDER_DEBUG_TRANSACTION_COMPLETE
BINDER_DEBUG_FREE_BUFFER
BINDER_DEBUG_INTERNAL_REFS
BINDER_DEBUG_BUFFER_ALLOC
BINDER_DEBUG_PRIORITY_CAP
BINDER_DEBUG_BUFFER_ALLOC_ASYNC

You could also sprinkle a few of the print_binder_* functions that are included in binder.c at strategic locations throughout the code. For example, print_binder_buffer() or print_binder_transaction(). You would probably want to make these conditional based on a particular uid or pid, since there will otherwise be a LOT of stuff flying by the log.

Paul Ratazzi
  • 6,289
  • 3
  • 38
  • 50
0

Here is a code example on how to communicate with /dev/binder. It get's the binder version and nothing more. But it proofs that it is possible to communicate with /dev/binder directly. You don't need to request any Android permissions nor do you need root. This code really only is a proof of concept.

#include <fcntl.h>
#include <unistd.h>
#include <linux/android/binder.h>
#include <android/log.h>

void testBinder()
{
  int fd = open("/dev/binder", 0);
  if (fd < 0)
  {
    __android_log_print(ANDROID_LOG_ERROR, "bindertest", "error, open() returned %i", fd);
    return;
  }

  __android_log_print(ANDROID_LOG_ERROR, "bindertest", "ok, open() returnd %i", fd);

  fcntl(fd, F_SETFD, FD_CLOEXEC);
  struct binder_version vers;
  int result = ioctl(fd, BINDER_VERSION, &vers);
  if (result < 0)
  {
    __android_log_print(ANDROID_LOG_ERROR, "bindertest", "ioctl() failed");
    return;
  }
  __android_log_print(ANDROID_LOG_ERROR, "bindertest", "binder version is %i ", vers.protocol_version);

  if (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)
  {
    __android_log_print(ANDROID_LOG_ERROR, "bindertest", "binder version does not match");
    return;
  }
}

You have to analyze the Android source code to see how /dev/binder works.

If you really want "talk" to /dev/binder (requesting services and making calls) you should use Android's binder client library.

For example there is the class android.os.Binder. It runs in user space and connects to the kernel binder driver.

It's everything written down in the source code.

zomega
  • 1,538
  • 8
  • 26