forked from CyanogenMod/android_packages_apps_Superuser
-
Notifications
You must be signed in to change notification settings - Fork 1
/
activity.cpp
113 lines (90 loc) · 3.77 KB
/
activity.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <unistd.h>
#include <android_runtime/ActivityManager.h>
#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <assert.h>
extern "C" {
#include "su.h"
#include <private/android_filesystem_config.h>
#include <cutils/properties.h>
}
using namespace android;
static const int BROADCAST_INTENT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 13;
static const int FLAG_ACTIVITY_NO_HISTORY = 0x40000000;
static const int FLAG_ACTIVITY_NEW_TASK = 0x10000000;
static const int FLAG_ACTIVITY_MULTIPLE_TASK = 0x08000000;
static const int URI_TYPE_ID = 1;
static const int NULL_TYPE_ID = 0;
static const int VAL_NULL = -1;
static const int VAL_STRING = 0;
static const int VAL_INTEGER = 1;
static const int START_SUCCESS = 0;
int do_request(struct su_initiator *from, struct su_request *to, const char *socket_path)
{
char sdk_version_prop[PROPERTY_VALUE_MAX] = "0";
property_get("ro.build.version.sdk", sdk_version_prop, "0");
int sdk_version = atoi(sdk_version_prop);
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> am = sm->checkService(String16("activity"));
assert(am != NULL);
Parcel data, reply;
data.writeInterfaceToken(String16("android.app.IActivityManager"));
data.writeStrongBinder(NULL); /* caller */
/* intent */
data.writeString16(String16("com.noshufou.android.su.REQUEST")); /* action */
data.writeInt32(NULL_TYPE_ID); /* Uri - data */
data.writeString16(NULL, 0); /* type */
data.writeInt32(0); /* flags */
if (sdk_version >= 4) {
// added in donut
data.writeString16(NULL, 0); /* package name - DONUT ONLY, NOT IN CUPCAKE. */
}
data.writeString16(NULL, 0); /* ComponentName - package */
data.writeInt32(0); /* Categories - size */
if (sdk_version >= 7) {
// added in eclair rev 7
data.writeInt32(0);
}
{ /* Extras */
data.writeInt32(-1); /* dummy, will hold length */
int oldPos = data.dataPosition();
data.writeInt32(0x4C444E42); // 'B' 'N' 'D' 'L'
{ /* writeMapInternal */
data.writeInt32(4); /* writeMapInternal - size */
data.writeInt32(VAL_STRING);
data.writeString16(String16("caller_uid"));
data.writeInt32(VAL_INTEGER);
data.writeInt32(from->uid);
data.writeInt32(VAL_STRING);
data.writeString16(String16("desired_uid"));
data.writeInt32(VAL_INTEGER);
data.writeInt32(to->uid);
data.writeInt32(VAL_STRING);
data.writeString16(String16("desired_cmd"));
data.writeInt32(VAL_STRING);
data.writeString16(String16(to->command));
data.writeInt32(VAL_STRING);
data.writeString16(String16("socket"));
data.writeInt32(VAL_STRING);
data.writeString16(String16(socket_path));
}
int newPos = data.dataPosition();
data.setDataPosition(oldPos - 4);
data.writeInt32(newPos - oldPos); /* length */
data.setDataPosition(newPos);
}
data.writeString16(NULL, 0); /* resolvedType */
data.writeStrongBinder(NULL); /* resultTo (something about this makes for an error reading it back */
data.writeInt32(-1); /* resultCode */
data.writeString16(NULL, 0); /* resultData */
data.writeInt32(-1); /* somewhere between these two lines is resultExtras */
data.writeInt32(-1); /* not sure which line it is, but they both need to be here*/
data.writeString16(String16("com.noshufou.android.su.RESPOND")); /* perm */
data.writeInt32(0); /* serialized */
data.writeInt32(0); /* sticky */
status_t ret = am->transact(BROADCAST_INTENT_TRANSACTION, data, &reply);
if (ret < START_SUCCESS) return -1;
return 0;
}