-
-
[旧帖] [申请邀请码]分析注册码,高手也来看看我能否得到邀请码 0.00雪花
-
发表于: 2011-4-6 22:19 948
-
0040来看雪学习已经一个多月了每天都来论坛,开始几天我的kx加了几点后来不知道怎么了一点都不加了前天我看到其他朋友发帖原创申请邀请码今天我决定要用一天时间研究个作品。
我用vc写了个简单的注册程序简单的算法说程序里的算法我比较惭愧因为时间段我也没用心设计里面的算法。
今天大家一定要看看我分析的程序明天我把代码发上来
哈哈~!其实我只是个菜鸟。
我测试用的用户名123123假吗123123
00402579 |. 8945 D4 mov dword ptr ss:[ebp-2C], eax
0040257C |. 8BF4 mov esi, esp
0040257E |. 6A 10 push 10 ; /Count = 10 (16.)
00402580 |. 8D45 EC lea eax, dword ptr ss:[ebp-14] ; |
00402583 |. 50 push eax ; |Buffer
00402584 |. 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
00402589 |. 8B4D D4 mov ecx, dword ptr ss:[ebp-2C] ; |
0040258C |. 51 push ecx ; |hWnd
0040258D |. FF15 0C774100 call near dword ptr ds:[<&USER32.GetD>; \GetDlgItemTextA
00402593 |. 3BF4 cmp esi, esp
00402595 |. E8 40FBFFFF call register._chkesp ; jmp 到 MSVCRTD._chkesp
0040259A |. 8BF4 mov esi, esp
0040259C |. 6A 10 push 10 ; /Count = 10 (16.)
0040259E |. 8D55 DC lea edx, dword ptr ss:[ebp-24] ; |
004025A1 |. 52 push edx ; |Buffer
004025A2 |. 68 E9030000 push 3E9 ; |ControlID = 3E9 (1001.)
004025A7 |. 8B45 D4 mov eax, dword ptr ss:[ebp-2C] ; |
004025AA |. 50 push eax ; |hWnd
004025AB |. FF15 0C774100 call near dword ptr ds:[<&USER32.GetD>; \GetDlgItemTextA
004025B1 |. 3BF4 cmp esi, esp
004025B3 |. E8 22FBFFFF call register._chkesp ; jmp 到 MSVCRTD._chkesp
004025B8 |. 8D4D EC lea ecx, dword ptr ss:[ebp-14] ; ecx=用户名后入栈
004025BB |. 51 push ecx ; /s
004025BC |. E8 7FFBFFFF call register.strlen ; \调用strlen得到用户名长度
004025C1 |. 83C4 04 add esp, 4
004025C4 |. 8945 D0 mov dword ptr ss:[ebp-30], eax ; eax=用户名长度
004025C7 |. 8D55 DC lea edx, dword ptr ss:[ebp-24] ; 注册码=edx
004025CA |. 52 push edx ; /s
004025CB |. E8 70FBFFFF call register.strlen ; \调用strlen得到注册码长度
004025D0 |. 83C4 04 add esp, 4
004025D3 |. 8945 CC mov dword ptr ss:[ebp-34], eax ; eax=注册码长度
004025D6 |. 837D D0 10 cmp dword ptr ss:[ebp-30], 10 ; 判断用户名是否超过16位
004025DA |. 7E 24 jle short register.00402600 ; 超过16位不跳转执行到错误
004025DC |. 8BF4 mov esi, esp
004025DE |. 6A 00 push 0 ; /Style = MB_
004025E0 |. 68 1C514100 push register.0041511C ; |Title = "
004025E5 |. 68 DC524100 push register.004152DC ; |Text = "用",
004025EA |. 8B45 D4 mov eax, dword ptr ss:[ebp-2C] ; |
004025ED |. 50 push eax ; |hOwner
004025EE |. FF15 10774100 call near dword ptr ds:[<&USER32.Mess>; \MessageBoxA
上面这部分指令不重要就不多说了
00402610 |> /8B4D C4 /mov ecx, dword ptr ss:[ebp-3C]
00402613 |. |83C1 01 |add ecx, 1
00402616 |. |894D C4 |mov dword ptr ss:[ebp-3C], ecx
00402619 |> |8B55 C4 mov edx, dword ptr ss:[ebp-3C] ; edx=当前循环次数
0040261C |. |3B55 D0 |cmp edx, dword ptr ss:[ebp-30] ; 循环次数是用户名的长度
0040261F |. |7D 28 |jge short register.00402649
00402621 |. |6A 00 |push 0 ; 这里是参数2=0
00402623 |. |8B45 C4 |mov eax, dword ptr ss:[ebp-3C]
00402626 |. |8A4C05 EC |mov cl, byte ptr ss:[ebp+eax-14] ; 取用户名一个字符我输入的用户名是123456也就是取1
0040262A |. |51 |push ecx ; 这里是参数1=用户名的一个字符
0040262B |. |E8 61EAFFFF |call register.00401091 ; 执行函数对用户名运算返回值在eax中
00402630 |. |83C4 08 |add esp, 8
00402633 |. |8945 C8 |mov dword ptr ss:[ebp-38], eax ; 运算结果入栈
00402636 |. |8B55 C4 |mov edx, dword ptr ss:[ebp-3C]
00402639 |. |8B45 C8 |mov eax, dword ptr ss:[ebp-38]
0040263C |. |894495 84 |mov dword ptr ss:[ebp+edx*4-7C], ea>; 将运算结果=给一个数组
00402640 |. |C745 C8 00000>|mov dword ptr ss:[ebp-38], 0
00402647 |.^\EB C7 \jmp short register.00402610
上面这部分是个循环语句循环执行这个函数有两个参数,参数1是用户名的一个字节参数2=0下面我们跟进去看看这个函数做了什么
00401D10 >/> \55 push ebp
00401D11 |. 8BEC mov ebp, esp
00401D13 |. 83EC 48 sub esp, 48
00401D16 |. 53 push ebx
00401D17 |. 56 push esi
00401D18 |. 57 push edi
00401D19 |. 8D7D B8 lea edi, dword ptr ss:[ebp-48]
00401D1C |. B9 12000000 mov ecx, 12
00401D21 |. B8 CCCCCCCC mov eax, CCCCCCCC
00401D26 |. F3:AB rep stos dword ptr es:[edi]
00401D28 |. 837D 0C 00 cmp dword ptr ss:[ebp+C], 0 ; 判断参数2是否为0,=0就跳转运算用户名
00401D2C |. 74 4E je short register.00401D7C ; 不等于0就继续向下执行运算注册码
00401D2E |. C745 FC 00000>mov dword ptr ss:[ebp-4], 0
00401D35 |. 0FBE45 08 movsx eax, byte ptr ss:[ebp+8]
00401D39 |. 8945 FC mov dword ptr ss:[ebp-4], eax ; 取注册吗一个字符
00401D3C |. 837D FC 3F cmp dword ptr ss:[ebp-4], 3F
00401D40 |. 7F 11 jg short register.00401D53
00401D42 |. 8B4D FC mov ecx, dword ptr ss:[ebp-4]
00401D45 |. 81C1 2C010000 add ecx, 12C ; 注册码+12c
00401D4B |. 894D FC mov dword ptr ss:[ebp-4], ecx
00401D4E |. 8B45 FC mov eax, dword ptr ss:[ebp-4]
00401D51 |. EB 77 jmp short register.00401DCA
00401D53 |> 837D FC 40 cmp dword ptr ss:[ebp-4], 40
00401D57 |. 7C 11 jl short register.00401D6A
00401D59 |. 8B55 FC mov edx, dword ptr ss:[ebp-4]
00401D5C |. 81C2 2C010000 add edx, 12C ; 注册码+12c
00401D62 |. 8955 FC mov dword ptr ss:[ebp-4], edx
00401D65 |. 8B45 FC mov eax, dword ptr ss:[ebp-4]
00401D68 |. EB 60 jmp short register.00401DCA
00401D6A |> 837D FC 40 cmp dword ptr ss:[ebp-4], 40
00401D6E |. 7C 0A jl short register.00401D7A
00401D70 |. 837D FC 3F cmp dword ptr ss:[ebp-4], 3F
00401D74 |. 7F 04 jg short register.00401D7A
00401D76 |. 33C0 xor eax, eax
00401D78 |. EB 50 jmp short register.00401DCA
00401D7A |> EB 4C jmp short register.00401DC8
00401D7C |> C745 F8 00000>mov dword ptr ss:[ebp-8], 0
00401D83 |. 0FBE45 08 movsx eax, byte ptr ss:[ebp+8]
00401D87 |. 8945 F8 mov dword ptr ss:[ebp-8], eax ; eax=用户名的一个字符
00401D8A |. 837D F8 3F cmp dword ptr ss:[ebp-8], 3F ; 判断用户名的一个字符是否大于3f
00401D8E |. 7F 11 jg short register.00401DA1 ; 大于3f跳转
00401D90 |. 8B4D F8 mov ecx, dword ptr ss:[ebp-8]
00401D93 |. 81C1 45010000 add ecx, 145 ; 用户名的一个字符加上145
00401D99 |. 894D F8 mov dword ptr ss:[ebp-8], ecx
00401D9C |. 8B45 F8 mov eax, dword ptr ss:[ebp-8]
00401D9F |. EB 29 jmp short register.00401DCA
00401DA1 |> 837D F8 40 cmp dword ptr ss:[ebp-8], 40 ; 用户名的一个字符小于40跳转
00401DA5 |. 7C 11 jl short register.00401DB8
00401DA7 |. 8B55 F8 mov edx, dword ptr ss:[ebp-8]
00401DAA |. 81C2 45010000 add edx, 113
00401DB0 |. 8955 F8 mov dword ptr ss:[ebp-8], edx
00401DB3 |. 8B45 F8 mov eax, dword ptr ss:[ebp-8]
00401DB6 |. EB 12 jmp short register.00401DCA
00401DB8 |> 837D F8 40 cmp dword ptr ss:[ebp-8], 40
00401DBC |. 7C 0A jl short register.00401DC8
00401DBE |. 837D F8 3F cmp dword ptr ss:[ebp-8], 3F
00401DC2 |. 7F 04 jg short register.00401DC8
00401DC4 |. 33C0 xor eax, eax
00401DC6 |. EB 02 jmp short register.00401DCA
00401DC8 |> 33C0 xor eax, eax
00401DCA |> 5F pop edi
00401DCB |. 5E pop esi
00401DCC |. 5B pop ebx
00401DCD |. 8BE5 mov esp, ebp
00401DCF |. 5D pop ebp
00401DD0 \. C3 retn
上面这部分很简单只是对用户名的ascii 加上145如果是注册码就加上12c
下面看看环绕执行函数对注册码运算
0040267C |> /8B95 40FFFFFF /mov edx, dword ptr ss:[ebp-C0]
00402682 |. |83C2 01 |add edx, 1
00402685 |. |8995 40FFFFFF |mov dword ptr ss:[ebp-C0], edx
0040268B |> |8B85 40FFFFFF mov eax, dword ptr ss:[ebp-C0]
00402691 |. |3B45 D0 |cmp eax, dword ptr ss:[ebp-30]
00402694 |. |7D 31 |jge short register.004026C7
00402696 |. |6A 01 |push 1 ; 不同之处参数2=1
00402698 |. |8B8D 40FFFFFF |mov ecx, dword ptr ss:[ebp-C0]
0040269E |. |8A540D DC |mov dl, byte ptr ss:[ebp+ecx-24]
004026A2 |. |52 |push edx ; 不同之处参数1=注册码的一个字符
004026A3 |. |E8 E9E9FFFF |call register.00401091
004026A8 |. |83C4 08 |add esp, 8
004026AB |. |8945 C8 |mov dword ptr ss:[ebp-38], eax
004026AE |. |8B85 40FFFFFF |mov eax, dword ptr ss:[ebp-C0]
004026B4 |. |8B4D C8 |mov ecx, dword ptr ss:[ebp-38]
004026B7 |. |898C85 44FFFF>|mov dword ptr ss:[ebp+eax*4-BC], ecx
004026BE |. |C745 C8 00000>|mov dword ptr ss:[ebp-38], 0
004026C5 |.^\EB B5 \jmp short register.0040267C
这部分跟环绕执行函数运算用户名是一样得唯一不同的是函数的参数不同
再简单的介绍下原理
其实整个程序在od里面就没出现过真的的注册码我在论坛里总看到别人发帖说非明码比价不知道这算不算
分析程序整体
测试用户名输入dongkui123
在上面我们可以看到在运算用户名过程中先判断字符的ascii是否大于3F如果大于3f则用户名的ascii加上113如果小于3f则加上145
再看看注册码的运算过程是吧注册码的ascii加上了12c
这样以来我们看看其中有什么奥秘
首先我们先看看用户名的第一个字符d的ascii=64大于3f则64+113=177-12c=4B,4B的ASCII=大写的k
把用户名dongkui123按照这样全部算一遍对应的注册码就是KVUNR\PJKL
004026D1 |. /EB 0F jmp short register.004026E2
004026D3 |> |8B95 3CFFFFFF /mov edx, dword ptr ss:[ebp-C4]
004026D9 |. |83C2 01 |add edx, 1
004026DC |. |8995 3CFFFFFF |mov dword ptr ss:[ebp-C4], edx
004026E2 |> \8B85 3CFFFFFF mov eax, dword ptr ss:[ebp-C4] ; 用户名的长度决定循环次数
004026E8 |. 3B45 D0 |cmp eax, dword ptr ss:[ebp-30] ; 判断当前循环多少次了
004026EB |. 7D 33 |jge short register.00402720
004026ED |. 837D D8 00 |cmp dword ptr ss:[ebp-28], 0
004026F1 |. 75 02 |jnz short register.004026F5
004026F3 |. EB 2B |jmp short register.00402720
004026F5 |> 8B8D 3CFFFFFF |mov ecx, dword ptr ss:[ebp-C4]
004026FB |. 8B95 3CFFFFFF |mov edx, dword ptr ss:[ebp-C4]
00402701 |. 8B448D 84 |mov eax, dword ptr ss:[ebp+ecx*4-7C]
00402705 |. 3B8495 44FFFF>|cmp eax, dword ptr ss:[ebp+edx*4-BC] ; 判断两个数组内的值
0040270C |. 75 09 |jnz short register.00402717 ; 如果不相等则跳转
0040270E |. C745 D8 01000>|mov dword ptr ss:[ebp-28], 1
00402715 |. EB 07 |jmp short register.0040271E
00402717 |> C745 D8 00000>|mov dword ptr ss:[ebp-28], 0 ; 这里是一个全局bool类型的变量
0040271E |>^ EB B3 \jmp short register.004026D3
00402720 |> 837D D8 00 cmp dword ptr ss:[ebp-28], 0 ; 这里判断全局bool类型变量是否为真
00402724 |. 74 21 je short register.00402747 ; 如果为真则不跳转执行到注册成功
上面部分直接判断真码和假吗
下面分别是真码和假吗的两个堆栈的值
0012F624 00000177
0012F628 00000178
0012F62C 00000179
0012F630 00000177
0012F634 00000178
0012F638 00000179
0012F5E4 0000015E
0012F5E8 0000015F
0012F5EC 00000160
0012F5F0 0000015E
0012F5F4 0000015F
0012F5F8 00000160
当然我只分析的时候输入的注册码是不正确的这两个堆栈的值也是不同的
我用vc写了个简单的注册程序简单的算法说程序里的算法我比较惭愧因为时间段我也没用心设计里面的算法。
今天大家一定要看看我分析的程序明天我把代码发上来
哈哈~!其实我只是个菜鸟。
我测试用的用户名123123假吗123123
00402579 |. 8945 D4 mov dword ptr ss:[ebp-2C], eax
0040257C |. 8BF4 mov esi, esp
0040257E |. 6A 10 push 10 ; /Count = 10 (16.)
00402580 |. 8D45 EC lea eax, dword ptr ss:[ebp-14] ; |
00402583 |. 50 push eax ; |Buffer
00402584 |. 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
00402589 |. 8B4D D4 mov ecx, dword ptr ss:[ebp-2C] ; |
0040258C |. 51 push ecx ; |hWnd
0040258D |. FF15 0C774100 call near dword ptr ds:[<&USER32.GetD>; \GetDlgItemTextA
00402593 |. 3BF4 cmp esi, esp
00402595 |. E8 40FBFFFF call register._chkesp ; jmp 到 MSVCRTD._chkesp
0040259A |. 8BF4 mov esi, esp
0040259C |. 6A 10 push 10 ; /Count = 10 (16.)
0040259E |. 8D55 DC lea edx, dword ptr ss:[ebp-24] ; |
004025A1 |. 52 push edx ; |Buffer
004025A2 |. 68 E9030000 push 3E9 ; |ControlID = 3E9 (1001.)
004025A7 |. 8B45 D4 mov eax, dword ptr ss:[ebp-2C] ; |
004025AA |. 50 push eax ; |hWnd
004025AB |. FF15 0C774100 call near dword ptr ds:[<&USER32.GetD>; \GetDlgItemTextA
004025B1 |. 3BF4 cmp esi, esp
004025B3 |. E8 22FBFFFF call register._chkesp ; jmp 到 MSVCRTD._chkesp
004025B8 |. 8D4D EC lea ecx, dword ptr ss:[ebp-14] ; ecx=用户名后入栈
004025BB |. 51 push ecx ; /s
004025BC |. E8 7FFBFFFF call register.strlen ; \调用strlen得到用户名长度
004025C1 |. 83C4 04 add esp, 4
004025C4 |. 8945 D0 mov dword ptr ss:[ebp-30], eax ; eax=用户名长度
004025C7 |. 8D55 DC lea edx, dword ptr ss:[ebp-24] ; 注册码=edx
004025CA |. 52 push edx ; /s
004025CB |. E8 70FBFFFF call register.strlen ; \调用strlen得到注册码长度
004025D0 |. 83C4 04 add esp, 4
004025D3 |. 8945 CC mov dword ptr ss:[ebp-34], eax ; eax=注册码长度
004025D6 |. 837D D0 10 cmp dword ptr ss:[ebp-30], 10 ; 判断用户名是否超过16位
004025DA |. 7E 24 jle short register.00402600 ; 超过16位不跳转执行到错误
004025DC |. 8BF4 mov esi, esp
004025DE |. 6A 00 push 0 ; /Style = MB_
004025E0 |. 68 1C514100 push register.0041511C ; |Title = "
004025E5 |. 68 DC524100 push register.004152DC ; |Text = "用",
004025EA |. 8B45 D4 mov eax, dword ptr ss:[ebp-2C] ; |
004025ED |. 50 push eax ; |hOwner
004025EE |. FF15 10774100 call near dword ptr ds:[<&USER32.Mess>; \MessageBoxA
上面这部分指令不重要就不多说了
00402610 |> /8B4D C4 /mov ecx, dword ptr ss:[ebp-3C]
00402613 |. |83C1 01 |add ecx, 1
00402616 |. |894D C4 |mov dword ptr ss:[ebp-3C], ecx
00402619 |> |8B55 C4 mov edx, dword ptr ss:[ebp-3C] ; edx=当前循环次数
0040261C |. |3B55 D0 |cmp edx, dword ptr ss:[ebp-30] ; 循环次数是用户名的长度
0040261F |. |7D 28 |jge short register.00402649
00402621 |. |6A 00 |push 0 ; 这里是参数2=0
00402623 |. |8B45 C4 |mov eax, dword ptr ss:[ebp-3C]
00402626 |. |8A4C05 EC |mov cl, byte ptr ss:[ebp+eax-14] ; 取用户名一个字符我输入的用户名是123456也就是取1
0040262A |. |51 |push ecx ; 这里是参数1=用户名的一个字符
0040262B |. |E8 61EAFFFF |call register.00401091 ; 执行函数对用户名运算返回值在eax中
00402630 |. |83C4 08 |add esp, 8
00402633 |. |8945 C8 |mov dword ptr ss:[ebp-38], eax ; 运算结果入栈
00402636 |. |8B55 C4 |mov edx, dword ptr ss:[ebp-3C]
00402639 |. |8B45 C8 |mov eax, dword ptr ss:[ebp-38]
0040263C |. |894495 84 |mov dword ptr ss:[ebp+edx*4-7C], ea>; 将运算结果=给一个数组
00402640 |. |C745 C8 00000>|mov dword ptr ss:[ebp-38], 0
00402647 |.^\EB C7 \jmp short register.00402610
上面这部分是个循环语句循环执行这个函数有两个参数,参数1是用户名的一个字节参数2=0下面我们跟进去看看这个函数做了什么
00401D10 >/> \55 push ebp
00401D11 |. 8BEC mov ebp, esp
00401D13 |. 83EC 48 sub esp, 48
00401D16 |. 53 push ebx
00401D17 |. 56 push esi
00401D18 |. 57 push edi
00401D19 |. 8D7D B8 lea edi, dword ptr ss:[ebp-48]
00401D1C |. B9 12000000 mov ecx, 12
00401D21 |. B8 CCCCCCCC mov eax, CCCCCCCC
00401D26 |. F3:AB rep stos dword ptr es:[edi]
00401D28 |. 837D 0C 00 cmp dword ptr ss:[ebp+C], 0 ; 判断参数2是否为0,=0就跳转运算用户名
00401D2C |. 74 4E je short register.00401D7C ; 不等于0就继续向下执行运算注册码
00401D2E |. C745 FC 00000>mov dword ptr ss:[ebp-4], 0
00401D35 |. 0FBE45 08 movsx eax, byte ptr ss:[ebp+8]
00401D39 |. 8945 FC mov dword ptr ss:[ebp-4], eax ; 取注册吗一个字符
00401D3C |. 837D FC 3F cmp dword ptr ss:[ebp-4], 3F
00401D40 |. 7F 11 jg short register.00401D53
00401D42 |. 8B4D FC mov ecx, dword ptr ss:[ebp-4]
00401D45 |. 81C1 2C010000 add ecx, 12C ; 注册码+12c
00401D4B |. 894D FC mov dword ptr ss:[ebp-4], ecx
00401D4E |. 8B45 FC mov eax, dword ptr ss:[ebp-4]
00401D51 |. EB 77 jmp short register.00401DCA
00401D53 |> 837D FC 40 cmp dword ptr ss:[ebp-4], 40
00401D57 |. 7C 11 jl short register.00401D6A
00401D59 |. 8B55 FC mov edx, dword ptr ss:[ebp-4]
00401D5C |. 81C2 2C010000 add edx, 12C ; 注册码+12c
00401D62 |. 8955 FC mov dword ptr ss:[ebp-4], edx
00401D65 |. 8B45 FC mov eax, dword ptr ss:[ebp-4]
00401D68 |. EB 60 jmp short register.00401DCA
00401D6A |> 837D FC 40 cmp dword ptr ss:[ebp-4], 40
00401D6E |. 7C 0A jl short register.00401D7A
00401D70 |. 837D FC 3F cmp dword ptr ss:[ebp-4], 3F
00401D74 |. 7F 04 jg short register.00401D7A
00401D76 |. 33C0 xor eax, eax
00401D78 |. EB 50 jmp short register.00401DCA
00401D7A |> EB 4C jmp short register.00401DC8
00401D7C |> C745 F8 00000>mov dword ptr ss:[ebp-8], 0
00401D83 |. 0FBE45 08 movsx eax, byte ptr ss:[ebp+8]
00401D87 |. 8945 F8 mov dword ptr ss:[ebp-8], eax ; eax=用户名的一个字符
00401D8A |. 837D F8 3F cmp dword ptr ss:[ebp-8], 3F ; 判断用户名的一个字符是否大于3f
00401D8E |. 7F 11 jg short register.00401DA1 ; 大于3f跳转
00401D90 |. 8B4D F8 mov ecx, dword ptr ss:[ebp-8]
00401D93 |. 81C1 45010000 add ecx, 145 ; 用户名的一个字符加上145
00401D99 |. 894D F8 mov dword ptr ss:[ebp-8], ecx
00401D9C |. 8B45 F8 mov eax, dword ptr ss:[ebp-8]
00401D9F |. EB 29 jmp short register.00401DCA
00401DA1 |> 837D F8 40 cmp dword ptr ss:[ebp-8], 40 ; 用户名的一个字符小于40跳转
00401DA5 |. 7C 11 jl short register.00401DB8
00401DA7 |. 8B55 F8 mov edx, dword ptr ss:[ebp-8]
00401DAA |. 81C2 45010000 add edx, 113
00401DB0 |. 8955 F8 mov dword ptr ss:[ebp-8], edx
00401DB3 |. 8B45 F8 mov eax, dword ptr ss:[ebp-8]
00401DB6 |. EB 12 jmp short register.00401DCA
00401DB8 |> 837D F8 40 cmp dword ptr ss:[ebp-8], 40
00401DBC |. 7C 0A jl short register.00401DC8
00401DBE |. 837D F8 3F cmp dword ptr ss:[ebp-8], 3F
00401DC2 |. 7F 04 jg short register.00401DC8
00401DC4 |. 33C0 xor eax, eax
00401DC6 |. EB 02 jmp short register.00401DCA
00401DC8 |> 33C0 xor eax, eax
00401DCA |> 5F pop edi
00401DCB |. 5E pop esi
00401DCC |. 5B pop ebx
00401DCD |. 8BE5 mov esp, ebp
00401DCF |. 5D pop ebp
00401DD0 \. C3 retn
上面这部分很简单只是对用户名的ascii 加上145如果是注册码就加上12c
下面看看环绕执行函数对注册码运算
0040267C |> /8B95 40FFFFFF /mov edx, dword ptr ss:[ebp-C0]
00402682 |. |83C2 01 |add edx, 1
00402685 |. |8995 40FFFFFF |mov dword ptr ss:[ebp-C0], edx
0040268B |> |8B85 40FFFFFF mov eax, dword ptr ss:[ebp-C0]
00402691 |. |3B45 D0 |cmp eax, dword ptr ss:[ebp-30]
00402694 |. |7D 31 |jge short register.004026C7
00402696 |. |6A 01 |push 1 ; 不同之处参数2=1
00402698 |. |8B8D 40FFFFFF |mov ecx, dword ptr ss:[ebp-C0]
0040269E |. |8A540D DC |mov dl, byte ptr ss:[ebp+ecx-24]
004026A2 |. |52 |push edx ; 不同之处参数1=注册码的一个字符
004026A3 |. |E8 E9E9FFFF |call register.00401091
004026A8 |. |83C4 08 |add esp, 8
004026AB |. |8945 C8 |mov dword ptr ss:[ebp-38], eax
004026AE |. |8B85 40FFFFFF |mov eax, dword ptr ss:[ebp-C0]
004026B4 |. |8B4D C8 |mov ecx, dword ptr ss:[ebp-38]
004026B7 |. |898C85 44FFFF>|mov dword ptr ss:[ebp+eax*4-BC], ecx
004026BE |. |C745 C8 00000>|mov dword ptr ss:[ebp-38], 0
004026C5 |.^\EB B5 \jmp short register.0040267C
这部分跟环绕执行函数运算用户名是一样得唯一不同的是函数的参数不同
再简单的介绍下原理
其实整个程序在od里面就没出现过真的的注册码我在论坛里总看到别人发帖说非明码比价不知道这算不算
分析程序整体
测试用户名输入dongkui123
在上面我们可以看到在运算用户名过程中先判断字符的ascii是否大于3F如果大于3f则用户名的ascii加上113如果小于3f则加上145
再看看注册码的运算过程是吧注册码的ascii加上了12c
这样以来我们看看其中有什么奥秘
首先我们先看看用户名的第一个字符d的ascii=64大于3f则64+113=177-12c=4B,4B的ASCII=大写的k
把用户名dongkui123按照这样全部算一遍对应的注册码就是KVUNR\PJKL
004026D1 |. /EB 0F jmp short register.004026E2
004026D3 |> |8B95 3CFFFFFF /mov edx, dword ptr ss:[ebp-C4]
004026D9 |. |83C2 01 |add edx, 1
004026DC |. |8995 3CFFFFFF |mov dword ptr ss:[ebp-C4], edx
004026E2 |> \8B85 3CFFFFFF mov eax, dword ptr ss:[ebp-C4] ; 用户名的长度决定循环次数
004026E8 |. 3B45 D0 |cmp eax, dword ptr ss:[ebp-30] ; 判断当前循环多少次了
004026EB |. 7D 33 |jge short register.00402720
004026ED |. 837D D8 00 |cmp dword ptr ss:[ebp-28], 0
004026F1 |. 75 02 |jnz short register.004026F5
004026F3 |. EB 2B |jmp short register.00402720
004026F5 |> 8B8D 3CFFFFFF |mov ecx, dword ptr ss:[ebp-C4]
004026FB |. 8B95 3CFFFFFF |mov edx, dword ptr ss:[ebp-C4]
00402701 |. 8B448D 84 |mov eax, dword ptr ss:[ebp+ecx*4-7C]
00402705 |. 3B8495 44FFFF>|cmp eax, dword ptr ss:[ebp+edx*4-BC] ; 判断两个数组内的值
0040270C |. 75 09 |jnz short register.00402717 ; 如果不相等则跳转
0040270E |. C745 D8 01000>|mov dword ptr ss:[ebp-28], 1
00402715 |. EB 07 |jmp short register.0040271E
00402717 |> C745 D8 00000>|mov dword ptr ss:[ebp-28], 0 ; 这里是一个全局bool类型的变量
0040271E |>^ EB B3 \jmp short register.004026D3
00402720 |> 837D D8 00 cmp dword ptr ss:[ebp-28], 0 ; 这里判断全局bool类型变量是否为真
00402724 |. 74 21 je short register.00402747 ; 如果为真则不跳转执行到注册成功
上面部分直接判断真码和假吗
下面分别是真码和假吗的两个堆栈的值
0012F624 00000177
0012F628 00000178
0012F62C 00000179
0012F630 00000177
0012F634 00000178
0012F638 00000179
0012F5E4 0000015E
0012F5E8 0000015F
0012F5EC 00000160
0012F5F0 0000015E
0012F5F4 0000015F
0012F5F8 00000160
当然我只分析的时候输入的注册码是不正确的这两个堆栈的值也是不同的
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
- [求助]ReadProcessMemory的问题 4739
- [求助]汇编指令 842
- [申请邀请码]分析注册码,高手也来看看我能否得到邀请码 949
- [推荐]添加图片方法 723
- [求助][求助]脱壳upx 976
看原图
赞赏
雪币:
留言: