Mit C++ Assemblercode ändern

Hey Leute,

habe eine frage zu C++ und Assembler ^^

Ich habe ein Crackme gelöst, indem ich aus JE SHORT 00401719 ein JNZ SHORT 00401719 gemacht habe.

Meine Frage: Wie kann ich das in einem Code automatisieren?
Ich meine, dass das Programm automatisch daraus ein JNZ macht?(in C++)
(Ist das Programm dann ein Patch ? Oder wie heißt das nochmal, der Name fällt mir nichtmehr ein -.-)

Vielen Dank schonmal für Hilfe =)

MFG
 
Das nennt man "Patcher".

Also grundsätzlich kannst du die exe einlesen (achtung, binär, keine Stringoperationen benutzen, da diese bei 0x00 terminieren) und nach der codestelle suchen.

Sieh dir doch mal den hexdump in olly an, wenn du die exe geladen hast. Wenn sich der exe code selber verändert, dann kommst du so aber nicht weit. Wenn das Zeug z.B. mit UPX od. äh, gepackt ist, wird es schwieriger. Ich habe damit aber keine Erfahrung, habe nur einmal damit herumexperimentiert. :)
 
Ich wollte so ein gelöstes CrackMe automatisieren^^
Habe jetzt die Exe so verändert, dass das JN jetzt ein JNZ ist...

Aber mich interessiert auch, wie man es mit einem "Patcher" macht. (also Patcht^^)

MFG

PS: Habe das mit OllyDbg und W32Dasm gemacht ;)
 
Du errechnest zuerst die Position des geänderten Bytes in der Datei - also VirtualAdress aus Olly in FileOffset umrechen. Dazu bietet es sich an, LordPE oder PETools Funktion zu verwenden - als Übungsaufgabe kannst Du das natürlich auch gerne per Hand machen ;)

Wenn man die Datei nun binär öffnet:
Code:
ofstream myFile;
myFile.open ("data", ios::out | ios::binary);
zu der Position geht:
myFile.seekp (offset_wert);
und dann ein Byte reinschreibt:
myFile.put(0x75);
myFile.close();
oder so ähnlich. C++ mag mich nicht und das beruht auf Gegenseitigkeit ;)
 
Aber so ändert man doch nicht, ob es JE oder JNZ ist, oder?
doch, aber nur wenn es draußen kälter ist, als nachts ;)

Falls Du meinst, ob man so nicht erkennen kann, was man ändert - tja, darüber sollte man sich vorher gedanken machen. Also die virtuelle Adresse aus dem Debugger in das Fileoffset umrechnen.
Es gibt so gesehen zwei grobe Arten von Patchern - die die eine feste Adresse überschreiben und die, die nach Mustern suchen und diese patchen. Mustersuche ist etwas aufwändiger unzusetzen - aber an festen Adressen Bytes zu überschreiben sollte eigentlich schon ausreichen ;).
 
Ok, Bsp: du willst in Pinball.exe
Code:
01020FB1    . /75 1F                      JNZ SHORT PINBALL.01020FD2
zu einem JE ändern. In Olly hat man ja die bequeme Möglichkeit, direkt Assembly zu schreiben. Ändert man nun JNZ in JE, so steht nun da:
Code:
01020FB1      /74 1F                      JE SHORT PINBALL.01020FD2
Olly hat also den Assembly code in richtige Opcodes umgesetzt.

Zusätzlich sind die geänderten Bytes in Olly nun rot markiert. Möchte man das ohne Olly machen, so kann man eine Tabelle
http://www.poseidon-blue.de/html/asscodes.htm
oder
ftp://download.intel.com/design/PentiumII/manuals/24319102.PDF
bemühen.

Naja, man sieht nun in Olly, dass nur 1 Byte geändert wurde - die 75 wurde zu 74.
Jetzt rechnet man die virtuelle Adresse um:
(z.B mit LordPE öffnen, auf FLC gehen, VA auswäheln und 01020FB1 eingeben -
entspricht dem Fileoffset 0x203b1).

also muss man an der Position 0x203b1 ein Byte mit 0x74 überschreiben:
Code:
#include <iostream>
#include <fstream>
using namespace std;

int main () 
{
  fstream myFile;
  myFile.open ("pinball.exe", ios::in|ios::out | ios::binary);

  myFile.seekp (0x203b1);
  //überschreiben
  
  myFile.put(0x74);
  myFile.close();
 
  return 0;
}
PS: der Code ist zwar getestet - ich gebe allerdings keine Garantie für die absolute ANSI - Korrektheit ;)
 
achsooo ^^

Danke für die Idiotensicher erklärung, bin noch ein n00b in der "Cracking-szene" ^^
Und das mit den Bytes 75 und 74 habe ich auch nicht gewusst =)

Vielen Herzlichen Dank

MFG
 
Der unnötigen Vollständigkeit halber nochmal in C, das Ganze, wenn es jemanden interessieren sollte:
Code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    FILE *f; // Filehandle erzeugen
    f = fopen("crackme.exe", "r+"); // Zu patchende Datei

    fseek(f, 0x00001B55, SEEK_SET); // fileoffset als zweites Argument
    fputc(0x74, f); // zu schreibender Wert (ein Byte)
    fclose(f); // Filehandle wieder schließen

    return 0;
}

Vom Schreibaufwand genau so wenig wie die iostream Variante von CDW, aber nicht nur mit C++- sondern auch mit C-Compilern lauffähig (Ich weiß, dass nach einer C++-Lösung gefragt wurde und die auch gegeben wurde, das ganze stellt lediglich eine Ergänzung dar).
 
Zurück
Oben