005DA39C . 55 push ebp
005DA39D . 8BEC mov ebp,esp
005DA39F . B9 05000000 mov ecx,0x5
005DA3A4 > 6A 00 push 0x0
005DA3A6 . 6A 00 push 0x0
005DA3A8 . 49 dec ecx
005DA3A9 .^ 75 F9 jnz short dump.005DA3A4
005DA3AB . 51 push ecx
005DA3AC . 53 push ebx
005DA3AD . 56 push esi
005DA3AE . 57 push edi
005DA3AF . 8945 FC mov dword ptr ss:[ebp-0x4],eax
005DA3B2 . 33C0 xor eax,eax
005DA3B4 . 55 push ebp
005DA3B5 . 68 FDA55D00 push dump.005DA5FD
005DA3BA . 64:FF30 push dword ptr fs:[eax]
005DA3BD . 64:8920 mov dword ptr fs:[eax],esp
005DA3C0 . A1 D0435E00 mov eax,dword ptr ds:[0x5E43D0]
005DA3C5 . 8038 00 cmp byte ptr ds:[eax],0x0
005DA3C8 . 0F85 F1010000 jnz dump.005DA5BF
005DA3CE . C645 F7 00 mov byte ptr ss:[ebp-0x9],0x0
005DA3D2 . A1 AC495E00 mov eax,dword ptr ds:[0x5E49AC] ; ld^
005DA3D7 . 8338 00 cmp dword ptr ds:[eax],0x0
005DA3DA . 0F85 DF010000 jnz dump.005DA5BF
这段就是点注册按钮的按钮事件地方,我们单步跟踪下去看看。。。
005DA511 > 8D4D F7 lea ecx,dword ptr ss:[ebp-0x9]
005DA514 . 8D55 F8 lea edx,dword ptr ss:[ebp-0x8]
005DA517 . A1 08475E00 mov eax,dword ptr ds:[0x5E4708] ; dc^
005DA51C . 8B00 mov eax,dword ptr ds:[eax]
005DA51E . E8 75EEF3FF call dump.00519398 ; 算法call
005DA523 . 8B45 F8 mov eax,dword ptr ss:[ebp-0x8]
005DA526 . BA 84A65D00 mov edx,dump.005DA684 ; YesIKnow
005DA52B . E8 ACABE2FF call dump.004050DC
005DA530 . 74 04 je short dump.005DA536
005DA532 . C645 F7 00 mov byte ptr ss:[ebp-0x9],0x0
005DA536 > 807D F7 00 cmp byte ptr ss:[ebp-0x9],0x0
005DA53A . 75 62 jnz short dump.005DA59E
005DA53C . 33C9 xor ecx,ecx
005DA53E . B2 01 mov dl,0x1
005DA540 . A1 7C355800 mov eax,dword ptr ds:[0x58357C] ; 佧F
005DA545 . E8 C27EEAFF call dump.0048240C
005DA54A . 8B15 AC495E00 mov edx,dword ptr ds:[0x5E49AC] ; ld^
005DA550 . 8902 mov dword ptr ds:[edx],eax
005DA552 . 33C0 xor eax,eax
005DA554 . 55 push ebp
005DA555 . 68 97A55D00 push dump.005DA597
005DA55A . 64:FF30 push dword ptr fs:[eax]
005DA55D . 64:8920 mov dword ptr fs:[eax],esp
005DA560 . A1 D0435E00 mov eax,dword ptr ds:[0x5E43D0]
005DA565 . C600 01 mov byte ptr ds:[eax],0x1
005DA568 . A1 AC495E00 mov eax,dword ptr ds:[0x5E49AC] ; ld^
005DA56D . 8B00 mov eax,dword ptr ds:[eax]
005DA56F . 8B10 mov edx,dword ptr ds:[eax]
005DA571 . FF92 EC000000 call dword ptr ds:[edx+0xEC]
005DA577 . 33C0 xor eax,eax
005DA579 . 5A pop edx ; 0012F8F4
005DA57A . 59 pop ecx ; 0012F8F4
005DA57B . 59 pop ecx ; 0012F8F4
005DA57C . 64:8910 mov dword ptr fs:[eax],edx
005DA57F . 68 A8A55D00 push dump.005DA5A8
005DA584 > A1 AC495E00 mov eax,dword ptr ds:[0x5E49AC] ; ld^
005DA589 . E8 C65CE3FF call dump.00410254
005DA58E . A1 D0435E00 mov eax,dword ptr ds:[0x5E43D0]
005DA593 . C600 00 mov byte ptr ds:[eax],0x0
005DA596 . C3 retn
005DA597 .^ E9 8C9FE2FF jmp dump.00404528
005DA59C .^ EB E6 jmp short dump.005DA584
005DA59E > B8 98A65D00 mov eax,dump.005DA698 ; 您已经注册了本软件!
005DA5A3 . E8 2441F2FF call dump.004FE6CC
005DA5A8 . 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
大家看到我标记的红色跳转地址,这个是判断是否注册成功的关键,所以说在这个跳转的上面肯定有个call是关键的算法call 经过分析 005DA51E 这个地址就是算法call 所以我们跟进去看看 这个记为算法call 1
分别判断注册码和用户名是否输入为空
005193EE |. E8 C53AFEFF call dump.004FCEB8 ; 获得硬盘序列号 S2ATTJKG
005193F3 |. 8B45 F0 mov eax,[local.4]
005193F6 |. 8D55 F4 lea edx,[local.3]
这个是获取我电脑的硬盘序列号 S2ATTJKG 这串东西很重要,因为作者拿这个序列号来进行计算注册码
00519408 |. 8D45 EC lea eax,[local.5]
0051940B |. 50 push eax
0051940C |. 8B03 mov eax,dword ptr ds:[ebx]
0051940E |. B1 61 mov cl,0x61
00519410 |. 66:BA 5904 mov dx,0x459
00519414 |. E8 9347FEFF call dump.004FDBAC ; 计算出软件显示出来的机器码 XV8OCxJDauE
00519419 |. 8B55 EC mov edx,[local.5]
0051941C |. 8BC3 mov eax,ebx
这个call是计算得出软件所显示出来的机器码
00519423 |. 8B45 FC mov eax,[local.1] ; 假码
00519426 |. 50 push eax
00519427 |. 57 push edi
00519428 |. 8BD3 mov edx,ebx
0051942A |. 8B4D F8 mov ecx,[local.2] ; 用户名
0051942D |. 8BC6 mov eax,esi
0051942F |. E8 64000000 call dump.00519498 ; 算法
00519434 |. 84C0 test al,al
00519436 74 0C je short dump.00519444
00519438 |. 8BC3 mov eax,ebx
0051943A |. BA 8C945100 mov edx,dump.0051948C ; YesIKnow
标记红色的地址为算法call 这个记为算法call 2
所以不用我多说了,直接F7跟进去看看
005194B0 |. 8BF2 mov esi,edx
005194B2 |. 8945 FC mov [local.1],eax ; dump.005E62FE
005194B5 |. 8B45 F8 mov eax,[local.2] ; 用户名
005194B8 |. E8 C3BCEEFF call dump.00405180
005194BD |. 8B45 0C mov eax,[arg.2] ; 假码
005194C0 |. E8 BBBCEEFF call dump.00405180
005194C5 |. 33C0 xor eax,eax ; dump.005E62FE
005194C7 |. 55 push ebp
005194C8 |. 68 90975100 push dump.00519790
005194CD |. 64:FF30 push dword ptr fs:[eax]
005194D0 |. 64:8920 mov dword ptr fs:[eax],esp
005194D3 |. 33DB xor ebx,ebx
005194D5 |. A1 54455E00 mov eax,dword ptr ds:[0x5E4554]
005194DA |. 8038 00 cmp byte ptr ds:[eax],0x0
005194DD |. 0F85 8A020000 jnz dump.0051976D
005194E3 |. 8D55 E0 lea edx,[local.8]
005194E6 |. B8 AC975100 mov eax,dump.005197AC ; SOFTAAENG
005194EB |. E8 C839FEFF call dump.004FCEB8
005194F0 |. 8B45 E0 mov eax,[local.8] ; 硬盘序列号
005194F3 |. 8D55 F4 lea edx,[local.3]
005194F6 |. E8 5906EFFF call dump.00409B54
005194FB |. 8D45 DC lea eax,[local.9]
005194FE |. 50 push eax ; dump.005E62FE
005194FF |. 8B06 mov eax,dword ptr ds:[esi] ; 生成机器码
00519501 |. B1 78 mov cl,0x78
00519503 |. 66:BA 5904 mov dx,0x459
00519507 |. E8 A046FEFF call dump.004FDBAC
0051950C |. 8B55 DC mov edx,[local.9] ; 序列号
0051950F |. 8B45 F4 mov eax,[local.3] ; 机器码
00519512 |. E8 C5BBEEFF call dump.004050DC
00519517 |. 0F85 50020000 jnz dump.0051976D
0051951D |. 8B45 0C mov eax,[arg.2] ; 假码
00519520 |. E8 6BBAEEFF call dump.00404F90
00519525 |. 8BF0 mov esi,eax ; 获得假码长度
00519527 |. 8D45 EC lea eax,[local.5]
0051952A |. 50 push eax ; dump.005E62FE
0051952B |. 8D45 D8 lea eax,[local.10]
0051952E |. 8B4D F8 mov ecx,[local.2] ; 用户名
00519531 |. 8B55 F4 mov edx,[local.3] ; 机器码
00519534 |. E8 A3BAEEFF call dump.00404FDC ; 合并字符串
00519539 |. 8B4D D8 mov ecx,[local.10] ; S2ATTJKGSendige
0051953C |. 8B45 FC mov eax,[local.1]
0051953F |. 8B40 60 mov eax,dword ptr ds:[eax+0x60]
00519542 |. BA C8010000 mov edx,0x1C8 ; 常量1c8
00519547 |. E8 FCE9FFFF call dump.00517F48 ; 注册码生成call
全部都是关键的东西啊,所以要注意了。
标记红色的为算法call 3 就是这个call才是我们要跟的地方,因为这个地方会出现真正的注册码
我们先不要进入这个call 继续单步调试下去看看
上图为第一个过渡注册码,就是说这个注册码是没用的
然后一路单步下去会发现全部都是一样的过程
1.获取机器码,生成硬盘系列号
2.获取用户名和机器码后,这2个进行合并
3.然后push 一个常量(用来进行计算的)分别为:1C8、2E、164和 0xFC
过渡注册码1 100937-12343464-2223981
过渡注册码2 94787-1245174-2223571
过渡注册码3 99437-9636564-2223881
真正注册码 97877-6821388-2223777
所以一直跟下去会发现这些信息,我们得知最后一个是真正的注册码后,所以我们只关注出真正的注册码的call就可以知道算法了
00517F48 /$ 55 push ebp ; 最终核心算法call
00517F49 |. 8BEC mov ebp,esp
00517F4B |. 6A 00 push 0x0
00517F4D |. 6A 00 push 0x0
00517F4F |. 6A 00 push 0x0
00517F51 |. 6A 00 push 0x0
00517F53 |. 6A 00 push 0x0
00517F55 |. 6A 00 push 0x0
00517F57 |. 6A 00 push 0x0
00517F59 |. 53 push ebx
00517F5A |. 56 push esi
00517F5B |. 894D F8 mov [local.2],ecx ; S2ATTJKGSendige
00517F5E |. 8955 FC mov [local.1],edx ; 0xFC
00517F61 |. 8B45 F8 mov eax,[local.2] ; S2ATTJKGSendige
0xFC是在进入call之前就压入堆栈的,这个数据是参与注册码计算
00517F84 |. 33DB xor ebx,ebx
00517F86 |. 837D FC 00 cmp [local.1],0x0 ; 对比常量是否为0
00517F8A |. 0F84 B3000000 je dump.00518043
00517F90 |. 837D F8 00 cmp [local.2],0x0 ; 对比这个是否为0 S2ATTJKGSendige
00517F94 |. 0F84 A9000000 je dump.00518043
00517F9A |. 8B45 F8 mov eax,[local.2]
00517F9D |. E8 EECFEEFF call dump.00404F90 ; S2ATTJKGSendige 获取这个的长度
00517FA2 |. 8945 F0 mov [local.4],eax ; strlen F为长度
00517FA5 |. 8B45 F0 mov eax,[local.4]
00517FA8 |. 85C0 test eax,eax ; 对比长度
我这里声明一些东西
str=S2ATTJKGSendige
constant=0xFC
strlen=S2ATTJKGSendige的长度(我这里的长度为0xF)
Str之和=addstrlen=509
00517FAC |. BA 01000000 mov edx,0x1
00517FB1 |> 8B4D F8 /mov ecx,[local.2]
00517FB4 |. 0FB64C11 FF |movzx ecx,byte ptr ds:[ecx+edx-0x1] ; 拆解字符串
00517FB9 |. 03D9 |add ebx,ecx
00517FBB |. 42 |inc edx
00517FBC |. 48 |dec eax
00517FBD |.^ 75 F2 jnz short dump.00517FB1
00517FBF |> 81FB 204E0000 cmp ebx,0x4E20 ; ebx为S2ATTJKGSendige 字符串的16进制相加的结果 509
这个00517FB4 地址 是进行拆分str 大家可以跟下看看 然后把拆分的每个字符串转换为16进制进行相加
标记为红色的2个地址已经说明的很清楚了。。。
所以得出ebx=509
就是上面所说的addstrlen 因为这个后面也是用来进行运算的
整个程序最关键的地方来了 整个程序最关键的地方来了 整个程序最关键的地方来了 重要的事情说三次
算法1
00517FD3 |> 8B75 FC mov esi,[local.1] ; 把常量0xFC给esi
00517FD6 |. 0FAF75 F0 imul esi,[local.4] ; [local.4]=strlen 常量和长度F相乘 结果存到esi
00517FDA |. 6BC3 49 imul eax,ebx,0x49 ; 上面说了ebx=509 即addstrlen和49相乘 结果存到eax
00517FDD |. 03F0 add esi,eax ; 两个结果相加
00517FDF |. 8D55 EC lea edx,[local.5]
00517FE2 |. 8BC6 mov eax,esi
00517FE4 |. E8 DB20EFFF call dump.0040A0C4 ; 将相加的结果转换为10进制
00517FE9 |. 8B55 EC mov edx,[local.5] ; 97877
两个数据相加的结果是00017E55 所以转换为10进制就是 97877
绿色这个call 是一个转换进制的函数而已
好了,我们接下来继续分析
00517FE9 |. 8B55 EC mov edx,[local.5] ; 97877
00517FEC |. 8D45 F4 lea eax,[local.3]
00517FEF |. B9 A0805100 mov ecx,dump.005180A0 ; -
00517FF4 |. E8 E3CFEEFF call dump.00404FDC
走到这里后,我们可以看到堆栈出现 0012F850 014276E4 ASCII "97877-"
所以可以看到这个是用来加“-”这个字符串和所得到的数字进行连接
算法2
00517FF9 |. 8B45 FC mov eax,[local.1] ; constant给eax
00517FFC |. F7EB imul ebx ; ebx=509=addstrlen 这句汇编的意思是将eax * ebx 得到的结果存在eax
00517FFE |. 6BF0 15 imul esi,eax,0x15 ;eax*15 结果存在esi
00518001 |. FF75 F4 push [local.3]
00518004 |. 8D55 E8 lea edx,[local.6]
00518007 |. 8BC6 mov eax,esi
00518009 |. E8 B620EFFF call dump.0040A0C4 ; 将相加的结果转换为10进制
得出 6821388
算法3
00518023 |. 8B45 F0 mov eax,[local.4] ; strlen给eax
00518026 |. F7EB imul ebx ; ebx=509=addstrlen eax*ebx 结果存在eax
00518028 |. 6BF0 73 imul esi,eax,0x73 ; eax*73 结果放在esi
0051802B |. 0375 FC add esi,[local.1]
0051802E |. 8D55 E4 lea edx,[local.7]
00518031 |. 8BC6 mov eax,esi ; dump.0068160C
00518033 |. E8 8C20EFFF call dump.0040A0C4 ; 将相加的结果转换为10进制
得出 2223777
最后连接注册码得出 0012F850 0142CDE4 ASCII "97877-6821388-2223777"
算法总结
算法1:constant*strlen+addstrlen*49=A
算法2:constant*addstrlen*15=B
算法3:strlen*addstrlen*73+constant=C
最终注册码: A-B-C
易语言源码展示
代码写的很挫 大家见谅 为了防止注册码泛滥,所以这里就不放上源码,只贴出图片,这个仅供大家参考,请勿用于非法用途,尊重作者的劳动成果!!!
HKEY_LOCAL_MACHINESOFTWARElsjsoftdct
By ↖星空·之上↗
个人博客:http://xingkongpj.blog.163.com/
16:39 2016/6/29