public bool deobfuscate(Blocks blocks) { if (blocks.Method.Name != ".cctor" && blocks.Method.Name != ".ctor") return false; foreach (var block in blocks.MethodBlocks.getAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 2; i++) { var ldtoken = instrs[i]; if (ldtoken.OpCode.Code != Code.Ldtoken) continue; var call1 = instrs[i + 1]; if (call1.OpCode.Code != Code.Call && call1.OpCode.Code != Code.Callvirt) continue; if (!DotNetUtils.isMethod(call1.Operand as IMethod, "System.Type", "(System.RuntimeTypeHandle)")) continue; var call2 = instrs[i + 2]; if (call2.OpCode.Code != Code.Call && call2.OpCode.Code != Code.Callvirt) continue; if (!MethodEqualityComparer.CompareDeclaringTypes.Equals(call2.Operand as IMethod, strongNameCheckMethod)) continue; block.remove(i, 3); return true; } } return false; }
public void ParseBody() { var blocks = new Blocks(Method).MethodBlocks.GetAllBlocks(); foreach (var blockAnalyzer in blocks.Select(block => new BlockAnalyzer(block))) Expressions.AddRange(blockAnalyzer.GenerateExpressions()); }
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 call = instrs[i]; if (call.OpCode.Code != Code.Call) continue; var calledMethod = call.Operand as MethodDefinition; if (calledMethod == null) continue; MethodReference newMethod = null; if (calledMethod == getManifestResourceStream1Method) newMethod = Assembly_GetManifestResourceStream1; else if (calledMethod == getManifestResourceStream2Method) newMethod = Assembly_GetManifestResourceStream2; else if (calledMethod == getManifestResourceNamesMethod) newMethod = Assembly_GetManifestResourceNames; if (newMethod == null) continue; instrs[i] = new Instr(Instruction.Create(OpCodes.Callvirt, newMethod)); } } }
public bool remove(Blocks blocks) { if (antiStrongNameMethod == null) return false; Block antiSnBlock; int numInstructions; if (!findBlock(blocks, out antiSnBlock, out numInstructions)) return false; if (antiSnBlock.FallThrough == null || antiSnBlock.Targets == null || antiSnBlock.Targets.Count != 1) throw new ApplicationException("Invalid state"); var goodBlock = antiSnBlock.Targets[0]; var badBlock = antiSnBlock.FallThrough; antiSnBlock.replaceLastInstrsWithBranch(numInstructions, goodBlock); if (badBlock.FallThrough == badBlock && badBlock.Sources.Count == 1 && badBlock.Targets == null) { badBlock.Parent.removeGuaranteedDeadBlock(badBlock); return true; } if (badBlock.Instructions.Count <= 1 && badBlock.LastInstr.OpCode.Code == Code.Nop) { if (badBlock.FallThrough != null && badBlock.Targets == null && badBlock.Sources.Count == 0) { var badBlock2 = badBlock.FallThrough; if (badBlock2.FallThrough == badBlock2 && badBlock2.Sources.Count == 2 && badBlock2.Targets == null) { badBlock.Parent.removeGuaranteedDeadBlock(badBlock); badBlock2.Parent.removeGuaranteedDeadBlock(badBlock2); return true; } } } throw new ApplicationException("Invalid state"); }
public void Deobfuscate(Blocks blocks) { if (type == null) return; foreach (var block in blocks.MethodBlocks.GetAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { var instr = instrs[i]; if (instr.OpCode.Code != Code.Ldc_I4) continue; var call = instrs[i + 1]; if (call.OpCode.Code != Code.Call) continue; var method = call.Operand as IMethod; if (method == null) continue; if (!new SigComparer().Equals(type, method.DeclaringType)) continue; var methodDef = DotNetUtils.GetMethod(module, method); if (methodDef == null) continue; if (methodDef != typeMethod && methodDef != fieldMethod) continue; uint token = (uint)(int)instrs[i].Operand; instrs[i] = new Instr(OpCodes.Nop.ToInstruction()); instrs[i + 1] = new Instr(new Instruction(OpCodes.Ldtoken, module.ResolveToken(token) as ITokenOperand)); } } }
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 MethodReference; 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 FieldReference; if (field == null) continue; var decrypted = fieldToDecryptedString.find(field); if (decrypted == null) continue; instrs[i] = new Instr(Instruction.Create(OpCodes.Ldstr, decrypted)); Log.v("Decrypted string: {0}", Utils.toCsharpString(decrypted)); } } } }
public void deobfuscate(Blocks blocks) { if (type == null) return; foreach (var block in blocks.MethodBlocks.getAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { var instr = instrs[i]; if (instr.OpCode.Code != Code.Ldc_I4) continue; var call = instrs[i + 1]; if (call.OpCode.Code != Code.Call) continue; var method = call.Operand as MethodReference; if (method == null) continue; if (!MemberReferenceHelper.compareTypes(type, method.DeclaringType)) continue; var methodDef = DotNetUtils.getMethod(module, method); if (methodDef == null) continue; if (methodDef != typeMethod && methodDef != fieldMethod) continue; int token = (int)instrs[i].Operand; instrs[i] = new Instr(Instruction.Create(OpCodes.Nop)); instrs[i + 1] = new Instr(new Instruction(OpCodes.Ldtoken, module.LookupToken(token) as MemberReference)); } } }
public IEnumerable<FieldDef> cleanUp() { var removedFields = new List<FieldDef>(); var moduleCctor = DotNetUtils.getModuleTypeCctor(module); if (moduleCctor == null) return removedFields; var moduleCctorBlocks = new Blocks(moduleCctor); var keep = findFieldsToKeep(); foreach (var fieldInfo in fieldToInfo.getValues()) { if (keep.ContainsKey(fieldInfo)) continue; if (removeInitCode(moduleCctorBlocks, fieldInfo)) { removedFields.Add(fieldInfo.field); removedFields.Add(fieldInfo.arrayInitField); } fieldInfo.arrayInitField.InitialValue = new byte[1]; fieldInfo.arrayInitField.FieldSig.Type = module.CorLibTypes.Byte; fieldInfo.arrayInitField.RVA = 0; } IList<Instruction> allInstructions; IList<ExceptionHandler> allExceptionHandlers; moduleCctorBlocks.getCode(out allInstructions, out allExceptionHandlers); DotNetUtils.restoreBody(moduleCctorBlocks.Method, allInstructions, allExceptionHandlers); return removedFields; }
public void deobfuscate(Blocks blocks) { foreach (var block in blocks.MethodBlocks.getAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 2; i++) { var ldsfld = instrs[i]; if (ldsfld.OpCode.Code != Code.Ldsfld) continue; var ldci4 = instrs[i + 1]; if (!ldci4.isLdcI4()) continue; var stfld = instrs[i + 2]; if (stfld.OpCode.Code != Code.Stfld) continue; var field = stfld.Operand as FieldReference; if (!MemberReferenceHelper.compareFieldReferenceAndDeclaringType(enumField, field)) continue; block.remove(i, 3); i--; } } }
public void deobfuscate(Blocks blocks) { foreach (var block in blocks.MethodBlocks.getAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 2; i++) { var ldsfld = instrs[i]; if (ldsfld.OpCode.Code != Code.Ldsfld) continue; var ldci4 = instrs[i + 1]; if (!ldci4.isLdcI4()) continue; var stfld = instrs[i + 2]; if (stfld.OpCode.Code != Code.Stfld) continue; var field = stfld.Operand as IField; if (!FieldEqualityComparer.CompareDeclaringTypes.Equals(enumField, field)) continue; block.remove(i, 3); i--; } } }
public void deobfuscate(Blocks blocks) { var removeInfos = new Dictionary<Block, List<RemoveInfo>>(); var allBlocks = blocks.MethodBlocks.getAllBlocks(); foreach (var block in allBlocks) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; if (instr.OpCode == OpCodes.Ldsfld) { var di = getDelegateInfo(instr.Operand as FieldReference); if (di == null) continue; var visited = new Dictionary<Block, bool>(); var callInfo = findProxyCall(di, block, i, visited, 1); if (callInfo != null) { add(removeInfos, block, i, null); add(removeInfos, callInfo.Block, callInfo.Index, di); } else { Log.w("Could not fix proxy call. Method: {0} ({1:X8}), Proxy type: {2} ({3:X8})", blocks.Method, blocks.Method.MetadataToken.ToInt32(), di.field.DeclaringType, di.field.DeclaringType.MetadataToken.ToInt32()); } } else if (instr.OpCode == OpCodes.Call) { var method = instr.Operand as MethodDefinition; if (method == null) continue; FieldDefinition field; if (!proxyMethodToField.TryGetValue(method, out field)) continue; var di = getDelegateInfo(field); if (di == null) continue; add(removeInfos, block, i, di); } } } foreach (var block in removeInfos.Keys) { var list = removeInfos[block]; var removeIndexes = new List<int>(list.Count); foreach (var info in list) { if (info.IsCall) { var opcode = info.DelegateInfo.callOpcode; var newInstr = Instruction.Create(opcode, info.DelegateInfo.methodRef); block.replace(info.Index, 1, newInstr); } else removeIndexes.Add(info.Index); } block.remove(removeIndexes); } fixBrokenCalls(blocks.Method, allBlocks); }
public bool Remove(Blocks blocks) { var allBlocks = blocks.MethodBlocks.GetAllBlocks(); foreach (var block in allBlocks) { if (Remove(blocks, block)) return true; } return false; }
bool find(Blocks blocks, out TryBlock tryBlock) { tryBlock = null; foreach (var bb in blocks.MethodBlocks.BaseBlocks) { tryBlock = bb as TryBlock; if (tryBlock == null) continue; if (tryBlock.TryHandlerBlocks.Count != 1) continue; var catchBlock = tryBlock.TryHandlerBlocks[0]; if (catchBlock.HandlerType != ExceptionHandlerType.Catch || catchBlock.CatchType.FullName != "System.Exception") { continue; } if (catchBlock.BaseBlocks.Count != 1) continue; var handlerBlock = catchBlock.BaseBlocks[0] as HandlerBlock; if (handlerBlock == null) continue; int calls = 0; Instr callInstr = null; bool failed = false; foreach (var bb2 in handlerBlock.BaseBlocks) { var block = bb2 as Block; if (block == null) { failed = true; break; } foreach (var instr in block.Instructions) { switch (instr.OpCode.Code) { case Code.Call: case Code.Calli: case Code.Callvirt: calls++; callInstr = instr; break; } } } if (failed || calls != 1 || callInstr.OpCode.Code != Code.Call) continue; var calledMethod = callInstr.Operand as MethodReference; if (calledMethod == null) continue; if (!isExceptionLogger(calledMethod)) continue; return true; } return false; }
public bool remove(Blocks blocks) { if (!HasExceptionLoggers) return false; TryBlock tryBlock; if (!find(blocks, out tryBlock)) return false; blocks.MethodBlocks.removeTryBlock(tryBlock); NumRemovedExceptionLoggers++; return true; }
TamperBlocks FindTamperBlocks(Blocks blocks, IList<Block> allBlocks) { var tamperBlocks = new TamperBlocks(); if (!FindFirstBlocks(tamperBlocks, allBlocks, blocks.Locals)) return null; var second = tamperBlocks.second; var badBlock = second.Block.LastInstr.IsBrfalse() ? second.Block.Targets[0] : second.Block.FallThrough; tamperBlocks.bad = FindBadBlock(badBlock); if (tamperBlocks.bad == null) return null; return tamperBlocks; }
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 call = instrs[i]; if (call.OpCode.Code != Code.Call) continue; var realInstanceMethod = classMethods.find(call.Operand as IMethod); if (realInstanceMethod == null) continue; call.Operand = realInstanceMethod; } } }
public int decrypt(Blocks theBlocks) { try { blocks = theBlocks; callResults = new List<CallResult>(); allBlocks = new List<Block>(blocks.MethodBlocks.getAllBlocks()); findAllCallResults(); inlineAllCalls(); inlineReturnValues(); return callResults.Count; } finally { blocks = null; callResults = null; allBlocks = null; variableValues = null; } }
public void Deobfuscate(Blocks blocks) { foreach (var block in blocks.MethodBlocks.GetAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { var first = instrs[i]; var second = instrs[i + 1]; if (first.OpCode.Code == Code.Not && second.OpCode.Code == Code.Neg) { // It's increment instrs[i] = new Instr(OpCodes.Ldc_I4_1.ToInstruction()); instrs[i + 1] = new Instr(OpCodes.Add.ToInstruction()); } else if (first.OpCode.Code == Code.Neg && second.OpCode.Code == Code.Not) { // It's decrement instrs[i] = new Instr(OpCodes.Ldc_I4_1.ToInstruction()); instrs[i + 1] = new Instr(OpCodes.Sub.ToInstruction()); } } } }
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.Newobj) continue; var ctor = instr.Operand as MethodReference; if (ctor == null) continue; var newCtor = resourceManagerCtors.find(ctor); if (newCtor == null) newCtor = componentManagerCtors.find(ctor); if (newCtor == null) continue; instr.Operand = newCtor; } } }
static bool RemoveResolveHandlerCode(Blocks blocks, MethodDef handler, string installHandlerMethod) { bool modified = false; foreach (var block in blocks.MethodBlocks.GetAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 4; i++) { var call = instrs[i]; if (call.OpCode.Code != Code.Call) continue; var calledMethod = call.Operand as IMethod; if (calledMethod == null || calledMethod.FullName != "System.AppDomain System.AppDomain::get_CurrentDomain()") continue; if (instrs[i + 1].OpCode.Code != Code.Ldnull) continue; var ldftn = instrs[i + 2]; if (ldftn.OpCode.Code != Code.Ldftn) continue; if (ldftn.Operand != handler) continue; var newobj = instrs[i + 3]; if (newobj.OpCode.Code != Code.Newobj) continue; var ctor = newobj.Operand as IMethod; if (ctor == null || ctor.FullName != "System.Void System.ResolveEventHandler::.ctor(System.Object,System.IntPtr)") continue; var callvirt = instrs[i + 4]; if (callvirt.OpCode.Code != Code.Callvirt) continue; calledMethod = callvirt.Operand as IMethod; if (calledMethod == null || calledMethod.FullName != installHandlerMethod) continue; block.Remove(i, 5); modified = true; } } return modified; }
public void deobfuscate(Blocks blocks) { if (!Detected) return; if (stringStructField == null) return; foreach (var block in blocks.MethodBlocks.getAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { var ldstr = instrs[i]; if (ldstr.OpCode.Code != Code.Ldstr) continue; var ldfld = instrs[i + 1]; if (ldfld.OpCode.Code != Code.Ldfld) continue; if (!MemberReferenceHelper.compareFieldReferenceAndDeclaringType(stringStructField, ldfld.Operand as FieldReference)) continue; block.remove(i + 1, 1); } } }
public void deobfuscate(Blocks blocks) { if (!Detected) return; if (stringStructField == null) return; foreach (var block in blocks.MethodBlocks.getAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { var ldstr = instrs[i]; if (ldstr.OpCode.Code != Code.Ldstr) continue; var ldfld = instrs[i + 1]; if (ldfld.OpCode.Code != Code.Ldfld) continue; if (!FieldEqualityComparer.CompareDeclaringTypes.Equals(stringStructField, ldfld.Operand as IField)) continue; block.remove(i + 1, 1); } } }
public void deobfuscate(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) continue; var structField = instr.Operand as FieldReference; if (structField == null || !structFieldsToFix.find(structField)) continue; var ldStFld = instrs[findLdStFieldIndex(instrs, i + 1)]; ldStFld.Operand = getNewField(structField, ldStFld.Operand as FieldReference); instrsToRemove.Add(i); } if (instrsToRemove.Count > 0) block.remove(instrsToRemove); } }
public override void deobfuscateMethodEnd(Blocks blocks) { proxyCallFixer.deobfuscate(blocks); if (options.DecryptConstants) { int32ValueInliner.decrypt(blocks); int64ValueInliner.decrypt(blocks); singleValueInliner.decrypt(blocks); doubleValueInliner.decrypt(blocks); } base.deobfuscateMethodEnd(blocks); }
public override void DeobfuscateMethodEnd(Blocks blocks) { stringDecrypter.Deobfuscate(blocks); int32ValueInliner.Decrypt(blocks); arrayValueInliner.Decrypt(blocks); if (options.RestoreLocals) localsRestorer.Deobfuscate(blocks); if (options.RemoveAntiStrongName) { if (strongNameChecker.Deobfuscate(blocks)) Logger.v("Removed strong name checker code"); } logicalExpressionFixer.Deobfuscate(blocks); base.DeobfuscateMethodEnd(blocks); }
public override void DeobfuscateMethodBegin(Blocks blocks) { proxyCallFixer.Deobfuscate(blocks); base.DeobfuscateMethodBegin(blocks); }
public void Deobfuscate(Blocks blocks) { if (oldToNewMethod.Count == 0) return; foreach (var block in blocks.MethodBlocks.GetAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var call = instrs[i]; if (call.OpCode.Code != Code.Call) continue; var calledMethod = call.Operand as MethodDef; if (calledMethod == null) continue; var newMethodInfo = oldToNewMethod.Find(calledMethod); if (newMethodInfo == null) continue; instrs[i] = new Instr(Instruction.Create(newMethodInfo.opCode, newMethodInfo.method)); } } }
public override void deobfuscateMethodEnd(Blocks blocks) { if (CanRemoveStringDecrypterType) stringDecrypter.deobfuscate(blocks); enumClassFinder.deobfuscate(blocks); base.deobfuscateMethodEnd(blocks); }
public int Decrypt(Blocks blocks) { if (!HasHandlers) return 0; return Decrypt(blocks.Method, blocks.MethodBlocks.GetAllBlocks()); }
void RemoveStackFrameHelperCode(Blocks blocks) { if (!options.RemoveStackFrameHelper) return; if (stackFrameHelper.ExceptionLoggerRemover.Remove(blocks)) Logger.v("Removed StackFrameHelper code"); }