/* * backdoorpw.c * * This will search the drive specified as argv[1], initially making * sure it is a TiVo drive. If so, it will attempt to open the first * MFS Application region partition, searching for either the v3.x * or v4.0 backdoor SHA hashes. If found, it will patch them with a * "known" code -- the code is an empty SHA string. This will allow * the user to enable backdoors by going into the "Search by Title" * screen and pressing the "Thumbs Up" key. * * Created by Steve White on Fri Apr 18 2003. * Copyright (c) 2003 Steve White. All rights reserved. * */ #include #include #include #include #include char KNOWNCODES[][41] = { "5CA5D9DBE5338BAB8690C79C9A9310BCD3A8F23B", // 3.0 (FWIW the code is '3 0 BC') "96F8B204FD99534759A6C11A181EEDDFEB2DF1D4", // 3.1/3.2 "61508C7FC1C2250E1794624D8619B9ED760FFABA", // 4.0 GM }; char newcode[40] = "EEA339DA0D4B6B5EEFBF5532901860950907D8AF"; #define NUMOFCODES sizeof(KNOWNCODES)/41 int checkDriveSignature(char *drive); int searchAndReplaceHashes(char *mfsapp); int main(int argc, char **argv) { char mfsapp[10]; int result=0; if (argc < 2) { printf("usage: %s \n", argv[0]); printf(" i.e. If your TiVo drive is hooked up as Secondary Master, you would execute:\n"); printf(" %s /dev/hdc\n", argv[0]); exit(EXIT_FAILURE); } if (checkDriveSignature(argv[1]) == -1) exit(EXIT_FAILURE); sprintf(mfsapp, "%s10", argv[1]); result += searchAndReplaceHashes(mfsapp); if (result == 0) printf("Unable to find any occurrences of the backdoor hashes on %s\n", mfsapp); sprintf(mfsapp, "%s12", argv[1]); result += searchAndReplaceHashes(mfsapp); if (result == 0) printf("Unable to find any occurrences of the backdoor hashes on %s\n", mfsapp); if (result <= 0) exit(EXIT_FAILURE); printf("Success! You may now put the drive back in your TiVo.\n"); printf("To enable backdoor mode, go into 'Search by Title' and press thumbsup.\n"); exit(EXIT_SUCCESS); } int checkDriveSignature(char *drive) { unsigned char signature[2]; int fp; if ( (fp = open(drive, O_RDONLY)) < 0) { printf("Error opening device %s\n", drive); return -1; } read(fp, &signature, 2); close(fp); if (signature[0] == 0x14 && signature[1] == 0x92) { printf("Good! This is a TiVo drive\n"); return 0; } else if (signature[0] == 0x92 && signature[1] == 0x14) { printf("Bad! This is a TiVo drive, but the bytes are swapped\n"); printf("If you have a Series1 you need to enable drive byteswapping.\n"); printf("If you have a Series2 you need to disable drive byteswapping.\n"); printf("Please reboot your system and select the proper byteswapping for this drive.\n"); return -1; } else { printf("Bad! This is not a TiVo drive.\n"); return -1; } return -1; } int searchAndReplaceHashes(char *mfsapp) { unsigned char data[1048576]; // 1MB buffer int fp,i,hashCount=0,readsize=strlen(data); char *position; long curoffset; printf("Opening MFS Application Region partition: %s...\n", mfsapp); if ((fp = open(mfsapp, O_RDWR)) < 0) { printf("Unable to open %s for writing!\n", mfsapp); return -1; } while (read(fp, &data, readsize) == readsize) { curoffset = lseek(fp, 0, SEEK_CUR); // cheap hack to strstr to work "properly" for (i=0; i