/utils/ipod/bin2note/bin2note.c

https://github.com/jdgordon/rockbox · C · 180 lines · 121 code · 27 blank · 32 comment · 11 complexity · 6d3bab8b30968d7dbfc6755800d538b2 MD5 · raw file

  1. /***************************************************************************
  2. * __________ __ ___.
  3. * Open \______ \ ____ ____ | | _\_ |__ _______ ___
  4. * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
  5. * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
  6. * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
  7. * \/ \/ \/ \/ \/
  8. * $Id$
  9. *
  10. * bin2note - a program to insert binary code in an iPod Nano 2nd
  11. * Generation notes file
  12. *
  13. * Based on research by stooo, TheSeven and others.
  14. *
  15. * Copyright (C) 2009 Dave Chapman
  16. *
  17. * This program is free software; you can redistribute it and/or
  18. * modify it under the terms of the GNU General Public License
  19. * as published by the Free Software Foundation; either version 2
  20. * of the License, or (at your option) any later version.
  21. *
  22. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  23. * KIND, either express or implied.
  24. *
  25. ****************************************************************************/
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #include <fcntl.h>
  31. #include <stdlib.h>
  32. #include <unistd.h>
  33. #include <stdint.h>
  34. #ifndef O_BINARY
  35. #define O_BINARY 0
  36. #endif
  37. static off_t filesize(int fd)
  38. {
  39. struct stat buf;
  40. fstat(fd,&buf);
  41. return buf.st_size;
  42. }
  43. void write_utf16le(unsigned char* buf, int len, FILE* fp)
  44. {
  45. int i;
  46. char tmp[2];
  47. tmp[1] = 0;
  48. for (i=0;i<len;i++) {
  49. tmp[0] = buf[i];
  50. fwrite(tmp, 1, sizeof(tmp), fp);
  51. }
  52. }
  53. void insert_link(unsigned char* buf, uint32_t pointer)
  54. {
  55. char link[] = "<a href=\"AAAAAAA"
  56. "AAAAAAAAAAAAAAAA"
  57. "AAAAAAAAAAAAAAAA"
  58. "AAAAAAAAAAAAAAAA"
  59. "AAAAAAAAAAAAAAAA"
  60. "AAAAAAAAAAAAAAAA"
  61. "AAAAAAAAAAAAAAAA"
  62. "AAAAAAAAAAAAAAAA"
  63. "AAAAAAAAAAAAAAAA"
  64. "AAAAAAAAAAAAAAAA"
  65. "AAAAAAAAAAAAAAAA"
  66. "AAAAAAAAAAAAAAAA"
  67. "AAAAAAAAAAAAAAAA"
  68. "AAAAAAAAAAAAAAAA"
  69. "AAAAAAAAAAAAAAAA"
  70. "AAAAAAAAAAAAAAAA"
  71. "AAAAAAAAAAAAAAAA"
  72. "AAAAAAAAAAAAA%xx"
  73. "%xx%xx%xx\"></a>";
  74. char tmp[32];
  75. unsigned int i;
  76. sprintf(tmp, "%%%02x%%%02x%%%02x%%%02x",
  77. pointer & 0xff,
  78. (pointer >> 8) & 0xff,
  79. (pointer >> 16) & 0xff,
  80. (pointer >> 24) & 0xff);
  81. memcpy(link + 0x11d, tmp, 12);
  82. /* UTF-16 little-endian BOM */
  83. buf[0] = 0xff;
  84. buf[1] = 0xfe;
  85. /* UTF-16 little-endian URL */
  86. for (i=0;i<strlen(link);i++) {
  87. buf[i*2+2] = link[i];
  88. buf[i*2+3] = 0;
  89. }
  90. }
  91. #define MAX_NOTES_SIZE 4096
  92. #define MAX_PAYLOAD_SIZE (MAX_NOTES_SIZE - 0x260 - 4)
  93. int main (int argc, char* argv[])
  94. {
  95. char* infile;
  96. char* htmname;
  97. int fdin,fdout;
  98. unsigned char buf[MAX_NOTES_SIZE];
  99. int len;
  100. int n;
  101. int i;
  102. if (argc != 3) {
  103. fprintf(stderr,"Usage: bin2note file.bin file.htm\n");
  104. return 1;
  105. }
  106. infile=argv[1];
  107. htmname=argv[2];
  108. fdin = open(infile,O_RDONLY|O_BINARY);
  109. if (fdin < 0) {
  110. fprintf(stderr,"Can not open %s\n",infile);
  111. return 1;
  112. }
  113. len = filesize(fdin);
  114. if (len > MAX_PAYLOAD_SIZE) {
  115. fprintf(stderr,"Payload too big!\n");
  116. close(fdin);
  117. return 1;
  118. }
  119. /* **** Input file is OK, now build the note **** */
  120. /* Insert URL at start of note */
  121. insert_link(buf, 0x08640568);
  122. /* Load code at offset 0x260 */
  123. n = read(fdin,buf + 0x260,len);
  124. if (n < len) {
  125. fprintf(stderr,"Short read, aborting\n");
  126. return 1;
  127. }
  128. close(fdin);
  129. /* Fill the remaining buffer with NOPs (mov r1,r1) - 0xe1a01001 */
  130. for (i=0x260 + len; i < MAX_NOTES_SIZE-4; i+=4) {
  131. buf[i] = 0x01;
  132. buf[i+1] = 0x10;
  133. buf[i+2] = 0xa0;
  134. buf[i+3] = 0xe1;
  135. }
  136. /* Finally append a branch back to our code - 0x260 in the note */
  137. buf[MAX_NOTES_SIZE-4] = 0x97;
  138. buf[MAX_NOTES_SIZE-3] = 0xfc;
  139. buf[MAX_NOTES_SIZE-2] = 0xff;
  140. buf[MAX_NOTES_SIZE-1] = 0xea;
  141. fdout = open(htmname, O_CREAT|O_TRUNC|O_BINARY|O_WRONLY, 0666);
  142. if (fdout < 0) {
  143. fprintf(stderr,"Could not open output file\n");
  144. return 1;
  145. }
  146. if (write(fdout, buf, sizeof(buf)) != sizeof(buf)) {
  147. fprintf(stderr,"Error writing output file\n");
  148. close(fdout);
  149. return 1;
  150. }
  151. close(fdout);
  152. return 0;
  153. }