程序是里诺客户管理软件2.0单机版。一般基础用于我这样的菜鸟学习软件,一般是没有壳的,不过我们还是先用PEID查一下壳。 Borland Delphi 6.0 - 7.0 果然不出我所料,Delphi写的。 先去他注册地方看看,注册提示信息,提示“软件注册失败”接下来,我们直接用OD载入,可以用OD的插件查找他的“ASCII”字符.查找有关信息. 这里功能和W32asm的字符串参考功能一般,不过比W32asm更方便,我用W32asm载入速度n慢,有时候还死机,汗!电脑配置差不能怪别人. 我们搜索“注册”,就可以找到我们的信息。我们在“提示注册成功,本程序所有能限制下次启动…..”这句地方,回车进入代码处,因为程序是重上面往下运行,所以我们分析要重下往上看. 0060FFCE . 55 PUSH EBP 0060FFCF . 68 0D016100 PUSH EasyCRM.0061010D 0060FFD4 . 64:FF30 PUSH DWORD PTR FS:[EAX] 0060FFD7 . 64:8920 MOV DWORD PTR FS:[EAX],ESP 0060FFDA . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0060FFDD . E8 AE020000 CALL EasyCRM.00610290 //调用算法 0060FFE2 . 84C0 TEST AL,AL //比较 0060FFE4 0F84 DB000000 JE EasyCRM.006100C5 //相等跳006100C5 0060FFEA . 33C0 XOR EAX,EAX 我们来看看006100C5处 006100C5 > 6A 40 PUSH 40 006100C7 . 68 58016100 PUSH EasyCRM.00610158 //软件注册 006100CC . 68 B4016100 PUSH EasyCRM.006101B4 //注册成功 经过,本菜鸟的简单分析, 0060FFDD . E8 AE020000 CALL EasyCRM.00610290 //这句就是他的关键CALL 0060FFE4 0F84 DB000000 JE EasyCRM.006100C5 //这句就是他的关键跳 那我们在他关键CALL 下断点,那我们输入假注册码,他是否会和真注册进行比较呢?下个断点试下就知道了。在0060FFDD 处F2下断点.接着F9运行程序,进行注册, 在注册的用户名我们就添入我们黑客防线的网站地址吧。在注册码随便输入些数字。点击注册,程序停止运行,有点假死的味道,我们来看看F7步入F8下走来看看OD的反映。 00610298 6A00 push 00000000 :0061029A 6A00 push 00000000 :0061029C 49 dec ecx :0061029D 75F9 jne 00610298 // 回跳在610298 :0061029F 51 push ecx //F4 进入之后在0061029D处有个回跳,我们直接在0061029F F4运行到所选,继续F8慢慢下看。经过n个F8后,我们在OD的下面看到一写类似的注册的ASCII的友情提示。 Stack SS:[0012EC0C]=01976030, (ASCII "CRM4-E63656ei8-E2D6") EDX=019764A4, (ASCII "www.hacker.com.cn") 我们刚才输入的用户名就是:www.hacker.com.cn 那CRM4-E63656ei8-E2D6 会不会是我们的注册码呢,我们来输入看看吧。 看图,提示“提示注册成功,本程序所有能限制下次启动…..”对于程序就破接ok了。接着我们就写我们的内存注册机了。对于内存注册就断在 006102f5的 edx上,因为这里是我们追出注册码的地方, 中断地址:6102f8 中断次数:1 第一字节:58 指令长度:1 对于程序的算法,我特别差,这里要感谢诗人的帮忙. 我们可以在 0060FFDD . E8 AE020000 CALL EasyCRM.00610290 //调用算法 进去看看他的算法分析,尝试写个算法注册机. 006103FD 6A 00 push 0 //初始化 006103FF 6A 00 push 0 00610401 49 dec ecx 00610402 ^ 75 F9 jnz short EasyCRM.006103FD 00610404 51 push ecx 00610405 874D FC xchg dword ptr ss:[ebp-4],ecx 00610408 53 push ebx 00610409 56 push esi 0061040A 57 push edi 0061040B 8BF9 mov edi,ecx 0061040D 8955 FC mov dword ptr ss:[ebp-4],edx 00610410 8B45 FC mov eax,dword ptr ss:[ebp-4] 00610413 E8 C84CDFFF call EasyCRM.004050E0 00610418 33C0 xor eax,eax 0061041A 55 push ebp 0061041B 68 B5056100 push EasyCRM.006105B5 00610420 64:FF30 push dword ptr fs:[eax] 00610423 64:8920 mov dword ptr fs:[eax],esp 00610426 8BC7 mov eax,edi 00610428 E8 0348DFFF call EasyCRM.00404C30 //取用户名 0061042D 8B45 FC mov eax,dword ptr ss:[ebp-4] 00610430 E8 BB4ADFFF call EasyCRM.00404EF0 //取用户名长度 00610435 8BF0 mov esi,eax 00610437 85F6 test esi,esi 00610439 7E 26 jle short EasyCRM.00610461 0061043B BB 01000000 mov ebx,1 00610440 8D4D EC lea ecx,dword ptr ss:[ebp-14] 00610443 8B45 FC mov eax,dword ptr ss:[ebp-4] 00610446 0FB64418 FF movzx eax,byte ptr ds:[eax+ebx-1] //循环 ebx作计数器 0061044B 33D2 xor edx,edx 0061044D E8 3A9FDFFF call EasyCRM.0040A38C //取 ascii码值的函数 00610452 8B55 EC mov edx,dword ptr ss:[ebp-14] 00610455 8D45 F8 lea eax,dword ptr ss:[ebp-8] 00610458 E8 9B4ADFFF call EasyCRM.00404EF8 // 保存在寄存器中,dd eax 0061045D 43 inc ebx 0061045E 4E dec esi 0061045F ^ 75 DF jnz short EasyCRM.00610440 00610461 8B45 F8 mov eax,dword ptr ss:[ebp-8] 00610464 E8 874ADFFF call EasyCRM.00404EF0 //取长度函数,相当于vb中的 len 00610469 8BF0 mov esi,eax 0061046B 85F6 test esi,esi 0061046D 7E 2C jle short EasyCRM.0061049B 0061046F BB 01000000 mov ebx,1 00610474 8B45 F8 mov eax,dword ptr ss:[ebp-8] //ebp-8中存的就是用户名的asc值 00610477 E8 744ADFFF call EasyCRM.00404EF0 0061047C 2BC3 sub eax,ebx 0061047E 8B55 F8 mov edx,dword ptr ss:[ebp-8] 00610481 8A1402 mov dl,byte ptr ds:[edx+eax] 00610484 8D45 E8 lea eax,dword ptr ss:[ebp-18] 00610487 E8 8C49DFFF call EasyCRM.00404E18 0061048C 8B55 E8 mov edx,dword ptr ss:[ebp-18] // 这一段处理的就是将asc反转, 0061048F 8D45 F4 lea eax,dword ptr ss:[ebp-C] //比如12asc码是 3132反转后变为2313 00610492 E8 614ADFFF call EasyCRM.00404EF8 // 相当于vb函数中的 StrReverse 00610497 43 inc ebx // 结果保存在 [ebp-c] 寄存器里 00610498 4E dec esi 00610499 ^ 75 D9 jnz short EasyCRM.00610474 0061049B 8D45 F8 lea eax,dword ptr ss:[ebp-8] 0061049E 50 push eax 0061049F B9 04000000 mov ecx,4 006104A4 BA 01000000 mov edx,1 006104A9 8B45 F4 mov eax,dword ptr ss:[ebp-C] 006104AC E8 9F4CDFFF call EasyCRM.00405150 // 取反序后的1-4位 006104B1 8D45 F4 lea eax,dword ptr ss:[ebp-C] 006104B4 50 push eax 006104B5 B9 04000000 mov ecx,4 006104BA BA 05000000 mov edx,5 006104BF 8B45 F4 mov eax,dword ptr ss:[ebp-C] 006104C2 E8 894CDFFF call EasyCRM.00405150 // 取反序后的5-8位 006104C7 8B45 F8 mov eax,dword ptr ss:[ebp-8] // 取出来的1-4为赋给eax 006104CA E8 214ADFFF call EasyCRM.00404EF0 006104CF 83F8 04 cmp eax,4 // 比较长度是否够4位 006104D2 7D 2F jge short EasyCRM.00610503 // 够则跳 继续处理,否则进行以下操作 006104D4 8B45 F8 mov eax,dword ptr ss:[ebp-8] 006104D7 E8 144ADFFF call EasyCRM.00404EF0 006104DC 8BD8 mov ebx,eax 006104DE 83FB 03 cmp ebx,3 006104E1 7F 20 jg short EasyCRM.00610503 006104E3 8D4D E4 lea ecx,dword ptr ss:[ebp-1C] 006104E6 8BC3 mov eax,ebx 006104E8 C1E0 02 shl eax,2 // 左移两位 也就是 乘以4 006104EB 33D2 xor edx,edx 006104ED E8 9A9EDFFF call EasyCRM.0040A38C 006104F2 8B55 E4 mov edx,dword ptr ss:[ebp-1C] // 不足4位就填充 长度*2*2的数字字符 006104F5 8D45 F8 lea eax,dword ptr ss:[ebp-8] 006104F8 E8 FB49DFFF call EasyCRM.00404EF8 006104FD 43 inc ebx 006104FE 83FB 04 cmp ebx,4 00610501 ^ 75 E0 jnz short EasyCRM.006104E3 00610503 8B45 F4 mov eax,dword ptr ss:[ebp-C] 00610506 E8 E549DFFF call EasyCRM.00404EF0 0061050B 83F8 04 cmp eax,4 // 5-8为空 也就是长度为0,则像前面一样处理 0061050E 7D 2F jge short EasyCRM.0061053F 00610510 8B45 F4 mov eax,dword ptr ss:[ebp-C] 00610513 E8 D849DFFF call EasyCRM.00404EF0 00610518 8BD8 mov ebx,eax 0061051A 83FB 03 cmp ebx,3 // 这里都是进行这样的处理 0061051D 7F 20 jg short EasyCRM.0061053F // 写成 vb的程序就是 0061051F 8D4D E0 lea ecx,dword ptr ss:[ebp-20] // for i=0 to 3 m=m&str(I*4) 00610522 8BC3 mov eax,ebx 00610524 C1E0 02 shl eax,2 00610527 33D2 xor edx,edx 00610529 E8 5E9EDFFF call EasyCRM.0040A38C 0061052E 8B55 E0 mov edx,dword ptr ss:[ebp-20] 00610531 8D45 F4 lea eax,dword ptr ss:[ebp-C] 00610534 E8 BF49DFFF call EasyCRM.00404EF8 00610539 43 inc ebx 0061053A 83FB 04 cmp ebx,4 0061053D ^ 75 E0 jnz short EasyCRM.0061051F 0061053F 8D45 F0 lea eax,dword ptr ss:[ebp-10] 00610542 BA CC056100 mov edx,EasyCRM.006105CC ; ASCII "CRM456ei878" 00610547 E8 7C47DFFF call EasyCRM.00404CC8 0061054C 8D45 DC lea eax,dword ptr ss:[ebp-24] // 特定字符串 0061054F 50 push eax 00610550 B9 04000000 mov ecx,4 00610555 BA 01000000 mov edx,1 0061055A 8B45 F0 mov eax,dword ptr ss:[ebp-10] 0061055D E8 EE4BDFFF call EasyCRM.00405150 // 取特定字符串1-4为也就是 CRM4 00610562 FF75 DC push dword ptr ss:[ebp-24] 00610565 68 E0056100 push EasyCRM.006105E0 0061056A FF75 F8 push dword ptr ss:[ebp-8] 0061056D 8D45 D8 lea eax,dword ptr ss:[ebp-28] 00610570 50 push eax // 将 算出来的 M1,M2分别插到特定字符串的具体位置 00610571 B9 05000000 mov ecx,5 00610576 BA 05000000 mov edx,5 // 就得出真正的注册码了 0061057B 8B45 F0 mov eax,dword ptr ss:[ebp-10] 0061057E E8 CD4BDFFF call EasyCRM.00405150 00610583 FF75 D8 push dword ptr ss:[ebp-28] 00610586 68 E0056100 push EasyCRM.006105E0 0061058B FF75 F4 push dword ptr ss:[ebp-C] 0061058E 8BC7 mov eax,edi 00610590 BA 06000000 mov edx,6 00610595 E8 164ADFFF call EasyCRM.00404FB0 0061059A 33C0 xor eax,eax 0061059C 5A pop edx 0061059D 59 pop ecx 0061059E 59 pop ecx 0061059F 64:8910 mov dword ptr fs:[eax],edx 006105A2 68 BC056100 push EasyCRM.006105BC 006105A7 8D45 D8 lea eax,dword ptr ss:[ebp-28] 006105AA BA 0A000000 mov edx,0A 006105AF E8 A046DFFF call EasyCRM.00404C54 006105B4 C3 retn 006105B5 ^ E9 163FDFFF jmp EasyCRM.004044D0 006105BA ^ EB EB jmp short EasyCRM.006105A7 006105BC 5F pop edi 006105BD 5E pop esi 006105BE 5B pop ebx 006105BF 8BE5 mov esp,ebp 006105C1 5D pop ebp 006105C2 C3 retn 例如,我们输入注册用户名字是1,那1 转换为 16进制的ASCII码是“31”,“31”不足八位,需要补全补为 318c048c ,翻转为 C840 C831 x1=c840 x2=C831 填到 CRM4-(x1)-56ei8-(x2) 得到的注册码就是:CRM4-138C56ei8-048C ,算法分析大概就是这样,知道了原理,我们就来写我们的算法注册机(编写语言VB)。 代码如下: Private Sub Command1_Click() Dim LenText1, i As Integer Dim str, ValueText1 As String ValueText1 = Text1.Text LenText1 = Len(ValueText1) If LenText1 = 0 Then MsgBox "注册名总不会为空吧", , "提示" Exit Sub End If For i = 1 To LenText1 str = str & Hex(Asc(Mid$(ValueText1, i, 1))) Next str = StrReverse(str) If LenText1 = 3 Then str = str & "8C" ElseIf LenText1 = 2 Then str = str & "048C" ElseIf LenText1 = 1 Then str = str & "8C048C" End If Text2.Text = "CRM4-" & Left$(str, 4) & "56ei8-" & Right$(str, 4) End Sub
|