Picture Lock WriteUp
已经看不懂自己写的什么东西了
大概就是要先弄懂利用有限域 \(GF\) 进行可逆乘法的操作,然后暴力枚举解出一个 \(key\),最后用这个 \(key\) 把原图像解出来就行了
/*#include<bits/stdc++.h>
using namespace std;
const int N=400;
int T,n;
int a[4]={1,3,3,7},b[4];
int f[N][N];
int gflog[N],gfilog[N];
int add(int a,int b){
return a^b;
}
int sub(int a,int b){
return add(a,b);
}
unsigned char mul(char a1,unsigned char a2){
unsigned char v5 = 0;
while ( a1 && a2 )
{
if ( (a2 & 1) != 0 )
v5 ^= a1;
if (a1 >= 0)
a1 *= 2;
else
a1 = (2 * a1) ^ 0x1D;
a2 >>= 1;
}
return v5;
}
unsigned char kp(char x,unsigned char p){
unsigned char res=1;
while(p){
//cout<<p<<endl;
if(p&1) res=mul(res,x);
x=mul(x,x);
p>>=1;
}
return res;
}
void init(){
for(int i=0;i<255;++i){
gfilog[i]=(unsigned char)kp(2,i);
gflog[gfilog[i]]=i;
}
}
int _mul(int a1,int a2){
return gfilog[(gflog[a1]+gflog[a2])%255];
}
int _div(int a1,int a2){
return gfilog[(gflog[a1]-gflog[a2]+255)%255];
}
void gauss(){
n=4;
for(int i=1;i<=n;++i) f[i][n+1]=b[i-1];
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
int k=(j-i+4)%4;
f[i][j]=a[k];
}
}
for(int i=1;i<=n;++i){
int r=i;
for(int j=i;j<=n;++j){
if(f[r][i]<f[j][i]) r=j;
}
if(!f[r][i]){
printf("No Solution");
return;
}
if(i!=r) swap(f[r],f[i]);
int tmp=f[i][i];
for(int j=i;j<=n+1;++j) f[i][j]=_div(f[i][j],tmp);
for(int j=1;j<=n;++j){
if(j==i) continue;
int tmp=f[j][i];
for(int k=1;k<=n+1;++k) f[j][k]=sub(f[j][k],_mul(f[i][k],tmp));
}
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n+1;++j) cout<<f[i][j]<<" ";
cout<<endl;
}
}
void solve() {
for(int i=0;i<4;++i) cin>>b[i];
init();
gauss();
}
int main() {
solve();
return 0;
}*/
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int T,n;
#define _BYTE char
#define _DWORD int
#define BYTE char
#define WORD short
#define DWORD int
#define DWORD_PTR int
#define LOBYTE(w) ((char) (w & 0xff))
#define HIBYTE(w) ((char) (( (w >> 24) & 0xff)))
unsigned char src[N],s[N],in[N],stk[N];
unsigned char ans[8]={0x16,0x1A ,0xFC ,0x29 ,0xF7 ,0x22 ,0x4D ,0x5A};
__int64 __fastcall sub_40094D(char a1, unsigned __int8 a2)
{
unsigned __int8 v5; // [rsp+17h] [rbp-1h]
v5 = 0;
while ( a1 && a2 )
{
if ( (a2 & 1) != 0 )
v5 ^= a1;
if ( a1 >= 0 )
a1 *= 2;
else
a1 = (2 * a1) ^ 0x1D;
a2 >>= 1;
}
return v5;
}
char __fastcall sub_400936(char a1, char a2)
{
return a2 ^ a1;
}
void sub_4009A1(char *a1, unsigned int a2)
{
unsigned __int8 v2; // al
unsigned __int8 v4; // [rsp+1Fh] [rbp-31h]
unsigned int i; // [rsp+20h] [rbp-30h]
int j; // [rsp+24h] [rbp-2Ch]
int k; // [rsp+28h] [rbp-28h]
int m; // [rsp+2Ch] [rbp-24h]
int v9[4]; // [rsp+30h] [rbp-20h]
int v10[2]; // [rsp+40h] [rbp-10h]
v9[0] = 117637889;
v10[0] = 0;
for ( i = 0; a2 >> 2 >= i; ++i )
{
if ( a2 >> 2 == i )
{
memcpy((char *)src + (int)(4 * i), &a1[4 * i], a2 & 3);
}
else
{
for ( j = 0; j <= 3; ++j )
{
v4 = 0;
for ( k = 0; k <= 3; ++k )
{
//cout<<(int)*((unsigned __int8 *)v9 + k)<<" ";
v2 = sub_40094D(*((unsigned __int8 *)v9 + k), (unsigned __int8)a1[4 * i + k]);
v4 = sub_400936(v4, v2);
}
//cout<<endl;
*((_BYTE *)src + (int)(4 * i + j)) = v4;
for ( m = 3; m >= 0; --m )
{
if ( m )
*((_BYTE *)v10 + m) = *((_BYTE *)v9 + m - 1);
else{
for(int k=0;k<8;++k){
v10[0]=v10[0]^(v10[0]&(1<<k));
}
v10[0] |= HIBYTE(v9[0]);
}
}
v9[0] = v10[0];
}
}
}
memcpy(a1, src, a2);
}
int a[4]={1,3,3,7},b[4];
int f[400][400];
int gflog[400],gfilog[400];
int add(int a,int b){
return a^b;
}
int sub(int a,int b){
return add(a,b);
}
unsigned char mul(char a1,unsigned char a2){
unsigned char v5 = 0;
while ( a1 && a2 )
{
if ( (a2 & 1) != 0 )
v5 ^= a1;
if (a1 >= 0)
a1 *= 2;
else
a1 = (2 * a1) ^ 0x1D;
a2 >>= 1;
}
return v5;
}
unsigned char kp(char x,unsigned char p){
unsigned char res=1;
while(p){
//cout<<p<<endl;
if(p&1) res=mul(res,x);
x=mul(x,x);
p>>=1;
}
return res;
}
void init(){
for(int i=0;i<255;++i){
gfilog[i]=(unsigned char)kp(2,i);
gflog[gfilog[i]]=i;
}
}
int _mul(int a1,int a2){
return gfilog[(gflog[a1]+gflog[a2])%255];
}
int _div(int a1,int a2){
return gfilog[(gflog[a1]-gflog[a2]+255)%255];
}
void gauss(){
n=4;
for(int i=1;i<=n;++i) f[i][n+1]=b[i-1];
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
int k=(j-i+4)%4;
f[i][j]=a[k];
}
}
for(int i=1;i<=n;++i){
int r=i;
for(int j=i;j<=n;++j){
if(f[r][i]<f[j][i]) r=j;
}
if(!f[r][i]){
printf("No Solution");
return;
}
if(i!=r) swap(f[r],f[i]);
int tmp=f[i][i];
for(int j=i;j<=n+1;++j) f[i][j]=_div(f[i][j],tmp);
for(int j=1;j<=n;++j){
if(j==i) continue;
int tmp=f[j][i];
for(int k=1;k<=n+1;++k) f[j][k]=sub(f[j][k],_mul(f[i][k],tmp));
}
}
// for(int i=1;i<=n;++i){
// for(int j=1;j<=n+1;++j) cout<<f[i][j]<<" ";
// cout<<endl;
// }
}
/*
void reverse_sub_4009A1(char *a1, unsigned int a2)
{
unsigned __int8 v2;
unsigned __int8 v4;
int j;
int k;
int m;
int v9[4];
int v10[2];
v9[0] = 117637889;
v10[0] = 0;
memcpy(src, a1, a2);
for (int i = (a2 >> 2); i >= 0; --i)
{
if (a2 >> 2 == i)
{
memcpy( (char *)src + (int)(4 * i),&a1[4 * i], a2 & 3);
}
else
{
for (j = 3; j >= 0; --j)
{
for (m = 0; m <= 3; ++m)
{
if (m == 3){
for(int k=24;k<32;++k){
v10[0]=v10[0]^(v10[0]&(1ll<<k));
}
v10[0] |= (unsigned int)(LOBYTE(v9[0])<<24);
}
else{
*((_BYTE *)v10 + m) = *((_BYTE *)v9 + m + 1);
}
}
v9[0]=v10[0];
v4 = a1[4 * i + j];
for (k = 0; k <= 3; ++k)
{
//cout<<(int)*((unsigned __int8 *)v9 + k)<<" ";
v2 = sub_40094D(*((unsigned __int8 *)v9 + k), v4);
v4 = sub_400936(v4, v2);
}
//cout<<endl;
*((_BYTE *)src + (int)(4 * i + j))= v4;
//printf("%x ",v4);
}
}
}
memcpy(a1, src, a2);
}
*/
void reverse_sub_4009A1(char *a1, unsigned int a2)
{
unsigned __int8 v2;
unsigned __int8 v4;
int j;
int k;
int m;
int v9[4];
int v10[2];
v9[0] = 117637889;
v10[0] = 0;
memcpy(src, a1, a2);
init();
for (int i = 0; i <= (a2 >> 2); ++i)
{
if (a2 >> 2 == i)
{
memcpy( (char *)src + (int)(4 * i),&a1[4 * i], a2 & 3);
}
else
{
//cout<<"!"<<endl;
for(j = 0; j <= 3; ++j){
b[j] = (unsigned char)a1[4 * i + j];
//cout<<b[j]<<" ";
}
//cout<<endl;
gauss();
for(j = 0; j <= 3; ++j){
*((_BYTE *)src + (int)(4 * i + j)) = (unsigned char)f[j+1][5];
//cout<<(int)(unsigned char)*((_BYTE *)src + (int)(4 * i + j))<<" ";
}
//cout<<endl;
}
}
memcpy(a1, src, a2);
}
void *__fastcall sub_400B5A(_BYTE *a1, unsigned int a2, __int64 a3, int a4, int a5)
{
unsigned int i; // [rsp+28h] [rbp-18h]
int j; // [rsp+2Ch] [rbp-14h]
int k; // [rsp+30h] [rbp-10h]
unsigned int m; // [rsp+34h] [rbp-Ch]
int v12; // [rsp+3Ch] [rbp-4h]
v12 = a2 & 7;
for ( i = 0; a2 >> 3 >= i; ++i )
{
if ( a2 >> 3 == i )
{
if ( v12 <= a4 )
{
memcpy((char *)src + (int)(8 * i), &a1[8 * i], a2 & 7);
break;
}
a5 = v12 - a4;
}
for ( j = 0; j < a5; ++j )
*((_BYTE *)src + (int)(8 * i + j)) = a1[j + 8 * i + a4];
for ( k = 0; k < a4; ++k )
*((_BYTE *)src + (int)(k + 8 * i + a5)) = a1[8 * i + k];
}
for ( m = 0; m < a2; ++m ){
//cout<<(int)*(_BYTE *)(src+(int)m)<<" ";
*((_BYTE *)src + (int)m) ^= *(_BYTE *)((int)m % 8 + a3);
//cout<<(int)*(_BYTE *)((int)m % 8 + a3)<<endl;
}
//for ( m = 0; m < 8; ++m )cout<<(int)*(_BYTE *)(src+(int)m)<<" ";
//cout<<endl;
return memcpy(a1, src, a2);
}
void reverse_sub_400B5A(_BYTE *a1, unsigned int a2, __int64 a3, int a4, int a5)
{
unsigned int i, m;
int j, k;
int v12 = a2 & 7;
// 逆向第一步:恢复异或操作
for (m = 0; m < a2; ++m)
a1[m] ^= *(_BYTE *)((int)m % 8 + a3);
// 逆向第二步:恢复字节顺序
for (i = 0; a2 >> 3 >= i; ++i)
{
if (a2 >> 3 == i)
{
if (v12 <= a4)
{
memcpy(&src[8 * i], (char *)a1 + (int)(8 * i), a2 & 7);
break;
}
a5 = v12 - a4;
}
for (j = 0; j < a5; ++j)
src[j + 8 * i + a4] = *((_BYTE *)a1 + (int)(8 * i + j));
for (k = 0; k < a4; ++k)
src[8 * i + k] = *((_BYTE *)a1 + (int)(k + 8 * i + a5));
}
// 逆向第三步:将 src 中的数据复制回 a1
memcpy(a1, src, a2);
}
int get_hex(){
int ans=0;
if(strlen((char *)in)==2){
if(in[0]>='a' && in[0]<='z'){
int c=in[0]-'a'+10;
ans+=c*16;
}else{
int c=in[0]-'0';
ans+=c*16;
}
if(in[1]>='a' && in[1]<='z'){
int c=in[1]-'a'+10;
ans+=c;
}else{
int c=in[1]-'0';
ans+=c;
}
}else{
if(in[0]>='a' && in[0]<='z'){
int c=in[0]-'a'+10;
ans+=c;
}else{
int c=in[0]-'0';
ans+=c;
}
}
return ans;
}
void output(__int64 a1, unsigned int a2){
//int len=a2>>4;
int len = 1;
for(int i=0;i<len;++i){
for(int j=0;j<16;++j){
printf("%x ",(unsigned char)*(_BYTE *)(a1 + 16 * i + j));
}
printf("\n");
}
printf("\n");
printf("\n");
}
void sub_400D1D(__int64 a1, unsigned int a2,char* v3)
{
//char v3[8];
char v4; // [rsp+18h] [rbp-18h]
unsigned __int64 v5; // [rsp+28h] [rbp-8h]
v4 = 0;
// freopen("jpg.txt","r",stdin);
// int cnt=0;
// for(int i=0,tmp;i<a2;++i){
// scanf("%s",in);
// tmp = get_hex();
// *(_BYTE *)(a1 + cnt++) = (unsigned char)(tmp);
// }
//
// freopen("key.txt","r",stdin);
// puts("Please enter your key:");
// scanf("%8s", &v3);
for(int i=0;i<8;++i){
*(_BYTE *)(a1 + i)=0;
}
// for(int i=0;i<8;++i) cout<<(int)v3[i]<<" ";
// cout<<endl;
sub_400B5A((_BYTE *)a1, a2, (__int64)v3, 4LL, 4LL);
//output(a1,a2);
sub_4009A1((_BYTE *)a1, a2);
//output(a1,a2);
sub_400B5A((_BYTE *)a1, a2, (__int64)v3, 2LL, 6LL);
//output(a1,a2);
int flag=1;
for(int i=0;i<8;++i){
//if(i==4 || i==5) continue;
if((unsigned char)*(_BYTE *)(a1 + i) != (unsigned char)*(_BYTE *)(ans + i)) flag = 0;
}
// for(int i=0;i<8;++i) printf("%x ",(unsigned char)*(_BYTE *)(a1 + i));
// cout<<endl;
if(flag){
for(int i=0;i<8;++i) cout<<v3[i];
cout<<endl;
for(int i=0;i<8;++i) printf("%x ",(unsigned char)*(_BYTE *)(a1 + i));
cout<<endl;
}
}
void reverse_sub_400D1D(__int64 a1, unsigned int a2,unsigned char x1,unsigned char x2)
{
char v3[8];
char v4; // [rsp+18h] [rbp-18h]
unsigned __int64 v5; // [rsp+28h] [rbp-8h]
v4 = 0;
freopen("new.txt","r",stdin);
int cnt=0;
for(int i=0,tmp;i<a2;++i){
scanf("%s",in);
tmp = get_hex();
*(_BYTE *)(a1 + cnt++) = (unsigned char)(tmp);
}
for(int i=0;i<8;++i) v3[i]=0x30+i;
v3[2]=x1,v3[4]=x2;
reverse_sub_400B5A((_BYTE *)a1, a2, (__int64)v3, 2LL, 6LL);
reverse_sub_4009A1((_BYTE *)a1, a2);
reverse_sub_400B5A((_BYTE *)a1, a2, (__int64)v3, 4LL, 4LL);
// for(int i=0;i<a2;++i){
// printf("%x ",(unsigned char)*(_BYTE *)(a1 + i));
// }
//freopen("flag.txt","w",stdout);
}
void reverse(__int64 a1, unsigned int a2)
{
//char v3[8];
char v4; // [rsp+18h] [rbp-18h]
unsigned __int64 v5; // [rsp+28h] [rbp-8h]
v4 = 0;
freopen("new.txt","r",stdin);
int cnt=0;
for(int i=0,tmp;i<a2;++i){
scanf("%s",in);
tmp = get_hex();
*(_BYTE *)(a1 + cnt++) = (unsigned char)(tmp);
}
char v3[10]="2019ACTF";
reverse_sub_400B5A((_BYTE *)a1, a2, (__int64)&v3, 2LL, 6LL);
reverse_sub_4009A1((_BYTE *)a1, a2);
reverse_sub_400B5A((_BYTE *)a1, a2, (__int64)&v3, 4LL, 4LL);
for(int i=0;i<a2;++i){
printf("%x ",(unsigned char)*(_BYTE *)(a1 + i));
}
}
void dfs(int step){
if(step==6){
sub_400D1D((__int64)s,8,(char *)stk);
return;
}
for(int i=33;i<=126;++i){
stk[step]=(unsigned char)i;
dfs(step+1);
}
// for(int i='A';i<='Z';++i){
// stk[step]=(unsigned char)i;
// dfs(step+1);
// }
// for(int i='a';i<='z';++i){
// stk[step]=(unsigned char)i;
// dfs(step+1);
// }
}
void solve() {
freopen("qua_key_2.txt","r",stdin);
//freopen("qua_key.txt","w",stdout);
int len=0x5A11ll;
for(int i=1;i<=103;++i){
gets((char *)stk);
//printf("%s\n",stk);
dfs(4);
}
}
int main() {
solve();
return 0;
}
// `bh{4_O0
// 上面这个是解出来的 key
评价为数学最差的一集
reverse 里还能有 “非常好玩” 的数学
你甚至在 reverse 里做 crypto