Beispiel #1
0
        private bool GetTypeMethods(string ns, string name, out int start, out int end)
        {
            start = end = -1;
            bool ret = false;
            MethodDefIterator methodIt = m_ClrFile.Metadata.Tables[(int)CorTokenType.mdtMethodDef] as MethodDefIterator;
            TypeDefIterator   it       = m_ClrFile.Metadata.Tables[(int)CorTokenType.mdtTypeDef] as TypeDefIterator;

            it.MoveToFirst();
            for (; !it.IsEnd; it.MoveToNext())
            {
                string nsName   = GetString(m_ClrFile.Buffer, m_StringStart, it.NameSpace);
                string typeName = GetString(m_ClrFile.Buffer, m_StringStart, it.Name);
                if (0 == typeName.CompareTo(name) && (string.IsNullOrEmpty(ns) || 0 == nsName.CompareTo(ns)))
                {
                    start = (int)it.MethodList;
                    if (it.MoveToNext())
                    {
                        end = (int)it.MethodList;
                    }
                    else
                    {
                        end = (int)methodIt.RecordNumber;
                    }
                    ret = true;
                    break;
                }
            }
            return(ret);
        }
Beispiel #2
0
        public void ModifyWithCallMethod(string fullName, string methodName, uint pos, byte op, string fullCn, string mn)
        {
            string classNs   = string.Empty;
            string className = fullName;
            int    srcIx     = fullName.LastIndexOf('.');

            if (srcIx > 0)
            {
                classNs   = fullName.Substring(0, srcIx);
                className = fullName.Substring(srcIx + 1);
            }
            string ns       = string.Empty;
            string cn       = fullCn;
            int    targetIx = fullCn.LastIndexOf('.');

            if (targetIx > 0)
            {
                ns = fullCn.Substring(0, targetIx);
                cn = fullCn.Substring(targetIx + 1);
            }

            Modify(classNs, className, methodName, (uint offset) => {
                int srcStart, srcEnd;
                bool srcValid = GetTypeMethods(ns, cn, out srcStart, out srcEnd);
                if (!srcValid)
                {
                    s_ErrorTxts.Add(string.Format("Can't find src {0}->{1}", cn, srcValid));
                    return;
                }
                MethodDefIterator it = m_ClrFile.Metadata.Tables[(int)CorTokenType.mdtMethodDef] as MethodDefIterator;
                for (uint ix = (uint)srcStart; ix < (uint)srcEnd; ++ix)
                {
                    it.MoveTo(ix - 1);
                    string name = GetString(m_ClrFile.Buffer, m_StringStart, it.Name);
                    if (name == mn)
                    {
                        m_ClrFile.Buffer[offset + pos]     = op;
                        m_ClrFile.Buffer[offset + pos + 1] = (byte)(ix & 0xff);
                        m_ClrFile.Buffer[offset + pos + 2] = (byte)((ix >> 8) & 0xff);
                        m_ClrFile.Buffer[offset + pos + 3] = (byte)((ix >> 16) & 0xff);
                        m_ClrFile.Buffer[offset + pos + 4] = (byte)0x06;
                        break;
                    }
                }
            });
        }
Beispiel #3
0
        public void Replace(string src, string target)
        {
            string srcNs   = string.Empty;
            string srcName = src;
            int    srcIx   = src.LastIndexOf('.');

            if (srcIx > 0)
            {
                srcNs   = src.Substring(0, srcIx);
                srcName = src.Substring(srcIx + 1);
            }
            string targetNs   = string.Empty;
            string targetName = target;
            int    targetIx   = target.LastIndexOf('.');

            if (targetIx > 0)
            {
                targetNs   = target.Substring(0, targetIx);
                targetName = target.Substring(targetIx + 1);
            }

            int  srcStart, srcEnd;
            int  targetStart, targetEnd;
            bool srcValid    = GetTypeMethods(srcNs, srcName, out srcStart, out srcEnd);
            bool targetValid = GetTypeMethods(targetNs, targetName, out targetStart, out targetEnd);

            if (!srcValid || !targetValid)
            {
                s_ErrorTxts.Add(string.Format("Can't find src {0}->{1} or target {2}->{3}", srcName, srcValid, targetName, targetValid));
                return;
            }
            MethodDefIterator it = m_ClrFile.Metadata.Tables[(int)CorTokenType.mdtMethodDef] as MethodDefIterator;

            for (uint ix = (uint)srcStart; ix < (uint)srcEnd; ++ix)
            {
                it.MoveTo(ix - 1);
                if (MoveToMatchedMethod(it, targetStart, targetEnd))
                {
                    uint rva = it.RVA;
                    it.MoveTo(ix - 1);
                    it.RVA = rva;
                }
            }
        }
