-
-
[原创]PEDIY CrackMe竞赛2016---第八题简单分析
-
发表于: 2016-11-17 11:34 3104
-
简单分析,此题又是一个多解题大概说一下,后面贴码大家自己研究研究。
注册码:44100A3434
恭喜你注册成功!
注册码:10000A12
恭喜你注册成功!
注册码:44100A1234
恭喜你注册成功!
//if (2 * a + names[vi][vj] == a * 3)
if (names[vi][vj] == a)
{
//成功//276/3=92
//92*92=8464
printf("OK\n");
}
输入1A1212什么之类的,然后看这步names[vi][vj]=多少,假设是a, 那么b=a*a; 那么输入bA1212就可以了。
前提输入不要让数组越界。
不多说了直接上分析“源”码:
// k8.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
int g_Array1[31];//?31个
int g_Xxxx;
int names[5][5] = {
276,284, 4,270,317,
271,265,263,343,310,
306,302,308,272,270,
267,272,282,300,306,
302,305,330,278,295
};//从文件读取
int g_Yyyy;
/*
276 284 4 270 317
271 265 263 343 310
306 302 308 272 270
267 272 282 300 306
302 305 330 278 295
*/
//ecx, edx, r8
int Calc2(int aa)
{
//不能返回0
if (aa == 874) return -1;
if (aa == 987654321) return -1;
int cc = aa;
int v3 = 1;
int v4 = 0;
if (cc)
{
while (cc)
{
v4++;
cc /= 10;
}
}
else
{
v4 = 1;
}
for (int i = 0; i < v4; i++)
{
v3 *= 10;
}
//////////////////////////////////////////////////////////////////////////
int rr = 0;
do
{
rr++;
} while (((rr * rr) % v3) != aa);
//找到一个数, 使得a*a % = 10000//aa= 1234
//比如a最好是一个完全平方数;开根号
// 11025
//100000
return rr;
}
void Func1(int xx)
{
if ((xx - 1) == g_Xxxx)
{
g_Yyyy++;
return;
}
for (int i = 0; i <= 1; i++)
{
if ((xx < 3) || (g_Array1[xx - 1] != i) || ( g_Array1[xx - 2] != i))
{
g_Array1[xx] = i;
Func1(xx + 1);
}
}
}
void Check2(int a, char *b)
{
//int oki = a;//那就是a
// g_Xxxx = 1;
// for (int i = 0; i <= 1;i++)
// {
// g_Array1[1] = i;
// Func1(2);
// }
int vi = 2;
int vj = 2;//固定=2
int vy = 0;
int ni;
int nj;
char *pp = b;
int len = strlen(b);
if (len != 0)
{
//DeleteCode();
ni = 2;
nj = 2;
//int v12 = 1;//好像无太多作用
//int v13 = 3;//好像无太多作用
//很复杂的循环
//循环所有字符
for (int vx = 0; vx < len; vx++)
{
//可能有用, 可能没用//用处不大
for (int i = 0; i < 5; i++)
{
names[i][0] ^= ((1 + vx) * *pp);
names[i][1] ^= ((1 + vx) * *pp);
names[i][2] ^= ((1 + vx) * *pp);
names[i][3] ^= ((1 + vx) * *pp);
names[i][4] ^= ((1 + vx) * *pp);
}
/*
(0,0) (0,1) (0,2) (0,3) (0, 4)
(1,0) (1,1) (1,2) (1,3) (1, 4)
(2,0) (2,1) (2,2) (2,3) (2, 4)
(3,0) (3,1) (3,2) (3,3) (3, 4)
(4,0) (4,1) (4,2) (4,3) (4, 4)
*/
switch(*pp)
{
case '1':
{
names[ni][nj] = vy;
vy++;
//if (v12 >= 4 + 3) over;//等价ni >= 5
//if (nj >= 5) over;
//v13--;
//v12--;//UP
vi--;
ni--;//ebp+5
};
break;
case '2'://DOWN
{
names[ni][nj] = vy;
vy++;
//if (v13 >= 4 + 3) over;
//if (nj >= 5) over;
//v13++;
//if (ni >= 5) over;
//v12++;
vi++;
ni++;//ebp+5
};
break;
case '3':
{
names[ni][nj] = vy;
vy++;
//if (vi >= 4 + 3) over;
//if (vj >= 6) over;
vj--;
nj--;//LEFT
};
break;
case '4':
{
names[ni][nj] = vy;
vy++;
//if (vi >= 4 + 3) over;
//if (vj >= 4) over;
vj++;
nj++;//RIGHT
};
break;
default:
{
//fuck over
};
}//end switch
//vx++;
pp++;
}
}//end if (len != 0)
//if (2 * a + names[vi][vj] == a * 3)
if (names[vi][vj] == a)
{
//成功//276/3=92
//92*92=8464
printf("OK\n");
}
else
{
printf("%dA%s", names[vi][vj] * names[vi][vj], b);
}
//失败
}
void Check()
{
char serial[256*4];
int bb[4];
printf("Input:");
//8464A1234123412341234123412341234
//8464A12
scanf("%dA%s", &bb[0], &serial[0]);
int v = Calc2( bb[0] );//求平方根? 输入的最好是完全平方数, 否则不好处理
if (v != 0)
{
g_Xxxx = 0;
g_Yyyy = 0;
memset(g_Array1, 0, sizeof(g_Array1));
//=
Check2(v, &serial[0]);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Check();
//char *p = (char*)argv[1];
//printf("%dA%s", 1023, p);
return 0;
}
/*
void DeleteCode()
{
//
if(0)
{
int vx = 0;
int index_first_zero = 0;
while (b[index_first_zero] != 0)//可能溢出??不能输入\0字符串
{
index_first_zero++;
}
if (index_first_zero != 0)
{
nj = vj;
int v12 = vj - 1;
int v13 = vj + 1;
//很复杂的循环
int ni = vj;
for(;;)
{
g_Xxxx = 1;
g_Yyyy = 0;//?
for (int i = 0; i <= 1; i++)
{
g_Array1[1] = i;
Func1( 2 );
}
for (int i = 0; i < 5; i++)
{
names[i][0] ^= ((g_Yyyy - 1 + vx) * *pp);
names[i][1] ^= ((g_Yyyy - 1 + vx) * *pp);
names[i][2] ^= ((g_Yyyy - 1 + vx) * *pp);
names[i][3] ^= ((g_Yyyy - 1 + vx) * *pp);
names[i][4] ^= ((g_Yyyy - 1 + vx) * *pp);
}
//
switch(*pp)
{
case '1':
{
g_Xxxx = 2;
g_Yyyy = 0;
names[ni][nj] = vy;
vy++;
memset(g_Array1, 0, sizeof(g_Array1));
for (int i = 0; i <= 1; i++)
{
g_Array1[1] = i;
Func1(2);
}
//if (v12 >= g_Yyyy + 3) over;
//if (nj >= 5) over;
vi--;
v13--;
v12--;
ni--;//ebp+5
};
break;
case '2':
{
g_Xxxx = 2;
g_Yyyy = 0;
names[ni][nj] = vy;
vy++;
memset(g_Array1, 0, sizeof(g_Array1));
for (int i = 0; i <= 1; i++)
{
g_Array1[1] = i;
Func1(2);
}
//if (v13 >= g_Yyyy + 3) over;
//if (nj >= 5) over;
vi++;
v13++;
v12++;
ni++;//ebp+5
};
break;
case '3':
{
g_Xxxx = 2;
g_Yyyy = 0;
names[ni][nj] = vy;
vy++;
memset(g_Array1, 0, sizeof(g_Array1));
for (int i = 0; i <= 1; i++)
{
g_Array1[1] = i;
Func1(2);
}
//if (vi >= g_Yyyy + 3) over;
//if (vj >= 6) over;
vj--;
nj--;
};
break;
case '4':
{
g_Xxxx = 2;
names[ni][nj] = vy;
vy++;
g_Yyyy = 0;
memset(g_Array1, 0, sizeof(g_Array1));
for (int i = 0; i <= 1; i++)
{
g_Array1[1] = i;
Func1(2);
}
printf("%d", g_Yyyy + 3);
//if (vi >= g_Yyyy + 3) over;
//if (vj >= 4) over;
vj++;
nj++;
};
break;
default:
{
//fuck over
};
}//end switch
vx++;
pp++;
//重新查找第一个为0的值
index_first_zero = 0;
while (b[index_first_zero] != 0)//可能溢出??
{
index_first_zero++;
}
if (vx >= index_first_zero) break;
}
}
}//end if 0
}
*/
注册码:44100A3434
恭喜你注册成功!
注册码:10000A12
恭喜你注册成功!
注册码:44100A1234
恭喜你注册成功!
//if (2 * a + names[vi][vj] == a * 3)
if (names[vi][vj] == a)
{
//成功//276/3=92
//92*92=8464
printf("OK\n");
}
输入1A1212什么之类的,然后看这步names[vi][vj]=多少,假设是a, 那么b=a*a; 那么输入bA1212就可以了。
前提输入不要让数组越界。
不多说了直接上分析“源”码:
// k8.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
int g_Array1[31];//?31个
int g_Xxxx;
int names[5][5] = {
276,284, 4,270,317,
271,265,263,343,310,
306,302,308,272,270,
267,272,282,300,306,
302,305,330,278,295
};//从文件读取
int g_Yyyy;
/*
276 284 4 270 317
271 265 263 343 310
306 302 308 272 270
267 272 282 300 306
302 305 330 278 295
*/
//ecx, edx, r8
int Calc2(int aa)
{
//不能返回0
if (aa == 874) return -1;
if (aa == 987654321) return -1;
int cc = aa;
int v3 = 1;
int v4 = 0;
if (cc)
{
while (cc)
{
v4++;
cc /= 10;
}
}
else
{
v4 = 1;
}
for (int i = 0; i < v4; i++)
{
v3 *= 10;
}
//////////////////////////////////////////////////////////////////////////
int rr = 0;
do
{
rr++;
} while (((rr * rr) % v3) != aa);
//找到一个数, 使得a*a % = 10000//aa= 1234
//比如a最好是一个完全平方数;开根号
// 11025
//100000
return rr;
}
void Func1(int xx)
{
if ((xx - 1) == g_Xxxx)
{
g_Yyyy++;
return;
}
for (int i = 0; i <= 1; i++)
{
if ((xx < 3) || (g_Array1[xx - 1] != i) || ( g_Array1[xx - 2] != i))
{
g_Array1[xx] = i;
Func1(xx + 1);
}
}
}
void Check2(int a, char *b)
{
//int oki = a;//那就是a
// g_Xxxx = 1;
// for (int i = 0; i <= 1;i++)
// {
// g_Array1[1] = i;
// Func1(2);
// }
int vi = 2;
int vj = 2;//固定=2
int vy = 0;
int ni;
int nj;
char *pp = b;
int len = strlen(b);
if (len != 0)
{
//DeleteCode();
ni = 2;
nj = 2;
//int v12 = 1;//好像无太多作用
//int v13 = 3;//好像无太多作用
//很复杂的循环
//循环所有字符
for (int vx = 0; vx < len; vx++)
{
//可能有用, 可能没用//用处不大
for (int i = 0; i < 5; i++)
{
names[i][0] ^= ((1 + vx) * *pp);
names[i][1] ^= ((1 + vx) * *pp);
names[i][2] ^= ((1 + vx) * *pp);
names[i][3] ^= ((1 + vx) * *pp);
names[i][4] ^= ((1 + vx) * *pp);
}
/*
(0,0) (0,1) (0,2) (0,3) (0, 4)
(1,0) (1,1) (1,2) (1,3) (1, 4)
(2,0) (2,1) (2,2) (2,3) (2, 4)
(3,0) (3,1) (3,2) (3,3) (3, 4)
(4,0) (4,1) (4,2) (4,3) (4, 4)
*/
switch(*pp)
{
case '1':
{
names[ni][nj] = vy;
vy++;
//if (v12 >= 4 + 3) over;//等价ni >= 5
//if (nj >= 5) over;
//v13--;
//v12--;//UP
vi--;
ni--;//ebp+5
};
break;
case '2'://DOWN
{
names[ni][nj] = vy;
vy++;
//if (v13 >= 4 + 3) over;
//if (nj >= 5) over;
//v13++;
//if (ni >= 5) over;
//v12++;
vi++;
ni++;//ebp+5
};
break;
case '3':
{
names[ni][nj] = vy;
vy++;
//if (vi >= 4 + 3) over;
//if (vj >= 6) over;
vj--;
nj--;//LEFT
};
break;
case '4':
{
names[ni][nj] = vy;
vy++;
//if (vi >= 4 + 3) over;
//if (vj >= 4) over;
vj++;
nj++;//RIGHT
};
break;
default:
{
//fuck over
};
}//end switch
//vx++;
pp++;
}
}//end if (len != 0)
//if (2 * a + names[vi][vj] == a * 3)
if (names[vi][vj] == a)
{
//成功//276/3=92
//92*92=8464
printf("OK\n");
}
else
{
printf("%dA%s", names[vi][vj] * names[vi][vj], b);
}
//失败
}
void Check()
{
char serial[256*4];
int bb[4];
printf("Input:");
//8464A1234123412341234123412341234
//8464A12
scanf("%dA%s", &bb[0], &serial[0]);
int v = Calc2( bb[0] );//求平方根? 输入的最好是完全平方数, 否则不好处理
if (v != 0)
{
g_Xxxx = 0;
g_Yyyy = 0;
memset(g_Array1, 0, sizeof(g_Array1));
//=
Check2(v, &serial[0]);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Check();
//char *p = (char*)argv[1];
//printf("%dA%s", 1023, p);
return 0;
}
/*
void DeleteCode()
{
//
if(0)
{
int vx = 0;
int index_first_zero = 0;
while (b[index_first_zero] != 0)//可能溢出??不能输入\0字符串
{
index_first_zero++;
}
if (index_first_zero != 0)
{
nj = vj;
int v12 = vj - 1;
int v13 = vj + 1;
//很复杂的循环
int ni = vj;
for(;;)
{
g_Xxxx = 1;
g_Yyyy = 0;//?
for (int i = 0; i <= 1; i++)
{
g_Array1[1] = i;
Func1( 2 );
}
for (int i = 0; i < 5; i++)
{
names[i][0] ^= ((g_Yyyy - 1 + vx) * *pp);
names[i][1] ^= ((g_Yyyy - 1 + vx) * *pp);
names[i][2] ^= ((g_Yyyy - 1 + vx) * *pp);
names[i][3] ^= ((g_Yyyy - 1 + vx) * *pp);
names[i][4] ^= ((g_Yyyy - 1 + vx) * *pp);
}
//
switch(*pp)
{
case '1':
{
g_Xxxx = 2;
g_Yyyy = 0;
names[ni][nj] = vy;
vy++;
memset(g_Array1, 0, sizeof(g_Array1));
for (int i = 0; i <= 1; i++)
{
g_Array1[1] = i;
Func1(2);
}
//if (v12 >= g_Yyyy + 3) over;
//if (nj >= 5) over;
vi--;
v13--;
v12--;
ni--;//ebp+5
};
break;
case '2':
{
g_Xxxx = 2;
g_Yyyy = 0;
names[ni][nj] = vy;
vy++;
memset(g_Array1, 0, sizeof(g_Array1));
for (int i = 0; i <= 1; i++)
{
g_Array1[1] = i;
Func1(2);
}
//if (v13 >= g_Yyyy + 3) over;
//if (nj >= 5) over;
vi++;
v13++;
v12++;
ni++;//ebp+5
};
break;
case '3':
{
g_Xxxx = 2;
g_Yyyy = 0;
names[ni][nj] = vy;
vy++;
memset(g_Array1, 0, sizeof(g_Array1));
for (int i = 0; i <= 1; i++)
{
g_Array1[1] = i;
Func1(2);
}
//if (vi >= g_Yyyy + 3) over;
//if (vj >= 6) over;
vj--;
nj--;
};
break;
case '4':
{
g_Xxxx = 2;
names[ni][nj] = vy;
vy++;
g_Yyyy = 0;
memset(g_Array1, 0, sizeof(g_Array1));
for (int i = 0; i <= 1; i++)
{
g_Array1[1] = i;
Func1(2);
}
printf("%d", g_Yyyy + 3);
//if (vi >= g_Yyyy + 3) over;
//if (vj >= 4) over;
vj++;
nj++;
};
break;
default:
{
//fuck over
};
}//end switch
vx++;
pp++;
//重新查找第一个为0的值
index_first_zero = 0;
while (b[index_first_zero] != 0)//可能溢出??
{
index_first_zero++;
}
if (vx >= index_first_zero) break;
}
}
}//end if 0
}
*/
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
看原图
赞赏
雪币:
留言: