简单分析原则,最近论坛发图老是挂掉,烦恼啊!这几天没怎么合眼有点逻辑混乱大家包含,我直接上代码大家自己看看吧。
第七题刚开始拿到题抽象不出模型,一堆递归调用,完全懵了,注册码在最后面哈!
代码如下:
得到这个数组后,输入序列号了。
unsigned __int64 Calc4(int minv, int maxv, unsigned __int64 Buf[][MAX_COUNT], unsigned int *Init)
{
if (minv > maxv) return 0;
if (Buf[minv][maxv] != 0xFFFFFFFFFFFFFFFF) return Buf[minv][maxv];
if (minv == maxv)
{
Buf[minv][maxv] = Init[minv];
return Buf[minv][maxv];
}
Buf[minv][maxv] = Calc4(minv + 1, maxv, Buf, Init) + Init[minv];
return Buf[minv][maxv];
}
unsigned __int64 Calc3(int minv, int maxv, unsigned __int64 Buf[][MAX_COUNT], unsigned int *Init)
{
if (minv > maxv) return 0;
if (Buf[minv][maxv] != 0xFFFFFFFFFFFFFFFF) return Buf[minv][maxv];
if (minv == maxv)
{
Buf[minv][maxv] = Init[minv];
return Buf[minv][maxv];
}
unsigned __int64 v1 = Calc3(minv + 1, maxv, Buf, Init);
unsigned __int64 v2 = Calc3(minv, maxv - 1, Buf, Init);
unsigned __int64 v3;
if (v2 < v1)
{
v3 = Calc3(minv, maxv - 1, Buf, Init);
}
else
{
v3 = Calc3(minv + 1, maxv, Buf, Init);
}
Buf[minv][maxv] = Calc4(minv, maxv, Buff2, Init) - v3;
return Buf[minv][maxv];
}
初始化代码中的关键代码,也应该从这里面推算出序列号。
Init[0] = 0x6C35B49D;
Init[1] = 0xA645500D;
Init[2] = 0xCB9E682E;
s = Init[0];
s += Init[1];
s += Init[2];
for (int i = 3; i < MAX_COUNT; i++)
{
Init[i] = Init[i-3] + Init[i-2] * Init[i-1];
s += Init[i];
}
memset( Buff1, 0xFF, sizeof(Buff1));
memset( Buff2, 0xFF, sizeof(Buff2));
unsigned __int64 kc = Calc3( 0, MAX_COUNT - 1, Buff1, &Init[0]);//=a ok
unsigned __int64 ke = Calc4( 0, MAX_COUNT - 1, Buff2, &Init[0]);;
unsigned __int64 kd = ke -kc;
这是全部初始化过程。
#define MAX_COUNT 1010
unsigned int Init[1010];
unsigned __int64 Buff1[1010][1010];
unsigned __int64 Buff2[1010][1010];
if (IS_DEC_INDEX == 0)
{
if (ab == 0) {a += Init[indexi];} else b += Init[indexi];
indexi++;
}
else
{
if (ab == 0) {a += Init[indexj];} else b += Init[indexj];
indexj--;
}
ab = (ab == 0) ? 1: 0;
这里是关键运算的子函数,如果计算结果, 能够让
c=000000FEF635D82A d=000000FAD883E964
a=c; b=d;答案就出来了。
BCBCBCBCBFCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBBBBBBBBBBBBBBBBBBBBBBBB
用这个序列号可以过Check0/Check1/Check2
int indexi = 0;
int indexj = MAX_COUNT - 1;
int sum = 0;
int IS_DEC_INDEX = 1;
int ab = 0;
unsigned __int64 a = 0, b = 0;
unsigned char sn[85];//969//=15*61+54//
for (size_t i = 0; i < strlen(SN); i++)
{
//char *p = ;
//假设字符都没问题
int j = strchr(charTab, SN[i]) - charTab;
sum += j;
for (int k = 0; k < j; k++)
{
if (IS_DEC_INDEX == 0)
{
if (ab == 0) {a += Init[indexi];} else b += Init[indexi];
indexi++;
}
else
{
if (ab == 0) {a += Init[indexj];} else b += Init[indexj];
indexj--;
}
ab = (ab == 0) ? 1: 0;
}
IS_DEC_INDEX = (IS_DEC_INDEX == 0) ? 1 : 0;
}
这个就是a需要用到的索引。
其它0-1009,不包含在内的,是b要用到的索引。
// unsigned __int64 a = 0;
// for (int i = 0; i < 505; i++)
// {
// a += Init[aa[i]];
// }
b与这类似。
字符控制后,//i = 470, j = 510
471-509之间的数据不用管
char charTab[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";//62=0x3E
//[1-3D]
只能取1-3D闭区间的值, 0不行,间隔为2个可以认为是同一个序列号范围控制;
突然为1,那一定序列号变索引了,关键把构成a,b的组合,转成序列号。
那个关键过程,每次调用a+; b+; a+; b+;这么切换;一旦出现不是这样的序列,序列号肯定要做下一个字符了。
红色是表示,一次a+, 一次b+,进行切换;
绿色则表示序列号索引切换了。
最后不解释了直接贴码大家好好看看吧:
// k7.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
//#include <set>
//#include <list>
#include <vector>
#include <algorithm>
#define MAX_COUNT 1010
unsigned int Init[1010];
//一维数组
unsigned __int64 Buf1[1010*1010];
unsigned __int64 Buf2[1010*1010];
//二维数组
unsigned __int64 Buff1[1010][1010];
unsigned __int64 Buff2[1010][1010];
//二维数组, 非递归
unsigned __int64 Bufff1[1010][1010];
unsigned __int64 Bufff2[1010][1010];
//求解构成a=c使用
using namespace std;
unsigned __int64 fff[MAX_COUNT][MAX_COUNT];
unsigned __int64 ggg[MAX_COUNT][MAX_COUNT];
vector<int>hhh[MAX_COUNT][MAX_COUNT];
//////////////////////////////////////////////////////////////////////////
//一维数组
unsigned __int64 Calc2(int minv, int maxv, unsigned __int64 *Buf, unsigned int *Init)
{
if (minv > maxv)
{
return 0;
}
if (Buf[minv * MAX_COUNT + maxv] != 0xFFFFFFFFFFFFFFFF)
{
return Buf[minv * MAX_COUNT + maxv];
}
if (minv == maxv)
{
Buf[minv * MAX_COUNT + maxv] = Init[minv];
return Buf[minv * MAX_COUNT + maxv];
}
Buf[minv * MAX_COUNT + maxv] = Calc2(minv + 1, maxv, Buf, Init) + Init[minv];
return Buf[minv * MAX_COUNT + maxv];
}
unsigned __int64 Calc1(int minv, int maxv, unsigned __int64 *Buf, unsigned int *Init)
{
if (minv > maxv)
{
return 0;
}
if (Buf[minv * MAX_COUNT + maxv] != 0xFFFFFFFFFFFFFFFF)
{
return Buf[minv * MAX_COUNT + maxv];
}
if (minv == maxv)
{
Buf[minv * MAX_COUNT + maxv] = Init[minv];
return Buf[minv * MAX_COUNT + maxv];
}
unsigned __int64 v1 = Calc1(minv + 1, maxv, Buf, Init);
unsigned __int64 v2 = Calc1(minv, maxv - 1, Buf, Init);
unsigned __int64 v3;
if (v2 < v1)
{
v3 = Calc1(minv, maxv - 1, Buf, Init);
}
else
{
v3 = Calc1(minv + 1, maxv, Buf, Init);
}
Buf[minv * MAX_COUNT + maxv] = Calc2(minv, maxv, &Buf2[0], Init) - v3;
return Buf[minv * MAX_COUNT + maxv];
} //////////////////////////////////////////////////////////////////////////
//二维数组
unsigned __int64 Calc4(int minv, int maxv, unsigned __int64 Buf[][MAX_COUNT], unsigned int *Init)
{
if (minv > maxv) return 0;
if (Buf[minv][maxv] != 0xFFFFFFFFFFFFFFFF) return Buf[minv][maxv];
if (minv == maxv)
{
Buf[minv][maxv] = Init[minv];
return Buf[minv][maxv];
}
Buf[minv][maxv] = Calc4(minv + 1, maxv, Buf, Init) + Init[minv];
return Buf[minv][maxv];
}
unsigned __int64 Calc3(int minv, int maxv, unsigned __int64 Buf[][MAX_COUNT], unsigned int *Init)
{
if (minv > maxv) return 0;
if (Buf[minv][maxv] != 0xFFFFFFFFFFFFFFFF) return Buf[minv][maxv];
if (minv == maxv)
{
Buf[minv][maxv] = Init[minv];
return Buf[minv][maxv];
}
unsigned __int64 v1 = Calc3(minv + 1, maxv, Buf, Init);
unsigned __int64 v2 = Calc3(minv, maxv - 1, Buf, Init);
unsigned __int64 v3;
if (v2 < v1)
{
v3 = Calc3(minv, maxv - 1, Buf, Init);
}
else
{
v3 = Calc3(minv + 1, maxv, Buf, Init);
}
Buf[minv][maxv] = Calc4(minv, maxv, Buff2, Init) - v3;
return Buf[minv][maxv];
} char charTab[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";//62=0x3E
首先看检查序列号函数
bool check_serial(const char *SN)
{
//0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF12345
//BBBBBBBBBFBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
//BCBCBCBCBFCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBBBBBBBBBBBBBBBBBBBBBBBB
//10+26+26=62个字符, [0-61]
//1-61
//0042E220 c=000000FEF635D82A d=000000FAD883E964
//sum=000001F9CEB9C18E
//////////////////////////////////////////////////////////////////////////
// b +=;IndexI++;
//char SN[] = "BCBCBCBCBFCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBBBBBBBBBBBBBBBBBBBBBBBB";
//check0//0040284B
if (strlen(SN) != 85) return false;
if (SN[9] != 'F') return false;
//////////////////////////////////////////////////////////////////////////
//序列号处理//0040284B
//1010
//969
//1010-969=41
//checkserial
int indexi = 0;
int indexj = MAX_COUNT - 1;
int sum = 0;
int IS_DEC_INDEX = 1;
int ab = 0;
unsigned __int64 a = 0, b = 0;
unsigned char sn[85];//969//=15*61+54//
for (size_t i = 0; i < strlen(SN); i++)
{
//char *p = ;
//假设字符都没问题
//004027DC//对每个字符进行处理
int j = strchr(charTab, SN[i]) - charTab;
sum += j;
for (int k = 0; k < j; k++)
{
if (IS_DEC_INDEX == 0)
{
if (ab == 0) {a += Init[indexi];} else b += Init[indexi];
indexi++;
}
else
{
if (ab == 0) {a += Init[indexj];} else b += Init[indexj];
indexj--;
}
ab = (ab == 0) ? 1: 0;
}
IS_DEC_INDEX = (IS_DEC_INDEX == 0) ? 1 : 0;
}
//////////////////////////////////////////////////////////////////////////
//后面的数据需要继续处理//004028D0
while (indexi <= indexj)
{
if (IS_DEC_INDEX == 0)
{
if (ab == 0) {a += Init[indexi];} else b += Init[indexi];
indexi++;//后来全在这个里面, 且第一次ab=1;
}
else
{
if (ab == 0) {a += Init[indexj];} else b += Init[indexj];
indexj--;
}
ab = (ab == 0) ? 1: 0;
}
//c=000000FEF635D82A d=000000FAD883E964 //c-d=41DB1EEC6 c^d=42EB6314E
//0042E200 a=000000FC08D3A291 b=000000FDC5E61EFD
//i = 470, j = 510
//sa=000000F4B9B59850, sb=000000F060FD60E8
/*
//Check0
lenSN= 0x55
SN[9] = 'F';
//Check1//004029D3
sum + d + c - sum - sum == 0 => d + c = sum //OK
//Check2//00402930
sum == 969;
i = 470;
j = 510;
//Check3//0040295F
num_c + num_b - num_a - num_d == 0 => c - d = a - b; a=c; b= d那就OK
//Check4//00402999
num_d == (num_c ^ num_b ^ num_a) = > c ^ d = a ^ b
//最简单的答案就是a=c; b=d;
if a =5E77DDEBB, b=1C9CBEFF5 => a-b= 41DB1EEC6 a^b = 42EB6314E
*/
//上诉条件全部满足则返回成功
return true;
} int _tmain(int argc, _TCHAR* argv[])
{
//////////////////////////////////////////////////////////////////////////
//数据初始化, //004026CD
unsigned __int64 s = 0;
Init[0] = 0x6C35B49D;
Init[1] = 0xA645500D;
Init[2] = 0xCB9E682E;
s = Init[0];
s += Init[1];
s += Init[2];
for (int i = 3; i < MAX_COUNT; i++)
{
Init[i] = Init[i-3] + Init[i-2] * Init[i-1];
s += Init[i];
}
//[1-3D]
//////////////////////////////////////////////////////////////////////////
//00402C34//以为数组方式初始化, 递归调用
memset( Buf1, 0xFF, sizeof(Buf1));
memset( Buf2, 0xFF, sizeof(Buf2));
unsigned __int64 c = Calc1( 0, MAX_COUNT - 1, &Buf1[0], &Init[0]);//=a ok
unsigned __int64 e = Calc2( 0, MAX_COUNT - 1, &Buf2[0], &Init[0]);;
unsigned __int64 d = e - c;//=b ok
//转成2维数组[1010][1010]
memcpy(Buff1, Buf1, sizeof(Buff1));
memcpy(Buff2, Buf2, sizeof(Buff2));
//////////////////////////////////////////////////////////////////////////
//二维数组的方式初始化, 递归调用(源程序可能使用这个办法)
//memset( Buff1, 0xFF, sizeof(Buff1));
//memset( Buff2, 0xFF, sizeof(Buff2));
//unsigned __int64 kc = Calc3( 0, MAX_COUNT - 1, Buff1, &Init[0]);//=a ok
//unsigned __int64 ke = Calc4( 0, MAX_COUNT - 1, Buff2, &Init[0]);;
//unsigned __int64 kd = ke -kc;
//经比较两种方式数据一致
//if (memcmp(Buf1, Buff1, sizeof(Buf1)) == 0)
//{
// printf("ok");
//}
//else
//{
// printf("failed");
//}
//////////////////////////////////////////////////////////////////////////
//去除递归调用, 二维数组初始化, 便于理解原理
//////////////////////////////////////////////////////////////////////////
//非递归调用
memset( Bufff1, 0xFF, sizeof(Bufff1));
memset( Bufff2, 0xFF, sizeof(Bufff2));
for (int i = MAX_COUNT-1; i >= 1; i--)
{
Bufff2[i][i] = Init[i];
for (int j = i - 1; j >= 0; j--)
{
Bufff2[j][i] = Bufff2[j+1][i] + Init[j];
}
}
for (int i = 0; i < MAX_COUNT; i++)
{
Bufff1[i][i] = Init[i];
}
for (int i = 0; i < MAX_COUNT - 1; i++)
{
for (int j = 0; j < MAX_COUNT- i - 1; j++)
{
unsigned __int64 v1 = Bufff1[j] [j+i];
unsigned __int64 v2 = Bufff1[j+1] [j+i+1];
unsigned __int64 v3;
if (v2 < v1)
{
v3 = v2;
}
else
{
v3 = v1;
}
Bufff1[j][j+i+1] = Bufff2[j][j+i+1] - v3;
}
}
//////////////////////////////////////////////////////////////////////////
//原理知道了, 计算c=[0][1009]是由哪些数组累加成的
//////////////////////////////////////////////////////////////////////////
//求解a=c的构成
memset(fff, 0xFF, sizeof(fff));
memset(ggg, 0xFF, sizeof(ggg));
/*
Buff2[i][j] = Buff2[i+ 1, j] + Init[i]
= Buff2[i+ 2, j] + Init[i+1] + Init[i]
= ...
= Init[j]+[]+[]+[i]
*/
for (int i = 0; i < MAX_COUNT; i++)
{
for (int j = 1; j < MAX_COUNT; j++)
{
if (i > j) continue;
unsigned __int64 aa = 0;
for (int k = i; k <= j; k++)
{
aa += Init[k];
}
fff[i][j] = aa;
}
} for (int i = 0; i < MAX_COUNT; i++)
{
ggg[i][i] = Init[i];
//list/set太耗内存了
hhh[i][i].push_back(i);//list/vector
}
for (int i = 0; i < MAX_COUNT - 1; i++)
{
for (int j = 0; j < MAX_COUNT- i - 1; j++)
{
unsigned __int64 v1 = ggg[j] [j+i];
unsigned __int64 v2 = ggg[j+1] [j+i+1];
unsigned __int64 v3;
if (v2 < v1)
{
v3 = v2;
//[ j+1,j+ 2,...j+i+1]
//[j,j+1,....j+i+1]
//hhh[j+1][j+i+1]
//hhh[j][j+i+1].push_back(j);
//hhh[j][j+i+1] -= hhh[0][0];
for (int k = j; k <= j + i + 1; k++)
{
if (find(hhh[j+1] [j+i+1].begin(), hhh[j+1] [j+i+1].end(), k) == hhh[j+1] [j+i+1].end())
{
hhh[j][j+i+1].push_back( k );
}
}
}
else
{
v3 = v1;
//ggg[j] [j+i];
//hhh[j][j+i+1].push_back(j+i+1);
for (int k = j; k <= j + i + 1; k++)
{
if (find(hhh[j] [j+i].begin(), hhh[j] [j+i].end(), k) == hhh[j] [j+i].end())
{
hhh[j][j+i+1].push_back( k );
}
}
}
ggg[j][j+i+1] = fff[j][j+i+1] - v3;
}
}
for (size_t i = 0; i < hhh[0][1009].size(); i++)
{
printf("%d,", hhh[0][1009][i]);
}
这是求解组成c=a的所有数据索引。
c=a=Buff1[0][1090];
intaa[]= 1,3,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,129,131,133,135,137,138,140,142,144,146,148,150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,202,204,206,208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,238,240,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270,272,274,276,278,280,282,284,286,288,290,292,294,296,298,300,302,304,306,308,310,312,314,316,318,320,322,324,326,328,330,332,334,336,338,340,342,344,346,348,350,352,354,356,358,360,362,364,366,368,370,372,374,376,378,380,382,384,386,387,389,391,393,395,397,399,401,403,405,407,409,411,413,415,417,419,421,423,425,427,429,431,433,435,437,439,441,443,445,447,449,451,453,455,457,459,461,463,465,467,469,471,473,475,477,479,481,483,485,487,489,491,493,495,497,499,501,503,505,507,509,511,513,515,517,519,521,523,525,527,529,531,533,535,537,539,541,543,545,547,549,551,553,555,557,559,561,563,565,567,569,571,573,575,577,579,581,583,585,587,589,591,593,595,597,599,601,603,605,607,609,611,613,615,617,619,621,623,625,627,629,631,633,635,637,639,641,643,645,647,649,651,653,655,657,659,661,663,665,667,669,671,673,675,677,679,681,683,685,687,689,691,693,695,697,699,701,703,705,707,709,711,713,716,718,720,722,724,726,728,730,732,734,736,738,740,742,744,746,748,750,752,754,756,758,760,762,764,766,768,770,772,774,776,778,780,782,784,786,788,790,792,794,796,798,800,802,804,806,808,810,812,814,816,818,820,822,824,826,828,830,832,834,836,838,840,842,844,846,848,850,852,854,856,858,860,862,864,866,868,870,872,874,876,878,880,883,885,887,889,891,893,895,897,899,901,903,905,907,909,911,913,915,917,919,921,923,925,927,930,932,934,936,938,940,942,944,946,948,950,952,954,956,958,960,962,964,966,968,970,972,974,976,978,980,982,984,986,988,990,992,994,996,998,1001,1003,1005,1007,1009
就是这组数据构成了a=c, 其余的数据组成了b=d;
for (size_t i = 0; i < hhh[0][1009].size(); i++)
{
printf("%d,", hhh[0][1009][i]);
}
//虽然知道了//程序仍不知道怎么计算结果??手工计算了~~~:(
//
int vv[33] = {
9, 4, 1, 53, 29, 40, 42, 41, 47, 15,
40, 58, 40, 58, 40, 58, 40, 58, 6, 2,
1, 1, 18, 8, 6, 8, 6, 8, 6, 2,
6, 2, 6
};
for (int i = 0; i < 85; i++)
{
if (i >= 33)
{
if (i & 1)
{printf("%c", charTab[2]);}
else
{printf("%c", charTab[6]);}
}
else
{
printf("%c", charTab[vv[i]]);
}
} //////////////////////////////////////////////////////////////////////////
//检查序列号
check_serial("941rTegflFcwgwewew6211I86868646262626262626262626262626262626262626262626262626262626"); return 0;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
上传的附件: