void deobfuscateNormal(Blocks blocks) { var instrsToRemove = new List <int>(); foreach (var block in blocks.MethodBlocks.getAllBlocks()) { instrsToRemove.Clear(); var instrs = block.Instructions; for (int i = instrs.Count - 1; i >= 0; i--) { var instr = instrs[i]; if (instr.OpCode.Code != Code.Ldflda && instr.OpCode.Code != Code.Ldfld) { continue; } var structField = instr.Operand as IField; if (structField == null || !structFieldsToFix.find(structField)) { continue; } var ldStFld = instrs[findLdStFieldIndex(instrs, i + 1)]; ldStFld.Operand = getNewField(structField, ldStFld.Operand as IField); instrsToRemove.Add(i); } if (instrsToRemove.Count > 0) { block.remove(instrsToRemove); } } }
bool initializeArrays2(ISimpleDeobfuscator simpleDeobfuscator, MethodDef method) { bool foundField = false; simpleDeobfuscator.deobfuscate(method, true); var instructions = method.Body.Instructions; for (int i = 0; i < instructions.Count; i++) { var ldci4 = instructions[i]; if (!ldci4.IsLdcI4()) { continue; } i++; var instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Newarr, OpCodes.Dup, OpCodes.Ldtoken, OpCodes.Call, OpCodes.Stsfld); if (instrs == null) { continue; } var arrayInitField = instrs[2].Operand as FieldDef; if (arrayInitField == null || arrayInitField.InitialValue == null || arrayInitField.InitialValue.Length == 0) { continue; } var calledMethod = instrs[3].Operand as IMethod; if (calledMethod == null || calledMethod.FullName != "System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)") { continue; } var targetField = instrs[4].Operand as FieldDef; if (targetField == null || targetField.FieldType.GetElementType() != ElementType.SZArray) { continue; } var etype = ((SZArraySig)targetField.FieldType).Next.GetElementType(); if (etype < ElementType.Boolean || etype > ElementType.U4) { continue; } if (fieldToInfo.find(targetField) == null) { fieldToInfo.add(targetField, new FieldInfo(targetField, arrayInitField)); foundField = true; } } return(foundField); }
static internal IEnumerable <FieldDef> getFields(TypeDef type) { var typeFields = new FieldDefAndDeclaringTypeDict <FieldDef>(); foreach (var field in type.Fields) { typeFields.add(field, field); } var realFields = new Dictionary <FieldDef, bool>(); foreach (var method in type.Methods) { if (method.Body == null) { continue; } foreach (var instr in method.Body.Instructions) { var fieldRef = instr.Operand as IField; if (fieldRef == null) { continue; } var field = typeFields.find(fieldRef); if (field == null) { continue; } realFields[field] = true; } } return(realFields.Keys); }
public void deobfuscate(Blocks blocks) { if (decrypter == null) { return; } foreach (var block in blocks.MethodBlocks.getAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; if (instr.OpCode.Code != Code.Ldsfld) { continue; } var field = instr.Operand as IField; if (field == null) { continue; } var info = stringInfos.find(field); if (info == null) { continue; } var decrypted = decrypt(info); instrs[i] = new Instr(OpCodes.Ldstr.ToInstruction(decrypted)); Logger.v("Decrypted string: {0}", Utils.toCsharpString(decrypted)); } } }
protected DelegateInfo getDelegateInfo(IField field) { if (field == null) { return(null); } return(fieldToDelegateInfo.find(field)); }
int findNextFieldUse(MethodDef method, int index) { var instrs = method.Body.Instructions; for (int i = index; i < instrs.Count; i++) { var instr = instrs[i]; if (instr.OpCode.Code != Code.Ldsfld && instr.OpCode.Code != Code.Stsfld) { continue; } var field = instr.Operand as IField; if (!fields.find(field)) { return(-1); } return(i); } return(-1); }
static short[] findKey(MethodDef initMethod, FieldDefAndDeclaringTypeDict <bool> fields) { var instrs = initMethod.Body.Instructions; for (int i = 0; i < instrs.Count - 2; i++) { var ldci4 = instrs[i]; if (!ldci4.IsLdcI4()) { continue; } var newarr = instrs[i + 1]; if (newarr.OpCode.Code != Code.Newarr) { continue; } if (newarr.Operand.ToString() != "System.Char") { continue; } var stloc = instrs[i + 2]; if (!stloc.IsStloc()) { continue; } var local = stloc.GetLocal(initMethod.Body.Variables); int startInitIndex = i; i++; var array = ArrayFinder.getInitializedInt16Array(ldci4.GetLdcI4Value(), initMethod, ref i); if (array == null) { continue; } var field = getStoreField(initMethod, startInitIndex, local); if (field == null) { continue; } if (fields.find(field)) { return(array); } } return(null); }
// Find the string decrypter string offset value or null if none found int?findOffsetValue(MethodDef method) { var fieldDict = new FieldDefAndDeclaringTypeDict <IField>(); foreach (var field in method.DeclaringType.Fields) { fieldDict.add(field, field); } var offsetField = findOffsetField(method); if (offsetField == null) { return(null); } return(findOffsetValue(method, (FieldDef)fieldDict.find(offsetField), fieldDict)); }
public void deobfuscate(Blocks blocks) { foreach (var block in blocks.MethodBlocks.getAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) { if (blocks.Method.DeclaringType == decrypterType) { continue; } var calledMethod = instr.Operand as IMethod; if (calledMethod != null && calledMethod.DeclaringType == decrypterType) { canRemoveType = false; } } else if (instr.OpCode.Code == Code.Ldsfld) { if (instr.OpCode.Code != Code.Ldsfld) { continue; } var field = instr.Operand as IField; if (field == null) { continue; } var decrypted = fieldToDecryptedString.find(field); if (decrypted == null) { continue; } instrs[i] = new Instr(OpCodes.Ldstr.ToInstruction(decrypted)); Logger.v("Decrypted string: {0}", Utils.toCsharpString(decrypted)); } } } }
int?findOffsetValue(MethodDef method, FieldDef offsetField, FieldDefAndDeclaringTypeDict <IField> fields) { var instructions = method.Body.Instructions; for (int i = 0; i <= instructions.Count - 2; i++) { var ldstr = instructions[i]; if (ldstr.OpCode.Code != Code.Ldstr) { continue; } var stringVal = ldstr.Operand as string; if (stringVal == null) { continue; } var stsfld = instructions[i + 1]; if (stsfld.OpCode.Code != Code.Stsfld) { continue; } var field = stsfld.Operand as IField; if (field == null || fields.find(field) != offsetField) { continue; } int value; if (!int.TryParse(stringVal, System.Globalization.NumberStyles.Integer, null, out value)) { continue; } return(value); } return(null); }
static short[] findKey(MethodDef initMethod, FieldDefAndDeclaringTypeDict<bool> fields) { var instrs = initMethod.Body.Instructions; for (int i = 0; i < instrs.Count - 2; i++) { var ldci4 = instrs[i]; if (!ldci4.IsLdcI4()) continue; var newarr = instrs[i + 1]; if (newarr.OpCode.Code != Code.Newarr) continue; if (newarr.Operand.ToString() != "System.Char") continue; var stloc = instrs[i + 2]; if (!stloc.IsStloc()) continue; var local = stloc.GetLocal(initMethod.Body.Variables); int startInitIndex = i; i++; var array = ArrayFinder.getInitializedInt16Array(ldci4.GetLdcI4Value(), initMethod, ref i); if (array == null) continue; var field = getStoreField(initMethod, startInitIndex, local); if (field == null) continue; if (fields.find(field)) return array; } return null; }
void initFieldEventHandlers(FieldDefAndDeclaringTypeDict<MFieldDef> ourFields, MethodDefAndDeclaringTypeDict<MMethodDef> ourMethods) { var checker = NameChecker; foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDef.Body == null) continue; if (methodDef.MethodDef.IsStatic) continue; var instructions = methodDef.MethodDef.Body.Instructions; for (int i = 0; i < instructions.Count - 6; i++) { // We're looking for this code pattern: // ldarg.0 // ldfld field // ldarg.0 // ldftn method / ldarg.0 + ldvirtftn // newobj event_handler_ctor // callvirt add_SomeEvent if (instructions[i].GetParameterIndex() != 0) continue; int index = i + 1; var ldfld = instructions[index++]; if (ldfld.OpCode.Code != Code.Ldfld) continue; var fieldRef = ldfld.Operand as IField; if (fieldRef == null) continue; var fieldDef = ourFields.find(fieldRef); if (fieldDef == null) continue; if (instructions[index++].GetParameterIndex() != 0) continue; IMethod methodRef; var instr = instructions[index + 1]; if (instr.OpCode.Code == Code.Ldvirtftn) { if (!isThisOrDup(instructions[index++])) continue; var ldvirtftn = instructions[index++]; methodRef = ldvirtftn.Operand as IMethod; } else { var ldftn = instructions[index++]; if (ldftn.OpCode.Code != Code.Ldftn) continue; methodRef = ldftn.Operand as IMethod; } if (methodRef == null) continue; var handlerMethod = ourMethods.find(methodRef); if (handlerMethod == null) continue; var newobj = instructions[index++]; if (newobj.OpCode.Code != Code.Newobj) continue; if (!isEventHandlerCtor(newobj.Operand as IMethod)) continue; var call = instructions[index++]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) continue; var addHandler = call.Operand as IMethod; if (addHandler == null) continue; if (!Utils.StartsWith(addHandler.Name.String, "add_", StringComparison.Ordinal)) continue; var eventName = addHandler.Name.String.Substring(4); if (!checker.isValidEventName(eventName)) continue; memberInfos.method(handlerMethod).suggestedName = string.Format("{0}_{1}", memberInfos.field(fieldDef).newName, eventName); } } }
void initializeWindowsFormsFieldsAndProps() { var checker = NameChecker; var ourFields = new FieldDefAndDeclaringTypeDict<MFieldDef>(); foreach (var fieldDef in type.AllFields) ourFields.add(fieldDef.FieldDef, fieldDef); var ourMethods = new MethodDefAndDeclaringTypeDict<MMethodDef>(); foreach (var methodDef in type.AllMethods) ourMethods.add(methodDef.MethodDef, methodDef); foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDef.Body == null) continue; if (methodDef.MethodDef.IsStatic || methodDef.MethodDef.IsVirtual) continue; var instructions = methodDef.MethodDef.Body.Instructions; for (int i = 2; i < instructions.Count; i++) { var call = instructions[i]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) continue; if (!isWindowsFormsSetNameMethod(call.Operand as IMethod)) continue; var ldstr = instructions[i - 1]; if (ldstr.OpCode.Code != Code.Ldstr) continue; var fieldName = ldstr.Operand as string; if (fieldName == null || !checker.isValidFieldName(fieldName)) continue; var instr = instructions[i - 2]; IField fieldRef = null; if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) { var calledMethod = instr.Operand as IMethod; if (calledMethod == null) continue; var calledMethodDef = ourMethods.find(calledMethod); if (calledMethodDef == null) continue; fieldRef = getFieldRef(calledMethodDef.MethodDef); var propDef = calledMethodDef.Property; if (propDef == null) continue; memberInfos.prop(propDef).suggestedName = fieldName; fieldName = "_" + fieldName; } else if (instr.OpCode.Code == Code.Ldfld) { fieldRef = instr.Operand as IField; } if (fieldRef == null) continue; var fieldDef = ourFields.find(fieldRef); if (fieldDef == null) continue; var fieldInfo = memberInfos.field(fieldDef); if (fieldInfo.renamed) continue; fieldInfo.suggestedName = variableNameState.getNewFieldName(fieldInfo.oldName, new NameCreator2(fieldName)); } } }
void initializeWindowsFormsFieldsAndProps() { var checker = NameChecker; var ourFields = new FieldDefAndDeclaringTypeDict <MFieldDef>(); foreach (var fieldDef in type.AllFields) { ourFields.add(fieldDef.FieldDef, fieldDef); } var ourMethods = new MethodDefAndDeclaringTypeDict <MMethodDef>(); foreach (var methodDef in type.AllMethods) { ourMethods.add(methodDef.MethodDef, methodDef); } foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDef.Body == null) { continue; } if (methodDef.MethodDef.IsStatic || methodDef.MethodDef.IsVirtual) { continue; } var instructions = methodDef.MethodDef.Body.Instructions; for (int i = 2; i < instructions.Count; i++) { var call = instructions[i]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) { continue; } if (!isWindowsFormsSetNameMethod(call.Operand as IMethod)) { continue; } var ldstr = instructions[i - 1]; if (ldstr.OpCode.Code != Code.Ldstr) { continue; } var fieldName = ldstr.Operand as string; if (fieldName == null || !checker.isValidFieldName(fieldName)) { continue; } var instr = instructions[i - 2]; IField fieldRef = null; if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) { var calledMethod = instr.Operand as IMethod; if (calledMethod == null) { continue; } var calledMethodDef = ourMethods.find(calledMethod); if (calledMethodDef == null) { continue; } fieldRef = getFieldRef(calledMethodDef.MethodDef); var propDef = calledMethodDef.Property; if (propDef == null) { continue; } memberInfos.prop(propDef).suggestedName = fieldName; fieldName = "_" + fieldName; } else if (instr.OpCode.Code == Code.Ldfld) { fieldRef = instr.Operand as IField; } if (fieldRef == null) { continue; } var fieldDef = ourFields.find(fieldRef); if (fieldDef == null) { continue; } var fieldInfo = memberInfos.field(fieldDef); if (fieldInfo.renamed) { continue; } fieldInfo.suggestedName = variableNameState.getNewFieldName(fieldInfo.oldName, new NameCreator2(fieldName)); } } }
void initFieldEventHandlers(FieldDefAndDeclaringTypeDict <MFieldDef> ourFields, MethodDefAndDeclaringTypeDict <MMethodDef> ourMethods) { var checker = NameChecker; foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDef.Body == null) { continue; } if (methodDef.MethodDef.IsStatic) { continue; } var instructions = methodDef.MethodDef.Body.Instructions; for (int i = 0; i < instructions.Count - 6; i++) { // We're looking for this code pattern: // ldarg.0 // ldfld field // ldarg.0 // ldftn method / ldarg.0 + ldvirtftn // newobj event_handler_ctor // callvirt add_SomeEvent if (instructions[i].GetParameterIndex() != 0) { continue; } int index = i + 1; var ldfld = instructions[index++]; if (ldfld.OpCode.Code != Code.Ldfld) { continue; } var fieldRef = ldfld.Operand as IField; if (fieldRef == null) { continue; } var fieldDef = ourFields.find(fieldRef); if (fieldDef == null) { continue; } if (instructions[index++].GetParameterIndex() != 0) { continue; } IMethod methodRef; var instr = instructions[index + 1]; if (instr.OpCode.Code == Code.Ldvirtftn) { if (!isThisOrDup(instructions[index++])) { continue; } var ldvirtftn = instructions[index++]; methodRef = ldvirtftn.Operand as IMethod; } else { var ldftn = instructions[index++]; if (ldftn.OpCode.Code != Code.Ldftn) { continue; } methodRef = ldftn.Operand as IMethod; } if (methodRef == null) { continue; } var handlerMethod = ourMethods.find(methodRef); if (handlerMethod == null) { continue; } var newobj = instructions[index++]; if (newobj.OpCode.Code != Code.Newobj) { continue; } if (!isEventHandlerCtor(newobj.Operand as IMethod)) { continue; } var call = instructions[index++]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) { continue; } var addHandler = call.Operand as IMethod; if (addHandler == null) { continue; } if (!Utils.StartsWith(addHandler.Name.String, "add_", StringComparison.Ordinal)) { continue; } var eventName = addHandler.Name.String.Substring(4); if (!checker.isValidEventName(eventName)) { continue; } memberInfos.method(handlerMethod).suggestedName = string.Format("{0}_{1}", memberInfos.field(fieldDef).newName, eventName); } } }
// Find the string decrypter string offset value or null if none found int? findOffsetValue(MethodDef method) { var fieldDict = new FieldDefAndDeclaringTypeDict<IField>(); foreach (var field in method.DeclaringType.Fields) fieldDict.add(field, field); var offsetField = findOffsetField(method); if (offsetField == null) return null; return findOffsetValue(method, (FieldDef)fieldDict.find(offsetField), fieldDict); }
int? findOffsetValue(MethodDef method, FieldDef offsetField, FieldDefAndDeclaringTypeDict<IField> fields) { var instructions = method.Body.Instructions; for (int i = 0; i <= instructions.Count - 2; i++) { var ldstr = instructions[i]; if (ldstr.OpCode.Code != Code.Ldstr) continue; var stringVal = ldstr.Operand as string; if (stringVal == null) continue; var stsfld = instructions[i + 1]; if (stsfld.OpCode.Code != Code.Stsfld) continue; var field = stsfld.Operand as IField; if (field == null || fields.find(field) != offsetField) continue; int value; if (!int.TryParse(stringVal, System.Globalization.NumberStyles.Integer, null, out value)) continue; return value; } return null; }
internal static IEnumerable<FieldDef> getFields(TypeDef type) { var typeFields = new FieldDefAndDeclaringTypeDict<FieldDef>(); foreach (var field in type.Fields) typeFields.add(field, field); var realFields = new Dictionary<FieldDef, bool>(); foreach (var method in type.Methods) { if (method.Body == null) continue; foreach (var instr in method.Body.Instructions) { var fieldRef = instr.Operand as IField; if (fieldRef == null) continue; var field = typeFields.find(fieldRef); if (field == null) continue; realFields[field] = true; } } return realFields.Keys; }