为什么C ++将此值乘以4?

时间:2014-01-02 21:11:35

标签: c++

  • pDosHeader已加载到ECX
  • pDosHeader->f_lfanew被加载到EAX(值,而不是指针)

    pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew);
    

上面的代码ades ECX + EAX并得到了我想要的结果......但是如果我决定在x64上编译一些内容,那么显然是对DWORD指针的不良习惯

  1. pNtHeaders = (PIMAGE_NT_HEADERS)( (PDWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew );
  2. pNtHeaders = (PIMAGE_NT_HEADERS)( (PDWORD)pDosHeader + pDosHeader->e_lfanew );
  3. 上面的代码添加了ECX + EAX * 4并获得了我不想要的结果。对于1和2。

    我的问题是为什么?为什么C ++会像这样编译我的代码?当我将dos标头转换为指针时,为什么它将e_lfanew乘以4?

    它是否假设我想让我的指针指向下一个元素x次?因此将它乘以4以便我可以到e_lfanew(th)元素而不是添加e_lfanew?它可能会。

    那我该怎么办?使用C ++方式编译此代码的正确方法是什么,以便在不使用不良习惯的情况下获得所需的结果?

    我不想要e_lfanewth的{​​{1}}元素。我只是想将pDosHeader添加到e_lfanew

3 个答案:

答案 0 :(得分:10)

  

当我将dos标头转换为指针时,为什么它将e_lfanew乘以4?

因为这是指针算法在C和C ++中的工作原理。向指针添加整数时,指针将按给定数量的元素调整,而不是 bytes 。由于PDWORD指向DWORDDWORD宽度为四个字节,因此向其添加n会将4 * n添加到地址。

要使其按您希望的方式工作,请将指针更改为PBYTE

答案 1 :(得分:2)

如果向类型为T的指针添加数字,指针将增加数字* sizeof(T)。

这应该做你想要的:

pNtHeaders = (PIMAGE_NT_HEADERS)( (char*)pDosHeader + pDosHeader->e_lfanew );

答案 2 :(得分:0)

i整数p添加到p + i中的指针*p时,会考虑p类型的大小。例如,如果int是指向sizeof(int)的指针,p+1为4,则p将超出p[1] 4个字节。 (这假设您指向允许指向的内存,否则未定义。)因此*(p+1)int *ip是等效表达式。

要向指针添加绝对字节数,它必须是指向的类型大小的倍数,并且必须将其转换为指向的多个对象。例如,int offset增加了多个字节ip = ip + offset / sizeof(*ip);

sizeof(int)

这要求偏移量为pDosHeader->e_lfanew的倍数。

但是,如果char *是任意数量的字节,那么在您的问题中似乎不是这种情况。在这种情况下,使用Master T或NPE的解决方案,使用指向char *的指针。通常在指向不同类型的指针之间进行转换将是未定义的行为,但是在别名规则下pDosHeader存在异常,因此无论{{1}}的类型如何都可以。