gpt4 book ai didi

C# 指针问题

转载 作者:太空宇宙 更新时间:2023-11-03 23:30:48 26 4
gpt4 key购买 nike

我曾尝试在 C# 中使用带有结构的指针,但是当我向指针添加偏移量时会发生一些奇怪的计算:

     p_FILE_HEADER = (IMAGE_FILE_HEADER*)(p_DOS_HEADER +  p_DOS_HEADER->e_lfanew);
  0000018a  mov         eax,dword ptr [ebp-3Ch] 
0000018d mov eax,dword ptr [eax+14h]
00000190 mov edx,dword ptr [ebp-3Ch]
00000193 mov edx,dword ptr [edx+14h]
00000196 mov edx,dword ptr [edx+3Ch]
00000199 xor ecx,ecx
0000019b shl edx,6 //strange
0000019e add eax,edx
000001a0 mov edx,dword ptr [ebp-3Ch]
000001a3 mov dword ptr [edx+0Ch],eax

除了移位指令外,一切似乎都还好,我不明白为什么它会在这里。

谁能告诉我原因?

这是结构定义(是的,它是 PE header 的一部分)

[StructLayout(LayoutKind.Sequential,Pack=1) ]
public unsafe struct IMAGE_DOS_HEADER
{ // DOS .EXE header


public ushort e_magic; //0x0 // Magic number
public ushort e_cblp; //0x2 // Bytes on last page of file
public ushort e_cp; //0x4 // Pages in file
public ushort e_crlc; //0x6 // Relocations
public ushort e_cparhdr; //0x8 // Size of header in paragraphs
public ushort e_minalloc; //0xA // Minimum extra paragraphs needed
public ushort e_maxalloc; //0xC // Maximum extra paragraphs needed
public ushort e_ss; //;0xE // Initial (relative) SS value
public ushort e_sp; //0x10 // Initial SP value
public ushort e_csum; //0x12 // Checksum
public ushort e_ip; //0x14 // Initial IP value
public ushort e_cs; //0x16 // Initial (relative) CS value
public ushort e_lfarlc; //0x18 // File address of relocation table
public ushort e_ovno; //0x1A // Overlay number

// [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)]
public fixed ushort e_res[4]; //0x1C // Reserved words
public ushort e_oemid; //0x24 // OEM identifier (for e_oeminfo)
public ushort e_oeminfo; //0x26 // OEM information; e_oemid specific
// [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 10)]
public fixed ushort e_res2 [10]; //0x28 // Reserved words

public uint e_lfanew; //0x3C // File address of new exe header

}

最佳答案

因此,让我们花一点时间了解一下。

p_FILE_HEADER = (IMAGE_FILE_HEADER*)(p_DOS_HEADER +  p_DOS_HEADER->e_lfanew);

因此您有一些变量 p_DOS_HEADER,它可能是 IMAGE_DOS_HEADER 的一个实例。您将 PE 镜像加载到内存中,并将此结构置于其上。所以 p_DOS_HEADER.e_lfanew 告诉您,“新的 exe header ”距离文件的开头有多远(以字节为单位)。 p_DOS_HEADER 告诉您"file"在内存中的起始位置。

在 C# 中,指针运算基于所指向类型的大小进行计算。 int* thing = ...; thing++ 会导致 thing 向前跳转四个字节(int 的大小),而不是一个字节。这与大多数其他支持指针的语言(如 C++ 或 C)所支持的约定相同。

但是,您正在读取的字段 - e_lfanew 以字节为单位存储偏移量。因此,您需要字节运算。

你想要这样的东西:

p_FILE_HEADER = (IMAGE_FILE_HEADER*)( (byte*)p_DOS_HEADER + p_DOS_HEADER->e_lfanew);

关于C# 指针问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32310942/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com