Example #1
0
        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);
                    }
                }
            });
        }