【问题标题】:How do I print hex values stored in little endian?如何打印以小端序存储的十六进制值?
【发布时间】:2019-01-03 20:53:31
【问题描述】:

我似乎对 Endianess 搞得一团糟。我的机器是配备 Ryzen 3 处理器的 64 位机器。报告为小端。

我正在用 C 编写一个小程序,它遍历进程虚拟内存并解析 MSDOS 标头并检查标头签名中的 MZ。

取自我的代码:

int pid = 10964;
DWORD_PTR addr = 0x7FF7BD730000;
MEMORY_BASIC_INFORMATION64 mbi;
IMAGE_NT_HEADERS header;

HANDLE pHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (pHandle == NULL)
{
    printf("Error getting handle for process %i. Failed with error: %i", pid, GetLastError());
    return -1;
}

/*
 * Retrieve information on virtual address space
 */
BOOL vqeResult = VirtualQueryEx(pHandle, addr, &mbi, sizeof(MEMORY_BASIC_INFORMATION64));
if (!vqeResult)
{
    printf("Error querying virtual memory: %i", GetLastError());
    return -1;
}

PrintMemoryBasicInformation64(&mbi);

/*
 * Read the DOS header
 */
BOOL rpmResult = ReadProcessMemory(pHandle, (LPCVOID)mbi.BaseAddress, (LPVOID)&header, sizeof(header), 0);
if (!rpmResult) {
    printf("Error reading memory address: %i. Failed with error: %i", mbi.BaseAddress, GetLastError());
    return -1;
}

一切正常,除非我尝试打印签名:

printf("Signature: %x", header.Signature);

它给出了一个不正确的十六进制值,基本上是MZ

Signature: 0x785a4d

由于我的系统是小端,这是有道理的,但我该如何正确打印呢?

我附上了一张图片来显示存储在headers.Signature 中的值:

【问题讨论】:

  • 据我所知,7887437(以 10 为底) 785a4d(十六进制)。你期待 0xd4a587 吗?
  • @Bob__ 是的,即xZM。应该是MZ。文档说签名是 4 个字节,其中 2 个是空的 docs.microsoft.com/en-us/windows/desktop/api/winnt/… ...我在某个地方感到困惑。
  • 字节顺序关注数字如何存储在内存中,但 C 本身正在处理数字本身,因此无论字节顺序如何,打印、移位等都会以相同的方式发生。现在,如果您将二进制数据直接读入整数类型(大于char),那么字节序应该匹配,但是由于您是在小端机器上读取小端数据,所以我看不到字节序的相关性.
  • @Arkku 如果不是字节序问题并且标题不正确,我们深表歉意。我想我会在发布我的问题之前删除并找出我正在处理的问题。我还带着我的训练轮。关于我可能会出错的地方的任何指示?
  • @Bob__ 抱歉错过了编辑。是的,这就是我所期望的价值。

标签: c printf


【解决方案1】:

@Arkuu 是正确的,这不是字节序问题。

更新

我对以下解决方案不满意。我觉得我错过了更多的东西。我应该使用 IMAGE_DOS_HEADER 而不是 IMAGE_NT_HEADERS,因为我正在检查 DOS 存根而不是 PE 标头。

IMAGE_DOS_HEADER header;
...
printf("Signature: %#x\n", header.e_magic);

我解决它的方法是像这样使用 [_byteswap_ulong][1] : #包括 ... printf("签名:%#lx\n", _byteswap_ulong(header.Signature)); 此宏将反转字节顺序。 根据[docs](https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_image_nt_headers),签名是: 将文件标识为 PE 映像的 4 字节签名。字节为“PE\0\0”。 在小端系统上,这将是相反的顺序,就像我的情况一样。使用 `_byteswap_ulong` 宏反转字节并返回我预期的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    相关资源
    最近更新 更多