]> git.zerfleddert.de Git - rsbs2/commitdiff
extract all files from the firmware image.
authorMichael Gernoth <michael@gernoth.net>
Sat, 31 Jan 2009 22:09:02 +0000 (23:09 +0100)
committerMichael Gernoth <michael@gernoth.net>
Sat, 31 Jan 2009 22:09:02 +0000 (23:09 +0100)
this should even make it possible, to build our own image with
changed graphics, text, ...

.gitignore
Makefile
extract.c [new file with mode: 0644]
extract.h [new file with mode: 0644]
firmware.c
rsb-lz.c
rsb-lz.h

index 5c01e42824f2043679aca36fc5ae49bae0571619..f5d5be4e6eed9c1afa682a31bad5ead436cfab7e 100644 (file)
@@ -1,3 +1,4 @@
+extract.o
 firmware
 firmware.o
 rsb-crc.o
index cac4a663e628159d2c478e83e5961efa1431c1b0..25c0efef427870566f88f05446b75daaf85ffc1d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,15 +2,17 @@ CFLAGS=-Wall -O3
 
 all: firmware 
 
-firmware: firmware.o rsb-crc.o rsb-lz.o
+firmware: firmware.o rsb-crc.o rsb-lz.o extract.o
 
-firmware.o: firmware.c rsb-crc.h rsb-lz.h
+firmware.o: firmware.c rsb-crc.h extract.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
+
 clean:
-       rm -f firmware firmware.o rsb-crc.o rsb-lz.o
+       rm -f firmware firmware.o rsb-crc.o rsb-lz.o extract.o
 
 .PHONY: all clean
diff --git a/extract.c b/extract.c
new file mode 100644 (file)
index 0000000..feab68f
--- /dev/null
+++ b/extract.c
@@ -0,0 +1,148 @@
+#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"
+
+void extract_files(unsigned char *fw, int len)
+{
+       unsigned char *pos;
+       unsigned int type, length;
+       char *name;
+
+       pos = fw + 0x28;
+       printf("Start of filesystem: 0x%08x\n", *((unsigned int*)pos));
+
+       pos = fw + *((unsigned int*)pos);
+
+       while (pos < (fw + len)) {
+               type = *((unsigned int*)pos);
+               pos += 4;
+               /* ??? */
+               pos++;
+               length = *((unsigned int*)pos);
+               pos += 4;
+               name = (char*)pos;
+               pos += strlen(name) + 1;
+
+               if ((pos + length) > (fw + len)) {
+                       printf("EOF reached\n");
+                       break;
+               }
+               printf("%s: type: 0x%x, length: %d", name, type, length);
+
+               if (length > 0) {
+                       write_file(name, pos, length);
+                       if (*((unsigned int*)pos) == LZ_MAGIC) {
+                               char *lzname;
+
+                               if ((lzname = strdup(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(pos, (unsigned char*)lzname);
+                               free(lzname);
+                       } else if (!strcmp(name, "firmware")) {
+                               unsigned char *lzpos;
+                               char lzname[128];
+
+                               bzero(lzname, sizeof(lzname));
+                               strcpy(lzname, "firmware.");
+
+                               lzpos = pos + *((unsigned int*)(pos + 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);
+                               }
+                       }
+               }
+
+               pos += length;
+
+       }
+}
+
+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);
+}
diff --git a/extract.h b/extract.h
new file mode 100644 (file)
index 0000000..d8b8d32
--- /dev/null
+++ b/extract.h
@@ -0,0 +1,2 @@
+void extract_files(unsigned char *fw, int len);
+void write_file(char *fname, unsigned char *buf, int len);
index 6ef5971461c7773eb7655e7b5cf9353f180a2f7f..cd7927b8f9854d86c20696adcfaabd8285f18dbf 100644 (file)
@@ -8,7 +8,7 @@
 #include <string.h>
 #include <strings.h>
 #include "rsb-crc.h"
-#include "rsb-lz.h"
+#include "extract.h"
 
 #define FINDSTR(addr, str) (!strncmp((char*)addr, str, strlen(str)))
 
@@ -462,7 +462,7 @@ int main(int argc, char **argv)
        }
 
        if (extract) {
-               search_lz_sections(fw, statbuf.st_size - 4);
+               extract_files(fw, statbuf.st_size - 4);
        }
 
        if (update_crc || patch_fw || patch_bd) {
index b6242658d2b6322a9041fd10b53f80620a1ab4f4..3e6e63820f6ab8c5251b367cac208e6c7d56f6b5 100644 (file)
--- a/rsb-lz.c
+++ b/rsb-lz.c
@@ -1,16 +1,12 @@
-#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-crc.h"
 #include "rsb-lz.h"
+#include "extract.h"
 
 /* TODO: IMPLEMET THIS! */
 /* Probably very broken lzw implementation by Agilent:
@@ -638,72 +634,6 @@ unsigned int crc_check_59684(unsigned char *arg1, unsigned int arg2, unsigned in
        return 4;
 }
 
-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);
-}
-
 void extract_lz_file(unsigned char *buf, unsigned char *name)
 {
        unsigned char *r3;
@@ -757,38 +687,3 @@ void extract_lz_file(unsigned char *buf, unsigned char *name)
        
        free(r7);
 }
-
-void search_lz_sections(unsigned char *fw, int len)
-{
-       int i;
-       unsigned char *j;
-
-       for(i = 0; i < len - 4; i++) {
-               if (*((unsigned int*)(fw+i)) == LZ_MAGIC) {
-                       j = fw + i - 1;
-                       printf("0x%02x: ", i);
-                       j--;
-                       while (j > fw) {
-                               if (!strncmp("SP3", (char*)j, 3)) {
-                                       unsigned char fname[5];
-
-                                       bzero(fname, sizeof(fname));
-                                       memcpy(fname, j, 4);
-                                       printf("Firmware found: %s", fname);
-                                       extract_lz_file(fw + i, fname);
-                                       break;
-                               }
-                               if (*j == 0x00) {
-                                       if ((*(j+1) != '/')) {
-                                               printf("ignoring...\n");
-                                               break;
-                                       }
-                                       printf("%s", j+1);
-                                       extract_lz_file(fw + i, j+1);
-                                       break;
-                               }
-                               j--;
-                       }
-               }
-       }
-}
index 5e1fd6dcb58f92d630078cbe095245859625b1f9..ed0d4fb4fee992c2246587e9ee83c6194e79d8b2 100644 (file)
--- a/rsb-lz.h
+++ b/rsb-lz.h
@@ -1,3 +1,3 @@
 #define LZ_MAGIC 0x6110beef
 
-void search_lz_sections(unsigned char *fw, int len);
+void extract_lz_file(unsigned char *buf, unsigned char *name);
Impressum, Datenschutz