androidmanifesteditor.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * Copyright (C) 2018 Hein-Pieter van Braam
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <stdint.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include "android-xml.h"
  21. #include "ResStringPool.h"
  22. #include "ResXMLTreeNode.h"
  23. #include "XMLNameSpace.h"
  24. uint32_t g_lineno = 0;
  25. int main(int argc, char **argv) {
  26. FILE* fp = fopen(argv[1], "rb");
  27. if (!fp) {
  28. perror("Error opening file");
  29. exit(1);
  30. }
  31. fseek(fp, 0, SEEK_END);
  32. uint32_t filesize = ftell(fp);
  33. rewind(fp);
  34. fprintf(stderr, "Got %i bytes of data\n", filesize);
  35. char* data = (char*) malloc(filesize);
  36. if (!data) {
  37. perror("Error allocating");
  38. exit(1);
  39. }
  40. fread(data, 1, filesize, fp);
  41. fclose(fp);
  42. uint32_t filepos = 0;
  43. ResChunk_header cur_header;
  44. memcpy(&cur_header, data + filepos, sizeof(ResChunk_header));
  45. if (cur_header.type != RES_XML_TYPE) {
  46. fprintf(stderr, "Not an Android binary XML file\n");
  47. exit(1);
  48. }
  49. if (cur_header.size != filesize) {
  50. fprintf(stderr, "Header size does not match filesize\n");
  51. exit(1);
  52. }
  53. filepos += cur_header.headerSize;
  54. ResXMLTreeNode root(true);
  55. ResXMLTreeNode* cur = &root;
  56. ResStringPool* stringpool = nullptr;
  57. XMLNameSpace* ns = nullptr;
  58. char* resource_map = nullptr;
  59. uint32_t resource_map_size = 0;
  60. while (filepos < filesize) {
  61. memcpy(&cur_header, data + filepos, sizeof(ResChunk_header));
  62. switch (cur_header.type) {
  63. case RES_STRING_POOL_TYPE: {
  64. fprintf(stderr, "RES_STRING_POOL_TYPE\n");
  65. stringpool = new ResStringPool(data + filepos);
  66. break;
  67. }
  68. case RES_XML_RESOURCE_MAP_TYPE: {
  69. fprintf(stderr, "RES_XML_RESOURCE_MAP_TYPE\n");
  70. // We don't really care what's in here
  71. resource_map = (char*) malloc(cur_header.size);
  72. resource_map_size = cur_header.size;
  73. memcpy(resource_map, data + filepos, cur_header.size);
  74. break;
  75. }
  76. case RES_XML_END_NAMESPACE_TYPE:
  77. fprintf(stderr, "RES_XML_END_NAMESPACE_TYPE\n");
  78. break;
  79. case RES_XML_CDATA_TYPE: {
  80. printf(
  81. "Sorry found XML_CDATA_TYPE don't know how to deal with that\n");
  82. exit(1);
  83. }
  84. case RES_XML_LAST_CHUNK_TYPE:
  85. fprintf(stderr, "RES_XML_LAST_CHUNK_TYPE\n");
  86. break;
  87. case RES_XML_START_ELEMENT_TYPE: {
  88. ResXMLTreeNode* node = new ResXMLTreeNode(*stringpool,
  89. data + filepos);
  90. cur->add_child(node);
  91. cur = node;
  92. break;
  93. }
  94. case RES_XML_END_ELEMENT_TYPE: {
  95. cur = cur->_parent;
  96. break;
  97. }
  98. case RES_XML_START_NAMESPACE_TYPE: {
  99. fprintf(stderr, "RES_XML_START_NAMESPACE_TYPE\n");
  100. ns = new XMLNameSpace(*stringpool, data + filepos);
  101. break;
  102. }
  103. default:
  104. fprintf(stderr, "Unknown chunk type 0x%03X\n", cur_header.type);
  105. exit(1);
  106. }
  107. filepos += cur_header.size;
  108. }
  109. char* xml_serialized;
  110. uint32_t xml_serialized_size;
  111. xml_serialized_size = root.serialize(*stringpool, &xml_serialized);
  112. fprintf(stderr, "XML serialized to %i bytes\n", xml_serialized_size);
  113. fprintf(stderr, "XML resource map was %i bytes\n", resource_map_size);
  114. FILE* out = fopen(argv[2], "wb");
  115. char* ns_serialzed;
  116. uint32_t ns_serialized_size = 0;
  117. if (ns) {
  118. ns_serialized_size = ns->serialize(*stringpool, &ns_serialzed);
  119. fprintf(stderr, "Namespace serialized to %i bytes\n",
  120. ns_serialized_size);
  121. }
  122. char* ns_end_serialzed;
  123. uint32_t ns_end_serialized_size = 0;
  124. if (ns) {
  125. ns_end_serialized_size = ns->serialize_end(*stringpool,
  126. &ns_end_serialzed);
  127. fprintf(stderr, "Namespace end serialized to %i bytes\n",
  128. ns_end_serialized_size);
  129. }
  130. char* stringpool_serialized;
  131. uint32_t stringpool_serialized_size;
  132. stringpool_serialized_size = stringpool->serialize(&stringpool_serialized);
  133. fprintf(stderr, "Stringpool serialized to %i bytes\n",
  134. stringpool_serialized_size);
  135. uint32_t serialized_size = sizeof(ResChunk_header) + xml_serialized_size
  136. + stringpool_serialized_size + resource_map_size
  137. + ns_serialized_size + ns_end_serialized_size;
  138. fprintf(stderr, "Total size: %i bytes\n", serialized_size);
  139. ResChunk_header header;
  140. header.headerSize = sizeof(ResChunk_header);
  141. header.size = serialized_size;
  142. header.type = RES_XML_TYPE;
  143. fwrite(&header, sizeof(ResChunk_header), 1, out);
  144. fwrite(stringpool_serialized, stringpool_serialized_size, 1, out);
  145. fwrite(resource_map, resource_map_size, 1, out);
  146. fwrite(ns_serialzed, ns_serialized_size, 1, out);
  147. fwrite(xml_serialized, xml_serialized_size, 1, out);
  148. fwrite(ns_end_serialzed, ns_end_serialized_size, 1, out);
  149. fclose(out);
  150. //root.dump(ns);
  151. stringpool->dump();
  152. free(xml_serialized);
  153. free(stringpool_serialized);
  154. free(ns_serialzed);
  155. free(data);
  156. free(resource_map);
  157. delete (stringpool);
  158. delete (ns);
  159. }