private void WriteImportDirectory(MetadataWriter mw) { mw.Write(ImportDirectoryRVA + 40); // ImportLookupTable mw.Write(0); // DateTimeStamp mw.Write(0); // ForwarderChain mw.Write(ImportHintNameTableRVA + 14); // Name mw.Write(ImportAddressTableRVA); mw.Write(new byte[20]); // Import Lookup Table mw.Write(ImportHintNameTableRVA); // Hint/Name Table RVA int size = 48; if (!peWriter.Is32Bit) { size += 4; mw.Write(0); } mw.Write(0); // alignment padding for (int i = (int)(ImportHintNameTableRVA - (ImportDirectoryRVA + size)); i > 0; i--) { mw.Write((byte)0); } // Hint/Name Table AssertRVA(mw, ImportHintNameTableRVA); mw.Write((ushort)0); // Hint if ((peWriter.Headers.FileHeader.Characteristics & IMAGE_FILE_HEADER.IMAGE_FILE_DLL) != 0) { mw.WriteAsciiz("_CorDllMain"); } else { mw.WriteAsciiz("_CorExeMain"); } // Name mw.WriteAsciiz("mscoree.dll"); mw.Write((byte)0); }
internal void Write(MetadataWriter mw, uint sdataRVA) { // sort the exports by ordinal text.moduleBuilder.unmanagedExports.Sort(CompareUnmanagedExportOrdinals); // Now write the Export Address Table text.AssertRVA(mw, exportAddressTableRVA); for (int i = 0, pos = 0; i < entries; i++) { if (text.moduleBuilder.unmanagedExports[pos].ordinal == i + ordinalBase) { mw.Write(text.peWriter.Thumb + stubsRVA + (uint)pos * stubLength); pos++; } else { mw.Write(0); } } // sort the exports by name text.moduleBuilder.unmanagedExports.Sort(CompareUnmanagedExportNames); // Now write the Export Name Pointer Table text.AssertRVA(mw, exportNamePointerTableRVA); uint nameOffset = (uint)text.moduleBuilder.fileName.Length + 1; foreach (UnmanagedExport exp in text.moduleBuilder.unmanagedExports) { if (exp.name != null) { mw.Write(namesRVA + nameOffset); nameOffset += (uint)exp.name.Length + 1; } } // Now write the Export Ordinal Table text.AssertRVA(mw, exportOrdinalTableRVA); foreach (UnmanagedExport exp in text.moduleBuilder.unmanagedExports) { if (exp.name != null) { mw.Write((ushort)(exp.ordinal - ordinalBase)); } } // Now write the actual names text.AssertRVA(mw, namesRVA); mw.WriteAsciiz(text.moduleBuilder.fileName); foreach (UnmanagedExport exp in text.moduleBuilder.unmanagedExports) { if (exp.name != null) { mw.WriteAsciiz(exp.name); } } text.AssertRVA(mw, namesRVA + namesLength); // alignment padding for (int i = (int)(stubsRVA - (namesRVA + namesLength)); i > 0; i--) { mw.Write((byte)0); } // sort the exports by ordinal text.moduleBuilder.unmanagedExports.Sort(CompareUnmanagedExportOrdinals); // Now write the stubs text.AssertRVA(mw, stubsRVA); for (int i = 0, pos = 0; i < entries; i++) { if (text.moduleBuilder.unmanagedExports[pos].ordinal == i + ordinalBase) { switch (text.peWriter.Headers.FileHeader.Machine) { case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: mw.Write((byte)0xFF); mw.Write((byte)0x25); mw.Write((uint)text.peWriter.Headers.OptionalHeader.ImageBase + text.moduleBuilder.unmanagedExports[pos].rva.initializedDataOffset + sdataRVA); mw.Write((short)0); // alignment break; case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64: mw.Write((byte)0x48); mw.Write((byte)0xA1); mw.Write(text.peWriter.Headers.OptionalHeader.ImageBase + text.moduleBuilder.unmanagedExports[pos].rva.initializedDataOffset + sdataRVA); mw.Write((byte)0xFF); mw.Write((byte)0xE0); mw.Write(0); // alignment break; case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_ARM: mw.Write((ushort)0xF8DF); mw.Write((ushort)0xC008); mw.Write((ushort)0xF8DC); mw.Write((ushort)0xC000); mw.Write((ushort)0x4760); mw.Write((ushort)0xDEFE); mw.Write((uint)text.peWriter.Headers.OptionalHeader.ImageBase + text.moduleBuilder.unmanagedExports[pos].rva.initializedDataOffset + sdataRVA); break; default: throw new NotSupportedException(); } pos++; } } }