Binder Service使用

背景

网上大部分的文章都是在讲binder的原理,但都没有详细地解释使用以及跨进程调用的条件以及注意的点,这篇文章主要是关注以上的点。

跨进程

跨进程需要注意的点:

  • 客户端与服务端的aidl文件必须完全一致才行
  • 如果不存在android:process属性,只有应用app本身进程存活,才可以进行跨进程调用
  • 如果存在android:process属性,无论app本身进程是否存活,只有process指定进程存活,才可以进行跨进程调用

代码实现

binderserver

OnTransact式实现:

package cn.tasfa.binderserver;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

/**
 * @author Tasfa
 */

public class VulnerableService extends Service {
    private static final String TAG = "VulnerableService";
    
    public final static int COMMUNICATION_CODE = 1;
    public final static String COMMUNICATION_CODE_DESCRIPTOR = "com.tasfa.Hacker.binder";

    /**
     * 配合VulImpBinder
     */
    public interface IVulInterface {
        int getKey(String values, int type);
    }

    /**
     * 此类实现通讯 可跨进程调用
     * 但是,需要服务端启动该服务,如果该服务不存在,无法调用
     * 关键点: 实现了onTransact函数,因此可远程调用
     */
    public static final class VulImpBinder extends Binder implements IVulInterface {
        /**
         * 该方法重载,实现自己的业务逻辑,也是跨进程的关键点
         * @param code code
         * @param data data
         * @param reply reply
         * @param flags flags
         * @return bool
         * @throws RemoteException RemoteException
         */
        @Override
        protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
            switch (code) {
                case COMMUNICATION_CODE:
                    data.enforceInterface(COMMUNICATION_CODE_DESCRIPTOR);
                    String values = data.readString();
                    int type = data.readInt();
                    int result = getKey(values, type);
                    reply.writeInterfaceToken(COMMUNICATION_CODE_DESCRIPTOR);
                    reply.writeInt(result);
                    return true;
                default:
                    break;
            }
            return super.onTransact(code, data, reply, flags);
        }

        @Override
        public int getKey(String values, int type) {
            return type + 300;
        }
    }


    /**
     * 此类方法不可以跨进程调用
     * 关键点:未实现onTransact函数,无法远程调用
     */
    /*    public static final class VulBinder extends Binder {
        public int getKey(String values, int type) throws RemoteException {
            return type + 100;
        }
    }*/

    private VulImpBinder mImpBinder;

    public VulnerableService() {
        mImpBinder = new VulImpBinder();
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind return binder");
        return mImpBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (mImpBinder == null){
            mImpBinder = new VulImpBinder();
        }
    }
}

AndroidManifest.xml
<service
    android:name=".VulnerableService"
    android:enabled="true"
    android:process=":vulbinder"> <!-- 可不使用该属性 -->
    <intent-filter>
        <action android:name="com.tasfa.pp.vulbinder.action" />
    </intent-filter>
</service>

<service
    android:name=".VulnerableServiceB"
    android:enabled="true"
    android:process=":aidlvul"> <!-- 可不使用该属性 -->
    <intent-filter>
        <action android:name="com.tasfa.wdj.vulbinder.action"/>
    </intent-filter>
</service>

AIDL方式实现:

package cn.tasfa.binderserver;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class VulnerableServiceB extends Service {
    public VulnerableServiceB() {
        mVulAIDLBinder = new VulAIDLBinder();

    }

    /**
     * 此类使用AIDL可以跨进程调用
     * 无需启动该服务,也可实现调用
     */
    public static final class VulAIDLBinder extends IVulAidlInterface.Stub {
        @Override
        public int getKey(String values, int type) throws RemoteException {
            return type + 200;
        }
    }

    private VulAIDLBinder mVulAIDLBinder;


    @Override
    public IBinder onBind(Intent intent) {
        return mVulAIDLBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (mVulAIDLBinder == null){
            mVulAIDLBinder = new VulAIDLBinder();
        }
    }
}

binderclient
package cn.tasfa.binderclient;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import cn.tasfa.binderserver.IVulAidlInterface;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "binderClient";

    /**
     * OnTransact式跨进程调用
     */
    private class HackerConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected Successfully !!!");
            useParcelHacker(service);
        }

        /**
         * 远程服务不使用AIDL
         * 使用自己实现的onTransact函数
         * @param service IBinder
         */
        private void useParcelHacker(IBinder service){
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();

            String hackerInterfaceToken = "com.tasfa.Hacker.binder";
            int hackerInterfaceCode = 1;

            data.writeInterfaceToken(hackerInterfaceToken);
            data.writeString("hello");
            data.writeInt(1);

            try {
                service.transact(hackerInterfaceCode, data, reply, 0);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            reply.enforceInterface(hackerInterfaceToken);
            int result = reply.readInt();
            Log.d(TAG, "useParcelHacker result: " + result);

            data.recycle();
            reply.recycle();

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }

    /**
     * AIDL Interface
     * 注意这里"包名以及内容"必须与远程服务的AIDL文件是一致的
     *
     */
    private IVulAidlInterface mIHackerAidlInterface;

    /**
     * AIDL式跨进程调用
     */
    private class HackerAIDLConnection implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.d(TAG, "onServiceConnected Successfully !!!");
            aidlHacker(iBinder);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mIHackerAidlInterface = null;
        }

        /**
         * AIDL 远程调用函数
         * @param service IBinder
         */
        private void aidlHacker(IBinder service){
            mIHackerAidlInterface = IVulAidlInterface.Stub.asInterface(service);
            try {
                int rel =  mIHackerAidlInterface.getKey("hello",1);
                Log.d(TAG, "mIHackerAidlInterface rel: " + rel);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startAttack();
            }
        });

        Button aidl = findViewById(R.id.aidl);
        aidl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startAIDLAttack();
            }
        });

    }

    private void startAttack(){
        Intent intent = new Intent();
        String vulPackageName = "cn.tasfa.binderserver";
        String vulBinderServiceClassName = "cn.tasfa.binderserver.VulnerableService";
        intent.setClassName(vulPackageName,vulBinderServiceClassName);
        bindService(intent, new HackerConnection(), BIND_AUTO_CREATE);
        Log.d(TAG, "Start Attack !");
    }

    private void startAIDLAttack(){
        Intent intent = new Intent();
        String vulPackageName = "cn.tasfa.binderserver";
        String vulBinderServiceClassName = "cn.tasfa.binderserver.VulnerableServiceB";
        intent.setClassName(vulPackageName,vulBinderServiceClassName);
        bindService(intent, new HackerAIDLConnection(), BIND_AUTO_CREATE);
        Log.d(TAG, "Start AIDL Attack !");
    }
}

参考

Android Service:利用Binder通信中,传递自定义类型

轻松理解 Android Binder,只需要读这一篇

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值