News Uni Dev Res Blag

Crackhead

2010/11/19 - 14:14

crackhead.cpp

/* crackhead.cpp - crc32 bruteforcer
 * Copyright (C) 2010  ed <irc.rizon.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, please refer to the following URL:
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 */

#include <cstdio>
#include <cstdlib>
#include <sstream>
#define uint unsigned int

// Last modified: 2010/02/10 (february)

uint ctab[256];
uint csum(uint old, char item)
{
    return ((old >> 8) & 0x00ffffff)
        ^ ctab[(old ^ item) & 0xff];
}

void cinit()
{
    int i, j;
    uint crc, poly;
    poly = 0xedb88320L;
    for (i = 0; i < 256; i++) {
        crc = i;
        for (j = 8; j > 0; j--) {
            if (crc & 1) {
                crc = (crc >> 1) ^poly;
            }else{
                crc >>= 1;
            }
        }
        ctab[i] = crc;
    }
}

uint htoi(char *str)
{
    std::stringstream ss;
    ss << std::hex << str;
    uint x; ss >> x;
    return static_cast<int>(x);
}

int main(int argc, char **argv)
{
    if (argc != 3)
    {
        printf("crackhead by ed <tripflag%cgmail%ccom>\n",'@','.');
        printf("Usage: %s OLDCRC NEWCRC\n", argv[0]);
        printf("Append output to original file\n");
        return 1;
    }
    //crca = 0xed82cd11;
    //crcb = 0x8587d865;

    uint ca,cb,cc;
    int ia,ib,ic,id;
    uint crca = htoi(argv[1]) ^ 0xffffffff;
    uint crcb = htoi(argv[2]) ^ 0xffffffff;

    char *cp = (char *)"[email protected]";
    fprintf(stderr,"[                                                                ]\r[");
    fflush(stderr);

    cinit();
    ca = crca;
    for (ia = -1; ia < 256; ia++)
    {
        // progressbar
        int ip = (ia + 1) % 4;
        if (ip==3)
        {
            fprintf(stderr,"%c",cp[ip]);
        }
        else
        {
            fprintf(stderr, "%c%c[D", cp[ip], 27);
        }
        fflush(stderr);

        // this looks ridiculous, but I can explain why I chose this method.
        // see, pointers aren't as fast as you'd think. the extra if tests
        // and lookup time caused by keeping the checksum in an array
        // effectively doubles the processing time. so fuck that.

        if (ia >= 0)
        {
            ca = csum(crca, ia);
        }
        for (ib = -1; ib < 256; ib++)
        {
            if (ib < 0)
            {
                cb = ca;
            }
            else
            {
                cb = csum(ca, ib);
            }
            for (ic = -1; ic < 256; ic++)
            {
                if (ic < 0)
                {
                    cc = cb;
                }
                else
                {
                    cc = csum(cb, ic);
                }
                for (id = 0; id < 256; id++)
                {
                    if (csum(cc, id) == crcb)
                    {
                        fprintf(stderr, "\n");
                        if (ia >= 0) printf("%02x", ia);
                        if (ib >= 0) printf("%02x", ib);
                        if (ic >= 0) printf("%02x", ic);
                        printf("%02x\n", id);
                        return 0;
                    }
                }
            }
        }
    }
    fprintf(stderr, "\nwait what\n");
    return 1;
}

Copyright © 2010 Ed Edland