de4dot

Ein Programm welches in C# geschrieben wird, wird beim kompilieren in ein Intermediate-Assembly umgewandelt. Das bedeutet das der Code in einer Zwischensprache darauf wartet auf seinem Zielsystem in nativen Code umgewandelt zu werden. Der Vor- und auch Nachteil dieser Vorgehensweise ist, das sich der Quellcode sehr einfach aus dem IL-Code zurückwandeln lässt. Im Idealfall verliert man bloß einige Variablennamen.

Um das zu verhindern gibt es sogenannte Obfuscatoren, welche versuchen den entsprechenden Quelltext zu verschleiern, so das er nicht mehr einfach zurückgewandelt werden kann. Aber wie so oft im Leben gibt es auch hier einen Wettlauf mit der Zeit. So gibt es einige Tools welche den obfuskierten Quelltext wieder deobfuskieren. Eines dieser Projekte ist „de4dot“ welches unter https://bitbucket.org/0xd4d/de4dot/ zu finden ist. Das unter der GPL stehende Projekte, erkennt dabei den verwendeten Obfuscator und versucht seine Änderungen soweit wie möglich rückgängig zu machen. Dabei werden eine stattliche Anzahl von Obfuscatoren, wie der Dotfuscator, Goliath.NET und Skater.NET unterstützt.

Controls im Visual Studio zur Designzeit debuggen

Die Entwicklung von Controls unter .NET und Windows Form geht eigentlich relativ leicht von der Hand. Kompliziert wird das ganze immer dann wenn Fehler auftreten. So lassen sich Controls welche im Designmodus Exceptions werfen, nur schwer debuggen. Aber wie immer gilt, wo ein Wille ist, da ist auch ein Weg.

Das Attach to Process Fenster

Das Attach to Process Fenster

Um ein Control zu debuggen, sollte man das entsprechende Projekt bzw. die Solution zwei mal öffnen. In dem einen Visual Studio öffnet man nun den Designer. Im anderen Visual Studio wählt man im Debugmenü den Punkt „Attach to Process…“ aus. Das sich öffnende Fenster zeigt alle Prozesse an, an welche sich der Debugger anhängen kann. Hier wird das erste Visual Studio (das mit dem Designer) ausgewählt. Nun kann man im Quelltext des Controls Breakpoints setzen und somit die Ausführung überwachen. Allerdings sollte man sich dabei nicht wundern, das dass Control im Debugger größer erscheint als es eigentlich ist. Der Grund dafür liegt darin, das genau genommen nicht das Control sondern das gesamte Visual Studio debuggt wird.

Threadsicheres Dictionary unter .NET

Das Dictionary unter .NET ist eine schöne Datenstruktur mit der man effizient Schlüssel- und Wertepaare verwalten kann:

Dictionary<uint, byte[]> idToValues=new Dictionary<uint, byte[]>();
idToValues.Add(1, data);

Problematisch wird das ganze, sobald in mehreren Threads gearbeitet wird, welche alle auf das gleiche Dictionary zugreifen. Hier müssen die Zugriffe auf das Wörterbuch kontrolliert und entsprechend gesperrt werden. Einfacher wird es mit der 4er .NET Framework. Dort gibt es ein ConcurrentDictionary welches von Haus aus threadsicher ist und dem Entwickler eine Menge Arbeit erspart.

ConcurrentDictionary<uint, byte[]> idToValues=new ConcurrentDictionary<uint, byte[]>();
idToValues.TryAdd(1, data);

Das „ConcurrentDictionary“ kann dabei im Großen und Ganzen wie ein normales Dictionary genutzt werden, so das die Umstellung nicht allzu schwer fallen sollte.

Hash von einem beliebigen .NET Objekt erzeugen

Unter .NET gibt es an jedem Objekt die Methode „GetHashCode“ welche einen HashCode zurückliefert. Das Problem an dieser Methode ist jedoch das sie vom Objekt selbst implementiert werden muss. Möchte man nun eine Methode mit der man jedes Objekt generisch hashen kann, so ist diese Funktion hilfreich:

public string GetSHA1HashFromObject(object obj)
{
	SHA1CryptoServiceProvider sha1Provider=new SHA1CryptoServiceProvider();
	DataContractSerializer serializer=new DataContractSerializer(obj.GetType());

	using(MemoryStream memoryStream=new MemoryStream())
	{
		serializer.WriteObject(memoryStream, obj);
		sha1Provider.ComputeHash(memoryStream.ToArray());
		return Convert.ToBase64String(sha1Provider.Hash);
	}
}

Die Funktion serialisiert dabei das Objekt und hasht anschließend das serialisierte Objekt. Damit ist es egal, welches Objekt in die Funktion gegeben wird.

Named Pipes zur Interprozesskommunikation

Interprozesskommunikation unter .NET ist so eine Sache. Da gibt es unter anderem das relativ mächtige Remoting Framework. Leider schlägt sich die Mächtigkeit auch in der Komplexität nieder. Wesentlich einfach wird das ganze mittels Named Pipes welche sich auch zur Interprozesskommunikation eignen. Dazu benötigt man einen Server und einen Client. Der Server könnte dabei unter .NET so aussehen:

Task.Factory.StartNew(() =>
{
	NamedPipeServerStream server=new NamedPipeServerStream("halfPipe");
	server.WaitForConnection();
	StreamReader reader=new StreamReader(server);
	StreamWriter writer=new StreamWriter(server);

	while(true)
	{
		string line=reader.ReadLine();
		
		if(line=="HELLO")
		{
			writer.WriteLine("Hi");
			writer.Flush();
		}
		else
		{
			writer.WriteLine("Unknown command.");
			writer.Flush();
		}
	}
});

Auf der Clientseite sieht die Kommunikation fast genauso aus:

NamedPipeClientStream pipeStream=new NamedPipeClientStream("halfPipe");
pipeStream.Connect();
StreamReader reader=new StreamReader(pipeStream);
StreamWriterwriter=new StreamWriter(pipeStream);

writer.WriteLine("HELLO");
writer.Flush();

string ret=reader.ReadLine();

Damit ist die Kommunikation zwischen den Prozessen eingerichtet. Natürlich kann man nicht nur Strings sondern auch andere Datentypen über die „Named Pipes“ verschicken.