private void StartRecurseThread(MethodDef cleanMethod, MethodDef obfMethod) { Interlocked.Increment(ref _inWork); ThreadPool.QueueUserWorkItem(state => { var lockTaken = false; try { if (cleanMethod is null || obfMethod is null) { return; } Monitor.Enter(obfMethod, ref lockTaken); // clean is used in OperandProcessors.ProcessMethod, hardcoded but that's important if (lockTaken) { var result = _namableProcessor.ProcessMethod(cleanMethod, obfMethod); if (cleanMethod.DeclaringType.IsEazInternalNameRecursive()) { return; } if (result == ProcessResult.Ok) { var cleanInstrs = cleanMethod.Body?.Instructions; var obfInstrs = obfMethod.Body?.Instructions; if (!cleanMethod.HasBody || !obfMethod.HasBody) { return; } // ReSharper disable PossibleNullReferenceException if (cleanInstrs.Count != obfInstrs.Count) { Message(XConsole.Error($"Instruction count differs ({cleanMethod.GetMethodName()}). {cleanInstrs.Count} (clean) {obfInstrs.Count} (obf).")); return; } var idx = AreOpcodesEqual(cleanInstrs, obfInstrs); if (idx > -1) { Message(XConsole.Error($"Instructions differ ({cleanMethod.GetMethodName()}).") + Environment.NewLine + "-*- Clean instructions:" + Environment.NewLine + PrintInstructions(cleanInstrs, idx) + Environment.NewLine + "-*- Obfuscated instructions:" + Environment.NewLine + PrintInstructions(obfInstrs, idx)); return; } for (int i = 0; i < cleanInstrs.Count; i++) { object cleanOperand = cleanInstrs[i].Operand; object obfOperand = obfInstrs[i].Operand; if (cleanOperand is null || obfOperand is null) { continue; } if (cleanOperand.GetType() != obfOperand.GetType()) { continue; } if (cleanOperand is IMethodDefOrRef) { StartRecurseThread(cleanOperand as IMethodDefOrRef, obfOperand as IMethodDefOrRef); } else if (cleanOperand is IType) { _namableProcessor.ProcessType(cleanOperand as IType, obfOperand as IType); } else if (cleanOperand is FieldDef) { _namableProcessor.ProcessField(cleanOperand as FieldDef, obfOperand as FieldDef); } } } else if (result.IsError()) { Message(XConsole.Error($"An error occurred while trying to process method ({cleanMethod.GetMethodName()}). Result code: {result}.")); _overallErroredMethods++; } } } catch (Exception e) { Message(XConsole.Error($"An exception occurred while trying to process method ({cleanMethod.GetMethodName()}). Details:\n{e}")); } finally { Interlocked.Decrement(ref _inWork); if (lockTaken) { Monitor.Exit(obfMethod); } } }); }