Search code examples
c++binaryhexportable-executable

Convert char array to integer value


I'm having a bit of a trouble figuring out the correct calculation of WORD, DWORD etc. I'm having kind of a knot in my brain, probably sitting on this problem for too long.

I'm reading a PE-section header. So far everything is ok. Here is a sample output from a random .exe file:

File is 286 Kbytes large
PE-Signature [@ 0x108]
0x00000100: ........ ........ 504500

Collect Information (PE file header):
[WORD]  Mashinae Type          :014C
[WORD]  Number of Sections     :0006
[DWORD] TimeStamp              :5C6ECB00
[DWORD] Pointer to symbol table:00000000
[DWORD] Number of Symbols      :00000000
[WORD]  Size of optional header:00E0

Now, as you see the size of the "optional" header is 0x00E0, so I was trying to buffer that for later. (Bc. it would make things faster to just read the complete header).

Where I'm having problems is the point where I am to convert the little-endian values to an actual integer. I need to read the value from behind (so the second WORD [ 00 ] is actually the first value to be read). The second value, however, needs to be shifted in some way (bc. significance of bytes), and this is where I am struggeling. I guess the solution is not that hard, I just ran out of wisdom lol.

Here is my draft for a function that should return an integer value with the value:

 //get a specific value and safe it for later usage
 int getValue(char* memory, int start, int end)
 {
   if (end <= start)
       return 0;

   unsigned int retVal = 0;

   //now just add up array fields 
   for (int i = end; i >= start; i--)
   {
       fprintf(stdout, "\n%02hhx", memory[i]);
       retVal &= (memory[i] << 8 * (i- start));
   }
   fprintf(stdout, "\n\n\n%d",retVal);

   return retVal;
}

In other words, I need to parse an array of hex values (or chars) to an actual integer, but in respect of the significance of the bytes.

Also: [Pointer to symbol table] and [Number of Symbols] seem to always be 0. I'm guessing this is due to the fact the binary is stripped of symbols, but I'm not sure since I am more an expert on Linux Binary Analysis. Is my asumption correct?


Solution

  • I really hope that this helps you. From what I understood so far this will grab the bytes that are within the start to end range and will place them in an integer:

    // here I am converting the chars from hex to int
    int getBitPattern(char ch)
    {
        if (ch >= 48 && ch <= 57)
        {
            return ch - '0';
        }
        else if (ch >= 65 && ch <= 70)
        {
            return ch - 55;
        }
        else
        {
            // this is in case of invalid input
            return -1;
        }
    }
    
    
    int getValue(const char* memory, int start, int end)
    {
        if (end <= start)
            return 0;
    
        unsigned int retVal = 0;
    
        //now just add up array fields 
        for (int i = end, j = 0; i >= start; i--, ++j)
        {
            fprintf(stdout, "\n%02hhx", memory[i]);
            // bitshift in order to insert the next set of 4 bits into their correct spot
            retVal |= (getBitPattern(memory[i]) << (4*j));
        }
        fprintf(stdout, "\n\n\n%d", retVal);
        return retVal;
    }