Esempio n. 1
0
 private void WriteRuntimeStartupStub(Stream peStream)
 {
     BinaryWriter writer = new BinaryWriter(new MemoryStream(16));
     // entry point code, consisting of a jump indirect to _CorXXXMain
     if (!_module.Requires64bits)
     {
         //emit 0's (nops) to pad the entry point code so that the target address is aligned on a 4 byte boundary.
         for (uint i = 0, n = (uint)(BitArithmeticUtilities.Align((uint)peStream.Position, 4) - peStream.Position); i < n; i++) writer.WriteByte(0);
         writer.WriteUshort(0);
         writer.WriteByte(0xff);
         writer.WriteByte(0x25); //4
         writer.WriteUint(_ntHeader.ImportAddressTable.RelativeVirtualAddress + (uint)_module.BaseAddress); //8
     }
     else
     {
         //emit 0's (nops) to pad the entry point code so that the target address is aligned on a 8 byte boundary.
         for (uint i = 0, n = (uint)(BitArithmeticUtilities.Align((uint)peStream.Position, 8) - peStream.Position); i < n; i++) writer.WriteByte(0);
         writer.WriteUint(0);
         writer.WriteUshort(0);
         writer.WriteByte(0xff);
         writer.WriteByte(0x25); //8
         writer.WriteUlong(_ntHeader.ImportAddressTable.RelativeVirtualAddress + _module.BaseAddress); //16
     }
     writer.BaseStream.WriteTo(peStream);
 }
Esempio n. 2
0
 private static void WriteCorHeader(Stream peStream, CorHeader corHeader)
 {
     BinaryWriter writer = new BinaryWriter(new MemoryStream(72));
     writer.WriteUint(72); // Number of bytes in this header  4
     writer.WriteUshort(corHeader.MajorRuntimeVersion); // 6 
     writer.WriteUshort(corHeader.MinorRuntimeVersion); // 8
     writer.WriteUint(corHeader.MetadataDirectory.RelativeVirtualAddress); // 12
     writer.WriteUint(corHeader.MetadataDirectory.Size); // 16
     writer.WriteUint((uint)corHeader.Flags); // 20
     writer.WriteUint(corHeader.EntryPointToken); // 24
     writer.WriteUint(corHeader.Resources.Size == 0 ? 0u : corHeader.Resources.RelativeVirtualAddress); // 28
     writer.WriteUint(corHeader.Resources.Size); // 32
     writer.WriteUint(corHeader.StrongNameSignature.Size == 0 ? 0u : corHeader.StrongNameSignature.RelativeVirtualAddress); // 36
     writer.WriteUint(corHeader.StrongNameSignature.Size); // 40
     writer.WriteUint(corHeader.CodeManagerTable.RelativeVirtualAddress); // 44
     writer.WriteUint(corHeader.CodeManagerTable.Size); // 48
     writer.WriteUint(corHeader.VTableFixups.RelativeVirtualAddress); // 52
     writer.WriteUint(corHeader.VTableFixups.Size); // 56
     writer.WriteUint(corHeader.ExportAddressTableJumps.RelativeVirtualAddress); // 60
     writer.WriteUint(corHeader.ExportAddressTableJumps.Size); // 64
     writer.WriteUlong(0); // 72
     writer.BaseStream.WriteTo(peStream);
 }
Esempio n. 3
0
        private void WriteImportAddressTable(Stream peStream)
        {
            BinaryWriter writer = new BinaryWriter(new MemoryStream(16));
            bool use32bitAddresses = !_module.Requires64bits;
            uint importTableRVA = _ntHeader.ImportTable.RelativeVirtualAddress;
            uint ilRVA = importTableRVA + 40;
            uint hintRva = ilRVA + (use32bitAddresses ? 12u : 16u);

            // Import Address Table
            if (use32bitAddresses)
            {
                writer.WriteUint(hintRva); // 4
                writer.WriteUint(0); // 8
            }
            else
            {
                writer.WriteUlong(hintRva); // 8
                writer.WriteUlong(0); // 16
            }

            writer.BaseStream.WriteTo(peStream);
        }
