all: firmware
-firmware: firmware.o rsb-crc.o rsb-lz.o extract.o
+firmware: firmware.o rsb-crc.o rsb-lz.o filesystem.o
-firmware.o: firmware.c rsb-crc.h extract.h
+firmware.o: firmware.c rsb-crc.h filesystem.h
rsb-crc.o: rsb-crc.c rsb-crc.h
rsb-lz.o: rsb-lz.c rsb-lz.h
-extract.o: extract.c extract.h rsb-lz.h
+filesystem.o: filesystem.c filesystem.h rsb-lz.h
clean:
- rm -f firmware firmware.o rsb-crc.o rsb-lz.o extract.o
+ rm -f firmware firmware.o rsb-crc.o rsb-lz.o filesystem.o
.PHONY: all clean
+++ /dev/null
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <libgen.h>
-#include "rsb-lz.h"
-#include "extract.h"
-
-struct file_entry* get_next_file(unsigned char *fw, int len)
-{
- static unsigned char *pos;
- static unsigned char *start;
- static unsigned char *end;
- static struct file_entry fent;
- int name_length;
-
- if (fw != NULL && len != 0) {
- pos = fw + 0x28;
-
-#if 0
- printf("Start of filesystem: 0x%08x\n", *((unsigned int*)pos));
-#endif
- start = fw;
- pos = fw + *((unsigned int*)pos);
- end = fw + len;
- }
-
- fent.unknown = *pos;
- pos++;
-
- if (fent.unknown == 0x00) {
- /* EOF */
- int fill = (4 - ((pos - start) % 4)) % 4;
- int i;
-
- for (i = 0; i < fill; i++) {
- if (*pos != 0xff) {
- fprintf(stderr, "Wrong fill byte after EOF: 0x%02x, aborting!\n", *pos);
- exit(1);
- }
- pos++;
- }
-
- if (pos != end) {
- fprintf(stderr, "EOF marker not at end-of-file %p <-> %p, aborting!\n", pos, end);
- exit(1);
- }
-
- return NULL;
- }
-
-
- name_length = *((unsigned int*)pos);
- pos += 4;
-
- fent.length = *((unsigned int*)pos);
- pos += 4;
-
- if ((fent.length > (end - pos)) ||
- (name_length > (end - pos))) {
- printf("EOF reached without hitting EOF marker, aborting "
- "(unknown: 0x%02x, namelen: 0x%08x, contentlen: 0x%08x!\n",
- fent.unknown, name_length, fent.length);
- exit(1);
- }
-
- fent.name = (char*)pos;
- pos += name_length;
-
- fent.start = pos;
- pos += fent.length;
-
- return &fent;
-}
-
-void extract_files(unsigned char *fw, int len)
-{
- struct file_entry *fent;
-
- fent = get_next_file(fw, len);
-
- while (fent) {
- printf("%s: unknown: 0x%02x, length: %d",
- fent->name, fent->unknown, fent->length);
-
- if (fent->length > 0) {
- write_file(fent->name, fent->start, fent->length);
- if (*((unsigned int*)fent->start) == LZ_MAGIC) {
- char *lzname;
-
- if ((lzname = strdup(fent->name)) == NULL) {
- perror("strdup");
- exit(1);
- }
-
- if (!strcmp(lzname + strlen(lzname) - 4 , ".lz")) {
- fprintf(stderr, "Ugh, can't derive filename...\n");
- exit(1);
- }
- lzname[strlen(lzname) - 3] = 0x00;
-
- printf("%s: packed file found", lzname);
-
- extract_lz_file(fent->start, (unsigned char*)lzname);
- free(lzname);
- } else if (!strcmp(fent->name, "firmware")) {
- unsigned char *lzpos;
- char lzname[128];
-
- bzero(lzname, sizeof(lzname));
- strcpy(lzname, "firmware.");
-
- lzpos = fent->start + *((unsigned int*)(fent->start + 0x20));
- memcpy(lzname + strlen(lzname), lzpos - 4, 4);
- lzpos += 4;
- if (*((unsigned int*)(lzpos)) == LZ_MAGIC) {
- printf("%s: compressed firmware part found", lzname);
- extract_lz_file(lzpos, (unsigned char*)lzname);
- }
- }
- } else {
- printf(", ignoring...\n");
- }
- fent = get_next_file(NULL, 0);
- }
-}
-
-void mkdir_p(char *dir)
-{
- char *copy, *parent;
-
- if ((dir == NULL) || (!strcmp(dir, ".")))
- return;
-
- if ((copy = strdup(dir)) == NULL) {
- perror("strdup");
- exit(1);
- }
- parent = dirname(copy);
- mkdir_p(parent);
-
- errno = 0;
- if (mkdir(dir, 0755) == -1) {
- if (errno != EEXIST) {
- fprintf(stderr, "%s: ", dir);
- perror("mkdir");
- exit(1);
- }
- }
- free(copy);
-}
-
-void write_file(char *fname, unsigned char *buf, int len)
-{
- char filename[PATH_MAX];
- char *filename_c, *dirn;
- int fd;
- int remaining;
- int ret;
-
- strcpy(filename, "extracted/");
- strcat(filename, fname);
-
- if ((filename_c = strdup(filename)) == NULL) {
- perror("strdup");
- exit(1);
- }
- dirn = dirname(filename_c);
- mkdir_p(dirn);
- free(filename_c);
-
- if ((fd = open(filename, O_WRONLY|O_CREAT, 0644)) == -1) {
- fprintf(stderr, "%s: ", filename);
- perror("open");
- exit(1);
- }
-
- remaining = len;
-
- while(remaining) {
- ret = write(fd, buf + (len - remaining), remaining);
- if (ret < 0) {
- perror("write");
- exit(1);
- }
- remaining -= ret;
- }
-
- printf(", %s written.\n", filename);
-
- close(fd);
-}
+++ /dev/null
-struct file_entry {
- char *name;
- unsigned char *start;
- int length;
- unsigned char unknown;
-};
-
-struct file_entry* get_next_file(unsigned char *fw, int len);
-void extract_files(unsigned char *fw, int len);
-void write_file(char *fname, unsigned char *buf, int len);
--- /dev/null
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <libgen.h>
+#include "rsb-lz.h"
+#include "filesystem.h"
+
+struct file_entry* get_next_file(unsigned char *fw, int len)
+{
+ static unsigned char *pos;
+ static unsigned char *start;
+ static unsigned char *end;
+ static struct file_entry fent;
+ int name_length;
+
+ if (fw != NULL && len != 0) {
+ pos = fw + 0x28;
+
+#if 0
+ printf("Start of filesystem: 0x%08x\n", *((unsigned int*)pos));
+#endif
+ start = fw;
+ pos = fw + *((unsigned int*)pos);
+ end = fw + len;
+ }
+
+ fent.unknown = *pos;
+ pos++;
+
+ if (fent.unknown == 0x00) {
+ /* EOF */
+ int fill = (4 - ((pos - start) % 4)) % 4;
+ int i;
+
+ for (i = 0; i < fill; i++) {
+ if (*pos != 0xff) {
+ fprintf(stderr, "Wrong fill byte after EOF: 0x%02x, aborting!\n", *pos);
+ exit(1);
+ }
+ pos++;
+ }
+
+ if (pos != end) {
+ fprintf(stderr, "EOF marker not at end-of-file %p <-> %p, aborting!\n", pos, end);
+ exit(1);
+ }
+
+ return NULL;
+ }
+
+
+ name_length = *((unsigned int*)pos);
+ pos += 4;
+
+ fent.length = *((unsigned int*)pos);
+ pos += 4;
+
+ if ((fent.length > (end - pos)) ||
+ (name_length > (end - pos))) {
+ printf("EOF reached without hitting EOF marker, aborting "
+ "(unknown: 0x%02x, namelen: 0x%08x, contentlen: 0x%08x!\n",
+ fent.unknown, name_length, fent.length);
+ exit(1);
+ }
+
+ fent.name = (char*)pos;
+ pos += name_length;
+
+ fent.start = pos;
+ pos += fent.length;
+
+ return &fent;
+}
+
+void extract_files(unsigned char *fw, int len)
+{
+ struct file_entry *fent;
+
+ fent = get_next_file(fw, len);
+
+ while (fent) {
+ printf("%s: unknown: 0x%02x, length: %d",
+ fent->name, fent->unknown, fent->length);
+
+ if (fent->length > 0) {
+ write_file(fent->name, fent->start, fent->length);
+ if (*((unsigned int*)fent->start) == LZ_MAGIC) {
+ char *lzname;
+
+ if ((lzname = strdup(fent->name)) == NULL) {
+ perror("strdup");
+ exit(1);
+ }
+
+ if (!strcmp(lzname + strlen(lzname) - 4 , ".lz")) {
+ fprintf(stderr, "Ugh, can't derive filename...\n");
+ exit(1);
+ }
+ lzname[strlen(lzname) - 3] = 0x00;
+
+ printf("%s: packed file found", lzname);
+
+ extract_lz_file(fent->start, (unsigned char*)lzname);
+ free(lzname);
+ } else if (!strcmp(fent->name, "firmware")) {
+ unsigned char *lzpos;
+ char lzname[128];
+
+ bzero(lzname, sizeof(lzname));
+ strcpy(lzname, "firmware.");
+
+ lzpos = fent->start + *((unsigned int*)(fent->start + 0x20));
+ memcpy(lzname + strlen(lzname), lzpos - 4, 4);
+ lzpos += 4;
+ if (*((unsigned int*)(lzpos)) == LZ_MAGIC) {
+ printf("%s: compressed firmware part found", lzname);
+ extract_lz_file(lzpos, (unsigned char*)lzname);
+ }
+ }
+ } else {
+ printf(", ignoring...\n");
+ }
+ fent = get_next_file(NULL, 0);
+ }
+}
+
+void mkdir_p(char *dir)
+{
+ char *copy, *parent;
+
+ if ((dir == NULL) || (!strcmp(dir, ".")))
+ return;
+
+ if ((copy = strdup(dir)) == NULL) {
+ perror("strdup");
+ exit(1);
+ }
+ parent = dirname(copy);
+ mkdir_p(parent);
+
+ errno = 0;
+ if (mkdir(dir, 0755) == -1) {
+ if (errno != EEXIST) {
+ fprintf(stderr, "%s: ", dir);
+ perror("mkdir");
+ exit(1);
+ }
+ }
+ free(copy);
+}
+
+void write_file(char *fname, unsigned char *buf, int len)
+{
+ char filename[PATH_MAX];
+ char *filename_c, *dirn;
+ int fd;
+ int remaining;
+ int ret;
+
+ strcpy(filename, "extracted/");
+ strcat(filename, fname);
+
+ if ((filename_c = strdup(filename)) == NULL) {
+ perror("strdup");
+ exit(1);
+ }
+ dirn = dirname(filename_c);
+ mkdir_p(dirn);
+ free(filename_c);
+
+ if ((fd = open(filename, O_WRONLY|O_CREAT, 0644)) == -1) {
+ fprintf(stderr, "%s: ", filename);
+ perror("open");
+ exit(1);
+ }
+
+ remaining = len;
+
+ while(remaining) {
+ ret = write(fd, buf + (len - remaining), remaining);
+ if (ret < 0) {
+ perror("write");
+ exit(1);
+ }
+ remaining -= ret;
+ }
+
+ printf(", %s written.\n", filename);
+
+ close(fd);
+}
--- /dev/null
+struct file_entry {
+ char *name;
+ unsigned char *start;
+ int length;
+ unsigned char unknown;
+};
+
+struct file_entry* get_next_file(unsigned char *fw, int len);
+void extract_files(unsigned char *fw, int len);
+void write_file(char *fname, unsigned char *buf, int len);
#include <string.h>
#include <strings.h>
#include "rsb-crc.h"
-#include "extract.h"
+#include "filesystem.h"
#define FINDSTR(addr, str) (!strncmp((char*)addr, str, strlen(str)))
#include <errno.h>
#include "rsb-crc.h"
#include "rsb-lz.h"
-#include "extract.h"
+#include "filesystem.h"
/* TODO: IMPLEMET THIS! */
/* Probably very broken lzw implementation by Agilent: