C++ 为什么C++;把这个值乘以4? pDosHeader已加载到ECX
C++ 为什么C++;把这个值乘以4? pDosHeader已加载到ECX,c++,C++,pDosHeader->f_lfanew被加载到EAX(值,而不是指针) 上面的代码是adesECX+EAX并得到了所需的结果。。。但很明显,如果我决定在x64上编译一些东西,那么向DWORD抛出指针是不好的习惯 pNtHeaders=(PIMAGE\u NT_头)((PDWORD)pDosHeader+(DWORD)pDosHeader->e_lfanew) pNtHeaders=(PIMAGE\u NT_头)((PDWORD)pDosHeader+pDosHeader->e_lfanew
pDosHeader->f_lfanew
被加载到EAX
(值,而不是指针)
上面的代码是adesECX+EAX
并得到了所需的结果。。。但很明显,如果我决定在x64上编译一些东西,那么向DWORD抛出指针是不好的习惯
pNtHeaders=(PIMAGE\u NT_头)((PDWORD)pDosHeader+(DWORD)pDosHeader->e_lfanew)代码>
pNtHeaders=(PIMAGE\u NT_头)((PDWORD)pDosHeader+pDosHeader->e_lfanew)代码>
ECX+EAX*4
,得到了我不想要的结果。对于1和2
我的问题是为什么?为什么C++会这样编译我的代码?当我将dos头转换为指针时,为什么它会将e_lfane乘以4
它是否假设我想让指针多次指向下一个元素x?因此,将它乘以4,这样我就可以得到e_lfanew(th)元素,而不是添加e_lfanew?可能是的
那我该怎么办?什么是正确的方法来铸造这个代码的C++方式,从而得到了预期的结果,而不使用坏习惯?< /P>
我不想要pDosHeader
的e\u lfanewth
元素。我只想让它将e_lfanew
添加到pDosHeader
当我将dos头转换为指针时,为什么它会将e_lfane乘以4
因为这是指针算法在C和C++中都是如何工作的。向指针添加整数时,指针将按给定的元素数而不是字节数进行调整。由于
PDWORD
指向DWORD
并且DWORD
有四个字节宽,因此向其添加n
会将4*n
添加到地址
要使其按您想要的方式工作,请将指针更改为
PBYTE
如果向类型为T的指针添加一个数字,指针将增加数字*sizeof(T)
这应该满足您的要求:
pNtHeaders = (PIMAGE_NT_HEADERS)( (char*)pDosHeader + pDosHeader->e_lfanew );
将整数
i
添加到指针p
时,如p+i
中所示,这将考虑*p
类型的大小。例如,如果p
是指向int
的指针,并且sizeof(int)
是4,那么p+1
将是p
之外的4个字节。(这是假设您指向允许您指向的内存,否则它是未定义的。)因此p[1]
和*(p+1)
是等价的表达式
要向指针添加绝对字节数,它必须是指向的类型大小的倍数,并且必须将其转换为指向的对象数。例如,对于按字节数递增的int*ip
,int offset
:
ip = ip + offset / sizeof(*ip);
这要求偏移量为sizeof(int)
的倍数
但是,如果
pDosHeader->elfanew
是任意字节数,那么您的问题似乎不是这样。在这种情况下,使用Master T或NPE的解决方案,将指针转换为char*
。通常,在指向不同类型的指针之间进行强制转换是未定义的行为,但在别名规则下,char*
有一个例外,因此无论pDosHeader
基本指针算法的类型如何,这都会起作用。如果你不认识它,你应该读一本关于C++的好的初学者书籍或教程,尤其是关于指针。让编译器来完成这项艰巨的工作,正如我在问题中所说的。我知道这一点。我从技术上问C++的方法是什么,因为你不应该把指针投向DWORD,因为这是X64的坏习惯。一开始就丢失微软Type!然后一切都会变清楚。你的算术全错了。在错误的一端应用缩放,产生错误的结果。将您的解决方案与发布的解决方案进行比较,您就会发现问题所在。请解释。我能看到的唯一区别是,如果pDosHeader->e_lfanew不是sizeof(*pDosHeader)的倍数,那么Master T的答案将有效,并且这种情况可能是未定义的行为(考虑将int指针增加3个字节)。唯一的区别就是这里的问题e_lfanew
是文件中的字节偏移量。由于<代码> EyLFANEW 存储在该文件中,您也不能对其进行任何限制。我没有考虑<代码> EyLFANEW 或<代码> PDOTHOMENT/<代码>的含义。Master T的解决方案是否有效/安全取决于pDosHeader
指向的内容。在读取Windows可执行文件的上下文中,它可能是有效的。经过进一步研究,似乎强制转换到char*
总是有效的。
ip = ip + offset / sizeof(*ip);