bool DeobfuscateFields() { foreach (var info in fieldWrites.Values) { info.Clear(); } foreach (var method in allMethods) { if (method.Body == null) { continue; } var instructions = method.Body.Instructions; for (int i = 0; i < instructions.Count; i++) { var instr = instructions[i]; TypeSig fieldType = null; TypeInfo <FieldDef> info = null; IField field; switch (instr.OpCode.Code) { case Code.Stfld: case Code.Stsfld: field = instr.Operand as IField; if (field == null) { continue; } if (!fieldWrites.TryGetValue(field, out info)) { continue; } bool wasNewobj; fieldType = GetLoadedType(info.arg.DeclaringType, method, instructions, i, out wasNewobj); if (fieldType == null) { continue; } info.Add(fieldType, wasNewobj); break; case Code.Call: case Code.Calli: case Code.Callvirt: case Code.Newobj: var pushedArgs = MethodStack.GetPushedArgInstructions(instructions, i); var calledMethod = instr.Operand as IMethod; if (calledMethod == null) { continue; } var calledMethodDefOrRef = calledMethod as IMethodDefOrRef; var calledMethodSpec = calledMethod as MethodSpec; if (calledMethodSpec != null) { calledMethodDefOrRef = calledMethodSpec.Method; } if (calledMethodDefOrRef == null) { continue; } IList <TypeSig> calledMethodArgs = DotNetUtils.GetArgs(calledMethodDefOrRef); calledMethodArgs = DotNetUtils.ReplaceGenericParameters(calledMethodDefOrRef.DeclaringType.TryGetGenericInstSig(), calledMethodSpec, calledMethodArgs); for (int j = 0; j < pushedArgs.NumValidArgs; j++) { var pushInstr = pushedArgs.GetEnd(j); if (pushInstr.OpCode.Code != Code.Ldfld && pushInstr.OpCode.Code != Code.Ldsfld) { continue; } field = pushInstr.Operand as IField; if (field == null) { continue; } if (!fieldWrites.TryGetValue(field, out info)) { continue; } fieldType = calledMethodArgs[calledMethodArgs.Count - 1 - j]; if (!IsValidType(info.arg.DeclaringType, fieldType)) { continue; } info.Add(fieldType); } break; default: continue; } } } bool modified = false; var removeThese = new List <FieldDef>(); foreach (var info in fieldWrites.Values) { if (info.UpdateNewType(module)) { removeThese.Add(info.arg); GetUpdatedField(info.arg).newFieldType = info.newType; info.arg.FieldSig.Type = info.newType; modified = true; } } foreach (var field in removeThese) { fieldWrites.Remove(field); } return(modified); }