Assembler Code analysieren

10/11/2015 21:52 Belur#16
Okay, so langsam werd ich verwirrt. Kann mich abends auch immer schlechter konzentrieren :awesome:
Also mein Code aus Post 10 findet auch negative Schlüssel:
Beispiele.
-1171446559
-780994987
-390543415
-390543414
-91842
Die sind alle gültig.

Der Code für das Testen von deiner korrigierten Version:
Code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {

	int var0;
	int i;
	for (i = 0; i <= 9223372036854775807; i++) {
		var0 = i;
		var0 = (((var0 << 2) + var0) * 2) + var0; // @ +45 to +62
		var0 = (var0 + (var0 >> 31)) / 2; // @ +62 to +77
		var0 /= 8; // @ +77
		var0 += 0xf7f9; // @ +81
		var0 -= 0x13c; // @ +88
		if (var0 == 0x17) {
			printf("%d \n", i);
			fflush(stdout);
		}
	}
}
Dann kriege ich als Ergebnis nach ein paar Sekunden diese Schlüssel:

Von den Schlüsseln stimmen aber nur 2 Stück. Einmal der, den du schon gefunden hattest und einmal
1952166018.
Der Rest ist ungültig.
10/11/2015 22:38 Jeoni#17
Nun, dann muss beim Rückübersetzen oder Compilerspezifischen "neukompilieren" irgendein "Fehler" unterlaufen sein.
Für deine Zwecke ist das Rückübersetzen aber eigentlich auch gar nicht nötig. Wenn du die check_key Funktion auf asm Ebene leicht abänderst, so dass sie direkt einen Integer nimmt, statt einen String, der dann mit atoi geparst wird, kannst du sie gut in deine for-schleife einbinden. Dann hättest du die Originalfunktion zum bruteforcen der Keys, ohne potentielle Fehler oder Ungenauigkeiten beim Rückübersetzen oder Kompilieren des rückübersetzten Codes. Theoretisch kannste auch ohne Änderung die Funktion gebrauchen, aber dann musste jeden Integer erst via sprintf o.Ä. zum String machen bzw. einen intelligenten, aber komplexen Weg finden, immer einen String mit der Zahl parat zu haben.
Ich werde mich morgen Nachmittag / Abend da mal ransetzen, wenn du's bis dahin noch nicht selbst genau gelöst hast.
Ist das eigentlich so ein CrackMe / KeygenMe? Und darf ich fragen, wofür genau du das machst? Also ist ja nichts verwerflich dran, aber wundert mich da so scheinbar ohne bzw. nur mit wenigen Vorkenntnissen dort einzusteigen.
Mit freundlichen Grüßen
Jeoni
10/11/2015 22:47 Belur#18
Danke ich werde morgen mal versuchen davon was umzusetzen.

Das ist eine Übungsaufgabe aus einem Kurs an der Uni. Eventuell fehlt mir auch noch eine Vorlesung, aber ich habs mir heute schonmal angeguckt.

Vllt. fällt es mir nach der nächsten Vorlesung auch etwas leichter, weil der Prof. nochmal einiges erläutert.
Im ersten Semester hatten wir ein bisschen Assembler, aber das ist auch schon etwas länger her.
10/11/2015 23:59 meak1#19
ida + hexrays, benutze ich für functionen nachbauen ;D (musste mal ziemlich viele Hackshield functionen kopieren^^)
10/12/2015 08:02 Jeoni#20
Quote:
Originally Posted by meak1 View Post
ida + hexrays, benutze ich für functionen nachbauen ;D (musste mal ziemlich viele Hackshield functionen kopieren^^)
Da kann man dann nur hoffen, dass keine eigenen Aufrufkonventionen verwendet werden oder sonst irgendwelche Obfuscations den Decompiler verwirren. Ist zwar ganz nett, um sich einen Überblick zu verschaffen, aber 100%ig verlassen würde ich mich darauf nicht.

Habe nun mal eben das Bruteforce-Programm geschrieben (source im Anhang). Ist mit Visual Studio spezifischem inline asm (geht nicht als x64, aber der Key ist ja eh nur ein 32 bit Integer, daher ist die Funktion nicht auf 64 bit Register angewiesen), aber was es macht, sollte ja ersichtlich sein. Ich weiß selber, dass das Auslagern des asm Codes in eine eigene Datei, oder (in dem Fall) einfach alles direkt in asm schreiben idR die sauberere Methode ist, aber hierfür reicht's auch so. Die check_key-Funktion habe ich vom Originalcode genommen und dann leicht abgeändert: auf 32 bit geändert; unnötige lokale Variablen entfernt (der Key, der vorher an rbp-4 stand ist nun in ecx); Funktion nimmt direkt den Key als int; Aufrufkonvention ist MS fastcall, also erstes Argument in ecx.
Als Output bekomme ich folgendes:
Mit dem Ansatz muss man kein Stück der Originalfunktion wirklich zurückübersetzen und der genaue Algorithmus zur Schlüsselverifikation ist ebenso unerheblich :D
Mit freundlichen Grüßen
Jeoni
10/12/2015 18:49 Belur#21
Werde mir später nochmal die Zeit nehmen das zu verstehen, danke schonmal.

Ich habe jetzt zum Üben eine andere ähnliche Aufgabe genommen und mich daran versucht. Assembler-Code sieht so aus:

Jetzt hab ich praktisch 2 Versionen, die allerdings beide nicht funktionieren.
Einmal das "sar" also normales "shr" interpretiert:

Und einmal das "sar" als n-Fache Division durch 2:

Allerdings scheint das beides nicht richtig zu sein. Die 1. Variante gibt falsche Keys aus und die 2. Variante gibt (zumindest nach ein paar Minuten) garkeine Keys aus.

Ich hätte vermutet dass die erste Variante wieder passt, da für das Beispiel von gestern (also "sar" als normalen Shift übersetzen) alles perfekt passte.
Evtl. hab ich also so etwas falsch gemacht.

Vllt sieht jemand den Fehler.

Ich hänge nochmal das Programm an, dann kann man auf Wunsch selbst testen.




Eine Sache noch: Ich hab jetzt schon einige Aufgaben gerechnet und hier ein anderes Beispiel:

Den Keygen-Code dazu habe ich so übersetzt:
Also das "sar" wieder ganz normal als Shift rückübersetzt. Bei der Lösung kriege ich auch nur richtige Schlüssel ausgegeben.

Ich sehe eigentlich keinen Unterschied zu der 1. Version von oben. Es sind halt andere Operationen aber ich habe praktisch nach dem gleichen "Verfahren" rückübersetzt. Einmal klappt es perfekt und einmal garnicht.