|
First of all, as usual, let's check the main executable
program (BPK.EXE) using PEiD, well this time it's not
packed so our work will be easier, but also give a look
at the CRC signature which are present inside the
program.
Scanning the file "bpk.exe" with PeId 0.93: Microsoft
Visual C++ 6.0 PeID Krpyto plugin (kanal.dll) shows:
BASE64 table at 0044A340 , MD5 at 00406A4B. But don't
worry we will work around this problem indeed without
modifying a single bit of the target application.
Load file "bpk.exe" into Ollydbg. Press F9 to run it.
Running bring some ugly Nag. Enter some fake details
into registration boxes (click on: "Enter Registration
Code") :
user_name: Halle Berry
fake_serial: 1111 2222 3333 4444
Click on OK.
Another Nag popups: "Registration code or user name is
invalid. Please check all fields and try again!"..this
is the right point where to start using OllyDbg and
stopping the program.
Go back to Ollydbg and press F12 (Pause) and then Alt+K
(Call stack).
Call stack of
main thread
Address Stack Procedure / arguments Called from
0069BC34 00415139 ? <JMP.&MFC42.#4224> BPK.00415134
0069BC38 0044B0DC Arg1 = 0044B0DC ASCII "Registration
code or u
0069BC3C 0044B130 Arg2 = 0044B130 ASCII "Registration
error"
0069BC40 00000040 Arg3 = 00000040
0069BD38 0041548D ? BPK.00414F89 BPK.00415488
0069BD40 5F40228D Includes BPK.0041548D MFC42.5F40228A
0069BD50 5F4021E6 MFC42.5F4021F1 MFC42.5F4021E1
0069BD80 5F406506 MFC42.#4424 MFC42.5F406501
0069BDA4 5F402AE5 Includes MFC42.5F406506 MFC42.5F402AE2
0069BDF4 5F401BE1 Includes MFC42.5F402AE5 MFC42.5F401BDB
0069BE74 5F401AFF Includes MFC42.5F401BE1 MFC42.5F401AF9
0069BE94 5F401A88 Includes MFC42.5F401AFF MFC42.5F401A82
0069BEF4 5F401A10 MFC42.#1109 MFC42.5F401A0B
0069BF10 5F4019CF MFC42.#1578 MFC42.5F4019CA
0069BF3C BFF7363B Includes MFC42.5F4019CF
KERNEL32.BFF73638
0069BF5C BFF94407 ? KERNEL32.BFF735FD KERNEL32.BFF94402
Right click on: BPK.00415134 -> Show Call (your offset
might be different due to relocation of the program but
note that the right point is the only call into the BPK
program, all the other are into external libraries).
0041511C |. E8
211B0200 CALL <JMP.&MFC42.#860>
00415121 |. 6A 01 PUSH 1
00415123 |. 58 POP EAX
;
BPK.0044B130
00415124 |. EB 20 JMP SHORT BPK.00415146
00415126 |> 6A 40 PUSH 40
00415128 |. 68 30B14400 PUSH BPK.0044B130 ;
ASCII "Registration error"
0041512D |. 68 DCB04400 PUSH BPK.0044B0DC
; ASCII
"Registration code or user name is invalid. Please check
all fields and try again!"
00415132 |. 8BCE MOV ECX,ESI
00415134 |. E8 37200200 CALL <JMP.&MFC42.#4224>
; We are
here after -> Right click on: BPK.00415134 <-
00415139 |. 68 2C010000 PUSH 12C
; /Timeout =
300. ms
0041513E |. FF15 4CC14300 CALL NEAR DWORD PTR
DS:[<&KERNEL32.Sleep>;
\Sleep
00415144 |> 33C0 XOR EAX,EAX
;
BPK.0044B130
00415146 |> 8B4D F4 MOV ECX,[LOCAL.3]
00415149 |. 5F POP EDI
0041514A |. 5E POP ESI
0041514B |. 64:890D 000000>MOV DWORD PTR FS:[0],ECX
00415152 |. C9 LEAVE
00415153 \. C3 RETN
00415154 /$ 55 PUSH EBP
00415155 |. 8BEC MOV EBP,ESP
00415157 |. 83EC 40 SUB ESP,40
0041515A |. 8D45 C0 LEA EAX,[LOCAL.16]
0041515D |. 56 PUSH ESI
0041515E |. 50 PUSH EAX
;
BPK.0044B130
0041515F |. 68 50FA4300 PUSH BPK.0043FA50
; ASCII "_r
<()<1-Z2[l5,^"
Scroll up , until we are at the beginning of this
routine:
00414F89 /$ B8
1C9D4300 MOV EAX,BPK.00439D1C
; Put
breakpoint here (with F2).
00414F8E |. E8 BD230200 CALL <JMP.&MSVCRT._EH_prolog>
00414F93 |. 81EC DC000000 SUB ESP,0DC
00414F99 |. 56 PUSH ESI
00414F9A |. 57 PUSH EDI
00414F9B |. 8D85 4CFFFFFF LEA EAX,[LOCAL.45]
00414FA1 |. 6A 32 PUSH 32
00414FA3 |. 50 PUSH EAX
;
BPK.0044B130
00414FA4 |. 8BF1 MOV ESI,ECX
00414FA6 |. 68 D9D60000 PUSH 0D6D9
00414FAB |. E8 381F0200 CALL <JMP.&MFC42.#3098>
00414FB0 |. 80BD 4CFFFFFF >CMP BYTE PTR SS:[EBP-B4],0
00414FB7 75 53 JNZ SHORT BPK.0041500C
; Did the
sucker enter his name ?
After you put breakpoint , click again on OK. Ollydbg
should break.
Trace with F8 until here:
00415056 |. 50
PUSH EAX
; /String2 =
"1111"
00415057 |. 8D45 80 LEA EAX,[LOCAL.32] ; |
0041505A |. 50 PUSH EAX
; |String1 =
0069BCE8
0041505B |. FF15 38C14300 CALL NEAR DWORD PTR
DS:[<&KERNEL32.lstrc>;
\lstrcpyA
00415061 |. 8B3D 64C14300 MOV EDI,DWORD PTR
DS:[<&KERNEL32.lstrcat>
00415067 |. 8D45 D8 LEA EAX,[LOCAL.10]
0041506A |. 50 PUSH EAX
; /StringToAdd
= "1111"
0041506B |. 8D45 80 LEA EAX,[LOCAL.32] ; |
0041506E |. 50 PUSH EAX
; |ConcatString
= "1111"
0041506F |. FFD7 CALL NEAR EDI
; \lstrcatA
00415071 |. 8D45 C0 LEA EAX,[LOCAL.16]
00415074 |. 50 PUSH EAX
; /StringToAdd
= "1111"
00415075 |. 8D45 80 LEA EAX,[LOCAL.32] ; |
00415078 |. 50 PUSH EAX
; |ConcatString
= "1111"
00415079 |. FFD7 CALL NEAR EDI
; \lstrcatA
0041507B |. 8D45 CC LEA EAX,[LOCAL.13]
0041507E |. 50 PUSH EAX
; /StringToAdd
= "1111"
0041507F |. 8D45 80 LEA EAX,[LOCAL.32] ; |
00415082 |. 50 PUSH EAX
; |ConcatString
= "1111"
00415083 |. FFD7 CALL NEAR EDI
; \lstrcatA
00415085 |. 8D85 18FFFFFF LEA EAX,[LOCAL.58]
0041508B |. 50 PUSH EAX
What's this ? Well, program takes first 4 char. from our
fake_serial (from 1111 2222 3333 4444) and put them into
EAX.
Then it takes another 4 chars, do some manipulations
(add both strings), and the result is 11112222 .
Then after takes other 4 chars , so we get 111122223333.
Apply the same procedure for last 4 chars , result is
1111222233334444 .
Resume all using tracing, with F8 until here:
0041508C |.
8D85 4CFFFFFF LEA EAX,[LOCAL.45]
; load "Halle Berry" v EAX
00415092 |. 68 50FA4300 PUSH BPK.0043FA50
; ASCII "_r
<()<1-Z2[l5,^" ; push magic string to stack
00415097 |. 50 PUSH EAX
00415098 |. E8 1FFEFFFF CALL BPK.00414EBC
;
Interesting CALL , step into with F7
What's inside the call at 00414EBC:
1st iteration :
00414F08 |>
/8BC6 /MOV EAX,ESI
00414F0A |. |6A 19 |PUSH 19
00414F0C |. |99 |CDQ
; Convert
Double to Quad
00414F0D |. |F77D FC |IDIV [LOCAL.1]
; Signed
Integer Division (division with remainder)
00414F10 |. |8BC6 |MOV EAX,ESI
00414F12 |. |5B |POP EBX
; Pop Word
off Stack
00414F13 |. |8D0C3A |LEA ECX,DWORD PTR DS:[EDX+EDI]
; ECX
= "_r <()<1-Z2[l5,^"
00414F16 |. |99 |CDQ
00414F17 |. |F77D F8 |IDIV [LOCAL.2]
00414F1A |. |8B45 08 |MOV EAX,[ARG.1]
; load
string "Halle Berry" into EAX
00414F1D |. |0FB60402 |MOVZX EAX,BYTE PTR DS:[EDX+EAX]
;
take char. "H" (48) from string "Halle Berry" into EAX
00414F21 |. |0FB611 |MOVZX EDX,BYTE PTR DS:[ECX]
; take char. "_" (5F) from magic string into EDX
00414F24 |. |33C2 |XOR EAX,EDX
; EAX = EAX
xor EDX = 48 xor 5F = 17
00414F26 |. |99 |CDQ¸
; EBX = 19
00414F27 |. |F7FB |IDIV EBX
; EAX = EAX
div EBX = 17 div 19 = 0 ; remainder into EDX = 17
00414F29 |. |80C2 41 |ADD DL,41
; DL = DL + 41 (char. A) = 17 + 41 = 58 (char. X)
00414F2C |. |46 |INC ESI
; ESI = ESI
+ 1
00414F2D |. |3B75 0C |CMP ESI,[ARG.2]
00414F30 |. |8811 |MOV BYTE PTR DS:[ECX],DL
; MOVes
char. "X" v "_" ; changes ECX = "Xr <()<1-Z2[l5,^"
00414F32 |.^\7C D4 \JL SHORT BPK.00414F08
; Did we
finish? If no , jump.
00414F34 |> \8BC7 MOV EAX,EDI
; MOVes EDI
into EAX
00414F36 |. 5F POP EDI
; 82BA5FD8
00414F37 |> 5E POP ESI
; 82BA5FD8
00414F38 |. 5B POP EBX
; 82BA5FD8
00414F39 |. C9 LEAVE
00414F3A \. C3 RETN
; end of
CALL
2nd iteration:
00414F16 |. 99
|CDQ
; ECX = "r <()<1-Z2[l5,^" ; EDI = "Xr <()<1-Z2[l5,^"
00414F17 |. F77D F8 |IDIV [LOCAL.2]
00414F1A |. 8B45 08 |MOV EAX,[ARG.1]
00414F1D |. 0FB60402 |MOVZX EAX,BYTE PTR DS:[EDX+EAX]
;
take char. "a" (61) from string "Halle Berry" into EAX
00414F21 |. 0FB611 |MOVZX EDX,BYTE PTR DS:[ECX]
; take char.
"r" (72) from magic string into EDX
00414F24 |. 33C2 |XOR EAX,EDX
; EAX = EAX
xor EDX = 61 xor 72 = 13
00414F26 |. 99 |CDQ
; EBX = 19
00414F27 |. F7FB |IDIV EBX
; EAX = EAX div
EBX = 13 div 19 = 0 ; remainder into EDX = 13
00414F29 |. 80C2 41 |ADD DL,41
; DL = DL +
41 (char. A) = 13 + 41 = 54 (char. T) ; EDX = 13
00414F2C |. 46 |INC ESI
00414F2D |. 3B75 0C |CMP ESI,[ARG.2]
00414F30 |. 8811 |MOV BYTE PTR DS:[ECX],DL
00414F32 |.^ 7C D4 \JL SHORT BPK.00414F08
; ECX = "T
<()<1-Z2[l5,^" ; EDI = "XT <()<1-Z2[l5,^"
3rd iteration:
00414F1D |.
0FB60402 |MOVZX EAX,BYTE PTR DS:[EDX+EAX]
; take char.
"l" (6C) from string "Halle Berry" into EAX
00414F21 |. 0FB611 |MOVZX EDX,BYTE PTR DS:[ECX]
; take char.
" " (20) from magic string into EDX
00414F24 |. 33C2 |XOR EAX,EDX
; EAX = EAX
xor EDX = 6C xor 20 = 4C
00414F27 |. F7FB |IDIV EBX
; EAX = EAX
div EBX = 4C div 19 = 3 ; remainder into EDX = 1 ; 4C =
3 * 19 + 1
00414F29 |. 80C2 41 |ADD DL,41
; DL = DL +
41 (char. A) = 1 + 41 = 42 (char. B)
00414F2C |. 46 |INC ESI
00414F2D |. 3B75 0C |CMP ESI,[ARG.2]
00414F30 |. 8811 |MOV BYTE PTR DS:[ECX],DL
00414F32 |.^\7C D4 \JL SHORT BPK.00414F08
; ECX =
"B<()<1-Z2[l5,^" ; EDI = "XTB<()<1-Z2[l5,^"

After
all chars from user_name are taken and manipulated by
the code, the final result is into the EDI regiser: EDI
= "XTBFCJBJUPATNOOJ"
Halle Berry
XTBF-CJBJ-UPAT-NOOJ
Reg. info are stored into the file "pk.bin" . |