Skip to content

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