Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET DLL/EXE是否混淆?_C#_.net_Dll_Clr - Fatal编程技术网

C# .NET DLL/EXE是否混淆?

C# .NET DLL/EXE是否混淆?,c#,.net,dll,clr,C#,.net,Dll,Clr,出于兴趣,我一直在检查一个.NETDLL,使用ECMA-335作为参考,据我所知,我犯了一个严重的错误,因为它似乎是错的。我的错误是因为PE文件头没有在PE签名后立即出现 ECMA-335规定: “II.25.2.2 PE文件头 PE签名后的PE文件头由以下内容组成: 偏移量大小字段说明 02 机器始终为0x14c。“ 现在,当我使用下面的代码时,它适用于普通的、非托管的DLL和EXE unsafe static void Stuff(Stream stream, byte[] buf) {

出于兴趣,我一直在检查一个.NETDLL,使用ECMA-335作为参考,据我所知,我犯了一个严重的错误,因为它似乎是错的。我的错误是因为PE文件头没有在PE签名后立即出现

ECMA-335规定:

“II.25.2.2 PE文件头
PE签名后的PE文件头由以下内容组成:

偏移量大小字段说明
02
机器始终为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);
    }
}
机器号是幻数,创建时间是有意义的,并且PE可选标题中的幻数是正确的。在0x3c中指定的指针处,签名“PE\0\0”在那里,PE文件头直接在后面出现

但是,当我尝试检查.NET托管DLL时,我可以成功地找到签名“PE\0\0”,但PE文件头不会立即出现。所以我后来得到的数字是垃圾。当机器编号为34404(0x8664)而不是ECMA-335所述的332(0x14C)时,这一点变得明显


我一定是做错了什么,或者没有读到某个特定的部分,但我现在不知道那是什么。

它们符合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加载程序可以解析并运行托管代码。

规范有点过时,0x8664实际上是一个。托管(.net)程序集是PEs,我已经解析/检查了很多。它们是PEs。您刚刚遇到了一个PE32+,它是PE格式的一个扩展,用于解释64位代码。它们确实是,但.net版本似乎与ECMA-335不同(它似乎过时了)?请注意,它们包含本机指令。PE入口点必须始终指向旧操作系统的x86指令。实际上,通常会在那里调用MSCOREE.dll解释器(链接中的修复程序)。Windows loader是一种优化,可以跳过调用。此外,PE中的.NET标头指定程序集的EP(在所有存在的方法中,哪个方法是
main
方法),并且此EP可以是本机的(即x86指令)。