标 题:
apIt8.01注册算法初步分析
作 者: ForEver
时 间: 2006-04-02 14:11
链 接: http://bbs.pediy.com/showthread.php?threadid=23500
详细信息:
【标题】【VC】SnapIt8.01注册算法初步分析
【作者】 forever[RCT]
【语言】 VC7.1
【保护】 无壳,注册码
【难度】 复杂
【工具】 ollydbg,ida,peid
【正文】
分析这个程序时得到了xIkUg,Cnbragon,DarkNess0ut等人的帮助,在这里先说一声谢谢!同时感谢所有RCT小组
里的朋友们及所有支持我的朋友们!
用od载入程序,在注册窗口里输入用户名和注册码后,点击"ok"按钮,程序提示一个出错的对话框。提示你这是
一个无效的key。
![]()
确认后,就在od中发生异常了。仔细看,这不是一个消息框,所以不能下断点MessageBox。在这个时候看堆栈。
![]()
仔细看返回地址,直到找到最近的那个返回程序空间的那个地址,我这里是6F43D5h。Ctrl+G,输入地址,
来到下面:
在地址6F4364h按下F2下个断点。重新输入注册码,点"ok"按钮后中断在6F4364h处。下面的分析从这里开始:
.text:006F4353 lea eax, [esp+1Ch] ; 取注册码
.text:006F4357 push eax ; int
.text:006F4358 push 27EDh ; int
.text:006F435D mov ecx, esi
.text:006F435F mov [esp+8+arg_10], 1
.text:006F4364 call CWnd::GetDlgItemTextA(int,ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>> &)
.text:006F4369 lea ecx, [esp+8] ; 取用户名
.text:006F436D push ecx ; int
.text:006F436E push 27EEh ; char
.text:006F4373 mov ecx, esi
.text:006F4375 call CWnd::GetDlgItemTextA(int,ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>> &)
.text:006F437A mov ecx, [esi+74h]
.text:006F437D mov eax, [ecx+34h]
.text:006F4380 test eax, eax
.text:006F4382 jnz short loc_6F43B7
.text:006F4384 mov eax, [ecx+0BCh]
.text:006F438A test eax, eax
.text:006F438C jz short loc_6F43B7
.text:006F438E call sub_6F2260
.text:006F4393 test eax, eax
.text:006F4395 jnz short loc_6F43B7
.text:006F4397 push offset aReset ; "reset"
.text:006F439C lea ecx, [esp+4+arg_18]
.text:006F43A0 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::CompareNoCase(char const *)
.text:006F43A6 test eax, eax
.text:006F43A8 jnz short loc_6F43B7
.text:006F43AA mov ecx, [esi+74h]
.text:006F43AD push eax ; int
.text:006F43AE push 1 ; int
.text:006F43B0 call sub_6F2A40
.text:006F43B5 jmp short loc_6F43D5
.text:006F43B7
.text:006F43B7 loc_6F43B7:
.text:006F43B7 mov ecx, [esi+74h]
.text:006F43BA lea edx, [esp+8] ; 用户名
.text:006F43BE push edx
.text:006F43BF lea eax, [esp+32] ; 注册码
.text:006F43C3 push eax ; int
.text:006F43C4 push esi ; int
.text:006F43C5 call sub_6F2660 ; 关键CALL,要跟进
.text:006F43CA test al, al
.text:006F43CC jnz short loc_6F43D5
.text:006F43CE mov ecx, edi
.text:006F43D0 call CDataExchange::Fail(void)
.text:006F43D5
.text:006F2660 sub_6F2660 proc near
.text:006F2660 arg_0 = dword ptr 4
.text:006F2660 arg_4 = dword ptr 8
.text:006F2660 arg_B0 = dword ptr 0B4h
.text:006F2660
.text:006F2660 push ebx
.text:006F2661 mov ebx, [esp+8]
.text:006F2665 test ebx, ebx
.text:006F2667 push ebp ; uType
.text:006F2668 push esi ; lpCaption
.text:006F2669 mov esi, ecx
.text:006F266B jnz short loc_6F2687
.text:006F266D call AfxGetThread(void)
.text:006F2672 test eax, eax
.text:006F2674 jz short loc_6F2681
.text:006F2676 mov edx, [eax]
.text:006F2678 mov ecx, eax
.text:006F267A call dword ptr [edx+7Ch]
.text:006F267D mov ebx, eax
.text:006F267F jmp short loc_6F2683
.text:006F2681 loc_6F2681:
.text:006F2681 xor ebx, ebx
.text:006F2683
.text:006F2683 loc_6F2683:
.text:006F2683 mov [esp+0Ch+arg_0], ebx
.text:006F2687
.text:006F2687 loc_6F2687:
.text:006F2687 mov ebp, [esp+18h] ; 判断用户名是否为空
.text:006F268B mov ecx, ebp
.text:006F268D call ds:ATL::CSimpleStringT<char,1>::IsEmpty(void)
.text:006F2693 test al, al
.text:006F2695 jz short loc_6F26DE ; 这里要跳
.text:006F2697 push 283Eh
.text:006F269C lea ecx, [esp+14h]
.text:006F26A0 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(char const *)
.text:006F26A6 test ebx, ebx
.text:006F26A8 jz short loc_6F26AD
.text:006F26AA mov ebx, [ebx+20h]
.text:006F26AD
.text:006F26AD loc_6F26AD:
.text:006F26AD push 0
.text:006F26AF lea ecx, [esi+48h]
.text:006F26B2 call ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:006F26B8 push eax
.text:006F26B9 lea ecx, [esp+18h]
.text:006F26BD call ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:006F26C3 push eax ; lpText
.text:006F26C4 push ebx ; hWnd
.text:006F26C5 call ds:MessageBoxA
.text:006F26CB lea ecx, [esp+10h]
.text:006F26CF call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::~CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
.text:006F26D5 pop esi
.text:006F26D6 pop ebp
.text:006F26D7 xor ax, ax
.text:006F26DA pop ebx
.text:006F26DB retn 0Ch
.text:006F26DE loc_6F26DE:
.text:006F26DE push edi
.text:006F26DF mov edi, [esp+18h] ; 注册码
.text:006F26E3 mov ecx, edi
.text:006F26E5 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::Trim(void)
.text:006F26EB mov eax, [esi]
.text:006F26ED push ebp ; 用户名
.text:006F26EE push edi ; 注册码
.text:006F26EF mov ecx, esi
.text:006F26F1 call dword ptr [eax+18h] ; 512FD0 ,关键CALL1,要根进
.text:006F26F4 test al, al
.text:006F26F6 jnz short loc_6F270A ; 返回0就验证失败了
.text:006F26F8 mov edx, [esi]
.text:006F26FA push ebx
.text:006F26FB mov ecx, esi
.text:006F26FD call dword ptr [edx+1Ch]
.text:006F2700 pop edi
.text:006F2701 pop esi
.text:006F2702 pop ebp
.text:006F2703 xor ax, ax
.text:006F2706 pop ebx
.text:006F2707 retn 0Ch
.text:006F270A
.text:006F270A loc_6F270A:
.text:006F270A push offset Data
.text:006F270F push offset asc_830788 ; "-"
.text:006F2714 mov ecx, edi ; 去掉注册码中的"-"号
.text:006F2716 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::Replace(char const *,char const *)
.text:006F271C mov ebx, [esi]
.text:006F271E mov ecx, edi
.text:006F2720 call ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:006F2726 push eax ; 取得注册码,压入堆栈
.text:006F2727 mov ecx, ebp
.text:006F2729 call ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:006F272F push eax ; 取得用户名,压入堆栈
.text:006F2730 mov ecx, esi
.text:006F2732 call dword ptr [ebx+24h] ; 513700 ,关键CALL2,要根进
.text:006F2735 mov ebx, eax
.text:006F2737 cmp bl, 1
.text:006F273A jnz short loc_6F278F
.text:006F273C mov ecx, edi
.text:006F273E mov dword ptr [esi+34h], 1
.text:006F2745 mov dword ptr [esi+0BCh], 0
.text:006F274F call ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:006F2755 push eax ; lpValueName
.text:006F2756 push offset aRegistrationke ; int
.text:006F275B mov ecx, esi ; int
.text:006F275D call sub_6F1E50
.text:006F2762 mov ecx, ebp
.text:006F2764 call ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:006F276A push eax ; lpValueName
.text:006F276B push offset aRegisteredto ; int
.text:006F2770 mov ecx, esi ; int
.text:006F2772 call sub_6F1E50
.text:006F2777 mov ecx, [esp+14h]
.text:006F277B mov eax, [esi]
.text:006F277D push edi ; 注册码
.text:006F277E push ebp ; 注册名
.text:006F277F push ecx
.text:006F2780 mov ecx, esi
.text:006F2782 call dword ptr [eax+28h] ; 513bd0
.text:006F2785 pop edi
.text:006F2786 pop esi
.text:006F2787 pop ebp
.text:006F2788 mov ax, bx
.text:006F278B pop ebx
.text:006F278C retn 0Ch ; lpCaption
.text:006F278F
.text:006F278F loc_6F278F:
.text:006F278F cmp bx, 0FFFFh
.text:006F2794 mov eax, ebx
.text:006F2796 jnz short loc_6F279C
.text:006F2798 mov ax, [esi+40h]
.text:006F279C
.text:006F279C loc_6F279C:
.text:006F279C cmp ah, 11
.text:006F279F jnz short loc_6F27F1
.text:006F27A1 push 10305 ; Unfortunately, your current Software Key will
not work with this version. Upgrade today and
get a new key.
可以看出,关键CALL1要返回1,关键CALL2返回值的低8位要等于1。
下面先跟进关键CALL1:
.text:00512FD0 v1_512FD0 proc near
.text:00512FD0
.text:00512FD0 arg_0 = dword ptr 4
.text:00512FD0 arg_4 = dword ptr 8
.text:00512FD0
.text:00512FD0 mov eax, [esp+arg_4]
.text:00512FD4 push esi
.text:00512FD5 mov esi, [esp+4+arg_0]
.text:00512FD9 push eax ; 用户名
.text:00512FDA push esi ; 注册码
.text:00512FDB call sub_6F2090 ; 初步检查注册码是否合法
.text:00512FE0 test al, al ; 注册码长度要大于等于14,
.text:00512FE2 jnz short loc_513032 ; 组成注册码的字符要在 "0123456789ABCDEF-" 里
.text:00512FE4 push ebx
.text:00512FE5 push edi
.text:00512FE6 mov ecx, esi ; 注册码
.text:00512FE8 call ds:ATL::CSimpleStringT<char,1>::GetLength(void)
.text:00512FEE cmp eax, 29 ; 长度等于29则跳
.text:00512FF1 jz short loc_513004
.text:00512FF3 mov ecx, esi
.text:00512FF5 call ds:ATL::CSimpleStringT<char,1>::GetLength(void)
.text:00512FFB cmp eax, 25 ; 长度等于25则跳
.text:00512FFE jz short loc_513004
.text:00513000 xor bl, bl
.text:00513002 jmp short loc_513006
.text:00513004
.text:00513004 loc_513004:
.text:00513004
.text:00513004 mov bl, 1
.text:00513006
.text:00513006 loc_513006:
.text:00513006 mov ecx, esi
.text:00513008 call ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:0051300E push offset a23456789abcdef ; "23456789ABCDEFGHJKLMNPQRSTUVWXYZ-"
.text:00513013 push eax ; unsigned __int8 *
.text:00513014 call ds:_mbsspn
.text:0051301A add esp, 8
.text:0051301D mov ecx, esi
.text:0051301F mov edi, eax
.text:00513021 call ds:ATL::CSimpleStringT<char,1>::GetLength(void)
.text:00513027 cmp edi, eax
.text:00513029 setz cl
.text:0051302C and bl, cl
.text:0051302E pop edi
.text:0051302F mov al, bl
.text:00513031 pop ebx
.text:00513032
.text:00513032 loc_513032:
.text:00513032 pop esi
.text:00513033 retn 8
.text:00513033 v1_512FD0 endp ; sp = 14h
这里要求注册码长度要等于29或者25,并且组成注册码的字符在字符串"23456789ABCDEFGHJKLMNPQRSTUVWXYZ-"里。
接着根进关键CALL2:
.text:00513700 sub_513700 proc near
.text:00513700
.text:00513700 var_9A_f1 = byte ptr -9Ah
.text:00513700 var_99_ver = byte ptr -99h
.text:00513700 var_98_RegCode = dword ptr -98h
.text:00513700 var_91_regf = byte ptr -91h
.text:00513700 var_90 = dword ptr -90h
.text:00513700 var_8C = dword ptr -8Ch
.text:00513700 var_88 = dword ptr -88h
.text:00513700 var_7C = dword ptr -7Ch
.text:00513700 var_78 = dword ptr -78h
.text:00513700 var_6C = dword ptr -6Ch
.text:00513700 var_60 = dword ptr -60h
.text:00513700 var_54 = dword ptr -54h
.text:00513700 var_50 = dword ptr -50h
.text:00513700 var_4C = dword ptr -4Ch
.text:00513700 var_48 = word ptr -48h
.text:00513700 var_46 = byte ptr -46h
.text:00513700 var_44 = dword ptr -44h
.text:00513700 var_10 = dword ptr -10h
.text:00513700 var_C = dword ptr -0Ch
.text:00513700 var_8 = dword ptr -8
.text:00513700 var_4 = dword ptr -4
.text:00513700 arg_0 = dword ptr 4
.text:00513700 arg_4 = dword ptr 8
.text:00513700
.text:00513700 push 0FFFFFFFFh
.text:00513702 push offset loc_7DC9A5
.text:00513707 mov eax, large fs:0
.text:0051370D push eax
.text:0051370E mov large fs:0, esp
.text:00513715 sub esp, 90h
.text:0051371B mov eax, dword_8F6114
.text:00513720 push ebx
.text:00513721 push ebp
.text:00513722 push esi
.text:00513723 mov [esp+0A8h+var_10], eax
.text:0051372A mov eax, [esp+0A8h+arg_4] ; 注册码
.text:00513731 push edi ; int
.text:00513732 xor ebx, ebx
.text:00513734 mov ebp, ecx
.text:00513736 mov [esp+0ACh+var_90], ebx
.text:0051373A mov edi, 1
.text:0051373F push eax
.text:00513740 lea ecx, [esp+0B0h+var_98_RegCode]
.text:00513744 mov [esp+0B0h+var_8C], ebx ; 初值0
.text:00513748 mov [esp+0B0h+var_7C], edi ; 初值1
.text:0051374C mov [esp+0B0h+var_99_ver], 10 ; 初值10
.text:00513751 mov [esp+0B0h+var_91_regf], bl ; 初值0
.text:00513755 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(char const *)
.text:0051375B lea ecx, [esp+0ACh+var_98_RegCode] ; 注册码
.text:0051375F mov [esp+0ACh+var_4], ebx
.text:00513766 call ds:ATL::CSimpleStringT<char,1>::GetLength(void)
.text:0051376C cmp eax, 29 ; 比较长度是否等于29
.text:0051376F jz loc_51398A
.text:00513775 lea ecx, [esp+0ACh+var_98_RegCode]
.text:00513779 call ds:ATL::CSimpleStringT<char,1>::GetLength(void)
.text:0051377F cmp eax, 25 ; 比较长度是否等于25
.text:00513782 jz loc_51398A
;这里我删去了旧版本里留下来的代码
;从上面可以看出,注册码长度必须等于25或者29
;删去的这些事实上永远不会执行
.text:0051398A loc_51398A:
.text:0051398A lea ecx, [esp+0ACh+var_98_RegCode] ; 注册码
.text:0051398E lea esi, [ebp+0D4h] ; 这里要返回一个数组
.text:00513994 call ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:0051399A push eax ; 注册码
.text:0051399B mov ecx, esi ; 返回值
.text:0051399D call v_6F38C0 ; 关键CALL,要跟进******
.text:005139A2 test al, al
.text:005139A4 jz short loc_5139C6
.text:005139A6 cmp [ebp+0D8h], edi ; [1]必须为1
.text:005139AC jnz short loc_5139C6
.text:005139AE lea ecx, [esp+0ACh+var_88]
.text:005139B2 push ecx
.text:005139B3 mov ecx, esi
.text:005139B5 call sub_513450
.text:005139BA cmp dword ptr [eax], 0 ; 比较协议类型是否等于0
.text:005139BD mov ebx, edi
.text:005139BF mov [esp+0ACh+var_9A_f1], 1
.text:005139C4 jnz short loc_5139CB
.text:005139C6
.text:005139C6 loc_5139C6:
.text:005139C6 mov [esp+0ACh+var_9A_f1], 0
.text:005139CB
.text:005139CB loc_5139CB:
.text:005139CB test bl, 1
.text:005139CE jz short loc_5139DC
.text:005139D0 lea ecx, [esp+0ACh+var_88]
.text:005139D4 and ebx, 0FFFFFFFEh
.text:005139D7 call sub_4FCCA0 ; 最低位不为1则协议字符串释放
.text:005139DC
.text:005139DC loc_5139DC:
.text:005139DC mov al, [esp+0ACh+var_9A_f1]
.text:005139E0 test al, al
.text:005139E2 jz loc_513B89
.text:005139E8 push 0
.text:005139EA push 0
.text:005139EC push 8
.text:005139EE lea ecx, [esp+0B8h+var_78]
.text:005139F2 call formver_61E3F0
.text:005139F7 mov edi, eax
.text:005139F9 lea edx, [esp+0ACh+var_88]
.text:005139FD push edx
.text:005139FE mov ecx, esi
.text:00513A00 call getver_512E80
.text:00513A05 push edi
.text:00513A06 mov ecx, eax
.text:00513A08 mov byte ptr [esp+0B0h+var_4], 2
.text:00513A10 call compver_61E410 ; 检查版本信息
.text:00513A15 lea ecx, [esp+0ACh+var_88]
.text:00513A19 mov [esp+0ACh+var_9A_f1], al
.text:00513A1D mov byte ptr [esp+0ACh+var_4], 1
.text:00513A25 call nullcall
.text:00513A2A lea ecx, [esp+0ACh+var_78]
.text:00513A2E mov byte ptr [esp+0ACh+var_4], 0
.text:00513A36 call nullcall
.text:00513A3B mov al, [esp+0ACh+var_9A_f1]
.text:00513A3F test al, al
.text:00513A41 jz short loc_513A80
.text:00513A43 lea eax, [esp+0ACh+var_88]
.text:00513A47 push eax
.text:00513A48 mov ecx, esi
.text:00513A4A mov [esp+0B0h+var_91_regf], 1 ; 注册成功标志
.text:00513A4F call sub_513450
.text:00513A54 mov eax, [eax]
.text:00513A56 lea ecx, [ebp+0CCh]
.text:00513A5C push eax
.text:00513A5D mov byte ptr [esp+0B0h+var_4], 3
.text:00513A65 call GetLicType_61E070
.text:00513A6A lea ecx, [esp+0ACh+var_88]
.text:00513A6E mov byte ptr [esp+0ACh+var_4], 0
.text:00513A76 call sub_4FCCA0
.text:00513A7B jmp loc_513B89
.text:00513A80
.text:00513A80 loc_513A80:
;删除一些检查是否是老版本的注册码的代码
.text:00513B7C
.text:00513B7C loc_513B7C:
.text:00513B7C mov al, [esp+0ACh+var_9A_f1]
.text:00513B80 test al, al
.text:00513B82 jz short loc_513B89
.text:00513B84 mov [esp+0ACh+var_99_ver], 11 ; 旧版本标志
.text:00513B89
.text:00513B89 loc_513B89:
.text:00513B89 lea ecx, [esp+0ACh+var_98_RegCode]
.text:00513B8D call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::~CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
.text:00513B93 mov ecx, [esp+0ACh+var_C]
.text:00513B9A xor eax, eax
.text:00513B9C mov ah, [esp+0ACh+var_99_ver] ; 旧版本标志
.text:00513BA0 pop edi
.text:00513BA1 pop esi
.text:00513BA2 pop ebp
.text:00513BA3 mov large fs:0, ecx
.text:00513BAA mov ecx, [esp+0A0h+var_10]
.text:00513BB1 pop ebx
.text:00513BB2 mov al, [esp+9Ch+var_91_regf] ; 注册成功标志
.text:00513BB6 call sub_6FBECD
.text:00513BBB add esp, 9Ch
.text:00513BC1 retn 8
.text:00513BC1 sub_513700 endp
继续跟进 v_6F38C0 这个关键CALL,胜利在望,但痛苦才刚刚开始..
.text:006F38C0 v_6F38C0 proc near
.text:006F38C0
.text:006F38C0 var_4C_r21 = dword ptr -4Ch
.text:006F38C0 var_48_md5s = dword ptr -48h
.text:006F38C0 var_44_RegCode = dword ptr -44h
.text:006F38C0 var_40 = dword ptr -40h
.text:006F38C0 var_3C_r4 = dword ptr -3Ch
.text:006F38C0 var_38_s = dword ptr -38h
.text:006F38C0 var_34_sa2 = dword ptr -34h
.text:006F38C0 var_30_pStr = dword ptr -30h
.text:006F38C0 var_2C_Len = dword ptr -2Ch
.text:006F38C0 var_28 = dword ptr -28h
.text:006F38C0 var_24 = dword ptr -24h
.text:006F38C0 var_20_sa1 = dword ptr -20h
.text:006F38C0 var_1C_pStr = dword ptr -1Ch
.text:006F38C0 var_18_Len = dword ptr -18h
.text:006F38C0 var_14 = dword ptr -14h
.text:006F38C0 var_10 = dword ptr -10h
.text:006F38C0 var_4 = dword ptr -4
.text:006F38C0 arg_0 = dword ptr 4
.text:006F38C0
.text:006F38C0 push 0FFFFFFFFh
.text:006F38C2 push offset loc_7F70CF
.text:006F38C7 mov eax, large fs:0
.text:006F38CD push eax
.text:006F38CE mov large fs:0, esp
.text:006F38D5 sub esp, 40h
.text:006F38D8 mov eax, [esp+4Ch+arg_0]
.text:006F38DC push ebx
.text:006F38DD push ebp
.text:006F38DE push esi
.text:006F38DF push edi
.text:006F38E0 mov [esp+5Ch+var_40], ecx
.text:006F38E4 push eax ; 注册码
.text:006F38E5 lea ecx, [esp+60h+var_44_RegCode] ; 保存到这里
.text:006F38E9 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(char const *)
.text:006F38EF lea ecx, [esp+5Ch+var_44_RegCode] ; 去掉两边的空格
.text:006F38F3 mov [esp+5Ch+var_4], 0
.text:006F38FB call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::Trim(void)
.text:006F3901 push '-'
.text:006F3903 lea ecx, [esp+60h+var_44_RegCode] ; 删除注册码中的'-'
.text:006F3907 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::Remove(char)
.text:006F390D push ' '
.text:006F390F lea ecx, [esp+60h+var_44_RegCode] ; 删除注册码中的空格
.text:006F3913 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::Remove(char)
.text:006F3919 lea ecx, [esp+5Ch+var_44_RegCode] ; 转换成大写
.text:006F391D call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::MakeUpper(void)
.text:006F3923 lea ecx, [esp+5Ch+var_44_RegCode]
.text:006F3927 mov byte ptr [esp+5Ch+arg_0], 0
.text:006F392C call ds:ATL::CSimpleStringT<char,1>::GetLength(void) ; 取注册码长度
.text:006F3932 cmp eax, 25
.text:006F3935 jnz loc_6F3E86 ; 长度不等于25则验证失败
.text:006F393B push 4
.text:006F393D lea ecx, [esp+60h+var_3C_r4] ; 取右边4个字符保存在r4
.text:006F3941 push ecx
.text:006F3942 lea ecx, [esp+64h+var_44_RegCode]
.text:006F3946 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::Right(int)
.text:006F394C push 21
.text:006F394E lea edx, [esp+60h+var_4C_r21] ; 取左边21个字符保存在r21
.text:006F3952 push edx
.text:006F3953 lea ecx, [esp+64h+var_44_RegCode]
.text:006F3957 mov byte ptr [esp+64h+var_4], 1
.text:006F395C call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::Left(int)
.text:006F3962 push 5 ; 取r21的第6个字符
.text:006F3964 lea ecx, [esp+60h+var_4C_r21]
.text:006F3968 mov byte ptr [esp+60h+var_4], 2
.text:006F396D call ds:ATL::CSimpleStringT<char,1>::operator[](int)
.text:006F3973 or edi, 0FFFFFFFFh ; 没找到则返回-1
.text:006F3976 xor ecx, ecx
.text:006F3978
.text:006F3978 loc_6F3978:
.text:006F3978 cmp al, byte ptr ds:Table1_865058[ecx] ; "CA5BDWF4H9PJK3SUM2XEL7GRZNQTY6V8"
.text:006F397E jz short loc_6F3988
.text:006F3980 inc ecx
.text:006F3981 cmp ecx, 32
.text:006F3984 jl short loc_6F3978
.text:006F3986 jmp short loc_6F398A ; 查表
.text:006F3988
.text:006F3988 loc_6F3988:
.text:006F3988 mov edi, ecx ; 取得第6个字符在表中的索引i6
.text:006F398A
.text:006F398A loc_6F398A:
.text:006F398A push 1
.text:006F398C push 5
.text:006F398E lea ecx, [esp+64h+var_4C_r21] ; 删除r21中第六个字符
.text:006F3992 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::Delete(int,int)
.text:006F3998 push 10 ; 取r21的第11个字符
.text:006F399A lea ecx, [esp+60h+var_4C_r21]
.text:006F399E call ds:ATL::CSimpleStringT<char,1>::operator[](int)
.text:006F39A4 or esi, 0FFFFFFFFh ; 没找到则返回-1
.text:006F39A7 xor ecx, ecx
.text:006F39A9 lea esp, [esp+0]
.text:006F39B0
.text:006F39B0 loc_6F39B0:
.text:006F39B0 cmp al, byte ptr ds:Table1_865058[ecx] ; "CA5BDWF4H9PJK3SUM2XEL7GRZNQTY6V8"
.text:006F39B6 jz short loc_6F39C0
.text:006F39B8 inc ecx
.text:006F39B9 cmp ecx, 32
.text:006F39BC jl short loc_6F39B0
.text:006F39BE jmp short loc_6F39C2 ; 查表
.text:006F39C0
.text:006F39C0 loc_6F39C0:
.text:006F39C0 mov esi, ecx ; 取得第11个字符在表中的索引i11
.text:006F39C2
.text:006F39C2 loc_6F39C2:
.text:006F39C2 push 1
.text:006F39C4 push 10
.text:006F39C6 lea ecx, [esp+64h+var_4C_r21] ; 删除r21中第11个字符
.text:006F39CA call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::Delete(int,int)
.text:006F39D0 xor eax, eax
.text:006F39D2 mov ebp, (offset Table1_865058+20h) ; 构造一个动态数组
.text:006F39D7 mov [esp+5Ch+var_20_sa1], ebp
.text:006F39DB mov [esp+5Ch+var_1C_pStr], eax
.text:006F39DF mov [esp+5Ch+var_10], eax
.text:006F39E3 mov [esp+5Ch+var_14], eax
.text:006F39E7 mov [esp+5Ch+var_18_Len], eax
.text:006F39EB lea eax, [esp+5Ch+var_20_sa1]
.text:006F39EF mov bl, 3
.text:006F39F1 push eax ; 压入堆栈
.text:006F39F2 lea ecx, [esp+60h+var_4C_r21]
.text:006F39F6 mov byte ptr [esp+60h+var_4], bl
.text:006F39FA call ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:006F3A00 push eax ; r21
.text:006F3A01 call fun1_6F37C0
.text:006F3A06 add esi, 32 ; i11 += 32
.text:006F3A09 add esp, 8
.text:006F3A0C cmp esi, 0FFFFFFFFh ; if i11 == -1
.text:006F3A0F jnz short loc_6F3A16
.text:006F3A11 mov esi, [esp+5Ch+var_18_Len] ; i11 = strlen(r21) * 5 - 1
.text:006F3A15 dec esi
.text:006F3A16
.text:006F3A16 loc_6F3A16:
.text:006F3A16 mov eax, edi ; i6
.text:006F3A18 cdq
.text:006F3A19 lea ecx, [esi+1] ; i11 + 1
.text:006F3A1C idiv ecx
.text:006F3A1E push esi ; 参数4: i11
.text:006F3A1F push 0 ; 参数3: 0
.text:006F3A21 sub ecx, edx
.text:006F3A23 push ecx ; 参数2: (i11 + 1) - i6 % (i11 + 1)
.text:006F3A24 lea ecx, [esp+68h+var_20_sa1]
.text:006F3A28 push ecx ; 参数1: 数组sa1
.text:006F3A29 call fun2_6F35B0
.text:006F3A2E lea edx, [esp+6Ch+var_20_sa1]
.text:006F3A32 push edx
.text:006F3A33 lea eax, [esp+70h+var_38_s]
.text:006F3A37 push eax
.text:006F3A38 call fun3_6F36E0
.text:006F3A3D add esp, 18h
.text:006F3A40 push eax
.text:006F3A41 lea ecx, [esp+60h+var_4C_r21] ; r21
.text:006F3A45 mov byte ptr [esp+60h+var_4], 4
.text:006F3A4A call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::operator=(ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>> const &)
.text:006F3A50 lea ecx, [esp+5Ch+var_38_s]
.text:006F3A54 mov byte ptr [esp+5Ch+var_4], bl
.text:006F3A58 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::~CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
.text:006F3A5E push 10 ; 取r21的第11个字符
.text:006F3A60 lea ecx, [esp+60h+var_4C_r21]
.text:006F3A64 call ds:ATL::CSimpleStringT<char,1>::operator[](int)
.text:006F3A6A or esi, 0FFFFFFFFh ; 没找到则返回-1
.text:006F3A6D xor ecx, ecx
.text:006F3A6F nop
.text:006F3A70
.text:006F3A70 loc_6F3A70:
.text:006F3A70 cmp al, byte ptr ds:Table1_865058[ecx] ; "CA5BDWF4H9PJK3SUM2XEL7GRZNQTY6V8"
.text:006F3A76 jz short loc_6F3A80
.text:006F3A78 inc ecx
.text:006F3A79 cmp ecx, 20h
.text:006F3A7C jl short loc_6F3A70
.text:006F3A7E jmp short loc_6F3A82 ; 查表
.text:006F3A80
.text:006F3A80 loc_6F3A80:
.text:006F3A80 mov esi, ecx ; 取得第11个字符在表中的索引i11
.text:006F3A82
.text:006F3A82 loc_6F3A82:
.text:006F3A82 push 1
.text:006F3A84 push 10 ; 删除第11个字符
.text:006F3A86 lea ecx, [esp+64h+var_4C_r21]
.text:006F3A8A call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::Delete(int,int)
.text:006F3A90 lea ecx, [esp+5Ch+var_20_sa1]
.text:006F3A94 push ecx ; 动态数组
.text:006F3A95 lea ecx, [esp+60h+var_4C_r21]
.text:006F3A99 call ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:006F3A9F push eax ; r21
.text:006F3AA0 call fun1_6F37C0
.text:006F3AA5 push 0FFFFFFFFh ; 参数4: -1
.text:006F3AA7 xor edi, edi
.text:006F3AA9 push edi ; 参数3: 0
.text:006F3AAA lea edx, [esp+6Ch+var_20_sa1]
.text:006F3AAE push esi ; 参数2: i11
.text:006F3AAF push edx ; 参数1: 动态数组sa1
.text:006F3AB0 call fun2_6F35B0
.text:006F3AB5 lea eax, [esp+74h+var_20_sa1]
.text:006F3AB9 push eax
.text:006F3ABA lea ecx, [esp+78h+var_38_s]
.text:006F3ABE push ecx
.text:006F3ABF call fun3_6F36E0
.text:006F3AC4 add esp, 20h
.text:006F3AC7 push eax
.text:006F3AC8 lea ecx, [esp+60h+var_4C_r21] ; r21
.text:006F3ACC mov byte ptr [esp+60h+var_4], 5
.text:006F3AD1 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::operator=(ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>> const &)
.text:006F3AD7 lea ecx, [esp+5Ch+var_38_s]
.text:006F3ADB mov byte ptr [esp+5Ch+var_4], bl
.text:006F3ADF call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::~CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
.text:006F3AE5 lea edx, [esp+5Ch+var_4C_r21] ; r21
.text:006F3AE9 push edx
.text:006F3AEA lea eax, [esp+60h+var_48_md5s]
.text:006F3AEE push eax
.text:006F3AEF call md5_6224C0 ; 标准MD5,变换成小写字符串
.text:006F3AF4 add esp, 8
.text:006F3AF7 push 4
.text:006F3AF9 lea ecx, [esp+60h+var_38_s] ; 取md5s的左边4个字符
.text:006F3AFD push ecx
.text:006F3AFE lea ecx, [esp+64h+var_48_md5s]
.text:006F3B02 mov byte ptr [esp+64h+var_4], 6
.text:006F3B07 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::Left(int)
.text:006F3B0D push eax
.text:006F3B0E lea ecx, [esp+60h+var_48_md5s] ; 保存到这里
.text:006F3B12 mov byte ptr [esp+60h+var_4], 7
.text:006F3B17 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::operator=(ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>> const &)
.text:006F3B1D lea ecx, [esp+5Ch+var_38_s]
.text:006F3B21 mov byte ptr [esp+5Ch+var_4], 6
.text:006F3B26 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::~CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
.text:006F3B2C xor esi, esi
.text:006F3B2E mov edi, edi
.text:006F3B30
.text:006F3B30 loc_6F3B30:
.text:006F3B30 push esi
.text:006F3B31 lea ecx, [esp+60h+var_48_md5s]
.text:006F3B35 call ds:ATL::CSimpleStringT<char,1>::operator[](int)
.text:006F3B3B cmp al, '0' ; 把'0'替换成'R'
.text:006F3B3D lea ecx, [esp+5Ch+var_48_md5s]
.text:006F3B41 jnz short loc_6F3B47
.text:006F3B43 push 'R'
.text:006F3B45 jmp short loc_6F3B58
.text:006F3B47
.text:006F3B47 loc_6F3B47:
.text:006F3B47 push esi
.text:006F3B48 call ds:ATL::CSimpleStringT<char,1>::operator[](int)
.text:006F3B4E cmp al, '1' ; 把'1'替换成'M'
.text:006F3B50 jnz short loc_6F3B5F
.text:006F3B52 push 'M'
.text:006F3B54 lea ecx, [esp+60h+var_48_md5s]
.text:006F3B58
.text:006F3B58 loc_6F3B58:
.text:006F3B58 push esi
.text:006F3B59 call ds:ATL::CSimpleStringT<char,1>::SetAt(int,char)
.text:006F3B5F
.text:006F3B5F loc_6F3B5F:
.text:006F3B5F inc esi
.text:006F3B60 cmp esi, 4
.text:006F3B63 jl short loc_6F3B30
.text:006F3B65 lea ecx, [esp+5Ch+var_48_md5s] ; 转换成大写
.text:006F3B69 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::MakeUpper(void)
.text:006F3B6F lea ecx, [esp+5Ch+var_3C_r4]
.text:006F3B73 call ds:ATL::CSimpleStringT<char,1>::operator char const *(void)
.text:006F3B79 push eax
.text:006F3B7A lea ecx, [esp+60h+var_48_md5s]
.text:006F3B7E call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::Compare(char const *)
.text:006F3B84 test eax, eax ; 和注册码的最后4个字符比较
.text:006F3B86 jnz loc_6F3E52 ; 不等则校验失败
.text:006F3B8C mov [esp+5Ch+var_34_sa2], ebp ; 构造一个动态数组
.text:006F3B90 mov [esp+5Ch+var_30_pStr], edi
.text:006F3B94 mov [esp+5Ch+var_24], edi
.text:006F3B98 mov [esp+5Ch+var_28], edi
.text:006F3B9C mov [esp+5Ch+var_2C_Len], edi
.text:006F3BA0 push 0FFFFFFFFh
.text:006F3BA2 push 60 ; 数组大小
.text:006F3BA4 lea ecx, [esp+64h+var_34_sa2]
.text:006F3BA8 mov byte ptr [esp+64h+var_4], 8
.text:006F3BAD call new_6F3410 ; 分配60个字节空间
.text:006F3BB2 lea ecx, [esp+5Ch+var_4C_r21] ; r21
.text:006F3BB6 xor esi, esi
.text:006F3BB8 xor ebx, ebx
.text:006F3BBA call ds:ATL::CSimpleStringT<char,1>::GetLength(void)
.text:006F3BC0 test eax, eax
.text:006F3BC2 jle loc_6F3C4E
.text:006F3BC8 xor ebp, ebp
.text:006F3BCA lea ebx, [ebx+0]
.text:006F3BD0
.text:006F3BD0 loc_6F3BD0:
.text:006F3BD0 push ebx
.text:006F3BD1 lea ecx, [esp+60h+var_4C_r21] ; 取r21一个字符
.text:006F3BD5 call ds:ATL::CSimpleStringT<char,1>::operator[](int)
.text:006F3BDB or edi, 0FFFFFFFFh ; 没找到则返回-1
.text:006F3BDE xor ecx, ecx
.text:006F3BE0
.text:006F3BE0 loc_6F3BE0:
.text:006F3BE0 cmp al, byte ptr ds:Table1_865058[ecx] ; "CA5BDWF4H9PJK3SUM2XEL7GRZNQTY6V8"
.text:006F3BE6 jz short loc_6F3BF0
.text:006F3BE8 inc ecx
.text:006F3BE9 cmp ecx, 32
.text:006F3BEC jl short loc_6F3BE0
.text:006F3BEE jmp short loc_6F3BF2 ; 查表
.text:006F3BF0
.text:006F3BF0 loc_6F3BF0:
.text:006F3BF0 mov edi, ecx ; 取得在表中的索引
.text:006F3BF2
.text:006F3BF2 loc_6F3BF2:
.text:006F3BF2 xor ecx, ecx
.text:006F3BF4
.text:006F3BF4 loc_6F3BF4:
.text:006F3BF4 lea edx, [ecx+ebp]
.text:006F3BF7 mov eax, offset Table2_864FE0
.text:006F3BFC lea esp, [esp+0]
.text:006F3C00
.text:006F3C00 loc_6F3C00:
.text:006F3C00 cmp edx, [eax]
.text:006F3C02 jz &