Являются ли .NET DLL / EXEs PE конфиденциальными? - PullRequest
0 голосов
/ 13 февраля 2019

Я интересуюсь проверяю .NET DLL, используя ECMA-335 для справки, и, насколько я могу судить, я делаю серьезную ошибку, поскольку она кажется неправильной.Моя ошибка происходит из-за того, что заголовок файла PE не появляется сразу после подписи PE.

ECMA-335 утверждает, что:

"II.25.2.2 Заголовок файла PE
Сразу после подписи PE находится заголовок файла PE, состоящий из следующего:

Размер смещения Поле Описание
0 2
Machine Always 0x14c. "

Теперь, когда я использую следующий код, это работает для обычных неуправляемых DLL и EXE-файлов.

unsafe static void Stuff(Stream stream, byte[] buf)
{
    int read = stream.Read(buf, 0, 1024);
    // skip the first 128 bytes 
    // since that's the header 
    fixed (byte* ptr = buf)
    {
        // get the position of the signature?
        int PEHeaderStart = *(int*)(ptr + 0x3c);
        char PEsig1 = (char)*(ptr + PEHeaderStart); // P
        char PEsig2 = (char)*(ptr + PEHeaderStart + 1); // E
        char PEsig3 = (char)*(ptr + PEHeaderStart + 2); // \0
        char PEsig4 = (char)*(ptr + PEHeaderStart + 3); // \0 

        ushort machine = *(ushort*)(ptr + PEHeaderStart + 4);
        ushort noSections = *(ushort*)(ptr + PEHeaderStart + 6);

        uint secondsFrom1970 = *(uint*)(ptr + PEHeaderStart + 8);
        DateTime timeOfCreation = new DateTime(1970, 1, 1) + new TimeSpan((long)secondsFrom1970 * 1000 * 10000);

        uint pointerToSymbolTable = *(uint*)(ptr + PEHeaderStart + 12);
        uint numberOfSymbols = *(uint*)(ptr + PEHeaderStart + 16);
        ushort sizeOfOptionalHeader = *(ushort*)(ptr + PEHeaderStart + 20);

        ushort characteristics = *(ushort*)(ptr + PEHeaderStart + 22);

        // flags from characteristics 
        bool IMAGE_FILE_RELOCS_STRIPPED = (characteristics & 0x0001) == 1;
        bool IMAGE_FILE_EXECUTABLE_IMAGE = (characteristics & 0x002) == 1;
        bool IMAGE_FILE_32BIT_MACHINE = (characteristics & 0x0100) == 1;
        bool IMAGE_FILE_DLL = (characteristics & 0x2000) == 1;

        int optionalHeaderStart = PEHeaderStart + 24;

        // PE optional header 
        ushort magic = *(ushort*)(ptr + optionalHeaderStart);
        byte lmajor = *(ptr + optionalHeaderStart + 2);                
        byte lminor = *(ptr + optionalHeaderStart + 3);

        uint codesize = *(uint*)(ptr + optionalHeaderStart + 4);
    }
}

Номер машины - это магическое число, и timeOfCreation имеет смысл, и магическое число в необязательном заголовке PE является правильным.По указателю, указанному в 0x3c, есть подпись 'PE \ 0 \ 0', и заголовок файла PE появляется непосредственно после этого.

Однако, когда я пытаюсь проверить управляемую DLL-библиотеку .NET, я могу успешнонайдите подпись 'PE \ 0 \ 0', но заголовок файла PE не приходит сразу после этого.Так что число, которое я получаю после этого, является мусором.Это становится очевидным, когда номер машины равен 34404 (0x8664), а не 332 (0x14C), что, как говорит ECMA-335, должно иметь место.

Я, должно быть, делаю что-то не так или не читаю определенную часть, но я не могу понять, что это в данный момент.

1 Ответ

0 голосов
/ 14 февраля 2019

Они соответствуют PE, однако они не содержат разумных инструкций машины.Попробуйте запустить dumpbin /disasm на одном из них.Вы увидите, что он пытается интерпретировать код IL как машинные инструкции, что дает бессмысленные результаты.Например:

Microsoft (R) COFF/PE Dumper Version 14.16.27026.1
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file hello.exe

File Type: EXECUTABLE IMAGE

  00402000: 80 23 00           and         byte ptr [ebx],0
  00402003: 00 00              add         byte ptr [eax],al
  00402005: 00 00              add         byte ptr [eax],al
  00402007: 00 48 00           add         byte ptr [eax],cl
  0040200A: 00 00              add         byte ptr [eax],al
  0040200C: 02 00              add         al,byte ptr [eax]
  0040200E: 05 00 68 20 00     add         eax,206800h
  00402013: 00 E4              add         ah,ah
  00402015: 02 00              add         al,byte ptr [eax]
  00402017: 00 01              add         byte ptr [ecx],al
  00402019: 00 00              add         byte ptr [eax],al
  0040201B: 00 01              add         byte ptr [ecx],al
  0040201D: 00 00              add         byte ptr [eax],al
  0040201F: 06                 push        es
  00402020: 00 00              add         byte ptr [eax],al
  00402022: 00 00              add         byte ptr [eax],al
  00402024: 00 00              add         byte ptr [eax],al
  00402026: 00 00              add         byte ptr [eax],al
  00402028: 00 00              add         byte ptr [eax],al
  0040202A: 00 00              add         byte ptr [eax],al
  0040202C: 00 00              add         byte ptr [eax],al

Однако это нормально, поскольку загрузчик Windows знает, как загружать сборки .NET , чтобы управляемый код анализировался и выполнялся вместо него.

...