Keygenning
RE section is dead so yeah...
I'm trying to create a keygen for a crackme app, I'm a novice at all this, patching is easy, but serial fishing, meh, not that much for me.
Here's the code that takes care of the serial generation and checkup:
Now I don't quite understand, the serial is neither at EBP+C or calculated by the name's bytes. Strange but I fail to see a proper serial verification =/
Any help?
EDIT: Now that I take another look at it, it seems that the program calculates some kind of result from the name and then performs some kind of hash for the serial, then it xors them both to check if they are the same or not. HOWEVER I still cannot see the difference between.
So until now:
> Build a key based on the name given.
> Hash the serial.
> Use the key to interact with the hashed serial in order to determine if we have the right answer.
EDIT2: My C++ Code is as the follows
http://pastebin.com/wRx2LrGm
EDIT3:
Nvm, got it. The result was pretty obvious:
> Calculate a key based on the given name.
> Analyze the given serial and hash it to produce something new.
> Compare the key created with the hashed serial.
Basically we firstly need to create a key, easy peasy. Next we gotta create a serial which when we hash it is the same as the key. So basically do an inverse-hashing of the key and VIOLA! We have a working serial.
Final result:

Done in C++:
http://pastebin.com/UjrsJzSz
I'm trying to create a keygen for a crackme app, I'm a novice at all this, patching is easy, but serial fishing, meh, not that much for me.
Here's the code that takes care of the serial generation and checkup:
Code:
PUSH EBP ; In here we are asked to enter our name and then it will calculate some kind of serial based on the name given.
MOV EBP,ESP ; IDK
PUSH ECX ; Well, we all know this.
PUSH ECX ; Don't quite understand, why does it push ecx two times in a row?
AND DWORD PTR [EBP-4],0 ; Clear the address I guess?
PUSH ESI
MOV ESI,DWORD PTR [EBP+8]
PUSH EDI
PUSH ESI
CALL DWORD PTR [<&KERNEL32.lstrlenA>] ; kernel32.lstrlenA
MOV EDI,EAX ; Number of characters in our name.
XOR EDX,EDX
TEST EDI,EDI
JLE @crackme8_00401047
MOVSX ECX,BYTE PTR [EDX+ESI] ; Assign the currently working-on character to ecx.
ADD DWORD PTR [EBP-4],ECX ; Add ecx to the base pointer - 4
MOV DWORD PTR [EBP-8],ECX ; Do the same at bp-8
ROL DWORD PTR [EBP-4],1 ; Rotate the character bits by 1.
MOV EAX,ECX ; Assign the character to eax.
IMUL EAX,DWORD PTR [EBP-4] ; Multiplicate the character by the rotated bits.
MOV DWORD PTR [EBP-4],EAX ; Assign the result at bp-4
MOV EAX,DWORD PTR [EBP-8] ; Assign the character back to eax.
ADD DWORD PTR [EBP-4],EAX ; Modified byte + original byte.
XOR DWORD PTR [EBP-4],ECX ; XOR the result above with the old byte.
INC EDX ; i++
CMP EDX,EDI ; Are we done with each character?
JL @crackme8_0040101D
CMP DWORD PTR [EBP-4],0
JNZ @crackme8_00401063 ; Skip..
PUSH 0
PUSH Crackme8_0040230C ; ASCII "A problem has occurred"
PUSH Crackme8_004022CC ; ASCII "There is no valid key for this name, please use another one."
PUSH DWORD PTR [04023ACh]
CALL DWORD PTR [<&USER32.MessageBoxA>] ; apphelp.72C08650
XOR EAX,EAX
JMP @crackme8_0040107F
XOR DWORD PTR [EBP+0Ch],01337C0DEh ; EPB+C=Our given serial (when we run the app), so it's <ENTERED SERIAL> XOR 0x1337C0DE
SUB DWORD PTR [EBP+0Ch],0BADC0DE5h ; Substract.
MOV EAX,DWORD PTR [EBP-4] ; Assign our calculated value to EAX.
NOT DWORD PTR [EBP+0Ch] ; Reverse the XORed thing above.
XOR EAX,DWORD PTR [EBP+0Ch] ; CALCULATED VALUE XOR REVERSED XORed thing. Looking at the lines below this is probably to check whether EAX matches EBP+C
NEG EAX ; Since EAX is not 0, CF will be set to 1.
SBB EAX,EAX ; Since CF=1, this will result in -1.
INC EAX ; Increment EAX, which will be set to 0, therefore ZF=1 !!!!
POP EDI
POP ESI
LEAVE
RET
Any help?
EDIT: Now that I take another look at it, it seems that the program calculates some kind of result from the name and then performs some kind of hash for the serial, then it xors them both to check if they are the same or not. HOWEVER I still cannot see the difference between.
So until now:
> Build a key based on the name given.
> Hash the serial.
> Use the key to interact with the hashed serial in order to determine if we have the right answer.
EDIT2: My C++ Code is as the follows
http://pastebin.com/wRx2LrGm
EDIT3:
Nvm, got it. The result was pretty obvious:
> Calculate a key based on the given name.
> Analyze the given serial and hash it to produce something new.
> Compare the key created with the hashed serial.
Basically we firstly need to create a key, easy peasy. Next we gotta create a serial which when we hash it is the same as the key. So basically do an inverse-hashing of the key and VIOLA! We have a working serial.
Final result:

Done in C++:
http://pastebin.com/UjrsJzSz