我贴出代码段。。不再写注册机了,算法很简单,你看看应该就会了 (7千字)
代码分析:这是一个Fn(Name)+Fc(Company) = Fs(Code)的模式,也就是说将输入的Name、Company和Code分别进行运算,如果
Name和Company的运算后的值相加等于Code运算后的值,那么就可以了。
全文分四部分,就是讲Fn(Name)、Fc(Company)、Fs(Code)以及输入是否正确的判断地点。
第一部分:—— Fs(Code) 代码端如下:
:0040BA60 83EC08 sub esp, 00000008
:0040BA63 89542404 mov dword ptr [esp+04], edx
:0040BA67 53 push ebx
:0040BA68 C744240400000000 mov [esp+04], 00000000
:0040BA70 56 push esi
:0040BA71 57 push edi
:0040BA72 55 push ebp
:0040BA73 BE01000000 mov esi, 00000001 //将esi置1,算Fs(Code)时要用到
:0040BA78 51 push ecx
:0040BA79 8BE9 mov ebp, ecx // ebp = 输入Code的位置Offset
:0040BA7B FF15F4134100 call dword ptr [004113F4]
:0040BA81 8D78FF lea edi, dword ptr [eax-01] // edi=Code长度
:0040BA84 85FF test edi, edi
:0040BA86 7C3B jl 0040BAC3
:0040BA88 8A5C3D00 mov bl, byte ptr [ebp+edi] // 将Code中的字符赋给bl
:0040BA8C 80FB30 cmp bl, 30 |
:0040BA8F 7209 jb 0040BA9A | 判断Code是不是数字,在这里说明一下,判断Code必须全部为数字
:0040BA91 80FB39 cmp bl, 39 | 的Call在前面,在此省略
:0040BA94 7704 ja 0040BA9A |
:0040BA96 85FF test edi, edi //看字符是否运算完?是从后到前运算的
:0040BA98 7D0E jge 0040BAA8
:0040BA9A B914D44000 mov ecx, 0040D414
:0040BA9F 8B542414 mov edx, dword ptr [esp+14]
:0040BAA3 E848FBFFFF call 0040B5F0
:0040BAA8 33C0 xor eax, eax
:0040BAAA 8D0CB6 lea ecx, dword ptr [esi+4*esi] // ecx = esi * 5
:0040BAAD 8AC3 mov al, bl
:0040BAAF 83E830 sub eax, 00000030 //取十进制数字值,
:0040BAB2 0FAFC6 imul eax, esi
:0040BAB5 8D344D00000000 lea esi, dword ptr [2*ecx+00000000] // esi = ecx * 2
:0040BABC 01442410 add dword ptr [esp+10], eax // [esp+10]放累加和
:0040BAC0 4F dec edi
:0040BAC1 79C5 jns 0040BA88
:0040BAC3 8B442410 mov eax, dword ptr [esp+10] // 此Call将运算完后的值返回到 eax
:0040BAC7 5D pop ebp
:0040BAC8 5F pop edi
:0040BAC9 5E pop esi
:0040BACA 5B pop ebx
:0040BACB 83C408 add esp, 00000008
:0040BACE C3 ret
第二部分:Fn(Name) 和 Fc(Company) 的代码段:
:00406790 53 push ebx
:00406791 56 push esi
:00406792 668BD9 mov bx, cx
:00406795 57 push edi
:00406796 55 push ebp
:00406797 8BF2 mov esi, edx // esi 放 Name 或 Company 的位置偏移
:00406799 85F6 test esi, esi
:0040679B 7475 je 00406812
:0040679D 803E00 cmp byte ptr [esi], 00 // 判断是否为空?
:004067A0 7470 je 00406812
:004067A2 8BFE mov edi, esi
:004067A4 B9FFFFFFFF mov ecx, FFFFFFFF
:004067A9 2BC0 sub eax, eax
:004067AB F2 repnz
:004067AC AE scasb
:004067AD F7D1 not ecx
:004067AF 49 dec ecx // ecx放字符串长度
:004067B0 6685DB test bx, bx
:004067B3 7444 je 004067F9
:004067B5 6683FB01 cmp bx, 0001
:004067B9 743E je 004067F9
:004067BB 0FB7FB movzx edi, bx
:004067BE 8BC7 mov eax, edi
:004067C0 99 cdq
:004067C1 F7F9 idiv ecx
:004067C3 0FBE0416 movsx eax, byte ptr [esi+edx]
:004067C7 0FAFC2 imul eax, edx
:004067CA 0FAFC7 imul eax, edi
:004067CD 03C1 add eax, ecx
:004067CF 33D2 xor edx, edx // 置0,即从第一个字符开始处理
:004067D1 85C9 test ecx, ecx
:004067D3 7E19 jle 004067EE
:004067D5 8BD9 mov ebx, ecx
:004067D7 2BDF sub ebx, edi
:004067D9 0FBE3C16 movsx edi, byte ptr [esi+edx] // edi放字符串的单个字符
:004067DD 8BEB mov ebp, ebx
:004067DF 2BEA sub ebp, edx
:004067E1 42 inc edx
:004067E2 83C56F add ebp, 0000006F
:004067E5 0FAFFD imul edi, ebp
:004067E8 03C7 add eax, edi
:004067EA 3BCA cmp ecx, edx
:004067EC 7FEB jg 004067D9 // 是否全部运算完?
:004067EE 85C0 test eax, eax
:004067F0 7D25 jge 00406817
:004067F2 F7D8 neg eax // 如果为负则取补
:004067F4 5D pop ebp
:004067F5 5F pop edi
:004067F6 5E pop esi
:004067F7 5B pop ebx
:004067F8 C3 ret
:00406817 5D pop ebp |
:00406818 5F pop edi |
:00406819 5E pop esi | 此段代码我怎么也看不明白 —— 画蛇添足? *_^
:0040681A 5B pop ebx |
:0040681B C3 ret |
第三部分:Fn(Name) + Fc(Company)的部分在:
:00406820 53 push ebx
:00406821 56 push esi
:00406822 57 push edi
:00406823 8BD9 mov ebx, ecx
:00406825 668BCA mov cx, dx
:00406828 668BFA mov di, dx
:0040682B 8B542410 mov edx, dword ptr [esp+10] // edx = Name的偏移
:0040682F 6681E1FF00 and cx, 00FF
:00406834 66C1EF08 shr di, 08
:00406838 E853FFFFFF call 00406790 // Fn()
:0040683D 668BCF mov cx, di
:00406840 8BF0 mov esi, eax // 运算和先放到 esi种暂存
:00406842 6685C9 test cx, cx
:00406845 7517 jne 0040685E
:00406847 8B542414 mov edx, dword ptr [esp+14]
:0040684B E840FFFFFF call 00406790
:00406850 8D0C33 lea ecx, dword ptr [ebx+esi]
:00406853 5F pop edi
:00406854 0FAFC8 imul ecx, eax
:00406857 8BC1 mov eax, ecx
:00406859 5E pop esi
:0040685A 5B pop ebx
:0040685B C20800 ret 0008
:0040685E 6641 inc cx
:00406860 8B542414 mov edx, dword ptr [esp+14] // edx = Company的偏移
:00406864 E827FFFFFF call 00406790
:00406869 03C6 add eax, esi // Fn(Name) + Fc(Company)
:0040686B 5F pop edi
:0040686C 03C3 add eax, ebx
:0040686E 5E pop esi
:0040686F 5B pop ebx
:00406870 C20800 ret 0008
第四部分:输入是否正确的判断地点
:00406CF8 8BE8 mov ebp, eax // ebp = Fn(Name) + Fc(Company)
:00406CFA 2BEE sub ebp, esi // esi = Fs(Code)
:00406CFC 85ED test ebp, ebp
:00406CFE 7429 je 00406D29 // 相等就行了
算法是不是很简单?看看就会了,如果还是有疑问的话,那么动态跟踪好了。。呵呵
