如何打印存储在小尾数法中的十六进制值?

时间:2019-01-03 20:53:31

标签: c printf

我似乎对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中的值:

enter image description here

1 个答案:

答案 0 :(得分:0)

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

更新

我对下面的解决方案不满意。我觉得我还缺少其他东西。在检查DOS存根而不是PE标头时,我应该一直使用IMAGE_DOS_HEADER而不是IMAGE_NT_HEADERS

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

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