论坛九宫格CM的算法简单分析
本帖最后由 wgz001 于 2018-11-27 20:22 编辑目标地址:类似九宫格算法Crackmehttps://www.chinapyg.com/thread-121565-1-1.html
(出处: 飘云阁(PYG官方论坛) )
简单分析:
一开始作者没有判断为0的情况,比较容易就搞定了,开始我还自己写程序爆破,因为也没看懂算法,现在想想有点好笑,算法的话不难,但是我觉得作者设计的比较好,上一下OD分析的记录,注册码分为18位,我记为N1......N18
004013B7|.83C4 08 add esp,0x8
004013BA|.F2:AE repne scas byte ptr es:
004013BC|.F7D1 not ecx
004013BE|.49 dec ecx
004013BF|.83F9 12 cmp ecx,0x12 ;比较注册码长度
004013C2|.0F84 83000000 je test.0040144B
004013C8|.8DB424 E00000>lea esi,dword ptr ss:
004013CF|.BF 19000000 mov edi,0x19
这样注释好了,下面就好分析了
0040144B|> \0FBE8424 C401>movsx eax,byte ptr ss:
00401453|.0FBE9424 C501>movsx edx,byte ptr ss:
0040145B|.8D0C80 lea ecx,dword ptr ds:
0040145E|.8D844A F0FDFF>lea eax,dword ptr ds:
00401465|.83F8 20 cmp eax,0x20 ;这里固定了前两位为:32
00401468|.0F85 08030000 jnz test.00401776
0040146E|.0FBE8424 CC01>movsx eax,byte ptr ss:
00401476|.0FBE9424 CD01>movsx edx,byte ptr ss:
0040147E|.8D0C80 lea ecx,dword ptr ds:
00401481|.8D844A F0FDFF>lea eax,dword ptr ds:
00401488|.83F8 10 cmp eax,0x10 ;这里固定了第9,10位为:16
0040148B|.0F85 E5020000 jnz test.00401776
00401491|.0FBE8424 C601>movsx eax,byte ptr ss: ;N3---->EAX
00401499|.0FBE9424 C701>movsx edx,byte ptr ss: ;N4---->EDX
004014A1|.8D0C80 lea ecx,dword ptr ds: ;N3*5---->ECX
004014A4|.8D844A F0FDFF>lea eax,dword ptr ds: ;(N4+N3*0xA-0x210)---->EAX
004014AB|.0FBE9424 C901>movsx edx,byte ptr ss: ;N6---->EDX
004014B3|.894424 14 mov dword ptr ss:,eax ;save eax
004014B7|.0FBE8424 C801>movsx eax,byte ptr ss: ;N5---->EAX
004014BF|.8D0C80 lea ecx,dword ptr ds: ;N5*5---->ECX
004014C2|.0FBE8424 CA01>movsx eax,byte ptr ss: ;N7---->EAX
004014CA|.8DAC4A F0FDFF>lea ebp,dword ptr ds: ;(N6+N5*0xA-0x210)----->ebp
004014D1|.0FBE8C24 CB01>movsx ecx,byte ptr ss: ;N8---->ECX
004014D9|.8D0480 lea eax,dword ptr ds: ;N7*5---->EAX
004014DC|.896C24 18 mov dword ptr ss:,ebp ;save ebp
004014E0|.8DBC41 F0FDFF>lea edi,dword ptr ds: ;(N8+N7*0xA-0x210)----->EDI
004014E7|.0FBE8424 CE01>movsx eax,byte ptr ss: ;N11---->EAX
004014EF|.8D1480 lea edx,dword ptr ds: ;N11*5---->EDX
004014F2|.0FBE8424 CF01>movsx eax,byte ptr ss: ;N12---->EAX
004014FA|.8D8C50 F0FDFF>lea ecx,dword ptr ds: ;(N12+N11*0xA-0x210)----->ECX
00401501|.0FBE8424 D001>movsx eax,byte ptr ss: ;N13---->EAX
00401509|.894C24 10 mov dword ptr ss:,ecx ;save ecx
0040150D|.8D1480 lea edx,dword ptr ds: ;N13*5---->EDX
00401510|.0FBE8424 D101>movsx eax,byte ptr ss: ;N14---->EAX
00401518|.8DB450 F0FDFF>lea esi,dword ptr ds: ;(N14+N13*0xA-0x210)----->ESI
0040151F|.0FBE8424 D201>movsx eax,byte ptr ss: ;N15----->EAX
00401527|.0FBE9424 D301>movsx edx,byte ptr ss: ;N16----->EDX
0040152F|.8D0C80 lea ecx,dword ptr ds: ;N15*5----->ECX
00401532|.0FBE8424 D401>movsx eax,byte ptr ss: ;N17----->EAX
0040153A|.8D8C4A F0FDFF>lea ecx,dword ptr ds: ;(N16+N15*0xA-0x210)------>ECX
00401541|.0FBE9424 D501>movsx edx,byte ptr ss: ;N18----->EDX
00401549|.8D0480 lea eax,dword ptr ds: ;N17*5----->EAX
0040154C|.8D8442 F0FDFF>lea eax,dword ptr ds: ;(N18+N17*0xA-0x210)---->EAX
00401553|.3BC3 cmp eax,ebx ;新增加的判断17,18位是不是为0
00401555|.0F84 BD010000 je test.00401718
下面就是九宫格中,相乘后的比较,分了5部分
0040155B|.8B5424 10 mov edx,dword ptr ss:
0040155F|.0FAF6C24 14 imul ebp,dword ptr ss:
00401564|.0FAFD7 imul edx,edi
00401567|.C1E2 04 shl edx,0x4
0040156A|.C1E5 05 shl ebp,0x5
0040156D|.3BEA cmp ebp,edx
0040156F|.0F85 45010000 jnz test.004016BA
00401575|.8BE8 mov ebp,eax
00401577|.0FAFE9 imul ebp,ecx
0040157A|.0FAFEE imul ebp,esi
0040157D|.3BD5 cmp edx,ebp
0040157F|.0F85 35010000 jnz test.004016BA
00401585|.0FAF4C24 14 imul ecx,dword ptr ss:
0040158A|.8BD6 mov edx,esi
0040158C|.0FAFD7 imul edx,edi
0040158F|.C1E1 04 shl ecx,0x4
00401592|.C1E2 05 shl edx,0x5
00401595|.3BD1 cmp edx,ecx
00401597|.0F85 BF000000 jnz test.0040165C
0040159D|.8BF8 mov edi,eax
0040159F|.8B5424 18 mov edx,dword ptr ss:
004015A3|.0FAF7C24 10 imul edi,dword ptr ss:
004015A8|.0FAFFA imul edi,edx
004015AB|.3BCF cmp ecx,edi
004015AD|.0F85 A9000000 jnz test.0040165C
004015B3|.0FAFF2 imul esi,edx
004015B6|.C1E6 04 shl esi,0x4
004015B9|.C1E0 09 shl eax,0x9
004015BC|.3BC6 cmp eax,esi
004015BE|.75 3E jnz short test.004015FE
上面的整理后就是这样子
(N12+N11*0xA-0x210)*(N8+N7*0xA-0x210)*0x10== (N6+N5*0xA-0x210)*(N4+N3*0xA-0x210)*0x20
(N18+N17*0xA-0x210)*(N16+N15*0xA-0x210)*(N14+N13*0xA-0x210)==(N12+N11*0xA-0x210)*(N8+N7*0xA-0x210)*0x10
(N16+N15*0xA-0x210)*(N4+N3*0xA-0x210)*0x10== (N14+N13*0xA-0x210)*(N8+N7*0xA-0x210)*0x20
(N18+N17*0xA-0x210)*(N12+N11*0xA-0x210)*(N6+N5*0xA-0x210)==(N16+N15*0xA-0x210)*(N4+N3*0xA-0x210)*0x10
(N6+N5*0xA-0x210)*(N14+N13*0xA-0x210)*0x10==(N18+N17*0xA-0x210)*0x200
这5部分类似这个图
解释:N1N2就类似表中的12,N1为十位数,N2为个位数,组成一个两位整数.........N17,N18就是表中的17,18,N17为十位数,N18为个位数,组成一个两位整数,表中相同颜色的线中的三个数字相乘要相等。
最后可以凑出合法的注册码,如图
感谢GG老师及一起玩游戏小组全体成员!!
一起玩游戏 已跪拜! 膜拜楼主,这个算法设计也是在看书的过程中突然想到的就实现了一下
本帖最后由 hoy0a1d 于 2018-12-5 14:50 编辑
借楼发一下源码吧
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char RegKey;
int tip = {80, 108, 101, 97, 115, 101, 0, 105, 110, 112, 117, 116, 0,
82, 101, 103, 75, 101, 121, 58, 0};
// Please input RegKey:
int ok = {86, 101, 114, 121, 0, 103, 111, 111, 100, 33, 0, 89, 111, 117, 114, 0,
82, 101, 103, 75, 101, 121, 0, 105, 115, 0, 82, 105, 103, 104, 116, 33};
// Very good! Your RegKey is Right!
int no = {83, 111, 114, 114, 121, 33, 0, 89, 111, 117, 114, 0,
82, 101, 103, 75, 101, 121, 0, 105, 115, 0, 87, 114, 111, 110, 103, 33};
// Sorry! Your RegKey is Wrong!
int TestLen = {82, 101, 103, 75, 101, 121, 0, 108, 101, 110, 103, 116, 104, 0,
109, 117, 115, 116, 0, 98, 101, 0, 49, 56, 46};
// RegKey length must be 18.
for(int i = 0; i < 21; i++)
cout << (char)tip;
cin >> RegKey;
int key1 = 32, key2, key3, key4, key5 = 16, key6, key7, key8, key9;
// 判断输入位数是否为 18若不等于 18 输出提示
if(strlen(RegKey) != 18)
{
for(int i = 0; i < 25; i++)
cout << (char)TestLen;
cout << endl;
}
else
{
/*
————————————————
| 32 | xx | xx |
| | | |
| xx | 16 | xx |
| | | |
| xx | xx | xx |
————————————————
*/
// 判断左上角是否为 32 且中心是否为 16
if((RegKey - '0') * 10 + (RegKey - '0') == key1
&& (RegKey - '0') * 10 + (RegKey - '0') == key5)
{
key2 = (RegKey - '0') * 10 + (RegKey - '0');
key3 = (RegKey - '0') * 10 + (RegKey - '0');
key4 = (RegKey - '0') * 10 + (RegKey - '0');
key6 = (RegKey - '0') * 10 + (RegKey - '0');
key7 = (RegKey - '0') * 10 + (RegKey - '0');
key8 = (RegKey - '0') * 10 + (RegKey - '0');
key9 = (RegKey - '0') * 10 + (RegKey - '0');
// 这里判断一下右下角是否为 0因为右下角为 0 则除了已给出的 32 和 16
// 其他部位全部填 0 则可正确注册
if(key9 != 0)
{
// 判断横排三组数相乘是否相等
if(key1 * key2 * key3 == key4 * key5 * key6
&& key4 * key5 * key6 == key7 * key8 * key9)
{
// 判断竖排三组数相乘是否相等
if(key1 * key4 * key7 == key2 * key5 * key8
&& key2 * key5 * key8 == key3 * key6 * key9)
{
// 判断对角两组数相乘是否相等
if(key1 * key5 * key9 == key3 * key5 * key7)
{
for(int i = 0; i < 32; i++)
cout << (char)ok;
cout << endl;
}
else
{
for(int i = 0; i < 28; i++)
cout << (char)no;
cout << endl;
}
}
else
{
for(int i = 0; i < 28; i++)
cout << (char)no;
cout << endl;
}
}
else
{
for(int i = 0; i < 28; i++)
cout << (char)no;
cout << endl;
}
}
else
{
for(int i = 0; i < 28; i++)
cout << (char)no;
cout << endl;
}
}
else
{
for(int i = 0; i < 28; i++)
cout << (char)no;
cout << endl;
}
}
return 0;
}
hoy0a1d 发表于 2018-11-28 13:30
膜拜楼主,这个算法设计也是在看书的过程中突然想到的就实现了一下
666
羡慕会编程的表哥,自己的想法可以用程序实现出来,赞
页:
[1]