²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²² ²² ____ __ __ ²²ßÛ ²² / _/_ _ __ _ ___ ____/ /____ _/ / ²² ÛßÛ ²² _/ // ' \/ ' \/ _ \/ __/ __/ _ `/ / ²² Û Û ²² /___/_/_/_/_/_/_/\___/_/ \__/\_,_/_/ ²² Û Û ²² ____ __ __ ²² Û Û ²² / __ \___ ___ _______ ___ ___/ /__ ____ / /____²² Û Û ²² / /_/ / -_|_-. So this listing is exactly the same code, but you have a much better overview. .text:00401289 call j_?GetDlgItemTextA@CWnd@@QBEHHPADH@Z ; CWnd::GetDlgItemTextA(int,char *,int) .text:0040128E lea eax, [ebp+var_104] .text:00401294 push eax <- eax is a pointer to the buffer holding your nick, type d eax to see your nick ;) this pointer gets pushed onto onto stack, used for _strlen. .text:00401295 call _strlen <- _strlen, that's why the return value in eax was '7', 'cause there are 7 chars in 'defiler'. .text:0040129A mov ebx, eax <- eax is holding the number of characters of the nick you entered. .text:0040129C pop ecx .text:0040129D test ebx, ebx <- ebx is zero, when user didn't enter anything this is the first part to memorize. .text:0040129F jle short loc_0_4012BB <- skip first serial-calculation-part the algorithm calculating your serial starts HERE : .text:004012A1 loc_0_4012A1: ; CODE XREF: sub_0_401265+54j .text:004012A1 movsx eax, [ebp+edi+var_104] <- eax(al) is holding the first char of your nick. .text:004012A9 lea ecx, [esi+eax*4] <- ecx=eax*4+esi - explanation: eax is holding the first char of your nick, will then be multiplicated by 4, esi (initialized with 0) will be added and finally stored into ecx(esi and eax will NOT be affected). .text:004012AC add eax, ecx <- this number stored in ecx will be added to to your nick's first char. .text:004012AE imul eax, edi <- eax=eax*edi - explanation: eax will be multiplicated with edi, the result will be stored in eax (edi also got initialized with 0). .text:004012B1 shl eax, 0Ah <- shift eax 0ah(10) bytes left. .text:004012B4 inc edi <- edi=edi+1 .text:004012B5 mov esi, eax <- esi=eax .text:004012B7 cmp edi, ebx <- compare edi with number of bytes in nick .text:004012B9 jl short loc_0_4012A1 <- if edi is lower, go on with serial calculation. .text:004012BB .text:004012BB loc_0_4012BB: ; CODE XREF: sub_0_401265+3Aj .text:004012BB mov ecx, [ebp+var_4] .text:004012BE push 0 <- parametres for the GetDlgItemInt Api .text:004012C0 push 0 .text:004012C2 push 3E9h .text:004012C7 call j_?GetDlgItemInt@CWnd@@QBEIHPAHH@Z ; CWnd::GetDlgItemInt(int,int *,int) .text:004012CC lea ecx, [esi+ebx+0FAACCDh] <- ecx=esi+ebx+0FAACCDh - explanation: esi is holding our previously calculated serial, ebx the length of your nickname, 0FAACCDh is an ugly constant and it will simply be added together and stored into ecx. .text:004012D3 pop edi .text:004012D4 pop esi .text:004012D5 pop ebx .text:004012D6 cmp ecx, eax <- here we have a comparison between 2 registers. you know that ecx contains some weird number, that got calculated using your nick.so eax must be a dummy serial.if you'll have a look at the code below, you'll first see a conditional jump (the one, you've always patched before, as tKC told you ;), then a nice string, that'll be displayed in a msgbox.the jump will only jump, if the zero-flag was set.the zero flag will be set, when ecx and eax do NOT differ, in other words: when they are equal ;) type '? ecx' to get your serial. .text:004012D8 push 0 .text:004012DA jnz short loc_0_4012F7 <- are serials equal ? if not, jump to bad boy .text:004012DC mov ecx, [ebp+var_4] .text:004012DF push offset aRichtigerCode ; "Richtiger Code" .text:004012E4 push offset unk_0_403054 .text:004012E9 call j_?MessageBoxA@CWnd@@QAEHPBD0I@Z ; CWnd::MessageBoxA(char const *,char const *,uint) .text:004012EE mov byte_0_4031BC, 1 <- most probably a boolean variable, 1=true=regged .text:004012F5 leave .text:004012F6 retn .text:004012F7 ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ .text:004012F7 .text:004012F7 loc_0_4012F7: <- bad guy Ok, I've marked the things we need for a keygen with green. Now a little summary for our keygen: .text:00401285 xor edi, edi <- edi=0 .text:00401287 xor esi, esi <- esi=0 .text:0040129D test ebx, ebx <- if no serial entered, jump to .text:0040129F jle short loc_0_4012BB <- loc_0_4012BB .text:004012A1 loc_0_4012A1: .text:004012A1 movsx eax, [ebp+edi+var_104] <- eax=Name[ebp+edi+var_104] .text:004012A9 lea ecx, [esi+eax*4] <- ecx=esi+eax*4 .text:004012AC add eax, ecx <- eax=eax+ecx .text:004012AE imul eax, edi <- eax=eax*edi .text:004012B1 shl eax, 0Ah <- shl eax,0ah .text:004012B4 inc edi <- edi=edi+1 .text:004012B5 mov esi, eax <- esi=eax .text:004012B7 cmp edi, ebx <- loop until edi=len(name) .text:004012B9 jl short loc_0_4012A1 .text:004012BB loc_0_4012BB: .text:004012CC lea ecx, [esi+ebx+0FAACCDh] <- ecx=esi+ebx+0FAACCDh ;ebx=len(name) ecx is our serial ;) This is all info you need to build a keygen for DaBrain's crackme #1. ======================================================================== GREETINGS (no specific order) ======================================================================== ultraschall,sat0r,targ0n,AB4DS,iczelion,hutch,ratso,KeyboardJunky,lazarus, f0dder,cardenal mendoza,cTT,Kaparo,noos,neuralnoise,visionz,kaai,lw2000, ferrex(du stinkst so abartig),DnNuke,_mcp_,innu3ndo,LightDruid,masta,notty, knotty,kwayzy webbit,secret,mister e,peegee,antixryst,acidburn,azzyrian, #win32asm,#cracking,#cracking4newbies,#elitereverser and all i forgot (sorry) a special greeting to kobold666 btw: i didn't get her :( defiler@elitereversers.de