diff options
Diffstat (limited to 'rbutil/sansapatcher/sansapatcher.c')
-rw-r--r-- | rbutil/sansapatcher/sansapatcher.c | 104 |
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 | ||
46 | unsigned char* sansa_sectorbuf = NULL; | ||
47 | |||
48 | static off_t filesize(int fd) { | 46 | static 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; |