public static bool IsStLoc(this CodeInstruction code, Type type, MethodBase method) { if (!code.IsStloc()) { return(false); } if (code.opcode == OpCodes.Stloc_0) { return(method.GetMethodBody().LocalVariables[0].LocalType == type); } else if (code.opcode == OpCodes.Stloc_1) { return(method.GetMethodBody().LocalVariables[1].LocalType == type); } else if (code.opcode == OpCodes.Stloc_2) { return(method.GetMethodBody().LocalVariables[2].LocalType == type); } else if (code.opcode == OpCodes.Stloc_3) { return(method.GetMethodBody().LocalVariables[3].LocalType == type); } else { return(code.operand is LocalBuilder lb && lb.LocalType == type); } }
public static bool IsStloc(this CodeInstruction instruction, LocalVar local) { if (!instruction.IsStloc(local.builder)) { return(false); } if (local.builder != null) { return(true); } return(LocalVar.OpCodeToInt[instruction.opcode] == local.index); }
public LocalVar(MethodInfo m, CodeInstruction instruction) { method = m; if (!instruction.IsLdloc() && !instruction.IsStloc()) { throw new Exception("Code instruction is not a Ldloc or Stloc"); } var t = instruction.ToLocalVar(); index = t.index; builder = t.builder; }
public static LocalVar ToLocalVar(this CodeInstruction instruction, MethodInfo method = null) { if (!instruction.IsLdloc() && !instruction.IsStloc()) { return(null); } if (instruction.operand is LocalBuilder builder) { return(new LocalVar(builder)); } return(new LocalVar(LocalVar.OpCodeToInt[instruction.opcode]) { method = method }); }
public virtual bool SearchMethod(MethodInfo searchMethod, out List <ItemPos <StatDef> > Results, out List <CodeInstruction> PawnIns) { Results = new List <ItemPos <StatDef> >(); PawnIns = new List <CodeInstruction>(); bool foundResult = false; bool foundPawn = false; List <CodeInstruction> instructionList; try { instructionList = PatchProcessor.GetCurrentInstructions(searchMethod); } catch { instructionList = PatchProcessor.GetOriginalInstructions(searchMethod); } List <int?> ParamList = searchMethod.GetParameters()?.Where(t => t.ParameterType.IsAssignableFrom(typeof(Pawn)))?.Select(t => new int?(t.Position))?.ToList() ?? new List <int?>(); List <LocalBuilder> LocalList = new List <LocalBuilder>(); if (!ParamList.NullOrEmpty()) { foundPawn = true; } for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.opcode == OpCodes.Ldfld && instruction.operand is FieldInfo pawnField && pawnField.FieldType.IsAssignableFrom(typeof(Pawn))) { foundPawn = true; for (int j = 1; j < i; j++) { if (instructionList[i - j].IsLdarg(0)) { PawnIns = new List <CodeInstruction>(instructionList.GetRange(i - j, j + 1)); break; } } } if (ParamList.Any(t => instruction.IsLdarg(t))) { PawnIns = new List <CodeInstruction>() { instruction } } ; if (instruction.IsStloc() && instruction.operand is LocalBuilder local && !LocalList.Contains(local) && local.LocalType.IsAssignableFrom(typeof(Pawn))) { LocalList.Add(local); } if (LocalList.Any(t => instruction.IsLdloc(t))) { PawnIns = new List <CodeInstruction>() { instruction } } ; // Ambiguous method call if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && instruction.operand is MethodInfo calledMethod) { if (calledMethod.ReturnType == typeof(StatDef)) { foundResult = true; Results.Add((ItemPos <StatDef>)(i, null)); } else if (calledMethod.ReturnType.IsAssignableFrom(typeof(Pawn))) { foundPawn = true; if (calledMethod.IsStatic) { PawnIns = new List <CodeInstruction>() { instruction } } ; else { for (int j = 1; j < i; j++) { if (instructionList[i - j].IsLdarg(0)) { PawnIns = new List <CodeInstruction>(instructionList.GetRange(i - j, j + 1)); break; } } } } } // StatDefOf call if (instruction.opcode == OpCodes.Ldsfld && instruction.operand is FieldInfo statField && statField.FieldType == typeof(StatDef) && StatDefOfFieldInfo.Contains(statField)) { Results.Add((ItemPos <StatDef>)(i, FieldToStat[statField])); foundResult = true; } if (!FindAll && foundResult && (!findPawn || foundPawn)) { return(foundResult); } } return(foundResult); } } }
public bool IsStloc(CodeInstruction instruction) { return(instruction.IsStloc()); }