EAX und Stack
-
freakC++ schrieb:
Ich hab den Code im Borland Builder inline eingebunden. Das geht da recht schön mit der Funktion asm.
Aber die Stackgeschichte hat doch damit eigentlich nichts zu tun oder? Danke
Da http://docs.google.com/viewer?a=v&q=cache:J5Etx6N3-74J:www.krucker.ch/Skripten-Uebungen/InfUeb/Assembler%20in%20C-CPP%20Programmen%20BCB.pdf+c%2B%2B+builder+inline+asm&hl=de&gl=de&pid=bl&srcid=ADGEESiy3tlDMd5nLRmUkqRZcwZpKzK_aj3FAjb5NQ-GChxXjLPkmkXDJ9vdNwtLTy_cFW_cdglzIpbwhAErxc36I5Z52EvTxwaML2IMeZqIu-61S0TtuuzMG_vFLDGK-lIG-Wuo5y62&sig=AHIEtbSr1YxuBwrSZAI8sp5DKlsfJCO0uQ (auf Seite 5) macht er das genau wie Du.
Ohne push und pop.
Es müßte klappen, sag ich mal.
-
Ich habe vergessen, den POP Befehl rauszunehmen. Klar, dass dann ein Fehler kommt. Kein PUSH aber POP...
Ich habe eben aus Spaß ein kleines C++ Programm geschrieben mit einem Eingabefeld und einem Button (mit Borland Builder). Nur wenn man das richtige Passwort eingibt, kommt eine Meldung, die "Willkommen" ausgibt. Mithilfe eines Disassemblers habe ich den Assemblercode erhalten und habe den entsprechenden "jne" Befehl modifiziert, wodurch ich jetzt kein Passwort mehr eingeben muss. Dazu habe ich ein paar Fragen:
Das Passwort heißt "Auto". An der entsprechenden Stelle steht:
mov edx, dword ptr [00454DC0] call 00404258 jne 00453812
Der C++ lautet
if (Eingabe == Passwort) ShowMessage("Willkommen");
1.) Warum ist der entscheidenen Jump ein jne Befehl. Er steht ja für "jump if not equal". Aber eigentlich soll der Jump doch nur erfolgen, wenn es equal ist. Es gibt keinen else Teil.
2.) Wenn ich nun den JUMP Befehl austausche, sodass immer "Willkommen" beim Buttondruck ausgegeben wird, muss ich folgendes machen:
Intern sieht der JUMP Befehl wohl so aus (Original Bytes):
75 0A B8 3C 38 45 00 E8 ...
Nun weiß ich, dass ich einfach die 75 in eine 74 ändern muss. Warum eigentlich? ASCII Code ist das sicherlich nicht. Was ändert die 74 am Jump Befehl?
3.) Wie werden Strings in Assembler abgespeichert? Ich habe nämlich versucht, den String "Willkommen" durch "Hallo" zu ersetzen.
Vielen Dank euch.
lg, freakC++
-
-
Du solltest dir mal ansehen, wo die Zieladressen im Programm liegen. Ich würde ja vermuten, daß der jne-Befehl die nächsten Anweisungen überspringt, die den ShowMessage-Call überspringt.
-
75 bzw. 74 sind die Codes für verschiedene Assembler-Anweisungen, vermutlich steht die 74 für eine andere Sprunganweisung, da müsstest du dir mal den modifizierten Code ansehen.
-
normalerweise sollten die Literale irgendwo in ACSII-Format stehen, da solltest du mal mit einem Hex-Editor oder im Dissassembler nach dem Willkommens-String suchen.
-
-
Konstante Strings liegen in der Regel im Datanbereich der Executable. Mit einem normalen Editor solltest du den Text finden. Zu dissamblieren gibt es da nicht viel, weil da einfach nur Daten drin stehen. Du musst natürlich beim Editieren auch beachten das die Datenlänge gleich bleibt, da sich sonst die Adressen der folgenden Daten verändert und nicht mehr mit dem Code übereinstimmen.
-
freakC++ schrieb:
if (Eingabe == Passwort) ShowMessage("Willkommen");
1.) Warum ist der entscheidenen Jump ein jne Befehl. Er steht ja für "jump if not equal". Aber eigentlich soll der Jump doch nur erfolgen, wenn es equal ist. Es gibt keinen else Teil.
Ich kenne den Code nicht.
Aber ich kann mir vorstellen, daß der Compiler aus
tuwas1(); if (Eingabe == Passwort) ShowMessage("Willkommen"); tuwas2();
das hier macht:
tuwas1(); int tmp = strcmp(Eingabe.data,Passwort.data) if(tmp!=0) goto hinten; //jne ShowMessage("Willkommen"); hinten: tuwas2();
-
freakC++ schrieb:
75 0A B8 3C 38 45 00 E8 ...
Nun weiß ich, dass ich einfach die 75 in eine 74 ändern muss. Warum eigentlich? ASCII Code ist das sicherlich nicht. Was ändert die 74 am Jump Befehl?
3.) Wie werden Strings in Assembler abgespeichert? Ich habe nämlich versucht, den String "Willkommen" durch "Hallo" zu ersetzen.
Bei den Sprungbefehl handelt es sich um einen short jump (8Bit relativ-Adresse zum nächten Befehl) -> 75 0A -> je $+2+10
Wenn du eines String ersetzen möchtest, ist es sinnvoll, an der entsprechenden Stelle[n] den/die Zeiger zu ändern. Den neuen String hängt man z.B. ans Daten Segment an.
-
volkard schrieb:
Aber ich kann mir vorstellen, daß der Compiler aus
tuwas1(); if (Eingabe == Passwort) ShowMessage("Willkommen"); tuwas2();
Bei mir gibt es aber kein tuwas2(). Nach der if-Abfrage ist Schluss. Das Programm beinhaltet ausschließlich diese Fallunterscheidung.
Tobiking2 schrieb:
Konstante Strings liegen in der Regel im Datanbereich der Executable. Mit einem normalen Editor solltest du den Text finden.
Ich benutze den Disassembler "ursoft w32dasm". Darin gibt es eine Funktion, die nennt sich "String Data References". Dort kann ich tatäschlich nach einem String suchen und ich finde ihn auch. Angenommen ich gebe "Auto" (das Passwort) ein, dann lande ich bei folgender Stelle:
* Possible StringData Ref from Code Obj -> "Auto" mov edx, dword ptr[00454DC0] call 00404258 jne 00453812
Für mich erscheint die Zeile mit dem Wort "Auto" wie ein Kommentar, da diese in Grün geschrieben ist. Ich finde aber keine Stelle, wo das Wort nun wirklich abgelegt also gespeichert ist und wo ich dieses dann durch ein gleichlanges ersetzen kann. Mir geht es ja um das Ersetzen. Damit möchte ich erreichen, dass ich im Nachhinein mittels Assembler das Kennwort ersetzen kann. Beispielsweise soll "Auto" zu "Sofa" werden. Kennt jemand den Disassembler den ich nutze oder könnt ihr mir einen besseren raten? Ich kenne ihn selbst nicht.
masm schrieb:
Bei den Sprungbefehl handelt es sich um einen short jump (8Bit relativ-Adresse zum nächten Befehl) -> 75 0A -> je $+2+10
Vielleich ist das Grundwissen, aber wofür steht "$+2+10"?
Vielen Dank und bis bald
-
freakC++ schrieb:
volkard schrieb:
Aber ich kann mir vorstellen, daß der Compiler aus
tuwas1(); if (Eingabe == Passwort) ShowMessage("Willkommen"); tuwas2();
Bei mir gibt es aber kein tuwas2(). Nach der if-Abfrage ist Schluss. Das Programm beinhaltet ausschließlich diese Fallunterscheidung.
Es gibt immer ein tuwas2() - und wenn es das implizite
return 0;
am Ende der main() istTobiking2 schrieb:
Konstante Strings liegen in der Regel im Datanbereich der Executable. Mit einem normalen Editor solltest du den Text finden.
Ich benutze den Disassembler "ursoft w32dasm". Darin gibt es eine Funktion, die nennt sich "String Data References". Dort kann ich tatäschlich nach einem String suchen und ich finde ihn auch. Angenommen ich gebe "Auto" (das Passwort) ein, dann lande ich bei folgender Stelle:
* Possible StringData Ref from Code Obj -> "Auto" mov edx, dword ptr[00454DC0] call 00404258 jne 00453812
Für mich erscheint die Zeile mit dem Wort "Auto" wie ein Kommentar, da diese in Grün geschrieben ist. Ich finde aber keine Stelle, wo das Wort nun wirklich abgelegt also gespeichert ist und wo ich dieses dann durch ein gleichlanges ersetzen kann. Mir geht es ja um das Ersetzen. Damit möchte ich erreichen, dass ich im Nachhinein mittels Assembler das Kennwort ersetzen kann. Beispielsweise soll "Auto" zu "Sofa" werden. Kennt jemand den Disassembler den ich nutze oder könnt ihr mir einen besseren raten? Ich kenne ihn selbst nicht.
Hast du irgendeine Möglichkeit, die Adressen der einzelnen Anweisungen herauszufinden? Wenn ja, würde ich mal unter Adresse 00454DC0 nachsehen, was dort steht.
masm schrieb:
Bei den Sprungbefehl handelt es sich um einen short jump (8Bit relativ-Adresse zum nächten Befehl) -> 75 0A -> je $+2+10
Vielleich ist das Grundwissen, aber wofür steht "$+2+10"?
Vielen Dank und bis bald
$ - aktuelle Position des Instruction Pointers, +2 - nächster Befehl, +10 steht in dem Srpungbefehl (0A)
-
freakC++ schrieb:
Bei mir gibt es aber kein tuwas2(). Nach der if-Abfrage ist Schluss. Das Programm beinhaltet ausschließlich diese Fallunterscheidung.
Dein Code ist ja trotzdem nicht wirklich freistehend. Da passiert einiges wie z.B. Parameterübergabe bevor die main Funktion aufgerufen wird, und am Ende wird aufgeräumt. Man kann also durchaus hinter deinen Code springen.
freakC++ schrieb:
Für mich erscheint die Zeile mit dem Wort "Auto" wie ein Kommentar, da diese in Grün geschrieben ist.
Ja, das ist nur ein Kommentar. Ich kenne aber gerade auch keinen Disassembler der direkt das editoeren von Strings erlaubt. Selbst die kostenlose Version von IDA Pro scheint die Strings nur anzuzeigen.
freakC++ schrieb:
Vielleich ist das Grundwissen, aber wofür steht "$+2+10"?
Das $ wird (zumindest bei nasm) als Platzhalter für die Anfangsadresse des aktuellen Befehls verwendet. Die 10 kommt aus dem Befehl, weil man 10 Byte (0A) (Vom Ende des Befehls) weiter springen will. Die +2 kommen weil der Sprungbefehl 2 Byte lang ist, und man vom Ende aus weiter springen will.
Edit: Da hab ich wohl zu lange zum Tippen gebraucht :p
-
Danke für eure Antworten. Ich denke, dass ich erstmal besser in Assembler werden sollte, bevor ich anfange bei .exe Programmen die Strings auszutauschen. Ich merke nämlich, dass Assembler gar nicht so einfach ist.
Ihr habt mir wieder mal geholfen.