OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * This program is free software; you can redistribute it and/or modify |
||
3 | * it under the terms of the GNU General Public License as published by |
||
4 | * the Free Software Foundation; version 2 of the License |
||
5 | * |
||
6 | * This program is distributed in the hope that it will be useful, |
||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
9 | * GNU General Public License for more details. |
||
10 | * |
||
11 | * You should have received a copy of the GNU General Public License |
||
12 | * along with this program; if not, write to the Free Software |
||
13 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
||
14 | * |
||
15 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> |
||
16 | */ |
||
17 | |||
18 | #include <sys/types.h> |
||
19 | #include <sys/stat.h> |
||
20 | #include <unistd.h> |
||
21 | #include <stdlib.h> |
||
22 | #include <stdio.h> |
||
23 | #include <string.h> |
||
24 | #include <errno.h> |
||
25 | #include <fcntl.h> |
||
26 | |||
27 | #include "LzmaWrapper.h" |
||
28 | |||
29 | #define FW_NAME "/tmp/firmware-speedport-w921v-1.44.000.bin" |
||
30 | |||
31 | #define MAGIC 0x50 |
||
32 | #define MAGIC_SZ 0x3FFC00 |
||
33 | #if __BYTE_ORDER == __LITTLE_ENDIAN |
||
34 | #define MAGIC_PART 0x12345678 |
||
35 | #define MAGIC_LZMA 0x8000005D |
||
36 | #define MAGIC_ANNEX_B 0x3C |
||
37 | #define MAGIC_TAPI 0x5A |
||
38 | #else |
||
39 | #define MAGIC_PART 0x78563412 |
||
40 | #define MAGIC_LZMA 0x5D000080 |
||
41 | #define MAGIC_ANNEX_B 0x3C000000 |
||
42 | #define MAGIC_TAPI 0x5A000000 |
||
43 | #endif |
||
44 | |||
45 | |||
46 | const char* part_type(unsigned int id) |
||
47 | { |
||
48 | switch(id) { |
||
49 | case MAGIC_ANNEX_B: |
||
50 | return "/tmp/vr9_dsl_fw_annex_b.bin"; |
||
51 | case MAGIC_TAPI: |
||
52 | return "/tmp/vr9_tapi_fw.bin"; |
||
53 | } |
||
54 | printf("\tUnknown lzma type 0x%02X\n", id); |
||
55 | return "/tmp/unknown.lzma"; |
||
56 | } |
||
57 | |||
58 | int main(int argc, char **argv) |
||
59 | { |
||
60 | struct stat s; |
||
61 | unsigned char *buf_orig; |
||
62 | unsigned int *buf; |
||
63 | int buflen; |
||
64 | int fd; |
||
65 | int i; |
||
66 | int err; |
||
67 | int start = 0, end = 0; |
||
68 | |||
69 | printf("Arcadyan Firmware cutter v0.1\n"); |
||
70 | printf("-----------------------------\n"); |
||
71 | printf("This tool extracts the different parts of an arcadyan firmware update file\n"); |
||
72 | printf("This tool is for private use only. The Firmware that gets extracted has a license that forbids redistribution\n"); |
||
73 | printf("Please only run this if you understand the risks\n\n"); |
||
74 | printf("I understand the risks ? (y/N)\n"); |
||
75 | |||
76 | if (getchar() != 'y') |
||
77 | return -1; |
||
78 | |||
79 | if (stat(FW_NAME, &s) != 0) { |
||
80 | printf("Failed to find %s\n", FW_NAME); |
||
81 | printf("Ask Google or try https://www.telekom.de/hilfe/downloads/firmware-speedport-w921v-1.44.000.bin\n"); |
||
82 | return -1; |
||
83 | } |
||
84 | |||
85 | buf_orig = malloc(s.st_size); |
||
86 | buf = malloc(s.st_size); |
||
87 | if (!buf_orig || !buf) { |
||
88 | printf("Failed to alloc %d bytes\n", s.st_size); |
||
89 | return -1; |
||
90 | } |
||
91 | |||
92 | fd = open(FW_NAME, O_RDONLY); |
||
93 | if (fd < 0) { |
||
94 | printf("Unable to open %s\n", FW_NAME); |
||
95 | return -1; |
||
96 | } |
||
97 | |||
98 | |||
99 | buflen = read(fd, buf_orig, s.st_size); |
||
100 | close(fd); |
||
101 | if (buflen != s.st_size) { |
||
102 | printf("Loaded %d instead of %d bytes inside %s\n", buflen, s.st_size, FW_NAME); |
||
103 | return -1; |
||
104 | } |
||
105 | |||
106 | /* <magic> */ |
||
107 | buf_orig++; |
||
108 | buflen -= 1; |
||
109 | for (i = 0; i < MAGIC_SZ; i++) { |
||
110 | if ((i % 16) < 3) |
||
111 | buf_orig[i] = buf_orig[i + 16] ^ MAGIC; |
||
112 | else |
||
113 | buf_orig[i] = buf_orig[i] ^ MAGIC; |
||
114 | } |
||
115 | buflen -= 3; |
||
116 | memmove(&buf_orig[MAGIC_SZ], &buf_orig[MAGIC_SZ + 3], buflen - MAGIC_SZ); |
||
117 | memcpy(buf, buf_orig, s.st_size); |
||
118 | |||
119 | /* </magic> */ |
||
120 | do { |
||
121 | if (buf[end] == MAGIC_PART) { |
||
122 | end += 2; |
||
123 | printf("Found partition at 0x%08X with size %d\n", |
||
124 | start * sizeof(unsigned int), |
||
125 | (end - start) * sizeof(unsigned int)); |
||
126 | if (buf[start] == MAGIC_LZMA) { |
||
127 | int dest_len = 1024 * 1024; |
||
128 | int len = buf[end - 3]; |
||
129 | unsigned int id = buf[end - 6]; |
||
130 | const char *type = part_type(id); |
||
131 | unsigned char *dest; |
||
132 | |||
133 | dest = malloc(dest_len); |
||
134 | if (!dest) { |
||
135 | printf("Failed to alloc dest buffer\n"); |
||
136 | return -1; |
||
137 | } |
||
138 | |||
139 | if (lzma_inflate((unsigned char*)&buf[start], len, dest, &dest_len)) { |
||
140 | printf("Failed to decompress data\n"); |
||
141 | return -1; |
||
142 | } |
||
143 | |||
144 | fd = creat(type, S_IRUSR | S_IWUSR); |
||
145 | if (fd != -1) { |
||
146 | if (write(fd, dest, dest_len) != dest_len) |
||
147 | printf("\tFailed to write %d bytes\n", dest_len); |
||
148 | else |
||
149 | printf("\tWrote %d bytes to %s\n", dest_len, type); |
||
150 | close(fd); |
||
151 | } else { |
||
152 | printf("\tFailed to open %s\n", type); |
||
153 | } |
||
154 | free(dest); |
||
155 | } else { |
||
156 | printf("\tThis is not lzma\n"); |
||
157 | } |
||
158 | start = end; |
||
159 | } else { |
||
160 | end++; |
||
161 | } |
||
162 | } while(end < buflen / sizeof(unsigned int)); |
||
163 | |||
164 | return 0; |
||
165 | } |