external/koush/Superuser
Revisão | db2065dc6d038d4471af04a16e0872c878125744 (tree) |
---|---|
Hora | 2013-11-08 06:12:07 |
Autor | Koushik Dutta <koushd@gmai...> |
Commiter | Koushik Dutta |
Merge remote-tracking branch 'koush/master' into cm-10.2
@@ -26,6 +26,8 @@ You'll need the "Widgets" dependency. | ||
26 | 26 | These repositories do not keep the actual projects in the top level directory. |
27 | 27 | This is because they contain tests, libs, and samples. |
28 | 28 | |
29 | +Make sure the SDK Platform for API 17 is installed, through the Android SDK Manager. Install NDK Revision 8e from [here](http://developer.android.com/tools/sdk/ndk/index.html). | |
30 | + | |
29 | 31 | ## Eclipse |
30 | 32 | |
31 | 33 | In Eclipse, import Widgets/Widgets and Superuser/Superuser. It should Just Work (TM). |
@@ -36,21 +38,30 @@ In Eclipse, import Widgets/Widgets and Superuser/Superuser. It should Just Work | ||
36 | 38 | * $ cd /path/to/src |
37 | 39 | * $ cd Superuser/Superuser |
38 | 40 | |
39 | -In this directory, create a file called local.properties. This file is used by ant for custom properties. You need to specify the location of the ndk directory: | |
41 | +In this directory, create a file called local.properties. This file is used by ant for custom properties. You need to specify the location of the ndk directory and your keystore parameters: | |
40 | 42 | |
41 | 43 | ``` |
42 | 44 | ndk.dir=/Users/koush/src/android-ndk |
45 | +key.store=/Users/koush/.keystore | |
46 | +key.alias=mykey | |
43 | 47 | ``` |
44 | 48 | |
49 | +If you do not have a release key yet, [create one using keytool](http://developer.android.com/tools/publishing/app-signing.html). | |
50 | + | |
51 | +Set up your SDK path (this is the directory containing platform-tools/, tools/, etc.): | |
52 | + | |
53 | +* $ export ANDROID_HOME=/Users/koush/src/sdk | |
54 | + | |
45 | 55 | Then you can build: |
46 | 56 | |
47 | 57 | * $ ant release |
48 | 58 | |
49 | 59 | Outputs: |
50 | 60 | * bin/update.zip - Recovery installable zip |
51 | -* bin/Superuser.apk - Superuser Android app | |
61 | +* bin/Superuser-release.apk - Superuser Android app | |
52 | 62 | * libs/armeabi/su - ARM su binary |
53 | 63 | * libs/x86/su - x86 su binary |
64 | +* libs/mips/su - MIPS su binary | |
54 | 65 | |
55 | 66 | ## Building the su binary |
56 | 67 |
@@ -7,12 +7,13 @@ echo -n -e 'ui_print Installing Superuser...\n' > /proc/self/fd/$2 | ||
7 | 7 | echo -n -e 'ui_print\n' > /proc/self/fd/$2 |
8 | 8 | |
9 | 9 | # detect binary versions to install |
10 | -X86=$(uname -a | grep x86) | |
11 | -I686=$(uname -a | grep i686) | |
12 | -I386=$(uname -a | grep i386) | |
13 | -if [ ! -z "$X86" -o ! -z "$I686" -o ! -z "$I386" ] | |
14 | -then | |
10 | +ARCH=$(uname -m) | |
11 | + | |
12 | +# x86 needs to match: i486, i686, x86_64, ... | |
13 | +if echo "$ARCH" | grep -q 86; then | |
15 | 14 | PLATFORM=x86 |
15 | +elif [ "$ARCH" = "mips" -o "$ARCH" = "mips64" ]; then | |
16 | + PLATFORM=mips | |
16 | 17 | else |
17 | 18 | PLATFORM=armeabi |
18 | 19 | fi |
@@ -55,25 +56,26 @@ chmod 644 /system/app/Superuser.apk | ||
55 | 56 | |
56 | 57 | # if the system is at least 4.3, and there is no su daemon built in, |
57 | 58 | # let's try to install it using install-recovery.sh |
58 | -BUILD_RELEASE_VERSION=$(cat /system/build.prop | grep ro\\.build\\.version\\.release) | |
59 | -IS_43=$(echo $BUILD_RELEASE_VERSION | grep 4\\.3) | |
60 | -if [ ! -z "$IS_43" ] | |
59 | +BUILD_RELEASE_VERSION="$(grep 'ro\.build\.version\.release' /system/build.prop)" | |
60 | +VERSION="${BUILD_RELEASE_VERSION##*=}" | |
61 | +MAJ=${VERSION%%.*} | |
62 | +MIN=${VERSION#*.} | |
63 | +MIN=${MIN//.*} | |
64 | + | |
65 | +if [ "$MAJ" -ge 4 -a "$MIN" -ge 3 ] | |
61 | 66 | then |
62 | - if [ "$IS_43" \> "4.3" -o "$IS_43" == "4.3" ] | |
67 | + # check for rom su daemon before clobbering install-recovery.sh | |
68 | + if [ ! -f "/system/etc/.has_su_daemon" ] | |
63 | 69 | then |
64 | - # check for rom su daemon before clobbering install-recovery.sh | |
65 | - if [ ! -f "/system/etc/.has_su_daemon" ] | |
66 | - then | |
67 | - echo -n -e 'ui_print Installing Superuser daemon...\n' > /proc/self/fd/$2 | |
68 | - echo -n -e 'ui_print\n' > /proc/self/fd/$2 | |
69 | - chattr -i /system/etc/install-recovery.sh | |
70 | - cp install-recovery.sh /system/etc/install-recovery.sh | |
71 | - chmod 755 /system/etc/install-recovery.sh | |
72 | - # note that an post install su daemon was installed | |
73 | - # so recovery doesn't freak out and recommend you disable | |
74 | - # the install-recovery.sh execute bit. | |
75 | - touch /system/etc/.installed_su_daemon | |
76 | - fi | |
70 | + echo -n -e 'ui_print Installing Superuser daemon...\n' > /proc/self/fd/$2 | |
71 | + echo -n -e 'ui_print\n' > /proc/self/fd/$2 | |
72 | + chattr -i /system/etc/install-recovery.sh | |
73 | + cp install-recovery.sh /system/etc/install-recovery.sh | |
74 | + chmod 755 /system/etc/install-recovery.sh | |
75 | + # note that an post install su daemon was installed | |
76 | + # so recovery doesn't freak out and recommend you disable | |
77 | + # the install-recovery.sh execute bit. | |
78 | + touch /system/etc/.installed_su_daemon | |
77 | 79 | fi |
78 | 80 | fi |
79 | 81 |
@@ -99,6 +99,7 @@ | ||
99 | 99 | <arg value="../bin/update.zip"/> |
100 | 100 | <arg value="armeabi"/> |
101 | 101 | <arg value="x86"/> |
102 | + <arg value="mips"/> | |
102 | 103 | </exec> |
103 | 104 | </target> |
104 | 105 |
@@ -12,6 +12,16 @@ include $(BUILD_EXECUTABLE) | ||
12 | 12 | |
13 | 13 | include $(CLEAR_VARS) |
14 | 14 | |
15 | +LOCAL_MODULE := reboot | |
16 | +LOCAL_LDFLAGS := -llog | |
17 | +LOCAL_STATIC_LIBRARIES := sqlite3 | |
18 | +LOCAL_C_INCLUDES := $(LOCAL_PATH)/sqlite3 | |
19 | +LOCAL_SRC_FILES := reboot/reboot.c | |
20 | +include $(BUILD_EXECUTABLE) | |
21 | + | |
22 | + | |
23 | +include $(CLEAR_VARS) | |
24 | + | |
15 | 25 | LOCAL_MODULE := sqlite3 |
16 | 26 | LOCAL_SRC_FILES := sqlite3/sqlite3.c |
17 | 27 | LOCAL_CFLAGS := -DSQLITE_OMIT_LOAD_EXTENSION |
@@ -1,3 +1,3 @@ | ||
1 | -APP_ABI := x86 armeabi | |
1 | +APP_ABI := x86 armeabi mips | |
2 | 2 | NDK_TOOLCHAIN_VERSION=4.7 |
3 | 3 | APP_PIE = false |
\ No newline at end of file |
@@ -0,0 +1,145 @@ | ||
1 | +/* | |
2 | +** Copyright 2013, Kevin Cernekee <cernekee@gmail.com> | |
3 | +** | |
4 | +** This was reverse engineered from an HTC "reboot" binary and is an attempt | |
5 | +** to remain bug-compatible with the original. | |
6 | +** | |
7 | +** Licensed under the Apache License, Version 2.0 (the "License"); | |
8 | +** you may not use this file except in compliance with the License. | |
9 | +** You may obtain a copy of the License at | |
10 | +** | |
11 | +** http://www.apache.org/licenses/LICENSE-2.0 | |
12 | +** | |
13 | +** Unless required by applicable law or agreed to in writing, software | |
14 | +** distributed under the License is distributed on an "AS IS" BASIS, | |
15 | +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
16 | +** See the License for the specific language governing permissions and | |
17 | +** limitations under the License. | |
18 | +*/ | |
19 | + | |
20 | +#include <stdio.h> | |
21 | +#include <stdlib.h> | |
22 | +#include <unistd.h> | |
23 | + | |
24 | +#include <sqlite3.h> | |
25 | +#include <sys/reboot.h> | |
26 | +#include <android/log.h> | |
27 | + | |
28 | +#define SETTINGS_DB "/data/data/com.android.providers.settings/databases/settings.db" | |
29 | +#define SCREEN_LOCK_STATUS "/data/misc/screen_lock_status" | |
30 | + | |
31 | +int pattern_lock; | |
32 | + | |
33 | +int sqlcallback(void *private, int n_columns, char **col_values, char **col_names) | |
34 | +{ | |
35 | + pattern_lock = 0; | |
36 | + | |
37 | + if (n_columns == 0 || !col_values[0]) | |
38 | + return 0; | |
39 | + | |
40 | + if (!strcmp(col_values[0], "1")) | |
41 | + pattern_lock = 1; | |
42 | + | |
43 | + __android_log_print(ANDROID_LOG_INFO, NULL, | |
44 | + "sqlcallback %s = %s, pattern_locks= %d\n", | |
45 | + col_names[0], col_values[0], pattern_lock); | |
46 | + return 0; | |
47 | +} | |
48 | + | |
49 | +int checkPatternLock(void) | |
50 | +{ | |
51 | + sqlite3 *pDb = NULL; | |
52 | + char *errmsg = NULL; | |
53 | + | |
54 | + if (sqlite3_open(SETTINGS_DB, &pDb) != 0) { | |
55 | + __android_log_print(ANDROID_LOG_ERROR, NULL, | |
56 | + "sqlite3_open error"); | |
57 | + /* BUG? probably shouldn't call sqlite3_close() if open failed */ | |
58 | + goto out; | |
59 | + } | |
60 | + | |
61 | + if (sqlite3_exec(pDb, | |
62 | + "select value from system where name= \"lock_pattern_autolock\"", | |
63 | + sqlcallback, "checkPatternLock", &errmsg) != 0) { | |
64 | + __android_log_print(ANDROID_LOG_ERROR, NULL, | |
65 | + "SQL error: %s\n", errmsg); | |
66 | + sqlite3_free(errmsg); | |
67 | + goto out; | |
68 | + } | |
69 | + | |
70 | +out: | |
71 | + sqlite3_close(pDb); | |
72 | + return 0; | |
73 | +} | |
74 | + | |
75 | +int main(int argc, char **argv) | |
76 | +{ | |
77 | + int no_sync = 0, power_off = 0; | |
78 | + int ret; | |
79 | + | |
80 | + opterr = 0; | |
81 | + while ((ret = getopt(argc, argv, "np")) != -1) { | |
82 | + switch (ret) { | |
83 | + case 'n': | |
84 | + no_sync = 1; | |
85 | + break; | |
86 | + case 'p': | |
87 | + power_off = 1; | |
88 | + break; | |
89 | + case '?': | |
90 | + fprintf(stderr, "usage: %s [-n] [-p] [rebootcommand]\n", | |
91 | + argv[0]); | |
92 | + exit(1); | |
93 | + break; | |
94 | + } | |
95 | + } | |
96 | + | |
97 | + if (argc > (optind + 1)) { | |
98 | + fprintf(stderr, "%s: too many arguments\n", argv[0]); | |
99 | + exit(1); | |
100 | + } | |
101 | + | |
102 | + /* BUG: this should use optind */ | |
103 | + if (argc > 1 && !strcmp(argv[1], "oem-78")) { | |
104 | + /* HTC RUU mode: "reboot oem-78" */ | |
105 | + | |
106 | + FILE *f; | |
107 | + char buf[5]; | |
108 | + | |
109 | + checkPatternLock(); | |
110 | + f = fopen(SCREEN_LOCK_STATUS, "r"); | |
111 | + if (!f) { | |
112 | + fputs("5\n", stderr); | |
113 | + exit(0); | |
114 | + } | |
115 | + fgets(buf, 5, f); | |
116 | + if (atoi(buf) == 1) { | |
117 | + if (pattern_lock != 0) { | |
118 | + fputs("1\n", stderr); | |
119 | + exit(0); | |
120 | + } | |
121 | + } | |
122 | + fputs("0\n", stderr); | |
123 | + } | |
124 | + | |
125 | + if (!no_sync) | |
126 | + sync(); | |
127 | + | |
128 | + if (power_off) { | |
129 | + ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, | |
130 | + LINUX_REBOOT_CMD_POWER_OFF, 0); | |
131 | + } else if (optind >= argc) { | |
132 | + ret = reboot(LINUX_REBOOT_CMD_RESTART); | |
133 | + } else { | |
134 | + ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, | |
135 | + LINUX_REBOOT_CMD_RESTART2, argv[optind]); | |
136 | + } | |
137 | + | |
138 | + if (ret < 0) { | |
139 | + perror("reboot"); | |
140 | + exit(1); | |
141 | + } else { | |
142 | + fputs("reboot returned\n", stderr); | |
143 | + exit(0); | |
144 | + } | |
145 | +} |
@@ -67,13 +67,21 @@ public class MainActivity extends BetterListActivity { | ||
67 | 67 | |
68 | 68 | return super.onCreateOptionsMenu(menu); |
69 | 69 | } |
70 | + | |
71 | + private String getArch() { | |
72 | + String prop = System.getProperty("os.arch"); | |
73 | + if (prop.contains("x86") || prop.contains("i686") || prop.contains("i386")) { | |
74 | + return "x86"; | |
75 | + } else if (prop.contains("mips")) { | |
76 | + return "mips"; | |
77 | + } else { | |
78 | + return "armeabi"; | |
79 | + } | |
80 | + } | |
70 | 81 | |
71 | 82 | File extractSu() throws IOException, InterruptedException { |
72 | - String arch = "armeabi"; | |
73 | - if (System.getProperty("os.arch").contains("x86") || System.getProperty("os.arch").contains("i686") || System.getProperty("os.arch").contains("i386")) | |
74 | - arch = "x86"; | |
75 | 83 | ZipFile zf = new ZipFile(getPackageCodePath()); |
76 | - ZipEntry su = zf.getEntry("assets/" + arch + "/su"); | |
84 | + ZipEntry su = zf.getEntry("assets/" + getArch() + "/su"); | |
77 | 85 | InputStream zin = zf.getInputStream(su); |
78 | 86 | File ret = getFileStreamPath("su"); |
79 | 87 | FileOutputStream fout = new FileOutputStream(ret); |
@@ -111,7 +119,7 @@ public class MainActivity extends BetterListActivity { | ||
111 | 119 | zout.close(); |
112 | 120 | |
113 | 121 | ZipFile zf = new ZipFile(getPackageCodePath()); |
114 | - ZipEntry ze = zf.getEntry("assets/reboot"); | |
122 | + ZipEntry ze = zf.getEntry("assets/" + getArch() + "/reboot"); | |
115 | 123 | InputStream in; |
116 | 124 | FileOutputStream reboot; |
117 | 125 | StreamUtility.copyStream(in = zf.getInputStream(ze), reboot = openFileOutput("reboot", MODE_PRIVATE)); |