Here's a piece of code for obtaining the time when a .NET assembly was built。注意:
const int c_LinkerTimestampOffset = 8;
以后:
int secondsSince1970 = System.BitConverter.ToInt32(b, i + c_LinkerTimestampOffset);
此代码提取存储在程序集中的IMAGE_FILE_HEADER structure TimeDateStamp
成员。结构定义如下:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
和WORD
是两个字节,应该是两个字节对齐的。当我使用Visual C ++ 10编译以下代码时:
IMAGE_FILE_HEADER header;
char* start = (char*)&header;
char* field = (char*)(&header.TimeDateStamp);
int diff = field - start;
diff
等于4
,正如我个人所期望的那样。
这是C#代码中的错误吗?为什么使用8
的偏移值?
答案 0 :(得分:3)
用于跳过其他签名,因为i
包含NT标头的偏移量,而不是文件图像标头(请参阅formal PE structure):
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature; //<- we need to skip this
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
因此实际总和为sizeof(WORD /* FileHeader.Machine */) + sizeof(WORD /* FileHeader.NumberOfSections */) + sizeof(DWORD /* Signature */)
底线,不是一个错误,只是一些魔法可以跳过一些结构嵌套/内联。
答案 1 :(得分:0)
DWORD是一个int无符号值,4个字节。
C#代码不正确,它读取8个字节。我认为它应该是4。
int secondsSince1970 = System.BitConverter.ToInt32(b, i + c_LinkerTimestampOffset);
几天前我写过一个PE读者。我将它用于“图像文件标题”:
public class IMAGE_FILE_HEADER
{
public UInt16 Machine;
public UInt16 NumberOfSections;
public UInt32 TimeDateStamp;
public UInt32 PointerToSymbolTable;
public UInt32 NumberOfSymbols;
public UInt16 SizeOfOptionalHeader;
public UInt16 Characteristics;
}
答案 2 :(得分:-1)
你最有可能获得一个8字节的差异,因为你是在64位系统/目标平台上,如果你在32位上就可能是你所期望的那样。
在32位系统上,DWORD定义为uint(32位/ 4字节),在64位系统上定义为ulong(64位/ 8字节)。
WORD基本上代表架构的地址大小。当它被创造时,WORD是16位而DWORD是双字,32位(4字节)。
人们希望在x86系统上DWORD为64位/ 8字节,但MS希望保留传统支持,以便保留旧的定义:http://msdn.microsoft.com/en-us/library/aa383751(VS.85).aspx