Changes

Jump to navigation Jump to search
Initial release of parse-u8.c (beta version only)
<pre>
// parse-u8.c
// Compile with:
// gcc -g -DLARGE_FILES -D_FILE_OFFSET_BITS=64 -Wall -W -O2 -c -o parse-u8.o parse-u8.c
// gcc -g -lcrypto parse-u8.o tools.o bn.o ec.o -o parse-u8
// The other files are from segher's git repository, created by his Makefile.

// Copyright 2008 Magicus <magicus@gmail.com>
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt

// Version 0.5 Beta version, just lists contents, doesn't yet extract files.


#include <sys/stat.h>
#include <sys/types.h>

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include "tools.h"

#define ERROR(s) do { fprintf(stderr, s "\n"); exit(1); } while (0)

// FIXME: this should really move to tools.c
u16 be16(u8 *p)
{
return (p[0] << 8) | p[1];
}

static FILE *fp;

static char *outdir = "OUTDIR";

typedef struct
{
u16 type;
u16 name_offset;
u32 data_offset; // == absolut offset från U.8- headerns början
u32 size; // last included file num for directories
} U8_node;

typedef struct
{
u32 tag; // 0x55AA382D "U.8-"
u32 rootnode_offset; // offset to root_node, always 0x20.
u32 header_size; // size of header from root_node to end of string table.
u32 data_offset; // offset to data -- this is rootnode_offset + header_size, aligned to 0x40.
u8 zeroes[16];
} U8_archive_header;

/*
static void write_part(void* data, size_t size, char* name)
{
FILE *out;
char filename[128];

snprintf(filename, sizeof(filename), "%s_%s.bin", gamename, name);
filename[127] = '\0';
out = fopen(filename, "wb");
fwrite(data, 1, size, out);
fclose(out);
}
*/


static void do_U8_archive(void)
{
U8_archive_header header;
U8_node root_node;
u32 tag;
u32 num_nodes;
U8_node* nodes;
u8* string_table;
size_t rest_size;
unsigned int i;
u32 data_offset;

fread(&header, 1, sizeof header, fp);
tag = be32((u8*) &header.tag);
if (tag != 0x55AA382D) {
ERROR("No U8 tag");
}

fread(&root_node, 1, sizeof(root_node), fp);
num_nodes = be32((u8*) &root_node.size) - 1;
printf("Number of files: %d\n", num_nodes);

nodes = malloc(sizeof(U8_node) * (num_nodes));
fread(nodes, 1, num_nodes * sizeof(U8_node), fp);

data_offset = be32((u8*) &header.data_offset);
rest_size = data_offset - sizeof(header) - num_nodes*sizeof(U8_node);

string_table = malloc(rest_size);
fread(string_table, 1, rest_size, fp);

for (i = 0; i < num_nodes; i++) {
U8_node* node = &nodes[i];
u16 type = be16((u8*)&node->type);
u16 name_offset = be16((u8*)&node->name_offset);
u32 data_offset = be32((u8*)&node->data_offset);
u32 size = be32((u8*)&node->size);
char* name = (char*) &string_table[name_offset];
char* premarker;
char* postmarker;

if (type == 0x0100) {
premarker = "";
postmarker = "/";
} else {
premarker = " ";
postmarker = "";
}

printf("%s%s%s (%d) offset: %x\n", premarker, name, postmarker, size, data_offset);
}
}

int main(int argc, char **argv)
{
if (argc == 3) {
outdir = argv[2];
} else if (argc != 2) {
ERROR("Usage: parse-u8 <file> [<outdir>]");
}

fp = fopen(argv[1], "rb");

// mkdir(outdir, 0777);
// chdir(outdir);

do_U8_archive();

fclose(fp);

return 0;
}

</pre>
68

edits

Navigation menu