Advertisement
Guest User

Untitled

a guest
Feb 20th, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.49 KB | None | 0 0
  1. typedef uint32_t DWORD;
  2. typedef uint16_t WORD;
  3. typedef uint8_t BYTE;
  4.  
  5. #define READ_BYTE(p) (((unsigned char*)(p))[0])
  6. #define READ_WORD(p) ((((unsigned char*)(p))[0]) | ((((unsigned char*)(p))[1]) << 8))
  7. #define READ_DWORD(p) ((((unsigned char*)(p))[0]) | ((((unsigned char*)(p))[1]) << 8) |
  8. ((((unsigned char*)(p))[2]) << 16) | ((((unsigned char*)(p))[3]) << 24))
  9.  
  10. #define PAD(x) (((x) + 3) & 0xFFFFFFFC)
  11.  
  12. const char *FindVersion(const char *buf)
  13. {
  14.  
  15. //buf is a IMAGE_DOS_HEADER
  16. if (READ_WORD(buf) != 0x5A4D) //MZ signature
  17. return NULL;
  18.  
  19. //pe is a IMAGE_NT_HEADERS32
  20. const char *pe = buf + READ_DWORD(buf + 0x3C);
  21. if (READ_WORD(pe) != 0x4550) //PE signature
  22. return NULL;
  23.  
  24. //coff is a IMAGE_FILE_HEADER
  25. const char *coff = pe + 4;
  26.  
  27. WORD numSections = READ_WORD(coff + 2);
  28. WORD optHeaderSize = READ_WORD(coff + 16);
  29. if (numSections == 0 || optHeaderSize == 0)
  30. return NULL;
  31.  
  32. //optHeader is a IMAGE_OPTIONAL_HEADER32
  33. const char *optHeader = coff + 20;
  34. if (READ_WORD(optHeader) != 0x10b) //Optional header magic (32 bits)
  35. return NULL;
  36.  
  37. //dataDir is an array of IMAGE_DATA_DIRECTORY
  38. const char *dataDir = optHeader + 96;
  39. DWORD vaRes = READ_DWORD(dataDir + 8*2);
  40.  
  41. //secTable is an array of IMAGE_SECTION_HEADER
  42. const char *secTable = optHeader + optHeaderSize;
  43.  
  44. int i;
  45. for (i = 0; i < numSections; ++i)
  46. {
  47. //sec is a IMAGE_SECTION_HEADER*
  48. const char *sec = secTable + 40*i;
  49. char secName[9];
  50. memcpy(secName, sec, 8);
  51. secName[8] = 0;
  52.  
  53. if (strcmp(secName, ".rsrc") != 0)
  54. continue;
  55.  
  56. DWORD vaSec = READ_DWORD(sec + 12);
  57. const char *raw = buf + READ_DWORD(sec + 20);
  58.  
  59. const char *resSec = raw + (vaRes - vaSec);
  60.  
  61. WORD numNamed = READ_WORD(resSec + 12);
  62. WORD numId = READ_WORD(resSec + 14);
  63.  
  64. int j;
  65. for (j = 0; j < numNamed + numId; ++j)
  66. {
  67.  
  68. //resSec is a IMAGE_RESOURCE_DIRECTORY followed by an array
  69. // of IMAGE_RESOURCE_DIRECTORY_ENTRY
  70. const char *res = resSec + 16 + 8 * j;
  71. DWORD name = READ_DWORD(res);
  72. if (name != 16) //RT_VERSION
  73. continue;
  74.  
  75. DWORD offs = READ_DWORD(res + 4);
  76. if ((offs & 0x80000000) == 0) //is a dir resource?
  77. return NULL;
  78. //verDir is another IMAGE_RESOURCE_DIRECTORY and
  79. // IMAGE_RESOURCE_DIRECTORY_ENTRY array
  80. const char *verDir = resSec + (offs & 0x7FFFFFFF);
  81.  
  82. numNamed = READ_WORD(verDir + 12);
  83. numId = READ_WORD(verDir + 14);
  84. if (numNamed == 0 && numId == 0)
  85. return NULL;
  86. res = verDir + 16;
  87. offs = READ_DWORD(res + 4);
  88. if ((offs & 0x80000000) == 0) //is a dir resource?
  89. return NULL;
  90.  
  91. //and yet another IMAGE_RESOURCE_DIRECTORY, etc.
  92. verDir = resSec + (offs & 0x7FFFFFFF);
  93. numNamed = READ_WORD(verDir + 12);
  94. numId = READ_WORD(verDir + 14);
  95. if (numNamed == 0 && numId == 0)
  96. return NULL;
  97. res = verDir + 16;
  98. offs = READ_DWORD(res + 4);
  99. if ((offs & 0x80000000) != 0) //is a dir resource?
  100. return NULL;
  101. verDir = resSec + offs;
  102.  
  103. DWORD verVa = READ_DWORD(verDir);
  104.  
  105. const char *verPtr = raw + (verVa - vaSec);
  106. return verPtr;
  107.  
  108. }
  109. return NULL;
  110. }
  111. return NULL;
  112. }
  113.  
  114. int PrintVersion(const char *version, int offs)
  115. {
  116.  
  117. offs = PAD(offs);
  118.  
  119. WORD len = READ_WORD(version + offs);
  120. offs += 2;
  121. WORD valLen = READ_WORD(version + offs);
  122. offs += 2;
  123. WORD type = READ_WORD(version + offs);
  124. offs += 2;
  125.  
  126. char info[200];
  127. int i;
  128. for (i=0; i < 200; ++i)
  129. {
  130. WORD c = READ_WORD(version + offs);
  131. offs += 2;
  132.  
  133. info[i] = c;
  134. if (!c)
  135. break;
  136. }
  137.  
  138. offs = PAD(offs);
  139.  
  140. if (type != 0) //TEXT
  141. {
  142. char value[200];
  143. for (i=0; i < valLen; ++i)
  144. {
  145. WORD c = READ_WORD(version + offs);
  146. offs += 2;
  147. value[i] = c;
  148. }
  149. value[i] = 0;
  150. printf("info <%s>: <%s>n", info, value);
  151. }
  152.  
  153. else
  154. {
  155. if (strcmp(info, "VS_VERSION_INFO") == 0)
  156. {
  157.  
  158. //fixed is a VS_FIXEDFILEINFO
  159. const char *fixed = version + offs;
  160. WORD fileA = READ_WORD(fixed + 10);
  161. WORD fileB = READ_WORD(fixed + 8);
  162. WORD fileC = READ_WORD(fixed + 14);
  163. WORD fileD = READ_WORD(fixed + 12);
  164. WORD prodA = READ_WORD(fixed + 18);
  165. WORD prodB = READ_WORD(fixed + 16);
  166. WORD prodC = READ_WORD(fixed + 22);
  167. WORD prodD = READ_WORD(fixed + 20);
  168. printf("tFile: %d.%d.%d.%dn", fileA, fileB, fileC, fileD);
  169. printf("tProd: %d.%d.%d.%dn", prodA, prodB, prodC, prodD);
  170. }
  171. offs += valLen;
  172. }
  173.  
  174. while (offs < len)
  175. offs = PrintVersion(version, offs);
  176.  
  177. return PAD(offs);
  178. }
  179.  
  180. int main(int argc, char **argv)
  181. {
  182. struct stat st;
  183. if (stat(argv[1], &st) < 0)
  184. {
  185. perror(argv[1]);
  186. return 1;
  187. }
  188.  
  189. char *buf = malloc(st.st_size);
  190.  
  191. FILE *f = fopen(argv[1], "r");
  192. if (!f)
  193. {
  194. perror(argv[1]);
  195. return 2;
  196. }
  197.  
  198. fread(buf, 1, st.st_size, f);
  199. fclose(f);
  200.  
  201. const char *version = FindVersion(buf);
  202. if (!version)
  203. printf("No versionn");
  204. else
  205. PrintVersion(version, 0);
  206. return 0;
  207. }
  208.  
  209. wrestool --type=16 -x --raw Paint.NET.3.5.10.Install.exe
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement