/// <summary>Takes a string and adds it to the pool</summary> /// <param name="str">value to add</param> /// <returns>address reference of the string</returns> /// <remarks> /// If <see cref="Configuration.AllowDuplicates"/> is NOT true, this will return an address /// of a string which is equal to <paramref name="str"/> /// </remarks> public Values.PtrHandle Add(string str) { int index; if (string.IsNullOrEmpty(str)) { if (Settings.ImplicitNull) // if we're setup to use a implicit null string, its always the first string in the pool { return(Settings.BaseAddress); } if (mNullReference == kInvalidReference) // if not, check to see if a null string has been added yet { index = Count; this.AddInternal(""); mNullReference = Settings.BaseAddress + mReferences[index]; } return(mNullReference); } // If we allow dups, we won't try to find a matching entry, we'll immediately add it. if (Settings.AllowDuplicates || !mStringToIndex.TryGetValue(str, out index)) { index = Count; this.AddInternal(str); } return(mReferences[index]); }
public static bool StreamPointerizedCString(IO.EndianStream s, ref Values.PtrHandle pointer, ref string value) { Contract.Requires(s != null); bool streamed = false; if (s.IsReading) { if (!pointer.IsInvalidHandle) { s.Seek((long)pointer.u64, System.IO.SeekOrigin.Begin); value = s.Reader.ReadString(Memory.Strings.StringStorage.CStringAscii); streamed = true; } } else if (s.IsWriting) { if (string.IsNullOrEmpty(value)) { pointer = pointer.Is64bit ? Values.PtrHandle.InvalidHandle64 : Values.PtrHandle.InvalidHandle32; } else { pointer = new Values.PtrHandle(pointer, (ulong)s.BaseStream.Position); s.Writer.Write(value, Memory.Strings.StringStorage.CStringAscii); streamed = true; } } return(streamed); }
/// <summary>Read a pointer value from the stream</summary> /// <param name="addressSize">Size of the pointer we're to read</param> /// <returns> /// A handle that encapsulates the pointer value and its size. After the value /// is read from the stream, <see cref="BaseAddress"/> is subtracted. /// </returns> /// <remarks> /// Be sure to set <see cref="BaseAddress"/> to the proper value so you get /// a correct relative-virtual-address. Otherwise, set <see cref="BaseAddress"/> /// to zero to get the pure pointer value. /// </remarks> public Values.PtrHandle ReadPointer(Shell.ProcessorSize addressSize) { var ptr = new Values.PtrHandle(addressSize); if (!ptr.Is64bit) { ptr.u32 = ReadUInt32(); if (ptr.u32 != 0) { ptr.u32 -= BaseAddress.u32; } } else { ptr.u64 = ReadUInt64(); if (ptr.u64 != 0) { ptr.u64 -= BaseAddress.u64; } } return(ptr); }
public void Write(IO.EndianWriter s) { var xmbContext = s.UserData as XmbFileContext; s.Write(RootElementIndex); XmbVariantSerialization.Write(s, NameVariant); XmbVariantSerialization.Write(s, InnerTextVariant); if (xmbContext.PointerSize == Shell.ProcessorSize.x64) { s.Pad32(); } #region Attributes header s.Write(Attributes.Count); if (xmbContext.PointerSize == Shell.ProcessorSize.x64) { s.Pad32(); } mAttributesOffsetPos = s.PositionPtr; s.WriteVirtualAddress(Values.PtrHandle.InvalidHandle32); #endregion #region Children header s.Write(ChildrenIndices.Count); if (xmbContext.PointerSize == Shell.ProcessorSize.x64) { s.Pad32(); } mChildrenOffsetPos = s.PositionPtr; s.WriteVirtualAddress(Values.PtrHandle.InvalidHandle32); #endregion }
/// <summary>Write a pointer value to the stream</summary> /// <param name="value">Handle to stream</param> /// <remarks> /// <see cref="BaseAddress"/> is added to the value of <paramref name="value"/> /// before the final stream happens. /// /// Be sure to set <see cref="BaseAddress"/> to the proper value so you write /// the correct virtual-address. Otherwise, set <see cref="BaseAddress"/> /// to zero to write the pure pointer value. /// </remarks> public void WritePointer(Values.PtrHandle value) { if (!value.IsNull) { if (!value.Is64bit) { Write(value.u32 + BaseAddress.u32); } else { Write(value.u64 + BaseAddress.u64); } } else { if (!value.Is64bit) { Write(uint.MinValue); } else { Write(ulong.MinValue); } } }
/// <summary>Define a new <see cref="StringMemoryPool"/> configuration</summary> /// <param name="method">Text storage definition</param> /// <param name="implicitNull">Is a null string entry atomically added?</param> /// <param name="baseAddress">Base address for string references</param> /// <remarks><see cref="AddressSize"/> is determined from <see cref="baseAddress"/></remarks> public StringMemoryPoolSettings(StringStorage method, bool implicitNull, Values.PtrHandle baseAddress) { { Storage = method; AllowDuplicates = false; } mAddressSize = baseAddress.Is64bit ? Shell.ProcessorSize.x64 : Shell.ProcessorSize.x32; ImplicitNull = implicitNull; BaseAddress = baseAddress; }
public void StreamVirtualAddress(ref Values.PtrHandle physicalAddress) { if (IsReading) { Reader.ReadVirtualAddress(out physicalAddress); } else if (IsWriting) { Writer.WriteVirtualAddress(physicalAddress); } }
/// <summary>Increase the current address (PA) by a relative offset</summary> /// <param name="relativeOffset">Offset, relative to the current address</param> public void VirtualAddressTranslationIncrease(Values.PtrHandle relativeOffset) { if (Reader != null) { Reader.VirtualAddressTranslationIncrease(relativeOffset); } if (Writer != null) { Writer.VirtualAddressTranslationIncrease(relativeOffset); } }
/// <summary>Push a PA into to the VAT table, setting the current PA in the process</summary> /// <param name="physicalAddress">PA to push and to use as the VAT's current address</param> public void VirtualAddressTranslationPush(Values.PtrHandle physicalAddress) { if (Reader != null) { Reader.VirtualAddressTranslationPush(physicalAddress); } if (Writer != null) { Writer.VirtualAddressTranslationPush(physicalAddress); } }
/// <summary>Read a pointer value from the stream with no postprocessing to the result</summary> /// <param name="ptrHandle">Handle to stream the value into</param> public void ReadRawPointer(ref Values.PtrHandle ptrHandle) { if (!ptrHandle.Is64bit) { ptrHandle.u32 = ReadUInt32(); } else { ptrHandle.u64 = ReadUInt64(); } }
public virtual void BuildBuffer(IO.EndianStream blockStream, Stream sourceFile , Security.Cryptography.TigerHashBase hasher = null) { blockStream.AlignToBoundry(DataAlignmentBit); sourceFile.Seek(0, SeekOrigin.Begin); if (hasher != null) { UpdateDecompressedDataTigerHash(sourceFile, hasher); } Contract.Assert(blockStream.BaseStream.Position == blockStream.BaseStream.Length); DataOffset = blockStream.PositionPtr; // #TODO determine if compressing the sourceFile data has any savings (eg, 7% smaller) var assumed_compression_type = CompressionType; // #NOTE CompressionType can be Stored but IsDeflateStream can be true (seen it in XMB). // So just handle the flag as we do EcfCompressionType.DeflateStream if (IsDeflateStream) { assumed_compression_type = EcfCompressionType.DeflateStream; } switch (assumed_compression_type) { case EcfCompressionType.Stored: { // Update this ECF's size DataSize = (int)sourceFile.Length; // Also update this ECF's checksum Adler32 = Security.Cryptography.Adler32.Compute(sourceFile, DataSize, restorePosition: true); // Copy the source file's bytes to the block stream sourceFile.CopyTo(blockStream.BaseStream); break; } case EcfCompressionType.DeflateRaw: CompressSourceToStream(blockStream.Writer, sourceFile); break; case EcfCompressionType.DeflateStream: CompressSourceToCompressionStream(blockStream.Writer, sourceFile); break; default: throw new KSoft.Debug.UnreachableException(assumed_compression_type.ToString()); } Contract.Assert(blockStream.BaseStream.Position == ((long)DataOffset + DataSize)); }
public EndianStream StreamPointerViaBaseAddress(ref Values.PtrHandle value) { if (IsReading) { value = Reader.ReadPointerViaBaseAddress(); } else if (IsWriting) { Writer.WritePointer(value); } return(this); }
public EndianStream StreamPointer(ref Values.PtrHandle value, Shell.ProcessorSize addressSize) { if (IsReading) { value = Reader.ReadPointer(addressSize); } else if (IsWriting) { Writer.WritePointer(value); } return(this); }
public EndianStream StreamPointer(ref Values.PtrHandle value) { if (IsReading) { Reader.ReadPointer(ref value); } else if (IsWriting) { Writer.WritePointer(value); } return(this); }
public ResourceTagHeader(Shell.ProcessorSize pointerSize = Shell.ProcessorSize.x32) { if (pointerSize == Shell.ProcessorSize.x32) { TagMachineNameOffset = Values.PtrHandle.InvalidHandle32; TagUserNameOffset = Values.PtrHandle.InvalidHandle32; CreatorToolCommandLine = Values.PtrHandle.InvalidHandle32; } else { TagMachineNameOffset = Values.PtrHandle.InvalidHandle64; TagUserNameOffset = Values.PtrHandle.InvalidHandle64; CreatorToolCommandLine = Values.PtrHandle.InvalidHandle64; } }
/// <summary>Read the header for the pool from a stream to properly initialize this pool's configuration, counts, etc</summary> /// <param name="s"></param> public void ReadHeader(IO.EndianReader s) { Contract.Requires(s != null); // #TODO: test to see if the config is a built-in, else we could overwrite an existing config // Configuration.Read(s); int count = s.ReadInt32(); Size = s.ReadUInt32(); InitializeCollections(count); for (int x = 0; x < mReferences.Count; x++) { mReferences[x] = new Values.PtrHandle(Settings.AddressSize); } }
public void Read(KSoft.IO.EndianReader s) { var storage = new StringStorage(); storage.Read(s); Storage = storage; mAddressSize = (Shell.ProcessorSize)s.ReadByte(); ImplicitNull = s.ReadBoolean(); AllowDuplicates = s.ReadBoolean(); s.Seek(sizeof(byte)); var base_addr = new Values.PtrHandle(mAddressSize); base_addr.Read(s); BaseAddress.Read(s); }
/// <summary>Read a pointer value from the stream with no postprocessing to the result</summary> /// <param name="addressSize">Size of the pointer we're to read</param> /// <returns></returns> public Values.PtrHandle ReadRawPointer(Shell.ProcessorSize addressSize) { var ptr = new Values.PtrHandle(addressSize); if (!ptr.Is64bit) { ptr.u32 = ReadUInt32(); } else { ptr.u64 = ReadUInt64(); } return(ptr); }
/// <summary>Read a pointer value from the stream</summary> /// <param name="ptrHandle">Handle to stream the value into</param> /// <remarks> /// After the value is read from the stream, <see cref="BaseAddress"/> is subtracted. /// /// Be sure to set <see cref="BaseAddress"/> to the proper value so you get /// a correct relative-virtual-address. Otherwise, set <see cref="BaseAddress"/> /// to zero to get the pure pointer value. /// </remarks> public void ReadPointer(ref Values.PtrHandle ptrHandle) { if (!ptrHandle.Is64bit) { ptrHandle.u32 = ReadUInt32(); if (ptrHandle.u32 != 0) { ptrHandle.u32 -= BaseAddress.u32; } } else { ptrHandle.u64 = ReadUInt64(); if (ptrHandle.u64 != 0) { ptrHandle.u64 -= BaseAddress.u64; } } }
/*public*/ int GetIndex(Values.PtrHandle address) { return(mReferences.FindIndex(x => x == address)); }
public string this[Values.PtrHandle address] { get { return(Get(address)); } }
/// <summary>Push a PA into to the VAT table, setting the current PA in the process</summary> /// <param name="physicalAddress">PA to push and to use as the VAT's current address</param> public void VirtualAddressTranslationPush(Values.PtrHandle physicalAddress) { VerifyVAT(); mVAT.PushPhysicalAddress(physicalAddress); }
/// <summary>Increase the current address (PA) by a relative offset</summary> /// <param name="relativeOffset">Offset, relative to the current address</param> public void VirtualAddressTranslationIncrease(Values.PtrHandle relativeOffset) { VerifyVAT(); mVAT.PushPhysicalAddressOffset(relativeOffset); }
/// <summary>Write a physical address, translating it into a VA first, to the stream</summary> /// <param name="physicalAddress">Physical address to be translated into virtual address</param> public void WriteVirtualAddress(Values.PtrHandle physicalAddress) { VerifyVAT(); mVAT.WritePhysicalAsVirtualAddress(this, physicalAddress); }
/// <summary>Read and translate a VA from the stream into a physical address</summary> /// <param name="physicalAddress">Virtual address from the stream in physical address form</param> public void ReadVirtualAddress(out Values.PtrHandle physicalAddress) { VerifyVAT(); physicalAddress = mVAT.ReadVirtualAsPhysicalAddress(this); }
public string Get(Values.PtrHandle address) { return(mPool[GetIndex(address)]); }
/// <summary>Define a new <see cref="StringMemoryPool"/> configuration</summary> /// <param name="method">Text storage definition</param> /// <param name="baseAddress">Base address for string references</param> /// <remarks>A null string entry <b>is</b> added by default</remarks> public StringMemoryPoolSettings(StringStorage method, Values.PtrHandle baseAddress) : this(method, true, baseAddress) { }
/// <summary>Read a pointer value from the stream (size inherited from <see cref="BaseAddress"/>)</summary> /// <param name="ptrHandle">Handle to initialize and stream the value into</param> /// <remarks> /// After the value is read from the stream, <see cref="BaseAddress"/> is subtracted. /// /// Be sure to set <see cref="BaseAddress"/> to the proper value so you get /// a correct relative-virtual-address. Otherwise, set <see cref="BaseAddress"/> /// to zero to get the pure pointer value. /// </remarks> public void ReadPointerViaBaseAddress(out Values.PtrHandle ptrHandle) { ptrHandle = new Values.PtrHandle(BaseAddress.Size); ReadPointer(ref ptrHandle); }
public void Read(IO.EndianReader s) { var context = s.UserData as XmbFileContext; using (s.ReadSignatureWithByteSwapSupport(kSignature)) { if (context.PointerSize == Shell.ProcessorSize.x64) { // #HACK to deal with xmb files which weren't updated with new tools if (s.ByteOrder == Shell.EndianFormat.Big) { context.PointerSize = Shell.ProcessorSize.x32; } } s.VirtualAddressTranslationInitialize(context.PointerSize); Values.PtrHandle elements_offset_pos; if (context.PointerSize == Shell.ProcessorSize.x64) { s.Pad32(); } #region Initialize elements { int count = s.ReadInt32(); if (context.PointerSize == Shell.ProcessorSize.x64) { s.Pad32(); } s.ReadVirtualAddress(out elements_offset_pos); mElements = new List <Element>(count); } #endregion #region Initialize and read pool { int size = s.ReadInt32(); if (context.PointerSize == Shell.ProcessorSize.x64) { s.Pad32(); } Values.PtrHandle pool_offset_pos = s.ReadVirtualAddress(); s.Seek((long)pool_offset_pos); byte[] buffer = s.ReadBytes(size); mPool = new XmbVariantMemoryPool(buffer, s.ByteOrder); } #endregion if (context.PointerSize == Shell.ProcessorSize.x64) { s.Pad64(); } s.Seek((long)elements_offset_pos); for (int x = 0; x < mElements.Capacity; x++) { var e = new Element(); mElements.Add(e); e.Index = x; e.Read(this, context, s); } foreach (var e in mElements) { e.ReadAttributes(this, s); e.ReadChildren(s); } } }