hijack executable
diff --git a/hijack/Android.mk b/hijack/Android.mk
new file mode 100644
index 0000000..f877f39
--- /dev/null
+++ b/hijack/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH := $(call my-dir)
+
+ifdef BOARD_HIJACK_RECOVERY_PATH
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := hijack.c
+LOCAL_MODULE := hijack
+LOCAL_MODULE_TAGS := eng
+LOCAL_STATIC_LIBRARIES := libmtdutils libcutils libc
+LOCAL_FORCE_STATIC_EXECUTABLE := true
+LOCAL_CFLAGS += -DBOARD_HIJACK_RECOVERY_PATH=\"$(BOARD_HIJACK_RECOVERY_PATH)\"
+include $(BUILD_EXECUTABLE)
+
+endif
diff --git a/hijack/hijack.c b/hijack/hijack.c
new file mode 100644
index 0000000..231408d
--- /dev/null
+++ b/hijack/hijack.c
@@ -0,0 +1,99 @@
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <limits.h>
+#include <linux/input.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/reboot.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/wait.h>
+#include <sys/limits.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include <signal.h>
+#include <sys/wait.h>
+
+
+#define RECOVERY_MODE_FILE "/cache/.recovery_mode"
+#define UPDATE_BINARY BOARD_HIJACK_RECOVERY_PATH"/update-binary"
+#define UPDATE_PACKAGE BOARD_HIJACK_RECOVERY_PATH"/recovery.zip"
+#define BUSYBOX BOARD_HIJACK_RECOVERY_PATH"/busybox"
+#define PREPARE_SCRIPT BOARD_HIJACK_RECOVERY_PATH"/prepare.sh"
+
+// This was pulled from bionic: The default system command always looks
+// for shell in /system/bin/sh. This is bad.
+#define _PATH_BSHELL BOARD_HIJACK_RECOVERY_PATH"/sh"
+
+extern char **environ;
+int
+__system(const char *command)
+{
+  pid_t pid;
+    sig_t intsave, quitsave;
+    sigset_t mask, omask;
+    int pstat;
+    char *argp[] = {"sh", "-c", NULL, NULL};
+
+    if (!command)        /* just checking... */
+        return(1);
+
+    argp[2] = (char *)command;
+
+    sigemptyset(&mask);
+    sigaddset(&mask, SIGCHLD);
+    sigprocmask(SIG_BLOCK, &mask, &omask);
+    switch (pid = vfork()) {
+    case -1:            /* error */
+        sigprocmask(SIG_SETMASK, &omask, NULL);
+        return(-1);
+    case 0:                /* child */
+        sigprocmask(SIG_SETMASK, &omask, NULL);
+        execve(_PATH_BSHELL, argp, environ);
+    _exit(127);
+  }
+
+    intsave = (sig_t)  bsd_signal(SIGINT, SIG_IGN);
+    quitsave = (sig_t) bsd_signal(SIGQUIT, SIG_IGN);
+    pid = waitpid(pid, (int *)&pstat, 0);
+    sigprocmask(SIG_SETMASK, &omask, NULL);
+    (void)bsd_signal(SIGINT, intsave);
+    (void)bsd_signal(SIGQUIT, quitsave);
+    return (pid == -1 ? -1 : pstat);
+}
+
+int main(int argc, char** argv) {
+    char* hijacked_executable = argv[0];
+    struct stat info;
+    
+    if (NULL != strstr(hijacked_executable, "hijack")) {
+        // no op
+        printf("Hijack!\n");
+        return 0;
+    }
+
+    char cmd[PATH_MAX];
+    if (0 == stat(RECOVERY_MODE_FILE, &info)) {
+        remove(RECOVERY_MODE_FILE);
+        kill(getppid(), SIGKILL);
+        sprintf(cmd, "%s 2 0 %s", UPDATE_BINARY, UPDATE_PACKAGE);
+        return __system(cmd);
+    }
+    
+    sprintf(cmd, "%s.bin", hijacked_executable);
+    int i;
+    for (i = 1; i < argc; i++) {
+        strcat(cmd, " '");
+        strcat(cmd, argv[i]);
+        strcat(cmd, "'");
+    }
+    
+    __system(PREPARE_SCRIPT);
+    return __system(cmd);
+}
diff --git a/hijack/prepare.sh b/hijack/prepare.sh
new file mode 100644
index 0000000..cfa6322
--- /dev/null
+++ b/hijack/prepare.sh
@@ -0,0 +1,4 @@
+#!/preinstall/recovery/sh
+export PATH=$PATH:/preinstall/recovery
+busybox mount -orw,remount /
+busybox mkdir -p /res/images