Code:
00401069 /68 31404000 /PUSH Crackmme.00404031 ; ASCII "PW : "
0040106E |FF15 4C404000 |CALL DWORD PTR DS:[40404C] ; Crackmme.004020D3
00401074 |A1 2C434000 |MOV EAX,DWORD PTR DS:[40432C]
00401079 |50 |PUSH EAX
0040107A |50 |PUSH EAX
0040107B |FF15 50404000 |CALL DWORD PTR DS:[404050] ; Einlesen des Passworts
00401081 |8D0D 1C434000 |LEA ECX,DWORD PTR DS:[40431C]
00401087 |5A |POP EDX
00401088 |E8 830F0000 |CALL Crackmme.00402010
0040108D |FF35 1C434000 |PUSH DWORD PTR DS:[40431C]
00401093 |E8 A80F0000 |CALL Crackmme.00402040 ; feststellen der laenge
00401098 |89C3 |MOV EBX,EAX
0040109A |83FB 03 |CMP EBX,3
0040109D |7F 0D |JG SHORT Crackmme.004010AC ; kleiner als 3 == falsch
0040109F |68 13404000 |PUSH Crackmme.00404013 ; ASCII "Key laenge zu klein"
004010A4 |FF15 54404000 |CALL DWORD PTR DS:[404054] ; Crackmme.004022A4
004010AA ^ EB BD |JMP SHORT Crackmme.00401069
004010AC |FF35 1C434000 |PUSH DWORD PTR DS:[40431C]
004010B2 |8B15 14434000 |MOV EDX,DWORD PTR DS:[404314]
004010B8 |FF35 2C434000 |PUSH DWORD PTR DS:[40432C]
004010BE |E8 9D120000 |CALL Crackmme.00402360
004010C3 |8B15 18434000 |MOV EDX,DWORD PTR DS:[404318]
004010C9 |E8 92120000 |CALL Crackmme.00402360
004010CE |5A |POP EDX
004010CF |59 |POP ECX
004010D0 |8915 2C434000 |MOV DWORD PTR DS:[40432C],EDX
004010D6 |0315 48404000 |ADD EDX,DWORD PTR DS:[404048]
004010DC |E8 DF120000 |CALL Crackmme.004023C0 ; vergleiche eingabe mit festkodiertem
004010E1 |74 44 |JE SHORT Crackmme.00401127
004010E3 |FF35 1C434000 |PUSH DWORD PTR DS:[40431C]
004010E9 |E8 520F0000 |CALL Crackmme.00402040 ; nochmal laenge pruefen
004010EE |89C3 |MOV EBX,EAX
004010F0 |83FB 05 |CMP EBX,5
004010F3 |75 20 |JNZ SHORT Crackmme.00401115
004010F5 |68 37404000 |PUSH Crackmme.00404037 ; ASCII "Richtig"
004010FA |FF15 54404000 |CALL DWORD PTR DS:[404054] ; Crackmme.004022A4
wenn man nun an der Zeile:
Code:
004010DC |E8 DF120000 |CALL Crackmme.004023C0
in Olly angelangt ist, zeigen EDX und ECX auf die jeweiligen Strings - der eine ist die Eingabe, der andere das "Sollpasswort".
Höchstwahrscheinlich handelt es sich um die Vergleichsfunktion - es lohnt sich also diese noch genau anzuschauen:
Code:
004023C0 09D2 OR EDX,EDX
004023C2 75 05 JNZ SHORT Crackmme.004023C9
004023C4 BA 3F404000 MOV EDX,Crackmme.0040403F
004023C9 09C9 OR ECX,ECX
004023CB 75 05 JNZ SHORT Crackmme.004023D2
004023CD B9 3F404000 MOV ECX,Crackmme.0040403F
004023D2 8A22 MOV AH,BYTE PTR DS:[EDX] ; [edx] == speicheradresse des festkodierten passworts
004023D4 42 INC EDX
004023D5 8A01 MOV AL,BYTE PTR DS:[ECX] ; [ecx] == speicheradresse der Benutzereingabe
004023D7 41 INC ECX
004023D8 38C4 CMP AH,AL
004023DA 75 0C JNZ SHORT Crackmme.004023E8
004023DC 08E4 OR AH,AH
004023DE ^ 75 F2 JNZ SHORT Crackmme.004023D2 ; Vergleichsschleife
004023E0 B8 01000000 MOV EAX,1
004023E5 85C0 TEST EAX,EAX
004023E7 C3 RETN
schaut eigentlich nach "selbstgeschriebenem" Asm aus

Um zu verstehen, was hier gemacht wird, eignet sich wieder die "Ausprobiertaktik" - man geht langsam mittels "F8" durch den Code und schaut, was sich ändert - hier stellt man z.B fest, dass zuallererst in EDX/ECX die Stringreferenzen auf die Eingabe und (anscheinend) das Sollpassword geladen werden. Dann werden die jeweiligen Buchstaben eingelesen und verglichen. Nur wenn alles bis zum Ende verglichen werden kann (und die Strings damit übereinstimmen) wird eine 1 zurückgegeben.
Der Trick mit "Test eax,eax" ist ein Vergleich auf EAX == 0 noch in der Funktion selbst - nach sofortiger Rückkehr zum Aufrufer
Code:
004010DC |E8 DF120000 |CALL Crackmme.004023C0 ; vergleiche eingabe mit festkodiertem
004010E1 |74 44 |JE SHORT Crackmme.00401127
wird dieser Vergleich mittels JE "ausgewertet" (TEST EAX, EAX setzt den Z Flag, falls das Ergebnis von test eax, eax == 0 ist und JE (alias JZ) springt, wenn Z Flag gesetzt ist, weiter zu der "Falsch" Meldung.