Tags: obfuscated rev 

Rating:

The problem gives a c source full of macros and ascii art.

First get the preprocessing result using 'gcc -E' or 'gcc --save-temps', then format it using tools like indent. ignore the huge array, you will get some basic functions.

/* simple linked list */
struct s {
    struct s*s;
};
/* list insert head */
static struct s *z ( struct s*n) {
    struct s*t=n ;
    n =malloc (sizeof(struct s)) ;
    n-> s= t;
    return n ;
}
/* list length */
static int pi (struct s *n ) {
    int x =0;
    for(; n ; n=n-> s,x++) ;
    return x;;
}
/* create list of size n */
static struct s*ip(int n) {
    struct s*s=0;
    for(int i=0; i<n; i++) {
        s=z(s);
    }
    return s;
}
/* compare length of two lists, return 0 if equal */
static int pc(struct s*n,struct s*o) {
    for(; n&&o; n=n->s,o=o->s);
    return n||o;
}
/* simple per-byte transform, only 896/1024 bytes are transformed */ 
static void df(int*p) {
    register n=128;
    switch(1024%8) {
    case 0:
        do {
            *p^=0x63 ; p++;
        case 7:
            *p^=48; p++;
        case 6:
        case 5:
            *p<<=4; p++;
        case 4:
            *p<<=2; p++;
        case 3:
            *p*=55; p++;
        case 2:
            *p-=-97; p++;
        case 1:
            *p+=44; p++ ;
        }
        while(--n>0);
    }
}
/* simple copy */
static void dc(int*d,char*s) {
    register int n=(1024+7)/8;
    switch (1024%8) {
    case 0:
        do {
            *d++=*s++;
        case 7: *d++=*s++;
        case 6: *d++=*s++;
        case 5: *d++=*s++;
        case 4: *d++=*s++;
        case 3: *d++=*s++;
        case 2: *d++=*s++;
        case 1: *d++=*s++;
        }
        while(--n>0);
    }
}
/* checker */
static int ch (int*n) {
    struct s*a[1024]= {...};
    struct s*p;
    for(int i=0; i<1024; i++) {
        p=ip(i[n]);      /* create list of given length */
        if(pc(p,i[a])) { /* compare list length with given one */
            return 0;
        }
    }
    return 1;
}
int main(void) {
    static char b[1024];
    static int i[1024];
    fgets(b,1024, stdin);
    dc(i,b);             /* copy */
    df(i);               /* transform */
    return !!!!!!!!!!!!!!!!!!!!!!!ch(i);  /* compare */
}

The rest is simple:

  1. calculate the length of each list in a;
  2. perform reverse transform of df.
# counting list lengths (s is the string representation of the array a in function ch(). 
v = [x.count('z') for x in s.split(',')]
# reverse transform of df
o, i = '', 0
for x in v[:-128]:
    if i == 0:
        o += chr(x^0x63)
    elif i == 1:
        o += chr(x^48)
    elif i == 2:
        o += chr(x>>4)
    elif i == 3:
        o += chr(x>>2)
    elif i == 4:
        o += chr(x/55)
    elif i == 5:
        o += chr(x-97)
print o