自己實現Binder的onTransact完成跨進程通信

Android可以通過Binder來實現異步通信,實現方式有兩種:一種是通過AIDL(系統會實現onTransact),另一種是:通過自己的實現的onTransact方法來完成通信,其中第一種的還原可以參考之前的博文:Android中Binder安全性和還原逆向中被混淆的AIDL接口。本文講述如何通過自己實現Binder的onTransact完成跨進程通信,可以幫助逆向分析。

服務端:

 

public class MyService extends Service {
    private static final String DESCRIPTOR = "MyService";
    private final String[] names = {"test1", "test2", "test3", "test4"};
    private MyBinder myBinder = new MyBinder();
    private class MyBinder extends Binder{
        @Override
 protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
            switch (code){
                case 0x001:
                    data.enforceInterface(DESCRIPTOR);
                    int num = data.readInt();
                    reply.writeNoException();
                    reply.writeString(names[num]);
                    return true;
            }
            return super.onTransact(code, data, reply, flags);
        }
    }

    @Override
 public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
 return myBinder;
    }

}

可以看到onTransact有四個參數 
code , data ,replay , flags

  • code 是一個整形的唯一標識,用於區分執行哪個方法,客戶端會傳遞此參數,告訴服務端執行哪個方法;
  • data客戶端傳遞過來的參數;
  • replay服務器返回回去的值;
  • flags標明是否有返回值,0爲有(雙向),1爲沒有(單向)。

客戶端:

public class MainActivity extends AppCompatActivity {

    private TextView tv = null;
    private Button button = null;
    private IBinder binder = null;
    private ServiceConnection connection = new ServiceConnection() {
        @Override
 public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            binder = iBinder;
        }

        @Override
 public void onServiceDisconnected(ComponentName componentName) {
            binder = null;
        }
    };
    @Override
 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView)this.findViewById(R.id.tv_info);
        button = (Button)this.findViewById(R.id.bt_send);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
 public void onClick(View view) {
                int num = 2;
                if(binder != null){
                   android.os.Parcel _data = android.os.Parcel.obtain();
                   android.os.Parcel _reply = android.os.Parcel.obtain();
                   try{
                       _data.writeInterfaceToken("MyService");
                       _data.writeInt(num);
                       binder.transact(0x001, _data, _reply, 0);
                       _reply.readException();
                       tv.setText(_reply.readString());
                   }catch(RemoteException e){
                       e.printStackTrace();
                   }finally {
                       _reply.recycle();
                       _data.recycle();
                   }
                }else{
                    Toast.makeText(MainActivity.this, "未連接binder service服務。。", Toast.LENGTH_LONG).show();
                }
            }
        });
        Intent intent = new Intent(this, MyService.class);
        bindService(intent, connection, BIND_AUTO_CREATE);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章