private void SaveAtom(InputFile inFile, OutputFile outFile, LeafAtom leaf) { if (leaf.HeaderLength == 8) { outFile.WriteUInt32((UInt32)leaf.TotalLength); outFile.WriteChars(leaf.Type.ToCharArray()); } else { outFile.WriteUInt32(1); outFile.WriteChars(leaf.Type.ToCharArray()); outFile.WriteUInt64(leaf.TotalLength); } if (leaf.PayloadData != null) { outFile.WriteBytes(leaf.PayloadData); } else { if (leaf.OriginalPayloadFileOffset > 0) { outFile.WriteFromInput(inFile, leaf.OriginalPayloadFileOffset, leaf.PayloadLength); } else { outFile.WriteFromInput(inFile, leaf.PayloadFileOffset, leaf.PayloadLength); } } }
public ArrayList ParseFile(InputFile file) { ArrayList atoms = new ArrayList(); UInt64 position = 0; while (position < file.Length) { string type = GetAtomType(file, position); Atom atom = null; if (IsContainer(type)) { atom = new ContainerAtom(type); ParseContainer(file, position, (ContainerAtom)atom); } else if (IsAtom(type)) { atom = new LeafAtom(type); ParseAtom(file, position, atom); } else { throw new Exception("Invalid atom at pos 0x" + position.ToString("X16")); } atoms.Add(atom); position += atom.TotalLength; } return(atoms); }
private void ParseContainer(InputFile file, ulong position, ContainerAtom container) { ParseAtom(file, position, container); ArrayList atoms = new ArrayList(); UInt64 offset = container.HeaderLength; while (offset < container.TotalLength) { string type = GetAtomType(file, position + offset); Atom atom = null; if (IsContainer(type)) { atom = new ContainerAtom(type); ParseContainer(file, position + offset, (ContainerAtom)atom); } else { atom = new LeafAtom(type); ParseAtom(file, position + offset, atom); } container.Children.Add(atom); offset += atom.TotalLength; } }
private void BuildTree(TreeNode root, ArrayList atoms) { foreach (var obj in atoms) { if (obj is ContainerAtom) { ContainerAtom container = (ContainerAtom)obj; TreeNode node = new TreeNode(container + " C:" + container.Children.Count); BuildTree(node, ((ContainerAtom)obj).Children); root.Nodes.Add(node); } else { LeafAtom leaf = (LeafAtom)obj; TreeNode node = new TreeNode(leaf + ""); root.Nodes.Add(node); } } }
private UInt64 CalculateSizes(ArrayList atoms, UInt64 outFileOffset, bool absolute) { UInt64 totalSize = 0; string tabs = ""; for (int pos = 0; pos < TreeDepth; pos++) { tabs += " "; } foreach (var obj in atoms) { if (obj is ContainerAtom) { ContainerAtom container = (ContainerAtom)obj; if (absolute) { Log(tabs + " [" + container.Type + "] size: 0x" + container.TotalLength.ToString("X8") + " bytes"); } /* run first with absolute file offset set to zero, as it is not clear yet if we have 8 or 16 byte header */ UInt64 containerSize = CalculateSizes(container.Children, 0, false); if ((containerSize + 8) > 0xFFFFFFFF) { container.HeaderLength = 16; } else { container.HeaderLength = 8; } container.TotalLength = container.HeaderLength + containerSize; container.HeaderFileOffset = outFileOffset + totalSize; /* run again with the real absolute file offset */ if (absolute) { TreeDepth++; CalculateSizes(container.Children, container.PayloadFileOffset, true); TreeDepth--; } /* now we are done with that container */ totalSize += container.TotalLength; } else { LeafAtom leaf = (LeafAtom)obj; UInt64 contentSize = leaf.PayloadLength; /* replace content with our patched? */ if (leaf.PayloadData != null) { contentSize = (UInt64)leaf.PayloadData.Length; if (absolute) { Log(tabs + " [" + leaf.Type + "] Replacing data (0x" + leaf.OriginalPayloadLength.ToString("X8") + " bytes) with 0x" + contentSize.ToString("X8") + " bytes"); } } if ((contentSize + 8) > 0xFFFFFFFF) { leaf.HeaderLength = 16; } else { leaf.HeaderLength = 8; } leaf.TotalLength = leaf.HeaderLength + contentSize; leaf.HeaderFileOffset = outFileOffset + totalSize; totalSize += leaf.TotalLength; if (absolute) { Log(tabs + " [" + leaf.Type + "] size: 0x" + leaf.TotalLength.ToString("X8") + " pos: 0x" + leaf.HeaderFileOffset.ToString("X8")); } } } return(totalSize); }