diff options
Diffstat (limited to 'utils/zenutils/source/update_extract/main.cpp')
-rw-r--r--[-rwxr-xr-x] | utils/zenutils/source/update_extract/main.cpp | 558 |
1 files changed, 279 insertions, 279 deletions
diff --git a/utils/zenutils/source/update_extract/main.cpp b/utils/zenutils/source/update_extract/main.cpp index 0fae29e00c..4891329397 100755..100644 --- a/utils/zenutils/source/update_extract/main.cpp +++ b/utils/zenutils/source/update_extract/main.cpp | |||
@@ -1,279 +1,279 @@ | |||
1 | /* zenutils - Utilities for working with creative firmwares. | 1 | /* zenutils - Utilities for working with creative firmwares. |
2 | * Copyright 2007 (c) Rasmus Ry <rasmus.ry{at}gmail.com> | 2 | * Copyright 2007 (c) Rasmus Ry <rasmus.ry{at}gmail.com> |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
6 | * the Free Software Foundation; either version 2 of the License, or | 6 | * the Free Software Foundation; either version 2 of the License, or |
7 | * (at your option) any later version. | 7 | * (at your option) any later version. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it will be useful, | 9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write to the Free Software | 15 | * along with this program; if not, write to the Free Software |
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <iostream> | 19 | #include <iostream> |
20 | #include <iomanip> | 20 | #include <iomanip> |
21 | #include <ctime> | 21 | #include <ctime> |
22 | #include <getpot/getpot.hpp> | 22 | #include <getpot/getpot.hpp> |
23 | #include <file.h> | 23 | #include <file.h> |
24 | #include <updater.h> | 24 | #include <updater.h> |
25 | #include <utils.h> | 25 | #include <utils.h> |
26 | 26 | ||
27 | 27 | ||
28 | static const char VERSION[] = "0.1"; | 28 | static const char VERSION[] = "0.1"; |
29 | 29 | ||
30 | void print_version() | 30 | void print_version() |
31 | { | 31 | { |
32 | std::cout | 32 | std::cout |
33 | << "update_extract - Extracts a Creative firmware from an updater" | 33 | << "update_extract - Extracts a Creative firmware from an updater" |
34 | " executable." << std::endl | 34 | " executable." << std::endl |
35 | << "Version " << VERSION << std::endl | 35 | << "Version " << VERSION << std::endl |
36 | << "Copyright (c) 2007 Rasmus Ry" << std::endl; | 36 | << "Copyright (c) 2007 Rasmus Ry" << std::endl; |
37 | } | 37 | } |
38 | 38 | ||
39 | void print_help() | 39 | void print_help() |
40 | { | 40 | { |
41 | print_version(); | 41 | print_version(); |
42 | std::cout << std::endl | 42 | std::cout << std::endl |
43 | << "Usage: update_extract [command] [options]" << std::endl | 43 | << "Usage: update_extract [command] [options]" << std::endl |
44 | << std::endl | 44 | << std::endl |
45 | << " Commands:" << std::endl | 45 | << " Commands:" << std::endl |
46 | << " -h,--help" << std::endl | 46 | << " -h,--help" << std::endl |
47 | << " prints this message." << std::endl | 47 | << " prints this message." << std::endl |
48 | << " -u,--updater [file]" << std::endl | 48 | << " -u,--updater [file]" << std::endl |
49 | << " specifies the updater executable." << std::endl | 49 | << " specifies the updater executable." << std::endl |
50 | << std::endl | 50 | << std::endl |
51 | << " Options:" << std::endl | 51 | << " Options:" << std::endl |
52 | << " -V,--verbose" << std::endl | 52 | << " -V,--verbose" << std::endl |
53 | << " prints verbose messages." << std::endl | 53 | << " prints verbose messages." << std::endl |
54 | << " -f,--firmware [file]" << std::endl | 54 | << " -f,--firmware [file]" << std::endl |
55 | << " specifies the firmware arhive file name." << std::endl | 55 | << " specifies the firmware arhive file name." << std::endl |
56 | << " -k,--key [key]" << std::endl | 56 | << " -k,--key [key]" << std::endl |
57 | << " specifies the firmware archive key." << std::endl | 57 | << " specifies the firmware archive key." << std::endl |
58 | << " -o,--offset [offset]" << std::endl | 58 | << " -o,--offset [offset]" << std::endl |
59 | << " specifies the firmware archive offset in c-style" | 59 | << " specifies the firmware archive offset in c-style" |
60 | " hexadecimal." << std::endl | 60 | " hexadecimal." << std::endl |
61 | << std::endl | 61 | << std::endl |
62 | ; | 62 | ; |
63 | } | 63 | } |
64 | 64 | ||
65 | std::string options_name(const std::string& name) | 65 | std::string options_name(const std::string& name) |
66 | { | 66 | { |
67 | return shared::replace_extension(name, ".opt"); | 67 | return shared::replace_extension(name, ".opt"); |
68 | } | 68 | } |
69 | 69 | ||
70 | std::string default_firmware_name(const std::string& name) | 70 | std::string default_firmware_name(const std::string& name) |
71 | { | 71 | { |
72 | return shared::replace_extension(name, "_rk.bin"); | 72 | return shared::replace_extension(name, "_rk.bin"); |
73 | } | 73 | } |
74 | 74 | ||
75 | int process_arguments(int argc, char* argv[]) | 75 | int process_arguments(int argc, char* argv[]) |
76 | { | 76 | { |
77 | //-------------------------------------------------------------------- | 77 | //-------------------------------------------------------------------- |
78 | // Parse input variables. | 78 | // Parse input variables. |
79 | //-------------------------------------------------------------------- | 79 | //-------------------------------------------------------------------- |
80 | 80 | ||
81 | GetPot cl(argc, argv); | 81 | GetPot cl(argc, argv); |
82 | if (cl.size() == 1 || cl.search(2, "-h", "--help")) | 82 | if (cl.size() == 1 || cl.search(2, "-h", "--help")) |
83 | { | 83 | { |
84 | print_help(); | 84 | print_help(); |
85 | return 1; | 85 | return 1; |
86 | } | 86 | } |
87 | 87 | ||
88 | std::string updatername; | 88 | std::string updatername; |
89 | if (cl.search("-u") || cl.search("--updater")) | 89 | if (cl.search("-u") || cl.search("--updater")) |
90 | updatername = cl.next(""); | 90 | updatername = cl.next(""); |
91 | if (updatername.empty()) | 91 | if (updatername.empty()) |
92 | { | 92 | { |
93 | std::cerr << "Updater executable must be specified." << std::endl; | 93 | std::cerr << "Updater executable must be specified." << std::endl; |
94 | return 2; | 94 | return 2; |
95 | } | 95 | } |
96 | 96 | ||
97 | std::string firmarename = default_firmware_name(updatername); | 97 | std::string firmarename = default_firmware_name(updatername); |
98 | if (cl.search("-f") || cl.search("--firmware")) | 98 | if (cl.search("-f") || cl.search("--firmware")) |
99 | firmarename = cl.next(firmarename.c_str()); | 99 | firmarename = cl.next(firmarename.c_str()); |
100 | 100 | ||
101 | bool verbose = false; | 101 | bool verbose = false; |
102 | if (cl.search("-V") || cl.search("--verbose")) | 102 | if (cl.search("-V") || cl.search("--verbose")) |
103 | verbose = true; | 103 | verbose = true; |
104 | 104 | ||
105 | // Get or find the firmware archive key. | 105 | // Get or find the firmware archive key. |
106 | std::string key; | 106 | std::string key; |
107 | if (cl.search("-k") || cl.search("--key")) | 107 | if (cl.search("-k") || cl.search("--key")) |
108 | key = cl.next(""); | 108 | key = cl.next(""); |
109 | 109 | ||
110 | if (key.empty()) | 110 | if (key.empty()) |
111 | { | 111 | { |
112 | if (verbose) | 112 | if (verbose) |
113 | std::cout << "[*] Looking for firmware archive key..." | 113 | std::cout << "[*] Looking for firmware archive key..." |
114 | << std::endl; | 114 | << std::endl; |
115 | shared::bytes buffer; | 115 | shared::bytes buffer; |
116 | if (!shared::read_file(updatername, buffer)) | 116 | if (!shared::read_file(updatername, buffer)) |
117 | { | 117 | { |
118 | std::cerr << "Failed to read the firmware updater executable." | 118 | std::cerr << "Failed to read the firmware updater executable." |
119 | << std::endl; | 119 | << std::endl; |
120 | return 3; | 120 | return 3; |
121 | } | 121 | } |
122 | key = zen::find_firmware_key(&buffer[0], buffer.size()); | 122 | key = zen::find_firmware_key(&buffer[0], buffer.size()); |
123 | if (key.empty()) | 123 | if (key.empty()) |
124 | { | 124 | { |
125 | std::cerr << "Failed to find the firmware archive key." | 125 | std::cerr << "Failed to find the firmware archive key." |
126 | << std::endl; | 126 | << std::endl; |
127 | return 4; | 127 | return 4; |
128 | } | 128 | } |
129 | } | 129 | } |
130 | 130 | ||
131 | // Get or find the firmware archive offset. | 131 | // Get or find the firmware archive offset. |
132 | std::string offset; | 132 | std::string offset; |
133 | dword offset_pa = 0; | 133 | dword offset_pa = 0; |
134 | if (cl.search("-o") || cl.search("--ofset")) | 134 | if (cl.search("-o") || cl.search("--ofset")) |
135 | offset = cl.next(""); | 135 | offset = cl.next(""); |
136 | 136 | ||
137 | if (offset.empty()) | 137 | if (offset.empty()) |
138 | { | 138 | { |
139 | if (verbose) | 139 | if (verbose) |
140 | std::cout << "[*] Looking for firmware archive offset..." | 140 | std::cout << "[*] Looking for firmware archive offset..." |
141 | << std::endl; | 141 | << std::endl; |
142 | 142 | ||
143 | dword offset_va = 0; | 143 | dword offset_va = 0; |
144 | if (!zen::find_firmware_archive(updatername, offset_va, offset_pa)) | 144 | if (!zen::find_firmware_archive(updatername, offset_va, offset_pa)) |
145 | { | 145 | { |
146 | std::cerr << "Failed to find the firmware archive offset." | 146 | std::cerr << "Failed to find the firmware archive offset." |
147 | << std::endl; | 147 | << std::endl; |
148 | return 5; | 148 | return 5; |
149 | } | 149 | } |
150 | } | 150 | } |
151 | else | 151 | else |
152 | { | 152 | { |
153 | int offset_val; | 153 | int offset_val; |
154 | if (!sscanf(offset.c_str(), "0x%x", &offset_val)) | 154 | if (!sscanf(offset.c_str(), "0x%x", &offset_val)) |
155 | { | 155 | { |
156 | if (!sscanf(offset.c_str(), "0x%X", &offset_val)) | 156 | if (!sscanf(offset.c_str(), "0x%X", &offset_val)) |
157 | { | 157 | { |
158 | std::cerr << "\'" << offset | 158 | std::cerr << "\'" << offset |
159 | << "\' is not a valid c-style hexadecimal value." | 159 | << "\' is not a valid c-style hexadecimal value." |
160 | << std::endl; | 160 | << std::endl; |
161 | return 6; | 161 | return 6; |
162 | } | 162 | } |
163 | } | 163 | } |
164 | offset_pa = static_cast<dword>(offset_val); | 164 | offset_pa = static_cast<dword>(offset_val); |
165 | } | 165 | } |
166 | 166 | ||
167 | // Read firmware archive size. | 167 | // Read firmware archive size. |
168 | shared::bytes buffer; | 168 | shared::bytes buffer; |
169 | if (!shared::read_file(updatername, buffer, offset_pa, sizeof(dword))) | 169 | if (!shared::read_file(updatername, buffer, offset_pa, sizeof(dword))) |
170 | { | 170 | { |
171 | std::cerr << "Failed to read the firmware archive size." << std::endl; | 171 | std::cerr << "Failed to read the firmware archive size." << std::endl; |
172 | return 7; | 172 | return 7; |
173 | } | 173 | } |
174 | dword archive_size = *(dword*)&buffer[0]; | 174 | dword archive_size = *(dword*)&buffer[0]; |
175 | 175 | ||
176 | if (verbose) | 176 | if (verbose) |
177 | { | 177 | { |
178 | std::cout << "[*] Printing input variables..." << std::endl; | 178 | std::cout << "[*] Printing input variables..." << std::endl; |
179 | std::cout << " Updater executable: " << updatername << std::endl; | 179 | std::cout << " Updater executable: " << updatername << std::endl; |
180 | std::cout << " Firmware archive: " << firmarename << std::endl; | 180 | std::cout << " Firmware archive: " << firmarename << std::endl; |
181 | std::cout << " Key: " << key << std::endl; | 181 | std::cout << " Key: " << key << std::endl; |
182 | std::cout << " Offset: " | 182 | std::cout << " Offset: " |
183 | << std::hex << std::showbase << std::setw(10) | 183 | << std::hex << std::showbase << std::setw(10) |
184 | << std::setfill('0') << std::internal | 184 | << std::setfill('0') << std::internal |
185 | << offset_pa << std::endl; | 185 | << offset_pa << std::endl; |
186 | std::cout << " Size: " | 186 | std::cout << " Size: " |
187 | << std::hex << std::showbase << std::setw(10) | 187 | << std::hex << std::showbase << std::setw(10) |
188 | << std::setfill('0') << std::internal | 188 | << std::setfill('0') << std::internal |
189 | << archive_size << std::endl; | 189 | << archive_size << std::endl; |
190 | } | 190 | } |
191 | 191 | ||
192 | 192 | ||
193 | //-------------------------------------------------------------------- | 193 | //-------------------------------------------------------------------- |
194 | // Extract the firmware archive from the updater. | 194 | // Extract the firmware archive from the updater. |
195 | //-------------------------------------------------------------------- | 195 | //-------------------------------------------------------------------- |
196 | 196 | ||
197 | if (verbose) | 197 | if (verbose) |
198 | std::cout << "[*] Reading firmware archive..." << std::endl; | 198 | std::cout << "[*] Reading firmware archive..." << std::endl; |
199 | 199 | ||
200 | // Read the firmware archive. | 200 | // Read the firmware archive. |
201 | offset_pa += sizeof(dword); | 201 | offset_pa += sizeof(dword); |
202 | if (!shared::read_file(updatername, buffer, offset_pa, archive_size)) | 202 | if (!shared::read_file(updatername, buffer, offset_pa, archive_size)) |
203 | { | 203 | { |
204 | std::cerr << "Failed to read the firmware archive." << std::endl; | 204 | std::cerr << "Failed to read the firmware archive." << std::endl; |
205 | return 8; | 205 | return 8; |
206 | } | 206 | } |
207 | 207 | ||
208 | if (verbose) | 208 | if (verbose) |
209 | std::cout << "[*] Decrypting firmware archive..." << std::endl; | 209 | std::cout << "[*] Decrypting firmware archive..." << std::endl; |
210 | 210 | ||
211 | // Decrypt the firmware archive. | 211 | // Decrypt the firmware archive. |
212 | if (!zen::crypt_firmware(key.c_str(), &buffer[0], buffer.size())) | 212 | if (!zen::crypt_firmware(key.c_str(), &buffer[0], buffer.size())) |
213 | { | 213 | { |
214 | std::cerr << "Failed to decrypt the firmware archive." << std::endl; | 214 | std::cerr << "Failed to decrypt the firmware archive." << std::endl; |
215 | return 9; | 215 | return 9; |
216 | } | 216 | } |
217 | 217 | ||
218 | if (verbose) | 218 | if (verbose) |
219 | std::cout << "[*] Decompressing firmware archive..." << std::endl; | 219 | std::cout << "[*] Decompressing firmware archive..." << std::endl; |
220 | 220 | ||
221 | // Inflate the firmware archive to the output file. | 221 | // Inflate the firmware archive to the output file. |
222 | if (!shared::inflate_to_file(buffer, firmarename.c_str())) | 222 | if (!shared::inflate_to_file(buffer, firmarename.c_str())) |
223 | { | 223 | { |
224 | std::cerr << "Failed to decompress the firmware archive." << std::endl; | 224 | std::cerr << "Failed to decompress the firmware archive." << std::endl; |
225 | return 10; | 225 | return 10; |
226 | } | 226 | } |
227 | 227 | ||
228 | 228 | ||
229 | //-------------------------------------------------------------------- | 229 | //-------------------------------------------------------------------- |
230 | // Generate an options file for the extracted firmware archive. | 230 | // Generate an options file for the extracted firmware archive. |
231 | //-------------------------------------------------------------------- | 231 | //-------------------------------------------------------------------- |
232 | 232 | ||
233 | // Get options filename for the given input file. | 233 | // Get options filename for the given input file. |
234 | std::string optionsname = options_name(updatername); | 234 | std::string optionsname = options_name(updatername); |
235 | 235 | ||
236 | if (verbose) | 236 | if (verbose) |
237 | std::cout << "[*] Producing options file..." << std::endl; | 237 | std::cout << "[*] Producing options file..." << std::endl; |
238 | 238 | ||
239 | // Produce options file for the given input file. | 239 | // Produce options file for the given input file. |
240 | std::ofstream ofs; | 240 | std::ofstream ofs; |
241 | ofs.open(optionsname.c_str(), std::ios::binary); | 241 | ofs.open(optionsname.c_str(), std::ios::binary); |
242 | if (!ofs) | 242 | if (!ofs) |
243 | { | 243 | { |
244 | std::cerr << "Failed to create firmware archive options file." | 244 | std::cerr << "Failed to create firmware archive options file." |
245 | << std::endl; | 245 | << std::endl; |
246 | return 11; | 246 | return 11; |
247 | } | 247 | } |
248 | 248 | ||
249 | time_t timeval = time(NULL); | 249 | time_t timeval = time(NULL); |
250 | ofs << "# Options file generated at: " << ctime(&timeval) | 250 | ofs << "# Options file generated at: " << ctime(&timeval) |
251 | << "updater = \'" << shared::double_quote(updatername) << "\'" | 251 | << "updater = \'" << shared::double_quote(updatername) << "\'" |
252 | << std::endl | 252 | << std::endl |
253 | << "firmware = \'" << shared::double_quote(firmarename) << "\'" | 253 | << "firmware = \'" << shared::double_quote(firmarename) << "\'" |
254 | << std::endl | 254 | << std::endl |
255 | << "offset = " << (offset_pa - sizeof(dword)) << std::endl | 255 | << "offset = " << (offset_pa - sizeof(dword)) << std::endl |
256 | << "size = " << archive_size << std::endl | 256 | << "size = " << archive_size << std::endl |
257 | << "key = \'" << key << "\'" << std::endl; | 257 | << "key = \'" << key << "\'" << std::endl; |
258 | 258 | ||
259 | return 0; | 259 | return 0; |
260 | } | 260 | } |
261 | 261 | ||
262 | int main(int argc, char* argv[]) | 262 | int main(int argc, char* argv[]) |
263 | { | 263 | { |
264 | try | 264 | try |
265 | { | 265 | { |
266 | return process_arguments(argc, argv); | 266 | return process_arguments(argc, argv); |
267 | } | 267 | } |
268 | catch (const std::exception& xcpt) | 268 | catch (const std::exception& xcpt) |
269 | { | 269 | { |
270 | std::cerr << "Exception caught: " << xcpt.what() << std::endl; | 270 | std::cerr << "Exception caught: " << xcpt.what() << std::endl; |
271 | return -1; | 271 | return -1; |
272 | } | 272 | } |
273 | catch (...) | 273 | catch (...) |
274 | { | 274 | { |
275 | std::cerr << "Unknown exception caught." << std::endl; | 275 | std::cerr << "Unknown exception caught." << std::endl; |
276 | return -2; | 276 | return -2; |
277 | } | 277 | } |
278 | return -3; | 278 | return -3; |
279 | } | 279 | } |