예제 #1
0
파일: clsProfile.cs 프로젝트: Yommy/DiffGen
        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);
        }
예제 #2
0
파일: clsProfile.cs 프로젝트: Yommy/DiffGen
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
파일: clsDiff.cs 프로젝트: Yommy/DiffGen
        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_);
        }
예제 #5
0
파일: clsDiff.cs 프로젝트: Yommy/DiffGen
        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);
        }
예제 #6
0
파일: clsDiff.cs 프로젝트: Yommy/DiffGen
        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);
        }
예제 #7
0
파일: clsProfile.cs 프로젝트: Yommy/DiffGen
        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);
                }
            }
        }