风云CM - 算法分析 & genkey实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | // 风云CM分析 // 计算用户名 00402D8A |> \8D45 F8 LEA EAX, [LOCAL.2] 00402D8D |. 50 PUSH EAX 00402D8E |. E8 8B060000 CALL <Hash_md5> ; // md5(用户名) 00402D93 |. 8945 F4 MOV [LOCAL.3], EAX 00402D96 |. 8B5D F8 MOV EBX, [LOCAL.2] 00402D99 |. 85DB TEST EBX, EBX 00402D9B |. 74 09 JE SHORT 00402DA6 00402D9D |. 53 PUSH EBX 00402D9E |. E8 0C060100 CALL 004133AF 00402DA3 |. 83C4 04 ADD ESP, 0x4 00402DA6 |> 8B45 F4 MOV EAX, [LOCAL.3] // 2cbd779a6d41d9715d259a5d7e8bb93d 00402DBE |. A3 67D04100 MOV DWORD PTR DS:[0x41D067], EAX ; // [0x41D067] = md5(用户名) 00402E29 |. A3 6BD04100 MOV DWORD PTR DS:[0x41D06B], EAX ; // md5(注册码) // 到字节集(md5(user)) 转换成字节集 00402E71 |. A3 6FD04100 MOV DWORD PTR DS:[0x41D06F], EAX // 字节集到文本 00402E76 |. 68 6FD04100 PUSH 0041D06F 00402E7B |. E8 18070000 CALL 00403598 ; 字节集到文本 00402E9B |. A3 73D04100 MOV DWORD PTR DS:[0x41D073], EAX 0018F6C0 002DCBA8 ASCII "3263626437373961366434316439373135643235396135643765386262393364" aEnCode // 保存长度 64 00402EFD |. A3 77D04100 MOV DWORD PTR DS:[0x41D077], EAX // left(aEnCode,0,5) 00402F51 |. A3 7BD04100 MOV DWORD PTR DS:[0x41D07B], EAX // left(aEnCode, 10, 5) 00402FB1 |. A3 7FD04100 MOV DWORD PTR DS:[0x41D07F], EAX // left(aEnCode, 20, 5) 00403011 |. A3 83D04100 MOV DWORD PTR DS:[0x41D083], EAX // left(aEnCode, 30, 5) 00403071 |. A3 87D04100 MOV DWORD PTR DS:[0x41D087], EAX // left(aEnCode, 40, 5) 004030D1 |. A3 8BD04100 MOV DWORD PTR DS:[0x41D08B], EAX // left(aEnCode, 50, 5) 00403131 |. A3 8FD04100 MOV DWORD PTR DS:[0x41D08F], EAX // 再次MD5 00403170 |. 50 PUSH EAX ; // left(aEnCode,0,5) 00403171 |. E8 A8020000 CALL <Hash_md5> // left(MD5(left(aEnCode, 0, 5)), 0 , 5) 004031BB |. 8945 F4 MOV [LOCAL.3], EAX // left(aEnCode, 0, 5) 00403202 |. 8945 F0 MOV [LOCAL.4], EAX // md5(left(aEnCode, 0, 5)) 00403209 |. E8 10020000 CALL <Hash_md5> 0040320E |. 8945 EC MOV [LOCAL.5], EAX // right(md5(left(aEnCode, 0, 5)),0, 5) 00403253 |. 8945 E8 MOV [LOCAL.6], EAX // L7 = left(MD5(left(aEnCode, 0, 5)), 0 , 5) + right(md5(left(aEnCode, 0, 5)),0, 5) 00403266 |> \FF75 E8 PUSH [LOCAL.6] 00403269 |. FF75 F4 PUSH [LOCAL.3] 0040326C |. B9 02000000 MOV ECX, 0x2 00403271 |. E8 98F9FFFF CALL 00402C0E ; 组合 00403279 |. 8945 E4 MOV [LOCAL.7], EAX // left(L7,0, 6) 004032DA |. 8945 E0 MOV [LOCAL.8], EAX // upcase(left(L7, 0, 6); 00403313 |. 8945 DC MOV [LOCAL.9], EAX 0040333E |. A3 93D04100 MOV DWORD PTR DS:[0x41D093], EAX // 到了关键的地方了 下面就是关键跳 00403343 |. E8 67050000 CALL 004038AF ; // 关键的俩个函数 into 00403348 |. E8 E0090000 CALL 00403D2D ; //比较eax = 1成功 0040334D |. 8945 F8 MOV [LOCAL.2], EAX 00403350 |. 837D F8 01 CMP [LOCAL.2], 0x1 00403354 |. 0F85 4F000000 JNZ 004033A9 0040335A |. 68 04000080 PUSH 0x80000004 0040335F |. 6A 00 PUSH 0x0 00403361 |. 68 C1924100 PUSH 004192C1 00403366 |. 68 01030080 PUSH 0x80000301 0040336B |. 6A 00 PUSH 0x0 0040336D |. 68 00000000 PUSH 0x0 00403372 |. 68 04000080 PUSH 0x80000004 00403377 |. 6A 00 PUSH 0x0 00403379 |. 68 C6924100 PUSH 004192C6 ; ASCII "注册成功!" 0040337E |. 68 03000000 PUSH 0x3 00403383 |. BB 00030000 MOV EBX, 0x300 00403388 |. E8 630E0100 CALL 004141F0 0040338D |. 83C4 28 ADD ESP, 0x28 00403390 |. 68 64000000 PUSH 0x64 00403395 |. 68 63D04100 PUSH 0041D063 0040339A |. 8B0424 MOV EAX, DWORD PTR SS:[ESP] 0040339D |. 8B00 MOV EAX, DWORD PTR DS:[EAX] 0040339F |. 8B00 MOV EAX, DWORD PTR DS:[EAX] 004033A1 |. FF50 14 CALL DWORD PTR DS:[EAX+0x14] 004033A4 |. E9 36000000 JMP 004033DF // 先进 0x004038AF // UPcase(LEFT(MD5(left(aEnCode,0,5)),2,5)) // UPcase(LEFT(MD5(left(aEnCode, 10, 5),3,5)) // UPcase(LEFT(MD5(left(aEnCode, 20, 5),4,5)) // UPcase(LEFT(MD5(left(aEnCode, 30, 5),5,5)) // UPcase(LEFT(MD5(left(aEnCode, 40, 5),6,5)) // UPcase(LEFT(MD5(left(aEnCode, 50, 5),7,5)) 0041D07B 002E0450 ASCII "8F717" 0041D07F 002E03A0 ASCII "1DE45" 0041D083 002E04A0 ASCII "2F035" 0041D087 002E03E0 ASCII "2ED7B" 0041D08B 002E0470 ASCII "46F03" 0041D08F 002E0630 ASCII "DB200" 004038B8 |. 68 7BD04100 PUSH 0041D07B 004038BD |. E8 5CFBFFFF CALL <Hash_md5> 004038C2 |. 8945 FC MOV [LOCAL.1], EAX 004038C5 |. 68 01030080 PUSH 0x80000301 004038CA |. 6A 00 PUSH 0x0 004038CC |. 68 05000000 PUSH 0x5 004038D1 |. 68 01030080 PUSH 0x80000301 004038D6 |. 6A 00 PUSH 0x0 004038D8 |. 68 02000000 PUSH 0x2 004038DD |. 68 04000080 PUSH 0x80000004 004038E2 |. 6A 00 PUSH 0x0 004038E4 |. 8B45 FC MOV EAX, [LOCAL.1] ; 风云CM.0040333A 004038E7 |. 85C0 TEST EAX, EAX 004038E9 |. 75 05 JNZ SHORT 004038F0 004038EB |. B8 37924100 MOV EAX, 00419237 004038F0 |> 50 PUSH EAX 004038F1 |. 68 03000000 PUSH 0x3 004038F6 |. BB 3C010000 MOV EBX, 0x13C 004038FB |. E8 90070100 CALL 00414090 00403900 |. 83C4 28 ADD ESP, 0x28 00403903 |. 8945 F8 MOV [LOCAL.2], EAX 00403934 |. E8 37080100 CALL 00414170 ; upcase 0040393C |. 8945 F4 MOV [LOCAL.3], EAX 00403967 |. A3 7BD04100 MOV DWORD PTR DS:[0x41D07B], EAX // 后面已经懒得分析了 剩下的就是比对了 |
注册机实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #include <iostream> #include <string> #include "md5.h" using namespace std; const string& ToUpcase(string &Text){ for (string::size_type i = 0; i < Text.length(); ++i) if (Text[i] >= 'a' && Text[i] <= 'z' ) Text[i] = Text[i] & ~0x20; return Text; } string MD5ToAscii( const string &Binary){ string HexTable = "0123456789ABCDEF" ; string Ascii; for (string::size_type i = 0; i < Binary.size(); ++i){ char n = Binary.at(i); while (n){ Ascii.insert(i*2, 1,HexTable.at(n % 16)); n /= 16; } } return Ascii; } int main() { string name; cout << "Input User Name:" ; cin >> name; // 第二部分 string strSn1 = MD5ToAscii(MD5(name).toString()); string strSn2 = MD5(strSn1.substr(0,5)).toString().substr(0,5); string strSn3 = MD5(strSn1.substr(64 - 5,5)).toString().substr(32 - 5,5); string strSn4 = strSn2 + strSn3; strSn4 = strSn4.substr(3,6); ToUpcase(strSn4); // 转到大写 // 第一部分 string strSn5 = MD5(strSn1.substr(0,5)).toString().substr(1,5); ToUpcase(strSn5); string strSn6 = MD5(strSn1.substr(9,5)).toString().substr(2,5); ToUpcase(strSn6); string strSn7 = MD5(strSn1.substr(19,5)).toString().substr(3,5); ToUpcase(strSn7); string strSn8 = MD5(strSn1.substr(29,5)).toString().substr(4,5); ToUpcase(strSn8); string strSn9 = MD5(strSn1.substr(39,5)).toString().substr(5,5); ToUpcase(strSn9); string strSn10 = MD5(strSn1.substr(49,5)).toString().substr(6,5); ToUpcase(strSn10); char regCode[100] = {0}; sprintf (regCode, "64-%s-%s-%s-%s-%s-%s-%s" , strSn5.c_str(), strSn6.c_str(), strSn7.c_str(), strSn8.c_str(), strSn9.c_str(), strSn10.c_str(), strSn4.c_str()); cout << "Your RegCode:" << regCode << endl; return 0; } |
风云CM分析+md5算法库+Source(genkey)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET开发智能桌面机器人:用.NET IoT库编写驱动控制两个屏幕
· 用纯.NET开发并制作一个智能桌面机器人:从.NET IoT入门开始
· 一个超经典 WinForm,WPF 卡死问题的终极反思
· ASP.NET Core - 日志记录系统(二)
· .NET 依赖注入中的 Captive Dependency
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(二):用.NET IoT库
· 几个自学项目的通病,别因为它们浪费了时间!
· 在外漂泊的这几年总结和感悟,展望未来
· .NET 数据拷贝方案选择
· .net工作流elsa-书签