Beispiel #4
0
        private void Modify(string nsName, string className, string methodName, Action <uint> callback)
        {
            int  srcStart, srcEnd;
            bool srcValid = GetTypeMethods(nsName, className, out srcStart, out srcEnd);

            if (!srcValid)
            {
                s_ErrorTxts.Add(string.Format("Can't find src {0}->{1}", className, srcValid));
                return;
            }
            MethodDefIterator it = m_ClrFile.Metadata.Tables[(int)CorTokenType.mdtMethodDef] as MethodDefIterator;

            for (uint ix = (uint)srcStart; ix < (uint)srcEnd; ++ix)
            {
                it.MoveTo(ix - 1);
                string name = GetString(m_ClrFile.Buffer, m_StringStart, it.Name);
                if (name == methodName)
                {
                    uint offset   = m_ClrFile.GetFileOffset(it.RVA);
                    byte ilheader = m_ClrFile.Buffer[offset];
                    if ((ilheader & 0x03) == 0x02)
                    {
                        uint size       = (uint)(ilheader >> 2);
                        uint headerSize = 1;

                        callback(offset + headerSize);
                    }
                    else if ((ilheader & 0x03) == 0x03)
                    {
                        uint one   = MetadataTables.ReadUInt(m_ClrFile.Buffer, offset);
                        uint two   = MetadataTables.ReadUInt(m_ClrFile.Buffer, offset + 4);
                        uint three = MetadataTables.ReadUInt(m_ClrFile.Buffer, offset + 8);

                        uint headerSize = ((one & 0x0000f000) >> 12) * 4;

                        callback(offset + headerSize);
                    }
                }
            }
        }
Beispiel #5
0
        private bool MoveToMatchedMethod(MethodDefIterator it, int start, int end)
        {
            bool   ret       = false;
            string name      = GetString(m_ClrFile.Buffer, m_StringStart, it.Name);
            string signature = GetBlobString(m_ClrFile.Buffer, m_BlobStart, it.Signature);

            if (name == ".ctor" || name == ".cctor")
            {
                return(false);
            }
            for (uint ix = (uint)start; ix < (uint)end; ++ix)
            {
                it.MoveTo(ix - 1);
                string name2      = GetString(m_ClrFile.Buffer, m_StringStart, it.Name);
                string signature2 = GetBlobString(m_ClrFile.Buffer, m_BlobStart, it.Signature);
                if (0 == name.CompareTo(name2) && 0 == signature.CompareTo(signature2))
                {
                    ret = true;
                    break;
                }
            }
            return(ret);
        }
Beispiel #6
0
        public void Extend(string fullName, string methodName, uint insertSize)
        {
            string classNs   = string.Empty;
            string className = fullName;
            int    srcIx     = fullName.LastIndexOf('.');

            if (srcIx > 0)
            {
                classNs   = fullName.Substring(0, srcIx);
                className = fullName.Substring(srcIx + 1);
            }

            int  srcStart, srcEnd;
            bool srcValid = GetTypeMethods(classNs, className, out srcStart, out srcEnd);

            if (!srcValid)
            {
                s_ErrorTxts.Add(string.Format("Can't find src {0}->{1}", className, srcValid));
                return;
            }
            MethodDefIterator it = m_ClrFile.Metadata.Tables[(int)CorTokenType.mdtMethodDef] as MethodDefIterator;

            for (uint ix = (uint)srcStart; ix < (uint)srcEnd; ++ix)
            {
                it.MoveTo(ix - 1);
                string name = GetString(m_ClrFile.Buffer, m_StringStart, it.Name);
                if (name == methodName)
                {
                    uint offset   = m_ClrFile.GetFileOffset(it.RVA);
                    byte ilheader = m_ClrFile.Buffer[offset];
                    if ((ilheader & 0x03) == 0x02)
                    {
                        uint size = (uint)(ilheader >> 2);
                        if (size + insertSize < 64)
                        {
                            m_Methods[m_Pos] = (byte)(((size + insertSize) << 2) | 0x02);
                            Array.Copy(m_ClrFile.Buffer, offset + 1, m_Methods, m_Pos + 1 + insertSize, size);
                            it.RVA = m_Header.VirtualAddress + m_Pos;
                        }
                        else
                        {
                            MetadataTables.WriteUInt(m_Methods, m_Pos, 0x7fff3003);
                            MetadataTables.WriteUInt(m_Methods, m_Pos + 4, size + insertSize);
                            MetadataTables.WriteUInt(m_Methods, m_Pos + 8, 0);
                            Array.Copy(m_ClrFile.Buffer, offset + 1, m_Methods, m_Pos + 12 + insertSize, size);
                            it.RVA = m_Header.VirtualAddress + m_Pos;
                        }
                    }
                    else if ((ilheader & 0x03) == 0x03)
                    {
                        uint one   = MetadataTables.ReadUInt(m_ClrFile.Buffer, offset);
                        uint two   = MetadataTables.ReadUInt(m_ClrFile.Buffer, offset + 4);
                        uint three = MetadataTables.ReadUInt(m_ClrFile.Buffer, offset + 8);
                        MetadataTables.WriteUInt(m_Methods, m_Pos, one);
                        MetadataTables.WriteUInt(m_Methods, m_Pos + 4, two + insertSize);
                        MetadataTables.WriteUInt(m_Methods, m_Pos + 8, three);
                        Array.Copy(m_ClrFile.Buffer, offset + 12, m_Methods, m_Pos + 12 + insertSize, two);
                        it.RVA = m_Header.VirtualAddress + m_Pos;
                    }
                    m_Find = true;
                    break;
                }
            }
        }