|
|
|
|
|
|
|
|
|
|
||
|
||
|
|
There is a crack, a crack in everything. That's how the light gets in. |
|
|
|
Ok, enter 54545454545454 as the key. Ctrl-D into Soft-Ice and set a breakpoint by typing bpx hmemcpy. Ctrl-D to get out of Soft-Ice and back to SnagIt. Now, press Ok button and you are back to Soft-Ice. Press F11 and then F12 (7 or 8 times) to go back to the SnagIt32 process.
F10 until you arrive at
: :0041878D 80382D cmp byte ptr [eax], 2D ; reg. code contains '-'? :00418790 7503 jne 00418795 :00418792 40 inc eax :00418793 EBF8 jmp 0041878D :00418795 8A10 mov dl, byte ptr [eax] ; if not, put it in dl :00418797 8811 mov byte ptr [ecx], dl ; store dl to the location ; that ecx points to :00418799 41 inc ecx :0041879A 40 inc eax :0041879B 3BCD cmp ecx, ebp :0041879D 72EE jb 0041878Dbasically, the above loop just get rid of any '-' in your fake key if there is.
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0041878B(C) | :0041879F 802100 and byte ptr [ecx], 00 ; make sure '0' is at the ; end of the fake key :004187A2 8D6F5C lea ebp, dword ptr [edi+5C] :004187A5 53 push ebxtype 'd ebp', you will see, in the data window, 4 hex codes in front of your fake key. In my case, it looks like
80 44 06 02 35 34 35 34 35 34 ......so, let's 'd 02064480' to see what is there. Well, yes, it shows the name in the data window.
* Possible Reference to Dialog: DialogID_00E1, CONTROL_ID:0032, "H&elp" | :004187A6 6A32 push 00000032 :004187A8 8BCD mov ecx, ebp :004187AA E8156D0400 call 0045F4C4 ; convert your name to upper case ; so, if you 'd eax', you will see ; EVC_VIPER :004187AF 50 push eax :004187B0 8BCE mov ecx, esi :004187B2 E893C00100 call 0043484A ; (1) :004187B7 6AFF push FFFFFFFFAfter return back from 'call 0043484A', EAX=00000A00. Keep this in mind.
:004187B9 8BCD mov ecx, ebp :004187BB 89442414 mov dword ptr [esp+14], eax :004187BF E84F6D0400 call 0045F513 ; (2) :004187C4 6A01 push 00000001 :004187C6 58 pop eax :004187C7 38442410 cmp byte ptr [esp+10], al ; esp+10 = 0 :004187CB 0F85B4000000 jne 00418885 ; jump if bad reg codeIf you F10 004187CB, and keep F10 several times, the nag screen will pup up saying that 'you must enter a valid registration key'. Hence, you know the 'cmp byte ptr [esp+10], al' is the point to decide the input registration key is true or fake. Ok, what should we do know? I have traced this proggy several hours and it seems that it is impossible to sniff out the real registration key (I mean, the real key shows up in the data window for you to see -- like, hey, I am here~~~). But, I am pretty sure (well, my sixth sense) that at some where, our fake key is compared with real one. The question now is : where is the comparision routine? Answer: inside the call in (1) and (2) I marked above. Before we go on, if you trace the code again and d esp+10 at 004187c7, you will see '00 0A .......'. Hmmm...... isn't that something +ViPeR+ want me to keep in mind? Anyway, esp+10 = 0 and al=1, so, jump (not equal) and you are a bad cracker. Ok. I want to check the call labeled (2) first. Why? coz I knew it is short and I want to see if it got something to do with that esp+10.
* Referenced by a CALL at Addresses: |:004077B9 , :0040C7DD , :00410DC8 , :004181B7 , :004181F0 |:004187BF , :0041B67A , :0042468A , :0042A74D , :0042AA47 |:0042AAAD , :0042ADF6 , :0042AE44 , :0042AF0A , :0042AF55 |:0042AF76 , :0042B578 , :0043209E , :004320AF , :004320C0 |:004320D1 , :00433938 , :00433A35 , :00433A9C , :00433AE3 |:00433BA6 , :00433E84 , :004341B0 , :00436416 , :0045788D |:00457DB7 , :00457E29 , :00457EE5 , :00457F72 , :0045C023 |:0045C086 , :0045F278 , :0045F6EF , :0045FFC2 , :00460278 |:0046040A , :004615CF , :00461962 , :00461E8F , :00461F11 |:00463DE5 , :00463F82 , :004640EF , :004641CE , :0046B7C9 |:0046CF56 , :004709FB , :0047152A , :00471632 , :004724ED |:00474FCF , :00476859 , :00477035 | :0045F513 56 push esi :0045F514 8BF1 mov esi, ecx :0045F516 E86EFBFFFF call 0045F089 :0045F51B 8B442408 mov eax, dword ptr [esp+08] :0045F51F 83F8FF cmp eax, FFFFFFFF :0045F522 7508 jne 0045F52C :0045F524 FF36 push dword ptr [esi] * Reference To: KERNEL32.lstrlenA, Ord:0308h | :0045F526 FF1554C34700 Call dword ptr [0047C354] * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0045F522(C) | :0045F52C 8B0E mov ecx, dword ptr [esi] :0045F52E 8941F8 mov dword ptr [ecx-08], eax :0045F531 8B0E mov ecx, dword ptr [esi] :0045F533 5E pop esi :0045F534 80240100 and byte ptr [ecx+eax], 00 :0045F538 C20400 ret 0004Well, after return back, esp+10 is still 0. So, I waste a little bit of time. Anyway, the call at (1) is the key to unlock the secret. So, re-do the above trace and F8 into 'call 0043484A' at 004187B2.
:0043484A 55 push ebp :0043484B 8BEC mov ebp, esp :0043484D 83EC50 sub esp, 00000050 :00434850 8365F800 and dword ptr [ebp-08], 00000000 :00434854 8065FE00 and byte ptr [ebp-02], 00 :00434858 53 push ebx :00434859 56 push esi :0043485A 57 push edi :0043485B 6A0F push 0000000F :0043485D 8D45E4 lea eax, dword ptr [ebp-1C] :00434860 6A00 push 00000000 :00434862 8BD9 mov ebx, ecx :00434864 50 push eax :00434865 C745F401000000 mov [ebp-0C], 00000001 :0043486C C645FF01 mov [ebp-01], 01 :00434870 E8EB2B0100 call 00447460 :00434875 8B7D0C mov edi, dword ptr [ebp+0C] ; edi is the fake key :00434878 8B3554C34700 mov esi, dword ptr [0047C354] :0043487E 83C40C add esp, 0000000C :00434881 57 push edi ; fake key :00434882 FFD6 call esi ; calculate the length of the fake key :00434884 50 push eax ; eax=0000000E :00434885 8D45E4 lea eax, dword ptr [ebp-1C] :00434888 57 push edi ; push fake key into stack :00434889 50 push eax :0043488A E8312C0100 call 004474C0 ; uppercase the name :0043488F 83C40C add esp, 0000000C :00434892 8BCB mov ecx, ebx :00434894 FF7508 push [ebp+08] ; name becomes 'EVC_VIPER' :00434897 E8B1000000 call 0043494D :0043489C 8945F8 mov dword ptr [ebp-08], eax : :After this, you will see a lot of CALL and TEST. But trust me, only the following is the one worth tracing.
: : :004348E2 8D45E4 lea eax, dword ptr [ebp-1C] :004348E5 50 push eax :004348E6 8D45B0 lea eax, dword ptr [ebp-50] :004348E9 50 push eax :004348EA E8216EFFFF call 0042B710 ; <-- this is the one we need to get in.The call at 004348EA is the routine that compare our fake key with the real key. ^_^ So, what are we waiting for, let's dive in right away.
* Referenced by a CALL at Address: |:004348EA | :0042B710 55 push ebp :0042B711 8BEC mov ebp, esp :0042B713 83EC7C sub esp, 0000007C :0042B716 6A30 push 00000030 :0042B718 33C9 xor ecx, ecx :0042B71A 58 pop eaxAbove code is not real interesting.
:0042B71B 0FB7D1 movzx edx, cx :0042B71E 41 inc ecx :0042B71F 884415EC mov byte ptr [ebp+edx-14], al :0042B723 40 inc eax :0042B724 663D3900 cmp ax, 0039 :0042B728 76F1 jbe 0042B71BBasically, the loop above generate '0123456789' and write it to the location that epb+dex-14 points to.
:0042B72A 6A41 push 00000041 ; 41(hex)='A' :0042B72C 58 pop eax :0042B72D 0FB7D1 movzx edx, cx :0042B730 41 inc ecx :0042B731 884415EC mov byte ptr [ebp+edx-14], al :0042B735 40 inc eax :0042B736 663D4600 cmp ax, 0046 :0042B73A 76F1 jbe 0042B72DThe same pattern as above, but this time, it generates 'ABCDEF' and appends them to the end of the above '0123456789'.
:0042B73C 53 push ebx :0042B73D 56 push esi :0042B73E 57 push edi ; edi contains fake key :0042B73F 8B7D0C mov edi, dword ptr [ebp+0C] ; ebp+c contains another ; copy of the fake key :0042B742 6A02 push 00000002 :0042B744 894DFC mov dword ptr [ebp-04], ecx :0042B747 8D470C lea eax, dword ptr [edi+0C] :0042B74A 50 push eax ; 'd eax' and you will see the last two ; characters of the fake key. ; This is an important hint. : :The rest of the code after 0042B74A contains a lot of moving memory location and function call.
: :0042B79E E88DD9FFFF call 00429130 :This call is the one I consider the most important one because it generates the real registration key (based on the last two registration keys you entered if my guessing is right). Don't F10 this call at this moment (if you did already, please re-try this lecture up to this point, sorry). Before this call, there are two instructions involve EAX register, just d eax before you F10 this call and you will see something in your data window.
What this function does is :it generates the 16 hex codes and store them in the memory somewhere. Where? you might wonder. Still remember that memory address the program generates '0123456789ABCDEF'? The 16 hex codes are just above that string.
In my case, since I use Name:evc_viper, key:54545454545454, so why I see on my data window is
: BF 67 F0 C8 6C DC 55 EF CD A6 30 05 4B CB BF 21 :Notice the even index hex code, what I mean is BF F0 6C 55 CD 30 4B BF. After this string has been generated, what the program should do? Of course, do the comparision with the fake key and here it is.
:0042B7B5 0FB7F3 movzx esi, bx :0042B7B8 8BC6 mov eax, esi :0042B7BA D1E8 shr eax, 1 :0042B7BC 8A0438 mov al, byte ptr [eax+edi] :0042B7BF 50 push eax :0042B7C0 E834FFFFFF call 0042B6F9 :0042B7C5 59 pop ecx :0042B7C6 8A4C35DC mov cl, byte ptr [ebp+esi-24] :0042B7CA 83E10F and ecx, 0000000F :0042B7CD 38440DEC cmp byte ptr [ebp+ecx-14], al :0042B7D1 7510 jne 0042B7E3 :0042B7D3 43 inc ebx :0042B7D4 43 inc ebx :0042B7D5 6683FB10 cmp bx, 0010 :0042B7D9 72DA jb 0042B7B5 :0042B7DB 6A01 push 00000001 :0042B7DD 58 pop eax :0042B7DE 5F pop edi :0042B7DF 5E pop esi :0042B7E0 5B pop ebx :0042B7E1 C9 leave :0042B7E2 C3 retHere, I will explain how the comparision work.
Since there are two inc ebx, so, only the first 8 keys will be compared(the key on the even index). But, this is not the end of the story. Ok, suppose that we get our first 8 correct registration keys. what else? of course we return to the calling routine and it is at
:004348EF 59 pop ecx :004348F0 85C0 test eax, eax :004348F2 59 pop ecx :004348F3 7509 jne 004348FE ; if EAX=1, then you pass the first ; phase of checking, and jump to 004348FE :004348F5 2045FF and byte ptr [ebp-01], al ; otherwise, set ebp-01 to 00 :004348F8 C645FE0A mov [ebp-02], 0A ; set ebp-02 to 0A :004348FC EB40 jmp 0043493E(Do you still remember I have mention at the very beginning something like '.... and EAX=00000A00 keep this in mind.'? or you have already totally lost in my lecture? Anyway, if the first 8 keys is not right, 0A00 is put in EAX. I don't really understand what is the main purpose of 0A. Anyway, let's keep going. Hey, don't fall asleep, go take a coffee and read on. Don't forget you want to be a real cracker not a lamer.
Ok, we have passed the first 8 keys checking, then we jump to 004348FE.
:004348FE 57 push edi :004348FF FFD6 call esi ; string length function :00434901 83F80E cmp eax, 0000000E ; length of registration key should ; be at least 14 characters. ; I enter exactly 14 caracters. :00434904 7C30 jl 00434936 :00434906 83C70C add edi, 0000000C ; edi=fake key location ; so, edi+c points to the last two ; fake key (54 in my case)coz I entered ; 14 characters. :00434909 6A02 push 00000002 :0043490B 57 push edi :0043490C E8886DFFFF call 0042B699 ; F10 this call, I saw EAX=00000054 ; 54 is the last two keys in my last fake key :00434911 59 pop ecx :00434912 83F841 cmp eax, 00000041 :00434915 59 pop ecx :00434916 7304 jnb 0043491C :00434918 33C0 xor eax, eax :0043491A EB08 jmp 00434924 :0043491C 83E841 sub eax, 00000041 :0043491F 83F840 cmp eax, 00000040 :00434922 7303 jnb 00434927 :00434924 83C00D add eax, 0000000D :00434927 83F841 cmp eax, 00000041 :0043492A 7312 jnb 0043493E :0043492C 8065FF00 and byte ptr [ebp-01], 00 ; (3) if the program goes here, ; you are still a bad cracker :00434930 C645FE0B mov [ebp-02], 0B :00434934 EB08 jmp 0043493E :00434936 8065FF00 and byte ptr [ebp-01], 00 ; (4) if the program goes here, ; again, you are still a bad ; cracker :0043493A C645FE0C mov [ebp-02], 0C :0043493E 33C0 xor eax, eax :00434940 5F pop edi :00434941 8A65FE mov ah, byte ptr [ebp-02] :00434944 5E pop esi :00434945 8A45FF mov al, byte ptr [ebp-01] ; if you have visited (3) or (4) ; then, al=0 and you will be dead ; soon. :00434948 5B pop ebx :00434949 C9 leave :0043494A C20800 ret 0008Therefore, in order to by pasee the above (3) and (4) block, your last two keys in the registration code should be at least 82. So, I change my key to: 54545454545482 and re-trace again.
VERY IMPORTANT NOTE:Since you have change the last two keys and coz the key generation routine is (kind of) based on those two key, so you have to set a breakpoint at 0042B79D, do a d eax, then F10 the real key generation roution and write down the first 8 correct keys.
In my case, it generates
7A 52 88 F6 64 A1 A1 69 C3 79 AD EB D7 06 3F 95
So the first 8 keys are : A8413D7F and my correct key is A8413D7F545482, with
name: evc_viper.
|
My thanks and gratitude goes to:-
Fravia+ for providing possibly the greatest
source of Reverse Engineering
knowledge on the Web.
|