我似乎对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
中的值:
答案 0 :(得分:0)
@Arkuu是正确的,这不是字节序问题。
更新
我对下面的解决方案不满意。我觉得我还缺少其他东西。在检查DOS存根而不是PE标头时,我应该一直使用IMAGE_DOS_HEADER
而不是IMAGE_NT_HEADERS
。
IMAGE_DOS_HEADER header;
...
printf("Signature: %#x\n", header.e_magic);