Target: Fereter’s CrackMe by Fereter #1.
URL: http://crackmes.de/users/fereter/crackme_by_fereter_1./
Protection: Serial
Description: Crackme with a serial protection. Goal is to patch the crackme to accept any serial.
Tools: IDA, Hex-editor
First lets load the crackme in IDA and find where the serial check is.
If we open up the strings window we can find two strings that looks interesting, “Incorrect number.” and “Correct numner.”.
When we locate the usage of those strings we see that both of them are used in sub_4030E7. So lets check that sub-routine out.
.code:004030E7 sub_4030E7 proc near ; DATA XREF: .data:WndClasso
.code:004030E7
.code:004030E7 hWnd = dword ptr 8
.code:004030E7 Msg = dword ptr 0Ch
.code:004030E7 wParam = dword ptr 10h
.code:004030E7 lParam = dword ptr 14h
.code:004030E7
.code:004030E7 ; FUNCTION CHUNK AT .code:004032D8 SIZE 00000018 BYTES
.code:004030E7
.code:004030E7 push ebp
.code:004030E8 mov ebp, esp
.code:004030EA push ebx
.code:004030EB push esi
.code:004030EC push edi
.code:004030ED cmp [ebp+Msg], 1
.code:004030F1 jz short loc_403121
.code:004030F3 cmp [ebp+Msg], 111h
.code:004030FA jz loc_40319F
.code:00403100 cmp [ebp+Msg], 2
.code:00403104 jz loc_4032B1
.code:0040310A push [ebp+lParam] ; lParam
.code:0040310D push [ebp+wParam] ; wParam
.code:00403110 push [ebp+Msg] ; Msg
.code:00403113 push [ebp+hWnd] ; hWnd
.code:00403116 call ds:DefWindowProcA
.code:0040311C jmp loc_4032BB
.code:00403121 ; ---------------------------------------------------------------------------
.code:00403121
.code:00403121 loc_403121: ; CODE XREF: sub_4030E7+Aj
.code:00403121 push 0 ; lpParam
.code:00403123 push WndClass.hInstance ; hInstance
.code:00403129 push 64h ; hMenu
.code:0040312B push [ebp+hWnd] ; hWndParent
.code:0040312E push 14h ; nHeight
.code:00403130 push 64h ; nWidth
.code:00403132 push 0Ah ; Y
.code:00403134 push 4Eh ; X
.code:00403136 push 50002180h ; dwStyle
.code:0040313B push 0 ; lpWindowName
.code:0040313D push offset aEdit ; "edit"
.code:00403142 push 200h ; dwExStyle
.code:00403147 call ds:CreateWindowExA
.code:0040314D mov ds:hWnd, eax
.code:00403152 push eax ; hWnd
.code:00403153 call ds:SetFocus
.code:00403159 push 0 ; lParam
.code:0040315B push 8 ; wParam
.code:0040315D push 0C5h ; Msg
.code:00403162 push ds:hWnd ; hWnd
.code:00403168 call ds:SendMessageA
.code:0040316E push 0 ; lpParam
.code:00403170 push WndClass.hInstance ; hInstance
.code:00403176 push 65h ; hMenu
.code:00403178 push [ebp+hWnd] ; hWndParent
.code:0040317B push 14h ; nHeight
.code:0040317D push 64h ; nWidth
.code:0040317F push 28h ; Y
.code:00403181 push 4Eh ; X
.code:00403183 push 50000001h ; dwStyle
.code:00403188 push offset aCheck ; "Check"
.code:0040318D push offset aButton ; "button"
.code:00403192 push 0 ; dwExStyle
.code:00403194 call ds:CreateWindowExA
.code:0040319A jmp loc_4032B9
.code:0040319F ; ---------------------------------------------------------------------------
.code:0040319F
.code:0040319F loc_40319F: ; CODE XREF: sub_4030E7+13j
.code:0040319F mov eax, [ebp+wParam]
.code:004031A2 cmp ax, 65h
.code:004031A6 jnz loc_4032B9
.code:004031AC push 1 ; bSigned
.code:004031AE push offset Translated ; lpTranslated
.code:004031B3 push 64h ; nIDDlgItem
.code:004031B5 push [ebp+hWnd] ; hDlg
.code:004031B8 call ds:GetDlgItemInt
.code:004031BE push ds:Translated
.code:004031C4 rdtsc
.code:004031C6 mov ecx, eax
.code:004031C8 rdtsc
.code:004031CA sub eax, ecx
.code:004031CC cmp eax, 100h
.code:004031D1 jg loc_4032D8
.code:004031D7 pop ecx
.code:004031D8 cmp ecx, 1
.code:004031DB jz short loc_403203
.code:004031DD
.code:004031DD loc_4031DD: ; CODE XREF: sub_4030E7+140j
.code:004031DD ; sub_4030E7+1A8j
.code:004031DD ; DATA XREF: ...
.code:004031DD push 40h ; uType
.code:004031DF push offset Caption ; "CrackMe by Fereter"
.code:004031E4 push offset aIncorrectNumbe ; "Incorrect number."
.code:004031E9 push [ebp+hWnd] ; hWnd
.code:004031EC call ds:MessageBoxA
.code:004031F2 push ds:hWnd ; hWnd
.code:004031F8 call ds:SetFocus
.code:004031FE
.code:004031FE loc_4031FE: ; DATA XREF: sub_4030E7+165o
.code:004031FE jmp loc_4032B9
.code:00403203 ; ---------------------------------------------------------------------------
.code:00403203
.code:00403203 loc_403203: ; CODE XREF: sub_4030E7+F4j
.code:00403203 mov ds:dword_402024, eax
.code:00403208 push 10h ; cchMax
.code:0040320A push offset String ; lpString
.code:0040320F push 64h ; nIDDlgItem
.code:00403211 push [ebp+hWnd] ; hDlg
.code:00403214 call ds:GetDlgItemTextA
.code:0040321A mov eax, ds:String
.code:0040321F mov ecx, 34393237h
.code:00403224 inc ecx
.code:00403225 cmp eax, ecx
.code:00403227 jnz short loc_4031DD
.code:00403229 dec ecx
.code:0040322A mov eax, ds:dword_40202C
.code:0040322F mov ecx, 303138h
.code:00403234 mov ds:dword_402068, offset loc_4031DD
.code:0040323E
.code:0040323E loc_40323E: ; CODE XREF: sub_4030E7+1A4j
.code:0040323E mov ebx, ds:dword_402068
.code:00403244 cmp ebx, offset loc_4032B9
.code:0040324A jz short loc_40328D
.code:0040324C mov edx, offset loc_4031FE
.code:00403251 add edx, 1
.code:00403254 cmp ebx, edx
.code:00403256 jz short loc_40327C
.code:00403258 mov edx, offset loc_403275
.code:0040325D sub edx, 1
.code:00403260 cmp ebx, edx
.code:00403262 jz short loc_40327C
.code:00403264 mov edx, offset loc_40327A
.code:00403269 sub edx, 1
.code:0040326C cmp ebx, edx
.code:0040326E jz short loc_40327C
.code:00403270 mov bl, [ebx]
.code:00403272 cmp bl, 0CCh
.code:00403275
.code:00403275 loc_403275: ; DATA XREF: sub_4030E7+171o
.code:00403275 jz short loc_4032DD
.code:00403277 cmp bl, 90h
.code:0040327A
.code:0040327A loc_40327A: ; DATA XREF: sub_4030E7+17Do
.code:0040327A jz short loc_4032DD
.code:0040327C
.code:0040327C loc_40327C: ; CODE XREF: sub_4030E7+16Fj
.code:0040327C ; sub_4030E7+17Bj ...
.code:0040327C mov ebx, ds:dword_402068
.code:00403282 add ebx, 1
.code:00403285 mov ds:dword_402068, ebx
.code:0040328B jmp short loc_40323E
.code:0040328D ; ---------------------------------------------------------------------------
.code:0040328D
.code:0040328D loc_40328D: ; CODE XREF: sub_4030E7+163j
.code:0040328D cmp eax, ecx
.code:0040328F jnz loc_4031DD
.code:00403295 call sub_4032C2
.code:0040329A push 0 ; uType
.code:0040329C push offset Caption ; "CrackMe by Fereter"
.code:004032A1 push offset aCorrectNumner_ ; "Correct numner."
.code:004032A6 push [ebp+hWnd] ; hWnd
.code:004032A9 call ds:MessageBoxA
.code:004032AF jmp short loc_4032B9
.code:004032B1 ; ---------------------------------------------------------------------------
.code:004032B1
.code:004032B1 loc_4032B1: ; CODE XREF: sub_4030E7+1Dj
.code:004032B1 push 0 ; nExitCode
.code:004032B3 call ds:PostQuitMessage
.code:004032B9
.code:004032B9 loc_4032B9: ; CODE XREF: sub_4030E7+B3j
.code:004032B9 ; sub_4030E7+BFj ...
.code:004032B9 xor eax, eax
.code:004032BB
.code:004032BB loc_4032BB: ; CODE XREF: sub_4030E7+35j
.code:004032BB pop edi
.code:004032BC pop esi
.code:004032BD pop ebx
.code:004032BE leave
.code:004032BF retn 10h
So we want to make sure that all paths lead to loc_40328D and no paths leads to loc_4031DD.
Our first change will be the conditional jump right before loc_4031DD.
.code:004031D8 cmp ecx, 1
.code:004031DB jz short loc_403203 ; We want to change this to a JMP instead of JZ.
.code:004031DD
.code:004031DD loc_4031DD: ; CODE XREF: sub_4030E7+140j
.code:004031DD ; sub_4030E7+1A8j
.code:004031DD ; DATA XREF: ...
.code:004031DD push 40h ; uType
.code:004031DF push offset Caption ; "CrackMe by Fereter"
.code:004031E4 push offset aIncorrectNumbe ; "Incorrect number."
Lets take a look at the hex-codes for that region.
59 83 F9 01 74 26 6A 40 68
So we want to patch the byte with value 74 (offset 7DB) and change it to EB, our patched region will look like this.
59 83 F9 01 EB 26 6A 40 68
Now lets take a look at the location of the jump to see whats going on there.
.code:00403203 loc_403203: ; CODE XREF: sub_4030E7+F4j
.code:00403203 mov ds:dword_402024, eax
.code:00403208 push 10h ; cchMax
.code:0040320A push offset String ; lpString
.code:0040320F push 64h ; nIDDlgItem
.code:00403211 push [ebp+hWnd] ; hDlg
.code:00403214 call ds:GetDlgItemTextA
.code:0040321A mov eax, ds:String
.code:0040321F mov ecx, 34393237h
.code:00403224 inc ecx
.code:00403225 cmp eax, ecx
.code:00403227 jnz short loc_4031DD ; Jump to the incorrect number-message.
.code:00403229 dec ecx
.code:0040322A mov eax, ds:dword_40202C
.code:0040322F mov ecx, 303138h
.code:00403234 mov ds:dword_402068, offset loc_4031DD
Here we find the first input check and a conditional jump to the incorrect number-message. Lets change that jump to a unconditional jump to the correct number-message.
The hex-codes for the region with the conditional jump:
39 C8 75 B4 49
Here we want to patch the bytes with values 75 B4 (offset 827) and change them to EB 64 (JMP SHORT loc_40328D), patched region should look like this:
39 C8 EB 64 49
Finally we get to the correct number-message location. Lets take a look at what happens there.
.code:0040328D loc_40328D: ; CODE XREF: sub_4030E7+163j
.code:0040328D cmp eax, ecx
.code:0040328F jnz loc_4031DD ; Jump to the incorrect number-message.
.code:00403295 call sub_4032C2
.code:0040329A push 0 ; uType
.code:0040329C push offset Caption ; "CrackMe by Fereter"
.code:004032A1 push offset aCorrectNumner_ ; "Correct numner."
.code:004032A6 push [ebp+hWnd] ; hWnd
.code:004032A9 call ds:MessageBoxA
.code:004032AF jmp short loc_4032B9
Here we find a conditional jump to the incorrect number-message. Lets delete that jump.
Hex-codes for the conditional jump region:
39 C8 0F 85 48 FF FF FF E8 28 00 00 00
Here we want to NOP the bytes containing the values 0F 85 48 FF FF FF (offset 88F), our patched region should look like this:
39 C8 90 90 90 90 90 90 E8 28 00 00 00
When we run our patched version we get the Correct number-message when entering any serial.