Crack Tutorial by Vizion, 09/97 [TARGET...........]: ByteCatcher v1.03 (url : www.save-it.com) [TOOLS............]: W32Dasm v8.9, SoftIce 3.01 [PROTECTION.......]: name/registration key type [REMARK(s)........]: This program is probably cracked by a dozen of other persons, this target could be a nice addition to Fravia's "Most Stupid Protection" part of his page [PRECRaCK NOTES...]: I assume that you have some knowledge about ASM and are able to use W32Dasm and SoftIce [THe KEY..........]: Ok, here we go. First of all make a dead-listing with W32Dasm to check what .dll files are used, this is always usefull I was told ;). In WD32asm goto the "Imported Functions" part, there we see the following : +++++++++++++++++++ IMPORTED FUNCTIONS ++++++++++++++++++ Number of Imported Modules = 13 (decimal) Import Module 001: WSOCK32.dll Import Module 002: WINMM.dll Import Module 003: KERNEL32.dll Import Module 004: USER32.dll <-- interesting, so jump to user32.dll Import Module 005: GDI32.dll Import Module 006: comdlg32.dll Import Module 007: WINSPOOL.DRV Import Module 008: ADVAPI32.dll Import Module 009: SHELL32.dll Import Module 010: COMCTL32.dll Import Module 011: oledlg.dll Import Module 012: ole32.dll Import Module 013: OLEAUT32.dll .... Import Module 004: USER32.dll ... Addr:0008BD70 hint(0168) Name: IsWindowEnabled Addr:0008BD60 hint(01AF) Name: PeekMessageA Addr:0008BD4C hint(0245) Name: TranslateMessage Addr:0008BD38 hint(0090) Name: DispatchMessageA Addr:0008BD2A hint(00C8) Name: EnumWindows Addr:0008BD18 hint(013F) Name: GetWindowTextA <--- interesting Addr:0008BD04 hint(00B8) Name: EnumChildWindows Addr:0008BCF2 hint(0152) Name: InvalidateRect Addr:0008BCE0 hint(01CC) Name: ReleaseCapture Addr:0008BCD2 hint(0194) Name: MessageBeep ... Enough dead-listing for now. We can see that BC (ByteCacther) uses the GetWindowTextA function (also often used is : GetDlgItemTextA). So let's try it... start SI (SoftIce). Load BC and goto Help|About ByteCatcher. Now you'll see a register button in the "About-box". Press it! Ok now enter your information, I used : registration number : 12121212 name : Vizion company name : VCrackz'97 Press Ok. You'll get the message "Sorry that number is incorrect....". Ok, don't panic, get in SI (Ctrl-D), and set a breakpoint on "GetWindowTextA", type (in SI) : BPX GetWindowTextA Get out SI (Ctrl-D, again). Press OK. CA!BOOM you should be back in SI, right in the GetWindowTextA function. Disable the the breakpoint type (in SI) : BD 0 Press F11 to get back to the BC-code, write down the addr:offset for me it was 001B:0043C184 (addr could be different for you). Ok, back to the dead-listing in W32Dasm, in "Goto|Goto Code Location" use the offset you wrote down. Now you should see the following code : * Reference To: USER32.GetWindowTextA, Ord:013Fh | :0043C17E FF1574AF4800 Call dword ptr [0048AF74] :0043C184 8B4D10 mov ecx, dword ptr [ebp+10] :0043C187 6AFF push FFFFFFFF :0043C189 E87A82FFFF call 00434408 :0043C18E EB0B jmp 0043C19B <-- jump to 0043C19B ... * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0043C18E(U) | :0043C19B 5F pop edi :0043C19C 5E pop esi :0043C19D 5D pop ebp :0043C19E C20C00 ret 000C <-- return to 00413977 (*) ... :00413977 8D4E60 lea ecx, dword ptr [esi+60] :0041397A 51 push ecx :0041397B 68F8030000 push 000003F8 :00413980 57 push edi :00413981 E8C9870200 call 0043C14F :00413986 83C664 add esi, 00000064 :00413989 56 push esi :0041398A 680B040000 push 0000040B :0041398F 57 push edi :00413990 E8BA870200 call 0043C14F :00413995 5F pop edi :00413996 5E pop esi :00413997 C20400 ret 0004 <--- return to 00432E0F (*) ... :00432E0F C7450801000000 mov [ebp+08], 00000001 :00432E16 EB27 jmp 00432E3F <--- jump to 00432E3F :00432E18 B83C2E4300 mov eax, 00432E3C :00432E1D C3 ret ... :00432E3F 8B45E8 mov eax, dword ptr [ebp-18] :00432E42 8B4DF4 mov ecx, dword ptr [ebp-0C] :00432E45 8987B8000000 mov dword ptr [edi+000000B8], eax :00432E4B 8B4508 mov eax, dword ptr [ebp+08] :00432E4E 5F pop edi :00432E4F 5E pop esi :00432E50 64890D00000000 mov dword ptr fs:[00000000], ecx :00432E57 5B pop ebx :00432E58 C9 leave :00432E59 C20400 ret 0004 <--- return to 00413A5A (*) ... :00413A5A 8B465C mov eax, dword ptr [esi+5C] * Possible StringData Ref from Data Obj ->"98437856278" | :00413A5D 68FCF34700 push 0047F3FC :00413A62 50 push eax :00413A63 E8B87F0000 call 0041BA20 <--- interesting :00413A68 83C408 add esp, 00000008 :00413A6B 85C0 test eax, eax <--- interesting :00413A6D 7552 jne 00413AC1 <--- jump if not equal :00413A6F 57 push edi :00413A70 E84E6B0300 call 0044A5C3 :00413A75 8B4E5C mov ecx, dword ptr [esi+5C] :00413A78 8B7804 mov edi, dword ptr [eax+04] :00413A7B 51 push ecx ... Ok, now what do we see, * Possible StringData Ref from Data Obj ->"98437856278" Now it can't be that simple can it :). Well let's presume we didn't see that... So now let's check the call (press F8 in SI, to enter the call) to 0041BA20 : * Referenced by a CALL at Addresses: |:00401F56 , :00401FD5 , :0040288C , :00404296 , :00404C23 |:004065F2 , :00406608 , :0040CA6A , :0040CB2B , :0040DDA1 |:0040DDC3 , :00413A00 , :00413A63 , :00415BDB , :00415BF1 |:004163C5 , :00416841 , :0041701E , :00417516 , :00417571 |:00417BF1 , :004184D8 , :0042F9D8 , :0042FE23 , :0042FE3B |:0044082E , :00443416 , :00443478 , :004434E2 , :0044369E |:00443764 , :0044382A , :00447A16 , :0044D0CF , :00454429 |:0045B11E | :0041BA20 A144764800 mov eax, dword ptr [00487644] :0041BA25 53 push ebx :0041BA26 55 push ebp :0041BA27 33ED xor ebp, ebp :0041BA29 56 push esi :0041BA2A 3BC5 cmp eax, ebp :0041BA2C 57 push edi :0041BA2D 7541 jne 0041BA70 :0041BA2F 8B742418 mov esi, dword ptr [esp+18] <--- move good value to esi :0041BA33 8B442414 mov eax, dword ptr [esp+14] <--- move your value to eax * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0041BA5D(C) | :0041BA37 8A10 mov dl, byte ptr [eax] <--- get first char :0041BA39 8A1E mov bl, byte ptr [esi] <--- get first char :0041BA3B 8ACA mov cl, dl :0041BA3D 3AD3 cmp dl, bl <--- compare :0041BA3F 7525 jne 0041BA66 <--- jump if not equal :0041BA41 84C9 test cl, cl :0041BA43 0F84C7000000 je 0041BB10 <--- jump if equal :0041BA49 8A5001 mov dl, byte ptr [eax+01] :0041BA4C 8A5E01 mov bl, byte ptr [esi+01] :0041BA4F 8ACA mov cl, dl :0041BA51 3AD3 cmp dl, bl :0041BA53 7511 jne 0041BA66 :0041BA55 83C002 add eax, 00000002 <--- add +2 to eax and esi :0041BA58 83C602 add esi, 00000002 :0041BA5B 84C9 test cl, cl :0041BA5D 75D8 jne 0041BA37 <--- jump if not equal :0041BA5F 33C0 xor eax, eax :0041BA61 5F pop edi :0041BA62 5E pop esi :0041BA63 5D pop ebp :0041BA64 5B pop ebx :0041BA65 C3 ret <--- get out of call ... Ok, interesting! Not? Well this part of the code you should run and check in SI, be sure to keep an eye on the values in dl an bl. Ok, you followed the code? You'll have noticed that's here where your code and the good registration code are compared. Your code will be in eax and the good one in esi. Try a "db esi" in SI and see what you get, now remember the line : * Possible StringData Ref from Data Obj ->"98437856278". Well yes, the one and only good registration code is hard-coded in the program. Well that's for finding the good key, what was very easy. (*) you can get all the return addresses when you trace through the code in SI, by using F10, I suggest you do that... [GREETZ...........]: All people on #cracking4newbies and #cracking, members of Mexelite`97/c4n Fravia for his (awesome) home page, Razzi, +ORC, and many others for there great tutorials [FiNAL NOTE.......]: This is my first tutorial, so I hope you where able to follow and to understand my way of thinking and working. Probably there some other ways to "pinpoint" the moment when your key is compared with the good one. But I thought for this target the basic (use F10 in SI) tracing was the easiest one. If you're a starter just like me, I suggest you read as many tutorials as possible. And try to crack everything you can lay your hands on. There will be more failure then succes, but like we say : No Pain No Gain! A hard-coded key like in BC is almost never used but plain simple compare of 2 keys and the call&test routine are used very often. So that's all folks, hope you enjoyed it and learned something, Vizion.