Пример #1
0
int find_gzip_recovery_ramdisk(char *boot_image, unsigned long *ramdisk_address) {
	unsigned char gzip_ramdisk[6] = {0x00, 0x00, 0x00, 0x00, 0x1f, 0x8b};
	unsigned long address1, address2;
	int return_val;

	// Find the first ramdisk
	return_val = scan_file_for_data(boot_image, &gzip_ramdisk, 6, 0, &address1);
	if (return_val < 0) {
		printf("No ramdisk found in '%s'\nFailed\n", boot_image);
		printf("This boot image may not be using gzip compression.\n");
		return -1;
	}
	address1 -= 2;
	printf("Ramdisk found in '%s' at offset 0x%08x\n", boot_image, address1);

	// Find the second (recovery) ramdisk
	return_val = scan_file_for_data(boot_image, &gzip_ramdisk, 6, address1 + 50, &address2);
	if (return_val < 0) {
		printf("No recovery ramdisk found in '%s'\nFailed\n", boot_image, address2);
		return -1;
	}
	address2 -= 2;
	printf("Recovery ramdisk found in '%s' at offset 0x%08x\n", boot_image, address2);

	*ramdisk_address = address2;
	return 0;
}
void extract_ramdisk() {
    int elf_fd, return_val = 0;
    Elf *e;
    GElf_Phdr phdr;
    char elf_filename[PATH_MAX], output[PATH_MAX], output2[PATH_MAX];
    char command[4096];
    size_t result;
    unsigned long fota_location;

    // Make sure that tmp_dir ends with a /
    if (tmp_dir[strlen(tmp_dir) - 1] != '/')
        strcat(tmp_dir, "/");

    if (elf_version(EV_CURRENT) == EV_NONE) {
        printf("ELF library initialization failed.\n");
        exit(-1);
    }

    if (use_dump_image) {
        strcpy(elf_filename, tmp_dir);
        strcat(elf_filename, "dumped.elf");
        printf("Dumping image to '%s'\n", elf_filename);
        sprintf(command, "dump_image '%s' '%s'\n", input_filename,
                elf_filename);
        __system(command);
    } else {
        strcpy(elf_filename, input_filename);
    }

    if ((elf_fd = open(elf_filename, O_RDONLY, 0)) < 0) {
        printf("Unable to open '%s' for read.\n", elf_filename);
        exit(-1);
    }

    if ((e = elf_begin(elf_fd, ELF_C_READ, NULL)) == NULL) {
        printf("elf_begin failed.\n");
        close(elf_fd);
        exit(-1);
    }

    if (elf_kind(e) != ELF_K_ELF) {
        printf("'%s' is not an ELF file.\n", elf_filename);
        elf_end(e);
        close(elf_fd);
        exit(-1);
    }

    if (gelf_getphdr(e, ramdisk_loc - 1, &phdr) != &phdr) {
        printf("Failed to get header %i\n", ramdisk_loc - 1);
        elf_end(e);
        close(elf_fd);
        exit(-1);
    }
    printf("Offset:      %llu\n", phdr.p_offset);
    printf("Size:        %llu\n", phdr.p_filesz);
    // printf("Flags:       %ll\n", phdr.e_flags); Does not exist in Android's
    //                                             libelf
    elf_end(e);
    close(elf_fd);

    if (dont_unzip) {
        strcpy(output, output_filename);
    } else {
        strcpy(output, tmp_dir);
        strcat(output, EER_TMP_RAMDISK_GZ);
        if (path_exists(output) && unlink(output)) {
            printf("Unable to unlink '%s'\n", output);
            exit(-1);
        }
    }

    copy_file_part(elf_filename, output, (unsigned long) phdr.p_offset,
                   (unsigned long) phdr.p_filesz);

    if (!dont_unzip) {
        if (check_ramdisk) {
            strcpy(output2, tmp_dir);
            strcat(output2, EER_TMP_RAMDISK_CPIO);
        } else {
            unlink(output_filename);
            strcpy(output2, output_filename);
        }
        sprintf(command, "busybox gunzip -c '%s' > '%s'", output,
                output2);
        __system(command);
        unlink(output);
        printf("Uncompressed ramdisk written to '%s'\n", output2);
        if (check_ramdisk) {
            printf("Checking ramdisk to ensure it is not a stock Sony ");
            printf("recovery.\n");
            printf("  (Checking for %s)\n", EER_SEARCH_STRING);
            // Find the ramdisk offset table
            unsigned char needle[7] = EER_SEARCH_STRING;
            return_val = scan_file_for_data(output2, needle, sizeof(needle), 0,
                                            &fota_location);
            if (return_val < 0) {
                printf("This is not a stock Sony recovery ramdisk.\n");
                copy_file_part(output2, output_filename, 0, 0);
                printf("Ramdisk copied to '%s'\nDONE!\n", output_filename);
            } else {
                printf("This is a stock Sony recovery ramdisk.\n");
                printf("Ramdisk NOT copied to '%s'\n", output_filename);
            }
            unlink(output2);
        } else {
            printf("DONE!\n");
        }
    } else {
        printf("Ramdisk copied to '%s'\nDONE!\n", output_filename);
    }
}
Пример #3
0
int write_new_ramdisk(char *bootimage, char *newramdisk, unsigned long start_location, char *outputimage) {
	FILE *bFile; // bootimage
	FILE *rFile; // ramdisk
	FILE *oFile; // output file
	unsigned long blSize, rlSize, offset_table, ramdisk_len;
	unsigned char *bbuffer, *rbuffer;
	size_t result;
	int return_val;

	// Read the original boot image
	printf("Reading the original boot image...\n");
	bFile = fopen(bootimage, "rb");
	if(bFile==NULL){
		printf("Unabled to open original boot image '%s'.\nFailed\n", bootimage);
		exit(0);
	}

	fseek (bFile , 0 , SEEK_END);
	blSize = ftell(bFile);
	rewind(bFile);
	printf("Size of original boot is %lu\n", blSize);

	bbuffer = (unsigned char*)malloc(sizeof(unsigned char) * blSize);
	if(bbuffer == NULL){
		printf("File read error on original boot image '%s'!\nFailed\n", bootimage);
		exit(0);
	}

	result = fread(bbuffer, 1, blSize, bFile);
	if (result != blSize) {
		printf("Error reading original boot image '%s'\nFailed\n", bootimage);
		exit(0);
	}

	// Find the ramdisk offset table
	unsigned char needle[13] = "recovery_len=";
	return_val = scan_file_for_data(bootimage, &needle, 13, 0, &offset_table);
	if (return_val < 0) {
		fclose(bFile);
		printf("Ramdisk offset table not found in %s!\nFailed\n", bootimage);
		exit(0);
	}
	printf("Ramdisk offset table found at 0x%08x\n", offset_table);

	// Read the ramdisk to insert into the boot image
	printf("Reading the ramdisk...\n");
	rFile = fopen(newramdisk, "rb");
	if(rFile==NULL){
		printf("Unabled to open ramdisk image '%s'.\nFailed\n", newramdisk);
		exit(0);
	}

	fseek (rFile , 0 , SEEK_END);
	rlSize = ftell(rFile);
	rewind(rFile);
	printf("Size of new ramdisk is %lu\n", rlSize);
	ramdisk_len = rlSize / 512;
	if ((rlSize % 512) != 0)
		ramdisk_len++;
	printf("Ramdisk length for offset table: %lu\n", ramdisk_len);

	rbuffer = (unsigned char*)malloc(sizeof(unsigned char) * blSize);
	if(rbuffer == NULL){
		printf("File read error on ramdisk image '%s'!\nFailed\n", newramdisk);
		exit(0);
	}

	result = fread(rbuffer, 1, rlSize, rFile);
	if (result != rlSize) {
		printf("Error reading ramdisk image '%s'\nFailed\n", newramdisk);
		exit(0);
	}

	// Open the output image for writing
	printf("Opening the output image for writing...\n");
	oFile = fopen(outputimage, "wb");
	if(oFile==NULL){
		printf("Unabled to open output image '%s'.\nFailed\n", outputimage);
		exit(0);
	}

	printf("Writing kernel and first ramdisk...\n");
	result = fwrite(bbuffer, 1, start_location - 1, oFile);
	if (result != start_location - 1) {
		printf("Write count does not match! (1)\n");
	}
	fseek(oFile, start_location, SEEK_SET);
	printf("Writing new second ramdisk...\n");
	result = fwrite(rbuffer, 1, rlSize, oFile);
	if (result != rlSize) {
		printf("Write count does not match! (2)\n");
	} else {
		printf("Finished writing new boot image '%s'\n", outputimage);
	}

	// Write new ramdisk_len to offset table
	printf("Writing new ramdisk length to offset table...\n");
	fseek(oFile, offset_table, SEEK_SET);
	char ramdisk_lens[20];
	sprintf(ramdisk_lens, "%lu;\n\n", ramdisk_len);
	fwrite(ramdisk_lens, 1, strlen(ramdisk_lens), oFile);

	fclose(bFile);
	fclose(rFile);
	fclose(oFile);
	free(bbuffer);
	free(rbuffer);

	printf("All done writing new image: '%s'\n", outputimage);
	return 1;
}
Пример #4
0
int main(int argc, char** argv) {
	int arg_error = 0, delete_ind = 0, return_val, index, len;
	unsigned long address2;
	unsigned char regular_check[8] = "ANDROID!";
	char boot_image[512], backup_image[512], boot_block_device[512], command[512];

	printf("-- InjectTWRP Recovery Ramdisk Injection Tool for Samsung devices. --\n");
	printf("--                  by Dees_Troy and Team Win                      --\n");
	printf("--                       http://teamw.in                           --\n");
	printf("--                Bringing some win to Samsung!                    --\n");
	printf("--        This tool comes with no warranties whatsoever!           --\n");
	printf("--        Use at your own risk and always keep a backup!           --\n\n");
	printf("Version 0.2 beta\n\n");

	// Parse the arguments
	if (argc < 2 || argc > 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, &regular_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, &regular_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;
}
Пример #5
0
int backup_recovery_ramdisk(char *bootimage, unsigned long start_location, char *outputimage) {
	FILE *bFile; // bootimage
	FILE *rFile; // ramdisk
	FILE *oFile; // output file
	unsigned long blSize, offset_table, ramdisk_len;
	unsigned char *bbuffer;
	size_t result;
	unsigned char ramdisk_lens[4], *p;
	int return_val, i;

	// Read the original boot image
	printf("Reading the original boot image...\n");
	bFile = fopen(bootimage, "rb");
	if(bFile==NULL){
		printf("Unabled to open original boot image '%s'.\nFailed\n", bootimage);
		exit(0);
	}

	fseek (bFile , 0 , SEEK_END);
	blSize = ftell(bFile);
	rewind(bFile);
	printf("Size of original boot is %lu\n", blSize);

	bbuffer = (unsigned char*)malloc(sizeof(unsigned char) * blSize);
	if(bbuffer == NULL){
		printf("File read error on original boot image '%s'!\nFailed\n", bootimage);
		exit(0);
	}

	result = fread(bbuffer, 1, blSize, bFile);
	if (result != blSize) {
		printf("Error reading original boot image '%s'\nFailed\n", bootimage);
		exit(0);
	}

	// Find the ramdisk offset table
	unsigned char needle[13] = "recovery_len=";
	return_val = scan_file_for_data(bootimage, &needle, 13, 0, &offset_table);
	if (return_val < 0) {
		fclose(bFile);
		printf("Ramdisk offset table not found in %s!\nFailed\n", bootimage);
		exit(0);
	}
	printf("Ramdisk offset table found at 0x%08x\n", offset_table);
	for (i=0; i<4; i++) {
		p = bbuffer + offset_table + i;
		if (*p == ';') {
			ramdisk_lens[i] = 0;
		} else {
			ramdisk_lens[i] = *p;
		}
	}
	ramdisk_len = atoi(ramdisk_lens);
	ramdisk_len *= 512;
	printf("Ramdisk length: %lu\n", ramdisk_len);

	// Open the output image for writing
	printf("Opening the output image for writing...\n");
	oFile = fopen(outputimage, "wb");
	if(oFile==NULL){
		printf("Unabled to open output image '%s'.\nFailed\n", outputimage);
		exit(0);
	}

	printf("Writing backup ramdisk...\n");
	result = fwrite(bbuffer + start_location, 1, ramdisk_len, oFile);
	if (result != ramdisk_len) {
		printf("Write count does not match! (1)\n");
	} else {
		printf("Finished backing up ramdisk image '%s'\n", outputimage);
	}

	fclose(bFile);
	fclose(oFile);
	free(bbuffer);
	return 1;
}