【标题】【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 short loc_6F3C34
.text:006F3C04 add eax, 4
.text:006F3C07 cmp eax, offset Table1_865058 ; "CA5BDWF4H9PJK3SUM2XEL7GRZNQTY6V8"
.text:006F3C0C jl short loc_6F3C00
.text:006F3C0E test esi, esi
.text:006F3C10 jl failed_6F3EA9
.text:006F3C16 cmp esi, [esp+5Ch+var_2C_Len]
.text:006F3C1A jge failed_6F3EA9
.text:006F3C20 mov edx, 1
.text:006F3C25 shl edx, cl
.text:006F3C27 test edx, edi
.text:006F3C29 mov edx, [esp+5Ch+var_30_pStr]
.text:006F3C2D setnz al
.text:006F3C30 mov [edx+esi], al
.text:006F3C33 inc esi
.text:006F3C34
.text:006F3C34 loc_6F3C34:
.text:006F3C34 inc ecx
.text:006F3C35 cmp ecx, 5
.text:006F3C38 jl short loc_6F3BF4
.text:006F3C3A lea ecx, [esp+5Ch+var_4C_r21]
.text:006F3C3E inc ebx
.text:006F3C3F add ebp, 5
.text:006F3C42 call ds:ATL::CSimpleStringT<char,1>::GetLength(void)
.text:006F3C48 cmp ebx, eax
.text:006F3C4A jl short loc_6F3BD0
.text:006F3C4C xor edi, edi
.text:006F3C4E
.text:006F3C4E loc_6F3C4E:
.text:006F3C4E mov esi, [esp+5Ch+var_30_pStr]
.text:006F3C52 mov ebx, [esp+5Ch+var_2C_Len]
.text:006F3C56 xor edx, edx
.text:006F3C58 mov eax, 21
.text:006F3C5D lea ecx, [ecx+0]
.text:006F3C60
.text:006F3C60 loc_6F3C60:
.text:006F3C60 cmp eax, edi
.text:006F3C62 jl failed_6F3EA9
.text:006F3C68 cmp eax, ebx
.text:006F3C6A jge failed_6F3EA9
.text:006F3C70 cmp byte ptr [esi+eax], 0
.text:006F3C74 jz short loc_6F3C82
.text:006F3C76 lea ecx, [eax-21]
.text:006F3C79 mov ebp, 1
.text:006F3C7E shl ebp, cl
.text:006F3C80 or edx, ebp
.text:006F3C82
.text:006F3C82 loc_6F3C82:
.text:006F3C82 inc eax
.text:006F3C83 cmp eax, 26
.text:006F3C86 jle short loc_6F3C60 ; 21-26,必须为0
.text:006F3C88 cmp edx, edi
.text:006F3C8A mov eax, [esp+5Ch+var_40]
.text:006F3C8E mov [eax], edx ; 保存结果
.text:006F3C90 jnz loc_6F3E40
.text:006F3C96 xor eax, eax
.text:006F3C98 xor ecx, ecx
.text:006F3C9A lea ebx, [ebx+0]
.text:006F3CA0
.text:006F3CA0 loc_6F3CA0:
.text:006F3CA0 cmp ecx, edi
.text:006F3CA2 jl failed_6F3EA9
.text:006F3CA8 cmp ecx, ebx
.text:006F3CAA jge failed_6F3EA9
.text:006F3CB0 cmp byte ptr [esi+ecx], 0
.text:006F3CB4 jz short loc_6F3CBF
.text:006F3CB6 mov edx, 1
.text:006F3CBB shl edx, cl
.text:006F3CBD or eax, edx
.text:006F3CBF
.text:006F3CBF loc_6F3CBF:
.text:006F3CBF inc ecx
.text:006F3CC0 cmp ecx, 4 ; 0-4
.text:006F3CC3 jle short loc_6F3CA0
.text:006F3CC5 mov ebp, [esp+5Ch+var_40]
.text:006F3CC9 mov [ebp+1Ch], eax ; 保存结果
.text:006F3CCC xor edi, edi
.text:006F3CCE mov eax, 5
.text:006F3CD3
.text:006F3CD3 loc_6F3CD3:
.text:006F3CD3 test eax, eax
.text:006F3CD5 jl failed_6F3EA9
.text:006F3CDB cmp eax, ebx
.text:006F3CDD jge failed_6F3EA9
.text:006F3CE3 cmp byte ptr [esi+eax], 0
.text:006F3CE7 jz short loc_6F3CF5
.text:006F3CE9 lea ecx, [eax-5]
.text:006F3CEC mov edx, 1
.text:006F3CF1 shl edx, cl
.text:006F3CF3 or edi, edx
.text:006F3CF5
.text:006F3CF5 loc_6F3CF5:
.text:006F3CF5 inc eax
.text:006F3CF6 cmp eax, 8 ; 5-8,主版本号
.text:006F3CF9 jle short loc_6F3CD3
.text:006F3CFB xor esi, esi
.text:006F3CFD mov eax, 9
.text:006F3D02
.text:006F3D02 loc_6F3D02:
.text:006F3D02 test eax, eax
.text:006F3D04 jl failed_6F3EA9
.text:006F3D0A cmp eax, ebx
.text:006F3D0C jge failed_6F3EA9
.text:006F3D12 mov ecx, [esp+5Ch+var_30_pStr]
.text:006F3D16 cmp byte ptr [ecx+eax], 0
.text:006F3D1A jz short loc_6F3D28
.text:006F3D1C lea ecx, [eax-9]
.text:006F3D1F mov edx, 1
.text:006F3D24 shl edx, cl
.text:006F3D26 or esi, edx
.text:006F3D28
.text:006F3D28 loc_6F3D28:
.text:006F3D28 inc eax
.text:006F3D29 cmp eax, 12 ; 9-12,从版本号
.text:006F3D2C jle short loc_6F3D02
.text:006F3D2E xor edx, edx
.text:006F3D30 mov eax, 13
.text:006F3D35
.text:006F3D35 loc_6F3D35:
.text:006F3D35 test eax, eax
.text:006F3D37 jl failed_6F3EA9
.text:006F3D3D cmp eax, ebx
.text:006F3D3F jge failed_6F3EA9
.text:006F3D45 mov ecx, [esp+5Ch+var_30_pStr]
.text:006F3D49 cmp byte ptr [ecx+eax], 0
.text:006F3D4D jz short loc_6F3D5F
.text:006F3D4F lea ecx, [eax-13]
.text:006F3D52 mov ebx, 1
.text:006F3D57 shl ebx, cl
.text:006F3D59 or edx, ebx
.text:006F3D5B mov ebx, [esp+5Ch+var_2C_Len]
.text:006F3D5F
.text:006F3D5F loc_6F3D5F:
.text:006F3D5F inc eax
.text:006F3D60 cmp eax, 16 ; 13-16,从版本号
.text:006F3D63 jle short loc_6F3D35
.text:006F3D65 push edx
.text:006F3D66 push esi
.text:006F3D67 push edi
.text:006F3D68 lea ecx, [ebp+8]
.text:006F3D6B call sub_61E140
.text:006F3D70 mov esi, [esp+5Ch+var_30_pStr]
.text:006F3D74 xor edx, edx
.text:006F3D76 mov eax, 17
.text:006F3D7B jmp short loc_6F3D80
.text:006F3D7D lea ecx, [ecx+0]
.text:006F3D80
.text:006F3D80 loc_6F3D80:
.text:006F3D80 test eax, eax
.text:006F3D82 jl failed_6F3EA9
.text:006F3D88 cmp eax, ebx
.text:006F3D8A jge failed_6F3EA9
.text:006F3D90 cmp byte ptr [esi+eax], 0
.text:006F3D94 jz short loc_6F3DA2
.text:006F3D96 lea ecx, [eax-11h]
.text:006F3D99 mov edi, 1
.text:006F3D9E shl edi, cl
.text:006F3DA0 or edx, edi
.text:006F3DA2
.text:006F3DA2 loc_6F3DA2:
.text:006F3DA2 inc eax
.text:006F3DA3 cmp eax, 20 ; 17-20 协议类型
.text:006F3DA6 jle short loc_6F3D80
.text:006F3DA8 push edx
.text:006F3DA9 lea ecx, [ebp+14h]
.text:006F3DAC call GetLicType_61E070
.text:006F3DB1 xor edx, edx
.text:006F3DB3 mov eax, 27
.text:006F3DB8
.text:006F3DB8 loc_6F3DB8:
.text:006F3DB8 test eax, eax
.text:006F3DBA jl failed_6F3EA9
.text:006F3DC0 cmp eax, ebx
.text:006F3DC2 jge failed_6F3EA9
.text:006F3DC8 cmp byte ptr [esi+eax], 0
.text:006F3DCC jz short loc_6F3DDA
.text:006F3DCE lea ecx, [eax-1Bh]
.text:006F3DD1 mov edi, 1
.text:006F3DD6 shl edi, cl
.text:006F3DD8 or edx, edi
.text:006F3DDA
.text:006F3DDA loc_6F3DDA:
.text:006F3DDA inc eax
.text:006F3DDB cmp eax, 31 ; 27-31,必须为1
.text:006F3DDE jle short loc_6F3DB8
.text:006F3DE0 mov [ebp+4], edx
.text:006F3DE3 xor eax, eax
.text:006F3DE5 mov edx, 32
.text:006F3DEA lea ebx, [ebx+0]
.text:006F3DF0
.text:006F3DF0 loc_6F3DF0:
.text:006F3DF0 test edx, edx
.text:006F3DF2 jl failed_6F3EA9
.text:006F3DF8 cmp edx, ebx
.text:006F3DFA jge failed_6F3EA9
.text:006F3E00 cmp byte ptr [esi+edx], 0
.text:006F3E04 jz short loc_6F3E12
.text:006F3E06 lea ecx, [edx-32]
.text:006F3E09 mov edi, 1
.text:006F3E0E shl edi, cl
.text:006F3E10 or eax, edi
.text:006F3E12
.text:006F3E12 loc_6F3E12:
.text:006F3E12 inc edx
.text:006F3E13 cmp edx, 45 ; 32-45
.text:006F3E16 jle short loc_6F3DF0 ; Cnbragon说这个是试用版天数限制:)
.text:006F3E18 push 0
.text:006F3E1A cdq
.text:006F3E1B push 15180h
.text:006F3E20 push edx ; 0
.text:006F3E21 push eax
.text:006F3E22 call __allmul
.text:006F3E27 mov esi, [esp+5Ch+var_30_pStr]
.text:006F3E2B add eax, 301DDF00h
.text:006F3E30 adc edx, 0
.text:006F3E33 mov [ebp+20h], eax
.text:006F3E36 mov [ebp+24h], edx
.text:006F3E39 mov byte ptr [esp+5Ch+arg_0], 1
.text:006F3E3E xor edi, edi
.text:006F3E40
.text:006F3E40 loc_6F3E40:
.text:006F3E40 cmp esi, edi
.text:006F3E42 mov byte ptr [esp+5Ch+var_4], 6
.text:006F3E47 jz short loc_6F3E52
.text:006F3E49 push esi
.text:006F3E4A call operator delete[](void *)
.text:006F3E4F add esp, 4
.text:006F3E52
.text:006F3E52 loc_6F3E52:
.text:006F3E52 lea ecx, [esp+5Ch+var_48_md5s]
.text:006F3E56 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::~CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
.text:006F3E5C mov eax, [esp+5Ch+var_1C_pStr]
.text:006F3E60 cmp eax, edi
.text:006F3E62 mov byte ptr [esp+5Ch+var_4], 2
.text:006F3E67 jz short loc_6F3E72
.text:006F3E69 push eax
.text:006F3E6A call operator delete[](void *)
.text:006F3E6F add esp, 4
.text:006F3E72
.text:006F3E72 loc_6F3E72:
.text:006F3E72 lea ecx, [esp+5Ch+var_4C_r21]
.text:006F3E76 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::~CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
.text:006F3E7C lea ecx, [esp+5Ch+var_3C_r4]
.text:006F3E80 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::~CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
.text:006F3E86
.text:006F3E86 loc_6F3E86:
.text:006F3E86 lea ecx, [esp+5Ch+var_44_RegCode]
.text:006F3E8A call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::~CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
.text:006F3E90 mov ecx, [esp+50h]
.text:006F3E94 mov al, byte ptr [esp+5Ch+arg_0]
.text:006F3E98 pop edi
.text:006F3E99 pop esi
.text:006F3E9A pop ebp
.text:006F3E9B pop ebx
.text:006F3E9C mov large fs:0, ecx
.text:006F3EA3 add esp, 4Ch
.text:006F3EA6 retn 4
.text:006F3EA9
.text:006F3EA9 failed_6F3EA9:
.text:006F3EA9 call AfxThrowInvalidArgException(void)
.text:006F3EAF v_6F38C0 endp
从上面也可以看出,注册码长度必须为25。
最后解析出来的60个位就是key的内容了。
我逆向了部分及其中的3个子程序,如下:
char * Table1[] = {"CA5BDWF4H9PJK3SUM2XEL7GRZNQTY6V8"};
int Table2[30] = {0 , 6, 0x0B, 0x0C, 0x11, 0x16, 0x19, 0x1C, 0x1D, 0x1E,
0x1F, 0x26, 0x27, 0x28, 0x29, 0x2F, 0x30, 0x31, 0x32, 0x37,
0x3C, 0x41, 0x44, 0x45, 0x46, 0x47, 0x4D, 0x4E, 0x54, 0x59};
CString sLic[] = {"Eval",
"Single",
"Multi",
"Academic"};
struct strarray{
int len;
unsigned char * sp;
};
int funv1(int retValue[],CString RegCode)
{
CString r21,r4,md5s;
char c1;
int len,i,j,k,l,n,m;
int i6,i11;
unsigned int x;
RegCode.TrimLeft();
RegCode.TrimRight();
RegCode.Remove('-');
RegCode.Remove(' ');
RegCode.MakeUpper();
if(RegCode.GetLength() != 25)return 0;
r4 = RegCode.Left(4);
r21 = RegCode.Right(21);
c1 = r21[5];
i6 = -1;
for(i = 0; i < 32; i ++)
{
if(c1 == Table1[i])
{
i6 = i;
break;
}
}
r21.Delete(5,1);
c1 = r21[10];
i11 = -1;
for(i = 0; i < 32; i ++)
{
if(c1 == Table1[i])
{
i11 = i;
break;
}
}
r21.Delete(10,1);
strarray sa1;
sa1.len = 0;
sa1.sp = NULL;
fun1(r21,&sa1);
i11 += 32;
if(i11 == -1)i11 = sa1.len - 1;
i = (i11 + 1) - i6 % (i11 + 1);
fun2(&sa1,i,0,i11);
r21 = fun3(&sa1);
c1 = r21[10];
i11 = -1;
for(i = 0; i < 32; i ++)
{
if(c1 == Table1[i])
{
i11 = i;
break;
}
}
r21.Delete(10,1);
fun1(r21,&sa1);
fun2(&sa1,i11,0,-1);
r21 = fun3(&sa1);
md5s = md5(r21);
md5s = md5s.Left(4);
for(i = 0; i < 4; i ++)
{
if(md5s[i] == '0')
md5s.SetAt(i,'R');
esle if(md5s[i] == '1')
md5s.SetAt(i,'M');
}
md5s.MakeUpper();
if(md5s.Compare(r4) != 0)return 0;
strarray sa2;
sa2.len = 0;
sa2.sp = NULL;
sa2.sp = new unsigned char[60];
sa2.len = 60;
memset(sa2.sp,0,60);
m = 0;
l = 0;
if(r21.GetLength() > 0)
{
for(j = 0; j < r21.GetLength(); j ++)
{
i6 = -1;
c1 = r21[j];
for(i = 0; i < 32; i ++)
{
if(c1 == Table1[i])
{
i6 = i;
break;
}
}
k = 0;
n = 0;
for(k = 0; k < 5; k ++)
{
for(n = 0; n < 30; n ++)
if((k+l) == Table2[n])
goto next1;
sa2.sp[m] = (((1 << k) & i6) != 0) ? 1 : 0;
m ++;
next1:
}
l += 5;
}
}
x = 0;
for(i = 21; i <= 26; i ++) //取key的21到26位,这里必须为0
{
if(sa2.sp[i] != 0)
{
x |= (1 << (i - 21));
}
}
retValue[0] = x;
if(x != 0)return 0;
x = 0;
for(i = 0; i <= 4; i ++)
{
if(sa2.sp[i] != 0)
{
x |= (1 << i);
}
}
retValue[7] = x;
x = 0;
for(i = 5; i <= 8; i ++)
{
if(sa2.sp[i] != 0)
{
x |= (1 <<(i-5));
}
}
retValue[2] = x;
x = 0;
for(i = 9; i <= 12; i ++)
{
if(sa2.sp[i] != 0)
{
x |= (1 <<(i-9));
}
}
retValue[3] = x;
x = 0;
for(i = 13; i <= 16; i ++)
{
if(sa2.sp[i] != 0)
{
x |= (1 <<(i-13));
}
}
retValue[4] = x;
x = 0;
for(i = 17; i <= 20; i ++)
{
if(sa2.sp[i] != 0)
{
x |= (1 <<(i-17));
}
}
if((x < 0) || (x >= 4)) x = 0;
retValue[5] = x;
retValue[6] = sLic[x];
x = 0;
for(i = 27; i <= 31; i ++)
{
if(sa2.sp[i] != 0)
{
x |= (1 <<(i-27));
}
}
retValue[1] = x;
x = 0;
for(i = 32; i <= 45; i ++)
{
if(sa2.sp[i] != 0)
{
x |= (1 <<(i-32));
}
}
__int64 y = Int32x32To64(x,0x15180);
y += 0x301DDF00;
*(__int64*)(&retvalue[8]) = y;
if(sa2.sp != NULL)delete [] sa2.sp;
sa2.sp = NULL;
sa2.len = 0;
if(sa1.sp != NULL)delete [] sa1.sp;
sa1.sp = NULL;
sa1.len = 0;
}
下面是其中3个子程序的逆向:
=======================================================================================
.text:006F37C0 fun1_6F37C0 proc near
.text:006F37C0
.text:006F37C0 var_10 = dword ptr -10h
.text:006F37C0 var_8 = dword ptr -8
.text:006F37C0 var_4 = dword ptr -4
.text:006F37C0 arg_0 = dword ptr 4
.text:006F37C0 arg_4 = dword ptr 8
.text:006F37C0
.text:006F37C0 push 0FFFFFFFFh
.text:006F37C2 push offset loc_7F7069
.text:006F37C7 mov eax, large fs:0
.text:006F37CD push eax
.text:006F37CE mov large fs:0, esp
.text:006F37D5 push ecx
.text:006F37D6 mov eax, [esp+10h+arg_0] ; 注册码
.text:006F37DA push ebx
.text:006F37DB push ebp
.text:006F37DC push esi
.text:006F37DD push edi
.text:006F37DE push eax
.text:006F37DF lea ecx, [esp+24h+var_10] ; 保存到这里
.text:006F37E3 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(char const *)
.text:006F37E9 mov esi, [esp+20h+arg_4] ; 动态数组
.text:006F37ED mov eax, [esi+4] ; 取数组长度
.text:006F37F0 xor ebp, ebp
.text:006F37F2 cmp eax, ebp
.text:006F37F4 mov [esp+20h+var_4], ebp
.text:006F37F8 jz short loc_6F3806
.text:006F37FA push eax
.text:006F37FB call operator delete[](void *) ; 数组已经分配则先释放
.text:006F3800 add esp, 4
.text:006F3803 mov [esi+4], ebp
.text:006F3806
.text:006F3806 loc_6F3806:
.text:006F3806 push 0FFFFFFFFh
.text:006F3808 lea ecx, [esp+24h+var_10] ; 注册码
.text:006F380C mov [esi+0Ch], ebp
.text:006F380F mov [esi+8], ebp
.text:006F3812 call ds:ATL::CSimpleStringT<char,1>::GetLength(void)
.text:006F3818 lea ecx, [eax+eax*4] ; 长度乘以5
.text:006F381B push ecx
.text:006F381C mov ecx, esi
.text:006F381E call new_6F3410 ; 分配空间
.text:006F3823 lea ecx, [esp+20h+var_10] ; 注册码
.text:006F3827 call ds:ATL::CSimpleStringT<char,1>::GetLength(void)
.text:006F382D test eax, eax ; 取注册码长度
.text:006F382F jle short loc_6F389C
.text:006F3831 mov [esp+20h+arg_4], ebp ; 计数器清零,这里使用的一个参数空间作为变量
.text:006F3835
.text:006F3835 loc_6F3835:
.text:006F3835 push ebp ; 取一个字符
.text:006F3836 lea ecx, [esp+24h+var_10]
.text:006F383A call ds:ATL::CSimpleStringT<char,1>::operator[](int)
.text:006F3840 or edi, 0FFFFFFFFh
.text:006F3843 xor ecx, ecx
.text:006F3845
.text:006F3845 loc_6F3845:
.text:006F3845 cmp al, byte ptr ds:Table1_865058[ecx]
.text:006F384B jz short loc_6F3855
.text:006F384D inc ecx
.text:006F384E cmp ecx, 32
.text:006F3851 jl short loc_6F3845
.text:006F3853 jmp short loc_6F3857 ; 检查是否在表中
.text:006F3855
.text:006F3855 loc_6F3855:
.text:006F3855 mov edi, ecx ; 取得索引
.text:006F3857
.text:006F3857 loc_6F3857:
.text:006F3857 mov eax, [esp+20h+arg_4]
.text:006F385B xor ecx, ecx
.text:006F385D lea ecx, [ecx+0]
.text:006F3860
.text:006F3860 loc_6F3860:
.text:006F3860 test eax, eax
.text:006F3862 jl short loc_6F38B9 ; 计数器小于0则跳
.text:006F3864 cmp eax, [esi+8]
.text:006F3867 jge short loc_6F38B9 ; 计数器大于等于注册码长度*5则跳
.text:006F3869 mov ebx, [esi+4] ; 取动态内存地址
.text:006F386C mov edx, 1
.text:006F3871 shl edx, cl
.text:006F3873 test edx, edi
.text:006F3875 setnz dl ; 取出索引的0-5位
.text:006F3878 inc ecx
.text:006F3879 mov [eax+ebx], dl
.text:006F387C inc eax
.text:006F387D cmp ecx, 5
.text:006F3880 jl short loc_6F3860
.text:006F3882 mov edx, [esp+20h+arg_4]
.text:006F3886 add edx, 5 ; 计数器加上5
.text:006F3889 lea ecx, [esp+10h]
.text:006F388D inc ebp
.text:006F388E mov [esp+20h+arg_4], edx
.text:006F3892 call ds:ATL::CSimpleStringT<char,1>::GetLength(void)
.text:006F3898 cmp ebp, eax
.text:006F389A jl short loc_6F3835 ; 没处理完则继续
.text:006F389C
.text:006F389C loc_6F389C:
.text:006F389C lea ecx, [esp+20h+var_10]
.text:006F38A0 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::~CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
.text:006F38A6 mov ecx, [esp+14h]
.text:006F38AA pop edi
.text:006F38AB pop esi
.text:006F38AC pop ebp
.text:006F38AD pop ebx
.text:006F38AE mov large fs:0, ecx
.text:006F38B5 add esp, 10h
.text:006F38B8 retn
.text:006F38B9
.text:006F38B9 loc_6F38B9:
.text:006F38B9
.text:006F38B9 jmp AfxThrowInvalidArgException(void)
.text:006F38B9 fun1_6F37C0 endp
=======================================================================================
struct strarray{
int len;
char * sp;
};
strarray sa;
char Table[] = {"CA5BDWF4H9PJK3SUM2XEL7GRZNQTY6V8"};
void fun1(CString s,strarray * p)
{
int i,j,k,index;
unsigned int x;
if(p -> len != 0)
delete [](p -> sp);
p -> sp = 0;
p -> len = s.GetLength() * 5;
p -> sp = new char[p -> len];
memset(p -> sp,0,p -> len);
if(s.GetLength() <= 0)return;
j = 0;
k = 0;
do{
index = -1;
for(i = 0; i < 32; i++)
{
if(s[j] = Table[i])
{
index = i;
break;
}
}
for(i = 0; i < 5; i++)
{
x = 1;
x = x << i;
if(x & index)
(p -> sa)[k] = 1;
k ++;
}
j ++;
}while(j < s.GetLength());
}
=======================================================================================
.text:006F35B0 fun2_6F35B0 proc near
.text:006F35B0
.text:006F35B0 var_20 = dword ptr -20h
.text:006F35B0 var_1C_pStr = dword ptr -1Ch
.text:006F35B0 var_18_Len = dword ptr -18h
.text:006F35B0 var_14 = dword ptr -14h
.text:006F35B0 var_10 = dword ptr -10h
.text:006F35B0 var_C = dword ptr -0Ch
.text:006F35B0 var_4 = dword ptr -4
.text:006F35B0 arg_0 = dword ptr 4
.text:006F35B0 arg_4 = dword ptr 8
.text:006F35B0 arg_8 = dword ptr 0Ch
.text:006F35B0 arg_C = dword ptr 10h
.text:006F35B0
.text:006F35B0 mov eax, large fs:0
.text:006F35B6 push 0FFFFFFFFh
.text:006F35B8 push offset loc_7F7028
.text:006F35BD push eax
.text:006F35BE mov large fs:0, esp
.text:006F35C5 sub esp, 14h
.text:006F35C8 push ebx
.text:006F35C9 push ebp
.text:006F35CA mov ebp, [esp+28h+arg_C] ; 参数4
.text:006F35CE cmp ebp, 0FFFFFFFFh
.text:006F35D1 push esi
.text:006F35D2 push edi
.text:006F35D3 mov edi, [esp+30h+arg_0] ; 参数1,结构地址
.text:006F35D7 jnz short loc_6F35DD
.text:006F35D9 mov ebp, [edi+8] ; 5F
.text:006F35DC dec ebp
.text:006F35DD
.text:006F35DD loc_6F35DD:
.text:006F35DD mov ebx, [esp+30h+arg_8] ; 参数3:0
.text:006F35E1 xor eax, eax
.text:006F35E3 mov esi, ebp
.text:006F35E5 sub esi, ebx
.text:006F35E7 inc esi ; 参数4-参数3+1
.text:006F35E8 mov [esp+30h+var_20], offset off_865078
.text:006F35F0 mov [esp+30h+var_1C_pStr], eax
.text:006F35F4 mov [esp+30h+var_10], eax
.text:006F35F8 mov [esp+30h+var_14], eax
.text:006F35FC mov [esp+30h+var_18_Len], eax
.text:006F3600 push 0FFFFFFFFh
.text:006F3602 push esi ; 大小
.text:006F3603 lea ecx, [esp+38h+var_20]
.text:006F3607 mov [esp+38h+var_4], eax
.text:006F360B call new_6F3410 ; 分配空间
.text:006F3610 xor ecx, ecx
.text:006F3612 cmp ebx, ebp
.text:006F3614 mov eax, ebx
.text:006F3616 jg short loc_6F3657
.text:006F3618 jmp short loc_6F3620
.text:006F361A
.text:006F361A loc_6F361A:
.text:006F361A mov edi, [esp+30h+arg_0] ; 参数1,结构地址
.text:006F361E mov edi, edi
.text:006F3620
.text:006F3620 loc_6F3620:
.text:006F3620 test eax, eax
.text:006F3622 jl loc_6F36D2
.text:006F3628 cmp eax, [edi+8]
.text:006F362B jge loc_6F36D2
.text:006F3631 mov edi, [edi+4] ; 字符串指针
.text:006F3634 add edi, eax
.text:006F3636 test ecx, ecx
.text:006F3638 jl loc_6F36D2
.text:006F363E cmp ecx, [esp+30h+var_18_Len]
.text:006F3642 jge loc_6F36D2
.text:006F3648 mov dl, [edi]
.text:006F364A mov edi, [esp+30h+var_1C_pStr] ; 新建结构的字符串指针
.text:006F364E inc eax
.text:006F364F mov [edi+ecx], dl ; 复制结构中的部分值
.text:006F3652 inc ecx
.text:006F3653 cmp eax, ebp
.text:006F3655 jle short loc_6F361A
.text:006F3657
.text:006F3657 loc_6F3657:
.text:006F3657 mov eax, [esp+30h+arg_4] ; 参数2
.text:006F365B cdq
.text:006F365C idiv esi ; 新分配的空间大小
.text:006F365E xor ebp, ebp
.text:006F3660 test esi, esi
.text:006F3662 mov ecx, ebx ; 参数3:0
.text:006F3664 jle short loc_6F36A6
.text:006F3666 mov eax, edx ; 参数2模空间大小的值
.text:006F3668 sub eax, ebx ; 减去参数3
.text:006F366A mov [esp+30h+arg_C], eax ; 保存结果
.text:006F366E jmp short loc_6F3674
.text:006F3670
.text:006F3670 loc_6F3670:
.text:006F3670 mov eax, [esp+30h+arg_C]
.text:006F3674
.text:006F3674 loc_6F3674:
.text:006F3674 add eax, ecx
.text:006F3676 cdq
.text:006F3677 idiv esi
.text:006F3679 mov edi, edx ; 取模
.text:006F367B test edi, edi
.text:006F367D jl short loc_6F36D2
.text:006F367F cmp edi, [esp+30h+var_18_Len]
.text:006F3683 jge short loc_6F36D2
.text:006F3685 test ecx, ecx
.text:006F3687 jl short loc_6F36D2
.text:006F3689 mov eax, [esp+30h+arg_0] ; 取参数1:结构地址
.text:006F368D cmp ecx, [eax+8]
.text:006F3690 jge short loc_6F36D2
.text:006F3692 mov eax, [eax+4] ; 取指针地址
.text:006F3695 mov edx, [esp+30h+var_1C_pStr] ; 取新建结构的指针
.text:006F3699 mov dl, [edx+edi]
.text:006F369C add eax, ecx
.text:006F369E inc ebp
.text:006F369F inc ecx
.text:006F36A0 cmp ebp, esi
.text:006F36A2 mov [eax], dl
.text:006F36A4 jl short loc_6F3670
.text:006F36A6
.text:006F36A6 loc_6F36A6:
.text:006F36A6 mov eax, [esp+30h+var_1C_pStr]
.text:006F36AA test eax, eax
.text:006F36AC mov [esp+30h+var_4], 0FFFFFFFFh
.text:006F36B4 jz short loc_6F36BF
.text:006F36B6 push eax
.text:006F36B7 call operator delete[](void *)
.text:006F36BC add esp, 4
.text:006F36BF
.text:006F36BF loc_6F36BF:
.text:006F36BF mov ecx, [esp+24h]
.text:006F36C3 pop edi
.text:006F36C4 pop esi
.text:006F36C5 pop ebp
.text:006F36C6 pop ebx
.text:006F36C7 mov large fs:0, ecx
.text:006F36CE add esp, 20h
.text:006F36D1 retn
.text:006F36D2
.text:006F36D2 loc_6F36D2:
.text:006F36D2 jmp AfxThrowInvalidArgException(void)
.text:006F36D2 fun2_6F35B0 endp
=======================================================================================
void fun2(strarray * p,int a1,int a2,int a3)
{
int i,j,k;
strarray q;
if(a3 == -1)a3 = (p -> len) - 1;
i = a3 - a2 + 1;
q.sp = 0;
q.len = i;
q.sp = new char[i];
memset(q.sp,0,i);
if(a2 <= a3)
{
i = a2;
do{
q.sp[i] = (p -> sp)[i];
i ++;
}while(i <= a3);
}
i = a1 % q.len - a2;
if(q.len > 0)
{
j = 0;
do{
k = (i + a2) % q.len;
(p -> sp)[a2] = q.sp[k];
a2 ++;
j ++;
}while(j < q.len);
}
if(q.sp != 0)delete []q.sp;
}
=======================================================================================
.text:006F36E0 fun3_6F36E0 proc near
.text:006F36E0
.text:006F36E0 var_14 = dword ptr -14h
.text:006F36E0 var_10_cnt = dword ptr -10h
.text:006F36E0 var_4 = dword ptr -4
.text:006F36E0 arg_0 = dword ptr 4
.text:006F36E0 arg_4 = dword ptr 8
.text:006F36E0
.text:006F36E0 push 0FFFFFFFFh
.text:006F36E2 push offset loc_7F7049
.text:006F36E7 mov eax, large fs:0
.text:006F36ED push eax
.text:006F36EE mov large fs:0, esp
.text:006F36F5 sub esp, 8
.text:006F36F8 push ebx
.text:006F36F9 push ebp
.text:006F36FA push esi
.text:006F36FB xor esi, esi
.text:006F36FD push edi
.text:006F36FE lea ecx, [esp+24h+var_14] ; 构造一个字符串
.text:006F3702 mov [esp+24h+var_10_cnt], esi
.text:006F3706 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
.text:006F370C mov ebx, [esp+24h+arg_4] ; 传进来的结构地址
.text:006F3710 mov ecx, [ebx+8] ; 取长度
.text:006F3713 mov eax, 66666667h
.text:006F3718 imul ecx
.text:006F371A sar edx, 1
.text:006F371C mov ebp, edx
.text:006F371E shr ebp, 31
.text:006F3721 add ebp, edx ; /5,得到解码后的字符串长度
.text:006F3723 cmp ebp, esi
.text:006F3725 mov [esp+24h+var_4], esi
.text:006F3729 mov [esp+24h+var_10_cnt], esi
.text:006F372D jle short loc_6F3788
.text:006F372F nop
.text:006F3730
.text:006F3730 loc_6F3730:
.text:006F3730 lea edx, [esi+4] ; 加上4
.text:006F3733 xor edi, edi
.text:006F3735 xor ecx, ecx
.text:006F3737 cmp esi, edx
.text:006F3739 mov eax, esi
.text:006F373B jg short loc_6F3765
.text:006F373D lea ecx, [ecx+0]
.text:006F3740
.text:006F3740 loc_6F3740:
.text:006F3740 test eax, eax
.text:006F3742 jl short loc_6F37B8
.text:006F3744 cmp eax, [ebx+8]
.text:006F3747 jge short loc_6F37B8
.text:006F3749 mov ebx, [ebx+4]
.text:006F374C cmp byte ptr [eax+ebx], 0
.text:006F3750 jz short loc_6F375B
.text:006F3752 mov ebx, 1
.text:006F3757 shl ebx, cl
.text:006F3759 or edi, ebx
.text:006F375B
.text:006F375B loc_6F375B:
.text:006F375B mov ebx, [esp+24h+arg_4]
.text:006F375F inc ecx
.text:006F3760 inc eax
.text:006F3761 cmp eax, edx
.text:006F3763 jle short loc_6F3740
.text:006F3765
.text:006F3765 loc_6F3765:
.text:006F3765 xor eax, eax
.text:006F3767 mov al, ds:Table1_865058[edi] ; 查表,连接到字符串
.text:006F376D lea ecx, [esp+24h+var_14]
.text:006F3771 push eax
.text:006F3772 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::operator+=(char)
.text:006F3778 mov eax, [esp+24h+var_10_cnt]
.text:006F377C inc eax
.text:006F377D add esi, 5
.text:006F3780 cmp eax, ebp
.text:006F3782 mov [esp+24h+var_10_cnt], eax
.text:006F3786 jl short loc_6F3730
.text:006F3788
.text:006F3788 loc_6F3788:
.text:006F3788 mov esi, [esp+24h+arg_0] ; 返回这个字符串
.text:006F378C lea ecx, [esp+24h+var_14]
.text:006F3790 push ecx
.text:006F3791 mov ecx, esi
.text:006F3793 call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>> const &)
.text:006F3799 lea ecx, [esp+24h+var_14]
.text:006F379D call ds:ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>::~CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char>>>(void)
.text:006F37A3 mov ecx, [esp+18h]
.text:006F37A7 pop edi
.text:006F37A8 mov eax, esi
.text:006F37AA pop esi
.text:006F37AB pop ebp
.text:006F37AC pop ebx
.text:006F37AD mov large fs:0, ecx
.text:006F37B4 add esp, 14h
.text:006F37B7 retn
.text:006F37B8
.text:006F37B8 loc_6F37B8:
.text:006F37B8 jmp AfxThrowInvalidArgException(void)
.text:006F37B8 fun3_6F36E0 endp
=======================================================================================
CString fun3(strarray *p)
{
int cnt,i,j,k,m,n;
unsigned int x;
CString s;
cnt = p -> len / 5;
if(cnt <= 0)return s;
j = 0;
i = 0;
do{
k = j + 4;
x = 0;
m = 0;
if(j <= k)
{
do{
n = j;
if((p -> sp)[n] != 0)
{
x = x | (1 << m);
}
m ++;
n ++;
}while(n <= k);
}
s = s + Table[x];
j = j + 5;
i ++;
}while(i < cnt);
return s;
}
=======================================================================================
算法部分先对注册码左边21个字符使用了两次使用了查表变换(BASE32?),得到一个18个字符
的字符串。然后对这18个字符取md5,得到md5字符串左边4个字符,替换掉其中的'0'和'1'后
转换成大写,和注册码后4个字符比较。然后用18个字符的字符串变换出下面的key结构:
0-4 : 未知
5-8 : >= 8
9-12 : 0
13-16: 0
17-20: 协议类型:1:Single 2 Multi 3 Academic
21-26: 0
27-31: 1
32-45: 未知,形成一整数
46-59: 随意
这不是一个完整的分析,我没有时间继续去追踪了。老板要发彪了:(
感兴趣的朋友可以继续分析启动时的验证。
=======================================================================================
【全文完】