Esempio n. 4
0
        private void WriteImportTable(Stream peStream)
        {
            BinaryWriter writer = new BinaryWriter(new MemoryStream(70));
            bool use32bitAddresses = !_module.Requires64bits;
            uint importTableRVA = _ntHeader.ImportTable.RelativeVirtualAddress;
            uint ilRVA = importTableRVA + 40;
            uint hintRva = ilRVA + (use32bitAddresses ? 12u : 16u);
            uint nameRva = hintRva + 12 + 2;

            // Import table
            writer.WriteUint(ilRVA); // 4
            writer.WriteUint(0); // 8
            writer.WriteUint(0); // 12
            writer.WriteUint(nameRva); // 16
            writer.WriteUint(_ntHeader.ImportAddressTable.RelativeVirtualAddress); // 20
            writer.BaseStream.Position += 20; // 40

            // Import Lookup table
            if (use32bitAddresses)
            {
                writer.WriteUint(hintRva); // 44
                writer.WriteUint(0); // 48
                writer.WriteUint(0); // 52
            }
            else
            {
                writer.WriteUlong(hintRva); // 48
                writer.WriteUlong(0); // 56
            }

            // Hint table
            writer.WriteUshort(0); // Hint 54|58
            string entryPointName =
                (_module.Kind == ModuleKind.DynamicallyLinkedLibrary || _module.Kind == ModuleKind.WindowsRuntimeMetadata)
                ? "_CorDllMain" : "_CorExeMain";

            foreach (char ch in entryPointName)
            {
                writer.WriteByte((byte)ch); // 65|69
            }

            writer.WriteByte(0); // 66|70

            writer.BaseStream.WriteTo(peStream);
        }
