Skip to content
General-purpose binder server tester
C++ Makefile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.



This is a repeater serving reproduce binder transaction from client side.

Command line

./repeater service_name cmd flag base64(data) mDataSize mObjects mObjectsSize
  • service_name should be identical to adb shell service list results, the same as in Service Manager.

  • base64(data) mDataSize mObjects mObjectsSize these four arguments are the truly essential part of Parcel data.

After provide these arguments, a fake binder transaction will be sent to server.

Implementation Detail

struct Parcel {
    status_t            mError;
    uint8_t*            mData;
    size_t              mDataSize;
    size_t              mDataCapacity;
    mutable size_t      mDataPos;
    binder_size_t*      mObjects;
    size_t              mObjectsSize;
    size_t              mObjectsCapacity;
    mutable size_t      mNextObjectHint;
    mutable bool        mObjectsSorted;

    mutable bool        mFdsKnown;
    mutable bool        mHasFds;
    bool                mAllowFds;

    release_func        mOwner;
    void*               mOwnerCookie;

Parcel has these private fields, but only some of them will be actually recorded and pass through the binder driver.

status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
    binder_transaction_data tr; = 0; /* Don't pass uninitialized stack data to a remote process */ = handle;
    tr.code = code;
    tr.flags = binderFlags;
    tr.cookie = 0;
    tr.sender_pid = 0;
    tr.sender_euid = 0;

    const status_t err = data.errorCheck();
    if (err == NO_ERROR) {
        //Start Here
        tr.data_size = data.ipcDataSize(); = data.ipcData();
        tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t); = data.ipcObjects();
        //End Here
    } else if (statusBuffer) {
        tr.flags |= TF_STATUS_CODE;
        *statusBuffer = err;
        tr.data_size = sizeof(status_t); = reinterpret_cast<uintptr_t>(statusBuffer);
        tr.offsets_size = 0; = 0;
    } else {
        return (mLastError = err);

    mOut.write(&tr, sizeof(tr));

    return NO_ERROR;

The parts between comments is critical! After checking all four ipc*() functions, you' ll figure out the only four field passed out are mData, mDataSize, mObjects, and mObjectsSize.

The associated code which recover a Parcel from these fields can be found in binder_thread_read() in binder driver source code.

As a consequence, we will build a repeater which is quite general purpose to test server backed by binder. And here it is! : )

You can’t perform that action at this time.