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; } } }
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; } } }); }
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); } } } }
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); }
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; } } }