Laden...

manuelles Laden von Assemblies

Erstellt von mogel vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.050 Views
mogel Themenstarter:in
156 Beiträge seit 2010
vor 13 Jahren
manuelles Laden von Assemblies

Moin,

ich experiementiere gerade mit dem manuellen Laden von Assemblies ... Sinn ist das verschlüsseln eben jener und dann das Laden und Interne entschlüsseln ... dazu habe ich 3 Librarys - "interface", "library" und "projekt" ... "projekt" enthält eine Form mit 2 Buttons ... "interface" stellt ein Interface zum Zugriff auf "library" von "projekt" aus ... "library" wird unter "projekt" ebenfalls dynamisch geladen" (als Plugin quasi)

dann habe ich ein Programm "Loader" - welches eben "projekt" und "interface" laden und entschlüsseln soll ... im Moment habe ich quasi das - was nur teilweise funktioniert


		public Loader()
		{
			PrepareFile("interface.dll");
			PrepareFile("projekt.dll");

			try
			{
				AppDomain dom = AppDomain.CurrentDomain; 
				dom.Load(LoadAssembly("interface.dll"));
				dom.Load(LoadAssembly("projekt.dll"));

				foreach (Assembly asm in dom.GetAssemblies())
				{
					Logging.info("loaded: " + asm.FullName);
					foreach (Type t in asm.GetTypes())
					{
						if (t.FullName.Equals("projekt.GUI"))
						{
							// PrepareFile("interface.dll");
							Assembly a = t.Assembly;
							Form f = a.CreateInstance("projekt.GUI", true) as Form;
							Application.Run(f);
						}
					}
				}
			} catch (Exception ex)
			{
				Logging.error(ex);
			}
		}

PrepareFile verschlüsselt (bzw. entschlüsselt) mit simplen XOR (0xff) ... die Dateien werden testweise am Anfang verschlüsselt da sie ja bei jedem Build neu erstellt werden ... LoadAssembly lädt die Assembly und entschlüsselt sie entsprechend

das Einlesen der Assemblies "interface" und "projekt" funktioniert wie erwartet ... "projekt" referenziert die bereits geladen "interface" in der AppDomain ... denn wenn ich die beiden Zeilen tauschen, dann knallt es - da "projekt" in der AppDomain "interface" nicht findet und .NET versucht dann eben die verschlüsselte von Pladde zu laden

das Problem ist das Erzeugen des Objektes "projekt.GUI" ... hier wird immer die "interface" von der Platte direkt geladen - welche ja verschlüsselt ist ... wenn ich den Kommentar bei PrepareFile vor der Instanzierung wegnehme, wird "interface" wieder entschlüsselt und ich habe meine Form -.-

zuerst hatte ich ja dom.CreateInstance versucht ... aber da wird dann auch die Assembly direkt von der Platte geladen ... der zweite Versuch war die Instanzierung direkt als Type - in der Hoffung das er dann aus dem "inneren" alles richtig verwendet ... öhm - Nein

ich bräuchte mal einen Tipp wie ich das richtig hinbekomme

hand, mogel


		private void PrepareFile(String source)
		{
			if (File.Exists(source))
			{
				Logging.info("codiere: " + source);
				byte[] asm = File.ReadAllBytes(source);
				for(int i = 0; i < asm.Length; i++) asm[i] = (byte) ((asm[i] ^ 0xff) & 0xff);
				File.WriteAllBytes(source, asm);
			}
		}


		private byte [] LoadAssembly(String name)
		{
			Logging.info("lade: " + name);
			String path = Path.Combine(Environment.CurrentDirectory, name);
			byte[] asm = File.ReadAllBytes(path);
			for(int i = 0; i < asm.Length; i++) asm[i] = (byte) ((asm[i] ^ 0xff) & 0xff);
			return asm;
		}

849 Beiträge seit 2006
vor 13 Jahren

Ohne es ausprobiert zu haben..

ich würde versuchen die verschlüsselte dll anders zu benennen, und dann AppDomain.CurrentDomain.AssemblyResolve abonnieren.

-> Die dll wird nicht gefunden
-> Assembly Resolve
-> verschlüsselte Assembly decodieren
-> mit Assembly.Load laden
-> Decodierte Assembly zurückgeben.

sollte klappen denke ich.

mogel Themenstarter:in
156 Beiträge seit 2010
vor 13 Jahren

super - funktioniert 🙂 ... sowas in der Richtung habe ich schon den ganzen Tag gesucht ... also das ich die entsprechende DLL vorgeben kann 8)


		private byte[] asmi;
		private byte[] asmp;

		public Program()
		{
			PrepareFile("interface.dll", "i.dll");
			PrepareFile("projekt.dll");

			try
			{
				AppDomain dom = AppDomain.CurrentDomain;

				dom.AssemblyResolve += new ResolveEventHandler(dom_AssemblyResolve);

				asmi = LoadAssembly("i.dll");
				asmp = LoadAssembly("projekt.dll");

				dom.Load(asmi);
				dom.Load(asmp);

				foreach (Assembly asm in dom.GetAssemblies())
				{
					Logging.info("loaded: " + asm.FullName);
					foreach (Type t in asm.GetTypes())
					{
						if (t.FullName.Equals("projekt.GUI"))
						{
							Logging.info("starte GUI");
							Assembly a = t.Assembly;
							Form f = a.CreateInstance("projekt.GUI", true) as Form;
							Application.Run(f);
						}
					}
				}
			} catch (Exception ex)
			{
				Logging.error(ex);
			}
		}


		Assembly dom_AssemblyResolve(object sender, ResolveEventArgs args)
		{
			String name = args.Name.Split(',')[0];
			if (name.Equals("interface")) return Assembly.Load(asmi);
			return null;
		}


		private void PrepareFile(String source, String destination)
		{
			if (File.Exists(source))
			{
				PrepareFile(source);
				File.Copy(source, destination, true);
				File.Delete(source);
			}
		}

danke, mogel