Frage zu JE SHORT EasyCrac.0040113D

hi, schaut euch mal folgenden code aus einem crackme an

Code:
00401124   |.  50                PUSH EAX
00401125   |.  E8 D6FEFFFF       CALL EasyCrac.00401000  //serial wird geprüft
0040112A   |.  85C0              TEST EAX,EAX
0040112C   |.  59                POP ECX
0040112D   |.  59                POP ECX
0040112E   |.  56                PUSH ESI
0040112F   |.  74 0C             JE SHORT EasyCrac.0040113D   //<------????
00401131   |.  68 38234000       PUSH EasyCrac.00402338                           ;  ASCII "RIGHT"
00401136   |.  68 2C234000       PUSH EasyCrac.0040232C                           ;  ASCII "You got it!"
0040113B   |.^ EB DA             JMP SHORT EasyCrac.00401117
0040113D   |>  A1 B4234000       MOV EAX,DWORD PTR DS:[4023B4]                    ; |
00401142   |.  68 24234000       PUSH EasyCrac.00402324                           ; |Title = "WRONG"
00401147   |.  6A 0B             PUSH 0B                                          ; |
00401149   |.  59                POP ECX                                          ; |
ich koennte jetzt einfach den JE SHORT EasyCrac.0040113D aushebeln, aber das möchte ich nicht.

meine frage ist, was wird da verglichen bei JE SHORT EasyCrac.0040113D
also wann springt er?
ESI ist in beiden fällen 0x00. also egal ob serial richtig/flasch ist
wenn ich eax manuell auf 0 oder 1 setze springt er auch immer.
wenn die serial oben in
Code:
00401125   |.  E8 D6FEFFFF       CALL EasyCrac.00401000
richtig ist, führt er den jump nicht aus.
aber wie prüft er das?
 
Zuletzt bearbeitet:
danke dir, aber es gab keine anderen referenzen zu dem befehl.

bin mal essen gegangen und hab nen bissl "offline" überlegt.
JE überprüft ob das Zero flag gesetzt ist, also muesste das z flag in der call funktion gesetzt werden.
es werden also keine serials miteinander verglichen, sondern nur ob die eingebene serial durch fest definierte mathematische funktionen 0 oder !=0 ergibt.

nochmal an den pc gesetzt und es kontrolliert, es ist in der tat so, dass in dem call aufruf das zero flag auf 1 bzw 0 gesetzt in abhängigkeit von der gültigkeit der serial.
war nen bissl tricky weil ein überlauf produziert wird, aber naja, bin noch anfänger
problem gelößt.


 
Zuletzt bearbeitet:
http://www.informatik.htw-dresden.de/~beck/ASM/assembler.html
(Abschnitt "bedingte Sprünge" - da sind auch die Flagzustände mit aufgelistet)
Nun setzen aber nicht alle Operationen diese Flags - d.h zwischen
solcher "Prüfungsoperation" und dem Sprung können ruhig diese eingeschoben
werden ;)

PS: nicht der Callaufruf, sondern TEST EAX,EAX ist hier entscheidend.
Denn dieses setzt oder löscht das ZF.
TEST EAX,EAX ist fast das gleiche
wie AND EAX,EAX (nur wird dabei der Inhalt des Registers nicht verändert).
 
in dem call wird das zflag schon "richtig" gesetzt (man koennte TEST EAX,EAX deshalb auch weglassen finde ich),

weis nicht ob das flag durch irgentwelche interrups geändert werden kann, da ja TEST EAX,EAX direkt nach dem call ist. aber schaden kann es nicht.
 
Zuletzt bearbeitet:
wieso ist TEST EAX,EAX das wichtige?
Weil TEST EAX,EAX die Flags trotzdem setzt - abhängig vom Inhalt ;)
EAX kann gerne den Wert 0 oder 01 haben. Das heißt aber noch lange nicht, dass ZF automatisch auch gesetzt ist ;). Z.B weil die Rückgabe EAX==0 oder EAX==1 am Ende der Funktion durch MOV EAX,0 / MOV EAX,1 oder MOV EAX, Variable
zustande gekommen ist. Dann ist EAX auch 0/1/was auch immer, die Flags werden dabei aber nicht verändert. Und natürlich können zwischen dem "nullsetzen" des Wertes irgendwo in der geCALLten Funktion und dem eigentlichen JE noch andere Operationen kommen - z.B am Ende der aufgerufenen Funktion:
Code:
MOV EAX, 0 (== hierbei wird ZF NICHT gesetzt)
ADD ESP, 20 (Stackbereinigung, hierbei wird ZF gelöscht, weil das Ergebniss dieser Operation ungleich 0 war).
RET
Um Missverständnisse zu vermeiden: Flags werden nur nach bestimmten Operationen in Abhängigkeit vom Registerinhalt gesetzt.

Edit:
jep, hier kann es sein, dass es überflüssig ist - nur kann der Compiler dies nicht immer erkennen.
 
Zurück
Oben