HTTP/1.1 200 OK Date: Mon, 04 Jul 2011 03:10:59 GMT Server: Apache Last-Modified: Tue, 27 Jun 2000 18:59:23 GMT ETag: "383fd-117d-36b0de5b938c0" Accept-Ranges: bytes Content-Length: 4477 Content-Type: text/x-csrc Connection: close /* dcrp.c - scrambles and unscrambles Dreamcast-executables * * 2000 Maiwe * * contact: jlo@ludd.luth.se * */ /* Notes: * ~~~~~~ * * Dreamcast(tm) has a special method for booting regular CDs as opposed * to GDs. The executable file to be booted must be scrambled in a * certain way in order to execute properly which is what this program * does. * */ #include #include #include #include #include int main(int, char **); void usage(void); void scramble(void); void scramble2(int, char *); void copy_data(char *); void unscramble(void); void unscramble2(int, char *); void copy_data2(char *); unsigned int permutation_key = 0; unsigned short permutation_buf[0x10000]; char *input_buf; char *output_buf; int buf_pos; int data_size; int main(argc, argv) int argc; char **argv; { struct stat st_buf; FILE *ins, *outs; if (argc != 4) usage(); if (stat(argv[2], &st_buf) < 0) { fprintf(stderr, "dcrp: %s: %s\n", argv[2], strerror(errno)); exit (-1); } data_size = st_buf.st_size; if (!(input_buf = malloc(data_size))) { fprintf(stderr, "dcrp: %s\n", strerror(errno)); exit (-1); } if (!(output_buf = malloc(data_size))) { fprintf(stderr, "dcrp: %s\n", strerror(errno)); exit (-1); } ins = fopen(argv[2], "r"); if (ins == NULL) { fprintf(stderr, "dcrp: %s: %s\n", argv[2], strerror(errno)); exit (-1); } outs = fopen(argv[3], "w"); if (outs == NULL) { fprintf(stderr, "dcrp: %s: %s\n", argv[3], strerror(errno)); exit (-1); } if (fread(input_buf, data_size, 1, ins) != 1) { if (ferror(ins)) { fprintf(stderr, "dcrp: fread() failed: %s\n", strerror(errno)); exit (-1); } fprintf(stderr, "dcrp: fread() failed: not all of input file read\n"); exit (-1); } fclose(ins); if (strcmp(argv[1], "scramble") == 0) scramble(); else if (strcmp(argv[1], "unscramble") == 0) unscramble(); else usage(); if (fwrite(output_buf, data_size, 1, outs) != 1) { if (ferror(outs)) { fprintf(stderr, "dcrp: fwrite() failed: %s\n", strerror(errno)); exit (-1); } fprintf(stderr, "dcrp: fwrite() failed: not all of input file written\n"); exit (-1); } fprintf(stdout, "Done\n"); } void usage() { fprintf(stderr, "dcrp v1.1 13-Jun-2000 Maiwe\n"); fprintf(stderr, "usage: dcrp \n"); exit (-1); } void scramble() { int j; char *ptr; int align; int size = data_size; permutation_key = size & 0x0000ffff; buf_pos = 0; align = size & 0x0000001f; if (align != 0) size -= align; ptr = input_buf; j = 0x00200000; do { while (size >= j) { scramble2(j, ptr); size = size - j; ptr = ptr + ((j>>2)<<2); } j = j>>1; } while (j >= 0x20); if (align != 0) copy_data(ptr); } void scramble2(size, addr) int size; char *addr; { unsigned short *ptr = permutation_buf; int i; int bs = size>>5; unsigned short *k; unsigned short index; int m; unsigned short temp; for (i = 0; i < bs; i++) ptr[i] = i; k = &ptr[bs-1]; for (m = bs - 1; m >= 0; m--) { permutation_key = (permutation_key * 2109 + 9273) & 0x7fff; index = (((permutation_key + 0xc000) & 0xffff) * m)>>16; temp = ptr[index]; ptr[index] = *k; *k = temp; copy_data(addr + ((*k)<<5)); k--; } } void copy_data(addr) char *addr; { int i; for (i = 0; i < 0x20 && buf_pos < data_size; i++) *(output_buf + (buf_pos++)) = addr[i]; } void unscramble() { int j; char *ptr; int align; int size = data_size; permutation_key = size & 0x0000ffff; buf_pos = 0; align = size & 0x0000001f; if (align != 0) size -= align; ptr = output_buf; j = 0x00200000; do { while (size >= j) { unscramble2(j, ptr); size = size - j; ptr = ptr + ((j>>2)<<2); } j = j>>1; } while (j >= 0x20); if (align != 0) copy_data2(ptr); } void unscramble2(size, addr) int size; char *addr; { short *ptr = permutation_buf; int i; int bs = size>>5; unsigned short *k; unsigned short index; int m; unsigned short temp; for (i = 0; i < bs; i++) ptr[i] = i; k = &ptr[bs-1]; for (m = bs - 1; m >= 0; m--) { permutation_key = (permutation_key * 2109 + 9273) & 0x7fff; index = (((permutation_key + 0xc000) & 0xffff) * m)>>16; temp = ptr[index]; ptr[index] = *k; *k = temp; copy_data2(addr + ((*k)<<5)); k--; } } void copy_data2(addr) char *addr; { int i; for (i = 0; i < 0x20 && buf_pos < data_size; i++) addr[i] = *(input_buf + (buf_pos++)); }