summaryrefslogtreecommitdiff
path: root/rbutil/sansapatcher/sansapatcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/sansapatcher/sansapatcher.c')
-rw-r--r--rbutil/sansapatcher/sansapatcher.c104
1 files changed, 51 insertions, 53 deletions
diff --git a/rbutil/sansapatcher/sansapatcher.c b/rbutil/sansapatcher/sansapatcher.c
index 9297f36e02..5cf7d8ae75 100644
--- a/rbutil/sansapatcher/sansapatcher.c
+++ b/rbutil/sansapatcher/sansapatcher.c
@@ -43,8 +43,6 @@ int sansa_verbose = 0;
43 and initialise it with sansa_alloc_buf() in main(). 43 and initialise it with sansa_alloc_buf() in main().
44*/ 44*/
45 45
46unsigned char* sansa_sectorbuf = NULL;
47
48static off_t filesize(int fd) { 46static off_t filesize(int fd) {
49 struct stat buf; 47 struct stat buf;
50 48
@@ -92,17 +90,17 @@ int sansa_read_partinfo(struct sansa_t* sansa, int silent)
92 int i; 90 int i;
93 unsigned long count; 91 unsigned long count;
94 92
95 count = sansa_read(sansa,sansa_sectorbuf, sansa->sector_size); 93 count = sansa_read(sansa,sansa->sectorbuf, sansa->sector_size);
96 94
97 if (count <= 0) { 95 if (count <= 0) {
98 sansa_print_error(" Error reading from disk: "); 96 sansa_print_error(" Error reading from disk: ");
99 return -1; 97 return -1;
100 } 98 }
101 99
102 if ((sansa_sectorbuf[510] == 0x55) && (sansa_sectorbuf[511] == 0xaa)) { 100 if ((sansa->sectorbuf[510] == 0x55) && (sansa->sectorbuf[511] == 0xaa)) {
103 /* parse partitions */ 101 /* parse partitions */
104 for ( i = 0; i < 4; i++ ) { 102 for ( i = 0; i < 4; i++ ) {
105 unsigned char* ptr = sansa_sectorbuf + 0x1be + 16*i; 103 unsigned char* ptr = sansa->sectorbuf + 0x1be + 16*i;
106 sansa->pinfo[i].type = ptr[4]; 104 sansa->pinfo[i].type = ptr[4];
107 sansa->pinfo[i].start = BYTES2INT32(ptr, 8); 105 sansa->pinfo[i].start = BYTES2INT32(ptr, 8);
108 sansa->pinfo[i].size = BYTES2INT32(ptr, 12); 106 sansa->pinfo[i].size = BYTES2INT32(ptr, 12);
@@ -112,7 +110,7 @@ int sansa_read_partinfo(struct sansa_t* sansa, int silent)
112 /* not handled yet */ 110 /* not handled yet */
113 } 111 }
114 } 112 }
115 } else if ((sansa_sectorbuf[0] == 'E') && (sansa_sectorbuf[1] == 'R')) { 113 } else if ((sansa->sectorbuf[0] == 'E') && (sansa->sectorbuf[1] == 'R')) {
116 if (!silent) fprintf(stderr,"[ERR] Bad boot sector signature\n"); 114 if (!silent) fprintf(stderr,"[ERR] Bad boot sector signature\n");
117 return -1; 115 return -1;
118 } 116 }
@@ -406,14 +404,14 @@ int is_sansa(struct sansa_t* sansa)
406 } 404 }
407 405
408 /* Check Bootloader header */ 406 /* Check Bootloader header */
409 if (sansa_seek_and_read(sansa, sansa->start, sansa_sectorbuf, 0x200) < 0) { 407 if (sansa_seek_and_read(sansa, sansa->start, sansa->sectorbuf, 0x200) < 0) {
410 return -2; 408 return -2;
411 } 409 }
412 if (memcmp(sansa_sectorbuf,"PPBL",4)!=0) { 410 if (memcmp(sansa->sectorbuf,"PPBL",4)!=0) {
413 /* No bootloader header, abort */ 411 /* No bootloader header, abort */
414 return -4; 412 return -4;
415 } 413 }
416 ppbl_length = (le2int(sansa_sectorbuf+4) + 0x1ff) & ~0x1ff; 414 ppbl_length = (le2int(sansa->sectorbuf+4) + 0x1ff) & ~0x1ff;
417 415
418 /* Sanity/safety check - the bootloader can't be larger than PPMI_OFFSET */ 416 /* Sanity/safety check - the bootloader can't be larger than PPMI_OFFSET */
419 if (ppbl_length > PPMI_OFFSET) 417 if (ppbl_length > PPMI_OFFSET)
@@ -422,12 +420,12 @@ int is_sansa(struct sansa_t* sansa)
422 } 420 }
423 421
424 /* Load Sansa bootloader and check for "Sansa C200" magic string */ 422 /* Load Sansa bootloader and check for "Sansa C200" magic string */
425 if (sansa_seek_and_read(sansa, sansa->start + 0x200, sansa_sectorbuf, ppbl_length) < 0) { 423 if (sansa_seek_and_read(sansa, sansa->start + 0x200, sansa->sectorbuf, ppbl_length) < 0) {
426 fprintf(stderr,"[ERR] Seek and read to 0x%08llx in is_sansa failed.\n", 424 fprintf(stderr,"[ERR] Seek and read to 0x%08llx in is_sansa failed.\n",
427 sansa->start+0x200); 425 sansa->start+0x200);
428 return -6; 426 return -6;
429 } 427 }
430 if (sansa_memmem(sansa_sectorbuf, ppbl_length, "Sansa C200", 10) != NULL) { 428 if (sansa_memmem(sansa->sectorbuf, ppbl_length, "Sansa C200", 10) != NULL) {
431 /* C200 */ 429 /* C200 */
432 sansa->targetname="c200"; 430 sansa->targetname="c200";
433 } else { 431 } else {
@@ -436,25 +434,25 @@ int is_sansa(struct sansa_t* sansa)
436 } 434 }
437 435
438 /* Check Main firmware header */ 436 /* Check Main firmware header */
439 if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sansa_sectorbuf, 0x200) < 0) { 437 if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sansa->sectorbuf, 0x200) < 0) {
440 fprintf(stderr,"[ERR] Seek to 0x%08llx in is_sansa failed.\n", 438 fprintf(stderr,"[ERR] Seek to 0x%08llx in is_sansa failed.\n",
441 sansa->start+PPMI_OFFSET); 439 sansa->start+PPMI_OFFSET);
442 return -5; 440 return -5;
443 } 441 }
444 if (memcmp(sansa_sectorbuf,"PPMI",4)!=0) { 442 if (memcmp(sansa->sectorbuf,"PPMI",4)!=0) {
445 /* No bootloader header, abort */ 443 /* No bootloader header, abort */
446 return -7; 444 return -7;
447 } 445 }
448 ppmi_length = le2int(sansa_sectorbuf+4); 446 ppmi_length = le2int(sansa->sectorbuf+4);
449 447
450 /* Check main mi4 file header */ 448 /* Check main mi4 file header */
451 if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET+0x200, sansa_sectorbuf, 0x200) < 0) { 449 if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET+0x200, sansa->sectorbuf, 0x200) < 0) {
452 fprintf(stderr,"[ERR] Seek to 0x%08llx in is_sansa failed.\n", 450 fprintf(stderr,"[ERR] Seek to 0x%08llx in is_sansa failed.\n",
453 sansa->start+PPMI_OFFSET+0x200); 451 sansa->start+PPMI_OFFSET+0x200);
454 return -5; 452 return -5;
455 } 453 }
456 454
457 if (get_mi4header(sansa_sectorbuf,&mi4header) < 0) { 455 if (get_mi4header(sansa->sectorbuf,&mi4header) < 0) {
458 fprintf(stderr,"[ERR] Invalid mi4header\n"); 456 fprintf(stderr,"[ERR] Invalid mi4header\n");
459 return -6; 457 return -6;
460 } 458 }
@@ -466,15 +464,15 @@ int is_sansa(struct sansa_t* sansa)
466 */ 464 */
467 465
468 sansa->hasoldbootloader = 0; 466 sansa->hasoldbootloader = 0;
469 if (memcmp(sansa_sectorbuf+0x1f8,"RBBL",4)==0) { 467 if (memcmp(sansa->sectorbuf+0x1f8,"RBBL",4)==0) {
470 /* Look for an original firmware after the first image */ 468 /* Look for an original firmware after the first image */
471 if (sansa_seek_and_read(sansa, 469 if (sansa_seek_and_read(sansa,
472 sansa->start + PPMI_OFFSET + 0x200 + ppmi_length, 470 sansa->start + PPMI_OFFSET + 0x200 + ppmi_length,
473 sansa_sectorbuf, 512) < 0) { 471 sansa->sectorbuf, 512) < 0) {
474 return -7; 472 return -7;
475 } 473 }
476 474
477 if (get_mi4header(sansa_sectorbuf,&mi4header)!=0) { 475 if (get_mi4header(sansa->sectorbuf,&mi4header)!=0) {
478 fprintf(stderr,"[ERR] No original firmware found\n"); 476 fprintf(stderr,"[ERR] No original firmware found\n");
479 sansa->hasoldbootloader = 1; 477 sansa->hasoldbootloader = 1;
480 } 478 }
@@ -659,7 +657,7 @@ int sansa_read_firmware(struct sansa_t* sansa, const char* filename)
659 int outfile; 657 int outfile;
660 struct mi4header_t mi4header; 658 struct mi4header_t mi4header;
661 659
662 res = load_original_firmware(sansa,sansa_sectorbuf,&mi4header); 660 res = load_original_firmware(sansa,sansa->sectorbuf,&mi4header);
663 if (res < 0) 661 if (res < 0)
664 return res; 662 return res;
665 663
@@ -669,7 +667,7 @@ int sansa_read_firmware(struct sansa_t* sansa, const char* filename)
669 return -1; 667 return -1;
670 } 668 }
671 669
672 res = write(outfile,sansa_sectorbuf,mi4header.mi4size); 670 res = write(outfile,sansa->sectorbuf,mi4header.mi4size);
673 if (res != (int)mi4header.mi4size) { 671 if (res != (int)mi4header.mi4size) {
674 fprintf(stderr,"[ERR] Write error - %d\n", res); 672 fprintf(stderr,"[ERR] Write error - %d\n", res);
675 return -1; 673 return -1;
@@ -730,16 +728,16 @@ int sansa_add_bootloader(struct sansa_t* sansa, const unsigned char* bootloader,
730 int n; 728 int n;
731 729
732 /* Create PPMI header */ 730 /* Create PPMI header */
733 memset(sansa_sectorbuf,0,0x200); 731 memset(sansa->sectorbuf,0,0x200);
734 memcpy(sansa_sectorbuf,"PPMI",4); 732 memcpy(sansa->sectorbuf,"PPMI",4);
735 int2le(bl_length, sansa_sectorbuf+4); 733 int2le(bl_length, sansa->sectorbuf+4);
736 int2le(0x00020000, sansa_sectorbuf+8); 734 int2le(0x00020000, sansa->sectorbuf+8);
737 735
738 /* copy bootloader to sansa_sectorbuf+0x200 */ 736 /* copy bootloader to sansa->sectorbuf+0x200 */
739 memcpy(sansa_sectorbuf+0x200,bootloader,bl_length); 737 memcpy(sansa->sectorbuf+0x200,bootloader,bl_length);
740 738
741 /* Load original firmware from Sansa to the space after the bootloader */ 739 /* Load original firmware from Sansa to the space after the bootloader */
742 res = load_original_firmware(sansa,sansa_sectorbuf+0x200+bl_length,&mi4header); 740 res = load_original_firmware(sansa,sansa->sectorbuf+0x200+bl_length,&mi4header);
743 if (res < 0) 741 if (res < 0)
744 return res; 742 return res;
745 743
@@ -753,7 +751,7 @@ int sansa_add_bootloader(struct sansa_t* sansa, const unsigned char* bootloader,
753 751
754 length = 0x200 + bl_length + mi4header.mi4size; 752 length = 0x200 + bl_length + mi4header.mi4size;
755 753
756 n=sansa_write(sansa, sansa_sectorbuf, length); 754 n=sansa_write(sansa, length);
757 if (n < length) { 755 if (n < length) {
758 fprintf(stderr,"[ERR] Short write in add_bootloader\n"); 756 fprintf(stderr,"[ERR] Short write in add_bootloader\n");
759 return -6; 757 return -6;
@@ -769,16 +767,16 @@ int sansa_delete_bootloader(struct sansa_t* sansa)
769 int n; 767 int n;
770 int length; 768 int length;
771 769
772 /* Load original firmware from Sansa to sansa_sectorbuf+0x200 */ 770 /* Load original firmware from Sansa to sansa->sectorbuf+0x200 */
773 res = load_original_firmware(sansa,sansa_sectorbuf+0x200,&mi4header); 771 res = load_original_firmware(sansa,sansa->sectorbuf+0x200,&mi4header);
774 if (res < 0) 772 if (res < 0)
775 return res; 773 return res;
776 774
777 /* Create PPMI header */ 775 /* Create PPMI header */
778 memset(sansa_sectorbuf,0,0x200); 776 memset(sansa->sectorbuf,0,0x200);
779 memcpy(sansa_sectorbuf,"PPMI",4); 777 memcpy(sansa->sectorbuf,"PPMI",4);
780 int2le(mi4header.mi4size, sansa_sectorbuf+4); 778 int2le(mi4header.mi4size, sansa->sectorbuf+4);
781 int2le(0x00020000, sansa_sectorbuf+8); 779 int2le(0x00020000, sansa->sectorbuf+8);
782 780
783 /* Now write the whole thing back to the Sansa */ 781 /* Now write the whole thing back to the Sansa */
784 782
@@ -790,7 +788,7 @@ int sansa_delete_bootloader(struct sansa_t* sansa)
790 788
791 length = 0x200 + mi4header.mi4size; 789 length = 0x200 + mi4header.mi4size;
792 790
793 n=sansa_write(sansa, sansa_sectorbuf, length); 791 n=sansa_write(sansa, length);
794 if (n < length) { 792 if (n < length) {
795 fprintf(stderr,"[ERR] Short write in delete_bootloader\n"); 793 fprintf(stderr,"[ERR] Short write in delete_bootloader\n");
796 return -6; 794 return -6;
@@ -808,21 +806,21 @@ int sansa_list_images(struct sansa_t* sansa)
808 int num = 0; 806 int num = 0;
809 807
810 /* Check Main firmware header */ 808 /* Check Main firmware header */
811 if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sansa_sectorbuf, 0x200) < 0) { 809 if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sansa->sectorbuf, 0x200) < 0) {
812 return 0; 810 return 0;
813 } 811 }
814 812
815 ppmi_length = le2int(sansa_sectorbuf+4); 813 ppmi_length = le2int(sansa->sectorbuf+4);
816 814
817 printf("[INFO] Image 1 - %llu bytes\n",ppmi_length); 815 printf("[INFO] Image 1 - %llu bytes\n",ppmi_length);
818 num = 1; 816 num = 1;
819 817
820 /* Look for an original firmware after the first image */ 818 /* Look for an original firmware after the first image */
821 if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET + 0x200 + ppmi_length, sansa_sectorbuf, 512) < 0) { 819 if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET + 0x200 + ppmi_length, sansa->sectorbuf, 512) < 0) {
822 return 0; 820 return 0;
823 } 821 }
824 822
825 if (get_mi4header(sansa_sectorbuf,&mi4header)==0) { 823 if (get_mi4header(sansa->sectorbuf,&mi4header)==0) {
826 printf("[INFO] Image 2 - %d bytes\n",mi4header.mi4size); 824 printf("[INFO] Image 2 - %d bytes\n",mi4header.mi4size);
827 num = 2; 825 num = 2;
828 } 826 }
@@ -874,8 +872,8 @@ int sansa_update_of(struct sansa_t* sansa, const char* filename)
874 of_length = filesize(infile); 872 of_length = filesize(infile);
875 873
876 /* Load original firmware from file */ 874 /* Load original firmware from file */
877 memset(sansa_sectorbuf,0,0x200); 875 memset(sansa->sectorbuf,0,0x200);
878 n = read(infile,sansa_sectorbuf,of_length); 876 n = read(infile,sansa->sectorbuf,of_length);
879 close(infile); 877 close(infile);
880 if (n < of_length) { 878 if (n < of_length) {
881 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n" 879 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
@@ -884,13 +882,13 @@ int sansa_update_of(struct sansa_t* sansa, const char* filename)
884 } 882 }
885 883
886 /* Check we have a valid MI4 file. */ 884 /* Check we have a valid MI4 file. */
887 if (get_mi4header(sansa_sectorbuf,&mi4header)!=0) { 885 if (get_mi4header(sansa->sectorbuf,&mi4header)!=0) {
888 fprintf(stderr,"[ERR] %s is not a valid mi4 file\n",filename); 886 fprintf(stderr,"[ERR] %s is not a valid mi4 file\n",filename);
889 return -1; 887 return -1;
890 } 888 }
891 889
892 /* Decrypt and build the header */ 890 /* Decrypt and build the header */
893 if(prepare_original_firmware(sansa, sansa_sectorbuf, &mi4header)!=0){ 891 if(prepare_original_firmware(sansa, sansa->sectorbuf, &mi4header)!=0){
894 fprintf(stderr,"[ERR] Unable to build decrypted mi4 from %s\n" 892 fprintf(stderr,"[ERR] Unable to build decrypted mi4 from %s\n"
895 ,filename); 893 ,filename);
896 return -1; 894 return -1;
@@ -903,7 +901,7 @@ int sansa_update_of(struct sansa_t* sansa, const char* filename)
903 return -1; 901 return -1;
904 } 902 }
905 903
906 n=sansa_write(sansa, sansa_sectorbuf, of_length); 904 n=sansa_write(sansa, of_length);
907 if (n < of_length) { 905 if (n < of_length) {
908 fprintf(stderr,"[ERR] Short write in sansa_update_of\n"); 906 fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
909 return -1; 907 return -1;
@@ -920,8 +918,8 @@ int sansa_update_of(struct sansa_t* sansa, const char* filename)
920 return -1; 918 return -1;
921 } 919 }
922 920
923 memset(sansa_sectorbuf,0,NVPARAMS_SIZE); 921 memset(sansa->sectorbuf,0,NVPARAMS_SIZE);
924 n=sansa_write(sansa, sansa_sectorbuf, NVPARAMS_SIZE); 922 n=sansa_write(sansa, NVPARAMS_SIZE);
925 if (n < NVPARAMS_SIZE) { 923 if (n < NVPARAMS_SIZE) {
926 fprintf(stderr,"[ERR] Short write in sansa_update_of\n"); 924 fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
927 return -1; 925 return -1;
@@ -947,7 +945,7 @@ int sansa_update_ppbl(struct sansa_t* sansa, const char* filename)
947 945
948 ppbl_length = filesize(infile); 946 ppbl_length = filesize(infile);
949 947
950 n = read(infile,sansa_sectorbuf+0x200,ppbl_length); 948 n = read(infile,sansa->sectorbuf+0x200,ppbl_length);
951 close(infile); 949 close(infile);
952 if (n < ppbl_length) { 950 if (n < ppbl_length) {
953 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", ppbl_length, n); 951 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", ppbl_length, n);
@@ -955,10 +953,10 @@ int sansa_update_ppbl(struct sansa_t* sansa, const char* filename)
955 } 953 }
956 954
957 /* Step 2 - Build the header */ 955 /* Step 2 - Build the header */
958 memset(sansa_sectorbuf,0,0x200); 956 memset(sansa->sectorbuf,0,0x200);
959 memcpy(sansa_sectorbuf,"PPBL",4); 957 memcpy(sansa->sectorbuf,"PPBL",4);
960 int2le(ppbl_length, sansa_sectorbuf+4); 958 int2le(ppbl_length, sansa->sectorbuf+4);
961 int2le(0x00010000, sansa_sectorbuf+8); 959 int2le(0x00010000, sansa->sectorbuf+8);
962 960
963 /* Step 3 - write the bootloader to the Sansa */ 961 /* Step 3 - write the bootloader to the Sansa */
964 if (sansa_seek(sansa, sansa->start) < 0) { 962 if (sansa_seek(sansa, sansa->start) < 0) {
@@ -966,7 +964,7 @@ int sansa_update_ppbl(struct sansa_t* sansa, const char* filename)
966 return -1; 964 return -1;
967 } 965 }
968 966
969 n=sansa_write(sansa, sansa_sectorbuf, ppbl_length + 0x200); 967 n=sansa_write(sansa, ppbl_length + 0x200);
970 if (n < (ppbl_length+0x200)) { 968 if (n < (ppbl_length+0x200)) {
971 fprintf(stderr,"[ERR] Short write in sansa_update_ppbl\n"); 969 fprintf(stderr,"[ERR] Short write in sansa_update_ppbl\n");
972 return -1; 970 return -1;