public void Generate(PatchList list) { System.Windows.Forms.TreeNode node = list.Nodes[0]; do { if (node.Tag == null || !node.Checked) { continue; } if (node.Tag is DiffPatchGroup && node.Nodes.Count > 0) { foreach (System.Windows.Forms.TreeNode n in node.Nodes) { if (n.Checked && n.Tag is DiffPatch) { parsePatch((DiffPatch)n.Tag, true); } } } if (node.Tag is DiffPatch) { DiffPatch p = (DiffPatch)node.Tag; parsePatch(p, true); } } while((node = node.NextNode) != null); }
private void parsePatch(DiffPatch p, bool ignoreApply = false) { if (!ignoreApply && !p.Apply) { return; } DiffProfileEntry entry = new DiffProfileEntry(); entry.PatchID = p.ID; entry.PatchName = p.Name; foreach (DiffInput i in p.Inputs) { entry.Inputs.Add(new DiffProfileInput() { name = i.Name, value = ((i.Value == null) ? "" : i.Value) }); } Entries.Add(entry); }
private bool CanMoveToRight(int pid) { DiffPatch p = (DiffPatch)file.xPatches[pid]; if (p.GroupID <= 0) { return(true); } foreach (int idx in rightPatches) { if (idx != int.MaxValue && file.xPatches.ContainsKey(idx)) { DiffPatch p2 = (DiffPatch)file.xPatches[idx]; if (p2.GroupID == p.GroupID) { return(false); } } } return(true); }
public object GetNewValue(DiffPatch p) { object val = null; if (this.New_ is string && ((string)this.New_).StartsWith("$")) { string str = ((string)this.New_); str = str.TrimStart('$'); foreach (DiffInput i in p.Inputs) { if (i.Name == str) { if (Type == ChangeType.Byte) { val = byte.Parse(i.Value); } else if (Type == ChangeType.Dword) { if (i.Type == ChangeType.Color && i.Value.Length >= 6) { val = UInt32.Parse(String.Format("00{2:X}{1:X}{0:X}", i.Value.Substring(0, 2), i.Value.Substring(2, 2), i.Value.Substring(4, 2)), System.Globalization.NumberStyles.HexNumber); } else { val = UInt32.Parse(i.Value); } } else if (Type == ChangeType.Word) { val = UInt16.Parse(i.Value); } else if (Type == ChangeType.String) { val = i.Value; } else { return(null); } if (i.Operator != null && i.Operator.Length >= 2) { i.Operator = i.Operator.Trim(); char op = i.Operator[0]; if (op == '+') { string val2 = i.Operator.Substring(1).Trim(); if (Type == ChangeType.Byte) { return((byte)(((byte)val) + byte.Parse(val2))); } if (Type == ChangeType.Word) { return((ushort)(((ushort)val) + ushort.Parse(val2))); } if (Type == ChangeType.Dword) { return((uint)(((uint)val) + uint.Parse(val2))); } } else if (op == '-') { string val2 = i.Operator.Substring(1).Trim(); if (Type == ChangeType.Byte) { return((byte)(((byte)val) - byte.Parse(val2))); } if (Type == ChangeType.Word) { return((ushort)(((ushort)val) - ushort.Parse(val2))); } if (Type == ChangeType.Dword) { return((uint)(((uint)val) - uint.Parse(val2))); } } } else { return(val); } } } throw new Exception("Could not resolve input value '" + this.New_ + "'!"); } return(this.New_); }
private int ApplyPatch(DiffPatch patch, ref byte[] buf) { int changed = 0; if (!patch.Apply) { return(-1); } foreach (DiffInput i in patch.Inputs) { if (!DiffInput.CheckInput(i.Value, i)) { return(-2); } } foreach (DiffChange c in patch.Changes) { switch (c.Type) { case ChangeType.Byte: { byte old = buf[c.Offset]; if (old == (byte)c.Old) { buf[c.Offset] = (byte)c.GetNewValue(patch); changed++; } else { MessageBox.Show(String.Format("Data mismatch at 0x{0:X} (0x{1:X} != 0x{2:X})!", c.Offset, old, (byte)c.Old)); } break; } case ChangeType.Word: { UInt16 old = BitConverter.ToUInt16(buf, (int)c.Offset); if (old == (UInt16)c.Old) { UInt16 val = (UInt16)c.GetNewValue(patch); buf[c.Offset] = (byte)val; buf[c.Offset + 1] = (byte)(val >> 8); changed += 2; } else { MessageBox.Show(String.Format("Data mismatch at 0x{0:X} (0x{1:X} != 0x{2:X})!", c.Offset, old, (ushort)c.Old)); } break; } case ChangeType.Dword: { UInt32 old = BitConverter.ToUInt32(buf, (int)c.Offset); if (old == (UInt32)c.Old) { WriteDword(ref buf, (UInt32)c.GetNewValue(patch), c.Offset); changed += 4; } else { MessageBox.Show(String.Format("Data mismatch at 0x{0:X} (0x{1:X} != 0x{2:X})!", c.Offset, old, (uint)c.Old)); } break; } case ChangeType.String: // used only for displayable string { //currently not checking for old string - if client crashes your screwed byte[] val = Encoding.ASCII.GetBytes((String)c.GetNewValue(patch) + "\x00"); int i = 0; foreach (byte b in val) { buf[c.Offset + i++] = b; } changed += i; break; } } } //MessageBox.Show("Applied patch '" + patch.Name + "' (" + changed + " bytes)"); return(changed); }
public int Load(string fileName, DiffType type) { if (!File.Exists(fileName)) { return(1); } m_fileInfo = new FileInfo(fileName); if (m_patches != null) { m_patches.Clear(); } if (m_xpatches != null) { m_xpatches.Clear(); } m_type = type; if (type == DiffType.xDiff) { XmlDocument XDoc = null; /*try * {*/ XDoc = new XmlDocument(); XDoc.Load(fileName); this.ExeBuildDate = XDoc.SelectSingleNode("//diff/exe/builddate").InnerText; this.ExeName = XDoc.SelectSingleNode("//diff/exe/filename").InnerText; this.ExeCRC = int.Parse(XDoc.SelectSingleNode("//diff/exe/crc").InnerText); string xtype = XDoc.SelectSingleNode("//diff/exe/type").InnerText; this.ExeType = 0; this.Name = XDoc.SelectSingleNode("//diff/info/name").InnerText; this.Author = XDoc.SelectSingleNode("//diff/info/author").InnerText; this.Version = XDoc.SelectSingleNode("//diff/info/version").InnerText; this.ReleaseDate = XDoc.SelectSingleNode("//diff/info/releasedate").InnerText; //extra addition for adding .xdiff section m_xDiffSection.peHeader = Convert.ToUInt32(XDoc.SelectSingleNode("//diff/override/peheader").InnerText, 10); m_xDiffSection.imgSize = Convert.ToUInt32(XDoc.SelectSingleNode("//diff/override/imagesize").InnerText, 10); m_xDiffSection.sectCount = Convert.ToUInt16(XDoc.SelectSingleNode("//diff/override/sectioncount").InnerText, 10); m_xDiffSection.xDiffStart = Convert.ToUInt32(XDoc.SelectSingleNode("//diff/override/xdiffstart").InnerText, 10); UInt32 vSize = Convert.ToUInt32(XDoc.SelectSingleNode("//diff/override/vsize").InnerText, 10); UInt32 vOffset = Convert.ToUInt32(XDoc.SelectSingleNode("//diff/override/voffset").InnerText, 10); UInt32 rSize = Convert.ToUInt32(XDoc.SelectSingleNode("//diff/override/rsize").InnerText, 10); UInt32 rOffset = Convert.ToUInt32(XDoc.SelectSingleNode("//diff/override/roffset").InnerText, 10); m_xDiffSection.realSize = rSize + rOffset; //now create section data m_xDiffSection.sectionData = new byte[40]; UInt32 i = 0; // first section name foreach (byte b in Encoding.ASCII.GetBytes(".xdiff\x00\x00")) { m_xDiffSection.sectionData[i] = b; i++; } //next the offset and sizes WriteDword(ref m_xDiffSection.sectionData, vSize, 8); WriteDword(ref m_xDiffSection.sectionData, vOffset, 12); WriteDword(ref m_xDiffSection.sectionData, rSize, 16); WriteDword(ref m_xDiffSection.sectionData, rOffset, 20); //next the relocation and line numbers info - fill with 0 WriteDword(ref m_xDiffSection.sectionData, 0, 24); WriteDword(ref m_xDiffSection.sectionData, 0, 28); WriteDword(ref m_xDiffSection.sectionData, 0, 32); //Lastly Characteristics WriteDword(ref m_xDiffSection.sectionData, 0xE0000060, 36); XmlNode patches = XDoc.SelectSingleNode("//diff/patches"); foreach (XmlNode patch in patches.ChildNodes) { if (patch.Name == "patchgroup") { //XmlNode tmpNode = null; DiffPatchGroup g = new DiffPatchGroup(); g.ID = int.Parse(patch.Attributes["id"].InnerText); g.Name = patch.Attributes["name"].InnerText; foreach (XmlNode node in patch.ChildNodes) { if (node.Name == "patch") { DiffPatch p = new DiffPatch(); p.LoadFromXML(node); this.xPatches.Add(p.ID, p); g.Patches.Add(p); } } this.xPatches.Add(g.ID, g); } else if (patch.Name == "patch") { DiffPatch p = new DiffPatch(); p.LoadFromXML(patch); this.xPatches.Add(p.ID, p); } } /*} * catch (Exception ex) * { * MessageBox.Show("Failed to parse xDiff file: \n"+ex.ToString()); * return 2; * }*/ } else if (type == DiffType.Diff) { bool hex = false; using (StreamReader r = new StreamReader(fileName)) { string line; while (!r.EndOfStream && (line = r.ReadLine()) != null) { line = line.Trim(); if (line.Length < 5) { continue; } if (line.StartsWith("OCRC:")) { this.ExeCRC = int.Parse(line.Substring(5)); } else if (line.StartsWith("BLURB:")) { this.Name = line.Substring(6); } else if (line.StartsWith("READHEX")) { hex = true; } else if (line.StartsWith("byte_")) { string pType, pName; string pGroup; DiffChange change = new DiffChange(); DiffPatch patch = new DiffPatch(); string[] split = line.Split(':'); Regex regex = new Regex("(.+)_\\[(.+)\\]_(.+)"); Match match = regex.Match(split[0]); pName = ""; pType = ""; if (match.Success) { change.Type = ChangeType.Byte; pType = match.Groups[1].Captures[0].Value; pName = split[0].Substring(5); //match.Captures[2].Value.Replace('_', ' '); } else { regex = new Regex("(.+)_\\[(.+)\\]\\((.+)\\)_(.+)"); match = regex.Match(split[0]); if (match.Success) { change.Type = ChangeType.Byte; pType = match.Groups[1].Captures[0].Value; pGroup = match.Groups[3].Captures[0].Value; pName = split[0].Substring(5); //match.Groups[3].Captures[0].Value.Replace('_', ' '); } else { continue; } } change.Offset = uint.Parse(split[1], System.Globalization.NumberStyles.HexNumber); change.Old = (byte)((!hex) ? byte.Parse(split[2]) : byte.Parse(split[2], System.Globalization.NumberStyles.HexNumber)); change.New_ = (byte)((!hex) ? byte.Parse(split[3]) : byte.Parse(split[3], System.Globalization.NumberStyles.HexNumber)); if (m_patches.ContainsKey(pName)) { m_patches[pName].Changes.Add(change); } else { patch.Changes.Add(change); patch.Name = pName; patch.Type = pType; m_patches.Add(pName, patch); } } } } } else { return(2); } return(0); }
public void Apply(ref PatchList lstPatches, ref DiffFile file) { // Clear patches and inputs foreach (DiffPatchBase b in file.xPatches.Values) { if (b is DiffPatchGroup) { foreach (DiffPatch p in ((DiffPatchGroup)b).Patches) { p.Apply = false; foreach (DiffInput i in p.Inputs) { i.Value = null; } } } else if (b is DiffPatch) { ((DiffPatch)b).Apply = false; foreach (DiffInput i in ((DiffPatch)b).Inputs) { i.Value = null; } } } foreach (DiffProfileEntry entry in this.Entries) { DiffPatch patch = (DiffPatch)file.xPatches[entry.PatchID]; ((DiffPatch)file.xPatches[entry.PatchID]).Apply = true; foreach (DiffProfileInput j in entry.Inputs) { foreach (DiffInput k in patch.Inputs) { if (k.Name == j.name) { k.Value = j.value; } } } } // Lets just rebuild the whole thing =D lstPatches.Nodes.Clear(); foreach (KeyValuePair <int, DiffPatchBase> p in file.xPatches) { if (p.Value is DiffPatchGroup) { TreeNodeEx node = new TreeNodeEx(p.Value.Name); node.Tag = file.xPatches[p.Value.ID]; //is this a reference or a copy? :x node.ActAsRadioGroup = true; foreach (DiffPatch p2 in ((DiffPatchGroup)p.Value).Patches) { TreeNodeEx n = new TreeNodeEx(p2.Name); n.Tag = file.xPatches[p2.ID]; if (((DiffPatch)n.Tag).Apply) { n.Checked = true; node.Checked = true; } node.Nodes.Add(n); } lstPatches.Nodes.Add(node); } else if (p.Value is DiffPatch && ((DiffPatch)p.Value).GroupID <= 0) { TreeNodeEx node = new TreeNodeEx(p.Value.Name); node.Tag = file.xPatches[p.Value.ID]; if (((DiffPatch)node.Tag).Apply) { node.Checked = true; } lstPatches.Nodes.Add(node); } } }