Ich beantworte nur mal deine Frage, da ich denke, dass du den Rest alleine schaffst.
PS:
Wäre nett wenn mir jemand sagen könnte wie man den ersten CrackMe patched, da der wichtige jump ausserhalb ist...
Die Instruktionen der Hauptschleife des Programms sind zwar zum Zeitpunkt des Ausführens außerhalb. Aber die können ja nicht einfach "aus dem nichts" kommen.
Tatsächlich befindet sich der Code (und auch Konstanten übrigens) zuvor in der ".data" Section der Executable und wird von da erst herauskopiert in neu reserviertem Speicher.
Dort können wir natürlich erst hinterher patchen. Also zum Zeitpunkt des Ausführens.
Aber in der ".data" Section können wir schon vorher patchen.
Den Jump hast du sicher schon gefunden. In der ".data" Section findet man den dann auch:
Code:
10128190 21C0 AND EAX,EAX
10128192 0F84 FCFFFFFF JE 10128194
Vorsicht. Noch ist der Jump ungültig. (Die Instruktion jumpt "in sich selbst hinein")
Das Sprungziel wird erst hinterher korrigiert. Also nachdem der unkorrigierte Code von ".data" zu dem reservierten Speicherbereich kopiert wird.
Zum patchen gibt es nun zwei Möglichkeiten. Die eine ist einfach und langweilig. Dort patcht man einfach die Instruktionen vor dem Sprung so, dass immer das Z-Flag gelöscht ist.
Die zweite ist etwas interessanter. (Weil man noch etwas lernt.

)
Den Sprung selbst kann man nicht einfach noppen. Da an die Stelle (Sprungziel wird korrigiert) später noch geschrieben wird, leider auch über unsere Nops.
Wir müssen also etwas intelligenter patchen. Wir wollen nicht, dass gesprungen wird.
Wir sehen, dass zuvor ein AND EAX, EAX ausgführt wird.
Wir schauen nach, welche Flags AND mit einem DEFINIERTEN konstanten Wert immer gleich besetzt.
Wir sehen hier (vorletzte Spalte):
http://ref.x86asm.net/geek.html#x21
Dass das Overflow-Flag wird IMMER gelöscht, also auf Null gesetzt wird, nach JEDER AND Operation.
Wenn wir also den Jump auf ein JO (Jump if Overflow) ändern, dann wird unter keinen Umständen gesprungen.
Um das nun zu ändern, können wir leider nicht OllyDbgs Assemble-Funktion benutzen, da er für den Sprung eine andere Kodierung nimmt, die nicht die gleiche Instruktionsgröße hat. (Es gibt mehrere Kodierungen)
Das würde wieder schiefghen, wenn das Sprungziel im Nachhinein korrigiert wird.
Die Sprunginstruktion ist diesem Falle eine Two-Opcode Instruktion mit dem prefix 0x0F.
Wir schauen also in diese Tabelle und suchen JO.
http://sandpile.org/ia32/opc_2.htm
Und sehen, dass wir 0F84 in 0F80 ändern müssen. Und schon wird nie gesprungen, da nach einem AND das Overflow-Flag garantiert gelöscht ist.
Wie gesagt. Es geht noch einfacher. Aber nur mal als Anstoß für einen etwas anderen Ansatz. :wink: