public static void WriteRectangleArray(EndianAwareBinaryWriter writer, Rectangle[] values) { WriteFloatArray(writer, values.Select(n => n.MinX).ToArray()); WriteFloatArray(writer, values.Select(n => n.MinY).ToArray()); WriteFloatArray(writer, values.Select(n => n.MaxX).ToArray()); WriteFloatArray(writer, values.Select(n => n.MaxY).ToArray()); }
public static void WritePropertyDataHelper <T>(EndianAwareBinaryWriter writer, T[] values, Action <EndianAwareBinaryWriter, T> writeProc) { foreach (var val in values) { writeProc(writer, val); } }
private LinkerSymbol CreateCustomAttributesTable(MosaUnit unit) { var symbolName = Metadata.CustomAttributesTable + unit.FullName; var customAttributesTableSymbol = Linker.GetSymbol(symbolName); if (customAttributesTableSymbol.Size != 0) { return(customAttributesTableSymbol); } // Emit custom attributes table customAttributesTableSymbol = Linker.DefineSymbol(symbolName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer = new EndianAwareBinaryWriter(customAttributesTableSymbol.Stream, Architecture.Endianness); // 1. Number of Custom Attributes writer.Write(unit.CustomAttributes.Count, TypeLayout.NativePointerSize); // 2. Pointers to Custom Attributes for (int i = 0; i < unit.CustomAttributes.Count; i++) { // Get custom attribute var ca = unit.CustomAttributes[i]; // Build definition var customAttributeTableSymbol = CreateCustomAttribute(unit, ca, i); // Link Linker.Link(LinkType.AbsoluteAddress, NativePatchType, customAttributesTableSymbol, writer.Position, customAttributeTableSymbol, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); } return(customAttributesTableSymbol); }
public static void WriteLengthPrefixedString(EndianAwareBinaryWriter writer, string value) { var stringBytes = RobloxEncoding.GetBytes(value); writer.WriteInt32(stringBytes.Length); writer.WriteBytes(stringBytes); }
private LinkerSymbol CreateParameterDefinition(MosaParameter parameter) { // Emit parameter name var parameterNameSymbol = EmitStringWithLength(Metadata.NameString + parameter, parameter.FullName); // Emit parameter table var parameterTableSymbol = Linker.DefineSymbol(Metadata.MethodDefinition + parameter.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer = new EndianAwareBinaryWriter(parameterTableSymbol.Stream, Architecture.Endianness); // 1. Pointer to Name Linker.Link(LinkType.AbsoluteAddress, NativePatchType, parameterTableSymbol, writer.Position, parameterNameSymbol, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 2. Pointer to Custom Attributes if (parameter.CustomAttributes.Count > 0) { var customAttributeListSymbol = CreateCustomAttributesTable(parameter); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, parameterTableSymbol, writer.Position, customAttributeListSymbol, 0); } writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 3. Attributes writer.Write((uint)parameter.ParameterAttributes, TypeLayout.NativePointerSize); // 4. Pointer to Parameter Type Linker.Link(LinkType.AbsoluteAddress, NativePatchType, parameterTableSymbol, writer.Position, Metadata.TypeDefinition + parameter.ParameterType.FullName, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); return(parameterTableSymbol); }
private void Serialize(EndianAwareBinaryWriter writer) { writer.WriteInt32(TypeId); Util.WriteLengthPrefixedString(writer, Name); writer.WriteByte((byte)PropertyType); SerializeValues(writer); }
private void WriteSectionHeaderStringSection(Section section, EndianAwareBinaryWriter writer) { Debug.Assert(section == sectionHeaderStringSection); section.Size = (uint)sectionHeaderStringTable.Count; writer.Write(sectionHeaderStringTable.ToArray()); }
private LinkerSymbol CreateCustomAttributesTable(MosaUnit unit) { // Emit custom attributes table var customAttributesTableSymbol = Linker.CreateSymbol(unit.FullName + Metadata.CustomAttributesTable, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer1 = new EndianAwareBinaryWriter(customAttributesTableSymbol.Stream, Architecture.Endianness); // 1. Number of Custom Attributes writer1.Write(unit.CustomAttributes.Count, TypeLayout.NativePointerSize); // 2. Pointers to Custom Attributes // Create the definitions along the way for (int i = 0; i < unit.CustomAttributes.Count; i++) { // Get custom attribute var ca = unit.CustomAttributes[i]; // Build definition var customAttributeTableSymbol = CreateCustomAttribute(unit, ca, i); // Link Linker.Link(LinkType.AbsoluteAddress, NativePatchType, customAttributesTableSymbol, (int)writer1.Position, 0, customAttributeTableSymbol, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); } // Return customAttributesTableSymbol for linker usage return(customAttributesTableSymbol); }
internal void Write(EndianAwareBinaryWriter writer) { writer.Write(this.majorVersion); writer.Write(this.MinorVersion); writer.Write(this.buildNumber); writer.Write(this.revision); }
private void WriteProgramHeaders(EndianAwareBinaryWriter writer) { writer.Position = elfheader.ProgramHeaderOffset; foreach (var section in Sections) { if (section.Size == 0 && section.SectionKind != SectionKind.BSS) { continue; } var pheader = new ProgramHeader { Alignment = 0, FileSize = section.AlignedSize, MemorySize = section.AlignedSize, Offset = section.FileOffset, VirtualAddress = (uint)section.VirtualAddress, PhysicalAddress = (uint)section.VirtualAddress, Type = ProgramHeaderType.Load, Flags = (section.SectionKind == SectionKind.Text) ? ProgramHeaderFlags.Read | ProgramHeaderFlags.Execute : (section.SectionKind == SectionKind.ROData) ? ProgramHeaderFlags.Read : ProgramHeaderFlags.Read | ProgramHeaderFlags.Write }; pheader.Write(writer); } }
private void EmitDebugLineFileName(EndianAwareBinaryWriter wr, uint directoryIndex, string name) { wr.WriteNullTerminatedString(name); wr.WriteULEB128(directoryIndex); wr.WriteULEB128(DwarfConstants.NullFileTime); wr.WriteULEB128(DwarfConstants.NullFileLength); }
protected override void PrimitiveCollectionSerializeOverride(StreamLimiter stream, int? itemLength, int? itemCount) { var typeNode = (ListTypeNode)TypeNode; var childSerializer = (ValueValueNode)typeNode.Child.CreateSerializer(this); var writer = new EndianAwareBinaryWriter(stream, Endianness); var childSerializedType = childSerializer.TypeNode.GetSerializedType(); var list = BoundValue as IList; if (list == null) return; // Handle const-sized mismatched collections if (itemCount != null && list.Count != itemCount) { var tempList = list; list = (IList)CreateCollection(itemCount.Value); for (int i = 0; i < Math.Min(tempList.Count, list.Count); i++) list[i] = tempList[i]; } foreach (var value in list) { if (stream.IsAtLimit) break; childSerializer.Serialize(writer, value, childSerializedType, itemLength); } }
/// <summary> /// Writes the header to the given binary writer. /// </summary> /// <param name="writer">The binary writer to write to.</param> public void Write(EndianAwareBinaryWriter writer) { writer.Write(e_magic); writer.Write(e_cblp); writer.Write(e_cp); writer.Write(e_crlc); writer.Write(e_cparhdr); writer.Write(e_minalloc); writer.Write(e_maxalloc); writer.Write(e_ss); writer.Write(e_sp); writer.Write(e_csum); writer.Write(e_ip); writer.Write(e_cs); writer.Write(e_lfarlc); writer.Write(e_ovno); writer.Write(e_res00); writer.Write(e_res01); writer.Write(e_res02); writer.Write(e_res03); writer.Write(e_oemid); writer.Write(e_oeminfo); writer.Write(e_res20); writer.Write(e_res21); writer.Write(e_res22); writer.Write(e_res23); writer.Write(e_res24); writer.Write(e_res25); writer.Write(e_res26); writer.Write(e_res27); writer.Write(e_res28); writer.Write(e_res29); writer.Write(e_lfanew); }
private void EmitDebugInfo(EndianAwareBinaryWriter wr) { // note: Compilation Unit Header != Debugging Information Entry // Compilation Unit Header var compilationUnitSizePosition = wr.Position; wr.Write((uint)7); // length wr.Write((ushort)0x02); // version wr.Write((uint)0); // abbr tag offset. wr.WriteByte(4); //addr size of platform var context = new DwarfWriteContext { Writer = wr, AbbrevList = AbbrevList }; var textSection = Compiler.Linker.Sections[(int)SectionKind.Text]; // Debugging Information Entry var cu = new DwarfCompilationUnit { Producer = "Mosa Compiler", ProgramCounterLow = (uint)textSection.VirtualAddress, ProgramCounterHigh = (uint)textSection.VirtualAddress + textSection.Size }; cu.Emit(context); uint compilationUnitSize = (uint)(wr.Position - compilationUnitSizePosition - sizeof(uint)); wr.Position = compilationUnitSizePosition; wr.Write(compilationUnitSize); wr.Position = wr.BaseStream.Length; }
private void WriteLinkerSection(Section section, EndianAwareBinaryWriter writer) { var linkerSection = linker.Sections[(int)section.SectionKind]; writer.Position = section.Offset; linker.WriteTo(writer.BaseStream, linkerSection); }
private LinkerSymbol CreateCustomAttributeArgument(string symbolName, int count, string name, MosaCustomAttribute.Argument arg, bool isField) { string nameForSymbol = name ?? count.ToString(); nameForSymbol = symbolName + ":" + nameForSymbol; var symbol = Linker.DefineSymbol(Metadata.CustomAttributeArgument + nameForSymbol, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer1 = new EndianAwareBinaryWriter(symbol.Stream, Architecture.Endianness); // 1. Pointer to name (if named) if (name != null) { var nameSymbol = EmitStringWithLength(Metadata.NameString + nameForSymbol, name); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, writer1.Position, nameSymbol, 0); } writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 2. Is Argument A Field writer1.Write(isField, TypeLayout.NativePointerSize); // 3. Argument Type Pointer Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, writer1.Position, Metadata.TypeDefinition + arg.Type.FullName, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 4. Argument Size writer1.Write(ComputeArgumentSize(arg.Type, arg.Value), TypeLayout.NativePointerSize); // 5. Argument Value WriteArgument(writer1, symbol, arg.Type, arg.Value); return(symbol); }
protected override void PrimitiveCollectionSerializeOverride(StreamLimiter stream, int? itemLength, int? itemCount) { var typeNode = (ArrayTypeNode)TypeNode; var childSerializer = (ValueValueNode)typeNode.Child.CreateSerializer(this); var writer = new EndianAwareBinaryWriter(stream, Endianness); var childSerializedType = childSerializer.TypeNode.GetSerializedType(); var array = BoundValue as Array; if (array == null) return; // Handle const-sized mismatched collections if (itemCount != null && array.Length != itemCount) { var tempArray = array; array = (Array)CreateCollection(itemCount.Value); Array.Copy(tempArray, array, Math.Min(tempArray.Length, array.Length)); } for (int i = 0; i < array.Length; i++) { if (stream.IsAtLimit) break; var value = array.GetValue(i); childSerializer.Serialize(writer, value, childSerializedType, itemLength); } }
internal void Write(EndianAwareBinaryWriter writer) { writer.Write((ushort)this.imageKind); writer.Write(this.lMajor); writer.Write(this.lMinor); writer.Write(this.codeSize); writer.Write(this.initializedDataSize); writer.Write(this.uninitializedDataSize); writer.Write(this.entryPointRVA); writer.Write(this.baseOfCode); switch (this.imageKind) { case PEImageKind.x86Image: writer.Write(this.baseOfData); break; case PEImageKind.x64Image: break; case PEImageKind.RomImage: throw new NotImplementedException(); default: throw new BadImageFormatException(); } }
private LinkerSymbol CreateInterfaceMethodTable(MosaType type, MosaType interfaceType) { // Emit interface method table var interfaceMethodTableSymbol = Linker.DefineSymbol(Metadata.InterfaceMethodTable + type.FullName + "$" + interfaceType.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer = new EndianAwareBinaryWriter(interfaceMethodTableSymbol.Stream, Architecture.Endianness); var interfaceMethodTable = TypeLayout.GetInterfaceTable(type, interfaceType) ?? new MosaMethod[0]; // 1. Number of Interface Methods writer.Write((uint)interfaceMethodTable.Length, TypeLayout.NativePointerSize); // 2. Pointer to Interface Type Linker.Link(LinkType.AbsoluteAddress, NativePatchType, interfaceMethodTableSymbol, writer.Position, Metadata.TypeDefinition + interfaceType.FullName, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 3. Pointers to Method Definitions foreach (var method in interfaceMethodTable) { // Create definition and get the symbol var methodDefinitionSymbol = CreateMethodDefinition(method); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, interfaceMethodTableSymbol, writer.Position, methodDefinitionSymbol, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); } return(interfaceMethodTableSymbol); }
/// <summary> /// Writes the structure to the given writer. /// </summary> /// <param name="writer">The writer.</param> public void Write(EndianAwareBinaryWriter writer) { if (writer == null) throw new ArgumentNullException(@"writer"); writer.Write(this.VirtualAddress); writer.Write(this.Size); }
public byte[] Serialize() { var stream = new MemoryStream(); var writer = new EndianAwareBinaryWriter(stream); Serialize(writer); return(stream.GetBuffer().Take((int)stream.Length).ToArray()); }
/// <summary> /// Writes the structure to the given writer. /// </summary> /// <param name="writer">The writer.</param> public void Write(EndianAwareBinaryWriter writer) { if (writer == null) throw new ArgumentNullException(@"writer"); writer.Write(this.Signature); this.FileHeader.Write(writer); this.OptionalHeader.Write(writer); }
private LinkerSymbol CreateAssemblyDefinition(MosaModule module) { // Emit assembly name var assemblyNameSymbol = EmitStringWithLength(Metadata.NameString + module.Assembly, module.Assembly); // Emit assembly table var assemblyTableSymbol = Linker.DefineSymbol(Metadata.AssemblyDefinition + module.Assembly, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer = new EndianAwareBinaryWriter(assemblyTableSymbol.Stream, Architecture.Endianness); // 1. Pointer to Assembly Name Linker.Link(LinkType.AbsoluteAddress, NativePatchType, assemblyTableSymbol, writer.Position, assemblyNameSymbol, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 2. Pointer to Custom Attributes if (module.CustomAttributes.Count > 0) { var customAttributeListSymbol = CreateCustomAttributesTable(module); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, assemblyTableSymbol, writer.Position, customAttributeListSymbol, 0); } writer.WriteZeroBytes(TypeLayout.NativePointerSize); // 3. Attributes - IsReflectionOnly (32bit length) uint flags = 0x0; if (module.IsReflectionOnly) { flags |= 0x1; } writer.Write(flags, TypeLayout.NativePointerSize); // 4. Number of Types uint count = 0; writer.WriteZeroBytes(4); // 5. Pointers to Types foreach (var type in module.Types.Values) { if (type.IsModule) { continue; } var typeTableSymbol = CreateTypeDefinition(type, assemblyTableSymbol); // Link Linker.Link(LinkType.AbsoluteAddress, NativePatchType, assemblyTableSymbol, writer.Position, typeTableSymbol, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); count++; } writer.Position = 3 * TypeLayout.NativePointerSize; writer.Write(count, TypeLayout.NativePointerSize); return(assemblyTableSymbol); }
private void EmitDirectories(EndianAwareBinaryWriter wr) { foreach (var entry in Directories.OrderBy(e => e.Value)) // order matters! { EmitDebugLineDirectoryName(wr, entry.Value, entry.Key); } wr.WriteByte(DwarfConstants.EndOfDirectories); }
private void EmitDebugAbbrev(EndianAwareBinaryWriter wr) { foreach (var abbr in AbbrevList) { EmitDebugAbbrev(wr, abbr); } wr.WriteULEB128(DwarfConstants.NullTag); }
private void EmitFiles(EndianAwareBinaryWriter wr) { foreach (var file in FileList) // order matters! { EmitDebugLineFileName(wr, file.DirectoryNum, file.Name); } wr.WriteByte(DwarfConstants.EndOfFiles); }
private void EmitProtectedRegionTable() { var trace = CreateTraceLog("Regions"); var protectedRegionTableSymbol = MethodCompiler.Linker.DefineSymbol(Metadata.ProtectedRegionTable + MethodCompiler.Method.FullName, SectionKind.ROData, NativeAlignment, 0); var writer = new EndianAwareBinaryWriter(protectedRegionTableSymbol.Stream, Architecture.Endianness); int sectioncount = 0; // 1. Number of Regions (filled in later) writer.Write((uint)0); foreach (var region in MethodCompiler.ProtectedRegions) { var handler = (uint)MethodCompiler.GetPosition(region.Handler.HandlerStart); trace?.Log($"Handler: {region.Handler.TryStart.ToString("X4")} to {region.Handler.TryEnd.ToString("X4")} Handler: {region.Handler.HandlerStart.ToString("X4")} Offset: [{handler.ToString("X4")}]"); var sections = new List <Tuple <int, int> >(); foreach (var block in region.IncludedBlocks) { // Check if block continues to exist if (!BasicBlocks.Contains(block)) { continue; } int start = MethodCompiler.GetPosition(block.Label); int end = MethodCompiler.GetPosition(block.Label + 0x0F000000); trace?.Log($" Block: {block} [{start.ToString()}-{end.ToString()}]"); AddSection(sections, start, end); } foreach (var s in sections) { int start = s.Item1; int end = s.Item2; sectioncount++; var name = Metadata.ProtectedRegionTable + MethodCompiler.Method.FullName + "$" + sectioncount.ToString(); var protectedRegionDefinition = CreateProtectedRegionDefinition(name, (uint)start, (uint)end, handler, region.Handler.ExceptionHandlerType, region.Handler.Type); MethodCompiler.Linker.Link(LinkType.AbsoluteAddress, NativePatchType, protectedRegionTableSymbol, writer.Position, protectedRegionDefinition, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); trace?.Log($" Section: [{start.ToString()}-{end.ToString()}]"); } } // 1. Number of Regions (now put the real number) writer.Position = 0; writer.Write(sectioncount); }
/// <summary> /// Writes the structure to the given writer. /// </summary> /// <param name="writer">The writer.</param> public void Write(EndianAwareBinaryWriter writer) { if (writer == null) { throw new ArgumentNullException(@"writer"); } writer.Write(this.VirtualAddress); writer.Write(this.Size); }
public static void WriteNumberSequence(EndianAwareBinaryWriter writer, NumberSequence sequence) { writer.WriteInt32(sequence.Keypoints.Length); for (var i = 0; i < sequence.Keypoints.Length; i++) { writer.WriteSingle(sequence.Keypoints[i].Time); writer.WriteSingle(sequence.Keypoints[i].Value); writer.WriteSingle(sequence.Keypoints[i].Envelope); } }
internal void Write(EndianAwareBinaryWriter writer) { writer.Write(this.signature); writer.Write((ushort)this.machine); writer.Write(this.sectionCount); writer.Write(this.secondsElapsedSinceEpoc); symbolTableRVAndSize.Write(writer); writer.Write(optionalHeaderSize); writer.Write((ushort)this.characteristics); }
/// <summary> /// Writes the elf header /// </summary> /// <param name="elfType">Type of the elf.</param> /// <param name="writer">The writer.</param> public void Write(LinkerFormatType elfType, EndianAwareBinaryWriter writer) { if (elfType == LinkerFormatType.Elf32) { Write32(writer); } else // if (elfType == ElfType.Elf64) { Write64(writer); } }
/// <summary> /// Writes the structure to the given writer. /// </summary> /// <param name="writer">The writer.</param> public void Write(EndianAwareBinaryWriter writer) { if (writer == null) { throw new ArgumentNullException(@"writer"); } writer.Write(this.Signature); this.FileHeader.Write(writer); this.OptionalHeader.Write(writer); }
public byte[] Serialize() { var stream = new MemoryStream(); var writer = new EndianAwareBinaryWriter(stream); Serialize(writer); var buffer = new byte[stream.Length]; Array.Copy(stream.GetBuffer(), buffer, stream.Length); return(buffer); }
public static byte[] SerializeParentData(Tuple <int, int>[] parentData) { var stream = new MemoryStream(); var writer = new EndianAwareBinaryWriter(stream); SerializeParentData(writer, parentData); var buffer = new byte[stream.Length]; Array.Copy(stream.GetBuffer(), buffer, stream.Length); return(buffer); }
private void CreateAssemblyDefinitionTable(ITypeModule typeModule) { string assemblyNameSymbol = typeModule.Name + @"$aname"; // Emit assembly name using (Stream stream = linker.Allocate(assemblyNameSymbol, SectionKind.ROData, 0, typeLayout.NativePointerAlignment)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, architecture.IsLittleEndian)) { EmitStringWithLength(writer, typeModule.Name); } } uint moduleTypes = 0; foreach (RuntimeType type in typeModule.GetAllTypes()) { if (!type.IsModule) moduleTypes++; } string assemblyTableSymbol = typeModule.Name + @"$atable"; using (Stream stream = linker.Allocate(assemblyTableSymbol, SectionKind.ROData, 0, typeLayout.NativePointerAlignment)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, architecture.IsLittleEndian)) { // 1. Pointer to Assembly Name linker.Link(LinkType.AbsoluteAddress | LinkType.NativeI4, assemblyTableSymbol, 0, 0, assemblyNameSymbol, IntPtr.Zero); writer.Position += typeLayout.NativePointerSize; // 2. Number of types writer.Write(moduleTypes); // 3. Pointer to list of types foreach (var type in typeModule.GetAllTypes()) { if (!type.IsModule && !(type.Module is InternalTypeModule)) linker.Link(LinkType.AbsoluteAddress | LinkType.NativeI4, assemblyTableSymbol, (int)writer.Position, 0, type.FullName + @"$dtable", IntPtr.Zero); writer.Position += typeLayout.NativePointerSize; } } } foreach (var type in typeModule.GetAllTypes()) { if (!type.IsModule) { CreateTypeDefinitionTable(type, assemblyTableSymbol); } } }
protected override void EmitImplementation(Stream stream) { var writer = new EndianAwareBinaryWriter(stream, Encoding.Unicode, Endianness); // Write the PE headers WriteDosHeader(writer); WritePEHeader(writer); foreach (var section in Sections) { stream.Position = (long)FILE_SECTION_ALIGNMENT; section.WriteTo(stream); } }
private void CreateFieldDefinitions(MosaType type) { foreach (MosaField field in type.Fields) { string fieldNameSymbol = field.FullName + @"$name"; // Emit field name using (Stream stream = Linker.Allocate(fieldNameSymbol, SectionKind.ROData, 0, TypeLayout.NativePointerAlignment)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, Architecture.Endianness)) { EmitStringWithLength(writer, field.Name); } } string fieldDescSymbol = field.FullName + @"$desc"; // Emit field descriptor using (Stream stream = Linker.Allocate(fieldDescSymbol, SectionKind.ROData, 0, TypeLayout.NativePointerAlignment)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, Architecture.Endianness)) { // 1. Offset / Address if (field.IsStatic && !field.IsLiteral) { Linker.Link(LinkType.AbsoluteAddress | LinkType.I4, BuiltInPatch.I4, fieldDescSymbol, (int)writer.Position, 0, field.FullName, 0); } else { writer.Write(TypeLayout.GetFieldOffset(field)); writer.Position -= 4; } writer.Position += TypeLayout.NativePointerSize; // 2. Name Linker.Link(LinkType.AbsoluteAddress | LinkType.I4, BuiltInPatch.I4, fieldDescSymbol, (int)writer.Position, 0, fieldNameSymbol, 0); writer.Position += TypeLayout.NativePointerSize; // 3. Size writer.Write((uint)TypeLayout.GetFieldSize(field)); // 4. Metadata Token writer.Write((uint)0); //FIXME! } } } }
/// <summary> /// Emits the implementation. /// </summary> /// <param name="stream">The stream.</param> protected override void EmitImplementation(Stream stream) { var writer = new EndianAwareBinaryWriter(stream, Encoding.Unicode, Endianness); // Write ELF header WriteElfHeader(writer); // Write program headers WriteProgramHeaders(writer); // Write section headers WriteSectionHeaders(writer); // Write sections foreach (var section in Sections) { stream.Position = section.FileOffset; section.WriteTo(stream); } WriteStringSection(writer); }
private void WriteStringHeaderSection(EndianAwareBinaryWriter writer) { stringSection.Name = AddToStringTable(".shstrtab"); stringSection.Type = SectionType.StringTable; stringSection.Flags = (SectionAttribute)0; stringSection.Address = 0; stringSection.Offset = GetSection(SectionKind.BSS).FileOffset + GetSection(SectionKind.BSS).AlignedSize; stringSection.Size = (uint)stringTable.Count; stringSection.Link = 0; stringSection.Info = 0; stringSection.AddressAlignment = SectionAlignment; stringSection.EntrySize = 0; stringSection.Write(writer); }
/// <summary> /// Writes the header to the given binary writer. /// </summary> /// <param name="writer">The binary writer to write to.</param> public void Write(EndianAwareBinaryWriter writer) { writer.Write(e_magic); writer.Write(e_cblp); writer.Write(e_cp); writer.Write(e_crlc); writer.Write(e_cparhdr); writer.Write(e_minalloc); writer.Write(e_maxalloc); writer.Write(e_ss); writer.Write(e_sp); writer.Write(e_csum); writer.Write(e_ip); writer.Write(e_cs); writer.Write(e_lfarlc); writer.Write(e_ovno); writer.Write(e_res00); writer.Write(e_res01); writer.Write(e_res02); writer.Write(e_res03); writer.Write(e_oemid); writer.Write(e_oeminfo); writer.Write(e_res20); writer.Write(e_res21); writer.Write(e_res22); writer.Write(e_res23); writer.Write(e_res24); writer.Write(e_res25); writer.Write(e_res26); writer.Write(e_res27); writer.Write(e_res28); writer.Write(e_res29); writer.Write(e_lfanew); }
/// <summary> /// Creates the PE file. /// </summary> private void CreatePEFile() { // Open the output file using (FileStream fs = new FileStream(this.OutputFile, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(fs, Encoding.Unicode, true)) { // Write the PE headers WriteDosHeader(writer); WritePEHeader(writer); // Iterate all sections and store their data long position = writer.BaseStream.Position; foreach (Section section in this.sections.Values) { if (section.Length > 0) { // Write the section section.Write(writer); // Add padding... position += section.Length; position += (this.fileAlignment - (position % this.fileAlignment)); WritePaddingToPosition(writer, position); } } // Do we need to set the checksum? if (this.setChecksum) { // Flush all data to disk writer.Flush(); // Write the checksum to the file ntHeaders.OptionalHeader.CheckSum = CalculateChecksum(this.OutputFile); fs.Position = this.dosHeader.e_lfanew; ntHeaders.Write(writer); } } } }
/// <summary> /// Writes the elf header /// </summary> /// <param name="elfType">Type of the elf.</param> /// <param name="writer">The writer.</param> public void Write(LinkerFormatType elfType, EndianAwareBinaryWriter writer) { if (elfType == LinkerFormatType.Elf32) Write32(writer); else // if (elfType == ElfType.Elf64) Write64(writer); }
/// <summary> /// Writes the elf header /// </summary> /// <param name="writer">The writer.</param> protected void Write64(EndianAwareBinaryWriter writer) { writer.Seek(0, SeekOrigin.Begin); writer.Write(Ident); // ident writer.Write((ushort)Type); // type writer.Write((ushort)Machine); // machine writer.Write((uint)Version); // version writer.Write(EntryAddress); // entry writer.Write((ulong)ProgramHeaderOffset); // phoff writer.Write((ulong)SectionHeaderOffset); // shoff writer.Write(Flags); // flags writer.Write(ElfHeaderSize64); // ehsize writer.Write(ProgramHeader.EntrySize64); // phentsize writer.Write(ProgramHeaderNumber); // phnum writer.Write(SectionHeaderEntry.EntrySize64); // shentsize writer.Write((ushort)SectionHeaderNumber); // shnum writer.Write((ushort)SectionHeaderStringIndex); // shstrndx }
/// <summary> /// Creates the elf32 file. /// </summary> private void CreateElf64File() { using (FileStream fs = new FileStream(this.OutputFile, FileMode.Create, FileAccess.Write, FileShare.None)) { Header header = new Header(); header.Type = FileType.Executable; header.Machine = Machine; header.SectionHeaderNumber = (ushort)(Sections.Count + 2); header.SectionHeaderOffset = header.ElfHeaderSize; header.CreateIdent(IdentClass.Class64, IdentData.Data2LSB, null); // Calculate the concatenated size of all section's data uint offset = 0; foreach (Section section in Sections) { offset += (uint)section.Length; } offset += (uint)nullSection.Length; offset += (uint)stringTableSection.Length; // Calculate offsets header.ProgramHeaderOffset = (uint)header.ElfHeaderSize + (uint)header.SectionHeaderEntrySize * (uint)header.SectionHeaderNumber + offset; header.SectionHeaderStringIndex = (ushort)((ushort)header.ProgramHeaderOffset + (ushort)header.ProgramHeaderNumber * (ushort)header.ProgramHeaderEntrySize); EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(fs, IsLittleEndian); // Write the ELF Header header.Write(writer); // Overjump the Section Header Table and write the section's data first long tmp = fs.Position; writer.Seek((int)(tmp + header.SectionHeaderNumber * header.SectionHeaderEntrySize), SeekOrigin.Begin); nullSection.Write(writer); stringTableSection.Write(writer); // Write the sections foreach (Section section in Sections) section.Write(writer); // Jump back to the Section Header Table writer.Seek((int)tmp, SeekOrigin.Begin); nullSection.WriteHeader(writer); stringTableSection.WriteHeader(writer); // Write the section headers foreach (Section section in Sections) section.WriteHeader(writer); } }
private void WriteElfHeader(EndianAwareBinaryWriter writer) { ushort sectons = (ushort)(CountNonEmptySections() + 1); elfheader.Type = FileType.Executable; elfheader.Machine = (MachineType)MachineID; elfheader.EntryAddress = (uint)EntryPoint.VirtualAddress; elfheader.CreateIdent(IdentClass.Class32, Endianness == Endianness.Little ? IdentData.Data2LSB : IdentData.Data2MSB, null); elfheader.ProgramHeaderOffset = Header.ElfHeaderSize; elfheader.ProgramHeaderNumber = sectons; elfheader.SectionHeaderNumber = (ushort)(sectons + 2); elfheader.SectionHeaderOffset = (uint)(elfheader.ProgramHeaderOffset + (Header.ProgramHeaderEntrySize * elfheader.ProgramHeaderNumber)); elfheader.SectionHeaderStringIndex = (ushort)(sectons + 1); elfheader.Write(writer); }
/// <summary> /// Writes the specified fs. /// </summary> /// <param name="writer">The writer.</param> public void Write(EndianAwareBinaryWriter writer) { writer.Seek(0, SeekOrigin.Begin); writer.Write(Ident); writer.Write((ushort)Type); writer.Write((ushort)Machine); writer.Write((uint)Version); writer.Write(EntryAddress); writer.Write(ProgramHeaderOffset); writer.Write(SectionHeaderOffset); writer.Write(Flags); writer.Write(ElfHeaderSize); writer.Write(ProgramHeaderEntrySize); writer.Write(ProgramHeaderNumber); writer.Write(SectionHeaderEntrySize); writer.Write(SectionHeaderNumber); SectionHeaderStringIndex = 1; writer.Write(SectionHeaderStringIndex); }
public static void PatchSyslinux_6_03(PartitionDevice partitionDevice, FatFileSystem fat) { // Locate ldlinux.sys file for patching string filename = "ldlinux.sys"; string name = (Path.GetFileNameWithoutExtension(filename) + Path.GetExtension(filename).PadRight(4).Substring(0, 4)).ToUpper(); var location = fat.FindEntry(new Mosa.FileSystem.FAT.Find.WithName(name), 0); if (!location.IsValid) throw new InvalidProgramException("Unable to find syslinux.sys"); // Get the file size & number of sectors used uint fileSize = fat.GetFileSize(location.DirectorySector, location.DirectorySectorIndex); var sectors = new List<uint>(); // Create list of the sectors of the file for (uint cluster = location.FirstCluster; (cluster != 0); cluster = fat.GetNextCluster(cluster)) { uint sec = fat.GetSectorByCluster(cluster); for (uint i = 0; i < fat.SectorsPerCluster; i++) { sectors.Add(sec + i); } } // Get the ldlinux.sys file stream var ldlinux = new FatFileStream(fat, location); var ldlinuxReader = new EndianAwareBinaryReader(ldlinux, Endianness.Little); // Search for 0x3EB202FE (magic) while ((ldlinuxReader.ReadUInt32() != Syslinux.LDLINUX_MAGIC) && (ldlinux.Position < ldlinux.Length)) ; if (ldlinux.Position >= ldlinux.Length || ldlinux.Position <= 0) throw new InvalidProgramException("Unable to find patch location for syslinux"); uint patchArea = (uint)ldlinux.Position - 4; // Get Extended Patch Area offset ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.EPAOffset; ushort epa = ldlinuxReader.ReadUInt16(); ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.Sect1Ptr0; uint sect1Ptr0 = (uint)ldlinuxReader.ReadUInt16(); ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.Sect1Ptr1; uint sect1Ptr1 = (uint)ldlinuxReader.ReadUInt16(); ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.SecPtrOffset; uint ex = (uint)ldlinuxReader.ReadUInt16(); ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.SecPtrCnt; uint nptrs = (uint)ldlinuxReader.ReadUInt16(); ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.AdvPtrOffset; uint advptrs = (uint)ldlinuxReader.ReadUInt16(); if (sectors.Count > nptrs) throw new InvalidProgramException("Insufficient space for patching syslinux"); var ldlinuxWriter = new EndianAwareBinaryWriter(ldlinux, Endianness.Little); // Set up the totals ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors; ldlinuxWriter.Write((ushort)sectors.Count); ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors; ldlinuxWriter.Write((ushort)2); ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors; ldlinuxWriter.Write((uint)fileSize >> 2); // Generate Extents var extents = GenerateExtents(sectors); ldlinux.Position = ex; // Write out extents foreach (var extent in extents) { ldlinuxWriter.Write((ulong)extent.Start); ldlinuxWriter.Write((ushort)extent.Length); } // Write out ADV ldlinux.Position = advptrs; ldlinuxWriter.Write((ulong)sectors[sectors.Count - 2]); ldlinuxWriter.Write((ulong)sectors[sectors.Count - 1]); // Clear out checksum ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.Checksum; ldlinuxWriter.Write((uint)0); // Write back the updated cluster ldlinuxWriter.Flush(); // Re-Calculate checksum ldlinux.Position = 0; uint csum = Syslinux.LDLINUX_MAGIC; for (uint index = 0; index < (ldlinux.Length >> 2); index++) { csum = csum + ldlinuxReader.ReadUInt32(); } // Set the checksum ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.Checksum; ldlinuxWriter.Write(csum); // Write patched cluster back to disk ldlinuxWriter.Flush(); // Read boot sector var fatBootSector = new BinaryFormat(partitionDevice.ReadBlock(0, 1)); // Set the first sector location of the file fatBootSector.SetUInt(sect1Ptr0, fat.GetSectorByCluster(location.FirstCluster)); fatBootSector.SetUInt(sect1Ptr1, 0); // since only 32-bit offsets are support, the high portion of 64-bit value is zero // Write back patched boot sector partitionDevice.WriteBlock(0, 1, fatBootSector.Data); }
/// <summary> /// Writes the PE header. /// </summary> /// <param name="writer">The writer.</param> private void WritePEHeader(EndianAwareBinaryWriter writer) { // Write the PE signature and headers ntHeaders.Signature = ImageNtHeaders.PE_SIGNATURE; // Prepare the file header ntHeaders.FileHeader.Machine = ImageFileHeader.IMAGE_FILE_MACHINE_I386; ntHeaders.FileHeader.NumberOfSections = CountSections(); ntHeaders.FileHeader.TimeDateStamp = (uint)(DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds; ntHeaders.FileHeader.PointerToSymbolTable = 0; ntHeaders.FileHeader.NumberOfSymbols = 0; ntHeaders.FileHeader.SizeOfOptionalHeader = 0x00E0; ntHeaders.FileHeader.Characteristics = 0x010E; // FIXME: Use an enum here // Prepare the "optional" headers ntHeaders.OptionalHeader.Magic = ImageOptionalHeader.IMAGE_OPTIONAL_HEADER_MAGIC; ntHeaders.OptionalHeader.MajorLinkerVersion = 6; ntHeaders.OptionalHeader.MinorLinkerVersion = 0; ntHeaders.OptionalHeader.SizeOfCode = AlignValue(GetSectionLength(SectionKind.Text), this.sectionAlignment); ntHeaders.OptionalHeader.SizeOfInitializedData = AlignValue(GetSectionLength(SectionKind.Data) + GetSectionLength(SectionKind.ROData), this.sectionAlignment); ntHeaders.OptionalHeader.SizeOfUninitializedData = AlignValue(GetSectionLength(SectionKind.BSS), this.sectionAlignment); ntHeaders.OptionalHeader.AddressOfEntryPoint = (uint)(this.EntryPoint.VirtualAddress.ToInt64() - this.BaseAddress); ntHeaders.OptionalHeader.BaseOfCode = (uint)(GetSectionAddress(SectionKind.Text) - this.BaseAddress); long sectionAddress = GetSectionAddress(SectionKind.Data); if (sectionAddress != 0) ntHeaders.OptionalHeader.BaseOfData = (uint)(sectionAddress - this.BaseAddress); ntHeaders.OptionalHeader.ImageBase = (uint)this.BaseAddress; // FIXME: Linker Script/cmdline ntHeaders.OptionalHeader.SectionAlignment = this.sectionAlignment; // FIXME: Linker Script/cmdline ntHeaders.OptionalHeader.FileAlignment = this.fileAlignment; // FIXME: Linker Script/cmdline ntHeaders.OptionalHeader.MajorOperatingSystemVersion = 4; ntHeaders.OptionalHeader.MinorOperatingSystemVersion = 0; ntHeaders.OptionalHeader.MajorImageVersion = 0; ntHeaders.OptionalHeader.MinorImageVersion = 0; ntHeaders.OptionalHeader.MajorSubsystemVersion = 4; ntHeaders.OptionalHeader.MinorSubsystemVersion = 0; ntHeaders.OptionalHeader.Win32VersionValue = 0; ntHeaders.OptionalHeader.SizeOfImage = CalculateSizeOfImage(); ntHeaders.OptionalHeader.SizeOfHeaders = this.fileAlignment; // FIXME: Use the full header size ntHeaders.OptionalHeader.CheckSum = 0; ntHeaders.OptionalHeader.Subsystem = 0x03; ntHeaders.OptionalHeader.DllCharacteristics = 0x0540; ntHeaders.OptionalHeader.SizeOfStackReserve = 0x100000; ntHeaders.OptionalHeader.SizeOfStackCommit = 0x1000; ntHeaders.OptionalHeader.SizeOfHeapReserve = 0x100000; ntHeaders.OptionalHeader.SizeOfHeapCommit = 0x1000; ntHeaders.OptionalHeader.LoaderFlags = 0; ntHeaders.OptionalHeader.NumberOfRvaAndSizes = ImageOptionalHeader.IMAGE_NUMBEROF_DIRECTORY_ENTRIES; ntHeaders.OptionalHeader.DataDirectory = new ImageDataDirectory[ImageOptionalHeader.IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; // Populate the CIL data directory ntHeaders.OptionalHeader.DataDirectory[14].VirtualAddress = 0;// (uint)GetSymbol(CLI_HEADER.SymbolName).VirtualAddress.ToInt64(); ntHeaders.OptionalHeader.DataDirectory[14].Size = 0; // CLI_HEADER.Length; ntHeaders.Write(writer); // Write the section headers uint address = this.fileAlignment; foreach (LinkerSection section in this.sections.Values) { if (section.Length > 0) { ImageSectionHeader ish = new ImageSectionHeader(); ish.Name = section.Name; ish.VirtualSize = (uint)section.Length; ish.VirtualAddress = (uint)(section.VirtualAddress.ToInt64() - this.BaseAddress); if (section.SectionKind != SectionKind.BSS) ish.SizeOfRawData = (uint)section.Length; ish.PointerToRawData = address; ish.PointerToRelocations = 0; ish.PointerToLinenumbers = 0; ish.NumberOfRelocations = 0; ish.NumberOfLinenumbers = 0; switch (section.SectionKind) { case SectionKind.BSS: ish.Characteristics = 0x40000000 | 0x80000000 | 0x00000080; break; case SectionKind.Data: ish.Characteristics = 0x40000000 | 0x80000000 | 0x00000040; break; case SectionKind.ROData: ish.Characteristics = 0x40000000 | 0x00000040; break; case SectionKind.Text: ish.Characteristics = 0x20000000 | 0x40000000 | 0x80000000 | 0x00000020; break; } ish.Write(writer); address += (uint)section.Length; address = AlignValue(address, this.fileAlignment); } } WritePaddingToPosition(writer, this.fileAlignment); }
/// <summary> /// Writes the dos header of the PE file. /// </summary> /// <param name="writer">The writer.</param> private void WriteDosHeader(EndianAwareBinaryWriter writer) { /* * This code block generates the default DOS header of a PE image. * These constants are not further documented here, please consult * MSDN for their meaning. */ this.dosHeader.e_magic = ImageDosHeader.DOS_HEADER_MAGIC; this.dosHeader.e_cblp = 0x0090; this.dosHeader.e_cp = 0x0003; this.dosHeader.e_cparhdr = 0x0004; this.dosHeader.e_maxalloc = 0xFFFF; this.dosHeader.e_sp = 0xb8; this.dosHeader.e_lfarlc = 0x0040; this.dosHeader.e_lfanew = 0x00000080; this.dosHeader.Write(writer); // Write the following 64 bytes, which represent the default x86 code to // print a message on the screen. byte[] message = new byte[] { 0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x20, 0x61, 0x20, 0x4D, 0x4F, 0x53, 0x41, 0x20, 0x70, 0x6F, 0x77, 0x65, 0x72, 0x65, 0x64, 0x20, 0x4F, 0x53, 0x2E, 0x0D, 0x0D, 0x0A, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; writer.Write(message); }
/// <summary> /// Creates the final linked file. /// </summary> protected override void CreateFile() { using (FileStream fs = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None)) { Header header = new Header(); header.Type = FileType.Executable; header.Machine = (MachineType)MachineID; header.SectionHeaderNumber = (ushort)(Sections.Length + 2); header.SectionHeaderOffset = header.ElfHeaderSize; header.EntryAddress = (uint)EntryPoint.VirtualAddress; header.CreateIdent(IdentClass.Class32, Endianness == Endianness.Little ? IdentData.Data2LSB : IdentData.Data2MSB, null); // Calculate the concatenated size of all section's data uint offset = 0; ushort programHeaderNumber = 0; foreach (Elf32LinkerSection section in Sections) { offset += (uint)section.Length; if (section.SectionKind != SectionKind.BSS && section.Length > 0) programHeaderNumber++; } offset += (uint)nullSection.Length; offset += (uint)stringTableSection.Length; // Calculate offsets header.ProgramHeaderOffset = header.ElfHeaderSize + header.SectionHeaderEntrySize * (uint)header.SectionHeaderNumber + offset; header.ProgramHeaderNumber = programHeaderNumber; header.SectionHeaderStringIndex = 1; EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(fs, Endianness); // Write the ELF Header header.Write(writer); // Overjump the Section Header Table and write the section's data first long tmp = fs.Position; writer.Seek((int)(tmp + header.SectionHeaderNumber * header.SectionHeaderEntrySize), SeekOrigin.Begin); nullSection.Write(writer); stringTableSection.Write(writer); // Write the _sections foreach (Elf32LinkerSection section in Sections) section.Write(writer); // Jump back to the Section Header Table writer.Seek((int)tmp, SeekOrigin.Begin); nullSection.WriteHeader(writer); stringTableSection.WriteHeader(writer); // Write the section headers foreach (Elf32LinkerSection section in Sections) section.WriteHeader(writer); writer.Seek((int)header.ProgramHeaderOffset, SeekOrigin.Begin); foreach (Elf32LinkerSection section in Sections) { if (section.SectionKind == SectionKind.BSS || section.Length == 0) continue; ProgramHeader pheader = new ProgramHeader { Alignment = 0, FileSize = (uint)section.Length, MemorySize = (uint)section.Length, Offset = section.Header.Offset, VirtualAddress = (uint)section.VirtualAddress, PhysicalAddress = (uint)section.VirtualAddress, Type = ProgramHeaderType.Load, Flags = (section.SectionKind == SectionKind.Text) ? ProgramHeaderFlags.Read | ProgramHeaderFlags.Execute : (section.SectionKind == SectionKind.ROData) ? ProgramHeaderFlags.Read : ProgramHeaderFlags.Read | ProgramHeaderFlags.Write }; pheader.Write(writer); } } }
/// <summary> /// /// </summary> /// <returns></returns> public static IEnumerator SendVideoStream(int intDeviceScreenWidth, int intDeviceScreenHeight) { byte[] bytTexture; //UnityEngine.Debug.Log("Entered SendVideoStream"); //make sure we dont start a new image tx until the last one is complete //also make sure that we are already connected to the device if (blnSendingScreenShot == false && ClientControl.Instance.IsConnected() == true) { UnityEngine.Debug.Log("sending new screen shot"); blnSendingScreenShot = true; // wait for graphics to render yield return new WaitForEndOfFrame(); // create a texture to pass to encoding Texture2D txtScreenCapture = TextureUtilities.CaptureScreenShot(); //if the device screen size is different than this one, then resize it if (txtScreenCapture.width != intDeviceScreenWidth || txtScreenCapture.height != intDeviceScreenHeight) { yield return 0; // scale the texture down TextureUtilities.TextureScale.Point(txtScreenCapture, intDeviceScreenWidth, intDeviceScreenHeight); } yield return 0; //txtScreenCapture.format = TextureFormat.ATC_RGBA8; bytTexture = TextureUtilities.TextureToBytes(txtScreenCapture); Int32 intCompressedSize = bytTexture.Length; UnityEngine.Debug.Log("about to write data to stream"); MemoryStream stream = new MemoryStream(); using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, false)) { writer.Write(ViewerConstants.MESSAGE_IMAGE); writer.Write(intDeviceScreenWidth); writer.Write(intDeviceScreenHeight); writer.Write(intCompressedSize); writer.Write(bytTexture); } UnityEngine.Debug.Log("convert stream to byte array"); byte[] bytTxData = stream.ToArray(); //send the texture to the clients ClientControl.Instance.SendTx(bytTxData); yield return 0; //System.Threading.Thread.Sleep(5000); // Tell unity to delete the texture, by default it seems to keep hold of it and memory crashes will occur after too many screenshots. //DestroyObject(txtScreenCapture); blnSendingScreenShot = false; } //UnityEngine.Debug.Log("Leaving SendVideoStream"); }
private void CreateTypeDefinitionTable(RuntimeType type, string assemblySymbol) { string typeNameSymbol = type + @"$tname"; // Emit type name using (Stream stream = linker.Allocate(typeNameSymbol, SectionKind.ROData, 0, typeLayout.NativePointerAlignment)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, architecture.IsLittleEndian)) { EmitStringWithLength(writer, type.FullName); } } string typeTableSymbol = type.FullName + @"$dtable"; using (Stream stream = linker.Allocate(typeTableSymbol, SectionKind.ROData, 0, typeLayout.NativePointerAlignment)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, architecture.IsLittleEndian)) { // 1. Size writer.Write((uint)typeLayout.GetTypeSize(type)); // 2. Metadata Token writer.Write((uint)type.Token.ToUInt32()); // 3. Pointer to Name linker.Link(LinkType.AbsoluteAddress | LinkType.NativeI4, typeTableSymbol, (int)writer.Position, 0, typeNameSymbol, IntPtr.Zero); writer.Position += typeLayout.NativePointerSize; // 4. Pointer to Assembly Definition linker.Link(LinkType.AbsoluteAddress | LinkType.NativeI4, typeTableSymbol, (int)writer.Position, 0, assemblySymbol, IntPtr.Zero); writer.Position += typeLayout.NativePointerSize; // 5. TODO: Constructor that accept no parameters, if any, for this type writer.WriteZeroBytes(typeLayout.NativePointerSize); // 6. Flag: IsInterface writer.WriteByte((byte)(type.IsInterface ? 1 : 0)); } } }
private void EmitProtectedBlockTable() { List<ProtectedBlock> entries = new List<ProtectedBlock>(); foreach (var clause in MethodCompiler.Method.ExceptionBlocks) { ProtectedBlock prev = new ProtectedBlock(); foreach (BasicBlock block in exceptionBlocks[clause]) { uint start = (uint)codeEmitter.GetPosition(block.Label); uint end = (uint)codeEmitter.GetPosition(block.Label + 0x0F000000); ExceptionHandlerType kind = clause.HandlerType; uint handler = 0; uint filter = 0; MosaType type = clause.Type; handler = (uint)codeEmitter.GetPosition(clause.HandlerOffset); if (kind == ExceptionHandlerType.Filter) { filter = (uint)codeEmitter.GetPosition(clause.FilterOffset.Value); } // TODO: Optimization - Search for existing exception protected region (before or after) to merge the current block // Simple optimization assuming blocks are somewhat sorted by position if (prev.End == start && prev.Kind == kind && prev.Handler == handler && prev.Filter == filter && prev.Type == type) { // merge protected blocks sequence prev.End = end; } else if (prev.Start == end && prev.Kind == kind && prev.Handler == handler && prev.Filter == filter && prev.Type == type) { // merge protected blocks sequence prev.Start = start; } else { // new protection block sequence ProtectedBlock entry = new ProtectedBlock(start, end, handler, kind, type, filter); entries.Add(entry); prev = entry; } } } int tableSize = (entries.Count * NativePointerSize * 5) + NativePointerSize; string section = MethodCompiler.Method.FullName + @"$etable"; using (Stream stream = MethodCompiler.Linker.Allocate(section, SectionKind.ROData, tableSize, NativePointerAlignment)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, Architecture.Endianness)) { foreach (ProtectedBlock entry in entries) { // FIXME: Assumes x86 platform writer.Write((uint)entry.Kind); writer.Write(entry.Start); writer.Write(entry.Length); writer.Write(entry.Handler); if (entry.Kind == ExceptionHandlerType.Exception) { // Store method table pointer of the exception object type // The VES exception runtime will uses this to compare exception object types MethodCompiler.Linker.Link(LinkType.AbsoluteAddress | LinkType.I4, BuiltInPatch.I4, section, (int)writer.Position, 0, entry.Type.FullName + "$mtable", 0); writer.Position += NativePointerSize; } else if (entry.Kind == ExceptionHandlerType.Filter) { // TODO: There are no plans in the short term to support filtered exception clause as C# does not use them writer.Position += NativePointerSize; } else { writer.Position += NativePointerSize; } } // Mark end of table writer.Position += TypeLayout.NativePointerSize; } } }
private void WriteProgramHeaders(EndianAwareBinaryWriter writer) { writer.Position = elfheader.ProgramHeaderOffset; foreach (var section in Sections) { if (section.Size == 0 && section.SectionKind != SectionKind.BSS) continue; var pheader = new ProgramHeader { Alignment = section.SectionAlignment, FileSize = section.AlignedSize, MemorySize = section.AlignedSize, Offset = section.FileOffset, VirtualAddress = (uint)section.VirtualAddress, PhysicalAddress = (uint)section.VirtualAddress, Type = ProgramHeaderType.Load, Flags = (section.SectionKind == SectionKind.Text) ? ProgramHeaderFlags.Read | ProgramHeaderFlags.Execute : (section.SectionKind == SectionKind.ROData) ? ProgramHeaderFlags.Read : ProgramHeaderFlags.Read | ProgramHeaderFlags.Write }; pheader.Write(writer); } }
private void WriteSectionHeaders(EndianAwareBinaryWriter writer) { writer.Position = elfheader.SectionHeaderOffset; WriteNullHeaderSection(writer); foreach (var section in Sections) { if (section.Size == 0 && section.SectionKind != SectionKind.BSS) continue; var sheader = new SectionHeader(); sheader.Name = AddToStringTable(section.Name); switch (section.SectionKind) { case SectionKind.Text: sheader.Type = SectionType.ProgBits; sheader.Flags = SectionAttribute.AllocExecute; break; case SectionKind.Data: sheader.Type = SectionType.ProgBits; sheader.Flags = SectionAttribute.Alloc | SectionAttribute.Write; break; case SectionKind.ROData: sheader.Type = SectionType.ProgBits; sheader.Flags = SectionAttribute.Alloc; break; case SectionKind.BSS: sheader.Type = SectionType.NoBits; sheader.Flags = SectionAttribute.Alloc | SectionAttribute.Write; break; } sheader.Address = (uint)section.VirtualAddress; sheader.Offset = section.FileOffset; sheader.Size = section.AlignedSize; sheader.Link = 0; sheader.Info = 0; sheader.AddressAlignment = section.SectionAlignment; sheader.EntrySize = 0; sheader.Write(writer); } WriteStringHeaderSection(writer); }
private void EmitStringWithLength(EndianAwareBinaryWriter stream, string value) { stream.Write(value.Length); stream.Write(System.Text.ASCIIEncoding.ASCII.GetBytes(value)); }
private static void WriteNullHeaderSection(EndianAwareBinaryWriter writer) { var nullsection = new SectionHeader(); nullsection.Name = 0; nullsection.Type = SectionType.Null; nullsection.Flags = 0; nullsection.Address = 0; nullsection.Offset = 0; nullsection.Size = 0; nullsection.Link = 0; nullsection.Info = 0; nullsection.AddressAlignment = 0; nullsection.EntrySize = 0; nullsection.Write(writer); }
/// <summary> /// /// </summary> /// <param name="strFileName"></param> public static IEnumerator SendVideoViaRenderTexture(int intDeviceScreenWidth, int intDeviceScreenHeight) { if (blnSendingScreenShot == false) { blnSendingScreenShot = true; yield return new WaitForEndOfFrame(); RenderTexture rtRenderTexture = new RenderTexture(intDeviceScreenWidth, intDeviceScreenHeight, 24); Camera.main.targetTexture = rtRenderTexture; Texture2D txtScreenShot = new Texture2D(intDeviceScreenWidth, intDeviceScreenHeight, TextureFormat.RGB24, false); Camera.main.Render(); yield return 0; RenderTexture.active = rtRenderTexture; txtScreenShot.ReadPixels(new Rect(0, 0, intDeviceScreenWidth, intDeviceScreenHeight), 0, 0); Camera.main.targetTexture = null; RenderTexture.active = null; GameObject.Destroy(rtRenderTexture); yield return 0; byte[] bytTexture = TextureUtilities.TextureToBytes(txtScreenShot); Int32 intCompressedSize = bytTexture.Length; yield return 0; UnityEngine.Debug.Log("about to write data to stream"); MemoryStream stream = new MemoryStream(); using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, false)) { writer.Write(ViewerConstants.MESSAGE_IMAGE); writer.Write(intDeviceScreenWidth); writer.Write(intDeviceScreenHeight); writer.Write(intCompressedSize); writer.Write(bytTexture); } UnityEngine.Debug.Log("convert stream to byte array"); byte[] bytTxData = stream.ToArray(); //send the texture to the clients ClientControl.Instance.SendTx(bytTxData); blnSendingScreenShot = false; } }
/// <summary> /// Creates the elf32 file. /// </summary> /// <param name="compiler">The compiler.</param> private void CreateElf32File() { using (FileStream fs = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None)) { Header header = new Header(); header.Type = FileType.Executable; header.Machine = Machine; header.SectionHeaderNumber = (ushort)(Sections.Count + 2); header.SectionHeaderOffset = header.ElfHeaderSize; header.CreateIdent(IdentClass.Class32, IsLittleEndian ? IdentData.Data2LSB : IdentData.Data2MSB, null); // Calculate the concatenated size of all section's data uint offset = 0; foreach (Section section in Sections) { offset += (uint)section.Length; } offset += (uint)nullSection.Length; offset += (uint)stringTableSection.Length; // Calculate offsets header.ProgramHeaderOffset = header.ElfHeaderSize + header.SectionHeaderEntrySize * (uint)header.SectionHeaderNumber + offset; header.ProgramHeaderNumber = 1; header.SectionHeaderStringIndex = 1; EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(fs, IsLittleEndian); // Write the ELF Header header.Write(writer); // Overjump the Section Header Table and write the section's data first long tmp = fs.Position; writer.Seek((int)(tmp + header.SectionHeaderNumber * header.SectionHeaderEntrySize), SeekOrigin.Begin); nullSection.Write(writer); stringTableSection.Write(writer); // Write the _sections foreach (Section section in Sections) section.Write(writer); // Jump back to the Section Header Table writer.Seek((int)tmp, SeekOrigin.Begin); nullSection.WriteHeader(writer); stringTableSection.WriteHeader(writer); // Write the section headers foreach (Section section in Sections) section.WriteHeader(writer); ProgramHeader pheader = new ProgramHeader { Alignment = 0, FileSize = (uint)GetSection(SectionKind.Text).Length }; pheader.MemorySize = pheader.FileSize; pheader.VirtualAddress = 0xFF0000; pheader.Flags = ProgramHeaderFlags.Execute | ProgramHeaderFlags.Read | ProgramHeaderFlags.Write; pheader.Offset = ((Section)GetSection(SectionKind.Text)).Header.Offset; pheader.Type = ProgramHeaderType.Load; writer.Seek((int)header.ProgramHeaderOffset, SeekOrigin.Begin); pheader.Write(writer); } }
private void CreateAssemblyListTable() { string assemblyListSymbol = @"<$>AssemblyList"; using (Stream stream = linker.Allocate(assemblyListSymbol, SectionKind.ROData, 0, typeLayout.NativePointerAlignment)) { using (EndianAwareBinaryWriter writer = new EndianAwareBinaryWriter(stream, architecture.IsLittleEndian)) { // 1. Number of assemblies (modules) writer.Write((uint)typeSystem.TypeModules.Count); // 2. Pointers to assemblies foreach (var module in typeSystem.TypeModules) { linker.Link(LinkType.AbsoluteAddress | LinkType.NativeI4, assemblyListSymbol, (int)writer.Position, 0, module.Name + "$atable", IntPtr.Zero); writer.Position += typeLayout.NativePointerSize; } } } // Create a table per assembly foreach (var module in typeSystem.TypeModules) { CreateAssemblyDefinitionTable(module); } }