Decompiled source of MLVScan v1.5.3

Plugins/MLVScan.MelonLoader.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using MLVScan;
using MLVScan.Models;
using MLVScan.Services;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "MLVScan", "1.5.3", "Bars", null)]
[assembly: MelonPriority(int.MinValue)]
[assembly: MelonColor(255, 139, 0, 0)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MLVScan.MelonLoader")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ed0d0ca873e6deac78fcda7799234dde5c5e9ca8")]
[assembly: AssemblyProduct("MLVScan.MelonLoader")]
[assembly: AssemblyTitle("MLVScan.MelonLoader")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MLVScan
{
	public class Core : MelonPlugin
	{
		private ServiceFactory _serviceFactory;

		private ConfigManager _configManager;

		private ModScanner _modScanner;

		private ModDisabler _modDisabler;

		private bool _initialized = false;

		private static readonly string[] DefaultWhitelistedMods = new string[5] { "MLVScan.dll", "MLVScan.MelonLoader.dll", "CustomTV.dll", "CustomTV_Mono.dll", "CustomTV_IL2CPP.dll" };

		public override void OnEarlyInitializeMelon()
		{
			try
			{
				((MelonBase)this).LoggerInstance.Msg("Pre-scanning for malicious mods...");
				_serviceFactory = new ServiceFactory(((MelonBase)this).LoggerInstance);
				_configManager = _serviceFactory.CreateConfigManager();
				InitializeDefaultWhitelist();
				_modScanner = _serviceFactory.CreateModScanner();
				_modDisabler = _serviceFactory.CreateModDisabler();
				_initialized = true;
				ScanAndDisableMods(force: true);
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("Error in pre-mod scan: " + ex.Message);
				((MelonBase)this).LoggerInstance.Error(ex.StackTrace);
			}
		}

		public override void OnInitializeMelon()
		{
			try
			{
				((MelonBase)this).LoggerInstance.Msg("MLVScan initialization complete");
				if (_configManager.Config.WhitelistedMods.Length != 0)
				{
					((MelonBase)this).LoggerInstance.Msg($"{_configManager.Config.WhitelistedMods.Length} mod(s) are whitelisted and won't be scanned");
					((MelonBase)this).LoggerInstance.Msg("To manage whitelisted mods, edit MelonPreferences.cfg");
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("Error initializing MLVScan: " + ex.Message);
				((MelonBase)this).LoggerInstance.Error(ex.StackTrace);
			}
		}

		private void InitializeDefaultWhitelist()
		{
			if (_configManager != null)
			{
				string[] whitelistedMods = _configManager.GetWhitelistedMods();
				if (whitelistedMods.Length == 0)
				{
					((MelonBase)this).LoggerInstance.Msg("Initializing default whitelist");
					_configManager.SetWhitelistedMods(DefaultWhitelistedMods);
				}
			}
		}

		public Dictionary<string, List<ScanFinding>> ScanAndDisableMods(bool force = false)
		{
			try
			{
				if (!_initialized)
				{
					((MelonBase)this).LoggerInstance.Error("Cannot scan mods - MLVScan not properly initialized");
					return new Dictionary<string, List<ScanFinding>>();
				}
				((MelonBase)this).LoggerInstance.Msg("Scanning for suspicious mods...");
				Dictionary<string, List<ScanFinding>> source = _modScanner.ScanAllMods(force);
				Dictionary<string, List<ScanFinding>> dictionary = source.Where((KeyValuePair<string, List<ScanFinding>> kv) => kv.Value.Count > 0 && kv.Value.Any((ScanFinding f) => f.Location != "Assembly scanning")).ToDictionary((KeyValuePair<string, List<ScanFinding>> kv) => kv.Key, (KeyValuePair<string, List<ScanFinding>> kv) => kv.Value);
				if (dictionary.Count > 0)
				{
					((MelonBase)this).LoggerInstance.Warning($"Found {dictionary.Count} potentially malicious mods!");
					List<string> list = _modDisabler.DisableSuspiciousMods(dictionary, force);
					int count = list.Count;
					((MelonBase)this).LoggerInstance.Msg($"Disabled {count} suspicious mods");
					if (count <= 0)
					{
						return dictionary;
					}
					GenerateDetailedReports(list, dictionary);
					((MelonBase)this).LoggerInstance.Msg("To whitelist any false positives, add them to the MLVScan → WhitelistedMods setting in MelonPreferences.cfg");
				}
				else
				{
					((MelonBase)this).LoggerInstance.Msg("No suspicious mods found");
				}
				return dictionary;
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("Error scanning mods: " + ex.Message);
				return new Dictionary<string, List<ScanFinding>>();
			}
		}

		private void GenerateDetailedReports(List<string> disabledMods, Dictionary<string, List<ScanFinding>> scanResults)
		{
			((MelonBase)this).LoggerInstance.Warning("======= DETAILED SCAN REPORT =======");
			PromptGeneratorService promptGeneratorService = _serviceFactory.CreatePromptGeneratorService();
			string text = Path.Combine(MelonEnvironment.UserDataDirectory, "MLVScan", "Prompts");
			foreach (string disabledMod in disabledMods)
			{
				string fileName = Path.GetFileName(disabledMod);
				((MelonBase)this).LoggerInstance.Warning("SUSPICIOUS MOD: " + fileName);
				((MelonBase)this).LoggerInstance.Msg("-------------------------------");
				if (scanResults.TryGetValue(disabledMod, out var value))
				{
					List<ScanFinding> list = value.Where((ScanFinding f) => f.Location != "Assembly scanning").ToList();
					if (list.Count == 0)
					{
						((MelonBase)this).LoggerInstance.Msg("No specific suspicious patterns were identified.");
						continue;
					}
					Dictionary<string, List<ScanFinding>> dictionary = (from f in list
						group f by f.Description).ToDictionary((IGrouping<string, ScanFinding> g) => g.Key, (IGrouping<string, ScanFinding> g) => g.ToList());
					((MelonBase)this).LoggerInstance.Warning($"Total suspicious patterns found: {list.Count}");
					Dictionary<string, int> dictionary2 = (from f in list
						group f by f.Severity into g
						orderby GetSeverityRank(g.Key) descending
						select g).ToDictionary((IGrouping<string, ScanFinding> g) => g.Key, (IGrouping<string, ScanFinding> g) => g.Count());
					((MelonBase)this).LoggerInstance.Warning("Severity breakdown:");
					foreach (KeyValuePair<string, int> item in dictionary2)
					{
						string arg = FormatSeverityLabel(item.Key);
						((MelonBase)this).LoggerInstance.Msg($"  {arg}: {item.Value} issue(s)");
					}
					((MelonBase)this).LoggerInstance.Msg("-------------------------------");
					((MelonBase)this).LoggerInstance.Warning("Suspicious patterns found:");
					foreach (KeyValuePair<string, List<ScanFinding>> item2 in dictionary)
					{
						item2.Deconstruct(out var key, out var value2);
						string arg2 = key;
						List<ScanFinding> list2 = value2;
						string arg3 = FormatSeverityLabel(list2[0].Severity);
						((MelonBase)this).LoggerInstance.Warning($"[{arg3}] {arg2} ({list2.Count} instances)");
						int num = Math.Min(list2.Count, 3);
						for (int i = 0; i < num; i++)
						{
							ScanFinding scanFinding = list2[i];
							((MelonBase)this).LoggerInstance.Msg("  * At: " + scanFinding.Location);
							if (!string.IsNullOrEmpty(scanFinding.CodeSnippet))
							{
								((MelonBase)this).LoggerInstance.Msg("    Code Snippet (IL):");
								string[] array = scanFinding.CodeSnippet.Split(new char[2] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
								foreach (string text2 in array)
								{
									((MelonBase)this).LoggerInstance.Msg("      " + text2);
								}
							}
						}
						if (list2.Count > num)
						{
							((MelonBase)this).LoggerInstance.Msg($"  * And {list2.Count - num} more instances...");
						}
						((MelonBase)this).LoggerInstance.Msg("");
					}
					((MelonBase)this).LoggerInstance.Msg("-------------------------------");
					DisplaySecurityNotice(fileName);
					try
					{
						string text3 = Path.Combine(MelonEnvironment.UserDataDirectory, "MLVScan", "Reports");
						Directory.CreateDirectory(text3);
						string text4 = Path.Combine(text3, fileName + ".report.txt");
						using (StreamWriter streamWriter = new StreamWriter(text4))
						{
							streamWriter.WriteLine("MLVScan Detailed Report for " + fileName);
							streamWriter.WriteLine($"Scan Date: {DateTime.Now}");
							streamWriter.WriteLine($"Total Suspicious Patterns: {list.Count}");
							streamWriter.WriteLine("==============================================");
							streamWriter.WriteLine("\nSEVERITY BREAKDOWN:");
							foreach (KeyValuePair<string, int> item3 in dictionary2)
							{
								streamWriter.WriteLine($"- {item3.Key}: {item3.Value} issue(s)");
							}
							streamWriter.WriteLine("==============================================");
							foreach (KeyValuePair<string, List<ScanFinding>> item4 in dictionary)
							{
								streamWriter.WriteLine("\n== " + item4.Key + " ==");
								streamWriter.WriteLine("Severity: " + item4.Value[0].Severity);
								streamWriter.WriteLine($"Instances: {item4.Value.Count}");
								streamWriter.WriteLine("\nLocations & Snippets:");
								foreach (ScanFinding item5 in item4.Value)
								{
									streamWriter.WriteLine("- " + item5.Location);
									if (!string.IsNullOrEmpty(item5.CodeSnippet))
									{
										streamWriter.WriteLine("  Code Snippet (IL):");
										string[] array2 = item5.CodeSnippet.Split(new char[2] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
										foreach (string text5 in array2)
										{
											streamWriter.WriteLine("    " + text5);
										}
										streamWriter.WriteLine();
									}
								}
							}
							WriteSecurityNoticeToReport(streamWriter);
						}
						if (promptGeneratorService.SavePromptToFile(disabledMod, list, text))
						{
							((MelonBase)this).LoggerInstance.Msg("Detailed report saved to: " + text4);
							((MelonBase)this).LoggerInstance.Msg("LLM analysis prompt saved to: " + Path.Combine(text, fileName + ".prompt.md"));
							((MelonBase)this).LoggerInstance.Msg("You can copy the contents of the prompt file into ChatGPT to help determine if this is malware or a false positive, although don't trust ChatGPT to be 100% accurate.");
						}
						else
						{
							((MelonBase)this).LoggerInstance.Msg("Detailed report saved to: " + text4);
						}
					}
					catch (Exception ex)
					{
						((MelonBase)this).LoggerInstance.Error("Failed to save detailed report: " + ex.Message);
					}
				}
				((MelonBase)this).LoggerInstance.Warning("-------------------------------");
			}
			((MelonBase)this).LoggerInstance.Warning("====== END OF SCAN REPORT ======");
		}

		private static int GetSeverityRank(string severity)
		{
			string text = severity.ToLower();
			if (1 == 0)
			{
			}
			int result = text switch
			{
				"critical" => 4, 
				"high" => 3, 
				"medium" => 2, 
				"low" => 1, 
				_ => 0, 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		private static string FormatSeverityLabel(string severity)
		{
			string text = severity.ToLower();
			if (1 == 0)
			{
			}
			string result = text switch
			{
				"critical" => "CRITICAL", 
				"high" => "HIGH", 
				"medium" => "MEDIUM", 
				"low" => "LOW", 
				_ => severity.ToUpper(), 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		private void DisplaySecurityNotice(string modName)
		{
			((MelonBase)this).LoggerInstance.Warning("IMPORTANT SECURITY NOTICE");
			((MelonBase)this).LoggerInstance.Msg("MLVScan has detected and disabled " + modName + " before it was loaded.");
			((MelonBase)this).LoggerInstance.Msg("If this is your first time running the game with this mod, your PC is likely safe.");
			((MelonBase)this).LoggerInstance.Msg("However, if you've previously run the game with this mod, your system MAY be infected.");
			((MelonBase)this).LoggerInstance.Msg("Keep in mind that no detection system is perfect, and this mod may be falsely flagged.");
			((MelonBase)this).LoggerInstance.Warning("Recommended security steps:");
			((MelonBase)this).LoggerInstance.Msg("1. Check with the modding community first - no detection is perfect");
			((MelonBase)this).LoggerInstance.Msg("   Join the modding Discord at: https://discord.gg/rV2QSAnqhX");
			((MelonBase)this).LoggerInstance.Msg("   Ask about this mod in the #MLVScan or #report-mods channels to confirm if it's actually malicious");
			((MelonBase)this).LoggerInstance.Msg("2. Run a full system scan with a trusted antivirus like Malwarebytes");
			((MelonBase)this).LoggerInstance.Msg("   Malwarebytes is recommended as a free and effective antivirus solution");
			((MelonBase)this).LoggerInstance.Msg("3. Use Microsoft Safety Scanner for a secondary scan");
			((MelonBase)this).LoggerInstance.Msg("4. Change important passwords if antivirus shows a threat");
			((MelonBase)this).LoggerInstance.Warning("Resources for malware removal:");
			((MelonBase)this).LoggerInstance.Msg("- Malwarebytes: https://www.malwarebytes.com/cybersecurity/basics/how-to-remove-virus-from-computer");
			((MelonBase)this).LoggerInstance.Msg("- Microsoft Safety Scanner: https://learn.microsoft.com/en-us/defender-endpoint/safety-scanner-download");
		}

		private static void WriteSecurityNoticeToReport(StreamWriter writer)
		{
			writer.WriteLine("\n\n============== SECURITY NOTICE ==============\n");
			writer.WriteLine("IMPORTANT: READ THIS SECURITY INFORMATION\n");
			writer.WriteLine("MLVScan has detected and disabled this mod before it was loaded.");
			writer.WriteLine("This mod contains code patterns commonly associated with malware.\n");
			writer.WriteLine("YOUR SYSTEM SECURITY STATUS:");
			writer.WriteLine("- If this is your FIRST TIME starting the game with this mod installed:");
			writer.WriteLine("  Your PC is likely SAFE as MLVScan prevented the mod from loading.");
			writer.WriteLine("\n- If you have PREVIOUSLY PLAYED the game with this mod loaded:");
			writer.WriteLine("  Your system MAY BE INFECTED with malware. Take action immediately.\n");
			writer.WriteLine("RECOMMENDED SECURITY STEPS:");
			writer.WriteLine("1. Check with the modding community first - no detection system is perfect");
			writer.WriteLine("   Join the modding Discord at: https://discord.gg/rV2QSAnqhX");
			writer.WriteLine("   Ask about this mod in the #MLVScan or #report-mods channels to confirm if it's actually malicious");
			writer.WriteLine("\n2. Run a full system scan with a reputable antivirus program");
			writer.WriteLine("   Free option: Malwarebytes (https://www.malwarebytes.com/)");
			writer.WriteLine("   Malwarebytes is recommended as a free and effective antivirus solution");
			writer.WriteLine("\n3. Run Microsoft Safety Scanner as a secondary check");
			writer.WriteLine("   Download: https://learn.microsoft.com/en-us/defender-endpoint/safety-scanner-download");
			writer.WriteLine("\n4. Update all your software from official sources");
			writer.WriteLine("\n5. Change passwords for important accounts (from a clean device if possible)");
			writer.WriteLine("\n6. Monitor your accounts for any suspicious activity");
			writer.WriteLine("\nDETAILED MALWARE REMOVAL GUIDES:");
			writer.WriteLine("- Malwarebytes Guide: https://www.malwarebytes.com/cybersecurity/basics/how-to-remove-virus-from-computer");
			writer.WriteLine("- Microsoft Safety Scanner: https://learn.microsoft.com/en-us/defender-endpoint/safety-scanner-download");
			writer.WriteLine("\n=============================================");
		}
	}
}
namespace MLVScan.Services
{
	public class AssemblyScanner
	{
		private readonly IEnumerable<IScanRule> _rules;

		private DefaultAssemblyResolver _assemblyResolver;

		public AssemblyScanner(IEnumerable<IScanRule> rules)
		{
			_rules = rules ?? throw new ArgumentNullException("rules");
			InitializeResolver();
		}

		private void InitializeResolver()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			_assemblyResolver = new DefaultAssemblyResolver();
			string gameRootDirectory = MelonEnvironment.GameRootDirectory;
			string text = Path.Combine(gameRootDirectory, "MelonLoader");
			((BaseAssemblyResolver)_assemblyResolver).AddSearchDirectory(gameRootDirectory);
			if (Directory.Exists(text))
			{
				((BaseAssemblyResolver)_assemblyResolver).AddSearchDirectory(text);
				string text2 = Path.Combine(text, "Managed");
				if (Directory.Exists(text2))
				{
					((BaseAssemblyResolver)_assemblyResolver).AddSearchDirectory(text2);
				}
				string text3 = Path.Combine(text, "Dependencies");
				if (Directory.Exists(text3))
				{
					((BaseAssemblyResolver)_assemblyResolver).AddSearchDirectory(text3);
					string[] directories = Directory.GetDirectories(text3, "*", SearchOption.AllDirectories);
					foreach (string text4 in directories)
					{
						((BaseAssemblyResolver)_assemblyResolver).AddSearchDirectory(text4);
					}
				}
			}
			string text5 = Path.Combine(gameRootDirectory, "Schedule I_Data", "Managed");
			if (Directory.Exists(text5))
			{
				((BaseAssemblyResolver)_assemblyResolver).AddSearchDirectory(text5);
			}
		}

		public IEnumerable<ScanFinding> Scan(string assemblyPath)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrWhiteSpace(assemblyPath))
			{
				throw new ArgumentException("Assembly path must be provided", "assemblyPath");
			}
			if (!File.Exists(assemblyPath))
			{
				throw new FileNotFoundException("Assembly file not found", assemblyPath);
			}
			List<ScanFinding> list = new List<ScanFinding>();
			try
			{
				ReaderParameters val = new ReaderParameters
				{
					ReadWrite = false,
					InMemory = true,
					ReadSymbols = false,
					AssemblyResolver = (IAssemblyResolver)(object)_assemblyResolver
				};
				AssemblyDefinition val2 = AssemblyDefinition.ReadAssembly(assemblyPath, val);
				Enumerator<ModuleDefinition> enumerator = val2.Modules.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						ModuleDefinition current = enumerator.Current;
						ScanForDllImports(current, list);
						Enumerator<TypeDefinition> enumerator2 = current.Types.GetEnumerator();
						try
						{
							while (enumerator2.MoveNext())
							{
								TypeDefinition current2 = enumerator2.Current;
								ScanType(current2, list);
							}
						}
						finally
						{
							((IDisposable)enumerator2).Dispose();
						}
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}
			catch (Exception)
			{
				list.Add(new ScanFinding("Assembly scanning", "Warning: Some parts of the assembly could not be scanned. This doesn't necessarily mean the mod is malicious.", "Low"));
			}
			if (list.Count == 1 && list[0].Location == "Assembly scanning" && string.IsNullOrEmpty(list[0].CodeSnippet))
			{
				return new List<ScanFinding>();
			}
			return list;
		}

		private void ScanForDllImports(ModuleDefinition module, List<ScanFinding> findings)
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				foreach (TypeDefinition allType in GetAllTypes(module))
				{
					foreach (MethodDefinition method2 in ((IEnumerable<MethodDefinition>)allType.Methods).Where((MethodDefinition method) => method.HasCustomAttributes))
					{
						try
						{
							CustomAttribute val = ((IEnumerable<CustomAttribute>)method2.CustomAttributes).FirstOrDefault((Func<CustomAttribute, bool>)((CustomAttribute attr) => ((MemberReference)attr.AttributeType).Name == "DllImportAttribute"));
							if (val != null && _rules.Any((IScanRule rule) => rule.IsSuspicious((MethodReference)(object)method2)))
							{
								IScanRule scanRule = _rules.First((IScanRule r) => r.IsSuspicious((MethodReference)(object)method2));
								object[] array = new object[4];
								CustomAttributeArgument val2 = ((IEnumerable<CustomAttributeArgument>)val.ConstructorArguments).FirstOrDefault();
								array[0] = ((CustomAttributeArgument)(ref val2)).Value;
								array[1] = ((MemberReference)((MethodReference)method2).ReturnType).Name;
								array[2] = ((MemberReference)method2).Name;
								array[3] = string.Join(", ", ((IEnumerable<ParameterDefinition>)((MethodReference)method2).Parameters).Select((ParameterDefinition p) => ((MemberReference)((ParameterReference)p).ParameterType).Name + " " + ((ParameterReference)p).Name));
								string codeSnippet = string.Format("[DllImport(\"{0}\")]\n{1} {2}({3});", array);
								findings.Add(new ScanFinding(((MemberReference)method2.DeclaringType).FullName + "." + ((MemberReference)method2).Name, scanRule.Description, scanRule.Severity, codeSnippet));
							}
						}
						catch (Exception)
						{
						}
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private void ScanType(TypeDefinition type, List<ScanFinding> findings)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Enumerator<MethodDefinition> enumerator = type.Methods.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						MethodDefinition current = enumerator.Current;
						ScanMethod(current, findings);
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
				Enumerator<TypeDefinition> enumerator2 = type.NestedTypes.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						TypeDefinition current2 = enumerator2.Current;
						ScanType(current2, findings);
					}
				}
				finally
				{
					((IDisposable)enumerator2).Dispose();
				}
			}
			catch (Exception)
			{
			}
		}

		private void ScanMethod(MethodDefinition method, List<ScanFinding> findings)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!method.HasBody)
				{
					return;
				}
				Collection<Instruction> instructions = method.Body.Instructions;
				DetectCOMReflectionAttack(method, instructions, findings);
				for (int i = 0; i < instructions.Count; i++)
				{
					Instruction val = instructions[i];
					try
					{
						if (!(val.OpCode == OpCodes.Call) && !(val.OpCode == OpCodes.Callvirt))
						{
							continue;
						}
						object operand = val.Operand;
						MethodReference calledMethod = (MethodReference)((operand is MethodReference) ? operand : null);
						if (calledMethod == null)
						{
							continue;
						}
						if (_rules.Any((IScanRule rule) => rule.IsSuspicious(calledMethod)))
						{
							IScanRule scanRule = _rules.First((IScanRule r) => r.IsSuspicious(calledMethod));
							StringBuilder stringBuilder = new StringBuilder();
							int num = 2;
							for (int j = Math.Max(0, i - num); j < Math.Min(instructions.Count, i + num + 1); j++)
							{
								if (j == i)
								{
									stringBuilder.Append(">>> ");
								}
								else
								{
									stringBuilder.Append("    ");
								}
								stringBuilder.AppendLine(((object)instructions[j]).ToString());
							}
							findings.Add(new ScanFinding($"{((MemberReference)method.DeclaringType).FullName}.{((MemberReference)method).Name}:{val.Offset}", scanRule.Description, scanRule.Severity, stringBuilder.ToString().TrimEnd()));
						}
						ScanForReflectionInvocation(method, val, calledMethod, i, instructions, findings);
					}
					catch (Exception)
					{
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private void DetectCOMReflectionAttack(MethodDefinition methodDef, Collection<Instruction> instructions, List<ScanFinding> findings)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			string text = null;
			string text2 = null;
			Enumerator<Instruction> enumerator = instructions.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Instruction current = enumerator.Current;
					if (current.OpCode != OpCodes.Call && current.OpCode != OpCodes.Callvirt)
					{
						continue;
					}
					object operand = current.Operand;
					MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
					if (val == null || ((MemberReference)val).DeclaringType == null)
					{
						continue;
					}
					string fullName = ((MemberReference)((MemberReference)val).DeclaringType).FullName;
					string name = ((MemberReference)val).Name;
					if (fullName == "System.Type" && name == "GetTypeFromProgID")
					{
						flag = true;
						int num = instructions.IndexOf(current);
						for (int i = Math.Max(0, num - 5); i < num; i++)
						{
							if (instructions[i].OpCode == OpCodes.Ldstr && instructions[i].Operand is string text3)
							{
								text = text3;
								break;
							}
						}
					}
					if (fullName == "System.Activator" && name == "CreateInstance")
					{
						flag2 = true;
					}
					if (!(fullName == "System.Type") || !(name == "InvokeMember"))
					{
						continue;
					}
					flag3 = true;
					int num2 = instructions.IndexOf(current);
					for (int j = Math.Max(0, num2 - 5); j < num2; j++)
					{
						if (instructions[j].OpCode == OpCodes.Ldstr && instructions[j].Operand is string text4)
						{
							text2 = text4;
							break;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			if (!flag || !(flag2 || flag3) || ((text == null || !text.Contains("Shell")) && (text2 == null || !text2.Contains("ShellExecute")) && (text == null || text2 == null)))
			{
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			Enumerator<Instruction> enumerator2 = instructions.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					Instruction current2 = enumerator2.Current;
					stringBuilder.AppendLine(((object)current2).ToString());
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
			findings.Add(new ScanFinding(((MemberReference)methodDef.DeclaringType).FullName + "." + ((MemberReference)methodDef).Name, "Reflective shell execution detected via COM (GetTypeFromProgID + InvokeMember pattern)", "Critical", stringBuilder.ToString().TrimEnd()));
		}

		private void ScanForReflectionInvocation(MethodDefinition methodDef, Instruction instruction, MethodReference calledMethod, int index, Collection<Instruction> instructions, List<ScanFinding> findings)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_0098: Expected O, but got Unknown
			try
			{
				if (!IsReflectionInvokeMethod(calledMethod))
				{
					return;
				}
				string invokedMethodName = ExtractInvokedMethodName(instructions, index);
				if (string.IsNullOrEmpty(invokedMethodName) || IsLikelyLegitimateModContext(methodDef))
				{
					return;
				}
				MethodReference fakeMethodRef = new MethodReference(invokedMethodName, ((MemberReference)methodDef).Module.TypeSystem.Object)
				{
					DeclaringType = new TypeReference("", "ReflectedType", ((MemberReference)methodDef).Module, (IMetadataScope)null)
				};
				if (!_rules.Any((IScanRule rule) => rule.IsSuspicious(fakeMethodRef) || WouldRuleMatchMethodName(rule, invokedMethodName)))
				{
					return;
				}
				IScanRule scanRule = _rules.FirstOrDefault((IScanRule r) => r.IsSuspicious(fakeMethodRef) || WouldRuleMatchMethodName(r, invokedMethodName));
				if (scanRule == null)
				{
					return;
				}
				StringBuilder stringBuilder = new StringBuilder();
				int num = 4;
				for (int i = Math.Max(0, index - num); i < Math.Min(instructions.Count, index + num + 1); i++)
				{
					if (i == index)
					{
						stringBuilder.Append(">>> ");
					}
					else
					{
						stringBuilder.Append("    ");
					}
					stringBuilder.AppendLine(((object)instructions[i]).ToString());
				}
				findings.Add(new ScanFinding($"{((MemberReference)methodDef.DeclaringType).FullName}.{((MemberReference)methodDef).Name}:{instruction.Offset}", "Potential reflection bypass: " + scanRule.Description, (scanRule.Severity == "Low") ? "Medium" : scanRule.Severity, stringBuilder.ToString().TrimEnd()));
			}
			catch (Exception)
			{
			}
		}

		private bool IsLikelyLegitimateModContext(MethodDefinition methodDef)
		{
			if (((MemberReference)methodDef.DeclaringType).FullName.Contains("Patch") || ((MemberReference)methodDef.DeclaringType).FullName.Contains("Harmony") || ((MemberReference)methodDef).Name.Contains("Patch") || ((MemberReference)methodDef.DeclaringType).FullName.Contains("MonoMod"))
			{
				return true;
			}
			if (!((MemberReference)methodDef.DeclaringType).FullName.Contains("MelonLoader"))
			{
				string @namespace = ((TypeReference)methodDef.DeclaringType).Namespace;
				if (@namespace == null || !@namespace.Contains("MelonLoader"))
				{
					string namespace2 = ((TypeReference)methodDef.DeclaringType).Namespace;
					if (namespace2 == null || !namespace2.Contains("UnityEngine"))
					{
						if ((((MemberReference)methodDef).Name.Contains("Initialize") && !((MemberReference)methodDef).Name.Contains("OnInitializeMelon")) || ((MemberReference)methodDef).Name.Contains("Setup") || ((MemberReference)methodDef).Name == "OnSceneWasLoaded")
						{
							return true;
						}
						return false;
					}
				}
			}
			return true;
		}

		private bool IsReflectionInvokeMethod(MethodReference method)
		{
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			if (((MemberReference)method).DeclaringType == null)
			{
				return false;
			}
			string fullName = ((MemberReference)((MemberReference)method).DeclaringType).FullName;
			string name = ((MemberReference)method).Name;
			if (fullName == "System.Type" && name == "InvokeMember")
			{
				return true;
			}
			if (fullName == "System.Type" && name == "GetTypeFromProgID")
			{
				return true;
			}
			if (fullName == "System.Activator" && name == "CreateInstance")
			{
				return true;
			}
			if ((fullName == "System.Type" && name == "GetTypeFromProgID") || (fullName == "System.Type" && name == "GetTypeFromCLSID"))
			{
				Enumerator<ParameterDefinition> enumerator = method.Parameters.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						ParameterDefinition current = enumerator.Current;
						if (((ParameterReference)current).Name.Contains("Shell") || ((ParameterReference)current).Name.Contains("Command") || ((ParameterReference)current).Name.Contains("Process") || ((ParameterReference)current).Name.Contains("Exec"))
						{
							return true;
						}
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}
			if ((fullName == "System.Reflection.MethodInfo" && name == "Invoke") || (fullName == "System.Reflection.MethodBase" && name == "Invoke"))
			{
				return true;
			}
			return false;
		}

		private string ExtractInvokedMethodName(Collection<Instruction> instructions, int currentIndex)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			for (int i = Math.Max(0, currentIndex - 15); i < currentIndex; i++)
			{
				Instruction val = instructions[i];
				if (val.OpCode == OpCodes.Ldstr && val.Operand is string text)
				{
					if (text.Contains("Shell.Application") || text.Contains("shell32"))
					{
						return "ShellExecute";
					}
					if (IsSuspiciousMethodName(text))
					{
						return text;
					}
				}
			}
			for (int j = currentIndex + 1; j < Math.Min(instructions.Count, currentIndex + 10); j++)
			{
				Instruction val2 = instructions[j];
				if (val2.OpCode == OpCodes.Ldstr && val2.Operand is string text2 && (text2 == "ShellExecute" || text2 == "Execute" || text2 == "Shell"))
				{
					return text2;
				}
			}
			return "UnknownReflectionCall";
		}

		private bool IsSuspiciousMethodName(string str)
		{
			if (string.IsNullOrWhiteSpace(str))
			{
				return false;
			}
			if (str.Contains("Shell.Application") || str.Contains("shell32"))
			{
				return true;
			}
			string[] source = new string[18]
			{
				"ShellExecute", "Shell", "Execute", "Start", "Process", "Exec", "Run", "Launch", "CreateProcess", "Spawn",
				"Command", "Eval", "LoadLibrary", "LoadFrom", "cmd.exe", "powershell.exe", "wscript.exe", "cscript.exe"
			};
			return source.Any((string name) => str.Equals(name, StringComparison.OrdinalIgnoreCase) || str.Contains(name, StringComparison.OrdinalIgnoreCase));
		}

		private bool WouldRuleMatchMethodName(IScanRule rule, string methodName)
		{
			if (rule is Shell32Rule)
			{
				string[] source = new string[9] { "ShellExecute", "Shell", "Execute", "CreateProcess", "Spawn", "Command", "cmd.exe", "powershell.exe", "wscript.exe" };
				return source.Any((string name) => methodName.Equals(name, StringComparison.OrdinalIgnoreCase) || methodName.Contains(name, StringComparison.OrdinalIgnoreCase));
			}
			if (rule.Description.Contains("process") || rule.Description.Contains("Process"))
			{
				string[] source2 = new string[5] { "Start", "Process", "Exec", "Run", "Launch" };
				return source2.Any((string name) => methodName.Equals(name, StringComparison.OrdinalIgnoreCase) || methodName.Contains(name, StringComparison.OrdinalIgnoreCase));
			}
			if (rule.Description.Contains("base64") || rule.Description.Contains("Base64"))
			{
				return methodName.Equals("FromBase64String", StringComparison.OrdinalIgnoreCase) || methodName.Equals("ToBase64String", StringComparison.OrdinalIgnoreCase);
			}
			if (rule.Description.Contains("Registry"))
			{
				return methodName.Contains("Registry") || methodName.Contains("GetValue") || methodName.Contains("SetValue");
			}
			if (rule.Description.Contains("assembly") || rule.Description.Contains("Assembly"))
			{
				return methodName.Contains("Load") || methodName.Contains("Assembly") || methodName.Contains("Compile");
			}
			return false;
		}

		private IEnumerable<TypeDefinition> GetAllTypes(ModuleDefinition module)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			List<TypeDefinition> list = new List<TypeDefinition>();
			try
			{
				Enumerator<TypeDefinition> enumerator = module.Types.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						TypeDefinition current = enumerator.Current;
						list.Add(current);
						CollectNestedTypes(current, list);
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}
			catch (Exception)
			{
			}
			return list;
		}

		private void CollectNestedTypes(TypeDefinition type, List<TypeDefinition> allTypes)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Enumerator<TypeDefinition> enumerator = type.NestedTypes.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						TypeDefinition current = enumerator.Current;
						allTypes.Add(current);
						CollectNestedTypes(current, allTypes);
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}
			catch (Exception)
			{
			}
		}
	}
	public class ConfigManager
	{
		private readonly Instance _logger;

		private readonly MelonPreferences_Category _category;

		private readonly MelonPreferences_Entry<bool> _enableAutoScan;

		private readonly MelonPreferences_Entry<bool> _enableAutoDisable;

		private readonly MelonPreferences_Entry<string> _minSeverityForDisable;

		private readonly MelonPreferences_Entry<string[]> _scanDirectories;

		private readonly MelonPreferences_Entry<int> _suspiciousThreshold;

		private readonly MelonPreferences_Entry<string[]> _whitelistedMods;

		public ScanConfig Config { get; private set; }

		public ConfigManager(Instance logger)
		{
			_logger = logger ?? throw new ArgumentNullException("logger");
			try
			{
				_category = MelonPreferences.CreateCategory("MLVScan");
				_enableAutoScan = _category.CreateEntry<bool>("EnableAutoScan", true, (string)null, "Whether to scan mods at startup", false, false, (ValueValidator)null, (string)null);
				_enableAutoDisable = _category.CreateEntry<bool>("EnableAutoDisable", true, (string)null, "Whether to disable suspicious mods", false, false, (ValueValidator)null, (string)null);
				_minSeverityForDisable = _category.CreateEntry<string>("MinSeverityForDisable", "Medium", (string)null, "Minimum severity level to trigger disabling (Low, Medium, High, Critical)", false, false, (ValueValidator)null, (string)null);
				_scanDirectories = _category.CreateEntry<string[]>("ScanDirectories", new string[2] { "Mods", "Plugins" }, (string)null, "Directories to scan for mods", false, false, (ValueValidator)null, (string)null);
				_suspiciousThreshold = _category.CreateEntry<int>("SuspiciousThreshold", 1, (string)null, "How many suspicious findings required before disabling a mod", false, false, (ValueValidator)null, (string)null);
				_whitelistedMods = _category.CreateEntry<string[]>("WhitelistedMods", Array.Empty<string>(), (string)null, "List of mod filenames to skip when scanning (e.g., 'MLVScan.dll')", false, false, (ValueValidator)null, (string)null);
				((MelonEventBase<LemonAction<bool, bool>>)(object)_enableAutoScan.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)OnConfigChanged, 0, false);
				((MelonEventBase<LemonAction<bool, bool>>)(object)_enableAutoDisable.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)OnConfigChanged, 0, false);
				((MelonEventBase<LemonAction<string, string>>)(object)_minSeverityForDisable.OnEntryValueChanged).Subscribe((LemonAction<string, string>)OnConfigChanged, 0, false);
				((MelonEventBase<LemonAction<string[], string[]>>)(object)_scanDirectories.OnEntryValueChanged).Subscribe((LemonAction<string[], string[]>)OnConfigChanged, 0, false);
				((MelonEventBase<LemonAction<int, int>>)(object)_suspiciousThreshold.OnEntryValueChanged).Subscribe((LemonAction<int, int>)OnConfigChanged, 0, false);
				((MelonEventBase<LemonAction<string[], string[]>>)(object)_whitelistedMods.OnEntryValueChanged).Subscribe((LemonAction<string[], string[]>)OnConfigChanged, 0, false);
				UpdateConfigFromPreferences();
				_logger.Msg("Configuration loaded successfully");
			}
			catch (Exception ex)
			{
				_logger.Error("Failed to initialize config system: " + ex.Message);
				_logger.Msg("Using fallback in-memory configuration");
				Config = new ScanConfig();
			}
		}

		private void OnConfigChanged<T>(T oldValue, T newValue)
		{
			UpdateConfigFromPreferences();
			_logger.Msg("Configuration updated");
		}

		private void UpdateConfigFromPreferences()
		{
			Config = new ScanConfig
			{
				EnableAutoScan = _enableAutoScan.Value,
				EnableAutoDisable = _enableAutoDisable.Value,
				MinSeverityForDisable = _minSeverityForDisable.Value,
				ScanDirectories = _scanDirectories.Value,
				SuspiciousThreshold = _suspiciousThreshold.Value,
				WhitelistedMods = _whitelistedMods.Value
			};
		}

		public void SaveConfig(ScanConfig newConfig)
		{
			try
			{
				_enableAutoScan.Value = newConfig.EnableAutoScan;
				_enableAutoDisable.Value = newConfig.EnableAutoDisable;
				_minSeverityForDisable.Value = newConfig.MinSeverityForDisable;
				_scanDirectories.Value = newConfig.ScanDirectories;
				_suspiciousThreshold.Value = newConfig.SuspiciousThreshold;
				_whitelistedMods.Value = newConfig.WhitelistedMods;
				MelonPreferences.Save();
				_logger.Msg("Configuration saved successfully");
			}
			catch (Exception ex)
			{
				_logger.Error("Error saving configuration: " + ex.Message);
				Config = newConfig;
			}
		}

		public string[] GetWhitelistedMods()
		{
			return _whitelistedMods.Value;
		}

		public void SetWhitelistedMods(string[] mods)
		{
			if (mods != null)
			{
				string[] array = (from m in mods
					where !string.IsNullOrWhiteSpace(m)
					select m.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) ? m : (m + ".dll")).Distinct<string>(StringComparer.OrdinalIgnoreCase).ToArray();
				_whitelistedMods.Value = array;
				MelonPreferences.Save();
				UpdateConfigFromPreferences();
				_logger.Msg($"Updated whitelist with {array.Length} mod(s)");
			}
		}

		public bool IsModWhitelisted(string modFileName)
		{
			if (string.IsNullOrWhiteSpace(modFileName))
			{
				return false;
			}
			if (!modFileName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
			{
				modFileName += ".dll";
			}
			return Config.WhitelistedMods.Contains<string>(modFileName, StringComparer.OrdinalIgnoreCase);
		}
	}
	public class ModDisabler
	{
		private readonly Instance _logger = logger ?? throw new ArgumentNullException("logger");

		private readonly ScanConfig _config = config ?? throw new ArgumentNullException("config");

		private const string DisabledExtension = ".di";

		public ModDisabler(Instance logger, ScanConfig config)
		{
		}

		public List<string> DisableSuspiciousMods(Dictionary<string, List<ScanFinding>> scanResults, bool forceDisable = false)
		{
			if (!forceDisable && !_config.EnableAutoDisable)
			{
				_logger.Msg("Automatic disabling is turned off in configuration");
				return new List<string>();
			}
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, List<ScanFinding>> scanResult in scanResults)
			{
				scanResult.Deconstruct(out var key, out var value);
				string text = key;
				List<ScanFinding> source = value;
				List<ScanFinding> list2 = source.Where((ScanFinding f) => string.Compare(f.Severity, _config.MinSeverityForDisable, StringComparison.OrdinalIgnoreCase) >= 0).ToList();
				if (!forceDisable && list2.Count < _config.SuspiciousThreshold)
				{
					_logger.Msg("Mod " + Path.GetFileName(text) + " has suspicious patterns but below threshold");
					continue;
				}
				try
				{
					string text2 = Path.ChangeExtension(text, ".di");
					if (File.Exists(text2))
					{
						File.Delete(text2);
					}
					File.Move(text, text2);
					_logger.Warning("Disabled potentially malicious mod: " + Path.GetFileName(text));
					list.Add(text);
					foreach (ScanFinding item in list2.Take(3))
					{
						_logger.Warning($"  - {item}");
					}
					if (list2.Count > 3)
					{
						_logger.Warning($"  - And {list2.Count - 3} more suspicious patterns...");
					}
				}
				catch (Exception ex)
				{
					_logger.Error("Failed to disable mod " + Path.GetFileName(text) + ": " + ex.Message);
				}
			}
			return list;
		}
	}
	public class ModScanner
	{
		private readonly AssemblyScanner _assemblyScanner = assemblyScanner ?? throw new ArgumentNullException("assemblyScanner");

		private readonly Instance _logger = logger ?? throw new ArgumentNullException("logger");

		private readonly ScanConfig _config = config ?? throw new ArgumentNullException("config");

		private readonly ConfigManager _configManager = configManager ?? throw new ArgumentNullException("configManager");

		public ModScanner(AssemblyScanner assemblyScanner, Instance logger, ScanConfig config, ConfigManager configManager)
		{
		}

		public Dictionary<string, List<ScanFinding>> ScanAllMods(bool forceScanning = false)
		{
			Dictionary<string, List<ScanFinding>> dictionary = new Dictionary<string, List<ScanFinding>>();
			if (!forceScanning && !_config.EnableAutoScan)
			{
				_logger.Msg("Automatic scanning is disabled in configuration");
				return dictionary;
			}
			string[] scanDirectories = _config.ScanDirectories;
			foreach (string path in scanDirectories)
			{
				string text = Path.Combine(MelonEnvironment.GameRootDirectory, path);
				if (!Directory.Exists(text))
				{
					_logger.Warning("Directory not found: " + text);
				}
				else
				{
					ScanDirectory(text, dictionary);
				}
			}
			ScanThunderstoreModManager(dictionary);
			return dictionary;
		}

		private void ScanDirectory(string directoryPath, Dictionary<string, List<ScanFinding>> results)
		{
			string[] files = Directory.GetFiles(directoryPath, "*.dll", SearchOption.AllDirectories);
			_logger.Msg($"Found {files.Length} potential mod files in {directoryPath}");
			string[] array = files;
			foreach (string text in array)
			{
				try
				{
					string fileName = Path.GetFileName(text);
					if (_configManager.IsModWhitelisted(fileName))
					{
						_logger.Msg("Skipping whitelisted mod: " + fileName);
						continue;
					}
					List<ScanFinding> list = _assemblyScanner.Scan(text).ToList();
					if (list.Count >= _config.SuspiciousThreshold)
					{
						results.Add(text, list);
						_logger.Warning($"Found {list.Count} suspicious patterns in {Path.GetFileName(text)}");
					}
				}
				catch (Exception ex)
				{
					_logger.Error("Error scanning " + Path.GetFileName(text) + ": " + ex.Message);
				}
			}
		}

		private void ScanThunderstoreModManager(Dictionary<string, List<ScanFinding>> results)
		{
			try
			{
				string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
				string path = Path.Combine(folderPath, "Thunderstore Mod Manager", "DataFolder");
				if (!Directory.Exists(path))
				{
					return;
				}
				string[] directories = Directory.GetDirectories(path);
				foreach (string path2 in directories)
				{
					string path3 = Path.Combine(path2, "profiles");
					if (!Directory.Exists(path3))
					{
						continue;
					}
					string[] directories2 = Directory.GetDirectories(path3);
					foreach (string path4 in directories2)
					{
						string text = Path.Combine(path4, "Mods");
						if (Directory.Exists(text))
						{
							_logger.Msg("Scanning Thunderstore profile mods: " + text);
							ScanDirectory(text, results);
						}
						string text2 = Path.Combine(path4, "Plugins");
						if (Directory.Exists(text2))
						{
							_logger.Msg("Scanning Thunderstore profile plugins: " + text2);
							ScanDirectory(text2, results);
						}
					}
				}
			}
			catch (Exception ex)
			{
				_logger.Error("Error scanning Thunderstore Mod Manager directories: " + ex.Message);
			}
		}
	}
	public class PromptGeneratorService
	{
		private readonly ScanConfig _config;

		private readonly Instance _logger;

		public PromptGeneratorService(ScanConfig config, Instance logger)
		{
			_config = config ?? throw new ArgumentNullException("config");
			_logger = logger ?? throw new ArgumentNullException("logger");
		}

		public string GeneratePrompt(string modPath, List<ScanFinding> findings)
		{
			if (findings == null || !findings.Any())
			{
				return "No suspicious findings to analyze.";
			}
			string fileName = Path.GetFileName(modPath);
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("# Mod Security Analysis Request");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("I need to determine if the following mod is malicious or a false positive. Below is a security scan report generated by MLVScan (a security tool for MelonLoader mods).");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("## Mod Information");
			stringBuilder.AppendLine("- **Filename**: " + fileName);
			stringBuilder.AppendLine($"- **Scan Date**: {DateTime.Now}");
			stringBuilder.AppendLine($"- **Total Suspicious Patterns**: {findings.Count}");
			stringBuilder.AppendLine();
			Dictionary<string, int> dictionary = (from f in findings
				group f by f.Severity into g
				orderby GetSeverityRank(g.Key) descending
				select g).ToDictionary((IGrouping<string, ScanFinding> g) => g.Key, (IGrouping<string, ScanFinding> g) => g.Count());
			stringBuilder.AppendLine("## Severity Breakdown");
			foreach (KeyValuePair<string, int> item in dictionary)
			{
				stringBuilder.AppendLine($"- **{FormatSeverityLabel(item.Key)}**: {item.Value} issue(s)");
			}
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("## Detailed Findings");
			Dictionary<string, List<ScanFinding>> dictionary2 = (from f in findings
				group f by f.Description).ToDictionary((IGrouping<string, ScanFinding> g) => g.Key, (IGrouping<string, ScanFinding> g) => g.ToList());
			var (dictionary5, dictionary6) = ExtractCodeBlocks(modPath, findings);
			foreach (KeyValuePair<string, List<ScanFinding>> item2 in dictionary2)
			{
				stringBuilder.AppendLine("### " + item2.Key);
				stringBuilder.AppendLine("- **Severity**: " + item2.Value[0].Severity);
				stringBuilder.AppendLine($"- **Occurrences**: {item2.Value.Count}");
				stringBuilder.AppendLine("- **Locations & Snippets**:");
				foreach (ScanFinding item3 in item2.Value.Take(5))
				{
					stringBuilder.AppendLine("  - **Location**: " + item3.Location);
					if (!string.IsNullOrEmpty(item3.CodeSnippet))
					{
						stringBuilder.AppendLine("    **IL Snippet (Exact location of suspicious call)**:");
						stringBuilder.AppendLine("    ```");
						string[] array = item3.CodeSnippet.Split(new char[2] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
						foreach (string text in array)
						{
							stringBuilder.AppendLine("    " + text);
						}
						stringBuilder.AppendLine("    ```");
					}
					if (dictionary5.TryGetValue(item3.Location, out var value) && !string.IsNullOrWhiteSpace(value))
					{
						stringBuilder.AppendLine("    **Attempted C# Decompilation (Entire Method Context & Type Info)**:");
						stringBuilder.AppendLine("    ```csharp");
						string[] array2 = value.Split(new char[2] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
						foreach (string text2 in array2)
						{
							stringBuilder.AppendLine("    " + text2);
						}
						stringBuilder.AppendLine("    ```");
					}
					if (dictionary6.TryGetValue(item3.Location, out var value2) && !string.IsNullOrWhiteSpace(value2))
					{
						stringBuilder.AppendLine("    **Surrounding Class Structure (Member Signatures Only)**:");
						stringBuilder.AppendLine("    ```csharp");
						string[] array3 = value2.Split(new char[2] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
						foreach (string text3 in array3)
						{
							stringBuilder.AppendLine("    " + text3);
						}
						stringBuilder.AppendLine("    ```");
					}
					stringBuilder.AppendLine();
				}
				if (item2.Value.Count > 5)
				{
					stringBuilder.AppendLine($"  - *And {item2.Value.Count - 5} more occurrences (details omitted for brevity)*");
				}
				stringBuilder.AppendLine();
			}
			string value3 = ExtractAssemblyMetadata(modPath);
			if (!string.IsNullOrEmpty(value3))
			{
				stringBuilder.AppendLine("## Assembly Metadata");
				stringBuilder.AppendLine(value3);
				stringBuilder.AppendLine();
			}
			stringBuilder.AppendLine("## Request");
			stringBuilder.AppendLine("Based on this scan report and code analysis, please help me determine:");
			stringBuilder.AppendLine("1. Is this mod likely to be malicious or is it a false positive?");
			stringBuilder.AppendLine("2. If potentially malicious, what specific security risks does it pose?");
			stringBuilder.AppendLine("3. What is the intent of the suspicious code? Is there a benign explanation?");
			stringBuilder.AppendLine("4. What further actions should I take? (Whitelist it, delete it, report it, etc.)");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("Please explain your reasoning with reference to the specific code patterns and provide context about:");
			stringBuilder.AppendLine("- Whether these patterns are common in legitimate mods or game utilities");
			stringBuilder.AppendLine("- Alternative explanations for the suspicious patterns");
			stringBuilder.AppendLine("- Your confidence level in the assessment");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("Important context: This is a mod for a game using MelonLoader (a mod loading framework). Legitimate mods generally don't need to use system-level APIs like shell execution, registry access, etc.");
			return stringBuilder.ToString();
		}

		private Tuple<Dictionary<string, string>, Dictionary<string, string>> ExtractCodeBlocks(string modPath, List<ScanFinding> findings)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			Dictionary<string, string> dictionary2 = new Dictionary<string, string>();
			try
			{
				if (!File.Exists(modPath))
				{
					return Tuple.Create(dictionary, dictionary2);
				}
				ReaderParameters val = new ReaderParameters
				{
					ReadWrite = false,
					InMemory = true,
					ReadSymbols = false
				};
				AssemblyDefinition val2 = AssemblyDefinition.ReadAssembly(modPath, val);
				try
				{
					Dictionary<string, List<string>> dictionary3 = new Dictionary<string, List<string>>();
					Enumerator<ModuleDefinition> enumerator = val2.Modules.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							ModuleDefinition current = enumerator.Current;
							Enumerator<TypeDefinition> enumerator2 = current.Types.GetEnumerator();
							try
							{
								while (enumerator2.MoveNext())
								{
									TypeDefinition current2 = enumerator2.Current;
									CollectSuspiciousStrings(current2, dictionary3);
								}
							}
							finally
							{
								((IDisposable)enumerator2).Dispose();
							}
						}
					}
					finally
					{
						((IDisposable)enumerator).Dispose();
					}
					if (dictionary3.Any())
					{
						StringBuilder stringBuilder = new StringBuilder();
						stringBuilder.AppendLine("// Notable string literals found in the assembly:");
						stringBuilder.AppendLine();
						foreach (string item in dictionary3.Keys.OrderBy((string k) => k))
						{
							stringBuilder.AppendLine("// Potential " + item + ":");
							foreach (string item2 in dictionary3[item].Take(10))
							{
								stringBuilder.AppendLine("//   \"" + EscapeStringForCode(item2) + "\"");
							}
							if (dictionary3[item].Count > 10)
							{
								stringBuilder.AppendLine($"//   ... and {dictionary3[item].Count - 10} more");
							}
							stringBuilder.AppendLine();
						}
						dictionary["SuspiciousStrings"] = stringBuilder.ToString();
					}
					foreach (ScanFinding finding in findings)
					{
						try
						{
							string location = finding.Location;
							if (location == "Assembly scanning" || !location.Contains("."))
							{
								continue;
							}
							string empty = string.Empty;
							string fullTypeName;
							string methodNameFromFinding;
							if (location.Contains(":"))
							{
								string[] array = location.Split(':');
								string text = array[0];
								empty = array[1];
								int num = text.LastIndexOf('.');
								if (num > 0)
								{
									fullTypeName = text.Substring(0, num);
									methodNameFromFinding = text.Substring(num + 1);
									goto IL_032f;
								}
							}
							else
							{
								int num2 = location.LastIndexOf('.');
								if (num2 > 0)
								{
									fullTypeName = location.Substring(0, num2);
									methodNameFromFinding = location.Substring(num2 + 1);
									goto IL_032f;
								}
							}
							goto end_IL_0244;
							IL_032f:
							TypeDefinition val3 = FindType(val2.MainModule, fullTypeName);
							if (val3 == null)
							{
								continue;
							}
							if (!dictionary2.ContainsKey(finding.Location) || dictionary2[finding.Location] == string.Empty)
							{
								dictionary2[finding.Location] = GenerateClassStructure(val3, methodNameFromFinding);
							}
							MethodDefinition val4 = ((IEnumerable<MethodDefinition>)val3.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == methodNameFromFinding));
							if (val4 == null)
							{
								if (!dictionary.ContainsKey(finding.Location))
								{
									dictionary[finding.Location] = "// DllImport or external method: " + finding.Location + ". Primary context is the IL snippet and class structure.";
								}
								continue;
							}
							if (!val4.HasBody && !val4.IsAbstract)
							{
								if (!dictionary.ContainsKey(finding.Location))
								{
									dictionary[finding.Location] = "// Method " + methodNameFromFinding + " has no body or is abstract.";
								}
								continue;
							}
							string text2 = DecompileMethod(val4);
							if (string.IsNullOrEmpty(text2))
							{
								continue;
							}
							StringBuilder stringBuilder2 = new StringBuilder();
							stringBuilder2.AppendLine("// Context: Method is part of " + ((MemberReference)val3).FullName);
							if (val3.HasCustomAttributes)
							{
								stringBuilder2.AppendLine("// Type attributes:");
								foreach (CustomAttribute item3 in ((IEnumerable<CustomAttribute>)val3.CustomAttributes).Take(5))
								{
									stringBuilder2.AppendLine("// - " + ((MemberReference)item3.AttributeType).Name);
								}
								if (val3.CustomAttributes.Count > 5)
								{
									stringBuilder2.AppendLine($"// - ...and {val3.CustomAttributes.Count - 5} more");
								}
							}
							if (val3.BaseType != null && ((MemberReference)val3.BaseType).FullName != "System.Object")
							{
								stringBuilder2.AppendLine("// Inherits from: " + ((MemberReference)val3.BaseType).FullName);
							}
							List<MethodDefinition> list = FindRelatedSuspiciousMethods(val3, val4);
							if (list.Any())
							{
								stringBuilder2.AppendLine("// Other suspicious methods in this class (names only):");
								foreach (MethodDefinition item4 in list.Take(3))
								{
									stringBuilder2.AppendLine("// - " + ((MemberReference)item4).Name);
								}
								if (list.Count > 3)
								{
									stringBuilder2.AppendLine($"// - ...and {list.Count - 3} more");
								}
							}
							stringBuilder2.AppendLine();
							stringBuilder2.AppendLine("// Finding Description: " + finding.Description);
							stringBuilder2.AppendLine("// Severity: " + finding.Severity);
							stringBuilder2.AppendLine();
							dictionary[finding.Location] = stringBuilder2.ToString() + text2;
							end_IL_0244:;
						}
						catch (Exception ex)
						{
							_logger.Error("Failed to extract code for " + finding.Location + ": " + ex.Message);
							dictionary[finding.Location] = "// Error extracting detailed code for " + finding.Location + ": " + ex.Message;
						}
					}
					if (((IEnumerable<Resource>)val2.MainModule.Resources).Any())
					{
						StringBuilder stringBuilder3 = new StringBuilder();
						stringBuilder3.AppendLine("// Assembly Resources (could contain hidden payloads):");
						foreach (Resource item5 in ((IEnumerable<Resource>)val2.MainModule.Resources).Take(20))
						{
							stringBuilder3.AppendLine("//   " + item5.Name + " - " + GetResourceTypeName(item5));
						}
						if (val2.MainModule.Resources.Count > 20)
						{
							stringBuilder3.AppendLine($"//   ...and {val2.MainModule.Resources.Count - 20} more resources");
						}
						dictionary["Assembly.Resources"] = stringBuilder3.ToString();
					}
				}
				finally
				{
					((IDisposable)val2)?.Dispose();
				}
			}
			catch (Exception ex2)
			{
				_logger.Error("Failed to extract code blocks from " + modPath + ": " + ex2.Message);
			}
			return Tuple.Create(dictionary, dictionary2);
		}

		private void CollectSuspiciousStrings(TypeDefinition type, Dictionary<string, List<string>> suspiciousStrings)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<MethodDefinition> enumerator = type.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current = enumerator.Current;
					if (!current.HasBody)
					{
						continue;
					}
					Enumerator<Instruction> enumerator2 = current.Body.Instructions.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							Instruction current2 = enumerator2.Current;
							OpCode opCode = current2.OpCode;
							if (((OpCode)(ref opCode)).Name == "ldstr" && current2.Operand is string text && IsSuspiciousString(text, out var category))
							{
								if (!suspiciousStrings.ContainsKey(category))
								{
									suspiciousStrings[category] = new List<string>();
								}
								if (!suspiciousStrings[category].Contains(text))
								{
									suspiciousStrings[category].Add(text);
								}
							}
						}
					}
					finally
					{
						((IDisposable)enumerator2).Dispose();
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			Enumerator<TypeDefinition> enumerator3 = type.NestedTypes.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					TypeDefinition current3 = enumerator3.Current;
					CollectSuspiciousStrings(current3, suspiciousStrings);
				}
			}
			finally
			{
				((IDisposable)enumerator3).Dispose();
			}
		}

		private bool IsSuspiciousString(string value, out string category)
		{
			if (string.IsNullOrEmpty(value))
			{
				category = string.Empty;
				return false;
			}
			if (value.Length > 20 && IsLikelyBase64(value))
			{
				category = "Base64 encoded data";
				return true;
			}
			if (value.StartsWith("http://") || value.StartsWith("https://") || value.StartsWith("ftp://") || value.StartsWith("ws://"))
			{
				category = "URL";
				return true;
			}
			if (value.Contains(".exe") || value.Contains(".dll") || value.Contains(".bat") || value.Contains(".cmd") || value.Contains(".ps1") || value.Contains(".vbs"))
			{
				category = "executable file reference";
				return true;
			}
			if (IsLikelyIPAddress(value))
			{
				category = "IP address";
				return true;
			}
			if (value.StartsWith("HKEY_") || value.Contains("\\Software\\") || value.Contains("\\Microsoft\\") || value.Contains("\\System\\"))
			{
				category = "registry path";
				return true;
			}
			if (value.StartsWith("cmd ") || value.StartsWith("powershell ") || value.Contains(" /c ") || value.Contains(" /k "))
			{
				category = "command line";
				return true;
			}
			if (value.Contains("encrypt") || value.Contains("decrypt") || value.Contains("aes") || value.Contains("rsa") || value.Contains("md5") || value.Contains("sha") || value.Contains("hash"))
			{
				category = "cryptographic reference";
				return true;
			}
			if ((value.Contains(".") && !value.Contains(" ") && !value.Contains("\\") && !value.EndsWith(".cs") && !value.EndsWith(".txt") && value.Length > 5) || value.Contains("pastebin") || value.Contains("discord") || value.Contains("webhook"))
			{
				category = "domain or web service";
				return true;
			}
			category = string.Empty;
			return false;
		}

		private bool IsLikelyBase64(string value)
		{
			if (value.Length % 4 != 0)
			{
				return false;
			}
			foreach (char c2 in value)
			{
				if ((c2 < 'A' || c2 > 'Z') && (c2 < 'a' || c2 > 'z') && (c2 < '0' || c2 > '9') && c2 != '+' && c2 != '/' && c2 != '=')
				{
					return false;
				}
			}
			return value.Length > 20 && value.Any((char c) => c >= 'A' && c <= 'Z') && value.Any((char c) => c >= 'a' && c <= 'z') && value.Any((char c) => c >= '0' && c <= '9');
		}

		private bool IsLikelyIPAddress(string value)
		{
			string pattern = "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}";
			string pattern2 = "^[0-9a-fA-F:]+";
			return Regex.IsMatch(value, pattern) || Regex.IsMatch(value, pattern2);
		}

		private string GetResourceTypeName(Resource resource)
		{
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			EmbeddedResource val = (EmbeddedResource)(object)((resource is EmbeddedResource) ? resource : null);
			if (val != null)
			{
				using (Stream stream = val.GetResourceStream())
				{
					if (stream.Length > 0)
					{
						byte[] array = new byte[Math.Min(stream.Length, 16L)];
						stream.Read(array, 0, array.Length);
						if (array.Length >= 2 && array[0] == 77 && array[1] == 90)
						{
							return "PE File/DLL (MZ header)";
						}
						if (array.Length >= 4 && array[0] == 127 && array[1] == 69 && array[2] == 76 && array[3] == 70)
						{
							return "ELF Binary";
						}
						if (array.Length >= 4 && array[0] == 80 && array[1] == 75 && array[2] == 3 && array[3] == 4)
						{
							return "ZIP Archive";
						}
						if (array.Length >= 2 && array[0] == byte.MaxValue && array[1] == 216)
						{
							return "JPEG Image";
						}
						if (array.Length >= 3 && array[0] == 71 && array[1] == 73 && array[2] == 70)
						{
							return "GIF Image";
						}
						if (array.Length >= 4 && ((array[0] == 137 && array[1] == 80 && array[2] == 78 && array[3] == 71) || (array[0] == 66 && array[1] == 77)))
						{
							return "PNG or BMP Image";
						}
						return $"Binary data ({stream.Length} bytes)";
					}
					return "Empty resource";
				}
			}
			ResourceType resourceType = resource.ResourceType;
			return ((object)(ResourceType)(ref resourceType)).ToString();
		}

		private List<MethodDefinition> FindRelatedSuspiciousMethods(TypeDefinition type, MethodDefinition currentMethod)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			List<MethodDefinition> list = new List<MethodDefinition>();
			Enumerator<MethodDefinition> enumerator = type.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current = enumerator.Current;
					if (current == currentMethod || !current.HasBody)
					{
						continue;
					}
					Enumerator<Instruction> enumerator2 = current.Body.Instructions.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							Instruction current2 = enumerator2.Current;
							OpCode opCode = current2.OpCode;
							if (!(((OpCode)(ref opCode)).Name == "call"))
							{
								opCode = current2.OpCode;
								if (!(((OpCode)(ref opCode)).Name == "callvirt"))
								{
									opCode = current2.OpCode;
									if (!(((OpCode)(ref opCode)).Name == "newobj"))
									{
										continue;
									}
								}
							}
							object operand = current2.Operand;
							MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
							if (val != null && IsSuspiciousMethodCall(val))
							{
								list.Add(current);
								break;
							}
						}
					}
					finally
					{
						((IDisposable)enumerator2).Dispose();
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return list;
		}

		private TypeDefinition FindType(ModuleDefinition module, string fullTypeName)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<TypeDefinition> enumerator = module.Types.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current = enumerator.Current;
					if (((MemberReference)current).FullName == fullTypeName)
					{
						return current;
					}
					TypeDefinition val = FindNestedType(current, fullTypeName);
					if (val != null)
					{
						return val;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return null;
		}

		private TypeDefinition FindNestedType(TypeDefinition parentType, string fullTypeName)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<TypeDefinition> enumerator = parentType.NestedTypes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current = enumerator.Current;
					if (((MemberReference)current).FullName == fullTypeName)
					{
						return current;
					}
					TypeDefinition val = FindNestedType(current, fullTypeName);
					if (val != null)
					{
						return val;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return null;
		}

		private string DecompileMethod(MethodDefinition method)
		{
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			if (!method.HasBody)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine(GetMethodVisibility(method) + " " + ((MemberReference)((MethodReference)method).ReturnType).Name + " " + ((MemberReference)method).Name + "(" + GetMethodParameters(method) + ")");
			stringBuilder.AppendLine("{");
			string value = ReconstructCode(method);
			if (!string.IsNullOrEmpty(value))
			{
				stringBuilder.AppendLine(value);
			}
			else
			{
				stringBuilder.AppendLine("    // Method body:");
				List<ExceptionHandler> source = ((IEnumerable<ExceptionHandler>)method.Body.ExceptionHandlers).ToList();
				HashSet<int> hashSet = source.Select((ExceptionHandler h) => h.HandlerStart.Offset).ToHashSet();
				HashSet<int> hashSet2 = source.Select(delegate(ExceptionHandler h)
				{
					Instruction handlerEnd = h.HandlerEnd;
					return (handlerEnd != null) ? handlerEnd.Offset : int.MaxValue;
				}).ToHashSet();
				HashSet<int> hashSet3 = source.Select((ExceptionHandler h) => h.TryStart.Offset).ToHashSet();
				HashSet<int> hashSet4 = source.Select(delegate(ExceptionHandler h)
				{
					Instruction tryEnd = h.TryEnd;
					return (tryEnd != null) ? tryEnd.Offset : int.MaxValue;
				}).ToHashSet();
				bool flag = false;
				bool flag2 = false;
				List<VariableDefinition> variables = ((IEnumerable<VariableDefinition>)method.Body.Variables).ToList();
				List<ParameterDefinition> parameters = ((IEnumerable<ParameterDefinition>)((MethodReference)method).Parameters).ToList();
				List<Instruction> list = ((IEnumerable<Instruction>)method.Body.Instructions).ToList();
				for (int i = 0; i < list.Count; i++)
				{
					Instruction instruction = list[i];
					if (hashSet3.Contains(instruction.Offset) && !flag)
					{
						stringBuilder.AppendLine("    try {");
						flag = true;
					}
					if (hashSet.Contains(instruction.Offset) && !flag2)
					{
						ExceptionHandler val = ((IEnumerable<ExceptionHandler>)source).FirstOrDefault((Func<ExceptionHandler, bool>)((ExceptionHandler h) => h.HandlerStart.Offset == instruction.Offset));
						object obj;
						if (val == null)
						{
							obj = null;
						}
						else
						{
							TypeReference catchType = val.CatchType;
							obj = ((catchType != null) ? ((MemberReference)catchType).Name : null);
						}
						if (obj == null)
						{
							obj = "Exception";
						}
						stringBuilder.AppendLine("    } catch (" + (string?)obj + ") {");
						flag = false;
						flag2 = true;
					}
					if ((hashSet4.Contains(instruction.Offset) && flag) || (hashSet2.Contains(instruction.Offset) && flag2))
					{
						stringBuilder.AppendLine("    }");
						flag = false;
						flag2 = false;
					}
					string text = FormatInstructionWithContext(instruction, i, list, variables, parameters);
					if (!string.IsNullOrEmpty(text))
					{
						string text2 = "    ";
						if (flag || flag2)
						{
							text2 += "    ";
						}
						stringBuilder.AppendLine(text2 + text);
					}
				}
				if (flag || flag2)
				{
					stringBuilder.AppendLine("    }");
				}
			}
			if (((MethodReference)method).Parameters.Count > 0)
			{
				stringBuilder.AppendLine();
				stringBuilder.AppendLine("    // Method parameters:");
				Enumerator<ParameterDefinition> enumerator = ((MethodReference)method).Parameters.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						ParameterDefinition current = enumerator.Current;
						stringBuilder.AppendLine("    // " + ((MemberReference)((ParameterReference)current).ParameterType).FullName + " " + ((ParameterReference)current).Name);
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}
			if (method.Body.Variables.Count > 0)
			{
				stringBuilder.AppendLine();
				stringBuilder.AppendLine("    // Local variables:");
				Enumerator<VariableDefinition> enumerator2 = method.Body.Variables.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						VariableDefinition current2 = enumerator2.Current;
						stringBuilder.AppendLine($"    // {((MemberReference)((VariableReference)current2).VariableType).FullName} var_{((VariableReference)current2).Index}");
					}
				}
				finally
				{
					((IDisposable)enumerator2).Dispose();
				}
			}
			List<string> list2 = FindSuspiciousApiCalls(method);
			if (list2.Any())
			{
				stringBuilder.AppendLine();
				stringBuilder.AppendLine("    // Suspicious API calls:");
				foreach (string item in list2)
				{
					stringBuilder.AppendLine("    // " + item);
				}
			}
			stringBuilder.AppendLine("}");
			return stringBuilder.ToString();
		}

		private string ReconstructCode(MethodDefinition method)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			try
			{
				List<Instruction> list = ((IEnumerable<Instruction>)method.Body.Instructions).ToList();
				for (int i = 0; i < list.Count; i++)
				{
					Instruction val = list[i];
					OpCode opCode = val.OpCode;
					if (!(((OpCode)(ref opCode)).Name == "call"))
					{
						opCode = val.OpCode;
						if (!(((OpCode)(ref opCode)).Name == "callvirt"))
						{
							opCode = val.OpCode;
							if (((OpCode)(ref opCode)).Name == "newobj")
							{
								object operand = val.Operand;
								MethodReference val2 = (MethodReference)((operand is MethodReference) ? operand : null);
								if (val2 != null)
								{
									stringBuilder.AppendLine("    new " + ((MemberReference)((MemberReference)val2).DeclaringType).Name + "(...);");
									continue;
								}
							}
							opCode = val.OpCode;
							if (((OpCode)(ref opCode)).Name == "ldstr" && val.Operand is string value)
							{
								stringBuilder.AppendLine("    // String: \"" + EscapeStringForCode(value) + "\"");
							}
							continue;
						}
					}
					object operand2 = val.Operand;
					MethodReference val3 = (MethodReference)((operand2 is MethodReference) ? operand2 : null);
					if (val3 != null)
					{
						string methodCallRepresentation = GetMethodCallRepresentation(val3, list, i);
						if (!string.IsNullOrEmpty(methodCallRepresentation))
						{
							stringBuilder.AppendLine("    " + methodCallRepresentation + ";");
						}
					}
				}
				if (stringBuilder.Length == 0)
				{
					return string.Empty;
				}
				return stringBuilder.ToString();
			}
			catch
			{
				return string.Empty;
			}
		}

		private string EscapeStringForCode(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return value;
			}
			return value.Replace("\"", "\\\"").Replace("\r", "\\r").Replace("\n", "\\n")
				.Replace("\t", "\\t");
		}

		private string GetMethodCallRepresentation(MethodReference methodRef, List<Instruction> instructions, int currentIndex)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			string name = ((MemberReference)methodRef).Name;
			string name2 = ((MemberReference)((MemberReference)methodRef).DeclaringType).Name;
			if (name.Contains("Process") && name.Contains("Start"))
			{
				return "System.Diagnostics.Process.Start(...) // Executes external process";
			}
			if (name.Contains("Load") && name2.Contains("Assembly"))
			{
				return "Assembly." + name + "(...) // Dynamically loads code";
			}
			if ((name.Contains("FromBase64") || name.Contains("GetString")) && name2.Contains("Convert"))
			{
				string text = "...";
				for (int num = currentIndex - 1; num >= Math.Max(0, currentIndex - 5); num--)
				{
					OpCode opCode = instructions[num].OpCode;
					if (((OpCode)(ref opCode)).Name == "ldstr" && instructions[num].Operand is string)
					{
						text = instructions[num].Operand.ToString();
						if (text.Length > 20)
						{
							text = text.Substring(0, 17) + "...";
						}
						break;
					}
				}
				return "Convert." + name + "(\"" + text + "\") // Decodes Base64 data";
			}
			if (name.Contains("RegOpenKey") || name.Contains("RegCreateKey") || (name.Contains("Registry") && (name.Contains("Get") || name.Contains("Set"))))
			{
				return name2 + "." + name + "(...) // Registry manipulation";
			}
			if (name.Contains("CreateFile") || name.Contains("WriteFile") || name.Contains("ReadFile"))
			{
				return name2 + "." + name + "(...) // File system operation";
			}
			if (name.Contains("Socket") || name.Contains("Connect") || name.Contains("Send") || name.Contains("Receive"))
			{
				return name2 + "." + name + "(...) // Network communication";
			}
			return name2 + "." + name + "(...)";
		}

		private string FormatInstructionWithContext(Instruction instruction, int index, List<Instruction> allInstructions, List<VariableDefinition> variables, List<ParameterDefinition> parameters)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			OpCode opCode = instruction.OpCode;
			string name = ((OpCode)(ref opCode)).Name;
			if (name == "nop")
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append($"/* {instruction.Offset:X4} */ ");
			object operand = instruction.Operand;
			MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
			if (val != null)
			{
				stringBuilder.Append(name + " " + ((MemberReference)((MemberReference)val).DeclaringType).FullName + "." + ((MemberReference)val).Name + "()");
				if (val.Parameters.Count > 0)
				{
					stringBuilder.Append(" // Takes: " + string.Join(", ", ((IEnumerable<ParameterDefinition>)val.Parameters).Select((ParameterDefinition p) => ((MemberReference)((ParameterReference)p).ParameterType).Name)));
				}
				if (IsSuspiciousMethodCall(val))
				{
					stringBuilder.Append(" // SUSPICIOUS: " + GetSuspiciousMethodDescription(val));
				}
			}
			else
			{
				object operand2 = instruction.Operand;
				TypeReference val2 = (TypeReference)((operand2 is TypeReference) ? operand2 : null);
				if (val2 != null)
				{
					stringBuilder.Append(name + " " + ((MemberReference)val2).FullName);
				}
				else
				{
					object operand3 = instruction.Operand;
					FieldReference val3 = (FieldReference)((operand3 is FieldReference) ? operand3 : null);
					if (val3 != null)
					{
						stringBuilder.Append(name + " " + ((MemberReference)((MemberReference)val3).DeclaringType).Name + "." + ((MemberReference)val3).Name);
					}
					else
					{
						object operand4 = instruction.Operand;
						VariableDefinition val4 = (VariableDefinition)((operand4 is VariableDefinition) ? operand4 : null);
						if (val4 != null)
						{
							string name2 = ((MemberReference)((VariableReference)val4).VariableType).Name;
							stringBuilder.Append($"{name} V_{((VariableReference)val4).Index} /* {name2} */");
						}
						else
						{
							object operand5 = instruction.Operand;
							ParameterDefinition val5 = (ParameterDefinition)((operand5 is ParameterDefinition) ? operand5 : null);
							if (val5 != null)
							{
								string name3 = ((MemberReference)((ParameterReference)val5).ParameterType).Name;
								stringBuilder.Append(name + " " + ((ParameterReference)val5).Name + " /* " + name3 + " */");
							}
							else if (instruction.Operand is string text)
							{
								string text2 = text;
								if (text2.Length > 50)
								{
									text2 = text2.Substring(0, 47) + "...";
								}
								stringBuilder.Append(name + " \"" + EscapeStringForCode(text2) + "\"");
							}
							else
							{
								object operand6 = instruction.Operand;
								Instruction val6 = (Instruction)((operand6 is Instruction) ? operand6 : null);
								if (val6 != null)
								{
									stringBuilder.Append($"{name} IL_{val6.Offset:X4}");
								}
								else
								{
									string text3 = instruction.Operand?.ToString() ?? string.Empty;
									stringBuilder.Append(name + " " + text3);
								}
							}
						}
					}
				}
			}
			return stringBuilder.ToString();
		}

		private bool IsSuspiciousMethodCall(MethodReference methodRef)
		{
			string fullName = ((MemberReference)((MemberReference)methodRef).DeclaringType).FullName;
			string name = ((MemberReference)methodRef).Name;
			return (fullName.Contains("Process") && name.Contains("Start")) || (fullName.Contains("Assembly") && (name.Contains("Load") || name.Contains("LoadFrom") || name.Contains("LoadFile"))) || (fullName.Contains("Convert") && name.Contains("FromBase64")) || ((fullName.Contains("Registry") || name.Contains("Reg")) && (name.Contains("CreateKey") || name.Contains("OpenKey") || name.Contains("SetValue") || name.Contains("GetValue"))) || fullName.Contains("Shell32") || name.Contains("ShellExecute") || ((fullName.Contains("Socket") || fullName.Contains("Http") || fullName.Contains("Tcp") || fullName.Contains("Web") || fullName.Contains("Net")) && (name.Contains("Connect") || name.Contains("Send") || name.Contains("Download") || name.Contains("Upload")));
		}

		private string GetSuspiciousMethodDescription(MethodReference methodRef)
		{
			string fullName = ((MemberReference)((MemberReference)methodRef).DeclaringType).FullName;
			string name = ((MemberReference)methodRef).Name;
			if (fullName.Contains("Process") && name.Contains("Start"))
			{
				return "Executes external programs";
			}
			if (fullName.Contains("Assembly") && (name.Contains("Load") || name.Contains("LoadFrom") || name.Contains("LoadFile")))
			{
				return "Dynamically loads code which could be malicious";
			}
			if (fullName.Contains("Convert") && name.Contains("FromBase64"))
			{
				return "Decodes potentially obfuscated data";
			}
			if ((fullName.Contains("Registry") || name.Contains("Reg")) && (name.Contains("CreateKey") || name.Contains("OpenKey") || name.Contains("SetValue") || name.Contains("GetValue")))
			{
				return "Manipulates system registry which can persist malware";
			}
			if (fullName.Contains("Shell32") || name.Contains("ShellExecute"))
			{
				return "Executes system commands";
			}
			if ((fullName.Contains("Socket") || fullName.Contains("Http") || fullName.Contains("Tcp") || fullName.Contains("Web") || fullName.Contains("Net")) && (name.Contains("Connect") || name.Contains("Send") || name.Contains("Download") || name.Contains("Upload")))
			{
				return "Performs network operations that could exfiltrate data or download malware";
			}
			return "Potentially suspicious behavior";
		}

		private List<string> FindSuspiciousApiCalls(MethodDefinition method)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			Enumerator<Instruction> enumerator = method.Body.Instructions.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Instruction current = enumerator.Current;
					OpCode opCode = current.OpCode;
					if (!(((OpCode)(ref opCode)).Name == "call"))
					{
						opCode = current.OpCode;
						if (!(((OpCode)(ref opCode)).Name == "callvirt"))
						{
							opCode = current.OpCode;
							if (!(((OpCode)(ref opCode)).Name == "newobj"))
							{
								continue;
							}
						}
					}
					object operand = current.Operand;
					MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
					if (val != null && IsSuspiciousMethodCall(val))
					{
						list.Add(((MemberReference)((MemberReference)val).DeclaringType).FullName + "." + ((MemberReference)val).Name + "() - " + GetSuspiciousMethodDescription(val));
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return list.Distinct().ToList();
		}

		private string GetFieldVisibility(FieldDefinition field)
		{
			if (field.IsPublic)
			{
				return "public";
			}
			if (field.IsPrivate)
			{
				return "private";
			}
			if (field.IsFamily)
			{
				return "protected";
			}
			if (field.IsFamilyOrAssembly)
			{
				return "protected internal";
			}
			if (field.IsAssembly)
			{
				return "internal";
			}
			return "private";
		}

		private string GetPropertyVisibility(PropertyDefinition prop)
		{
			MethodDefinition getMethod = prop.GetMethod;
			MethodDefinition setMethod = prop.SetMethod;
			if ((getMethod != null && getMethod.IsPublic) || (setMethod != null && setMethod.IsPublic))
			{
				return "public";
			}
			if ((getMethod != null && getMethod.IsFamilyOrAssembly) || (setMethod != null && setMethod.IsFamilyOrAssembly))
			{
				return "protected internal";
			}
			if ((getMethod != null && getMethod.IsFamily) || (setMethod != null && setMethod.IsFamily))
			{
				return "protected";
			}
			if ((getMethod != null && getMethod.IsAssembly) || (setMethod != null && setMethod.IsAssembly))
			{
				return "internal";
			}
			if ((getMethod != null && getMethod.IsPrivate) || (setMethod != null && setMethod.IsPrivate))
			{
				return "private";
			}
			if (getMethod == null && setMethod == null)
			{
				return "public";
			}
			return "public";
		}

		private string GenerateClassStructure(TypeDefinition typeDef, string highlightMethodName = null)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if (typeDef == null)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("// Class Outline: " + ((MemberReference)typeDef).FullName);
			if (typeDef.BaseType != null && ((MemberReference)typeDef.BaseType).FullName != "System.Object")
			{
				stringBuilder.AppendLine("// Inherits from: " + ((MemberReference)typeDef.BaseType).FullName);
			}
			if (typeDef.HasInterfaces)
			{
				Enumerator<InterfaceImplementation> enumerator = typeDef.Interfaces.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						InterfaceImplementation current = enumerator.Current;
						stringBuilder.AppendLine("// Implements: " + ((MemberReference)current.InterfaceType).FullName);
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}
			string text = "class";
			if (typeDef.IsInterface)
			{
				text = "interface";
			}
			else if (typeDef.IsEnum)
			{
				text = "enum";
			}
			else if (((TypeReference)typeDef).IsValueType)
			{
				text = "struct";
			}
			stringBuilder.AppendLine("public " + text + " " + ((MemberReference)typeDef).Name + " // Simplified declaration");
			stringBuilder.AppendLine("{");
			List<FieldDefinition> list = ((IEnumerable<FieldDefinition>)typeDef.Fields).ToList();
			if (list.Any())
			{
				stringBuilder.AppendLine("  // Fields");
				foreach (FieldDefinition item in list.Take(10))
				{
					stringBuilder.AppendLine("  " + GetFieldVisibility(item) + " " + (item.IsStatic ? "static " : "") + ((MemberReference)((FieldReference)item).FieldType).Name + " " + ((MemberReference)item).Name + ";");
				}
				if (list.Count > 10)
				{
					stringBuilder.AppendLine($"  // ... and {list.Count - 10} more fields");
				}
				stringBuilder.AppendLine();
			}
			List<PropertyDefinition> list2 = ((IEnumerable<PropertyDefinition>)typeDef.Properties).ToList();
			if (list2.Any())
			{
				stringBuilder.AppendLine("  // Properties");
				foreach (PropertyDefinition item2 in list2.Take(10))
				{
					string text2 = "{ ";
					if (item2.GetMethod != null)
					{
						text2 += "get; ";
					}
					if (item2.SetMethod != null)
					{
						text2 += "set; ";
					}
					text2 += "}";
					MethodDefinition getMethod = item2.GetMethod;
					int num;
					if (getMethod == null || !getMethod.IsStatic)
					{
						MethodDefinition setMethod = item2.SetMethod;
						num = ((setMethod != null && setMethod.IsStatic) ? 1 : 0);
					}
					else
					{
						num = 1;
					}
					bool flag = (byte)num != 0;
					stringBuilder.AppendLine("  " + GetPropertyVisibility(item2) + " " + (flag ? "static " : "") + ((MemberReference)((PropertyReference)item2).PropertyType).Name + " " + ((MemberReference)item2).Name + " " + text2);
				}
				if (list2.Count > 10)
				{
					stringBuilder.AppendLine($"  // ... and {list2.Count - 10} more properties");
				}
				stringBuilder.AppendLine();
			}
			List<MethodDefinition> list3 = ((IEnumerable<MethodDefinition>)typeDef.Methods).Where((MethodDefinition m) => !m.IsConstructor && !m.IsSpecialName).ToList();
			if (list3.Any())
			{
				stringBuilder.AppendLine("  // Methods (signatures only, excluding constructors/property accessors)");
				foreach (MethodDefinition item3 in list3.Take(15))
				{
					string text3 = ((highlightMethodName != null && ((MemberReference)item3).Name == highlightMethodName) ? " // <<< Method with finding" : "");
					stringBuilder.AppendLine("  " + GetMethodVisibility(item3) + " " + (item3.IsStatic ? "static " : "") + ((MemberReference)((MethodReference)item3).ReturnType).Name + " " + ((MemberReference)item3).Name + "(" + GetMethodParameters(item3) + ");" + text3);
				}
				if (list3.Count > 15)
				{
					stringBuilder.AppendLine($"  // ... and {list3.Count - 15} more methods");
				}
			}
			stringBuilder.AppendLine("}");
			return stringBuilder.ToString();
		}

		private string GetMethodVisibility(MethodDefinition method)
		{
			if (method.IsPublic)
			{
				return "public";
			}
			if (method.IsPrivate)
			{
				return "private";
			}
			if (method.IsFamily)
			{
				return "protected";
			}
			if (method.IsFamilyOrAssembly)
			{
				return "protected internal";
			}
			return "internal";
		}

		private string GetMethodParameters(MethodDefinition method)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			Enumerator<ParameterDefinition> enumerator = ((MethodReference)method).Parameters.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ParameterDefinition current = enumerator.Current;
					list.Add(((MemberReference)((ParameterReference)current).ParameterType).Name + " " + ((ParameterReference)current).Name);
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			return string.Join(", ", list);
		}

		private string FormatInstruction(Instruction instruction)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			OpCode opCode = instruction.OpCode;
			string name = ((OpCode)(ref opCode)).Name;
			if (name == "nop")
			{
				return string.Empty;
			}
			string text = FormatOperand(instruction.Operand);
			return (name + " " + text).Trim();
		}

		private string FormatOperand(object operand)
		{
			if (operand == null)
			{
				return string.Empty;
			}
			MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
			if (val != null)
			{
				return ((MemberReference)((MemberReference)val).DeclaringType).Name + "." + ((MemberReference)val).Name + "()";
			}
			TypeReference val2 = (TypeReference)((operand is TypeReference) ? operand : null);
			if (val2 != null)
			{
				return ((MemberReference)val2).FullName;
			}
			FieldReference val3 = (FieldReference)((operand is FieldReference) ? operand : null);
			if (val3 != null)
			{
				return ((MemberReference)((MemberReference)val3).DeclaringType).Name + "." + ((MemberReference)val3).Name;
			}
			if (operand is string text)
			{
				return "\"" + text + "\"";
			}
			return operand.ToString();
		}

		private string ExtractAssemblyMetadata(string modPath)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			try
			{
				if (!File.Exists(modPath))
				{
					return string.Empty;
				}
				StringBuilder stringBuilder = new StringBuilder();
				ReaderParameters val = new ReaderParameters
				{
					ReadWrite = false,
					InMemory = true,
					ReadSymbols = false
				};
				AssemblyDefinition val2 = AssemblyDefinition.ReadAssembly(modPath, val);
				try
				{
					stringBuilder.AppendLine("- **Assembly Name**: " + ((AssemblyNameReference)val2.Name).Name);
					stringBuilder.AppendLine($"- **Version**: {((AssemblyNameReference)val2.Name).Version}");
					if (!string.IsNullOrEmpty(((AssemblyNameReference)val2.Name).Culture))
					{
						stringBuilder.AppendLine("- **Culture**: " + ((AssemblyNameReference)val2.Name).Culture);
					}
					stringBuilder.AppendLine("- **Referenced Assemblies**:");
					foreach (AssemblyNameReference item in ((IEnumerable<AssemblyNameReference>)val2.MainModule.AssemblyReferences).Take(10))
					{
						stringBuilder.AppendLine($"  - {item.Name} (v{item.Version})");
					}
					if (val2.MainModule.AssemblyReferences.Count > 10)
					{
						stringBuilder.AppendLine($"  - *and {val2.MainModule.AssemblyReferences.Count - 10} more...*");
					}
					List<CustomAttribute> list = ((IEnumerable<CustomAttribute>)val2.CustomAttributes).Where((CustomAttribute attr) => ((MemberReference)attr.AttributeType).Name.Contains("Security") || ((MemberReference)attr.AttributeType).Name.Contains("Permission") || ((MemberReference)attr.AttributeType).Name.Contains("Unsafe")).ToList();
					if (list.Any())
					{
						stringBuilder.AppendLine("- **Security-Related Attributes**:");
						foreach (CustomAttribute item2 in list)
						{
							stringBuilder.AppendLine("  - " + ((MemberReference)item2.AttributeType).Name);
						}
					}
					return stringBuilder.ToString();
				}
				finally
				{
					((IDisposable)val2)?.Dispose();
				}
			}
			catch (Exception ex)
			{
				_logger.Error("Failed to extract assembly metadata from " + modPath + ": " + ex.Message);
				return string.Empty;
			}
		}

		public bool SavePromptToFile(string modPath, List<ScanFinding> findings, string outputDirectory)
		{
			try
			{
				string contents = GeneratePrompt(modPath, findings);
				string fileName = Path.GetFileName(modPath);
				Directory.CreateDirectory(outputDirectory);
				string path = Path.Combine(outputDirectory, fileName + ".prompt.md");
				File.WriteAllText(path, contents);
				return true;
			}
			catch (Exception ex)
			{
				_logger.Error("Failed to save prompt to file: " + ex.Message);
				return false;
			}
		}

		private static int GetSeverityRank(string severity)
		{
			string text = severity.ToLower();
			if (1 == 0)
			{
			}
			int result = text switch
			{
				"critical" => 4, 
				"high" => 3, 
				"medium" => 2, 
				"low" => 1, 
				_ => 0, 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		private static string FormatSeverityLabel(stri