/* * This binary allows you to back up the second (recovery) ramdisk on * typical Samsung boot images and to inject a new second ramdisk into * an existing boot image. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * * The code was written from scratch by Dees_Troy dees_troy at * yahoo * * Copyright (c) 2012 */ #include #include #include #include #include #define INJECT_USE_TMP 1 int scan_file_for_data(char *filename, unsigned char *data, int data_size, unsigned long start_location, unsigned long *data_address) { FILE *pFile; unsigned long lSize; unsigned char *buffer, *last_needle = NULL; unsigned char needle[data_size]; size_t result; int i, return_val = 0; pFile = fopen(filename, "rb"); if(pFile==NULL){ printf("Unabled to open file '%s'.\nFailed\n", filename); return -1; } fseek (pFile , 0 , SEEK_END); lSize = ftell(pFile); rewind(pFile); buffer = (unsigned char*)malloc(sizeof(unsigned char) * lSize); if(buffer == NULL){ printf("Memory allocation error on '%s'!\nFailed\n", filename); return -1; } result = fread(buffer, 1, lSize, pFile); if (result != lSize) { printf("Error reading file '%s'\nFailed\n", filename); return -1; } for (i=0; i 6) arg_error = 1; else { strcpy(boot_block_device, "boot"); for (index = 1; index < argc; index++) { len = strlen(argv[index]); if (len > 3 && strncmp(argv[index], "bd=", 3) == 0) { strcpy(boot_block_device, argv[index] + 3); index = argc; } } if ((argc >= 2 && argc <= 4) && (strcmp(argv[1], "-b") == 0 || strcmp(argv[1], "--backup") == 0)) { // Backup existing boot image printf("Dumping boot image...\n"); #ifdef INJECT_USE_TMP sprintf(command, "dump_image %s /tmp/original_boot.img", boot_block_device); system(command); strcpy(boot_image, "/tmp/original_boot.img"); if (argc == 2) strcpy(backup_image, "/tmp/recovery_ramdisk.img"); else strcpy(backup_image, argv[2]); #else system("mount /cache"); sprintf(command, "dump_image %s /cache/original_boot.img", boot_block_device); system(command); strcpy(boot_image, "/cache/original_boot.img"); if (argc == 2) strcpy(backup_image, "/cache/recovery_ramdisk.img"); else strcpy(backup_image, argv[2]); #endif // Check if this is a normal Android image or a Samsung image return_val = scan_file_for_data(boot_image, ®ular_check, 8, 0, &address2); if (return_val >= 0) { printf("This is not a properly formatted Samsung boot image!\nFailed\n"); return 1; } // Find the ramdisk return_val = find_gzip_recovery_ramdisk(boot_image, &address2); if (return_val < 0) { return 1; } backup_recovery_ramdisk(boot_image, address2, backup_image); return 0; } else { // Inject new ramdisk if (strcmp(argv[1], "-d") == 0 || strcmp(argv[1], "--dump") == 0) { printf("Dumping boot image...\n"); #ifdef INJECT_USE_TMP sprintf(command, "dump_image %s /tmp/original_boot.img", boot_block_device); system(command); strcpy(boot_image, "/tmp/original_boot.img"); #else system("mount /cache"); sprintf(command, "dump_image %s /cache/original_boot.img", boot_block_device); system(command); strcpy(boot_image, "/cache/original_boot.img"); delete_ind = -1; #endif } else strcpy(boot_image, argv[1]); // Check if this is a normal Android image or a Samsung image return_val = scan_file_for_data(boot_image, ®ular_check, 8, 0, &address2); if (return_val >= 0) { printf("This is not a properly formatted Samsung boot image!\nFailed\n"); return 1; } // Find the ramdisk return_val = find_gzip_recovery_ramdisk(boot_image, &address2); if (return_val < 0) { return 1; } // Write the new image write_new_ramdisk(boot_image, argv[2], address2, argv[3]); // Delete --dump image if needed if (delete_ind) { printf("Deleting dumped boot image from /cache\n"); system("rm /cache/original_boot.img"); } if (argc >= 5 && (strcmp(argv[4], "-f") == 0 || strcmp(argv[4], "--flash") == 0)) { printf("Flashing new image...\n"); sprintf(command, "erase_image %s", boot_block_device); system(command); sprintf(command, "flash_image %s %s", boot_block_device, argv[3]); system(command); printf("Flash complete.\n"); } return 0; } } if (arg_error) { printf("Invalid arguments supplied.\n"); printf("Usage:\n\n"); printf("Backup existing recovery ramdisk (requires dump_image):\n"); printf("injecttwrp --backup [optionalbackuplocation.img]\n\n"); printf("Inject new recovery ramdisk:\n"); printf("injecttwrp originalboot.img ramdisk-recovery.img outputboot.img\n"); printf("injecttwrp --dump ramdisk-recovery.img outputboot.img [--flash]\n"); printf("--dump will use dump_image to dump your existing boot image\n"); printf("--flash will use flash_image to flash the new boot image\n\n"); printf("NOTE: dump_image, erase_image, and flash_image must already be installed!\n\n"); printf("If needed you can add bd=/dev/block/mmcblk0p5 to indicate the location\n"); printf("of the boot partition on emmc devices as the final parameter.\n"); return 0; } return 0; }