public static void Patch() { Type type = TypeByName("ZombieLand.ZombieStateHandler"); if (type != null) { foreach (MethodInfo method in type.GetMethods()) { if (method.IsDeclaredMember()) { try { IEnumerable <KeyValuePair <OpCode, object> > f = PatchProcessor.ReadMethodBody(method); foreach (KeyValuePair <OpCode, object> e in f) { if (e.Value is FieldInfo fieldInfo && RimThreadedHarmony.replaceFields.ContainsKey(fieldInfo)) { RimThreadedHarmony.TranspileFieldReplacements(method); break; } if (e.Value is MethodInfo methodInfo && RimThreadedHarmony.replaceFields.ContainsKey(methodInfo)) { RimThreadedHarmony.TranspileFieldReplacements(method); break; } } } catch (NotSupportedException) { } } } } }
public static IEnumerable <KeyValuePair <OpCode, object> > GetILInstructions(DynamicMethod method) { return(PatchProcessor.ReadMethodBody(method, method.GetILGenerator())); }
public static IEnumerable <KeyValuePair <OpCode, object> > GetILInstructions(MethodInfo method) { DynamicMethod dynMethod = new DynamicMethod(method.Name, method.ReturnType, method.GetParameters().Select(p => p.ParameterType).ToArray(), false); return(PatchProcessor.ReadMethodBody(method, dynMethod.GetILGenerator())); }
public static byte[] MakeCilSignatureSha256(this MethodBase mb) { #if DEBUG_METHOD_SIGNATURE using var hashSource = new MemoryStream(65536); var hashSourceStrs = new LinkedList <string>(); #endif var il = PatchProcessor.ReadMethodBody(mb); var buf = new byte[32]; using var hasher = SHA256.Create(); hasher.Initialize(); unsafe void ProcessUnsigned(ulong v, int size) { fixed(byte *pBuf = buf) * (ulong *)pBuf = v; hasher.TransformBlock(buf, 0, size, null, 0); #if DEBUG_METHOD_SIGNATURE hashSource.Write(buf, 0, size); #endif } void ProcessSigned(long v, int size) => ProcessUnsigned((ulong)v, size); void ProcessString(string s) { using var sigHasher = SHA256.Create(); var sig = sigHasher.ComputeHash(Encoding.Unicode.GetBytes(s)); hasher.TransformBlock(sig, 0, 32, null, 0); #if DEBUG_METHOD_SIGNATURE hashSourceStrs.AddLast(s); hashSource.Write(sig, 0, 32); #endif } unsafe void ProcessSingle(float v) { fixed(byte *pBuf = buf) * (float *)pBuf = v; hasher.TransformBlock(buf, 0, 4, null, 0); #if DEBUG_METHOD_SIGNATURE hashSource.Write(buf, 0, 4); #endif } unsafe void ProcessDouble(double v) { fixed(byte *pBuf = buf) * (double *)pBuf = v; hasher.TransformBlock(buf, 0, 8, null, 0); #if DEBUG_METHOD_SIGNATURE hashSource.Write(buf, 0, 8); #endif } void ProcessInstrRef(object r) { ProcessSigned((int)IlInstrOffsetField.GetValue(r), 4); #if DEBUG_METHOD_SIGNATURE hashSource.Write(buf, 0, 4); #endif } ProcessString(mb.FullDescription()); foreach (var instr in il) { var opCode = instr.Key; var opCodeValue = instr.Key.Value; var operand = instr.Value; for (var i = 0; i < opCode.Size; ++i) { buf[i] = (byte)(opCodeValue >> (i * 8)); } hasher.TransformBlock(buf, 0, opCode.Size, null, 0); #if DEBUG_METHOD_SIGNATURE hashSource.Write(buf, 0, opCode.Size); #endif switch (operand) { // @formatter:off case null: break; case byte v: ProcessUnsigned(v, 1); break; case ushort v: ProcessUnsigned(v, 2); break; case char v: ProcessUnsigned(v, 2); break; case uint v: ProcessUnsigned(v, 4); break; case ulong v: ProcessUnsigned(v, 8); break; case sbyte v: ProcessSigned(v, 1); break; case short v: ProcessSigned(v, 2); break; case int v: ProcessSigned(v, 4); break; case long v: ProcessSigned(v, 8); break; case float v: ProcessSingle(v); break; case double v: ProcessDouble(v); break; case string s: ProcessString(s); break; case MethodBase omb: ProcessString(omb.FullDescription()); break; case LocalVariableInfo lvi: ProcessSigned(lvi.LocalIndex, 4); break; case FieldInfo fi: ProcessString($"{fi.DeclaringType.FullDescription()}:{fi.Name}"); break; case Type t: ProcessString(t.FullDescription()); break; // @formatter:on case ParameterInfo p: { if (p.Member is MethodBase pmb && pmb == mb) { ProcessSigned(mb.GetParameters().IndexOf(p), 4); }