1

.NET アセンブリがビルドされた時刻を取得するためのコードを次に示します。ノート:

const int c_LinkerTimestampOffset = 8;

以降:

int secondsSince1970 = System.BitConverter.ToInt32(b, i + c_LinkerTimestampOffset);

このコードは、アセンブリ内に格納されているIMAGE_FILE_HEADER 構造体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;

であり、WORD2 バイトであり、2 バイトでアラインされている必要があります。次のコードを Visual C++ 10 でコンパイルすると:

IMAGE_FILE_HEADER header;
char* start = (char*)&header;
char* field = (char*)(&header.TimeDateStamp);
int diff = field - start;

diff4私が個人的に期待していたのと同じです。

それは C# コードのバグですか? のオフセット値が8使用されるのはなぜですか?

4

3 に答える 3

3

iファイル イメージ ヘッダーではなく、NT ヘッダーへのオフセットが含まれているため、追加の署名をスキップするために使用されます (正式な PE 構造を参照してください)。

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 */)

要するに、バグではなく、構造のネスト/インライン化を少しスキップするための魔法です。

于 2012-09-28T12:29:22.390 に答える
0

DWORD は int unsigned 値で、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;
}
于 2012-09-28T12:10:04.543 に答える
-1

64ビットのシステム/ターゲットプラットフォームを使用しているため、8バイトの差分が得られる可能性があります。32ビットを使用している場合は、期待どおりの結果になります。

32ビットシステムでは、DWORDはuint(32ビット/ 4バイト)として定義され、64ビットシステムでは、ulong(64ビット/ 8バイト)として定義されます。

WORDは、基本的にアーキテクチャのアドレスサイズを表します。造られたとき、WORDは16ビットで、DWORDは32ビット(4バイト)のダブルワードでした。

DWORDはx86システムでは64ビット/8バイトであると予想されますが、MSはレガシーサポートを維持したかったため、古い定義を維持しました:http://msdn.microsoft.com/en-us/library/aa383751(VS.85) .aspx

于 2012-09-28T12:49:36.570 に答える