【问题标题】:Convert char array to integer value将 char 数组转换为整数值
【发布时间】:2020-03-31 19:37:04
【问题描述】:

我在正确计算 WORD、DWORD 等时遇到了一些麻烦。 我的脑子里有一种结,可能是在这个问题上坐得太久了。

我正在阅读 PE 部分的标题。到目前为止一切正常。 以下是随机 .exe 文件的示例输出:

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

现在,如您所见,“可选”标头的大小为 0x00E0,因此我试图将其缓冲以备后用。 (公元前。阅读完整的标题会让事情变得更快)。

我遇到问题的地方是将小端值转换为实际整数。 我需要从后面读取值(因此第二个 WORD [00] 实际上是要读取的第一个值)。 然而,第二个值需要以某种方式移动(bc. 字节的重要性),这就是我苦苦挣扎的地方。我想解决方案并不难,我只是没智慧了哈哈。

这是我的草稿,该函数应该返回一个整数值,该值是:

 //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;
}

换句话说,我需要将一个十六进制值(或字符)数组解析为一个实际的整数,但要考虑字节的重要性。

还有: [Pointer to symbol table] 和 [Number of Symbols] 似乎总是 0。我猜这是因为二进制文件中没有符号,但我不确定,因为我更擅长 Linux 二进制文件分析。我的假设正确吗?

【问题讨论】:

  • 你能给我一个你想做的例子吗?输入和期望的输出
  • 所以你的意思是如果传递的char *是“00E0”,那retval应该等于14?
  • 您使用的是 C 还是 C++?如果您使用的是 C++,我建议您查看 cplusplus.com/reference/sstream/stringstream
  • 可能想要|= 而不是&amp;=——因为 retVal 从 0 开始,并且进入它永远不会改变它...
  • @zlogdan 正在使用 C++,是的 stringstream 可以解决我的问题,然后 stoi 操作再次失败

标签: c++ binary hex portable-executable


【解决方案1】:

我真的希望这对您有所帮助。根据我目前的理解,这将抓取开始到结束范围内的字节并将它们放在一个整数中:

// 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;
}

【讨论】:

    【解决方案2】:

    boyanhristov96 通过指出 OR 运算符而不是 AND 的用法提供了很大帮助,正是他/她的努力促成了这个解决方案

    在转换之前还必须进行转换 (unsigned char)。

    如果不是,变量将简单地移动到它的最大正范围内,
    产生值

    0xFFFFE000 (4294959104)

    而不是所需的 0x0000E000 (57344)

    我们必须左移 8,因为我们想一次移动 2 个 16 位的值,就像在

    0x00FF00

    最后一个函数也使用了 OR,就是这样:

    //now with or operation and cast
    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 = end-start; i >= start; i--, --j)
    {
        fprintf(stdout, "\n%02hhx", memory[i]);
        retVal |= ((unsigned char)(memory[i]) << (8 * j));
    }
    fprintf(stdout, "\n\n\n%u", retVal);
    return retVal;
    

    }

    非常感谢您的帮助

    编辑 16.12.2019:

    返回此处获取更新版本的函数; 重写它是有必要的,原因有两个: 1) PE-Header 的偏移量取决于目标二进制文件,因此我们必须首先获取该值(在位置 0x3c 处)。然后,使用指针从那里从一个值移动到另一个值。 2)计算混乱,我纠正了它们,现在它应该按预期工作。第二个参数是字节长度,f.e。 DWORD - 4 字节

    给你:

    //because file shambles
    int getValuePNTR(const char* memory, int &start, int size)
    {
        DWORD retVal = 0;
    
        //now just add up array fields 
        for (int i = start + size-1,j = size-1; j >= 0; --j ,i--)
        {
    
            fprintf(stdout, "\ncycle: %d, memory: [%x]", j, memory[i]);
    
            if ((unsigned char)memory[i] == 00 && j > 0)
                retVal <<= 8;
            else
                retVal |= ((unsigned char)(memory[i]) << (8 * j));
            //else
                //retVal |= ((unsigned char)(memory[i]));
    
    
        }
        //get the next field after this one
        start += size;
        return retVal;
    }
    

    【讨论】:

    • 没问题!我很高兴能够提供帮助。
    猜你喜欢
    • 2011-08-28
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2016-02-27
    • 2017-10-08
    相关资源
    最近更新 更多