Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么C++;把这个值乘以4? pDosHeader已加载到ECX_C++ - Fatal编程技术网

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
(值,而不是指针)

上面的代码是ades
ECX+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);