unpackbootimg.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <fcntl.h>
  6. #include <errno.h>
  7. #include <limits.h>
  8. #include <libgen.h>
  9. #include "bootimg.h"
  10. typedef unsigned char byte;
  11. int read_padding(FILE* f, unsigned itemsize, int pagesize)
  12. {
  13. byte* buf = (byte*)malloc(sizeof(byte) * pagesize);
  14. unsigned pagemask = pagesize - 1;
  15. unsigned count;
  16. if((itemsize & pagemask) == 0) {
  17. free(buf);
  18. return 0;
  19. }
  20. count = pagesize - (itemsize & pagemask);
  21. fread(buf, count, 1, f);
  22. free(buf);
  23. return count;
  24. }
  25. void write_string_to_file(char* file, char* string)
  26. {
  27. FILE* f = fopen(file, "w");
  28. fwrite(string, strlen(string), 1, f);
  29. fwrite("\n", 1, 1, f);
  30. fclose(f);
  31. }
  32. int usage() {
  33. printf("usage: unpackbootimg\n");
  34. printf("\t-i|--input boot.img\n");
  35. printf("\t[ -o|--output output_directory]\n");
  36. printf("\t[ -p|--pagesize <size-in-hexadecimal> ]\n");
  37. return 0;
  38. }
  39. int main(int argc, char** argv)
  40. {
  41. char tmp[PATH_MAX];
  42. char* directory = "./";
  43. char* filename = NULL;
  44. int pagesize = 0;
  45. argc--;
  46. argv++;
  47. while(argc > 0){
  48. char *arg = argv[0];
  49. char *val = argv[1];
  50. argc -= 2;
  51. argv += 2;
  52. if(!strcmp(arg, "--input") || !strcmp(arg, "-i")) {
  53. filename = val;
  54. } else if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) {
  55. directory = val;
  56. } else if(!strcmp(arg, "--pagesize") || !strcmp(arg, "-p")) {
  57. pagesize = strtoul(val, 0, 16);
  58. } else {
  59. return usage();
  60. }
  61. }
  62. if (filename == NULL) {
  63. return usage();
  64. }
  65. int total_read = 0;
  66. FILE* f = fopen(filename, "rb");
  67. boot_img_hdr header;
  68. //printf("Reading header...\n");
  69. int i;
  70. for (i = 0; i <= 512; i++) {
  71. fseek(f, i, SEEK_SET);
  72. fread(tmp, BOOT_MAGIC_SIZE, 1, f);
  73. if (memcmp(tmp, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0)
  74. break;
  75. }
  76. total_read = i;
  77. if (i > 512) {
  78. printf("Android boot magic not found.\n");
  79. return 1;
  80. }
  81. fseek(f, i, SEEK_SET);
  82. printf("Android magic found at: %d\n", i);
  83. fread(&header, sizeof(header), 1, f);
  84. printf("BOARD_KERNEL_CMDLINE %s\n", header.cmdline);
  85. printf("BOARD_KERNEL_BASE %08x\n", header.kernel_addr - 0x00008000);
  86. printf("BOARD_RAMDISK_OFFSET %08x\n", header.ramdisk_addr - header.kernel_addr + 0x00008000);
  87. printf("BOARD_SECOND_OFFSET %08x\n", header.second_addr - header.kernel_addr + 0x00008000);
  88. printf("BOARD_TAGS_OFFSET %08x\n",header.tags_addr - header.kernel_addr + 0x00008000);
  89. printf("BOARD_PAGE_SIZE %d\n", header.page_size);
  90. printf("BOARD_SECOND_SIZE %d\n", header.second_size);
  91. printf("BOARD_DT_SIZE %d\n", header.dt_size);
  92. if (pagesize == 0) {
  93. pagesize = header.page_size;
  94. }
  95. //printf("cmdline...\n");
  96. sprintf(tmp, "%s/%s", directory, basename(filename));
  97. strcat(tmp, "-cmdline");
  98. write_string_to_file(tmp, header.cmdline);
  99. //printf("base...\n");
  100. sprintf(tmp, "%s/%s", directory, basename(filename));
  101. strcat(tmp, "-base");
  102. char basetmp[200];
  103. sprintf(basetmp, "%08x", header.kernel_addr - 0x00008000);
  104. write_string_to_file(tmp, basetmp);
  105. //printf("ramdisk_offset...\n");
  106. sprintf(tmp, "%s/%s", directory, basename(filename));
  107. strcat(tmp, "-ramdisk_offset");
  108. char ramdisktmp[200];
  109. sprintf(ramdisktmp, "%08x", header.ramdisk_addr - header.kernel_addr + 0x00008000);
  110. write_string_to_file(tmp, ramdisktmp);
  111. //printf("second_offset...\n");
  112. sprintf(tmp, "%s/%s", directory, basename(filename));
  113. strcat(tmp, "-second_offset");
  114. char secondtmp[200];
  115. sprintf(secondtmp, "%08x", header.second_addr - header.kernel_addr + 0x00008000);
  116. write_string_to_file(tmp, secondtmp);
  117. //printf("tags_offset...\n");
  118. sprintf(tmp, "%s/%s", directory, basename(filename));
  119. strcat(tmp, "-tags_offset");
  120. char tagstmp[200];
  121. sprintf(tagstmp, "%08x", header.tags_addr - header.kernel_addr + 0x00008000);
  122. write_string_to_file(tmp, tagstmp);
  123. //printf("pagesize...\n");
  124. sprintf(tmp, "%s/%s", directory, basename(filename));
  125. strcat(tmp, "-pagesize");
  126. char pagesizetmp[200];
  127. sprintf(pagesizetmp, "%d", header.page_size);
  128. write_string_to_file(tmp, pagesizetmp);
  129. total_read += sizeof(header);
  130. //printf("total read: %d\n", total_read);
  131. total_read += read_padding(f, sizeof(header), pagesize);
  132. sprintf(tmp, "%s/%s", directory, basename(filename));
  133. strcat(tmp, "-zImage");
  134. FILE *k = fopen(tmp, "wb");
  135. byte* kernel = (byte*)malloc(header.kernel_size);
  136. //printf("Reading kernel...\n");
  137. fread(kernel, header.kernel_size, 1, f);
  138. total_read += header.kernel_size;
  139. fwrite(kernel, header.kernel_size, 1, k);
  140. fclose(k);
  141. //printf("total read: %d\n", header.kernel_size);
  142. total_read += read_padding(f, header.kernel_size, pagesize);
  143. byte* ramdisk = (byte*)malloc(header.ramdisk_size);
  144. //printf("Reading ramdisk...\n");
  145. fread(ramdisk, header.ramdisk_size, 1, f);
  146. total_read += header.ramdisk_size;
  147. sprintf(tmp, "%s/%s", directory, basename(filename));
  148. if(ramdisk[0] == 0x02 && ramdisk[1]== 0x21)
  149. strcat(tmp, "-ramdisk.lz4");
  150. else
  151. strcat(tmp, "-ramdisk.gz");
  152. FILE *r = fopen(tmp, "wb");
  153. fwrite(ramdisk, header.ramdisk_size, 1, r);
  154. fclose(r);
  155. total_read += read_padding(f, header.ramdisk_size, pagesize);
  156. sprintf(tmp, "%s/%s", directory, basename(filename));
  157. strcat(tmp, "-second");
  158. FILE *s = fopen(tmp, "wb");
  159. byte* second = (byte*)malloc(header.second_size);
  160. //printf("Reading second...\n");
  161. fread(second, header.second_size, 1, f);
  162. total_read += header.second_size;
  163. fwrite(second, header.second_size, 1, r);
  164. fclose(s);
  165. total_read += read_padding(f, header.second_size, pagesize);
  166. sprintf(tmp, "%s/%s", directory, basename(filename));
  167. strcat(tmp, "-dt");
  168. FILE *d = fopen(tmp, "wb");
  169. byte* dt = (byte*)malloc(header.dt_size);
  170. //printf("Reading dt...\n");
  171. fread(dt, header.dt_size, 1, f);
  172. total_read += header.dt_size;
  173. fwrite(dt, header.dt_size, 1, r);
  174. fclose(d);
  175. total_read += read_padding(f, header.dt_size, pagesize);
  176. sprintf(tmp, "%s/%s", directory, basename(filename));
  177. strcat(tmp, "-signature");
  178. FILE *fsig = fopen(tmp, "wb");
  179. byte* bsig = (byte*)malloc(256);
  180. //printf("Reading signature...\n");
  181. fread(bsig, 256, 1, f);
  182. total_read += 256;
  183. fwrite(bsig, 256, 1, r);
  184. fclose(fsig);
  185. fclose(f);
  186. //printf("Total Read: %d\n", total_read);
  187. return 0;
  188. }