Esempio n. 5
0
        private void WriteHeaders(Stream peStream, out long timestampOffset)
        {
            IModule module = _module;
            NtHeader ntHeader = _ntHeader;
            BinaryWriter writer = new BinaryWriter(_headerStream);

            // MS-DOS stub (128 bytes)
            writer.WriteBytes(s_dosHeader); // TODO: provide an option to suppress the second half of the DOS header?

            // PE Signature (4 bytes)
            writer.WriteUint(0x00004550); /* "PE\0\0" */

            // COFF Header 20 bytes
            writer.WriteUshort((ushort)module.Machine);
            writer.WriteUshort((ushort)ntHeader.NumberOfSections);
            timestampOffset = (uint)(writer.BaseStream.Position + peStream.Position);
            writer.WriteUint(ntHeader.TimeDateStamp);
            writer.WriteUint(ntHeader.PointerToSymbolTable);
            writer.WriteUint(0); // NumberOfSymbols
            writer.WriteUshort((ushort)(!module.Requires64bits ? 224 : 240)); // SizeOfOptionalHeader
            // ushort characteristics = 0x0002|0x0004|0x0008; // executable | no COFF line nums | no COFF symbols (as required by the standard)
            ushort characteristics = 0x0002; // executable (as required by the Linker team).
            if (module.Kind == ModuleKind.DynamicallyLinkedLibrary || module.Kind == ModuleKind.WindowsRuntimeMetadata)
            {
                characteristics |= 0x2000;
            }

            if (module.Requires32bits)
            {
                characteristics |= 0x0100; // 32 bit machine (The standard says to always set this, the linker team says otherwise)
                                           //The loader team says that this is not used for anything in the OS. 
            }
            else
            {
                characteristics |= 0x0020; // large address aware (the standard says never to set this, the linker team says otherwise).
                                           //The loader team says that this is not overridden for managed binaries and will be respected if set.
            }

            writer.WriteUshort(characteristics);

            // PE Header (224 bytes if 32 bits, 240 bytes if 64 bit)
            if (!module.Requires64bits)
            {
                writer.WriteUshort(0x10B); // Magic = PE32  // 2
            }
            else
            {
                writer.WriteUshort(0x20B); // Magic = PE32+ // 2
            }

            writer.WriteByte(module.LinkerMajorVersion); // 3
            writer.WriteByte(module.LinkerMinorVersion); // 4
            writer.WriteUint(ntHeader.SizeOfCode); // 8
            writer.WriteUint(ntHeader.SizeOfInitializedData); // 12
            writer.WriteUint(ntHeader.SizeOfUninitializedData); // 16
            writer.WriteUint(ntHeader.AddressOfEntryPoint); // 20
            writer.WriteUint(ntHeader.BaseOfCode); // 24
            if (!module.Requires64bits)
            {
                writer.WriteUint(ntHeader.BaseOfData); // 28
                writer.WriteUint((uint)module.BaseAddress); // 32
            }
            else
            {
                writer.WriteUlong(module.BaseAddress); // 32
            }

            writer.WriteUint(0x2000); // SectionAlignment 36
            writer.WriteUint(module.FileAlignment); // 40
            writer.WriteUshort(4); // MajorOperatingSystemVersion 42
            writer.WriteUshort(0); // MinorOperatingSystemVersion 44
            writer.WriteUshort(0); // MajorImageVersion 46
            writer.WriteUshort(0); // MinorImageVersion 48
            writer.WriteUshort(module.MajorSubsystemVersion); // MajorSubsystemVersion 50
            writer.WriteUshort(module.MinorSubsystemVersion); // MinorSubsystemVersion 52
            writer.WriteUint(0); // Win32VersionValue 56
            writer.WriteUint(ntHeader.SizeOfImage); // 60
            writer.WriteUint(ntHeader.SizeOfHeaders); // 64
            writer.WriteUint(0); // CheckSum 68
            switch (module.Kind)
            {
                case ModuleKind.ConsoleApplication:
                case ModuleKind.DynamicallyLinkedLibrary:
                case ModuleKind.WindowsRuntimeMetadata:
                    writer.WriteUshort(3); // 70
                    break;
                case ModuleKind.WindowsApplication:
                    writer.WriteUshort(2); // 70
                    break;
                default:
                    writer.WriteUshort(0); //
                    break;
            }

            writer.WriteUshort(module.DllCharacteristics);

            if (!module.Requires64bits)
            {
                writer.WriteUint((uint)module.SizeOfStackReserve); // 76
                writer.WriteUint((uint)module.SizeOfStackCommit); // 80
                writer.WriteUint((uint)module.SizeOfHeapReserve); // 84
                writer.WriteUint((uint)module.SizeOfHeapCommit); // 88
            }
            else
            {
                writer.WriteUlong(module.SizeOfStackReserve); // 80
                writer.WriteUlong(module.SizeOfStackCommit); // 88
                writer.WriteUlong(module.SizeOfHeapReserve); // 96
                writer.WriteUlong(module.SizeOfHeapCommit); // 104
            }

            writer.WriteUint(0); // LoaderFlags 92|108
            writer.WriteUint(16); // numberOfDataDirectories 96|112

            writer.WriteUint(ntHeader.ExportTable.RelativeVirtualAddress); // 100|116
            writer.WriteUint(ntHeader.ExportTable.Size); // 104|120
            writer.WriteUint(ntHeader.ImportTable.RelativeVirtualAddress); // 108|124
            writer.WriteUint(ntHeader.ImportTable.Size); // 112|128
            writer.WriteUint(ntHeader.ResourceTable.RelativeVirtualAddress); // 116|132
            writer.WriteUint(ntHeader.ResourceTable.Size); // 120|136
            writer.WriteUint(ntHeader.ExceptionTable.RelativeVirtualAddress); // 124|140
            writer.WriteUint(ntHeader.ExceptionTable.Size); // 128|144
            writer.WriteUint(ntHeader.CertificateTable.RelativeVirtualAddress); // 132|148
            writer.WriteUint(ntHeader.CertificateTable.Size); // 136|152
            writer.WriteUint(ntHeader.BaseRelocationTable.RelativeVirtualAddress); // 140|156
            writer.WriteUint(ntHeader.BaseRelocationTable.Size); // 144|160
            writer.WriteUint(ntHeader.DebugTable.RelativeVirtualAddress); // 148|164
            writer.WriteUint(ntHeader.DebugTable.Size); // 152|168
            writer.WriteUint(ntHeader.CopyrightTable.RelativeVirtualAddress); // 156|172
            writer.WriteUint(ntHeader.CopyrightTable.Size); // 160|176
            writer.WriteUint(ntHeader.GlobalPointerTable.RelativeVirtualAddress); // 164|180
            writer.WriteUint(ntHeader.GlobalPointerTable.Size); // 168|184
            writer.WriteUint(ntHeader.ThreadLocalStorageTable.RelativeVirtualAddress); // 172|188
            writer.WriteUint(ntHeader.ThreadLocalStorageTable.Size); // 176|192
            writer.WriteUint(ntHeader.LoadConfigTable.RelativeVirtualAddress); // 180|196
            writer.WriteUint(ntHeader.LoadConfigTable.Size); // 184|200
            writer.WriteUint(ntHeader.BoundImportTable.RelativeVirtualAddress); // 188|204
            writer.WriteUint(ntHeader.BoundImportTable.Size); // 192|208
            writer.WriteUint(ntHeader.ImportAddressTable.RelativeVirtualAddress); // 196|212
            writer.WriteUint(ntHeader.ImportAddressTable.Size); // 200|216
            writer.WriteUint(ntHeader.DelayImportTable.RelativeVirtualAddress); // 204|220
            writer.WriteUint(ntHeader.DelayImportTable.Size); // 208|224
            writer.WriteUint(ntHeader.CliHeaderTable.RelativeVirtualAddress); // 212|228
            writer.WriteUint(ntHeader.CliHeaderTable.Size); // 216|232
            writer.WriteUlong(0); // 224|240

            // Section Headers
            WriteSectionHeader(_textSection, writer);
            WriteSectionHeader(_rdataSection, writer);
            WriteSectionHeader(_sdataSection, writer);
            WriteSectionHeader(_coverSection, writer);
            WriteSectionHeader(_resourceSection, writer);
            WriteSectionHeader(_relocSection, writer);
            WriteSectionHeader(_tlsSection, writer);

            writer.BaseStream.WriteTo(peStream);
            _headerStream = _emptyStream;
        }