pDosHeader
已加载到ECX
pDosHeader->f_lfanew
被加载到EAX
(值,而不是指针)
pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew);
上面的代码ades ECX + EAX
并得到了我想要的结果......但是如果我决定在x64上编译一些内容,那么显然是对DWORD指针的不良习惯
pNtHeaders = (PIMAGE_NT_HEADERS)( (PDWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew );
pNtHeaders = (PIMAGE_NT_HEADERS)( (PDWORD)pDosHeader + pDosHeader->e_lfanew );
上面的代码添加了ECX + EAX * 4
并获得了我不想要的结果。对于1和2。
我的问题是为什么?为什么C ++会像这样编译我的代码?当我将dos标头转换为指针时,为什么它将e_lfanew乘以4?
它是否假设我想让我的指针指向下一个元素x次?因此将它乘以4以便我可以到e_lfanew(th)元素而不是添加e_lfanew?它可能会。
那我该怎么办?使用C ++方式编译此代码的正确方法是什么,以便在不使用不良习惯的情况下获得所需的结果?
我不想要e_lfanewth
的{{1}}元素。我只是想将pDosHeader
添加到e_lfanew
。
答案 0 :(得分:10)
当我将dos标头转换为指针时,为什么它将e_lfanew乘以4?
因为这是指针算法在C和C ++中的工作原理。向指针添加整数时,指针将按给定数量的元素调整,而不是 bytes 。由于PDWORD
指向DWORD
且DWORD
宽度为四个字节,因此向其添加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}}的类型如何都可以。