【破解作者】 +dEMON[RCT]
【作者邮箱】 demon_rct@163.com
【作者主页】 http://www.dev-club.com
【使用工具】 OllyDBG, IDA
【破解平台】 Win2003 Server
【所属组织】 Reverse Code Team
【软件名称】 PHPMaker 3.03 注册算法分析
【下载地址】 http://www.hkvstore.com/phpmaker/
【加壳方式】 Aspack
【破解声明】 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐!如果你觉得PHPMaker这款软件还不错,请购买注册!
--------------------------------------------------------------------------------
【破解内容】
注册过程如下,关键的标签,函数,和变量已经重新命名,旁边还有注释,我就不多讲了,直接看吧:
CODE:0064A6F6 lea edx, [ebp+szRegcode]
CODE:0064A6FC mov eax, [ebp+var_C]
CODE:0064A6FF mov eax, [eax+30Ch]
CODE:0064A705 call TControl::GetText(void) ; 取得注册码
CODE:0064A70A mov edx, [ebp+szRegcode]
CODE:0064A710 lea eax, [ebp+szRegcode1] ; szRegCode1 = LStrToString(szRegCode)
CODE:0064A716 mov ecx, 0FFh
CODE:0064A71B call System::__linkproc__ LStrToString(void)
CODE:0064A720 lea eax, [ebp+szRegcode1]
CODE:0064A726 push eax
CODE:0064A727 lea edx, [ebp+szUser]
CODE:0064A72D mov eax, [ebp+var_C]
CODE:0064A730 mov eax, [eax+308h]
CODE:0064A736 call TControl::GetText(void) ; 取得用户名
CODE:0064A73B mov edx, [ebp+szUser]
CODE:0064A741 lea eax, [ebp+szUser1] ; szUser1 = LStrToString(szUser)
CODE:0064A747 mov ecx, 0FFh
CODE:0064A74C call System::__linkproc__ LStrToString(void)
CODE:0064A751 lea eax, [ebp+szUser1]
CODE:0064A757 pop edx
CODE:0064A758 call ebx ; Jmp to 007b24d4
CODE:0064A758 ; function CheckRegInfo(User, Regcode): boolean;
CODE:0064A758 ; 检测注册信息
CODE:0064A758 ; 如果返回值为0则注册失败
CODE:0064A75A test al, al
CODE:0064A75C jz @RegisterFail
CODE:0064A762 lea edx, [ebp+szUser2]
CODE:0064A768 mov eax, [ebp+var_C]
CODE:0064A76B mov eax, [eax+308h]
CODE:0064A771 call TControl::GetText(void) ; 取得用户名
CODE:0064A771 ; szUser2 = szUser1 = szUser = 用户输入的用户名
CODE:0064A776 mov edx, [ebp+szUser2]
CODE:0064A77C lea eax, [ebp+szRegcode1]
CODE:0064A782 mov ecx, 0FFh
CODE:0064A787 call System::__linkproc__ LStrToString(void)
CODE:0064A78C lea edx, [ebp+szRegcode1]
CODE:0064A792 mov eax, [ebp+szUsername] ; szUsername = szUser = szUser1 = szUser2
CODE:0064A795 call CheckBlackList ; 检查注册用户是否位列黑名单内
CODE:0064A79A test al, al ; 如果位列黑名单中则注册失败
CODE:0064A79A ; 否则注册成功
CODE:0064A79C jnz @RegisterFail
CODE:0064A7A2 xor eax, eax
CODE:0064A7A4 push ebp
CODE:0064A7A5 push offset loc_64A85F
CODE:0064A7AA push dword ptr fs:[eax]
CODE:0064A7AD mov fs:[eax], esp
CODE:0064A7B0 lea edx, [ebp+var_220]
CODE:0064A7B6 mov eax, [ebp+szUsername]
CODE:0064A7B9 mov eax, [eax+44h]
CODE:0064A7BC call IntToStr
CODE:0064A7C1 mov edx, [ebp+var_220]
CODE:0064A7C7 lea ecx, [ebp+szRegcode1]
CODE:0064A7CD mov eax, [ebp+szUsername]
CODE:0064A7D0 call sub_64979C
CODE:0064A7D5 lea edx, [ebp+szRegcode1]
CODE:0064A7DB mov cl, 30h
CODE:0064A7DD mov eax, [ebp+szUsername]
CODE:0064A7E0 call WriteInfoToRegistry ; 把注册信息写入注册表
CODE:0064A7E0 ;
CODE:0064A7E0 ; HKEY_CLASSES_ROOT\CLSID\{AF670D53-621C-4647-98CD-E7EDC20524EA}\
CODE:0064A7E5 lea edx, [ebp+var_224]
CODE:0064A7EB mov eax, [ebp+var_C]
CODE:0064A7EE mov eax, [eax+308h]
CODE:0064A7F4 call TControl::GetText(void)
CODE:0064A7F9 mov edx, [ebp+var_224]
CODE:0064A7FF lea ecx, [ebp+szRegcode1]
CODE:0064A805 mov eax, [ebp+szUsername]
CODE:0064A808 call sub_64979C
CODE:0064A80D lea edx, [ebp+szRegcode1]
CODE:0064A813 mov cl, 32h
CODE:0064A815 mov eax, [ebp+szUsername]
CODE:0064A818 call WriteInfoToRegistry ; 把注册信息写入注册表
CODE:0064A818 ;
CODE:0064A818 ; HKEY_CLASSES_ROOT\CLSID\{AF670D53-621C-4647-98CD-E7EDC20524EA}\
CODE:0064A81D lea edx, [ebp+var_228]
CODE:0064A823 mov eax, [ebp+var_C]
CODE:0064A826 mov eax, [eax+30Ch]
CODE:0064A82C call TControl::GetText(void)
CODE:0064A831 mov edx, [ebp+var_228]
CODE:0064A837 lea ecx, [ebp+szRegcode1]
CODE:0064A83D mov eax, [ebp+szUsername]
CODE:0064A840 call sub_64979C
CODE:0064A845 lea edx, [ebp+szRegcode1]
CODE:0064A84B mov cl, 33h
CODE:0064A84D mov eax, [ebp+szUsername]
CODE:0064A850 call WriteInfoToRegistry ; 把注册信息写入注册表
CODE:0064A850 ;
CODE:0064A850 ; HKEY_CLASSES_ROOT\CLSID\{AF670D53-621C-4647-98CD-E7EDC20524EA}\
CODE:0064A855 xor eax, eax
CODE:0064A857 pop edx
CODE:0064A858 pop ecx
CODE:0064A859 pop ecx
CODE:0064A85A mov fs:[eax], edx
CODE:0064A85D jmp short @RegisterSucceed
CODE:0064A85F ; -------------------------------------------------------------------------------
CODE:0064A85F
CODE:0064A85F loc_64A85F: ; DATA XREF: sub_64A640+165o
CODE:0064A85F jmp loc_404800
CODE:0064A864 ; -------------------------------------------------------------------------------
CODE:0064A864 push 0
CODE:0064A866 mov cx, ds:word_64AA18
CODE:0064A86D mov dl, 2
CODE:0064A86F mov eax, offset aYouNeedAdminis ; "You need Administrator permission to re"...
CODE:0064A874 call Dialogs::MessageDlg(System::AnsiString,Dialogs::TMsgDlgType,System::Set<Dialogs::TMsgDlgBtn,(uchar)0,(uchar)10>,int)
CODE:0064A879 call __linkproc__ DoneExcept(void)
CODE:0064A87E
CODE:0064A87E @RegisterSucceed: ; 注册成功
CODE:0064A87E lea ecx, [ebp+szUser1]
CODE:0064A884 mov dl, 32h
CODE:0064A886 mov eax, [ebp+szUsername]
CODE:0064A889 call sub_649904
CODE:0064A88E lea edx, [ebp+szUser1]
CODE:0064A894 lea eax, [ebp+var_22C]
CODE:0064A89A call PChar ; Borland Visual Component Library & Packages
CODE:0064A89F mov edx, [ebp+var_22C]
CODE:0064A8A5 lea ecx, [ebp+szRegcode1]
CODE:0064A8AB mov eax, [ebp+szUsername]
CODE:0064A8AE call sub_649648
CODE:0064A8B3 lea edx, [ebp+szRegcode1]
CODE:0064A8B9 mov eax, [ebp+szUsername]
CODE:0064A8BC add eax, 4Ch
CODE:0064A8BF call PChar ; Borland Visual Component Library & Packages
CODE:0064A8C4 lea ecx, [ebp+szUser1]
CODE:0064A8CA mov dl, 33h
CODE:0064A8CC mov eax, [ebp+szUsername]
CODE:0064A8CF call sub_649904
CODE:0064A8D4 lea edx, [ebp+szUser1]
CODE:0064A8DA lea eax, [ebp+var_230]
CODE:0064A8E0 call PChar ; Borland Visual Component Library & Packages
CODE:0064A8E5 mov edx, [ebp+var_230]
CODE:0064A8EB lea ecx, [ebp+szRegcode1]
CODE:0064A8F1 mov eax, [ebp+szUsername]
CODE:0064A8F4 call sub_649648
CODE:0064A8F9 lea edx, [ebp+szRegcode1]
CODE:0064A8FF mov eax, [ebp+szUsername]
CODE:0064A902 add eax, 50h
CODE:0064A905 call PChar ; Borland Visual Component Library & Packages
CODE:0064A90A mov eax, [ebp+szUsername]
CODE:0064A90D call sub_649E84
CODE:0064A912 push 0
CODE:0064A914 push offset aThankYouForReg ; "Thank you for registering "
CODE:0064A919 mov eax, [ebp+szUsername]
CODE:0064A91C push dword ptr [eax+64h]
CODE:0064A91F push offset dword_64AA80
CODE:0064A924 lea eax, [ebp+var_234]
CODE:0064A92A mov edx, 3
CODE:0064A92F call StrCat
CODE:0064A934 mov eax, [ebp+var_234]
CODE:0064A93A mov cx, ds:word_64AA18
CODE:0064A941 mov dl, 2
CODE:0064A943 call Dialogs::MessageDlg(System::AnsiString,Dialogs::TMsgDlgType,System::Set<Dialogs::TMsgDlgBtn,(uchar)0,(uchar)10>,int)
CODE:0064A948 mov [ebp+var_8], 1
CODE:0064A94F jmp short @Exit
CODE:0064A951 ; -------------------------------------------------------------------------------
CODE:0064A951
CODE:0064A951 @RegisterFail: ; CODE XREF: sub_64A640+11Cj
CODE:0064A951 ; sub_64A640+15Cj
CODE:0064A951 push 0
CODE:0064A953 mov cx, ds:word_64AA18
CODE:0064A95A mov dl, 1
CODE:0064A95C mov eax, offset aTheLicenseKeyI ; "The license key is invalid."
CODE:0064A961 call Dialogs::MessageDlg(System::AnsiString,Dialogs::TMsgDlgType,System::Set<Dialogs::TMsgDlgBtn,(uchar)0,(uchar)10>,int)
CODE:0064A966 jmp short @Exit
附黑名单如下,其中有国内的crysky, ttdown.com和piaodown.com:
CODE:007B2BA8 aNemesis db 'NEMESIS]',0 ; DATA XREF: sub_7B2898+39o
CODE:007B2BBC aPanoramixPgc db 'PANORAMIX [PGC]',0 ; DATA XREF: sub_7B2898+46o
CODE:007B2BD4 aWishmaker db 'WISHMAKER',0 ; DATA XREF: sub_7B2898+53o
CODE:007B2BE8 aOvofax db 'OVOFAX',0 ; DATA XREF: sub_7B2898+60o
CODE:007B2BF8 aNevaStevens db 'NEVA STEVENS',0 ; DATA XREF: sub_7B2898+6Do
CODE:007B2C10 aNeima db 'NEIMA',0 ; DATA XREF: sub_7B2898+7Ao
CODE:007B2C20 aHeidi db 'HEIDI',0 ; DATA XREF: sub_7B2898+87o
CODE:007B2C30 aIan_williams db 'IAN_WILLIAMS',0 ; DATA XREF: sub_7B2898+94o
CODE:007B2C48 aKennethPerry db 'KENNETH PERRY',0 ; DATA XREF: sub_7B2898+A1o
CODE:007B2C60 aImranAhmad db 'IMRAN AHMAD',0 ; DATA XREF: sub_7B2898+AEo
CODE:007B2C74 aAngel db 'ANGEL',0 ; DATA XREF: sub_7B2898+BBo
CODE:007B2C84 aDanielSmith db 'DANIEL SMITH',0 ; DATA XREF: sub_7B2898+C8o
CODE:007B2C9C aDaniel db 'DANIEL',0 ; DATA XREF: sub_7B2898+D5o
CODE:007B2CAC aWww_ttdown_com db 'WWW.TTDOWN.COM',0 ; DATA XREF: sub_7B2898+E2o
CODE:007B2CC4 aTtdown_com db 'TTDOWN.COM',0 ; DATA XREF: sub_7B2898+EFo
CODE:007B2CD8 aCrsky db 'CRSKY',0 ; DATA XREF: sub_7B2898+FCo
CODE:007B2CE8 aGuillermoNagy db 'GUILLERMO NAGY',0 ; DATA XREF: sub_7B2898+109o
CODE:007B2D00 aNineGold db 'NINE-GOLD',0 ; DATA XREF: sub_7B2898+116o
CODE:007B2D14 aSharilNordin db 'SHARIL NORDIN',0 ; DATA XREF: sub_7B2898+123o
CODE:007B2D2C aAdminprotech db 'ADMINPROTECH',0 ; DATA XREF: sub_7B2898+130o
CODE:007B2D44 aRevengeCrew db 'REVENGE CREW',0 ; DATA XREF: sub_7B2898+13Do
CODE:007B2D5C aLeannChapman db 'LEANN CHAPMAN',0 ; DATA XREF: sub_7B2898+14Ao
CODE:007B2D74 aAllen db 'ALLEN',0 ; DATA XREF: sub_7B2898+157o
CODE:007B2D84 aClaudiuDesign db 'CLAUDIU DESIGN',0 ; DATA XREF: sub_7B2898+164o
CODE:007B2D9C aJamesUpshaw db 'JAMES UPSHAW',0 ; DATA XREF: sub_7B2898+171o
CODE:007B2DB4 aAnthonyGuth db 'ANTHONY GUTH',0 ; DATA XREF: sub_7B2898+17Eo
CODE:007B2DCC aIncubeNetwork db 'INCUBE NETWORK',0 ; DATA XREF: sub_7B2898+18Bo
CODE:007B2DE4 aQuartex db 'QUARTEX',0 ; DATA XREF: sub_7B2898+198o
CODE:007B2DF4 aTeamQuartex db 'TEAM QUARTEX',0 ; DATA XREF: sub_7B2898+1A5o
CODE:007B2E0C aVakaruge db 'VAKARUGE',0 ; DATA XREF: sub_7B2898+1B2o
CODE:007B2E20 aBryanKite db 'BRYAN KITE',0 ; DATA XREF: sub_7B2898+1BFo
CODE:007B2E34 aMuhMubin db 'MUH MUBIN',0 ; DATA XREF: sub_7B2898+1CCo
CODE:007B2E48 aMlebms db 'MLEBMS',0 ; DATA XREF: sub_7B2898+1D9o
CODE:007B2E58 aJoseArizmendi db 'JOSE ARIZMENDI',0 ; DATA XREF: sub_7B2898+1E6o
CODE:007B2E70 aJohnmips db 'JOHNMIPS',0 ; DATA XREF: sub_7B2898+1F3o
CODE:007B2E84 aDonnaM_Ruesink db 'DONNA M. RUESINK',0 ; DATA XREF: sub_7B2898+200o
CODE:007B2EAC aBillGoble db 'BILL GOBLE',0 ; DATA XREF: sub_7B2898+21Ao
CODE:007B2EC0 aLindaZifchock db 'LINDA ZIFCHOCK',0 ; DATA XREF: sub_7B2898+227o
CODE:007B2ED8 aArreMohamud db 'ARRE MOHAMUD',0 ; DATA XREF: sub_7B2898+234o
CODE:007B2EF0 aLehoan db 'LEHOAN',0 ; DATA XREF: sub_7B2898+241o
CODE:007B2F00 aCarolMoser db 'CAROL MOSER',0 ; DATA XREF: sub_7B2898+24Eo
CODE:007B2F14 aSheilaTyne db 'SHEILA TYNE',0 ; DATA XREF: sub_7B2898+25Bo
CODE:007B2F28 aZarabush db 'ZARABUSH',0 ; DATA XREF: sub_7B2898+268o
CODE:007B2F3C aMichelleRoukou db 'MICHELLE ROUKOUS',0 ; DATA XREF: sub_7B2898+275o
CODE:007B2F58 aNanaYawq db 'NANA YAWQ',0 ; DATA XREF: sub_7B2898+282o
CODE:007B2F6C aAmandaGable db 'AMANDA GABLE',0 ; DATA XREF: sub_7B2898+28Fo
CODE:007B2F84 aTwinTownTreatm db 'TWIN TOWN TREATMENT CENTERS',0
CODE:007B2FA8 aSystec db 'SYSTEC',0 ; DATA XREF: sub_7B2898+2A9o
CODE:007B2FB8 aTracyKim db 'TRACY KIM',0 ; DATA XREF: sub_7B2898+2B6o
CODE:007B2FCC aPiaodown_com db 'PIAODOWN.COM',0 ; DATA XREF: sub_7B2898+2C3o
CODE:007B2FE4 aSandraTDuncan db 'SANDRA T DUNCAN',0 ; DATA XREF: sub_7B2898+2D0o
CODE:007B2FFC aWww_365mf_com db 'WWW.365MF.COM',0 ; DATA XREF: sub_7B2898+2DDo
CODE:007B3014 aIgorOdebrecht db 'IGOR ODEBRECHT',0 ; DATA XREF: sub_7B2898+2EAo
CODE:007B302C aWesamMohamed db 'WESAM MOHAMED',0 ; DATA XREF: sub_7B2898+2F7o
关键的注册算法还在007b24d4处,且看:
CODE:007B24D4 ; function CheckRegCode(User, RegCode: string): boolean;
CODE:007B24D4 ; Attributes: bp-based frame
CODE:007B24D4
CODE:007B24D4 CheckRegCode proc near ; CODE XREF: sub_99FFA0+DCp
CODE:007B24D4 ; sub_9A1058+DCp ...
CODE:007B24D4
CODE:007B24D4 var_24C = dword ptr -24Ch
CODE:007B24D4 var_248 = dword ptr -248h
CODE:007B24D4 var_244 = dword ptr -244h
CODE:007B24D4 var_240 = dword ptr -240h
CODE:007B24D4 var_23C = dword ptr -23Ch
CODE:007B24D4 var_238 = dword ptr -238h
CODE:007B24D4 pUsername = dword ptr -234h
CODE:007B24D4 var_230 = dword ptr -230h
CODE:007B24D4 var_22C = dword ptr -22Ch
CODE:007B24D4 var_228 = dword ptr -228h
CODE:007B24D4 var_224 = dword ptr -224h
CODE:007B24D4 var_220 = dword ptr -220h
CODE:007B24D4 var_21C = dword ptr -21Ch
CODE:007B24D4 newUser = dword ptr -218h
CODE:007B24D4 pUser = dword ptr -214h
CODE:007B24D4 var_210 = dword ptr -210h
CODE:007B24D4 pRegCode = dword ptr -20Ch
CODE:007B24D4 RegCode = dword ptr -208h
CODE:007B24D4 User = dword ptr -108h
CODE:007B24D4 dwNow = qword ptr -2Ch
CODE:007B24D4 RegCodeNumber = dword ptr -8
CODE:007B24D4
CODE:007B24D4 push ebp
CODE:007B24D5 mov ebp, esp
CODE:007B24D7 mov ecx, 49h
CODE:007B24DC
CODE:007B24DC loc_7B24DC: ; CODE XREF: CheckRegCode+Dj
CODE:007B24DC push 0
CODE:007B24DE push 0
CODE:007B24E0 dec ecx
CODE:007B24E1 jnz short loc_7B24DC
CODE:007B24E3 push ecx
CODE:007B24E4 push ebx
CODE:007B24E5 push esi
CODE:007B24E6 push edi
CODE:007B24E7 mov esi, edx ; esi = RegCode
CODE:007B24E7 ; 把RegCode复制到RegCode的地址去
CODE:007B24E9 lea edi, [ebp+RegCode]
CODE:007B24EF xor ecx, ecx
CODE:007B24F1 mov cl, [esi]
CODE:007B24F3 inc ecx
CODE:007B24F4 rep movsb
CODE:007B24F6 mov esi, eax ; esi = User
CODE:007B24F6 ; 把User复制到User的地方去
CODE:007B24F8 lea edi, [ebp+User]
CODE:007B24FE xor ecx, ecx
CODE:007B2500 mov cl, [esi]
CODE:007B2502 inc ecx
CODE:007B2503 rep movsb
CODE:007B2505 xor eax, eax
CODE:007B2507 push ebp
CODE:007B2508 push offset loc_7B2888
CODE:007B250D push dword ptr fs:[eax]
CODE:007B2510 mov fs:[eax], esp
CODE:007B2513 lea eax, [ebp+pRegCode]
CODE:007B2519 lea edx, [ebp+RegCode]
CODE:007B251F call PChar ; Borland Visual Component Library & Packages
CODE:007B2524 mov eax, [ebp+pRegCode]
CODE:007B252A lea edx, [ebp+RegCodeNumber] ; RegCodeNumber指向RegCode的数字序列
CODE:007B252D mov ecx, 8
CODE:007B2532 call ConvertRegCodeToNumber ; 把输入的注册码转换成8个字节的数字序列表示
CODE:007B2532 ; 如输入:"1234567890abcdef"
CODE:007B2532 ; 则转换成:
CODE:007B2532 ; 12 34 56 78 90 ab cd ef
CODE:007B2532 ; 表示的数字序列
CODE:007B2537 xor ebx, ebx
CODE:007B2539 call Sysutils::Now(void)
CODE:007B253E add esp, 0FFFFFFF8h
CODE:007B2541 fstp [esp+2Ch+dwNow]
CODE:007B2544 wait
CODE:007B2545 call sub_5583FC
CODE:007B254A movzx eax, ax
CODE:007B254D and eax, 7
CODE:007B2550 cmp eax, 7 ; switch 8 cases
CODE:007B2553 ja @Exit ; default
CODE:007B2559 jmp ds:off_7B2560[eax*4] ; switch jump
CODE:007B2559 ; -------------------------------------------------------------------------------?
CODE:007B2560 off_7B2560 dd offset loc_7B2580 ; DATA XREF: CheckRegCode+85r
CODE:007B2560 dd offset loc_7B25DF ; jump table for switch statement
CODE:007B2560 dd offset loc_7B263E
CODE:007B2560 dd offset loc_7B269D
CODE:007B2560 dd offset loc_7B26FC
CODE:007B2560 dd offset loc_7B275B
CODE:007B2560 dd offset loc_7B27BA
CODE:007B2560 dd offset loc_7B2813
CODE:007B2580 ; -------------------------------------------------------------------------------?
CODE:007B2580
CODE:007B2580 loc_7B2580: ; CODE XREF: CheckRegCode+85j
CODE:007B2580 ; DATA XREF: CheckRegCode:off_7B2560o
CODE:007B2580 lea edx, [ebp+RegCodeNumber] ; case 0x0
CODE:007B2583 mov eax, offset Key1
CODE:007B2588 call CheckRegCode2bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B2588 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B2588 ; 是否为5B9C
CODE:007B2588 ; 如果为5B9C则返回true
CODE:007B2588 ; 否则返回false
CODE:007B2588 ;
CODE:007B2588 ; Key为:
CODE:007B2588 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B2588 ;
CODE:007B2588 ; 函数原型:
CODE:007B2588 ; function CheckRegCode2bytes(Key: TKey128; RegCodeNumber: array of byte): boolean;
CODE:007B258D test al, al
CODE:007B258F jz short loc_7B25D1
CODE:007B2591 lea edx, [ebp+RegCodeNumber]
CODE:007B2594 mov eax, offset Key1
CODE:007B2599 call GetRegcodeNumberLast4Bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B2599 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B2599 ; 是否为5B9C
CODE:007B2599 ; 如果为5B9C则返回解码后的RegCodeNumber的后4个字节
CODE:007B2599 ; 否则返回0
CODE:007B2599 ;
CODE:007B2599 ; Key为:
CODE:007B2599 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B2599 ;
CODE:007B2599 ; 函数原型:
CODE:007B2599 ; function GetRegcodeNumberLast4Bytes(Key: TKey128; RegCodeNumber: array of byte): DWORD;
CODE:007B259E mov ebx, eax
CODE:007B25A0 lea eax, [ebp+pUser]
CODE:007B25A6 lea edx, [ebp+User]
CODE:007B25AC call PChar ; Borland Visual Component Library & Packages
CODE:007B25B1 mov eax, [ebp+pUser]
CODE:007B25B7 lea edx, [ebp+var_210]
CODE:007B25BD call EnCodeUser ; 把User编码
CODE:007B25C2 mov eax, [ebp+var_210]
CODE:007B25C8 call ComputeValue ; 计算EnCodeUser(User)的值,给h
CODE:007B25C8 ; 如果h=Regcode的后4个字节
CODE:007B25C8 ; 那么注册成功
CODE:007B25CD cmp ebx, eax
CODE:007B25CF jz short loc_7B25D8
CODE:007B25D1
CODE:007B25D1 loc_7B25D1: ; CODE XREF: CheckRegCode+BBj
CODE:007B25D1 xor ebx, ebx
CODE:007B25D3 jmp @Exit ; default
CODE:007B25D8 ; -------------------------------------------------------------------------------?
CODE:007B25D8
CODE:007B25D8 loc_7B25D8: ; CODE XREF: CheckRegCode+FBj
CODE:007B25D8 mov bl, 1
CODE:007B25DA jmp @Exit ; default
CODE:007B25DF ; -------------------------------------------------------------------------------?
CODE:007B25DF
CODE:007B25DF loc_7B25DF: ; CODE XREF: CheckRegCode+85j
CODE:007B25DF ; DATA XREF: CheckRegCode:off_7B2560o
CODE:007B25DF lea edx, [ebp+RegCodeNumber] ; case 0x1
CODE:007B25E2 mov eax, offset Key1
CODE:007B25E7 call CheckRegCode2bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B25E7 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B25E7 ; 是否为5B9C
CODE:007B25E7 ; 如果为5B9C则返回true
CODE:007B25E7 ; 否则返回false
CODE:007B25E7 ;
CODE:007B25E7 ; Key为:
CODE:007B25E7 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B25E7 ;
CODE:007B25E7 ; 函数原型:
CODE:007B25E7 ; function CheckRegCode2bytes(Key: TKey128; RegCodeNumber: array of byte): boolean;
CODE:007B25EC test al, al
CODE:007B25EE jz short loc_7B2630
CODE:007B25F0 lea edx, [ebp+RegCodeNumber]
CODE:007B25F3 mov eax, offset Key1
CODE:007B25F8 call GetRegcodeNumberLast4Bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B25F8 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B25F8 ; 是否为5B9C
CODE:007B25F8 ; 如果为5B9C则返回解码后的RegCodeNumber的后4个字节
CODE:007B25F8 ; 否则返回0
CODE:007B25F8 ;
CODE:007B25F8 ; Key为:
CODE:007B25F8 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B25F8 ;
CODE:007B25F8 ; 函数原型:
CODE:007B25F8 ; function GetRegcodeNumberLast4Bytes(Key: TKey128; RegCodeNumber: array of byte): DWORD;
CODE:007B25FD mov ebx, eax
CODE:007B25FF lea eax, [ebp+var_21C]
CODE:007B2605 lea edx, [ebp+User]
CODE:007B260B call PChar ; Borland Visual Component Library & Packages
CODE:007B2610 mov eax, [ebp+var_21C]
CODE:007B2616 lea edx, [ebp+newUser] ; newUser为新用户名--经过编码后的用户名
CODE:007B261C call EnCodeUser ; 编码用户名
CODE:007B261C ; 分下面5个步骤
CODE:007B261C ; 1. 构建码表 buf
CODE:007B261C ; 把上面运算得到的3个字符串连接起来
CODE:007B261C ; 0012F61C 01B05BF0 ASCII "zyxwvutsrqpo"
CODE:007B261C ; 0012F614 01B05C0C ASCII "HIJKLMNOPQRSTUV"
CODE:007B261C ; 0012F610 015B083C ASCII "0987654321"
CODE:007B261C ;
CODE:007B261C ; 2.如果用户名长度等于17H,则把用户转为大写
CODE:007B261C ; 如果用户名长度大于17H,则通过一定的规则取其输入
CODE:007B261C ; 的用户名,组合成17H长度,全部字母转为大写
CODE:007B261C ; 如果用户名长度不足17H,则通过一个补码表把用户名补足
CODE:007B261C ; 17H长度,全部字母转为大写
CODE:007B261C ;
CODE:007B261C ; 转换后的用户名存入user1
CODE:007B261C ;
CODE:007B261C ; 3. 把user1的用户名,逐个字母的Ascii码转成Str,并存入
CODE:007B261C ; user2:
CODE:007B261C ; for i := 1 to Length(user1) do
CODE:007B261C ; begin
CODE:007B261C ; user2 := user2 + IntToStr(Ord(user1[i]));
CODE:007B261C ; end;
CODE:007B261C ;
CODE:007B261C ; 4. 以user2中5个字母为一组,计算索引AIndex
CODE:007B261C ; 从buf[AIndex]选出字母,组成一个新的中间用户名user3:
CODE:007B261C ; while i <= Length(user2) do
CODE:007B261C ; begin
CODE:007B261C ; s := copy(user2, i, 5);
CODE:007B261C ; w := StrToInt(s);
CODE:007B261C ; s1 := '';
CODE:007B261C ; if w > 0 then
CODE:007B261C ; repeat
CODE:007B261C ; a := w div $25;
CODE:007B261C ; AIndex := w mod $25;
CODE:007B261C ; s1 := buf[AIndex+1] + s1;
CODE:007B261C ; w := a;
CODE:007B261C ; until a = 0;
CODE:007B261C ; user3 := user3 + s1;
CODE:007B261C ; i := i + 5;
CODE:007B261C ; end;
CODE:007B261C ;
CODE:007B261C ; 5. 从user3中,通过一定的运算,组合出最终编码过后的用户名,
CODE:007B261C ; 新用户名长度为0CH
CODE:007B261C ;
CODE:007B261C ; userLen := Length(user3);
CODE:007B261C ; result := '';
CODE:007B261C ; for i := 1 to $c do
CODE:007B261C ; begin
CODE:007B261C ; AIndex := i * userLen div $C;
CODE:007B261C ; result := result + UpperCase(user3[AIndex]);
CODE:007B261C ; end;
CODE:007B261C ;
CODE:007B2621 mov eax, [ebp+newUser]
CODE:007B2627 call ComputeValue ; 通过一定的算法计算用户名的值,得到一个dword值
CODE:007B2627 ;
CODE:007B2627 ; 算法很简单,直接列出来吧:
CODE:007B2627 ; Encode proc near
CODE:007B2627 ; push ebx
CODE:007B2627 ; push esi
CODE:007B2627 ; xor ecx, ecx
CODE:007B2627 ; mov ebx, edx
CODE:007B2627 ; dec ebx
CODE:007B2627 ; test ebx, ebx
CODE:007B2627 ; jl short loc_7B2088
CODE:007B2627 ; inc ebx
CODE:007B2627 ;
CODE:007B2627 ; loc_7B2064:
CODE:007B2627 ; shl ecx, 4
CODE:007B2627 ; xor edx, edx
CODE:007B2627 ; mov dl, [eax]
CODE:007B2627 ; add ecx, edx
CODE:007B2627 ; mov edx, ecx
CODE:007B2627 ; and edx, 0F0000000h
CODE:007B2627 ; test edx, edx
CODE:007B2627 ; jz short loc_7B2080
CODE:007B2627 ; mov esi, edx
CODE:007B2627 ; shr esi, 18h
CODE:007B2627 ; xor ecx, esi
CODE:007B2627 ;
CODE:007B2627 ; loc_7B2080:
CODE:007B2627 ; not edx
CODE:007B2627 ; and ecx, edx
CODE:007B2627 ; inc eax
CODE:007B2627 ; dec ebx
CODE:007B2627 ; jnz short loc_7B2064
CODE:007B2627 ;
CODE:007B2627 ; loc_7B2088:
CODE:007B2627 ; mov eax, ecx
CODE:007B2627 ; pop esi
CODE:007B2627 ; pop ebx
CODE:007B2627 ; retn
CODE:007B2627 ; Encode endp
CODE:007B2627 ;
CODE:007B2627 ;
CODE:007B2627 ;
CODE:007B2627 ; 函数原型: function ComputeValue(username: string): DWORD;
CODE:007B2627 ;
CODE:007B262C cmp ebx, eax ; 如果计算得到的用户名的值等于解码后的RegCodeNumber的后4个字节
CODE:007B262C ; 那么注册成功
CODE:007B262E jz short loc_7B2637
CODE:007B2630
CODE:007B2630 loc_7B2630: ; CODE XREF: CheckRegCode+11Aj
CODE:007B2630 xor ebx, ebx
CODE:007B2632 jmp @Exit ; default
CODE:007B2637 ; -------------------------------------------------------------------------------?
CODE:007B2637
CODE:007B2637 loc_7B2637: ; CODE XREF: CheckRegCode+15Aj
CODE:007B2637 mov bl, 1
CODE:007B2639 jmp @Exit ; default
CODE:007B263E ; -------------------------------------------------------------------------------?
CODE:007B263E
CODE:007B263E loc_7B263E: ; CODE XREF: CheckRegCode+85j
CODE:007B263E ; DATA XREF: CheckRegCode:off_7B2560o
CODE:007B263E lea edx, [ebp+RegCodeNumber] ; case 0x2
CODE:007B2641 mov eax, offset Key1
CODE:007B2646 call CheckRegCode2bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B2646 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B2646 ; 是否为5B9C
CODE:007B2646 ; 如果为5B9C则返回true
CODE:007B2646 ; 否则返回false
CODE:007B2646 ;
CODE:007B2646 ; Key为:
CODE:007B2646 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B2646 ;
CODE:007B2646 ; 函数原型:
CODE:007B2646 ; function CheckRegCode2bytes(Key: TKey128; RegCodeNumber: array of byte): boolean;
CODE:007B264B test al, al
CODE:007B264D jz short loc_7B268F
CODE:007B264F lea edx, [ebp+RegCodeNumber]
CODE:007B2652 mov eax, offset Key1
CODE:007B2657 call GetRegcodeNumberLast4Bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B2657 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B2657 ; 是否为5B9C
CODE:007B2657 ; 如果为5B9C则返回解码后的RegCodeNumber的后4个字节
CODE:007B2657 ; 否则返回0
CODE:007B2657 ;
CODE:007B2657 ; Key为:
CODE:007B2657 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B2657 ;
CODE:007B2657 ; 函数原型:
CODE:007B2657 ; function GetRegcodeNumberLast4Bytes(Key: TKey128; RegCodeNumber: array of byte): DWORD;
CODE:007B265C mov ebx, eax
CODE:007B265E lea eax, [ebp+var_224]
CODE:007B2664 lea edx, [ebp+User]
CODE:007B266A call PChar ; Borland Visual Component Library & Packages
CODE:007B266F mov eax, [ebp+var_224]
CODE:007B2675 lea edx, [ebp+var_220]
CODE:007B267B call EnCodeUser ; 编码用户名
CODE:007B267B ; 分下面5个步骤
CODE:007B267B ; 1. 构建码表 buf
CODE:007B267B ; 把上面运算得到的3个字符串连接起来
CODE:007B267B ; 0012F61C 01B05BF0 ASCII "zyxwvutsrqpo"
CODE:007B267B ; 0012F614 01B05C0C ASCII "HIJKLMNOPQRSTUV"
CODE:007B267B ; 0012F610 015B083C ASCII "0987654321"
CODE:007B267B ;
CODE:007B267B ; 2.如果用户名长度等于17H,则把用户转为大写
CODE:007B267B ; 如果用户名长度大于17H,则通过一定的规则取其输入
CODE:007B267B ; 的用户名,组合成17H长度,全部字母转为大写
CODE:007B267B ; 如果用户名长度不足17H,则通过一个补码表把用户名补足
CODE:007B267B ; 17H长度,全部字母转为大写
CODE:007B267B ;
CODE:007B267B ; 转换后的用户名存入user1
CODE:007B267B ;
CODE:007B267B ; 3. 把user1的用户名,逐个字母的Ascii码转成Str,并存入
CODE:007B267B ; user2:
CODE:007B267B ; for i := 1 to Length(user1) do
CODE:007B267B ; begin
CODE:007B267B ; user2 := user2 + IntToStr(Ord(user1[i]));
CODE:007B267B ; end;
CODE:007B267B ;
CODE:007B267B ; 4. 以user2中5个字母为一组,计算索引AIndex
CODE:007B267B ; 从buf[AIndex]选出字母,组成一个新的中间用户名user3:
CODE:007B267B ; while i <= Length(user2) do
CODE:007B267B ; begin
CODE:007B267B ; s := copy(user2, i, 5);
CODE:007B267B ; w := StrToInt(s);
CODE:007B267B ; s1 := '';
CODE:007B267B ; if w > 0 then
CODE:007B267B ; repeat
CODE:007B267B ; a := w div $25;
CODE:007B267B ; AIndex := w mod $25;
CODE:007B267B ; s1 := buf[AIndex+1] + s1;
CODE:007B267B ; w := a;
CODE:007B267B ; until a = 0;
CODE:007B267B ; user3 := user3 + s1;
CODE:007B267B ; i := i + 5;
CODE:007B267B ; end;
CODE:007B267B ;
CODE:007B267B ; 5. 从user3中,通过一定的运算,组合出最终编码过后的用户名,
CODE:007B267B ; 新用户名长度为0CH
CODE:007B267B ;
CODE:007B267B ; userLen := Length(user3);
CODE:007B267B ; result := '';
CODE:007B267B ; for i := 1 to $c do
CODE:007B267B ; begin
CODE:007B267B ; AIndex := i * userLen div $C;
CODE:007B267B ; result := result + UpperCase(user3[AIndex]);
CODE:007B267B ; end;
CODE:007B267B ;
CODE:007B2680 mov eax, [ebp+var_220]
CODE:007B2686 call ComputeValue ; 通过一定的算法计算用户名的值,得到一个dword值
CODE:007B2686 ;
CODE:007B2686 ; 算法很简单,直接列出来吧:
CODE:007B2686 ; Encode proc near
CODE:007B2686 ; push ebx
CODE:007B2686 ; push esi
CODE:007B2686 ; xor ecx, ecx
CODE:007B2686 ; mov ebx, edx
CODE:007B2686 ; dec ebx
CODE:007B2686 ; test ebx, ebx
CODE:007B2686 ; jl short loc_7B2088
CODE:007B2686 ; inc ebx
CODE:007B2686 ;
CODE:007B2686 ; loc_7B2064:
CODE:007B2686 ; shl ecx, 4
CODE:007B2686 ; xor edx, edx
CODE:007B2686 ; mov dl, [eax]
CODE:007B2686 ; add ecx, edx
CODE:007B2686 ; mov edx, ecx
CODE:007B2686 ; and edx, 0F0000000h
CODE:007B2686 ; test edx, edx
CODE:007B2686 ; jz short loc_7B2080
CODE:007B2686 ; mov esi, edx
CODE:007B2686 ; shr esi, 18h
CODE:007B2686 ; xor ecx, esi
CODE:007B2686 ;
CODE:007B2686 ; loc_7B2080:
CODE:007B2686 ; not edx
CODE:007B2686 ; and ecx, edx
CODE:007B2686 ; inc eax
CODE:007B2686 ; dec ebx
CODE:007B2686 ; jnz short loc_7B2064
CODE:007B2686 ;
CODE:007B2686 ; loc_7B2088:
CODE:007B2686 ; mov eax, ecx
CODE:007B2686 ; pop esi
CODE:007B2686 ; pop ebx
CODE:007B2686 ; retn
CODE:007B2686 ; Encode endp
CODE:007B2686 ;
CODE:007B2686 ;
CODE:007B2686 ;
CODE:007B2686 ; 函数原型: function ComputeValue(username: string): DWORD;
CODE:007B2686 ;
CODE:007B268B cmp ebx, eax ; 如果计算得到的用户名的值等于解码后的RegCodeNumber的后4个字节
CODE:007B268B ; 那么注册成功
CODE:007B268D jz short loc_7B2696
CODE:007B268F
CODE:007B268F loc_7B268F: ; CODE XREF: CheckRegCode+179j
CODE:007B268F xor ebx, ebx
CODE:007B2691 jmp @Exit ; default
CODE:007B2696 ; -------------------------------------------------------------------------------?
CODE:007B2696
CODE:007B2696 loc_7B2696: ; CODE XREF: CheckRegCode+1B9j
CODE:007B2696 mov bl, 1
CODE:007B2698 jmp @Exit ; default
CODE:007B269D ; -------------------------------------------------------------------------------?
CODE:007B269D
CODE:007B269D loc_7B269D: ; CODE XREF: CheckRegCode+85j
CODE:007B269D ; DATA XREF: CheckRegCode:off_7B2560o
CODE:007B269D lea edx, [ebp+RegCodeNumber] ; case 0x3
CODE:007B26A0 mov eax, offset Key1
CODE:007B26A5 call CheckRegCode2bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B26A5 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B26A5 ; 是否为5B9C
CODE:007B26A5 ; 如果为5B9C则返回true
CODE:007B26A5 ; 否则返回false
CODE:007B26A5 ;
CODE:007B26A5 ; Key为:
CODE:007B26A5 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B26A5 ;
CODE:007B26A5 ; 函数原型:
CODE:007B26A5 ; function CheckRegCode2bytes(Key: TKey128; RegCodeNumber: array of byte): boolean;
CODE:007B26AA test al, al
CODE:007B26AC jz short loc_7B26EE
CODE:007B26AE lea edx, [ebp+RegCodeNumber]
CODE:007B26B1 mov eax, offset Key1
CODE:007B26B6 call GetRegcodeNumberLast4Bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B26B6 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B26B6 ; 是否为5B9C
CODE:007B26B6 ; 如果为5B9C则返回解码后的RegCodeNumber的后4个字节
CODE:007B26B6 ; 否则返回0
CODE:007B26B6 ;
CODE:007B26B6 ; Key为:
CODE:007B26B6 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B26B6 ;
CODE:007B26B6 ; 函数原型:
CODE:007B26B6 ; function GetRegcodeNumberLast4Bytes(Key: TKey128; RegCodeNumber: array of byte): DWORD;
CODE:007B26BB mov ebx, eax
CODE:007B26BD lea eax, [ebp+var_22C]
CODE:007B26C3 lea edx, [ebp+User]
CODE:007B26C9 call PChar ; Borland Visual Component Library & Packages
CODE:007B26CE mov eax, [ebp+var_22C]
CODE:007B26D4 lea edx, [ebp+var_228]
CODE:007B26DA call EnCodeUser ; 编码用户名
CODE:007B26DA ; 分下面5个步骤
CODE:007B26DA ; 1. 构建码表 buf
CODE:007B26DA ; 把上面运算得到的3个字符串连接起来
CODE:007B26DA ; 0012F61C 01B05BF0 ASCII "zyxwvutsrqpo"
CODE:007B26DA ; 0012F614 01B05C0C ASCII "HIJKLMNOPQRSTUV"
CODE:007B26DA ; 0012F610 015B083C ASCII "0987654321"
CODE:007B26DA ;
CODE:007B26DA ; 2.如果用户名长度等于17H,则把用户转为大写
CODE:007B26DA ; 如果用户名长度大于17H,则通过一定的规则取其输入
CODE:007B26DA ; 的用户名,组合成17H长度,全部字母转为大写
CODE:007B26DA ; 如果用户名长度不足17H,则通过一个补码表把用户名补足
CODE:007B26DA ; 17H长度,全部字母转为大写
CODE:007B26DA ;
CODE:007B26DA ; 转换后的用户名存入user1
CODE:007B26DA ;
CODE:007B26DA ; 3. 把user1的用户名,逐个字母的Ascii码转成Str,并存入
CODE:007B26DA ; user2:
CODE:007B26DA ; for i := 1 to Length(user1) do
CODE:007B26DA ; begin
CODE:007B26DA ; user2 := user2 + IntToStr(Ord(user1[i]));
CODE:007B26DA ; end;
CODE:007B26DA ;
CODE:007B26DA ; 4. 以user2中5个字母为一组,计算索引AIndex
CODE:007B26DA ; 从buf[AIndex]选出字母,组成一个新的中间用户名user3:
CODE:007B26DA ; while i <= Length(user2) do
CODE:007B26DA ; begin
CODE:007B26DA ; s := copy(user2, i, 5);
CODE:007B26DA ; w := StrToInt(s);
CODE:007B26DA ; s1 := '';
CODE:007B26DA ; if w > 0 then
CODE:007B26DA ; repeat
CODE:007B26DA ; a := w div $25;
CODE:007B26DA ; AIndex := w mod $25;
CODE:007B26DA ; s1 := buf[AIndex+1] + s1;
CODE:007B26DA ; w := a;
CODE:007B26DA ; until a = 0;
CODE:007B26DA ; user3 := user3 + s1;
CODE:007B26DA ; i := i + 5;
CODE:007B26DA ; end;
CODE:007B26DA ;
CODE:007B26DA ; 5. 从user3中,通过一定的运算,组合出最终编码过后的用户名,
CODE:007B26DA ; 新用户名长度为0CH
CODE:007B26DA ;
CODE:007B26DA ; userLen := Length(user3);
CODE:007B26DA ; result := '';
CODE:007B26DA ; for i := 1 to $c do
CODE:007B26DA ; begin
CODE:007B26DA ; AIndex := i * userLen div $C;
CODE:007B26DA ; result := result + UpperCase(user3[AIndex]);
CODE:007B26DA ; end;
CODE:007B26DA ;
CODE:007B26DF mov eax, [ebp+var_228]
CODE:007B26E5 call ComputeValue ; 通过一定的算法计算用户名的值,得到一个dword值
CODE:007B26E5 ;
CODE:007B26E5 ; 算法很简单,直接列出来吧:
CODE:007B26E5 ; Encode proc near
CODE:007B26E5 ; push ebx
CODE:007B26E5 ; push esi
CODE:007B26E5 ; xor ecx, ecx
CODE:007B26E5 ; mov ebx, edx
CODE:007B26E5 ; dec ebx
CODE:007B26E5 ; test ebx, ebx
CODE:007B26E5 ; jl short loc_7B2088
CODE:007B26E5 ; inc ebx
CODE:007B26E5 ;
CODE:007B26E5 ; loc_7B2064:
CODE:007B26E5 ; shl ecx, 4
CODE:007B26E5 ; xor edx, edx
CODE:007B26E5 ; mov dl, [eax]
CODE:007B26E5 ; add ecx, edx
CODE:007B26E5 ; mov edx, ecx
CODE:007B26E5 ; and edx, 0F0000000h
CODE:007B26E5 ; test edx, edx
CODE:007B26E5 ; jz short loc_7B2080
CODE:007B26E5 ; mov esi, edx
CODE:007B26E5 ; shr esi, 18h
CODE:007B26E5 ; xor ecx, esi
CODE:007B26E5 ;
CODE:007B26E5 ; loc_7B2080:
CODE:007B26E5 ; not edx
CODE:007B26E5 ; and ecx, edx
CODE:007B26E5 ; inc eax
CODE:007B26E5 ; dec ebx
CODE:007B26E5 ; jnz short loc_7B2064
CODE:007B26E5 ;
CODE:007B26E5 ; loc_7B2088:
CODE:007B26E5 ; mov eax, ecx
CODE:007B26E5 ; pop esi
CODE:007B26E5 ; pop ebx
CODE:007B26E5 ; retn
CODE:007B26E5 ; Encode endp
CODE:007B26E5 ;
CODE:007B26E5 ;
CODE:007B26E5 ;
CODE:007B26E5 ; 函数原型: function ComputeValue(username: string): DWORD;
CODE:007B26E5 ;
CODE:007B26EA cmp ebx, eax ; 如果计算得到的用户名的值等于解码后的RegCodeNumber的后4个字节
CODE:007B26EA ; 那么注册成功
CODE:007B26EC jz short loc_7B26F5
CODE:007B26EE
CODE:007B26EE loc_7B26EE: ; CODE XREF: CheckRegCode+1D8j
CODE:007B26EE xor ebx, ebx
CODE:007B26F0 jmp @Exit ; default
CODE:007B26F5 ; -------------------------------------------------------------------------------?
CODE:007B26F5
CODE:007B26F5 loc_7B26F5: ; CODE XREF: CheckRegCode+218j
CODE:007B26F5 mov bl, 1
CODE:007B26F7 jmp @Exit ; default
CODE:007B26FC ; -------------------------------------------------------------------------------?
CODE:007B26FC
CODE:007B26FC loc_7B26FC: ; CODE XREF: CheckRegCode+85j
CODE:007B26FC ; DATA XREF: CheckRegCode:off_7B2560o
CODE:007B26FC lea edx, [ebp+RegCodeNumber] ; case 0x4
CODE:007B26FF mov eax, offset Key1
CODE:007B2704 call CheckRegCode2bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B2704 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B2704 ; 是否为5B9C
CODE:007B2704 ; 如果为5B9C则返回true
CODE:007B2704 ; 否则返回false
CODE:007B2704 ;
CODE:007B2704 ; Key为:
CODE:007B2704 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B2704 ;
CODE:007B2704 ; 函数原型:
CODE:007B2704 ; function CheckRegCode2bytes(Key: TKey128; RegCodeNumber: array of byte): boolean;
CODE:007B2709 test al, al
CODE:007B270B jz short loc_7B274D
CODE:007B270D lea edx, [ebp+RegCodeNumber]
CODE:007B2710 mov eax, offset Key1
CODE:007B2715 call GetRegcodeNumberLast4Bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B2715 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B2715 ; 是否为5B9C
CODE:007B2715 ; 如果为5B9C则返回解码后的RegCodeNumber的后4个字节
CODE:007B2715 ; 否则返回0
CODE:007B2715 ;
CODE:007B2715 ; Key为:
CODE:007B2715 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B2715 ;
CODE:007B2715 ; 函数原型:
CODE:007B2715 ; function GetRegcodeNumberLast4Bytes(Key: TKey128; RegCodeNumber: array of byte): DWORD;
CODE:007B271A mov ebx, eax
CODE:007B271C lea eax, [ebp+pUsername]
CODE:007B2722 lea edx, [ebp+User]
CODE:007B2728 call PChar ; Borland Visual Component Library & Packages
CODE:007B272D mov eax, [ebp+pUsername]
CODE:007B2733 lea edx, [ebp+var_230]
CODE:007B2739 call EnCodeUser ; 编码用户名
CODE:007B2739 ; 分下面5个步骤
CODE:007B2739 ; 1. 构建码表 buf
CODE:007B2739 ; 把上面运算得到的3个字符串连接起来
CODE:007B2739 ; 0012F61C 01B05BF0 ASCII "zyxwvutsrqpo"
CODE:007B2739 ; 0012F614 01B05C0C ASCII "HIJKLMNOPQRSTUV"
CODE:007B2739 ; 0012F610 015B083C ASCII "0987654321"
CODE:007B2739 ;
CODE:007B2739 ; 2.如果用户名长度等于17H,则把用户转为大写
CODE:007B2739 ; 如果用户名长度大于17H,则通过一定的规则取其输入
CODE:007B2739 ; 的用户名,组合成17H长度,全部字母转为大写
CODE:007B2739 ; 如果用户名长度不足17H,则通过一个补码表把用户名补足
CODE:007B2739 ; 17H长度,全部字母转为大写
CODE:007B2739 ;
CODE:007B2739 ; 转换后的用户名存入user1
CODE:007B2739 ;
CODE:007B2739 ; 3. 把user1的用户名,逐个字母的Ascii码转成Str,并存入
CODE:007B2739 ; user2:
CODE:007B2739 ; for i := 1 to Length(user1) do
CODE:007B2739 ; begin
CODE:007B2739 ; user2 := user2 + IntToStr(Ord(user1[i]));
CODE:007B2739 ; end;
CODE:007B2739 ;
CODE:007B2739 ; 4. 以user2中5个字母为一组,计算索引AIndex
CODE:007B2739 ; 从buf[AIndex]选出字母,组成一个新的中间用户名user3:
CODE:007B2739 ; while i <= Length(user2) do
CODE:007B2739 ; begin
CODE:007B2739 ; s := copy(user2, i, 5);
CODE:007B2739 ; w := StrToInt(s);
CODE:007B2739 ; s1 := '';
CODE:007B2739 ; if w > 0 then
CODE:007B2739 ; repeat
CODE:007B2739 ; a := w div $25;
CODE:007B2739 ; AIndex := w mod $25;
CODE:007B2739 ; s1 := buf[AIndex+1] + s1;
CODE:007B2739 ; w := a;
CODE:007B2739 ; until a = 0;
CODE:007B2739 ; user3 := user3 + s1;
CODE:007B2739 ; i := i + 5;
CODE:007B2739 ; end;
CODE:007B2739 ;
CODE:007B2739 ; 5. 从user3中,通过一定的运算,组合出最终编码过后的用户名,
CODE:007B2739 ; 新用户名长度为0CH
CODE:007B2739 ;
CODE:007B2739 ; userLen := Length(user3);
CODE:007B2739 ; result := '';
CODE:007B2739 ; for i := 1 to $c do
CODE:007B2739 ; begin
CODE:007B2739 ; AIndex := i * userLen div $C;
CODE:007B2739 ; result := result + UpperCase(user3[AIndex]);
CODE:007B2739 ; end;
CODE:007B2739 ;
CODE:007B273E mov eax, [ebp+var_230]
CODE:007B2744 call ComputeValue ; 通过一定的算法计算用户名的值,得到一个dword值
CODE:007B2744 ;
CODE:007B2744 ; 算法很简单,直接列出来吧:
CODE:007B2744 ; Encode proc near
CODE:007B2744 ; push ebx
CODE:007B2744 ; push esi
CODE:007B2744 ; xor ecx, ecx
CODE:007B2744 ; mov ebx, edx
CODE:007B2744 ; dec ebx
CODE:007B2744 ; test ebx, ebx
CODE:007B2744 ; jl short loc_7B2088
CODE:007B2744 ; inc ebx
CODE:007B2744 ;
CODE:007B2744 ; loc_7B2064:
CODE:007B2744 ; shl ecx, 4
CODE:007B2744 ; xor edx, edx
CODE:007B2744 ; mov dl, [eax]
CODE:007B2744 ; add ecx, edx
CODE:007B2744 ; mov edx, ecx
CODE:007B2744 ; and edx, 0F0000000h
CODE:007B2744 ; test edx, edx
CODE:007B2744 ; jz short loc_7B2080
CODE:007B2744 ; mov esi, edx
CODE:007B2744 ; shr esi, 18h
CODE:007B2744 ; xor ecx, esi
CODE:007B2744 ;
CODE:007B2744 ; loc_7B2080:
CODE:007B2744 ; not edx
CODE:007B2744 ; and ecx, edx
CODE:007B2744 ; inc eax
CODE:007B2744 ; dec ebx
CODE:007B2744 ; jnz short loc_7B2064
CODE:007B2744 ;
CODE:007B2744 ; loc_7B2088:
CODE:007B2744 ; mov eax, ecx
CODE:007B2744 ; pop esi
CODE:007B2744 ; pop ebx
CODE:007B2744 ; retn
CODE:007B2744 ; Encode endp
CODE:007B2744 ;
CODE:007B2744 ;
CODE:007B2744 ;
CODE:007B2744 ; 函数原型: function ComputeValue(username: string): DWORD;
CODE:007B2744 ;
CODE:007B2749 cmp ebx, eax ; 如果计算得到的用户名的值等于解码后的RegCodeNumber的后4个字节
CODE:007B2749 ; 那么注册成功
CODE:007B274B jz short loc_7B2754
CODE:007B274D
CODE:007B274D loc_7B274D: ; CODE XREF: CheckRegCode+237j
CODE:007B274D xor ebx, ebx
CODE:007B274F jmp @Exit ; default
CODE:007B2754 ; -------------------------------------------------------------------------------?
CODE:007B2754
CODE:007B2754 loc_7B2754: ; CODE XREF: CheckRegCode+277j
CODE:007B2754 mov bl, 1
CODE:007B2756 jmp @Exit ; default
CODE:007B275B ; -------------------------------------------------------------------------------?
CODE:007B275B
CODE:007B275B loc_7B275B: ; CODE XREF: CheckRegCode+85j
CODE:007B275B ; DATA XREF: CheckRegCode:off_7B2560o
CODE:007B275B lea edx, [ebp+RegCodeNumber] ; case 0x5
CODE:007B275E mov eax, offset Key1
CODE:007B2763 call CheckRegCode2bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B2763 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B2763 ; 是否为5B9C
CODE:007B2763 ; 如果为5B9C则返回true
CODE:007B2763 ; 否则返回false
CODE:007B2763 ;
CODE:007B2763 ; Key为:
CODE:007B2763 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B2763 ;
CODE:007B2763 ; 函数原型:
CODE:007B2763 ; function CheckRegCode2bytes(Key: TKey128; RegCodeNumber: array of byte): boolean;
CODE:007B2768 test al, al
CODE:007B276A jz short loc_7B27AC
CODE:007B276C lea edx, [ebp+RegCodeNumber]
CODE:007B276F mov eax, offset Key1
CODE:007B2774 call GetRegcodeNumberLast4Bytes ; 取出解码后的RegCode的后4个字节
CODE:007B2779 mov ebx, eax
CODE:007B277B lea eax, [ebp+var_23C]
CODE:007B2781 lea edx, [ebp+User]
CODE:007B2787 call PChar ; Borland Visual Component Library & Packages
CODE:007B278C mov eax, [ebp+var_23C]
CODE:007B2792 lea edx, [ebp+var_238]
CODE:007B2798 call EnCodeUser ; 编码用户名
CODE:007B2798 ; 分下面5个步骤
CODE:007B2798 ; 1. 构建码表 buf
CODE:007B2798 ; 把上面运算得到的3个字符串连接起来
CODE:007B2798 ; 0012F61C 01B05BF0 ASCII "zyxwvutsrqpo"
CODE:007B2798 ; 0012F614 01B05C0C ASCII "HIJKLMNOPQRSTUV"
CODE:007B2798 ; 0012F610 015B083C ASCII "0987654321"
CODE:007B2798 ;
CODE:007B2798 ; 2.如果用户名长度等于17H,则把用户转为大写
CODE:007B2798 ; 如果用户名长度大于17H,则通过一定的规则取其输入
CODE:007B2798 ; 的用户名,组合成17H长度,全部字母转为大写
CODE:007B2798 ; 如果用户名长度不足17H,则通过一个补码表把用户名补足
CODE:007B2798 ; 17H长度,全部字母转为大写
CODE:007B2798 ;
CODE:007B2798 ; 转换后的用户名存入user1
CODE:007B2798 ;
CODE:007B2798 ; 3. 把user1的用户名,逐个字母的Ascii码转成Str,并存入
CODE:007B2798 ; user2:
CODE:007B2798 ; for i := 1 to Length(user1) do
CODE:007B2798 ; begin
CODE:007B2798 ; user2 := user2 + IntToStr(Ord(user1[i]));
CODE:007B2798 ; end;
CODE:007B2798 ;
CODE:007B2798 ; 4. 以user2中5个字母为一组,计算索引AIndex
CODE:007B2798 ; 从buf[AIndex]选出字母,组成一个新的中间用户名user3:
CODE:007B2798 ; while i <= Length(user2) do
CODE:007B2798 ; begin
CODE:007B2798 ; s := copy(user2, i, 5);
CODE:007B2798 ; w := StrToInt(s);
CODE:007B2798 ; s1 := '';
CODE:007B2798 ; if w > 0 then
CODE:007B2798 ; repeat
CODE:007B2798 ; a := w div $25;
CODE:007B2798 ; AIndex := w mod $25;
CODE:007B2798 ; s1 := buf[AIndex+1] + s1;
CODE:007B2798 ; w := a;
CODE:007B2798 ; until a = 0;
CODE:007B2798 ; user3 := user3 + s1;
CODE:007B2798 ; i := i + 5;
CODE:007B2798 ; end;
CODE:007B2798 ;
CODE:007B2798 ; 5. 从user3中,通过一定的运算,组合出最终编码过后的用户名,
CODE:007B2798 ; 新用户名长度为0CH
CODE:007B2798 ;
CODE:007B2798 ; userLen := Length(user3);
CODE:007B2798 ; result := '';
CODE:007B2798 ; for i := 1 to $c do
CODE:007B2798 ; begin
CODE:007B2798 ; AIndex := i * userLen div $C;
CODE:007B2798 ; result := result + UpperCase(user3[AIndex]);
CODE:007B2798 ; end;
CODE:007B2798 ;
CODE:007B279D mov eax, [ebp+var_238]
CODE:007B27A3 call ComputeValue ; 通过一定的算法计算用户名的值,得到一个dword值
CODE:007B27A3 ;
CODE:007B27A3 ; 算法很简单,直接列出来吧:
CODE:007B27A3 ; Encode proc near
CODE:007B27A3 ; push ebx
CODE:007B27A3 ; push esi
CODE:007B27A3 ; xor ecx, ecx
CODE:007B27A3 ; mov ebx, edx
CODE:007B27A3 ; dec ebx
CODE:007B27A3 ; test ebx, ebx
CODE:007B27A3 ; jl short loc_7B2088
CODE:007B27A3 ; inc ebx
CODE:007B27A3 ;
CODE:007B27A3 ; loc_7B2064:
CODE:007B27A3 ; shl ecx, 4
CODE:007B27A3 ; xor edx, edx
CODE:007B27A3 ; mov dl, [eax]
CODE:007B27A3 ; add ecx, edx
CODE:007B27A3 ; mov edx, ecx
CODE:007B27A3 ; and edx, 0F0000000h
CODE:007B27A3 ; test edx, edx
CODE:007B27A3 ; jz short loc_7B2080
CODE:007B27A3 ; mov esi, edx
CODE:007B27A3 ; shr esi, 18h
CODE:007B27A3 ; xor ecx, esi
CODE:007B27A3 ;
CODE:007B27A3 ; loc_7B2080:
CODE:007B27A3 ; not edx
CODE:007B27A3 ; and ecx, edx
CODE:007B27A3 ; inc eax
CODE:007B27A3 ; dec ebx
CODE:007B27A3 ; jnz short loc_7B2064
CODE:007B27A3 ;
CODE:007B27A3 ; loc_7B2088:
CODE:007B27A3 ; mov eax, ecx
CODE:007B27A3 ; pop esi
CODE:007B27A3 ; pop ebx
CODE:007B27A3 ; retn
CODE:007B27A3 ; Encode endp
CODE:007B27A3 ;
CODE:007B27A3 ;
CODE:007B27A3 ;
CODE:007B27A3 ; 函数原型: function ComputeValue(username: string): DWORD;
CODE:007B27A3 ;
CODE:007B27A8 cmp ebx, eax ; 如果计算得到的用户名的值等于解码后的RegCodeNumber的后4个字节
CODE:007B27A8 ; 那么注册成功
CODE:007B27AA jz short loc_7B27B3
CODE:007B27AC
CODE:007B27AC loc_7B27AC: ; CODE XREF: CheckRegCode+296j
CODE:007B27AC xor ebx, ebx
CODE:007B27AE jmp @Exit ; default
CODE:007B27B3 ; -------------------------------------------------------------------------------?
CODE:007B27B3
CODE:007B27B3 loc_7B27B3: ; CODE XREF: CheckRegCode+2D6j
CODE:007B27B3 mov bl, 1
CODE:007B27B5 jmp @Exit ; default
CODE:007B27BA ; -------------------------------------------------------------------------------?
CODE:007B27BA
CODE:007B27BA loc_7B27BA: ; CODE XREF: CheckRegCode+85j
CODE:007B27BA ; DATA XREF: CheckRegCode:off_7B2560o
CODE:007B27BA lea edx, [ebp+RegCodeNumber] ; case 0x6
CODE:007B27BD mov eax, offset Key1
CODE:007B27C2 call CheckRegCode2bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B27C2 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B27C2 ; 是否为5B9C
CODE:007B27C2 ; 如果为5B9C则返回true
CODE:007B27C2 ; 否则返回false
CODE:007B27C2 ;
CODE:007B27C2 ; Key为:
CODE:007B27C2 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B27C2 ;
CODE:007B27C2 ; 函数原型:
CODE:007B27C2 ; function CheckRegCode2bytes(Key: TKey128; RegCodeNumber: array of byte): boolean;
CODE:007B27C7 test al, al
CODE:007B27C9 jz short loc_7B280B
CODE:007B27CB lea edx, [ebp+RegCodeNumber]
CODE:007B27CE mov eax, offset Key1
CODE:007B27D3 call GetRegcodeNumberLast4Bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B27D3 ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B27D3 ; 是否为5B9C
CODE:007B27D3 ; 如果为5B9C则返回解码后的RegCodeNumber的后4个字节
CODE:007B27D3 ; 否则返回0
CODE:007B27D3 ;
CODE:007B27D3 ; Key为:
CODE:007B27D3 ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B27D3 ;
CODE:007B27D3 ; 函数原型:
CODE:007B27D3 ; function GetRegcodeNumberLast4Bytes(Key: TKey128; RegCodeNumber: array of byte): DWORD;
CODE:007B27D8 mov ebx, eax
CODE:007B27DA lea eax, [ebp+var_244]
CODE:007B27E0 lea edx, [ebp+User]
CODE:007B27E6 call PChar ; Borland Visual Component Library & Packages
CODE:007B27EB mov eax, [ebp+var_244]
CODE:007B27F1 lea edx, [ebp+var_240]
CODE:007B27F7 call EnCodeUser ; 编码用户名
CODE:007B27F7 ; 分下面5个步骤
CODE:007B27F7 ; 1. 构建码表 buf
CODE:007B27F7 ; 把上面运算得到的3个字符串连接起来
CODE:007B27F7 ; 0012F61C 01B05BF0 ASCII "zyxwvutsrqpo"
CODE:007B27F7 ; 0012F614 01B05C0C ASCII "HIJKLMNOPQRSTUV"
CODE:007B27F7 ; 0012F610 015B083C ASCII "0987654321"
CODE:007B27F7 ;
CODE:007B27F7 ; 2.如果用户名长度等于17H,则把用户转为大写
CODE:007B27F7 ; 如果用户名长度大于17H,则通过一定的规则取其输入
CODE:007B27F7 ; 的用户名,组合成17H长度,全部字母转为大写
CODE:007B27F7 ; 如果用户名长度不足17H,则通过一个补码表把用户名补足
CODE:007B27F7 ; 17H长度,全部字母转为大写
CODE:007B27F7 ;
CODE:007B27F7 ; 转换后的用户名存入user1
CODE:007B27F7 ;
CODE:007B27F7 ; 3. 把user1的用户名,逐个字母的Ascii码转成Str,并存入
CODE:007B27F7 ; user2:
CODE:007B27F7 ; for i := 1 to Length(user1) do
CODE:007B27F7 ; begin
CODE:007B27F7 ; user2 := user2 + IntToStr(Ord(user1[i]));
CODE:007B27F7 ; end;
CODE:007B27F7 ;
CODE:007B27F7 ; 4. 以user2中5个字母为一组,计算索引AIndex
CODE:007B27F7 ; 从buf[AIndex]选出字母,组成一个新的中间用户名user3:
CODE:007B27F7 ; while i <= Length(user2) do
CODE:007B27F7 ; begin
CODE:007B27F7 ; s := copy(user2, i, 5);
CODE:007B27F7 ; w := StrToInt(s);
CODE:007B27F7 ; s1 := '';
CODE:007B27F7 ; if w > 0 then
CODE:007B27F7 ; repeat
CODE:007B27F7 ; a := w div $25;
CODE:007B27F7 ; AIndex := w mod $25;
CODE:007B27F7 ; s1 := buf[AIndex+1] + s1;
CODE:007B27F7 ; w := a;
CODE:007B27F7 ; until a = 0;
CODE:007B27F7 ; user3 := user3 + s1;
CODE:007B27F7 ; i := i + 5;
CODE:007B27F7 ; end;
CODE:007B27F7 ;
CODE:007B27F7 ; 5. 从user3中,通过一定的运算,组合出最终编码过后的用户名,
CODE:007B27F7 ; 新用户名长度为0CH
CODE:007B27F7 ;
CODE:007B27F7 ; userLen := Length(user3);
CODE:007B27F7 ; result := '';
CODE:007B27F7 ; for i := 1 to $c do
CODE:007B27F7 ; begin
CODE:007B27F7 ; AIndex := i * userLen div $C;
CODE:007B27F7 ; result := result + UpperCase(user3[AIndex]);
CODE:007B27F7 ; end;
CODE:007B27F7 ;
CODE:007B27FC mov eax, [ebp+var_240]
CODE:007B2802 call ComputeValue ; 通过一定的算法计算用户名的值,得到一个dword值
CODE:007B2802 ;
CODE:007B2802 ; 算法很简单,直接列出来吧:
CODE:007B2802 ; Encode proc near
CODE:007B2802 ; push ebx
CODE:007B2802 ; push esi
CODE:007B2802 ; xor ecx, ecx
CODE:007B2802 ; mov ebx, edx
CODE:007B2802 ; dec ebx
CODE:007B2802 ; test ebx, ebx
CODE:007B2802 ; jl short loc_7B2088
CODE:007B2802 ; inc ebx
CODE:007B2802 ;
CODE:007B2802 ; loc_7B2064:
CODE:007B2802 ; shl ecx, 4
CODE:007B2802 ; xor edx, edx
CODE:007B2802 ; mov dl, [eax]
CODE:007B2802 ; add ecx, edx
CODE:007B2802 ; mov edx, ecx
CODE:007B2802 ; and edx, 0F0000000h
CODE:007B2802 ; test edx, edx
CODE:007B2802 ; jz short loc_7B2080
CODE:007B2802 ; mov esi, edx
CODE:007B2802 ; shr esi, 18h
CODE:007B2802 ; xor ecx, esi
CODE:007B2802 ;
CODE:007B2802 ; loc_7B2080:
CODE:007B2802 ; not edx
CODE:007B2802 ; and ecx, edx
CODE:007B2802 ; inc eax
CODE:007B2802 ; dec ebx
CODE:007B2802 ; jnz short loc_7B2064
CODE:007B2802 ;
CODE:007B2802 ; loc_7B2088:
CODE:007B2802 ; mov eax, ecx
CODE:007B2802 ; pop esi
CODE:007B2802 ; pop ebx
CODE:007B2802 ; retn
CODE:007B2802 ; Encode endp
CODE:007B2802 ;
CODE:007B2802 ;
CODE:007B2802 ;
CODE:007B2802 ; 函数原型: function ComputeValue(username: string): DWORD;
CODE:007B2802 ;
CODE:007B2807 cmp ebx, eax ; 如果计算得到的用户名的值等于解码后的RegCodeNumber的后4个字节
CODE:007B2807 ; 那么注册成功
CODE:007B2809 jz short loc_7B280F
CODE:007B280B
CODE:007B280B loc_7B280B: ; CODE XREF: CheckRegCode+2F5j
CODE:007B280B xor ebx, ebx
CODE:007B280D jmp short @Exit ; default
CODE:007B280F ; -------------------------------------------------------------------------------?
CODE:007B280F
CODE:007B280F loc_7B280F: ; CODE XREF: CheckRegCode+335j
CODE:007B280F mov bl, 1
CODE:007B2811 jmp short @Exit ; default
CODE:007B2813 ; -------------------------------------------------------------------------------?
CODE:007B2813
CODE:007B2813 loc_7B2813: ; CODE XREF: CheckRegCode+85j
CODE:007B2813 ; DATA XREF: CheckRegCode:off_7B2560o
CODE:007B2813 lea edx, [ebp+RegCodeNumber] ; case 0x7
CODE:007B2816 mov eax, offset Key1
CODE:007B281B call CheckRegCode2bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B281B ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B281B ; 是否为5B9C
CODE:007B281B ; 如果为5B9C则返回true
CODE:007B281B ; 否则返回false
CODE:007B281B ;
CODE:007B281B ; Key为:
CODE:007B281B ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B281B ;
CODE:007B281B ; 函数原型:
CODE:007B281B ; function CheckRegCode2bytes(Key: TKey128; RegCodeNumber: array of byte): boolean;
CODE:007B2820 test al, al
CODE:007B2822 jz short loc_7B2864
CODE:007B2824 lea edx, [ebp+RegCodeNumber]
CODE:007B2827 mov eax, offset Key1
CODE:007B282C call GetRegcodeNumberLast4Bytes ; 用Lockbox Quick cipher 解码RegCodeNumber
CODE:007B282C ; 并检查解码后的RegCodeNumber的前2个字节
CODE:007B282C ; 是否为5B9C
CODE:007B282C ; 如果为5B9C则返回解码后的RegCodeNumber的后4个字节
CODE:007B282C ; 否则返回0
CODE:007B282C ;
CODE:007B282C ; Key为:
CODE:007B282C ; DATA:009D8730 Key1 dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
CODE:007B282C ;
CODE:007B282C ; 函数原型:
CODE:007B282C ; function GetRegcodeNumberLast4Bytes(Key: TKey128; RegCodeNumber: array of byte): DWORD;
CODE:007B2831 mov ebx, eax
CODE:007B2833 lea eax, [ebp+var_24C]
CODE:007B2839 lea edx, [ebp+User]
CODE:007B283F call PChar ; Borland Visual Component Library & Packages
CODE:007B2844 mov eax, [ebp+var_24C]
CODE:007B284A lea edx, [ebp+var_248]
CODE:007B2850 call EnCodeUser ; 编码用户名
CODE:007B2850 ; 分下面5个步骤
CODE:007B2850 ; 1. 构建码表 buf
CODE:007B2850 ; 把上面运算得到的3个字符串连接起来
CODE:007B2850 ; 0012F61C 01B05BF0 ASCII "zyxwvutsrqpo"
CODE:007B2850 ; 0012F614 01B05C0C ASCII "HIJKLMNOPQRSTUV"
CODE:007B2850 ; 0012F610 015B083C ASCII "0987654321"
CODE:007B2850 ;
CODE:007B2850 ; 2.如果用户名长度等于17H,则把用户转为大写
CODE:007B2850 ; 如果用户名长度大于17H,则通过一定的规则取其输入
CODE:007B2850 ; 的用户名,组合成17H长度,全部字母转为大写
CODE:007B2850 ; 如果用户名长度不足17H,则通过一个补码表把用户名补足
CODE:007B2850 ; 17H长度,全部字母转为大写
CODE:007B2850 ;
CODE:007B2850 ; 转换后的用户名存入user1
CODE:007B2850 ;
CODE:007B2850 ; 3. 把user1的用户名,逐个字母的Ascii码转成Str,并存入
CODE:007B2850 ; user2:
CODE:007B2850 ; for i := 1 to Length(user1) do
CODE:007B2850 ; begin
CODE:007B2850 ; user2 := user2 + IntToStr(Ord(user1[i]));
CODE:007B2850 ; end;
CODE:007B2850 ;
CODE:007B2850 ; 4. 以user2中5个字母为一组,计算索引AIndex
CODE:007B2850 ; 从buf[AIndex]选出字母,组成一个新的中间用户名user3:
CODE:007B2850 ; while i <= Length(user2) do
CODE:007B2850 ; begin
CODE:007B2850 ; s := copy(user2, i, 5);
CODE:007B2850 ; w := StrToInt(s);
CODE:007B2850 ; s1 := '';
CODE:007B2850 ; if w > 0 then
CODE:007B2850 ; repeat
CODE:007B2850 ; a := w div $25;
CODE:007B2850 ; AIndex := w mod $25;
CODE:007B2850 ; s1 := buf[AIndex+1] + s1;
CODE:007B2850 ; w := a;
CODE:007B2850 ; until a = 0;
CODE:007B2850 ; user3 := user3 + s1;
CODE:007B2850 ; i := i + 5;
CODE:007B2850 ; end;
CODE:007B2850 ;
CODE:007B2850 ; 5. 从user3中,通过一定的运算,组合出最终编码过后的用户名,
CODE:007B2850 ; 新用户名长度为0CH
CODE:007B2850 ;
CODE:007B2850 ; userLen := Length(user3);
CODE:007B2850 ; result := '';
CODE:007B2850 ; for i := 1 to $c do
CODE:007B2850 ; begin
CODE:007B2850 ; AIndex := i * userLen div $C;
CODE:007B2850 ; result := result + UpperCase(user3[AIndex]);
CODE:007B2850 ; end;
CODE:007B2850 ;
CODE:007B2855 mov eax, [ebp+var_248]
CODE:007B285B call ComputeValue ; 通过一定的算法计算用户名的值,得到一个dword值
CODE:007B285B ;
CODE:007B285B ; 算法很简单,直接列出来吧:
CODE:007B285B ; Encode proc near
CODE:007B285B ; push ebx
CODE:007B285B ; push esi
CODE:007B285B ; xor ecx, ecx
CODE:007B285B ; mov ebx, edx
CODE:007B285B ; dec ebx
CODE:007B285B ; test ebx, ebx
CODE:007B285B ; jl short loc_7B2088
CODE:007B285B ; inc ebx
CODE:007B285B ;
CODE:007B285B ; loc_7B2064:
CODE:007B285B ; shl ecx, 4
CODE:007B285B ; xor edx, edx
CODE:007B285B ; mov dl, [eax]
CODE:007B285B ; add ecx, edx
CODE:007B285B ; mov edx, ecx
CODE:007B285B ; and edx, 0F0000000h
CODE:007B285B ; test edx, edx
CODE:007B285B ; jz short loc_7B2080
CODE:007B285B ; mov esi, edx
CODE:007B285B ; shr esi, 18h
CODE:007B285B ; xor ecx, esi
CODE:007B285B ;
CODE:007B285B ; loc_7B2080:
CODE:007B285B ; not edx
CODE:007B285B ; and ecx, edx
CODE:007B285B ; inc eax
CODE:007B285B ; dec ebx
CODE:007B285B ; jnz short loc_7B2064
CODE:007B285B ;
CODE:007B285B ; loc_7B2088:
CODE:007B285B ; mov eax, ecx
CODE:007B285B ; pop esi
CODE:007B285B ; pop ebx
CODE:007B285B ; retn
CODE:007B285B ; Encode endp
CODE:007B285B ;
CODE:007B285B ;
CODE:007B285B ;
CODE:007B285B ; 函数原型: function ComputeValue(username: string): DWORD;
CODE:007B285B ;
CODE:007B2860 cmp ebx, eax ; 如果计算得到的用户名的值等于解码后的RegCodeNumber的后4个字节
CODE:007B2860 ; 那么注册成功
CODE:007B2862 jz short loc_7B2868
CODE:007B2864
CODE:007B2864 loc_7B2864: ; CODE XREF: CheckRegCode+34Ej
CODE:007B2864 xor ebx, ebx
CODE:007B2866 jmp short @Exit ; default
CODE:007B2868 ; -------------------------------------------------------------------------------?
CODE:007B2868
CODE:007B2868 loc_7B2868: ; CODE XREF: CheckRegCode+38Ej
CODE:007B2868 mov bl, 1
CODE:007B286A
CODE:007B286A @Exit: ; CODE XREF: CheckRegCode+7Fj
CODE:007B286A ; CheckRegCode+FFj ...
CODE:007B286A xor eax, eax ; default
CODE:007B286C pop edx
CODE:007B286D pop ecx
CODE:007B286E pop ecx
CODE:007B286F mov fs:[eax], edx
CODE:007B2872 push offset loc_7B288F
CODE:007B2877
CODE:007B2877 loc_7B2877: ; CODE XREF: CODE:007B288Dj
CODE:007B2877 lea eax, [ebp+var_24C]
CODE:007B287D mov edx, 11h
CODE:007B2882 call System::__linkproc__ LStrArrayClr(void)
CODE:007B2887 retn
CODE:007B2887 CheckRegCode endp ; sp = -20h
至此,注册算法我们已经分析完毕, 这个软件的注册算法中对用户名的运算比较复杂点,其他都一般,注册算法用简单的伪码表示为:
if Left(decrypt(regcode), 2) = 5B9C then
if ComputeValue(EnCodeUser(user)) = Right(decrypt(regcode), 4) then
注册成功
else
注册失败
else
注册失败
注册码的解密Key为
Key dd 95AF0D1Dh, 0D66C365Eh, 46F457DAh, 0C214D7D5h
注册码必须为16个字符
--------------------------------------------------------------------------------
【算法注册机】
现在可以写出注册机了:
const
a09 = '1234567890';
aAZBig = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
aAZSmall = 'abcdefghijklmnopqrstuvwxyz';
function f2(newuser: string): DWORD;
var
i: integer;
l: integer;
c: byte;
r, k, n: DWORD;
begin
l := Length(newuser);
r := 0;
k := 0;
for i := 1 to l do
begin
r := r shl 4;
c := Ord(newuser[i]);
r := r + c;
k := r and $F0000000;
if k <> 0 then
begin
n := k shr $18;
r := r xor n;
end;
r := r and (not k);
end;
result := r;
end;
function ComputUsernameValue(Username: string): string;
var
buf, buf1, buf2, buf3: string;
userLen: DWORD;
i: integer;
d: integer;
a, b, c: integer;
k: integer;
w: smallint;
s, s1, s2, s3: string;
AIndex: integer;
aUser: string;
begin
buf1 := ReverseString(a09);
buf2 := Copy(ReverseString(aAZSmall), 1, $c);
buf3 := Copy(aAZBig, 8, $F);
buf := buf2 + buf3 + buf1;
aUser := Username;
userLen := Length(aUser);
if userLen < $17 then
begin
k := 0;
s1 := '';
for i := 1 to $17 do
begin
d := i;
d := d * userLen;
a := d div $17;
if a = 0 then
begin
a := 1;
end;
if a = k then
begin
b := i;
c := $25 - b;
s1 := s1 + UpperCase(buf[c]);
end
else
begin
s := aUser[a];
s := UpperCase(s);
s1 := s1 + s;
k := a;
end;
end;
end
else if userLen = $17 then
begin
for i := 1 to $17 do
begin
s1 := s1 + UpperCase(aUser[i]);
end;
end
else
begin
for i := 1 to $17 do
begin
AIndex := i * userLen div $17;
s1 := s1 + UpperCase(aUser[AIndex]);
end;
end;
s2 := '';
for i := 1 to $17 do
begin
s2 := s2 + IntToStr(Ord(s1[i]));
end;
i := 1;
s3 := '';
while i <= Length(s2) do
begin
s := copy(s2, i, 5);
w := StrToInt(s);
s1 := '';
if w > 0 then
repeat
a := w div $25;
c := w mod $25;
s1 := buf[c+1] + s1;
w := a;
until a = 0;
s3 := s3 + s1;
i := i + 5;
end;
userLen := Length(s3);
s1 := '';
for i := 1 to $c do
begin
AIndex := i * userLen div $C;
s1 := s1 + UpperCase(s3[AIndex]);
end;
result := IntToHex(f2(s1), 8);
result := Format('%s%s%s%s%s%s%s%s', [result[7],
result[8], result[5], result[6], result[3],
result[4], result[1], result[2]]);
end;
type
TKey128 = array [0..15] of Byte;
TLQCBlock = array[0..1] of LongInt; { LockBox Quick Cipher }
var
Key: TKey128 = ($1D, $0D, $AF, $95, $5E, $36, $6C, $D6, $DA, $57,
$F4, $46, $D5, $D7, $14, $C2);
RegCode: string;
procedure EncryptLQC(const Key : TKey128; var Block : TLQCBlock; Encrypt : Boolean);
const
CKeyBox : array [False..True, 0..3, 0..2] of LongInt =
(((0, 3, 1), (2, 1, 3), (1, 0, 2), (3, 2, 0)),
((3, 2, 0), (1, 0, 2), (2, 1, 3), (0, 3, 1)));
var
KeyInts : array [0..3] of Longint; {!!.01}
Blocks : array [0..1] of Longint; {!!.01}
Work : LongInt;
Right : LongInt;
Left : LongInt;
R : LongInt;
AA, BB : LongInt;
CC, DD : LongInt;
begin
Move(Key, KeyInts, SizeOf(KeyInts)); {!!.01}
Move(Block, Blocks, SizeOf(Blocks)); {!!.01}
Right := Blocks[0];
Left := Blocks[1];
for R := 0 to 3 do begin
{transform the right side}
AA := Right;
BB := KeyInts[CKeyBox[Encrypt, R, 0]];
CC := KeyInts[CKeyBox[Encrypt, R, 1]];
DD := KeyInts[CKeyBox[Encrypt, R, 2]];
{commented code does not affect results - removed for speed}
AA := AA + DD; DD := DD + AA; AA := AA xor (AA shr 7);
BB := BB + AA; AA := AA + BB; BB := BB xor (BB shl 13);
CC := CC + BB; BB := BB + CC; CC := CC xor (CC shr 17);
DD := DD + CC; CC := CC + DD; DD := DD xor (DD shl 9);
AA := AA + DD; DD := DD + AA; AA := AA xor (AA shr 3);
BB := BB + AA; {AA := AA + BB;} BB := BB xor (BB shl 7);
CC := CC + BB; {BB := BB + CC;} CC := CC xor (DD shr 15);
DD := DD + CC; {CC := CC + DD;} DD := DD xor (DD shl 11);
Work := Left xor DD;
Left := Right;
Right := Work;
end;
Blocks[0] := Left;
Blocks[1] := Right;
Move(Blocks, Block, SizeOf(Block)); {!!.01}
end;
function BufferToHex(const Buf; BufSize : Cardinal) : string;
var
I : LongInt;
begin
Result := '';
for I := 0 to BufSize - 1 do
Result := Result + IntToHex(TByteArray(Buf)[I], 2); {!!.01}
end;
procedure Generate(hWnd: THandle);
var
k1, k2: byte;
Block: TLQCBlock;
begin
Randomize;
k1 := Random($FF);
k2 := Random($FF);
RegCode := '5B9C' + IntToHex(k1, 2) + IntToHex(k2, 2);
sn := error;
SendMessage(hName, WM_GETTEXT, 256, INTEGER(name));
if Length(name) > 0 then
begin
RegCode := RegCode + ComputUsernameValue(name);
Block[0] := StrToInt('$' + Copy(RegCode, 1, 2));
Block[0] := Block[0] or StrToInt('$' + Copy(RegCode, 3, 2)) shl 8;
Block[0] := Block[0] or StrToInt('$' + Copy(RegCode, 5, 2)) shl 16;
Block[0] := Block[0] or StrToInt('$' + Copy(RegCode, 7, 2)) shl 24;
Block[1] := StrToInt('$' + Copy(RegCode, 9, 2));
Block[1] := Block[1] or StrToInt('$' + Copy(RegCode, 11, 2)) shl 8;
Block[1] := Block[1] or StrToInt('$' + Copy(RegCode, 13, 2)) shl 16;
Block[1] := Block[1] or StrToInt('$' + Copy(RegCode, 15, 2)) shl 24;
EncryptLQC(Key, Block, True);
RegCode := BufferToHex(Block, SizeOf(Block));//Format('%x, %x', [Block[0], Block[1]]);
sn := PChar(RegCode);
end;
SendMessage(hSn,WM_SETTEXT,0,Integer(sn));
SendMessage(hSn,EM_SETSEL,0,-1);
SendMessage(hSn,WM_COPY,0,0);
end;
--------------------------------------------------------------------------------
【破解总结】
此软件用了Lockbox Quick Cipher加密算法, 用户名变换部份较为复杂
我的注册码
+dEMON
AC3F1B9052E59692
注册信息放在
HKEY_CLASSES_ROOT\CLSID\{AF670D53-621C-4647-98CD-E7EDC20524EA}\152877354
[HKEY_CLASSES_ROOT\CLSID\{AF670D53-621C-4647-98CD-E7EDC20524EA}\152877354]
"0"="74627D6A7B736C657C"
"2"="6E330A1F030A"
"3"="04147C147D0666607D62087472736B77"
加了密了,真变态
删除 HKEY_CLASSES_ROOT\CLSID\{AF670D53-621C-4647-98CD-E7EDC20524EA} 下的键就可以重新注册了
--------------------------------------------------------------------------------
【感谢】
ForEver, MengLong, xIkUg, fly, kvllz, jwh51, bbbsl, winroot, xy2000, kanxue, heXer, sUNbIRD, forgot,
cnbragon, hmimys, yyxzz, CrackerABC, newlaos, woyao, linhanshi, DarkNeesOut, LeNgHoSt, shoooo, window,vcasm,lgl
all RCT members, and you!
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!