|
|
Line 3: |
Line 3: |
| ==Overview== | | ==Overview== |
| Sometimes it may be of interest to decode a service file distributed or make your own little script to clean up things. | | Sometimes it may be of interest to decode a service file distributed or make your own little script to clean up things. |
| I found this snippet of code at MPC Club and it was written by ScottJ97 (I think) | | I found this snippet of code at MPC Club and it was written by Accident 2009 (I think) |
| [http://www.mpcclub.com/forum/showthread.php?t=26187 ScottJ97's thread on MPC Club] | | [http://www.mpcclub.com/forum/showthread.php?t=26187 ScottJ97's thread on MPC Club] |
|
| |
|
| ==The Code== | | ==The Code== |
| This is just a copy and paste from the [http://pastebin.com/raw.php?i=bG8ZARUR pastebin] that most likely will die in the future | | This is an extract from [http://pastebin.com/raw.php?i=bG8ZARUR pastebin] that most likely will die in the future. |
| | [http://www.lysator.liu.se/~jonma/Dune/dsf_pack.c link] |
| <tt><pre>/* | | <tt><pre>/* |
| * | | * |
Line 29: |
Line 30: |
| * | | * |
| */ | | */ |
|
| |
| #include <stdio.h>
| |
| #include <fcntl.h>
| |
| #include <stdint.h>
| |
| #include <unistd.h>
| |
| #include <stdlib.h>
| |
| #include <string.h>
| |
|
| |
|
| |
| extern int getopt();
| |
| extern char *optarg;
| |
| extern int optind;
| |
|
| |
| static char *arg_decode = NULL;
| |
| static char *arg_encode = NULL;
| |
| static char *arg_outfilename = NULL;
| |
| static char *arg_comparename = NULL;
| |
| static int arg_verbose = 0;
| |
|
| |
|
| |
| // XOR block pulled from "shell".
| |
| static uint8_t key[] = {
| |
| 0xDA,
| |
| // Ah the KEY goes here, let's see if HDi gets angry about this....
| |
| 0x46
| |
| };
| |
|
| |
|
| |
|
| |
| static void options(char *prog)
| |
| {
| |
| printf("\n");
| |
| printf("%s - Dune .dsf encode/decode program\n\n", prog);
| |
| printf(" options:\n");
| |
| printf(" -h : display usage help (this output)\n");
| |
| printf(" -d filename : decode .dsf to outfile.gz\n");
| |
| printf(" -e filename : encode infile.gz to .dsf\n");
| |
| printf(" -o filename : specify different output filename\n");
| |
| printf(" -c filename : compare encode with file\n");
| |
| printf(" -v : verbose it up!\n");
| |
| printf("\n");
| |
| printf("Be aware that dune service files have to be named dune_service_*.dsf\n\n");
| |
| printf("Dune encoding tool by Accident.\nResist the temptation to do bad!\n\n");
| |
| exit(0);
| |
| }
| |
|
| |
|
| |
|
| |
| void arguments(int argc, char **argv)
| |
| {
| |
| int opt;
| |
|
| |
| while ((opt=getopt(argc, argv,
| |
| "hd:e:o:vc:"
| |
| )) != -1) {
| |
|
| |
| switch(opt) {
| |
|
| |
| case 'h':
| |
| options(argv[0]);
| |
| break;
| |
| case 'd':
| |
| arg_decode = strdup(optarg);
| |
| break;
| |
| case 'e':
| |
| arg_encode = strdup(optarg);
| |
| break;
| |
| case 'o':
| |
| arg_outfilename = strdup(optarg);
| |
| break;
| |
| case 'c':
| |
| arg_comparename = strdup(optarg);
| |
| break;
| |
| case 'v':
| |
| arg_verbose++;
| |
| break;
| |
| }
| |
| }
| |
|
| |
| if (!arg_decode && !arg_encode)
| |
| options(argv[0]);
| |
| }
| |
|
| |
|
| |
|
| |
|
| |
| int main(int argc, char **argv)
| |
| {
| |
| FILE *fd = NULL, *out = NULL;
| |
| uint8_t buffer[0x1000], v0,v1,a1,nv0;
| |
| uint32_t red, i, half_red;
| |
| uint32_t decode = 0;
| |
|
| |
|
| |
| arguments(argc, argv);
| |
|
| |
| if (arg_decode)
| |
| dune_decode(arg_decode);
| |
|
| |
| if (arg_encode)
| |
| dune_encode(arg_encode);
| |
|
| |
| }
| |
|
| |
|
| |
|
| |
| int dune_decode(char *infilename)
| |
| {
| |
| FILE *fd = NULL, *out = NULL;
| |
| uint8_t buffer[0x1000], v0,v1,a1,nv0;
| |
| uint32_t red, i, half_red;
| |
| uint32_t decode = 0;
| |
|
| |
|
| |
| fd = fopen(infilename, "rb");
| |
| if (!fd) goto failed;
| |
|
| |
| out = fopen(arg_outfilename ? arg_outfilename : "outfile.gz", "wb");
| |
| if (!out) goto failed;
| |
|
| |
| // read header
| |
| if (fread(buffer, 0x141, 1, fd) != 1) goto failed;
| |
|
| |
| // Read blocks:
| |
| while ((red = fread(buffer, 1, sizeof(buffer), fd)) > 0) {
| |
| // Decode block
| |
|
| |
| if (arg_verbose)
| |
| printf("read %x \n", red);
| |
|
| |
| half_red = red>>1;
| |
|
| |
| for (i = 0; i < half_red; i++) {
| |
|
| |
| v0 = buffer[i + half_red] ;
| |
| v1 = key[decode];
| |
| a1 = buffer[ i ];
| |
|
| |
| nv0 = v0;
| |
| nv0 ^= v1;
| |
| nv0 ^= a1;
| |
|
| |
| if (arg_verbose)
| |
| printf(" [%x]=%02X, xor %02X, [%x]=%02X, storing %02X\n",
| |
| i+half_red, v0, v1, i, a1, nv0);
| |
|
| |
| buffer[i] = nv0;
| |
|
| |
| decode++;
| |
| if (decode >= sizeof(key))
| |
| decode = 0;
| |
| }
| |
|
| |
|
| |
| for (i = half_red; i < red; i++) {
| |
|
| |
| v1 = key[decode];
| |
| a1 = buffer[ i ];
| |
|
| |
| nv0 = v1;
| |
| nv0 ^= a1;
| |
|
| |
| if (arg_verbose)
| |
| printf(" xor %02X, [%x]=%02X, storing %02X\n",
| |
| v1, i, a1, nv0);
| |
|
| |
| buffer[i] = nv0;
| |
|
| |
| decode++;
| |
| if (decode >= sizeof(key))
| |
| decode = 0;
| |
| }
| |
|
| |
|
| |
| // Write block
| |
| fwrite(buffer, red, 1, out);
| |
|
| |
| }
| |
|
| |
| fclose(fd);
| |
| fclose(out);
| |
|
| |
| printf("Decode complete\n");
| |
|
| |
| return 0;
| |
|
| |
| failed:
| |
| perror(":");
| |
| printf("failed\n");
| |
| if (fd)
| |
| fclose(fd);
| |
| else
| |
| fprintf(stderr, "Failed to open infile '%s'\r\n", infilename);
| |
|
| |
| if (out)
| |
| fclose(out);
| |
| else if (fd)
| |
| fprintf(stderr, "Failed to open outfile '%s'\r\n",
| |
| arg_outfilename ? arg_outfilename : "outfile.gz");
| |
|
| |
| }
| |
|
| |
|
| |
|
| |
| int dune_encode(char *infilename)
| |
| {
| |
|
| |
| FILE *fd = NULL, *out = NULL, *compare=NULL;
| |
| uint8_t buffer[0x1000], v0,v1,a1,nv0;
| |
| uint8_t compbuf[0x1000];
| |
| uint32_t red, i, half_red;
| |
| uint32_t decode = 0;
| |
| unsigned char stuff[] = {
| |
| 0x1d,0x25,0x7a,0xe4,0x27,0xff,0xe9,0x8c,0x58,0x0a,0x8b,0x18,0x70,0xbb,0xf2,0x87,
| |
| 0x3a,0xf2,0x41,0x68,0x9e,0x81,0x85,0xc6,0x82,0xe1,0x92,0x7d,0xa0,0x4e,0x5b,0xbd,
| |
| 0x73,0xd5,0xa1,0x9a,0xd4,0x8a,0x27,0x2c,0x95,0xb2,0x44,0x05,0x6d,0x37,0x8c,0xa7,
| |
| 0x29,0xce,0x0f,0xc7,0x4f,0x94,0x8e,0xd2,0x75,0x20,0x4f,0x15,0x6e,0xaa,0xd3,0xe1,0x7f
| |
| };
| |
|
| |
|
| |
| fd = fopen(infilename, "rb");
| |
| if (!fd) goto failed;
| |
|
| |
| out = fopen(arg_outfilename ? arg_outfilename : "outfile.dsf", "wb");
| |
| if (!out) goto failed;
| |
|
| |
| if (arg_comparename)
| |
| compare=fopen(arg_comparename, "rb");
| |
|
| |
| // read header
| |
| fwrite("DUNE SERVICE FILE", 18, 1, out);
| |
| // One day work out what these are.
| |
| fwrite("86673687", 9, 1, out);
| |
| fwrite("54139262", 9, 1, out);
| |
| fwrite("53151487", 9, 1, out);
| |
| fwrite("50852538", 9, 1, out);
| |
| fwrite("38155310", 9, 1, out);
| |
| fwrite("9047468", 8, 1, out);
| |
| fwrite("46935104", 9, 1, out);
| |
| fwrite("64658461", 9, 1, out);
| |
| fwrite("64007208", 9, 1, out);
| |
| fwrite("93556737", 9, 1, out);
| |
| fwrite("88478556", 9, 1, out);
| |
| fwrite("6195915", 8, 1, out);
| |
| fwrite("677883", 7, 1, out);
| |
| fwrite("9851071", 8, 1, out);
| |
| fwrite("82589884", 9, 1, out);
| |
| fwrite("81953245", 9, 1, out);
| |
|
| |
| // First header thing is 0x100.
| |
| fseek(out, 0x100, SEEK_SET);
| |
|
| |
| // Then there is 0x41 bytes of something.
| |
| fwrite(stuff, sizeof(stuff), 1, out);
| |
|
| |
|
| |
| if (compare)
| |
| fseek(compare, 0x141, SEEK_SET);
| |
|
| |
|
| |
| // Read blocks:
| |
| while ((red = fread(buffer, 1, sizeof(buffer), fd)) > 0) {
| |
| // Encode block
| |
| if (arg_verbose)
| |
| printf("read %x \n", red);
| |
|
| |
| if (compare)
| |
| fread(compbuf, 1, red, compare);
| |
|
| |
|
| |
| half_red = red>>1;
| |
| decode = half_red % sizeof(key);
| |
| if (arg_verbose) printf("Decode start %d\n", decode);
| |
|
| |
| for (i = half_red; i < red; i++) {
| |
|
| |
| v1 = key[decode];
| |
| a1 = buffer[ i ];
| |
|
| |
| nv0 = v1;
| |
| nv0 ^= a1;
| |
|
| |
| if (arg_verbose)
| |
| printf(" xor %02X, [%x]=%02X, storing %02X\n",
| |
| v1, i, a1, nv0);
| |
|
| |
| buffer[i] = nv0;
| |
|
| |
| if (compare &&
| |
| buffer[i] != compbuf[i])
| |
| printf("Compare buf has %02X\n", compbuf[i]);
| |
|
| |
| decode++;
| |
| if (decode >= sizeof(key))
| |
| decode = 0;
| |
| }
| |
|
| |
| decode = 0;
| |
| if (arg_verbose) printf("Halfway point as decode %d\n", decode);
| |
|
| |
| for (i = 0; i < half_red; i++) {
| |
|
| |
| v0 = buffer[i + half_red] ;
| |
| v1 = key[decode];
| |
| a1 = buffer[ i ];
| |
|
| |
| nv0 = v0;
| |
| nv0 ^= v1;
| |
| nv0 ^= a1;
| |
|
| |
| if (arg_verbose)
| |
| printf(" [%x]=%02X, xor %02X, [%x]=%02X, storing %02X\n",
| |
| i+half_red, v0, v1, i, a1, nv0);
| |
|
| |
| buffer[i] = nv0;
| |
|
| |
| if (compare &&
| |
| buffer[i] != compbuf[i])
| |
| printf("Compare buf has %02X\n", compbuf[i]);
| |
|
| |
| decode++;
| |
| if (decode >= sizeof(key))
| |
| decode = 0;
| |
| }
| |
|
| |
| // Write block
| |
| fwrite(buffer, red, 1, out);
| |
|
| |
|
| |
| }
| |
|
| |
| fclose(fd);
| |
| fclose(out);
| |
| if (compare)
| |
| fclose(compare);
| |
|
| |
| printf("Encode complete\n");
| |
|
| |
| return 0;
| |
|
| |
| failed:
| |
| perror(":");
| |
| printf("failed\n");
| |
| if (fd)
| |
| fclose(fd);
| |
| else
| |
| fprintf(stderr, "Failed to open infile '%s'\r\n", infilename);
| |
|
| |
| if (out)
| |
| fclose(out);
| |
| else if (fd)
| |
| fprintf(stderr, "Failed to open outfile '%s'\r\n",
| |
| arg_outfilename ? arg_outfilename : "outfile.gz");
| |
|
| |
| if (compare)
| |
| fclose(compare);
| |
|
| |
| }
| |
| d
| |
|
| |
| </pre></tt> | | </pre></tt> |
| --[[User:Gaston|Gaston]] 17:07, 19 January 2011 (JST) | | --[[User:Gaston|Gaston]] 17:07, 19 January 2011 (JST) |