SHARE
TWEET

Untitled

a guest Feb 20th, 2019 69 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top