blob: 231408d8300b5fce728f05ac377188deef1dac93 [file] [log] [blame]
Koushik Duttad632c0d2010-08-16 09:22:18 -07001#include <ctype.h>
2#include <errno.h>
3#include <fcntl.h>
4#include <getopt.h>
5#include <limits.h>
6#include <linux/input.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <sys/reboot.h>
11#include <sys/types.h>
12#include <time.h>
13#include <unistd.h>
14
15#include <sys/wait.h>
16#include <sys/limits.h>
17#include <dirent.h>
18#include <sys/stat.h>
19
20#include <signal.h>
21#include <sys/wait.h>
22
23
24#define RECOVERY_MODE_FILE "/cache/.recovery_mode"
25#define UPDATE_BINARY BOARD_HIJACK_RECOVERY_PATH"/update-binary"
26#define UPDATE_PACKAGE BOARD_HIJACK_RECOVERY_PATH"/recovery.zip"
27#define BUSYBOX BOARD_HIJACK_RECOVERY_PATH"/busybox"
28#define PREPARE_SCRIPT BOARD_HIJACK_RECOVERY_PATH"/prepare.sh"
29
30// This was pulled from bionic: The default system command always looks
31// for shell in /system/bin/sh. This is bad.
32#define _PATH_BSHELL BOARD_HIJACK_RECOVERY_PATH"/sh"
33
34extern char **environ;
35int
36__system(const char *command)
37{
38 pid_t pid;
39 sig_t intsave, quitsave;
40 sigset_t mask, omask;
41 int pstat;
42 char *argp[] = {"sh", "-c", NULL, NULL};
43
44 if (!command) /* just checking... */
45 return(1);
46
47 argp[2] = (char *)command;
48
49 sigemptyset(&mask);
50 sigaddset(&mask, SIGCHLD);
51 sigprocmask(SIG_BLOCK, &mask, &omask);
52 switch (pid = vfork()) {
53 case -1: /* error */
54 sigprocmask(SIG_SETMASK, &omask, NULL);
55 return(-1);
56 case 0: /* child */
57 sigprocmask(SIG_SETMASK, &omask, NULL);
58 execve(_PATH_BSHELL, argp, environ);
59 _exit(127);
60 }
61
62 intsave = (sig_t) bsd_signal(SIGINT, SIG_IGN);
63 quitsave = (sig_t) bsd_signal(SIGQUIT, SIG_IGN);
64 pid = waitpid(pid, (int *)&pstat, 0);
65 sigprocmask(SIG_SETMASK, &omask, NULL);
66 (void)bsd_signal(SIGINT, intsave);
67 (void)bsd_signal(SIGQUIT, quitsave);
68 return (pid == -1 ? -1 : pstat);
69}
70
71int main(int argc, char** argv) {
72 char* hijacked_executable = argv[0];
73 struct stat info;
74
75 if (NULL != strstr(hijacked_executable, "hijack")) {
76 // no op
77 printf("Hijack!\n");
78 return 0;
79 }
80
81 char cmd[PATH_MAX];
82 if (0 == stat(RECOVERY_MODE_FILE, &info)) {
83 remove(RECOVERY_MODE_FILE);
84 kill(getppid(), SIGKILL);
85 sprintf(cmd, "%s 2 0 %s", UPDATE_BINARY, UPDATE_PACKAGE);
86 return __system(cmd);
87 }
88
89 sprintf(cmd, "%s.bin", hijacked_executable);
90 int i;
91 for (i = 1; i < argc; i++) {
92 strcat(cmd, " '");
93 strcat(cmd, argv[i]);
94 strcat(cmd, "'");
95 }
96
97 __system(PREPARE_SCRIPT);
98 return __system(cmd);
99}