Security Administrator v1.3 Cracker : [Kwai_Lo] Date Written : 22/8/99 Target : Security Administrator v1.3 Tools : The One And Only SoftIce Protection : Serial ;) Introduction: Hello Again, This Here Is My Third Tutor ;), I'd Like To Congratulate T0RN@D0 For His Great Effort On Preparing The Next Gen Of Crackers To Come. In The Past 2 Tutorial's I Have Made, I Taught How To Keygen 2 Simple Apps That Used A Simple And Stright Forward Algo. In This Tutorial I Will Teach You How To Crack A Common Serial Protection And I Hope This Will Come In Handy To Ya All ;) Cracking: Before We Do Any Thing, We Must Study The Target First. I Run The Program It It Tells Me To Register ;). Ok Now I Exit The Program And I Restart It, Hmmmmmmm , Still The Same, Now We Know That If We Are Unregistered, It Shows The Nag. Ok Now I Put BPX's On 2 Common API's That Is GetWindowTextA And GetDlgItemTextA. But Before I Set The BPX's I Enter A Fake Serial.Ok After Setting The BPX's And Fake Serial I Clikc GO. Hmmmmm, Nothing Happens. Now We Know The Above API's Are Useless. Ok Clear All The BPX's (bc *). Now Set A BPX On Hmemcpy. Then We Click Go. We Are Hit Back Into SoftIce. Now F11 Once And F12 Eleven Times. Now You Are Where It Does The Comparing Of The Serial. You Should See Something Like The Code Below :0046AFF2 8B45F8 mov eax, dword ptr [ebp-08] :0046AFF5 8D55FC lea edx, dword ptr [ebp-04] :0046AFF8 E8CF62FFFF call 004612CC :0046AFFD 837DFC00 cmp dword ptr [ebp-04], 00000000 :0046B001 750D jne 0046B010 :0046B003 8D45FC lea eax, dword ptr [ebp-04] * Possible StringData Ref from Code Obj ->"err" | :0046B006 BA74B04600 mov edx, 0046B074 :0046B00B E82C8AF9FF call 00403A3C :0046B010 A1F43E4700 mov eax, dword ptr [00473EF4] :0046B015 8B00 mov eax, dword ptr [eax] :0046B017 8B55FC mov edx, dword ptr [ebp-04] :0046B01A E8256C0000 call 00471C44 :0046B01F 8B8308030000 mov eax, dword ptr [ebx+00000308] :0046B025 8B10 mov edx, dword ptr [eax] :0046B027 FF92B4000000 call dword ptr [edx+000000B4] :0046B02D A14C3E4700 mov eax, dword ptr [00473E4C] :0046B032 803800 cmp byte ptr [eax], 00 :0046B035 740A je 0046B041 :0046B037 C7832C02000001000000 mov dword ptr [ebx+0000022C], 00000001 We Trace Pass The First CALL, And The Program Takes The Jump And Goes To 46B010. We Trace Pass The Next Call And Bang It Shows Us The Error. Now We Now Know That The Check Is Done In Call 00471C44. So We Trace Back And Step Into The Call, We Should Land On The Code Below. :00471C44 55 push ebp :00471C45 8BEC mov ebp, esp :00471C47 51 push ecx :00471C48 53 push ebx :00471C49 8955FC mov dword ptr [ebp-04], edx :00471C4C 8BD8 mov ebx, eax :00471C4E 8B45FC mov eax, dword ptr [ebp-04] :00471C51 E87E21F9FF call 00403DD4 :00471C56 33C0 xor eax, eax :00471C58 55 push ebp :00471C59 68D81C4700 push 00471CD8 :00471C5E 64FF30 push dword ptr fs:[eax] :00471C61 648920 mov dword ptr fs:[eax], esp :00471C64 8B55FC mov edx, dword ptr [ebp-04] :00471C67 8BC3 mov eax, ebx :00471C69 E842B0FFFF call 0046CCB0 :00471C6E 84C0 test al, al :00471C70 7438 je 00471CAA :00471C72 8B4DFC mov ecx, dword ptr [ebp-04] * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00471C0E(C) | :00471C75 BAEC1C4700 mov edx, 00471CEC :00471C7A A1B4584700 mov eax, dword ptr [004758B4] :00471C7F E8E07FFFFF call 00469C64 :00471C84 B201 mov dl, 01 :00471C86 A1B4584700 mov eax, dword ptr [004758B4] :00471C8B E8B87FFFFF call 00469C48 :00471C90 6A40 push 00000040 * Possible StringData Ref from Code Obj ->"Information" | :00471C92 B9F01C4700 mov ecx, 00471CF0 * Possible StringData Ref from Code Obj ->"Registration has successfully " ->"completed!" | :00471C97 BAFC1C4700 mov edx, 00471CFC :00471C9C A1C0404700 mov eax, dword ptr [004740C0] :00471CA1 8B00 mov eax, dword ptr [eax] :00471CA3 E85C50FDFF call 00446D04 :00471CA8 EB18 jmp 00471CC2 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00471C70(C) | :00471CAA 6A10 push 00000010 * Possible StringData Ref from Code Obj ->"Error" | :00471CAC B9281D4700 mov ecx, 00471D28 * Possible StringData Ref from Code Obj ->"Sorry, this registration code " ->"is invalid!" | :00471CB1 BA301D4700 mov edx, 00471D30 :00471CB6 A1C0404700 mov eax, dword ptr [004740C0] :00471CBB 8B00 mov eax, dword ptr [eax] :00471CBD E84250FDFF call 00446D04 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00471CA8(U) | :00471CC2 33C0 xor eax, eax :00471CC4 5A pop edx :00471CC5 59 pop ecx :00471CC6 59 pop ecx :00471CC7 648910 mov dword ptr fs:[eax], edx * Possible StringData Ref from Code Obj ->"[Y]" | :00471CCA 68DF1C4700 push 00471CDF * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00471CDD(U) | :00471CCF 8D45FC lea eax, dword ptr [ebp-04] :00471CD2 E8CD1CF9FF call 004039A4 :00471CD7 C3 ret Here I Ripped The Whole Call Out ;). Now At 471C51 It Gets Our Fake Serial Length. Now Look At This. :00471C69 E842B0FFFF call 0046CCB0 :00471C6E 84C0 test al, al :00471C70 7438 je 00471CAA Follow The Jump And It Will Lead You Stright To The Error Message. So We Know Now That The Compare Is Being Done In That Call There. Step In The Call And You Should Reach The Code Below. :0046CCB0 55 push ebp :0046CCB1 8BEC mov ebp, esp :0046CCB3 51 push ecx :0046CCB4 53 push ebx :0046CCB5 56 push esi :0046CCB6 8955FC mov dword ptr [ebp-04], edx :0046CCB9 8BF0 mov esi, eax :0046CCBB 8B45FC mov eax, dword ptr [ebp-04] :0046CCBE E81171F9FF call 00403DD4 :0046CCC3 33C0 xor eax, eax :0046CCC5 55 push ebp :0046CCC6 68A4CD4600 push 0046CDA4 :0046CCCB 64FF30 push dword ptr fs:[eax] :0046CCCE 648920 mov dword ptr fs:[eax], esp :0046CCD1 33DB xor ebx, ebx :0046CCD3 C605B858470000 mov byte ptr [004758B8], 00 :0046CCDA B8BC584700 mov eax, 004758BC :0046CCDF E8C06CF9FF call 004039A4 :0046CCE4 8B45FC mov eax, dword ptr [ebp-04] :0046CCE7 E8346FF9FF call 00403C20 <- gest len :0046CCEC 83F80C cmp eax, 0000000C <- is len 12 :0046CCEF 0F8599000000 jne 0046CD8E <- if Not Set error flag, exit :0046CCF5 8B45FC mov eax, dword ptr [ebp-04] <-mov serial :0046CCF8 803838 cmp byte ptr [eax], 38 <- Is 1st digit 8 :0046CCFB 0F858D000000 jne 0046CD8E <- no, set error flag,exit :0046CD01 8B45FC mov eax, dword ptr [ebp-04] :0046CD04 80780233 cmp byte ptr [eax+02], 33 <- Is 3rd digit 3 :0046CD08 0F8580000000 jne 0046CD8E <- no, set error flag,exit :0046CD0E 8B45FC mov eax, dword ptr [ebp-04] :0046CD11 80780331 cmp byte ptr [eax+03], 31 <- is 4th digit 1 :0046CD15 7577 jne 0046CD8E <- no, set error flag,exit :0046CD17 8B45FC mov eax, dword ptr [ebp-04] :0046CD1A 80780439 cmp byte ptr [eax+04], 39 <- is 5th digit 9 :0046CD1E 756E jne 0046CD8E <- no, set error flag,exit :0046CD20 8B45FC mov eax, dword ptr [ebp-04] :0046CD23 80780830 cmp byte ptr [eax+08], 30 <- is 9th digit 0 :0046CD27 7565 jne 0046CD8E <- no, set error flag,exit :0046CD29 8B45FC mov eax, dword ptr [ebp-04] :0046CD2C 80780935 cmp byte ptr [eax+09], 35 <- is 10th digit 5 :0046CD30 755C jne 0046CD8E <- no, set error flag,exit :0046CD32 8B45FC mov eax, dword ptr [ebp-04] :0046CD35 80780A53 cmp byte ptr [eax+0A], 53 <- is 11th digit S :0046CD39 7553 jne 0046CD8E <- no, set error flag,exit :0046CD3B 8B45FC mov eax, dword ptr [ebp-04] :0046CD3E 80780B45 cmp byte ptr [eax+0B], 45 <- is 12th digit E :0046CD42 754A jne 0046CD8E <- no, set error flag,exit :0046CD44 B8BC584700 mov eax, 004758BC :0046CD49 8B55FC mov edx, dword ptr [ebp-04] :0046CD4C E8A76CF9FF call 004039F8 :0046CD51 C605B858470001 mov byte ptr [004758B8], 01 :0046CD58 B301 mov bl, 01 :0046CD5A 33D2 xor edx, edx :0046CD5C 8B8600050000 mov eax, dword ptr [esi+00000500] :0046CD62 E86DCEFCFF call 00439BD4 :0046CD67 33D2 xor edx, edx :0046CD69 8B8614050000 mov eax, dword ptr [esi+00000514] :0046CD6F E8B8D9FBFF call 0042A72C :0046CD74 33D2 xor edx, edx :0046CD76 8B8610030000 mov eax, dword ptr [esi+00000310] :0046CD7C E853CEFCFF call 00439BD4 :0046CD81 33D2 xor edx, edx :0046CD83 8B860C030000 mov eax, dword ptr [esi+0000030C] :0046CD89 E846CEFCFF call 00439BD4 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:0046CCEF(C), :0046CCFB(C), :0046CD08(C), :0046CD15(C), :0046CD1E(C) |:0046CD27(C), :0046CD30(C), :0046CD39(C), :0046CD42(C) | :0046CD8E 33C0 xor eax, eax :0046CD90 5A pop edx :0046CD91 59 pop ecx :0046CD92 59 pop ecx :0046CD93 648910 mov dword ptr fs:[eax], edx :0046CD96 68ABCD4600 push 0046CDAB * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0046CDA9(U) | :0046CD9B 8D45FC lea eax, dword ptr [ebp-04] :0046CD9E E8016CF9FF call 004039A4 :0046CDA3 C3 ret Look At The Notes Beside The Code Listing Above. So From The Above Code We Know That Our Serial Is Only Checked At Certain Places. So Our Serial Should Look Something Like 8x319xxx05SE. Now What Is The x's. My Guess Is It Can Be Anything. So We Clear All BPX's (bc *) And Go Back To The Program And Type In The Code We Got. We Fill In The x's With Numbers And Click Go. Volla, We Are Now Registered Users ;). Greets: I'd Like To Greet All The People At #cracking4newbies , #cracks And All My Personal Firends (You Know Who You Are ;P) And All The Newbies Wanting To Learn. You Can Contact Me At kwai_lo@hotmail.com [Kwai_Lo]