summaryrefslogtreecommitdiff
path: root/utils/zenutils/source
diff options
context:
space:
mode:
Diffstat (limited to 'utils/zenutils/source')
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/CMakeLists.txt12
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/firmware_extract/CMakeLists.txt6
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/firmware_extract/main.cpp486
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/firmware_make/CMakeLists.txt6
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/firmware_make/main.cpp522
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/CMakeLists.txt32
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/cenc.cpp666
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/cenc.h58
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/crypt.cpp182
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/crypt.h60
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/file.cpp212
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/file.h72
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/firmware.cpp774
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/firmware.h184
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/pe.cpp256
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/pe.h284
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/shared.cpp0
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/updater.cpp302
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/updater.h64
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/utils.cpp422
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/shared/utils.h136
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/update_extract/CMakeLists.txt6
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/update_extract/main.cpp558
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/update_patch/CMakeLists.txt6
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/update_patch/main.cpp818
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/zen_crypt/CMakeLists.txt8
-rw-r--r--[-rwxr-xr-x]utils/zenutils/source/zen_crypt/main.cpp1374
27 files changed, 3753 insertions, 3753 deletions
diff --git a/utils/zenutils/source/CMakeLists.txt b/utils/zenutils/source/CMakeLists.txt
index e3d44fd036..e7a4bcf63b 100755..100644
--- a/utils/zenutils/source/CMakeLists.txt
+++ b/utils/zenutils/source/CMakeLists.txt
@@ -1,6 +1,6 @@
1ADD_SUBDIRECTORY(firmware_extract) 1ADD_SUBDIRECTORY(firmware_extract)
2ADD_SUBDIRECTORY(firmware_make) 2ADD_SUBDIRECTORY(firmware_make)
3ADD_SUBDIRECTORY(shared) 3ADD_SUBDIRECTORY(shared)
4ADD_SUBDIRECTORY(update_extract) 4ADD_SUBDIRECTORY(update_extract)
5ADD_SUBDIRECTORY(update_patch) 5ADD_SUBDIRECTORY(update_patch)
6ADD_SUBDIRECTORY(zen_crypt) 6ADD_SUBDIRECTORY(zen_crypt)
diff --git a/utils/zenutils/source/firmware_extract/CMakeLists.txt b/utils/zenutils/source/firmware_extract/CMakeLists.txt
index 3814f03612..43af3e3235 100755..100644
--- a/utils/zenutils/source/firmware_extract/CMakeLists.txt
+++ b/utils/zenutils/source/firmware_extract/CMakeLists.txt
@@ -1,3 +1,3 @@
1ADD_EXECUTABLE(firmware_extract main.cpp) 1ADD_EXECUTABLE(firmware_extract main.cpp)
2 2
3TARGET_LINK_LIBRARIES(firmware_extract shared) 3TARGET_LINK_LIBRARIES(firmware_extract shared)
diff --git a/utils/zenutils/source/firmware_extract/main.cpp b/utils/zenutils/source/firmware_extract/main.cpp
index c677a91a75..bcd77afdfc 100755..100644
--- a/utils/zenutils/source/firmware_extract/main.cpp
+++ b/utils/zenutils/source/firmware_extract/main.cpp
@@ -1,243 +1,243 @@
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 <ctime> 20#include <ctime>
21#include <getpot/getpot.hpp> 21#include <getpot/getpot.hpp>
22#include <utils.h> 22#include <utils.h>
23#include <firmware.h> 23#include <firmware.h>
24 24
25 25
26static const char VERSION[] = "0.1"; 26static const char VERSION[] = "0.1";
27 27
28 28
29void print_version() 29void print_version()
30{ 30{
31 std::cout 31 std::cout
32 << "firmware_extract - Extracts files from a Creative firmware." 32 << "firmware_extract - Extracts files from a Creative firmware."
33 << std::endl 33 << std::endl
34 << "Version " << VERSION << std::endl 34 << "Version " << VERSION << std::endl
35 << "Copyright (c) 2007 Rasmus Ry" << std::endl; 35 << "Copyright (c) 2007 Rasmus Ry" << std::endl;
36} 36}
37 37
38void print_help() 38void print_help()
39{ 39{
40 print_version(); 40 print_version();
41 std::cout 41 std::cout
42 << "Usage: firmware_extract [command] [options]" << std::endl 42 << "Usage: firmware_extract [command] [options]" << std::endl
43 << std::endl 43 << std::endl
44 << " Commands:" << std::endl 44 << " Commands:" << std::endl
45 << " -h,--help" << std::endl 45 << " -h,--help" << std::endl
46 << " prints this message." << std::endl 46 << " prints this message." << std::endl
47 << " -f,--firmware [file]" << std::endl 47 << " -f,--firmware [file]" << std::endl
48 << " specifies the firmware arhive file name." << std::endl 48 << " specifies the firmware arhive file name." << std::endl
49 << std::endl 49 << std::endl
50 << " Options:" << std::endl 50 << " Options:" << std::endl
51 << " -V,--verbose" << std::endl 51 << " -V,--verbose" << std::endl
52 << " prints verbose messages." << std::endl 52 << " prints verbose messages." << std::endl
53 << " -p,--prefix [prefix]" << std::endl 53 << " -p,--prefix [prefix]" << std::endl
54 << " specifies a file name prefix for the extracted files." << std::endl 54 << " specifies a file name prefix for the extracted files." << std::endl
55 << std::endl 55 << std::endl
56 ; 56 ;
57} 57}
58 58
59 59
60struct save_entry_functor 60struct save_entry_functor
61{ 61{
62 save_entry_functor(const std::string& fileprefix) 62 save_entry_functor(const std::string& fileprefix)
63 : _fileprefix(fileprefix) {} 63 : _fileprefix(fileprefix) {}
64 64
65 bool operator()(const zen::firmware_entry& entry) 65 bool operator()(const zen::firmware_entry& entry)
66 { 66 {
67 std::string filename = _fileprefix + entry.get_content_name(); 67 std::string filename = _fileprefix + entry.get_content_name();
68 std::ofstream ofs; 68 std::ofstream ofs;
69 ofs.open(filename.c_str(), std::ios::binary); 69 ofs.open(filename.c_str(), std::ios::binary);
70 if (!ofs) 70 if (!ofs)
71 false; 71 false;
72 72
73 size_t off = entry.get_content_offset(); 73 size_t off = entry.get_content_offset();
74 std::streamsize size = entry.get_bytes().size() - off; 74 std::streamsize size = entry.get_bytes().size() - off;
75 ofs.write((const char*)&entry.get_bytes()[off], size); 75 ofs.write((const char*)&entry.get_bytes()[off], size);
76 76
77 return ofs.good(); 77 return ofs.good();
78 } 78 }
79 79
80 const std::string& _fileprefix; 80 const std::string& _fileprefix;
81}; //struct save_entry_functor 81}; //struct save_entry_functor
82 82
83struct print_entry_functor 83struct print_entry_functor
84{ 84{
85 print_entry_functor(std::ostream& os, const std::string& fileprefix) 85 print_entry_functor(std::ostream& os, const std::string& fileprefix)
86 : _os(os), _fileprefix(fileprefix), num(0) {} 86 : _os(os), _fileprefix(fileprefix), num(0) {}
87 87
88 bool operator()(const zen::firmware_entry& entry) 88 bool operator()(const zen::firmware_entry& entry)
89 { 89 {
90 std::string filename = _fileprefix + entry.get_content_name(); 90 std::string filename = _fileprefix + entry.get_content_name();
91 if (!num) 91 if (!num)
92 _os << "[./" << num++ << "]" << std::endl; 92 _os << "[./" << num++ << "]" << std::endl;
93 else 93 else
94 _os << "[../" << num++ << "]" << std::endl; 94 _os << "[../" << num++ << "]" << std::endl;
95 _os << "tag = " << entry.get_name() << std::endl; 95 _os << "tag = " << entry.get_name() << std::endl;
96 96
97 if (entry.get_content_offset()) 97 if (entry.get_content_offset())
98 _os << "name = " << entry.get_content_name() << std::endl; 98 _os << "name = " << entry.get_content_name() << std::endl;
99 99
100 _os << "file = \'" << shared::double_quote(filename) << "\'" 100 _os << "file = \'" << shared::double_quote(filename) << "\'"
101 << std::endl; 101 << std::endl;
102 102
103 return _os.good(); 103 return _os.good();
104 } 104 }
105 105
106 std::ostream& _os; 106 std::ostream& _os;
107 const std::string& _fileprefix; 107 const std::string& _fileprefix;
108 int num; 108 int num;
109}; //struct print_entry_functor 109}; //struct print_entry_functor
110 110
111 111
112int process_arguments(int argc, char* argv[]) 112int process_arguments(int argc, char* argv[])
113{ 113{
114 //-------------------------------------------------------------------- 114 //--------------------------------------------------------------------
115 // Parse input variables. 115 // Parse input variables.
116 //-------------------------------------------------------------------- 116 //--------------------------------------------------------------------
117 117
118 GetPot cl(argc, argv); 118 GetPot cl(argc, argv);
119 if (cl.size() == 1 || cl.search(2, "-h", "--help")) 119 if (cl.size() == 1 || cl.search(2, "-h", "--help"))
120 { 120 {
121 print_help(); 121 print_help();
122 return 1; 122 return 1;
123 } 123 }
124 124
125 std::string firmwarename; 125 std::string firmwarename;
126 if (cl.search("-f") || cl.search("--firmware")) 126 if (cl.search("-f") || cl.search("--firmware"))
127 firmwarename = cl.next(""); 127 firmwarename = cl.next("");
128 if (firmwarename.empty()) 128 if (firmwarename.empty())
129 { 129 {
130 std::cerr << "Firmware archive must be specified." << std::endl; 130 std::cerr << "Firmware archive must be specified." << std::endl;
131 return 2; 131 return 2;
132 } 132 }
133 133
134 bool verbose = false; 134 bool verbose = false;
135 if (cl.search("-V") || cl.search("--verbose")) 135 if (cl.search("-V") || cl.search("--verbose"))
136 verbose = true; 136 verbose = true;
137 137
138 std::string prefixname = shared::remove_extension(firmwarename) + "_"; 138 std::string prefixname = shared::remove_extension(firmwarename) + "_";
139 if (cl.search("-p") || cl.search("--prefix")) 139 if (cl.search("-p") || cl.search("--prefix"))
140 prefixname = cl.next(prefixname.c_str()); 140 prefixname = cl.next(prefixname.c_str());
141 141
142 142
143 //-------------------------------------------------------------------- 143 //--------------------------------------------------------------------
144 // Read the firmware archive. 144 // Read the firmware archive.
145 //-------------------------------------------------------------------- 145 //--------------------------------------------------------------------
146 146
147 if (verbose) 147 if (verbose)
148 std::cout << "[*] Reading firmware archive..." << std::endl; 148 std::cout << "[*] Reading firmware archive..." << std::endl;
149 149
150 zen::firmware_archive archive(false); 150 zen::firmware_archive archive(false);
151 std::ifstream ifs; 151 std::ifstream ifs;
152 ifs.open(firmwarename.c_str(), std::ios::binary); 152 ifs.open(firmwarename.c_str(), std::ios::binary);
153 if (!ifs) 153 if (!ifs)
154 { 154 {
155 std::cerr << "Failed to open the firmware archive." << std::endl; 155 std::cerr << "Failed to open the firmware archive." << std::endl;
156 return 3; 156 return 3;
157 } 157 }
158 158
159 if (!archive.read(ifs)) 159 if (!archive.read(ifs))
160 { 160 {
161 std::cerr << "Failed to read the firmware archive." << std::endl; 161 std::cerr << "Failed to read the firmware archive." << std::endl;
162 return 4; 162 return 4;
163 } 163 }
164 164
165 165
166 //-------------------------------------------------------------------- 166 //--------------------------------------------------------------------
167 // Generate a make file for the extracted firmware archive. 167 // Generate a make file for the extracted firmware archive.
168 //-------------------------------------------------------------------- 168 //--------------------------------------------------------------------
169 169
170 // Get make filename for the given input file. 170 // Get make filename for the given input file.
171 std::string makefile = shared::replace_extension(firmwarename, ".mk"); 171 std::string makefile = shared::replace_extension(firmwarename, ".mk");
172 172
173 if (verbose) 173 if (verbose)
174 std::cout << "[*] Producing make file..." << std::endl; 174 std::cout << "[*] Producing make file..." << std::endl;
175 175
176 176
177 // Produce make file for the given input file. 177 // Produce make file for the given input file.
178 std::ofstream ofs; 178 std::ofstream ofs;
179 ofs.open(makefile.c_str(), std::ios::binary); 179 ofs.open(makefile.c_str(), std::ios::binary);
180 if (!ofs) 180 if (!ofs)
181 { 181 {
182 std::cerr << "Failed to create firmware archive make file." 182 std::cerr << "Failed to create firmware archive make file."
183 << std::endl; 183 << std::endl;
184 return 5; 184 return 5;
185 } 185 }
186 186
187 time_t timeval = time(NULL); 187 time_t timeval = time(NULL);
188 ofs << "# Make file generated at: " << ctime(&timeval); 188 ofs << "# Make file generated at: " << ctime(&timeval);
189 ofs << "endian = " << (archive.is_big_endian() ? "big" : "little") 189 ofs << "endian = " << (archive.is_big_endian() ? "big" : "little")
190 << std::endl; 190 << std::endl;
191 ofs << "signed = " << (archive.is_signed() ? "true" : "false") 191 ofs << "signed = " << (archive.is_signed() ? "true" : "false")
192 << std::endl; 192 << std::endl;
193 193
194 ofs << "[children]" << std::endl; 194 ofs << "[children]" << std::endl;
195 ofs << "count = " << archive.get_children().size() << std::endl; 195 ofs << "count = " << archive.get_children().size() << std::endl;
196 196
197 std::for_each(archive.get_children().begin(), 197 std::for_each(archive.get_children().begin(),
198 archive.get_children().end(), 198 archive.get_children().end(),
199 print_entry_functor(ofs, prefixname)); 199 print_entry_functor(ofs, prefixname));
200 200
201 ofs << "[neighbours]" << std::endl; 201 ofs << "[neighbours]" << std::endl;
202 ofs << "count = " << archive.get_neighbours().size() << std::endl; 202 ofs << "count = " << archive.get_neighbours().size() << std::endl;
203 std::for_each(archive.get_neighbours().begin(), 203 std::for_each(archive.get_neighbours().begin(),
204 archive.get_neighbours().end(), 204 archive.get_neighbours().end(),
205 print_entry_functor(ofs, prefixname)); 205 print_entry_functor(ofs, prefixname));
206 206
207 207
208 //-------------------------------------------------------------------- 208 //--------------------------------------------------------------------
209 // Save firmware entries. 209 // Save firmware entries.
210 //-------------------------------------------------------------------- 210 //--------------------------------------------------------------------
211 211
212 if (verbose) 212 if (verbose)
213 std::cout << "[*] Saving firmware entries..." << std::endl; 213 std::cout << "[*] Saving firmware entries..." << std::endl;
214 214
215 std::for_each(archive.get_children().begin(), 215 std::for_each(archive.get_children().begin(),
216 archive.get_children().end(), 216 archive.get_children().end(),
217 save_entry_functor(prefixname)); 217 save_entry_functor(prefixname));
218 218
219 std::for_each(archive.get_neighbours().begin(), 219 std::for_each(archive.get_neighbours().begin(),
220 archive.get_neighbours().end(), 220 archive.get_neighbours().end(),
221 save_entry_functor(prefixname)); 221 save_entry_functor(prefixname));
222 222
223 return 0; 223 return 0;
224} 224}
225 225
226int main(int argc, char* argv[]) 226int main(int argc, char* argv[])
227{ 227{
228 try 228 try
229 { 229 {
230 return process_arguments(argc, argv); 230 return process_arguments(argc, argv);
231 } 231 }
232 catch (const std::exception& xcpt) 232 catch (const std::exception& xcpt)
233 { 233 {
234 std::cerr << "Exception caught: " << xcpt.what() << std::endl; 234 std::cerr << "Exception caught: " << xcpt.what() << std::endl;
235 return -1; 235 return -1;
236 } 236 }
237 catch (...) 237 catch (...)
238 { 238 {
239 std::cerr << "Unknown exception caught." << std::endl; 239 std::cerr << "Unknown exception caught." << std::endl;
240 return -2; 240 return -2;
241 } 241 }
242 return -3; 242 return -3;
243} 243}
diff --git a/utils/zenutils/source/firmware_make/CMakeLists.txt b/utils/zenutils/source/firmware_make/CMakeLists.txt
index 518a008730..39197e2f07 100755..100644
--- a/utils/zenutils/source/firmware_make/CMakeLists.txt
+++ b/utils/zenutils/source/firmware_make/CMakeLists.txt
@@ -1,3 +1,3 @@
1ADD_EXECUTABLE(firmware_make main.cpp) 1ADD_EXECUTABLE(firmware_make main.cpp)
2 2
3TARGET_LINK_LIBRARIES (firmware_make shared) 3TARGET_LINK_LIBRARIES (firmware_make shared)
diff --git a/utils/zenutils/source/firmware_make/main.cpp b/utils/zenutils/source/firmware_make/main.cpp
index b0602b6ffe..35d036e601 100755..100644
--- a/utils/zenutils/source/firmware_make/main.cpp
+++ b/utils/zenutils/source/firmware_make/main.cpp
@@ -1,261 +1,261 @@
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 <sstream> 20#include <sstream>
21#include <getpot/getpot.hpp> 21#include <getpot/getpot.hpp>
22#include <file.h> 22#include <file.h>
23#include <firmware.h> 23#include <firmware.h>
24#include <utils.h> 24#include <utils.h>
25 25
26 26
27static const char VERSION[] = "0.1"; 27static const char VERSION[] = "0.1";
28 28
29void print_version() 29void print_version()
30{ 30{
31 std::cout 31 std::cout
32 << "firmware_make - Creates a Creative firmware archive." << std::endl 32 << "firmware_make - Creates a Creative firmware archive." << std::endl
33 << "Version " << VERSION << std::endl 33 << "Version " << VERSION << std::endl
34 << "Copyright (c) 2007 Rasmus Ry" << std::endl; 34 << "Copyright (c) 2007 Rasmus Ry" << std::endl;
35} 35}
36 36
37void print_help() 37void print_help()
38{ 38{
39 print_version(); 39 print_version();
40 std::cout << std::endl 40 std::cout << std::endl
41 << "Usage: firmware_make [command] [options]" << std::endl 41 << "Usage: firmware_make [command] [options]" << std::endl
42 << std::endl 42 << std::endl
43 << " Commands:" << std::endl 43 << " Commands:" << std::endl
44 << " -h,--help" << std::endl 44 << " -h,--help" << std::endl
45 << " prints this message." << std::endl 45 << " prints this message." << std::endl
46 << " -m,--makefile [file]" << std::endl 46 << " -m,--makefile [file]" << std::endl
47 << " specifies the .mk file to build the firmware archive from." 47 << " specifies the .mk file to build the firmware archive from."
48 << std::endl << std::endl 48 << std::endl << std::endl
49 << " Options:" << std::endl 49 << " Options:" << std::endl
50 << " -V,--verbose" << std::endl 50 << " -V,--verbose" << std::endl
51 << " prints verbose messages." << std::endl 51 << " prints verbose messages." << std::endl
52 << " -f,--firmware [file]" << std::endl 52 << " -f,--firmware [file]" << std::endl
53 << " specifies the output firmware file name" << std::endl 53 << " specifies the output firmware file name" << std::endl
54 << std::endl 54 << std::endl
55 ; 55 ;
56} 56}
57 57
58dword get_tag_value(std::string tag) 58dword get_tag_value(std::string tag)
59{ 59{
60 if (tag[0] == '0' && tag[1] == 'x') 60 if (tag[0] == '0' && tag[1] == 'x')
61 { 61 {
62 dword val = 0; 62 dword val = 0;
63 if (sscanf(tag.c_str(), "0x%08X", &val) == 1) 63 if (sscanf(tag.c_str(), "0x%08X", &val) == 1)
64 return val; 64 return val;
65 if (sscanf(tag.c_str(), "0x%08x", &val) == 1) 65 if (sscanf(tag.c_str(), "0x%08x", &val) == 1)
66 return val; 66 return val;
67 } 67 }
68 else 68 else
69 { 69 {
70 return shared::swap(*(dword*)&tag[0]); 70 return shared::swap(*(dword*)&tag[0]);
71 } 71 }
72 return 0; 72 return 0;
73} 73}
74 74
75bool process_child(const GetPot& mkfile, const std::string& root, int index, 75bool process_child(const GetPot& mkfile, const std::string& root, int index,
76 zen::firmware_entry& entry) 76 zen::firmware_entry& entry)
77{ 77{
78 std::stringstream sstm; 78 std::stringstream sstm;
79 sstm << root << "/" << index; 79 sstm << root << "/" << index;
80 std::string var = sstm.str() + "/tag"; 80 std::string var = sstm.str() + "/tag";
81 std::string tag = mkfile(var.c_str(), ""); 81 std::string tag = mkfile(var.c_str(), "");
82 var = sstm.str() + "/name"; 82 var = sstm.str() + "/name";
83 std::string name = mkfile(var.c_str(), ""); 83 std::string name = mkfile(var.c_str(), "");
84 var = sstm.str() + "/file"; 84 var = sstm.str() + "/file";
85 std::string file = mkfile(var.c_str(), ""); 85 std::string file = mkfile(var.c_str(), "");
86 86
87 if (file.empty() || tag.empty()) 87 if (file.empty() || tag.empty())
88 { 88 {
89 std::cerr << "Invalid file or tag for var: " << sstm.str() 89 std::cerr << "Invalid file or tag for var: " << sstm.str()
90 << std::endl; 90 << std::endl;
91 return false; 91 return false;
92 } 92 }
93 93
94 shared::bytes buffer; 94 shared::bytes buffer;
95 if (!shared::read_file(file, buffer)) 95 if (!shared::read_file(file, buffer))
96 { 96 {
97 std::cerr << "Failed to read the file: " << file << std::endl; 97 std::cerr << "Failed to read the file: " << file << std::endl;
98 return false; 98 return false;
99 } 99 }
100 100
101 entry.get_bytes().clear(); 101 entry.get_bytes().clear();
102 entry.get_header().tag = get_tag_value(tag); 102 entry.get_header().tag = get_tag_value(tag);
103 size_t contoff = entry.get_content_offset(); 103 size_t contoff = entry.get_content_offset();
104 if (contoff) 104 if (contoff)
105 { 105 {
106 entry.get_bytes().resize(contoff, 0); 106 entry.get_bytes().resize(contoff, 0);
107 if (!name.empty()) 107 if (!name.empty())
108 { 108 {
109 size_t endoff = entry.is_big_endian() ? 1 : 0; 109 size_t endoff = entry.is_big_endian() ? 1 : 0;
110 for (int i = 0; i < name.size(); ++i) 110 for (int i = 0; i < name.size(); ++i)
111 entry.get_bytes()[i * 2 + endoff] = name[i]; 111 entry.get_bytes()[i * 2 + endoff] = name[i];
112 } 112 }
113 } 113 }
114 entry.get_bytes().insert(entry.get_bytes().end(), buffer.begin(), 114 entry.get_bytes().insert(entry.get_bytes().end(), buffer.begin(),
115 buffer.end()); 115 buffer.end());
116 116
117 entry.get_header().size = entry.get_bytes().size(); 117 entry.get_header().size = entry.get_bytes().size();
118 118
119 return true; 119 return true;
120} 120}
121 121
122int process_arguments(int argc, char* argv[]) 122int process_arguments(int argc, char* argv[])
123{ 123{
124 //-------------------------------------------------------------------- 124 //--------------------------------------------------------------------
125 // Parse input variables. 125 // Parse input variables.
126 //-------------------------------------------------------------------- 126 //--------------------------------------------------------------------
127 127
128 GetPot cl(argc, argv); 128 GetPot cl(argc, argv);
129 if (cl.size() == 1 || cl.search(2, "-h", "--help")) 129 if (cl.size() == 1 || cl.search(2, "-h", "--help"))
130 { 130 {
131 print_help(); 131 print_help();
132 return 1; 132 return 1;
133 } 133 }
134 134
135 std::string makefile; 135 std::string makefile;
136 if (cl.search("-m") || cl.search("--makefile")) 136 if (cl.search("-m") || cl.search("--makefile"))
137 makefile = cl.next(""); 137 makefile = cl.next("");
138 if (makefile.empty()) 138 if (makefile.empty())
139 { 139 {
140 std::cerr << "Makefile must be specified." << std::endl; 140 std::cerr << "Makefile must be specified." << std::endl;
141 return 2; 141 return 2;
142 } 142 }
143 143
144 std::string firmware; 144 std::string firmware;
145 if (cl.search("-f") || cl.search("--firmware")) 145 if (cl.search("-f") || cl.search("--firmware"))
146 firmware = cl.next(""); 146 firmware = cl.next("");
147 if (firmware.empty()) 147 if (firmware.empty())
148 { 148 {
149 std::cerr << "Firmware must be specified." << std::endl; 149 std::cerr << "Firmware must be specified." << std::endl;
150 return 3; 150 return 3;
151 } 151 }
152 152
153 bool verbose = false; 153 bool verbose = false;
154 if (cl.search("-V") || cl.search("--verbose")) 154 if (cl.search("-V") || cl.search("--verbose"))
155 verbose = true; 155 verbose = true;
156 156
157 GetPot mkfile(makefile.c_str()); 157 GetPot mkfile(makefile.c_str());
158 if (verbose) 158 if (verbose)
159 mkfile.print(); 159 mkfile.print();
160 160
161 bool big_endian; 161 bool big_endian;
162 std::string endian = mkfile("endian", "little"); 162 std::string endian = mkfile("endian", "little");
163 if (endian == "little") 163 if (endian == "little")
164 { 164 {
165 big_endian = false; 165 big_endian = false;
166 } 166 }
167 else if (endian == "big") 167 else if (endian == "big")
168 { 168 {
169 big_endian = true; 169 big_endian = true;
170 } 170 }
171 else 171 else
172 { 172 {
173 std::cerr << "Invalid value of 'endian'" << std::endl; 173 std::cerr << "Invalid value of 'endian'" << std::endl;
174 return 4; 174 return 4;
175 } 175 }
176 176
177 zen::firmware_archive archive(big_endian); 177 zen::firmware_archive archive(big_endian);
178 int childcount = mkfile("children/count", 0); 178 int childcount = mkfile("children/count", 0);
179 if (!childcount) 179 if (!childcount)
180 { 180 {
181 std::cerr << "A firmware archive must have at least one child entry." 181 std::cerr << "A firmware archive must have at least one child entry."
182 << std::endl; 182 << std::endl;
183 return 5; 183 return 5;
184 } 184 }
185 185
186 for (int i = 0; i < childcount; i++) 186 for (int i = 0; i < childcount; i++)
187 { 187 {
188 zen::firmware_entry entry(big_endian); 188 zen::firmware_entry entry(big_endian);
189 if (!process_child(mkfile, "children", i, entry)) 189 if (!process_child(mkfile, "children", i, entry))
190 { 190 {
191 return 6; 191 return 6;
192 } 192 }
193 archive.get_children().push_back(entry); 193 archive.get_children().push_back(entry);
194 } 194 }
195 195
196 int neighbourcount = mkfile("neighbours/count", 0); 196 int neighbourcount = mkfile("neighbours/count", 0);
197 for (int i = 0; i < neighbourcount; i++) 197 for (int i = 0; i < neighbourcount; i++)
198 { 198 {
199 zen::firmware_entry entry(big_endian); 199 zen::firmware_entry entry(big_endian);
200 if (!process_child(mkfile, "neighbours", i, entry)) 200 if (!process_child(mkfile, "neighbours", i, entry))
201 { 201 {
202 return 7; 202 return 7;
203 } 203 }
204 archive.get_neighbours().push_back(entry); 204 archive.get_neighbours().push_back(entry);
205 } 205 }
206 206
207 std::ofstream ofs; 207 std::ofstream ofs;
208 ofs.open(firmware.c_str(), std::ios::out|std::ios::binary|std::ios::trunc); 208 ofs.open(firmware.c_str(), std::ios::out|std::ios::binary|std::ios::trunc);
209 if (!ofs) 209 if (!ofs)
210 { 210 {
211 std::cerr << "Failed to create the firmware file." << std::endl; 211 std::cerr << "Failed to create the firmware file." << std::endl;
212 return 8; 212 return 8;
213 } 213 }
214 214
215 if (!archive.write(ofs)) 215 if (!archive.write(ofs))
216 { 216 {
217 std::cerr << "Failed to save the firmware archive." << std::endl; 217 std::cerr << "Failed to save the firmware archive." << std::endl;
218 return 9; 218 return 9;
219 } 219 }
220 ofs.close(); 220 ofs.close();
221 221
222 size_t length = archive.calc_size(); 222 size_t length = archive.calc_size();
223 if (!length) 223 if (!length)
224 { 224 {
225 std::cerr << "Failed to determine the size of the firmware archive." 225 std::cerr << "Failed to determine the size of the firmware archive."
226 << std::endl; 226 << std::endl;
227 return 10; 227 return 10;
228 } 228 }
229 229
230 int align = length % 4; 230 int align = length % 4;
231 if (align) 231 if (align)
232 { 232 {
233 shared::bytes padding(4 - align, 0); 233 shared::bytes padding(4 - align, 0);
234 if (!shared::write_file(firmware, padding, false, length)) 234 if (!shared::write_file(firmware, padding, false, length))
235 { 235 {
236 std::cerr << "Failed to write padding data." << std::endl; 236 std::cerr << "Failed to write padding data." << std::endl;
237 return 11; 237 return 11;
238 } 238 }
239 } 239 }
240 240
241 return 0; 241 return 0;
242} 242}
243 243
244int main(int argc, char* argv[]) 244int main(int argc, char* argv[])
245{ 245{
246 try 246 try
247 { 247 {
248 return process_arguments(argc, argv); 248 return process_arguments(argc, argv);
249 } 249 }
250 catch (const std::exception& xcpt) 250 catch (const std::exception& xcpt)
251 { 251 {
252 std::cerr << "Exception caught: " << xcpt.what() << std::endl; 252 std::cerr << "Exception caught: " << xcpt.what() << std::endl;
253 return -1; 253 return -1;
254 } 254 }
255 catch (...) 255 catch (...)
256 { 256 {
257 std::cerr << "Unknown exception caught." << std::endl; 257 std::cerr << "Unknown exception caught." << std::endl;
258 return -2; 258 return -2;
259 } 259 }
260 return -3; 260 return -3;
261} 261}
diff --git a/utils/zenutils/source/shared/CMakeLists.txt b/utils/zenutils/source/shared/CMakeLists.txt
index 2e42dbbe74..751257f64f 100755..100644
--- a/utils/zenutils/source/shared/CMakeLists.txt
+++ b/utils/zenutils/source/shared/CMakeLists.txt
@@ -1,16 +1,16 @@
1PROJECT(shared) 1PROJECT(shared)
2 2
3# source files for shared 3# source files for shared
4SET(shared_srcs 4SET(shared_srcs
5 cenc.cpp 5 cenc.cpp
6 crypt.cpp 6 crypt.cpp
7 file.cpp 7 file.cpp
8 firmware.cpp 8 firmware.cpp
9 pe.cpp 9 pe.cpp
10 updater.cpp 10 updater.cpp
11 utils.cpp 11 utils.cpp
12) 12)
13 13
14ADD_LIBRARY(shared ${shared_srcs}) 14ADD_LIBRARY(shared ${shared_srcs})
15TARGET_LINK_LIBRARIES(shared pelib) 15TARGET_LINK_LIBRARIES(shared pelib)
16TARGET_LINK_LIBRARIES(shared zlib) 16TARGET_LINK_LIBRARIES(shared zlib)
diff --git a/utils/zenutils/source/shared/cenc.cpp b/utils/zenutils/source/shared/cenc.cpp
index 932bee4625..929a59b64d 100755..100644
--- a/utils/zenutils/source/shared/cenc.cpp
+++ b/utils/zenutils/source/shared/cenc.cpp
@@ -1,333 +1,333 @@
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 "cenc.h" 19#include "cenc.h"
20#include <firmware.h> 20#include <firmware.h>
21#include <stdexcept> 21#include <stdexcept>
22 22
23 23
24namespace { 24namespace {
25const byte CODE_MASK = 0xC0; 25const byte CODE_MASK = 0xC0;
26const byte ARGS_MASK = 0x3F; 26const byte ARGS_MASK = 0x3F;
27 27
28const byte REPEAT_CODE = 0x00; 28const byte REPEAT_CODE = 0x00;
29const byte BLOCK_CODE = 0x40; 29const byte BLOCK_CODE = 0x40;
30const byte LONG_RUN_CODE = 0x80; 30const byte LONG_RUN_CODE = 0x80;
31const byte SHORT_RUN_CODE = 0xC0; 31const byte SHORT_RUN_CODE = 0xC0;
32 32
33const byte BLOCK_ARGS = 0x1F; 33const byte BLOCK_ARGS = 0x1F;
34const byte BLOCK_MODE = 0x20; 34const byte BLOCK_MODE = 0x20;
35 35
36 36
37void decode_run(byte* dst, word len, byte val, 37void decode_run(byte* dst, word len, byte val,
38 int& dstidx) 38 int& dstidx)
39{ 39{
40 memset(dst + dstidx, val, len); 40 memset(dst + dstidx, val, len);
41 dstidx += len; 41 dstidx += len;
42} 42}
43 43
44void decode_pattern(byte* src, byte* dst, 44void decode_pattern(byte* src, byte* dst,
45 word len, int& srcidx, int& dstidx, 45 word len, int& srcidx, int& dstidx,
46 bool bdecode, int npasses) 46 bool bdecode, int npasses)
47{ 47{
48 for (int i = 0; i < npasses; i++) 48 for (int i = 0; i < npasses; i++)
49 { 49 {
50 if (bdecode) 50 if (bdecode)
51 { 51 {
52 for (int j = 0; j < len; j++) 52 for (int j = 0; j < len; j++)
53 { 53 {
54 word c, d; 54 word c, d;
55 c = src[srcidx + j]; 55 c = src[srcidx + j];
56 d = (c >> 5) & 7; 56 d = (c >> 5) & 7;
57 c = (c << 3) & 0xF8; 57 c = (c << 3) & 0xF8;
58 src[srcidx + j] = static_cast<byte>(c | d); 58 src[srcidx + j] = static_cast<byte>(c | d);
59 } 59 }
60 bdecode = false; 60 bdecode = false;
61 } 61 }
62 memcpy(dst + dstidx, src + srcidx, len); 62 memcpy(dst + dstidx, src + srcidx, len);
63 dstidx += len; 63 dstidx += len;
64 } 64 }
65 srcidx += len; 65 srcidx += len;
66} 66}
67}; //namespace 67}; //namespace
68 68
69int zen::cenc_decode(byte* src, int srclen, byte* dst, int dstlen) 69int zen::cenc_decode(byte* src, int srclen, byte* dst, int dstlen)
70{ 70{
71 if (!src || !srclen || !dst || !dstlen) 71 if (!src || !srclen || !dst || !dstlen)
72 { 72 {
73 throw std::invalid_argument("Invalid argument(s)."); 73 throw std::invalid_argument("Invalid argument(s).");
74 } 74 }
75 75
76 int i = 0, j = 0; 76 int i = 0, j = 0;
77 do 77 do
78 { 78 {
79 word c, d, e; 79 word c, d, e;
80 c = src[i++]; 80 c = src[i++];
81 switch (c & CODE_MASK) 81 switch (c & CODE_MASK)
82 { 82 {
83 case REPEAT_CODE: // 2 bytes 83 case REPEAT_CODE: // 2 bytes
84 d = src[i++]; 84 d = src[i++];
85 d = d + 2; 85 d = d + 2;
86 86
87 e = (c & ARGS_MASK) + 2; 87 e = (c & ARGS_MASK) + 2;
88 88
89 decode_pattern(src, dst, e, i, j, false, d); 89 decode_pattern(src, dst, e, i, j, false, d);
90 break; 90 break;
91 91
92 case BLOCK_CODE: // 1/2/3 bytes 92 case BLOCK_CODE: // 1/2/3 bytes
93 d = c & BLOCK_ARGS; 93 d = c & BLOCK_ARGS;
94 if (!(c & BLOCK_MODE)) 94 if (!(c & BLOCK_MODE))
95 { 95 {
96 e = src[i++]; 96 e = src[i++];
97 e = (d << 8) + (e + 0x21); 97 e = (d << 8) + (e + 0x21);
98 98
99 d = static_cast<word>(i ^ j); 99 d = static_cast<word>(i ^ j);
100 } 100 }
101 else 101 else
102 { 102 {
103 e = d + 1; 103 e = d + 1;
104 104
105 d = static_cast<word>(i ^ j); 105 d = static_cast<word>(i ^ j);
106 } 106 }
107 if (d & 1) 107 if (d & 1)
108 { 108 {
109 i++; 109 i++;
110 } 110 }
111 111
112 decode_pattern(src, dst, e, i, j, true, 1); 112 decode_pattern(src, dst, e, i, j, true, 1);
113 break; 113 break;
114 114
115 case LONG_RUN_CODE: // 3 bytes 115 case LONG_RUN_CODE: // 3 bytes
116 d = src[i++]; 116 d = src[i++];
117 e = ((c & ARGS_MASK) << 8) + (d + 0x42); 117 e = ((c & ARGS_MASK) << 8) + (d + 0x42);
118 118
119 d = src[i++]; 119 d = src[i++];
120 d = ((d & 7) << 5) | ((d >> 3) & 0x1F); 120 d = ((d & 7) << 5) | ((d >> 3) & 0x1F);
121 121
122 decode_run(dst, e, static_cast<byte>(d), j); 122 decode_run(dst, e, static_cast<byte>(d), j);
123 break; 123 break;
124 124
125 case SHORT_RUN_CODE: // 2 bytes 125 case SHORT_RUN_CODE: // 2 bytes
126 d = src[i++]; 126 d = src[i++];
127 d = ((d & 3) << 6) | ((d >> 2) & 0x3F); 127 d = ((d & 3) << 6) | ((d >> 2) & 0x3F);
128 128
129 e = (c & ARGS_MASK) + 2; 129 e = (c & ARGS_MASK) + 2;
130 130
131 decode_run(dst, e, static_cast<byte>(d), j); 131 decode_run(dst, e, static_cast<byte>(d), j);
132 break; 132 break;
133 }; 133 };
134 } while (i < srclen && j < dstlen); 134 } while (i < srclen && j < dstlen);
135 135
136 return j; 136 return j;
137} 137}
138 138
139namespace { 139namespace {
140int encode_run(byte* dst, int& dstidx, byte val, int len, int dstlen) 140int encode_run(byte* dst, int& dstidx, byte val, int len, int dstlen)
141{ 141{
142 if (len < 2) 142 if (len < 2)
143 throw std::invalid_argument("Length is too small."); 143 throw std::invalid_argument("Length is too small.");
144 144
145 int ret = 0; 145 int ret = 0;
146 if (len <= 0x41) 146 if (len <= 0x41)
147 { 147 {
148 if ((dstidx + 2) > dstlen) 148 if ((dstidx + 2) > dstlen)
149 throw std::runtime_error("Not enough space to store run."); 149 throw std::runtime_error("Not enough space to store run.");
150 150
151 dst[dstidx++] = SHORT_RUN_CODE | (((len - 2) & ARGS_MASK)); 151 dst[dstidx++] = SHORT_RUN_CODE | (((len - 2) & ARGS_MASK));
152 dst[dstidx++] = ((val >> 6) & 3) | ((val & 0x3F) << 2); 152 dst[dstidx++] = ((val >> 6) & 3) | ((val & 0x3F) << 2);
153 153
154 ret = 2; 154 ret = 2;
155 } 155 }
156 else if (len <= 0x4041) 156 else if (len <= 0x4041)
157 { 157 {
158 if ((dstidx + 3) > dstlen) 158 if ((dstidx + 3) > dstlen)
159 throw std::runtime_error("Not enough space to store run."); 159 throw std::runtime_error("Not enough space to store run.");
160 160
161 byte b1 = (len - 0x42) >> 8; 161 byte b1 = (len - 0x42) >> 8;
162 byte b2 = (len - 0x42) & 0xFF; 162 byte b2 = (len - 0x42) & 0xFF;
163 163
164 dst[dstidx++] = LONG_RUN_CODE | ((b1 & ARGS_MASK)); 164 dst[dstidx++] = LONG_RUN_CODE | ((b1 & ARGS_MASK));
165 dst[dstidx++] = b2; 165 dst[dstidx++] = b2;
166 dst[dstidx++] = ((val >> 5) & 7) | ((val & 0x1F) << 3); 166 dst[dstidx++] = ((val >> 5) & 7) | ((val & 0x1F) << 3);
167 167
168 ret = 3; 168 ret = 3;
169 } 169 }
170 else 170 else
171 { 171 {
172 int long_count = len / 0x4041; 172 int long_count = len / 0x4041;
173 int short_len = len % 0x4041; 173 int short_len = len % 0x4041;
174 bool toosmall = short_len == 1; 174 bool toosmall = short_len == 1;
175 175
176 int run_len = 0x4041; 176 int run_len = 0x4041;
177 for (int i = 0; i < long_count; i++) 177 for (int i = 0; i < long_count; i++)
178 { 178 {
179 if (toosmall && (i == (long_count-1))) 179 if (toosmall && (i == (long_count-1)))
180 { 180 {
181 run_len--; 181 run_len--;
182 toosmall = false; 182 toosmall = false;
183 } 183 }
184 int tmp = encode_run(dst, dstidx, val, run_len, dstlen); 184 int tmp = encode_run(dst, dstidx, val, run_len, dstlen);
185 if (!tmp) return 0; 185 if (!tmp) return 0;
186 ret += tmp; 186 ret += tmp;
187 len -= run_len; 187 len -= run_len;
188 } 188 }
189 189
190 if (len) 190 if (len)
191 { 191 {
192 int short_count = len / 0x41; 192 int short_count = len / 0x41;
193 int short_rest = short_count ? (len % 0x41) : 0; 193 int short_rest = short_count ? (len % 0x41) : 0;
194 toosmall = short_rest == 1; 194 toosmall = short_rest == 1;
195 195
196 run_len = 0x41; 196 run_len = 0x41;
197 for (int i = 0; i < short_count; i++) 197 for (int i = 0; i < short_count; i++)
198 { 198 {
199 if (toosmall && (i == (short_count-1))) 199 if (toosmall && (i == (short_count-1)))
200 { 200 {
201 run_len--; 201 run_len--;
202 toosmall = false; 202 toosmall = false;
203 } 203 }
204 int tmp = encode_run(dst, dstidx, val, run_len, dstlen); 204 int tmp = encode_run(dst, dstidx, val, run_len, dstlen);
205 if (!tmp) return 0; 205 if (!tmp) return 0;
206 ret += tmp; 206 ret += tmp;
207 len -= run_len; 207 len -= run_len;
208 } 208 }
209 int tmp = encode_run(dst, dstidx, val, len, dstlen); 209 int tmp = encode_run(dst, dstidx, val, len, dstlen);
210 if (!tmp) return 0; 210 if (!tmp) return 0;
211 ret += tmp; 211 ret += tmp;
212 len -= len; 212 len -= len;
213 } 213 }
214 } 214 }
215 215
216 return ret; 216 return ret;
217} 217}
218 218
219int encode_block(byte* dst, int& dstidx, byte* src, int& srcidx, int len, 219int encode_block(byte* dst, int& dstidx, byte* src, int& srcidx, int len,
220 int dstlen) 220 int dstlen)
221{ 221{
222 if (len < 1) 222 if (len < 1)
223 throw std::invalid_argument("Length is too small."); 223 throw std::invalid_argument("Length is too small.");
224 224
225 int startidx = dstidx; 225 int startidx = dstidx;
226 if (len < 0x21) 226 if (len < 0x21)
227 { 227 {
228 if ((dstidx + 2 + len) > dstlen) 228 if ((dstidx + 2 + len) > dstlen)
229 throw std::runtime_error("Not enough space to store block."); 229 throw std::runtime_error("Not enough space to store block.");
230 230
231 dst[dstidx++] = BLOCK_CODE | BLOCK_MODE | ((len - 1) & BLOCK_ARGS); 231 dst[dstidx++] = BLOCK_CODE | BLOCK_MODE | ((len - 1) & BLOCK_ARGS);
232 if ((dstidx ^ srcidx) & 1) 232 if ((dstidx ^ srcidx) & 1)
233 dst[dstidx++] = 0; 233 dst[dstidx++] = 0;
234 234
235 for (int i = 0; i < len; i++) 235 for (int i = 0; i < len; i++)
236 { 236 {
237 byte c = src[srcidx++]; 237 byte c = src[srcidx++];
238 byte d = (c & 7) << 5; 238 byte d = (c & 7) << 5;
239 c = (c & 0xF8) >> 3; 239 c = (c & 0xF8) >> 3;
240 dst[dstidx++] = c | d; 240 dst[dstidx++] = c | d;
241 } 241 }
242 } 242 }
243 else if (len < 0x2021) 243 else if (len < 0x2021)
244 { 244 {
245 if ((dstidx + 3 + len) > dstlen) 245 if ((dstidx + 3 + len) > dstlen)
246 throw std::runtime_error("Not enough space to store block."); 246 throw std::runtime_error("Not enough space to store block.");
247 247
248 dst[dstidx++] = BLOCK_CODE | (((len - 0x21) >> 8) & BLOCK_ARGS); 248 dst[dstidx++] = BLOCK_CODE | (((len - 0x21) >> 8) & BLOCK_ARGS);
249 dst[dstidx++] = (len - 0x21) & 0xFF; 249 dst[dstidx++] = (len - 0x21) & 0xFF;
250 if ((dstidx ^ srcidx) & 1) 250 if ((dstidx ^ srcidx) & 1)
251 dst[dstidx++] = 0; 251 dst[dstidx++] = 0;
252 252
253 for (int i = 0; i < len; i++) 253 for (int i = 0; i < len; i++)
254 { 254 {
255 byte c = src[srcidx++]; 255 byte c = src[srcidx++];
256 byte d = (c & 7) << 5; 256 byte d = (c & 7) << 5;
257 c = (c & 0xF8) >> 3; 257 c = (c & 0xF8) >> 3;
258 dst[dstidx++] = c | d; 258 dst[dstidx++] = c | d;
259 } 259 }
260 } 260 }
261 else 261 else
262 { 262 {
263 int longblocks = len / 0x2020; 263 int longblocks = len / 0x2020;
264 int rest = len % 0x2020; 264 int rest = len % 0x2020;
265 for (int i = 0; i < longblocks; i++) 265 for (int i = 0; i < longblocks; i++)
266 { 266 {
267 int tmp = encode_block(dst, dstidx, src, srcidx, 0x2020, dstlen); 267 int tmp = encode_block(dst, dstidx, src, srcidx, 0x2020, dstlen);
268 if (!tmp) return 0; 268 if (!tmp) return 0;
269 } 269 }
270 if (rest) 270 if (rest)
271 { 271 {
272 int shortblocks = rest / 0x20; 272 int shortblocks = rest / 0x20;
273 for (int i = 0; i < shortblocks; i++) 273 for (int i = 0; i < shortblocks; i++)
274 { 274 {
275 int tmp = encode_block(dst, dstidx, src, srcidx, 0x20, dstlen); 275 int tmp = encode_block(dst, dstidx, src, srcidx, 0x20, dstlen);
276 if (!tmp) return 0; 276 if (!tmp) return 0;
277 } 277 }
278 rest = rest % 0x20; 278 rest = rest % 0x20;
279 int tmp = encode_block(dst, dstidx, src, srcidx, rest, dstlen); 279 int tmp = encode_block(dst, dstidx, src, srcidx, rest, dstlen);
280 if (!tmp) return 0; 280 if (!tmp) return 0;
281 } 281 }
282 } 282 }
283 283
284 return (dstidx - startidx); 284 return (dstidx - startidx);
285} 285}
286}; //namespace 286}; //namespace
287 287
288int zen::cenc_encode(byte* src, int srclen, byte* dst, int dstlen) 288int zen::cenc_encode(byte* src, int srclen, byte* dst, int dstlen)
289{ 289{
290 if (!src || !srclen || !dst || !dstlen) 290 if (!src || !srclen || !dst || !dstlen)
291 { 291 {
292 throw std::invalid_argument("Invalid argument(s)."); 292 throw std::invalid_argument("Invalid argument(s).");
293 } 293 }
294 294
295 int i = 0, j = 0, k = 0; 295 int i = 0, j = 0, k = 0;
296 word c, d, e; 296 word c, d, e;
297 int runlen = 0; 297 int runlen = 0;
298 while (i < srclen && j < dstlen) 298 while (i < srclen && j < dstlen)
299 { 299 {
300 k = i; 300 k = i;
301 c = src[i++]; 301 c = src[i++];
302 runlen = 1; 302 runlen = 1;
303 while (i < srclen && src[i] == c) 303 while (i < srclen && src[i] == c)
304 { 304 {
305 runlen++; 305 runlen++;
306 i++; 306 i++;
307 } 307 }
308 if (runlen >= 2) 308 if (runlen >= 2)
309 { 309 {
310 if (!encode_run(dst, j, c, runlen, dstlen)) 310 if (!encode_run(dst, j, c, runlen, dstlen))
311 return 0; 311 return 0;
312 } 312 }
313 else 313 else
314 { 314 {
315 runlen = 0; 315 runlen = 0;
316 i = k; 316 i = k;
317 while (i < (srclen - 1) && (src[i] != src[i + 1])) 317 while (i < (srclen - 1) && (src[i] != src[i + 1]))
318 { 318 {
319 runlen++; 319 runlen++;
320 i++; 320 i++;
321 } 321 }
322 if (i == (srclen - 1)) 322 if (i == (srclen - 1))
323 { 323 {
324 runlen++; 324 runlen++;
325 i++; 325 i++;
326 } 326 }
327 if (!encode_block(dst, j, src, k, runlen, dstlen)) 327 if (!encode_block(dst, j, src, k, runlen, dstlen))
328 return 0; 328 return 0;
329 } 329 }
330 } 330 }
331 331
332 return j; 332 return j;
333} 333}
diff --git a/utils/zenutils/source/shared/cenc.h b/utils/zenutils/source/shared/cenc.h
index 12a7c92516..e96794dcc4 100755..100644
--- a/utils/zenutils/source/shared/cenc.h
+++ b/utils/zenutils/source/shared/cenc.h
@@ -1,29 +1,29 @@
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#ifndef ZEN_CENC_H_INCLUDED 19#ifndef ZEN_CENC_H_INCLUDED
20#define ZEN_CENC_H_INCLUDED 20#define ZEN_CENC_H_INCLUDED
21 21
22#include <utils.h> 22#include <utils.h>
23 23
24namespace zen { 24namespace zen {
25 int cenc_decode(byte* src, int srclen, byte* dst, int dstlen); 25 int cenc_decode(byte* src, int srclen, byte* dst, int dstlen);
26 int cenc_encode(byte* src, int srclen, byte* dst, int dstlen); 26 int cenc_encode(byte* src, int srclen, byte* dst, int dstlen);
27}; //namespace zen 27}; //namespace zen
28 28
29#endif //CENC_H_INCLUDED 29#endif //CENC_H_INCLUDED
diff --git a/utils/zenutils/source/shared/crypt.cpp b/utils/zenutils/source/shared/crypt.cpp
index 9c2d33870c..3f15ac64f1 100755..100644
--- a/utils/zenutils/source/shared/crypt.cpp
+++ b/utils/zenutils/source/shared/crypt.cpp
@@ -1,91 +1,91 @@
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 "crypt.h" 19#include "crypt.h"
20#include <stdexcept> 20#include <stdexcept>
21#include <beecrypt/hmacsha1.h> 21#include <beecrypt/hmacsha1.h>
22#include <beecrypt/blockmode.h> 22#include <beecrypt/blockmode.h>
23#include <beecrypt/blowfish.h> 23#include <beecrypt/blowfish.h>
24 24
25 25
26bool zen::hmac_sha1_calc(const byte* key, size_t keylen, const byte* data, 26bool zen::hmac_sha1_calc(const byte* key, size_t keylen, const byte* data,
27 size_t datalen, byte* sig, size_t* siglen) 27 size_t datalen, byte* sig, size_t* siglen)
28{ 28{
29 hmacsha1Param param; 29 hmacsha1Param param;
30 if (hmacsha1Setup(&param, key, keylen * 8)) 30 if (hmacsha1Setup(&param, key, keylen * 8))
31 return false; 31 return false;
32 if (hmacsha1Update(&param, data, datalen)) 32 if (hmacsha1Update(&param, data, datalen))
33 return false; 33 return false;
34 if (hmacsha1Digest(&param, sig)) 34 if (hmacsha1Digest(&param, sig))
35 return false; 35 return false;
36 return true; 36 return true;
37} 37}
38 38
39bool zen::bf_cbc_encrypt(const byte* key, size_t keylen, byte* data, 39bool zen::bf_cbc_encrypt(const byte* key, size_t keylen, byte* data,
40 size_t datalen, const byte* iv) 40 size_t datalen, const byte* iv)
41{ 41{
42 if (datalen % blowfish.blocksize) 42 if (datalen % blowfish.blocksize)
43 throw std::invalid_argument( 43 throw std::invalid_argument(
44 "The length must be aligned on a 8 byte boundary."); 44 "The length must be aligned on a 8 byte boundary.");
45 45
46 blowfishParam param; 46 blowfishParam param;
47 if (blowfishSetup(&param, key, keylen * 8, ENCRYPT)) 47 if (blowfishSetup(&param, key, keylen * 8, ENCRYPT))
48 return false; 48 return false;
49 if (blowfishSetIV(&param, iv)) 49 if (blowfishSetIV(&param, iv))
50 return false; 50 return false;
51 51
52 byte* plain = new byte[datalen]; 52 byte* plain = new byte[datalen];
53 memcpy(plain, data, datalen); 53 memcpy(plain, data, datalen);
54 54
55 unsigned int nblocks = datalen / blowfish.blocksize; 55 unsigned int nblocks = datalen / blowfish.blocksize;
56 if (blockEncryptCBC(&blowfish, &param, (uint32_t*)data, (uint32_t*)plain, 56 if (blockEncryptCBC(&blowfish, &param, (uint32_t*)data, (uint32_t*)plain,
57 nblocks)) 57 nblocks))
58 { 58 {
59 delete [] plain; 59 delete [] plain;
60 return false; 60 return false;
61 } 61 }
62 62
63 return true; 63 return true;
64} 64}
65 65
66bool zen::bf_cbc_decrypt(const byte* key, size_t keylen, byte* data, 66bool zen::bf_cbc_decrypt(const byte* key, size_t keylen, byte* data,
67 size_t datalen, const byte* iv) 67 size_t datalen, const byte* iv)
68{ 68{
69 if (datalen % blowfish.blocksize) 69 if (datalen % blowfish.blocksize)
70 throw std::invalid_argument( 70 throw std::invalid_argument(
71 "The length must be aligned on a 8 byte boundary."); 71 "The length must be aligned on a 8 byte boundary.");
72 72
73 blowfishParam param; 73 blowfishParam param;
74 if (blowfishSetup(&param, key, keylen * 8, ENCRYPT)) 74 if (blowfishSetup(&param, key, keylen * 8, ENCRYPT))
75 return false; 75 return false;
76 if (blowfishSetIV(&param, iv)) 76 if (blowfishSetIV(&param, iv))
77 return false; 77 return false;
78 78
79 byte* cipher = new byte[datalen]; 79 byte* cipher = new byte[datalen];
80 memcpy(cipher, data, datalen); 80 memcpy(cipher, data, datalen);
81 81
82 unsigned int nblocks = datalen / blowfish.blocksize; 82 unsigned int nblocks = datalen / blowfish.blocksize;
83 if (blockDecryptCBC(&blowfish, &param, (uint32_t*)data, (uint32_t*)cipher, 83 if (blockDecryptCBC(&blowfish, &param, (uint32_t*)data, (uint32_t*)cipher,
84 nblocks)) 84 nblocks))
85 { 85 {
86 delete [] cipher; 86 delete [] cipher;
87 return false; 87 return false;
88 } 88 }
89 89
90 return true; 90 return true;
91} 91}
diff --git a/utils/zenutils/source/shared/crypt.h b/utils/zenutils/source/shared/crypt.h
index a057055b70..a357fef042 100755..100644
--- a/utils/zenutils/source/shared/crypt.h
+++ b/utils/zenutils/source/shared/crypt.h
@@ -1,30 +1,30 @@
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#ifndef ZEN_CRYPT_H_INCLUDED 19#ifndef ZEN_CRYPT_H_INCLUDED
20#define ZEN_CRYPT_H_INCLUDED 20#define ZEN_CRYPT_H_INCLUDED
21 21
22#include <utils.h> 22#include <utils.h>
23 23
24namespace zen { 24namespace zen {
25 bool hmac_sha1_calc(const byte* key, size_t keylen, const byte* data, size_t datalen, byte* sig, size_t* siglen); 25 bool hmac_sha1_calc(const byte* key, size_t keylen, const byte* data, size_t datalen, byte* sig, size_t* siglen);
26 bool bf_cbc_encrypt(const byte* key, size_t keylen, byte* data, size_t datalen, const byte* iv); 26 bool bf_cbc_encrypt(const byte* key, size_t keylen, byte* data, size_t datalen, const byte* iv);
27 bool bf_cbc_decrypt(const byte* key, size_t keylen, byte* data, size_t datalen, const byte* iv); 27 bool bf_cbc_decrypt(const byte* key, size_t keylen, byte* data, size_t datalen, const byte* iv);
28}; //namespace zen 28}; //namespace zen
29 29
30#endif //ZEN_CRYPT_H_INCLUDED 30#endif //ZEN_CRYPT_H_INCLUDED
diff --git a/utils/zenutils/source/shared/file.cpp b/utils/zenutils/source/shared/file.cpp
index 2c31498972..b1b1093170 100755..100644
--- a/utils/zenutils/source/shared/file.cpp
+++ b/utils/zenutils/source/shared/file.cpp
@@ -1,106 +1,106 @@
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 "file.h" 19#include "file.h"
20#include <fstream> 20#include <fstream>
21 21
22 22
23bool shared::read_file(const std::string& filename, bytes& buffer, 23bool shared::read_file(const std::string& filename, bytes& buffer,
24 std::streampos offset, std::streamsize count) 24 std::streampos offset, std::streamsize count)
25{ 25{
26 std::ifstream ifs; 26 std::ifstream ifs;
27 ifs.open(filename.c_str(), std::ios::binary); 27 ifs.open(filename.c_str(), std::ios::binary);
28 if (!ifs) 28 if (!ifs)
29 { 29 {
30 return false; 30 return false;
31 } 31 }
32 32
33 std::ifstream::pos_type startpos = offset; 33 std::ifstream::pos_type startpos = offset;
34 ifs.seekg(offset, std::ios::beg); 34 ifs.seekg(offset, std::ios::beg);
35 if (count == -1) 35 if (count == -1)
36 ifs.seekg(0, std::ios::end); 36 ifs.seekg(0, std::ios::end);
37 else 37 else
38 ifs.seekg(count, std::ios::cur); 38 ifs.seekg(count, std::ios::cur);
39 std::ifstream::pos_type endpos = ifs.tellg(); 39 std::ifstream::pos_type endpos = ifs.tellg();
40 40
41 buffer.resize(endpos-startpos); 41 buffer.resize(endpos-startpos);
42 ifs.seekg(offset, std::ios::beg); 42 ifs.seekg(offset, std::ios::beg);
43 43
44 ifs.read((char*)&buffer[0], endpos-startpos); 44 ifs.read((char*)&buffer[0], endpos-startpos);
45 45
46 ifs.close(); 46 ifs.close();
47 return ifs.good(); 47 return ifs.good();
48} 48}
49 49
50 50
51bool shared::write_file(const std::string& filename, bytes& buffer, 51bool shared::write_file(const std::string& filename, bytes& buffer,
52 bool truncate, std::streampos offset, 52 bool truncate, std::streampos offset,
53 std::streamsize count) 53 std::streamsize count)
54{ 54{
55 std::ios::openmode mode = std::ios::in|std::ios::out|std::ios::binary; 55 std::ios::openmode mode = std::ios::in|std::ios::out|std::ios::binary;
56 if (truncate) 56 if (truncate)
57 mode |= std::ios::trunc; 57 mode |= std::ios::trunc;
58 58
59 std::fstream ofs; 59 std::fstream ofs;
60 ofs.open(filename.c_str(), mode); 60 ofs.open(filename.c_str(), mode);
61 if (!ofs) 61 if (!ofs)
62 { 62 {
63 return false; 63 return false;
64 } 64 }
65 65
66 if (count == -1) 66 if (count == -1)
67 count = buffer.size(); 67 count = buffer.size();
68 else if (count > buffer.size()) 68 else if (count > buffer.size())
69 return false; 69 return false;
70 70
71 ofs.seekg(offset, std::ios::beg); 71 ofs.seekg(offset, std::ios::beg);
72 72
73 ofs.write((char*)&buffer[0], count); 73 ofs.write((char*)&buffer[0], count);
74 74
75 ofs.close(); 75 ofs.close();
76 return ofs.good(); 76 return ofs.good();
77} 77}
78 78
79bool shared::file_exists(const std::string& filename) 79bool shared::file_exists(const std::string& filename)
80{ 80{
81 std::ifstream ifs; 81 std::ifstream ifs;
82 ifs.open(filename.c_str(), std::ios::in); 82 ifs.open(filename.c_str(), std::ios::in);
83 if (ifs.is_open()) 83 if (ifs.is_open())
84 { 84 {
85 ifs.close(); 85 ifs.close();
86 return true; 86 return true;
87 } 87 }
88 return false; 88 return false;
89} 89}
90 90
91bool shared::copy_file(const std::string& srcname, const std::string& dstname) 91bool shared::copy_file(const std::string& srcname, const std::string& dstname)
92{ 92{
93 bytes buffer; 93 bytes buffer;
94 if (!read_file(srcname, buffer)) 94 if (!read_file(srcname, buffer))
95 return false; 95 return false;
96 return write_file(dstname, buffer, true); 96 return write_file(dstname, buffer, true);
97} 97}
98 98
99bool shared::backup_file(const std::string& filename, bool force) 99bool shared::backup_file(const std::string& filename, bool force)
100{ 100{
101 std::string backupname = filename + ".bak"; 101 std::string backupname = filename + ".bak";
102 if (!force) 102 if (!force)
103 if (file_exists(backupname)) 103 if (file_exists(backupname))
104 return true; 104 return true;
105 return copy_file(filename, backupname); 105 return copy_file(filename, backupname);
106} 106}
diff --git a/utils/zenutils/source/shared/file.h b/utils/zenutils/source/shared/file.h
index 8fa533c981..770f39a900 100755..100644
--- a/utils/zenutils/source/shared/file.h
+++ b/utils/zenutils/source/shared/file.h
@@ -1,36 +1,36 @@
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#ifndef SHARED_FILE_H_INCLUDED 19#ifndef SHARED_FILE_H_INCLUDED
20#define SHARED_FILE_H_INCLUDED 20#define SHARED_FILE_H_INCLUDED
21 21
22#include <string> 22#include <string>
23#include <iostream> 23#include <iostream>
24#include "utils.h" 24#include "utils.h"
25 25
26namespace shared { 26namespace shared {
27 bool read_file(const std::string& filename, bytes& buffer, 27 bool read_file(const std::string& filename, bytes& buffer,
28 std::streampos offset = 0, std::streamsize count = -1); 28 std::streampos offset = 0, std::streamsize count = -1);
29 bool write_file(const std::string& filename, bytes& buffer, bool truncate, 29 bool write_file(const std::string& filename, bytes& buffer, bool truncate,
30 std::streampos offset = 0, std::streamsize count = -1); 30 std::streampos offset = 0, std::streamsize count = -1);
31 bool file_exists(const std::string& filename); 31 bool file_exists(const std::string& filename);
32 bool copy_file(const std::string& srcname, const std::string& dstname); 32 bool copy_file(const std::string& srcname, const std::string& dstname);
33 bool backup_file(const std::string& filename, bool force = false); 33 bool backup_file(const std::string& filename, bool force = false);
34}; //namespace shared 34}; //namespace shared
35 35
36#endif //SHARED_FILE_H_INCLUDED 36#endif //SHARED_FILE_H_INCLUDED
diff --git a/utils/zenutils/source/shared/firmware.cpp b/utils/zenutils/source/shared/firmware.cpp
index 7767b55d8f..811b8146b4 100755..100644
--- a/utils/zenutils/source/shared/firmware.cpp
+++ b/utils/zenutils/source/shared/firmware.cpp
@@ -1,387 +1,387 @@
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 "firmware.h" 19#include "firmware.h"
20#include <iostream> 20#include <iostream>
21#include <stdexcept> 21#include <stdexcept>
22 22
23 23
24zen::firmware_entry::firmware_entry(bool big_endian) 24zen::firmware_entry::firmware_entry(bool big_endian)
25 : _big_endian(big_endian) 25 : _big_endian(big_endian)
26{ 26{
27} 27}
28 28
29zen::firmware_entry::firmware_entry(const firmware_entry& copy) 29zen::firmware_entry::firmware_entry(const firmware_entry& copy)
30{ 30{
31 assign(copy); 31 assign(copy);
32} 32}
33 33
34zen::firmware_entry& zen::firmware_entry::operator=(const firmware_entry& right) 34zen::firmware_entry& zen::firmware_entry::operator=(const firmware_entry& right)
35{ 35{
36 assign(right); 36 assign(right);
37 return *this; 37 return *this;
38} 38}
39 39
40 40
41bool zen::firmware_entry::read(std::istream& is) 41bool zen::firmware_entry::read(std::istream& is)
42{ 42{
43 // Read the header. 43 // Read the header.
44 is.read((char*)&_header, sizeof(firmware_header_t)); 44 is.read((char*)&_header, sizeof(firmware_header_t));
45 if (!is.good()) 45 if (!is.good())
46 return false; 46 return false;
47 47
48 // If the firmware is big-endian, swap the header values to little-endian. 48 // If the firmware is big-endian, swap the header values to little-endian.
49 if (_big_endian) 49 if (_big_endian)
50 { 50 {
51 _header.tag = shared::swap(_header.tag); 51 _header.tag = shared::swap(_header.tag);
52 if (_header.tag != 'NULL') 52 if (_header.tag != 'NULL')
53 { 53 {
54 _header.size = shared::swap(_header.size); 54 _header.size = shared::swap(_header.size);
55 } 55 }
56 } 56 }
57 57
58 // Resize the bytes buffer to the size specified in the header. 58 // Resize the bytes buffer to the size specified in the header.
59 _bytes.resize(_header.size); 59 _bytes.resize(_header.size);
60 60
61 // Read the entry contents. 61 // Read the entry contents.
62 is.read(reinterpret_cast<char*>(&_bytes[0]), 62 is.read(reinterpret_cast<char*>(&_bytes[0]),
63 _header.size); 63 _header.size);
64 64
65 return is.good(); 65 return is.good();
66} 66}
67 67
68bool zen::firmware_entry::write(std::ostream& os) const 68bool zen::firmware_entry::write(std::ostream& os) const
69{ 69{
70 // Form a header using the current size of the bytes buffer. 70 // Form a header using the current size of the bytes buffer.
71 firmware_header_t header = { 71 firmware_header_t header = {
72 _header.tag, 72 _header.tag,
73 static_cast<dword>(_bytes.size()) 73 static_cast<dword>(_bytes.size())
74 }; 74 };
75 75
76 // If the firmware is big-endian, swap the header values back into big-endian. 76 // If the firmware is big-endian, swap the header values back into big-endian.
77 if (_big_endian) 77 if (_big_endian)
78 { 78 {
79 if (header.tag != 'NULL') 79 if (header.tag != 'NULL')
80 { 80 {
81 header.size = shared::swap(header.size); 81 header.size = shared::swap(header.size);
82 } 82 }
83 header.tag = shared::swap(header.tag); 83 header.tag = shared::swap(header.tag);
84 } 84 }
85 85
86 // Write the header. 86 // Write the header.
87 os.write((const char*)&header, sizeof(firmware_header_t)); 87 os.write((const char*)&header, sizeof(firmware_header_t));
88 if (!os.good()) 88 if (!os.good())
89 return false; 89 return false;
90 90
91 // Write the entry contents. 91 // Write the entry contents.
92 os.write(reinterpret_cast<const char*>(&_bytes[0]), 92 os.write(reinterpret_cast<const char*>(&_bytes[0]),
93 static_cast<std::streamsize>(_bytes.size())); 93 static_cast<std::streamsize>(_bytes.size()));
94 94
95 return os.good(); 95 return os.good();
96} 96}
97 97
98 98
99bool zen::firmware_entry::is_big_endian() const 99bool zen::firmware_entry::is_big_endian() const
100{ 100{
101 return _big_endian; 101 return _big_endian;
102} 102}
103 103
104const zen::firmware_header_t& zen::firmware_entry::get_header() const 104const zen::firmware_header_t& zen::firmware_entry::get_header() const
105{ 105{
106 return _header; 106 return _header;
107} 107}
108zen::firmware_header_t& zen::firmware_entry::get_header() 108zen::firmware_header_t& zen::firmware_entry::get_header()
109{ 109{
110 return _header; 110 return _header;
111} 111}
112 112
113const shared::bytes& zen::firmware_entry::get_bytes() const 113const shared::bytes& zen::firmware_entry::get_bytes() const
114{ 114{
115 return _bytes; 115 return _bytes;
116} 116}
117shared::bytes& zen::firmware_entry::get_bytes() 117shared::bytes& zen::firmware_entry::get_bytes()
118{ 118{
119 return _bytes; 119 return _bytes;
120} 120}
121 121
122 122
123std::string zen::firmware_entry::get_name() const 123std::string zen::firmware_entry::get_name() const
124{ 124{
125 char name[5]; 125 char name[5];
126 *(dword*)name = shared::swap(_header.tag); 126 *(dword*)name = shared::swap(_header.tag);
127 name[4] = '\0'; 127 name[4] = '\0';
128 128
129 // Determine if all characters in the tag are printable. 129 // Determine if all characters in the tag are printable.
130 bool isprintable = true; 130 bool isprintable = true;
131 for (int i = 0; i < 4; i++) 131 for (int i = 0; i < 4; i++)
132 { 132 {
133 if (!isprint((byte)name[i])) 133 if (!isprint((byte)name[i]))
134 { 134 {
135 isprintable = false; 135 isprintable = false;
136 break; 136 break;
137 } 137 }
138 } 138 }
139 139
140 // If they are, simply return the tag as a string. 140 // If they are, simply return the tag as a string.
141 if (isprintable) 141 if (isprintable)
142 { 142 {
143 return std::string(name); 143 return std::string(name);
144 } 144 }
145 145
146 // Otherwise, encode the tag into a hexadecimal string. 146 // Otherwise, encode the tag into a hexadecimal string.
147 char buffer[11]; 147 char buffer[11];
148 sprintf(buffer, "0x%08x", _header.tag); 148 sprintf(buffer, "0x%08x", _header.tag);
149 return std::string(buffer); 149 return std::string(buffer);
150} 150}
151 151
152std::string zen::firmware_entry::get_content_name() const 152std::string zen::firmware_entry::get_content_name() const
153{ 153{
154 std::string name = get_name(); 154 std::string name = get_name();
155 if (name == "DATA") 155 if (name == "DATA")
156 { 156 {
157 name = ""; 157 name = "";
158 int nameoff = is_big_endian() ? 1 : 0; 158 int nameoff = is_big_endian() ? 1 : 0;
159 for (int i = 0; i < 16; i++) 159 for (int i = 0; i < 16; i++)
160 { 160 {
161 char c = get_bytes()[i * 2 + nameoff]; 161 char c = get_bytes()[i * 2 + nameoff];
162 if (!c) 162 if (!c)
163 break; 163 break;
164 name += c; 164 name += c;
165 } 165 }
166 } 166 }
167 else if (name == "EXT0") 167 else if (name == "EXT0")
168 { 168 {
169 name = ""; 169 name = "";
170 int nameoff = is_big_endian() ? 1 : 0; 170 int nameoff = is_big_endian() ? 1 : 0;
171 for (int i = 0; i < 12; i++) 171 for (int i = 0; i < 12; i++)
172 { 172 {
173 char c = get_bytes()[i * 2 + nameoff]; 173 char c = get_bytes()[i * 2 + nameoff];
174 if (!c) 174 if (!c)
175 break; 175 break;
176 name += c; 176 name += c;
177 } 177 }
178 } 178 }
179 return name; 179 return name;
180} 180}
181 181
182size_t zen::firmware_entry::get_content_offset() const 182size_t zen::firmware_entry::get_content_offset() const
183{ 183{
184 std::string name = get_name(); 184 std::string name = get_name();
185 if (name == "DATA") 185 if (name == "DATA")
186 { 186 {
187 return 32; 187 return 32;
188 } 188 }
189 else if (name == "EXT0") 189 else if (name == "EXT0")
190 { 190 {
191 return 24; 191 return 24;
192 } 192 }
193 return 0; 193 return 0;
194} 194}
195 195
196size_t zen::firmware_entry::calc_size() const 196size_t zen::firmware_entry::calc_size() const
197{ 197{
198 return _bytes.size() + sizeof(firmware_header_t); 198 return _bytes.size() + sizeof(firmware_header_t);
199} 199}
200 200
201 201
202void zen::firmware_entry::assign(const firmware_entry& copy) 202void zen::firmware_entry::assign(const firmware_entry& copy)
203{ 203{
204 _big_endian = copy._big_endian; 204 _big_endian = copy._big_endian;
205 _header.tag = copy._header.tag; 205 _header.tag = copy._header.tag;
206 _header.size = copy._header.size; 206 _header.size = copy._header.size;
207 _bytes.assign(copy._bytes.begin(), copy._bytes.end()); 207 _bytes.assign(copy._bytes.begin(), copy._bytes.end());
208} 208}
209 209
210 210
211 211
212zen::firmware_archive::firmware_archive(bool big_endian) 212zen::firmware_archive::firmware_archive(bool big_endian)
213 : _big_endian(big_endian) 213 : _big_endian(big_endian)
214{ 214{
215} 215}
216 216
217zen::firmware_archive::firmware_archive(const firmware_archive& copy) 217zen::firmware_archive::firmware_archive(const firmware_archive& copy)
218{ 218{
219 assign(copy); 219 assign(copy);
220} 220}
221 221
222zen::firmware_archive& zen::firmware_archive::operator=(const firmware_archive& right) 222zen::firmware_archive& zen::firmware_archive::operator=(const firmware_archive& right)
223{ 223{
224 assign(right); 224 assign(right);
225 return *this; 225 return *this;
226} 226}
227 227
228 228
229bool zen::firmware_archive::read(std::istream& is) 229bool zen::firmware_archive::read(std::istream& is)
230{ 230{
231 // Read the root entry's header. 231 // Read the root entry's header.
232 firmware_header_t root; 232 firmware_header_t root;
233 is.read((char*)&root, sizeof(firmware_header_t)); 233 is.read((char*)&root, sizeof(firmware_header_t));
234 if (!is.good()) 234 if (!is.good())
235 return false; 235 return false;
236 236
237 if ((root.tag != 'CIFF') && (root.tag != 'FFIC')) 237 if ((root.tag != 'CIFF') && (root.tag != 'FFIC'))
238 { 238 {
239 throw std::runtime_error("Invalid firmware archive format!"); 239 throw std::runtime_error("Invalid firmware archive format!");
240 } 240 }
241 241
242 _big_endian = root.tag == 'FFIC' ? true : false; 242 _big_endian = root.tag == 'FFIC' ? true : false;
243 if (_big_endian) 243 if (_big_endian)
244 { 244 {
245 root.tag = shared::swap(root.tag); 245 root.tag = shared::swap(root.tag);
246 root.size = shared::swap(root.size); 246 root.size = shared::swap(root.size);
247 } 247 }
248 248
249 // Save the current stream position. 249 // Save the current stream position.
250 std::istream::pos_type endpos = is.tellg(); 250 std::istream::pos_type endpos = is.tellg();
251 std::istream::pos_type curpos = endpos; 251 std::istream::pos_type curpos = endpos;
252 endpos += std::istream::pos_type(root.size); 252 endpos += std::istream::pos_type(root.size);
253 253
254 // Read untill the end of the root entry contents. 254 // Read untill the end of the root entry contents.
255 while (curpos < endpos) 255 while (curpos < endpos)
256 { 256 {
257 firmware_entry entry(_big_endian); 257 firmware_entry entry(_big_endian);
258 if (!entry.read(is)) 258 if (!entry.read(is))
259 return false; 259 return false;
260 260
261 _children.push_back(entry); 261 _children.push_back(entry);
262 curpos = is.tellg(); 262 curpos = is.tellg();
263 } 263 }
264 264
265 curpos = is.tellg(); 265 curpos = is.tellg();
266 is.seekg(0, std::ios::end); 266 is.seekg(0, std::ios::end);
267 endpos = is.tellg(); 267 endpos = is.tellg();
268 is.seekg(curpos); 268 is.seekg(curpos);
269 269
270 // Read untill the end of the file. 270 // Read untill the end of the file.
271 while (((size_t)curpos + sizeof(firmware_header_t)) < endpos) 271 while (((size_t)curpos + sizeof(firmware_header_t)) < endpos)
272 { 272 {
273 firmware_entry entry(_big_endian); 273 firmware_entry entry(_big_endian);
274 if (!entry.read(is)) 274 if (!entry.read(is))
275 return false; 275 return false;
276 276
277 _neighbours.push_back(entry); 277 _neighbours.push_back(entry);
278 curpos = is.tellg(); 278 curpos = is.tellg();
279 } 279 }
280 280
281 return true; 281 return true;
282} 282}
283 283
284bool zen::firmware_archive::write(std::ostream& os) const 284bool zen::firmware_archive::write(std::ostream& os) const
285{ 285{
286 // Read the root entry's header. 286 // Read the root entry's header.
287 firmware_header_t root = {'CIFF', 0}; 287 firmware_header_t root = {'CIFF', 0};
288 288
289 // Calculate the total size of all the children entries. 289 // Calculate the total size of all the children entries.
290 for (firmware_entries::const_iterator i = _children.begin(); 290 for (firmware_entries::const_iterator i = _children.begin();
291 i != _children.end(); ++i) 291 i != _children.end(); ++i)
292 { 292 {
293 root.size += i->calc_size(); 293 root.size += i->calc_size();
294 } 294 }
295 295
296 // If the firmware is big-endian, swap the header values back into big-endian. 296 // If the firmware is big-endian, swap the header values back into big-endian.
297 if (_big_endian) 297 if (_big_endian)
298 { 298 {
299 root.tag = shared::swap(root.tag); 299 root.tag = shared::swap(root.tag);
300 root.size = shared::swap(root.size); 300 root.size = shared::swap(root.size);
301 } 301 }
302 302
303 // Write the header. 303 // Write the header.
304 os.write((const char*)&root, sizeof(firmware_header_t)); 304 os.write((const char*)&root, sizeof(firmware_header_t));
305 if (!os.good()) 305 if (!os.good())
306 return false; 306 return false;
307 307
308 // Write all the child entries. 308 // Write all the child entries.
309 for (firmware_entries::const_iterator i = _children.begin(); 309 for (firmware_entries::const_iterator i = _children.begin();
310 i != _children.end(); ++i) 310 i != _children.end(); ++i)
311 { 311 {
312 if (!i->write(os)) 312 if (!i->write(os))
313 return false; 313 return false;
314 } 314 }
315 315
316 // Write all the neighbour entries. 316 // Write all the neighbour entries.
317 for (firmware_entries::const_iterator i = _neighbours.begin(); 317 for (firmware_entries::const_iterator i = _neighbours.begin();
318 i != _neighbours.end(); ++i) 318 i != _neighbours.end(); ++i)
319 { 319 {
320 if (!i->write(os)) 320 if (!i->write(os))
321 return false; 321 return false;
322 } 322 }
323 323
324 return true; 324 return true;
325} 325}
326 326
327 327
328bool zen::firmware_archive::is_big_endian() const 328bool zen::firmware_archive::is_big_endian() const
329{ 329{
330 return _big_endian; 330 return _big_endian;
331} 331}
332 332
333const zen::firmware_entries& zen::firmware_archive::get_children() const 333const zen::firmware_entries& zen::firmware_archive::get_children() const
334{ 334{
335 return _children; 335 return _children;
336} 336}
337zen::firmware_entries& zen::firmware_archive::get_children() 337zen::firmware_entries& zen::firmware_archive::get_children()
338{ 338{
339 return _children; 339 return _children;
340} 340}
341 341
342const zen::firmware_entries& zen::firmware_archive::get_neighbours() const 342const zen::firmware_entries& zen::firmware_archive::get_neighbours() const
343{ 343{
344 return _neighbours; 344 return _neighbours;
345} 345}
346zen::firmware_entries& zen::firmware_archive::get_neighbours() 346zen::firmware_entries& zen::firmware_archive::get_neighbours()
347{ 347{
348 return _neighbours; 348 return _neighbours;
349} 349}
350 350
351bool zen::firmware_archive::is_signed() const 351bool zen::firmware_archive::is_signed() const
352{ 352{
353 for (firmware_entries::const_iterator i = _neighbours.begin(); 353 for (firmware_entries::const_iterator i = _neighbours.begin();
354 i != _neighbours.end(); i++) 354 i != _neighbours.end(); i++)
355 { 355 {
356 if (i->get_name() == "NULL") 356 if (i->get_name() == "NULL")
357 return true; 357 return true;
358 } 358 }
359 return false; 359 return false;
360} 360}
361 361
362size_t zen::firmware_archive::calc_size() const 362size_t zen::firmware_archive::calc_size() const
363{ 363{
364 size_t size = sizeof(firmware_header_t); 364 size_t size = sizeof(firmware_header_t);
365 365
366 for (firmware_entries::const_iterator i = _children.begin(); 366 for (firmware_entries::const_iterator i = _children.begin();
367 i != _children.end(); i++) 367 i != _children.end(); i++)
368 { 368 {
369 size += i->calc_size(); 369 size += i->calc_size();
370 } 370 }
371 371
372 for (firmware_entries::const_iterator i = _neighbours.begin(); 372 for (firmware_entries::const_iterator i = _neighbours.begin();
373 i != _neighbours.end(); i++) 373 i != _neighbours.end(); i++)
374 { 374 {
375 size += i->calc_size(); 375 size += i->calc_size();
376 } 376 }
377 377
378 return size; 378 return size;
379} 379}
380 380
381 381
382void zen::firmware_archive::assign(const firmware_archive& copy) 382void zen::firmware_archive::assign(const firmware_archive& copy)
383{ 383{
384 _big_endian = copy._big_endian; 384 _big_endian = copy._big_endian;
385 _children.assign(copy._children.begin(), copy._children.end()); 385 _children.assign(copy._children.begin(), copy._children.end());
386 _neighbours.assign(copy._neighbours.begin(), copy._neighbours.end()); 386 _neighbours.assign(copy._neighbours.begin(), copy._neighbours.end());
387} 387}
diff --git a/utils/zenutils/source/shared/firmware.h b/utils/zenutils/source/shared/firmware.h
index 3542186590..3cd233c3b6 100755..100644
--- a/utils/zenutils/source/shared/firmware.h
+++ b/utils/zenutils/source/shared/firmware.h
@@ -1,92 +1,92 @@
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#ifndef ZEN_FIRMWARE_H_INCLUDED 19#ifndef ZEN_FIRMWARE_H_INCLUDED
20#define ZEN_FIRMWARE_H_INCLUDED 20#define ZEN_FIRMWARE_H_INCLUDED
21 21
22#include <list> 22#include <list>
23#include <utils.h> 23#include <utils.h>
24 24
25namespace zen { 25namespace zen {
26 struct firmware_header_t 26 struct firmware_header_t
27 { 27 {
28 dword tag; 28 dword tag;
29 dword size; 29 dword size;
30 }; //struct firmware_header_t 30 }; //struct firmware_header_t
31 31
32 class firmware_entry 32 class firmware_entry
33 { 33 {
34 public: 34 public:
35 firmware_entry(bool big_endian); 35 firmware_entry(bool big_endian);
36 firmware_entry(const firmware_entry& copy); 36 firmware_entry(const firmware_entry& copy);
37 firmware_entry& operator=(const firmware_entry& right); 37 firmware_entry& operator=(const firmware_entry& right);
38 38
39 bool read(std::istream& is); 39 bool read(std::istream& is);
40 bool write(std::ostream& os) const; 40 bool write(std::ostream& os) const;
41 41
42 bool is_big_endian() const; 42 bool is_big_endian() const;
43 const firmware_header_t& get_header() const; 43 const firmware_header_t& get_header() const;
44 firmware_header_t& get_header(); 44 firmware_header_t& get_header();
45 const shared::bytes& get_bytes() const; 45 const shared::bytes& get_bytes() const;
46 shared::bytes& get_bytes(); 46 shared::bytes& get_bytes();
47 47
48 std::string get_name() const; 48 std::string get_name() const;
49 std::string get_content_name() const; 49 std::string get_content_name() const;
50 size_t get_content_offset() const; 50 size_t get_content_offset() const;
51 size_t calc_size() const; 51 size_t calc_size() const;
52 52
53 protected: 53 protected:
54 void assign(const firmware_entry& copy); 54 void assign(const firmware_entry& copy);
55 55
56 private: 56 private:
57 bool _big_endian; 57 bool _big_endian;
58 firmware_header_t _header; 58 firmware_header_t _header;
59 shared::bytes _bytes; 59 shared::bytes _bytes;
60 }; //class firmware_entry 60 }; //class firmware_entry
61 61
62 typedef std::list<firmware_entry> firmware_entries; 62 typedef std::list<firmware_entry> firmware_entries;
63 63
64 class firmware_archive 64 class firmware_archive
65 { 65 {
66 public: 66 public:
67 firmware_archive(bool big_endian); 67 firmware_archive(bool big_endian);
68 firmware_archive(const firmware_archive& copy); 68 firmware_archive(const firmware_archive& copy);
69 firmware_archive& operator=(const firmware_archive& right); 69 firmware_archive& operator=(const firmware_archive& right);
70 70
71 bool read(std::istream& is); 71 bool read(std::istream& is);
72 bool write(std::ostream& os) const; 72 bool write(std::ostream& os) const;
73 73
74 bool is_big_endian() const; 74 bool is_big_endian() const;
75 const firmware_entries& get_children() const; 75 const firmware_entries& get_children() const;
76 firmware_entries& get_children(); 76 firmware_entries& get_children();
77 const firmware_entries& get_neighbours() const; 77 const firmware_entries& get_neighbours() const;
78 firmware_entries& get_neighbours(); 78 firmware_entries& get_neighbours();
79 bool is_signed() const; 79 bool is_signed() const;
80 size_t calc_size() const; 80 size_t calc_size() const;
81 81
82 protected: 82 protected:
83 void assign(const firmware_archive& copy); 83 void assign(const firmware_archive& copy);
84 84
85 private: 85 private:
86 firmware_entries _children; 86 firmware_entries _children;
87 firmware_entries _neighbours; 87 firmware_entries _neighbours;
88 bool _big_endian; 88 bool _big_endian;
89 }; //class firmware_archive 89 }; //class firmware_archive
90}; //namespace zen 90}; //namespace zen
91 91
92#endif //ZEN_FIRMWARE_ARCHIVE_H_INCLUDED 92#endif //ZEN_FIRMWARE_ARCHIVE_H_INCLUDED
diff --git a/utils/zenutils/source/shared/pe.cpp b/utils/zenutils/source/shared/pe.cpp
index c86ec6c8cc..10070074dd 100755..100644
--- a/utils/zenutils/source/shared/pe.cpp
+++ b/utils/zenutils/source/shared/pe.cpp
@@ -1,128 +1,128 @@
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 "pe.h" 19#include "pe.h"
20 20
21 21
22shared::pe_file::pe_file(PeLib::PeFile* pef) : _pef(pef) 22shared::pe_file::pe_file(PeLib::PeFile* pef) : _pef(pef)
23{ 23{
24} 24}
25shared::pe_file::~pe_file() 25shared::pe_file::~pe_file()
26{ 26{
27 if (_pef != NULL) 27 if (_pef != NULL)
28 delete _pef; 28 delete _pef;
29} 29}
30 30
31bool shared::pe_file::is_valid() const 31bool shared::pe_file::is_valid() const
32{ 32{
33 if (_pef->getBits() == 32) 33 if (_pef->getBits() == 32)
34 { 34 {
35 PeLib::PeHeader32& pef32 = static_cast<PeLib::PeFile32*>(_pef)->peHeader(); 35 PeLib::PeHeader32& pef32 = static_cast<PeLib::PeFile32*>(_pef)->peHeader();
36 if (!pef32.isValid()) 36 if (!pef32.isValid())
37 return false; 37 return false;
38 return true; 38 return true;
39 } 39 }
40 else if (_pef->getBits() == 64) 40 else if (_pef->getBits() == 64)
41 { 41 {
42 PeLib::PeHeader64& pef64 = static_cast<PeLib::PeFile64*>(_pef)->peHeader(); 42 PeLib::PeHeader64& pef64 = static_cast<PeLib::PeFile64*>(_pef)->peHeader();
43 if (!pef64.isValid()) 43 if (!pef64.isValid())
44 return false; 44 return false;
45 return true; 45 return true;
46 } 46 }
47 return false; 47 return false;
48} 48}
49 49
50bool shared::pe_file::read(const std::string& filename) 50bool shared::pe_file::read(const std::string& filename)
51{ 51{
52 if (_pef != NULL) 52 if (_pef != NULL)
53 { 53 {
54 delete _pef; 54 delete _pef;
55 _pef = NULL; 55 _pef = NULL;
56 } 56 }
57 57
58 _pef = PeLib::openPeFile(filename); 58 _pef = PeLib::openPeFile(filename);
59 if (!_pef) 59 if (!_pef)
60 { 60 {
61 return false; 61 return false;
62 } 62 }
63 if (_pef->readMzHeader()) 63 if (_pef->readMzHeader())
64 { 64 {
65 delete _pef; 65 delete _pef;
66 return false; 66 return false;
67 } 67 }
68 if (!_pef->mzHeader().isValid()) 68 if (!_pef->mzHeader().isValid())
69 { 69 {
70 delete _pef; 70 delete _pef;
71 return false; 71 return false;
72 } 72 }
73 if (_pef->readPeHeader()) 73 if (_pef->readPeHeader())
74 { 74 {
75 delete _pef; 75 delete _pef;
76 return false; 76 return false;
77 } 77 }
78 if (!is_valid()) 78 if (!is_valid())
79 { 79 {
80 delete _pef; 80 delete _pef;
81 return false; 81 return false;
82 } 82 }
83 return true; 83 return true;
84} 84}
85 85
86bool shared::pe_file::find_section(const std::string& name, section_info& info) const 86bool shared::pe_file::find_section(const std::string& name, section_info& info) const
87{ 87{
88 if (_pef->getBits() == 32) 88 if (_pef->getBits() == 32)
89 return find_section(static_cast<PeLib::PeFile32*>(_pef), 89 return find_section(static_cast<PeLib::PeFile32*>(_pef),
90 name, info); 90 name, info);
91 else if (_pef->getBits() == 64) 91 else if (_pef->getBits() == 64)
92 return find_section(static_cast<PeLib::PeFile64*>(_pef), 92 return find_section(static_cast<PeLib::PeFile64*>(_pef),
93 name, info); 93 name, info);
94 return false; 94 return false;
95} 95}
96 96
97bool shared::pe_file::add_section(const std::string& name, 97bool shared::pe_file::add_section(const std::string& name,
98 const bytes& buffer, section_info& info) 98 const bytes& buffer, section_info& info)
99{ 99{
100 if (_pef->getBits() == 32) 100 if (_pef->getBits() == 32)
101 { 101 {
102 return add_section(static_cast<PeLib::PeFile32*>(_pef), 102 return add_section(static_cast<PeLib::PeFile32*>(_pef),
103 name, buffer, info); 103 name, buffer, info);
104 } 104 }
105 else if (_pef->getBits() == 64) 105 else if (_pef->getBits() == 64)
106 { 106 {
107 return add_section(static_cast<PeLib::PeFile64*>(_pef), 107 return add_section(static_cast<PeLib::PeFile64*>(_pef),
108 name, buffer, info); 108 name, buffer, info);
109 } 109 }
110 return false; 110 return false;
111} 111}
112 112
113dword shared::pe_file::get_image_base() const 113dword shared::pe_file::get_image_base() const
114{ 114{
115 if (_pef->getBits() == 32) 115 if (_pef->getBits() == 32)
116 return static_cast<PeLib::PeFile32*>(_pef)->peHeader().getImageBase(); 116 return static_cast<PeLib::PeFile32*>(_pef)->peHeader().getImageBase();
117 else 117 else
118 return static_cast<PeLib::PeFile64*>(_pef)->peHeader().getImageBase(); 118 return static_cast<PeLib::PeFile64*>(_pef)->peHeader().getImageBase();
119 return 0; 119 return 0;
120} 120}
121dword shared::pe_file::pa_to_va(dword pa) const 121dword shared::pe_file::pa_to_va(dword pa) const
122{ 122{
123 if (_pef->getBits() == 32) 123 if (_pef->getBits() == 32)
124 return static_cast<PeLib::PeFile32*>(_pef)->peHeader().offsetToVa(pa); 124 return static_cast<PeLib::PeFile32*>(_pef)->peHeader().offsetToVa(pa);
125 else 125 else
126 return static_cast<PeLib::PeFile64*>(_pef)->peHeader().offsetToVa(pa); 126 return static_cast<PeLib::PeFile64*>(_pef)->peHeader().offsetToVa(pa);
127 return 0; 127 return 0;
128} 128}
diff --git a/utils/zenutils/source/shared/pe.h b/utils/zenutils/source/shared/pe.h
index 92a272d3c7..f2f3aa48e8 100755..100644
--- a/utils/zenutils/source/shared/pe.h
+++ b/utils/zenutils/source/shared/pe.h
@@ -1,142 +1,142 @@
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#ifndef SHARED_PE_H_INCLUDED 19#ifndef SHARED_PE_H_INCLUDED
20#define SHARED_PE_H_INCLUDED 20#define SHARED_PE_H_INCLUDED
21 21
22#include <string> 22#include <string>
23#include <pelib/PeLib.h> 23#include <pelib/PeLib.h>
24#include <utils.h> 24#include <utils.h>
25 25
26namespace shared { 26namespace shared {
27 struct section_info 27 struct section_info
28 { 28 {
29 word index; 29 word index;
30 dword virtual_address; 30 dword virtual_address;
31 dword virtual_size; 31 dword virtual_size;
32 dword raw_address; 32 dword raw_address;
33 dword raw_size; 33 dword raw_size;
34 dword characteristics; 34 dword characteristics;
35 }; //struct section_info 35 }; //struct section_info
36 36
37 class pe_file 37 class pe_file
38 { 38 {
39 public: 39 public:
40 pe_file(PeLib::PeFile* pef = NULL); 40 pe_file(PeLib::PeFile* pef = NULL);
41 ~pe_file(); 41 ~pe_file();
42 42
43 bool is_valid() const; 43 bool is_valid() const;
44 bool read(const std::string& filename); 44 bool read(const std::string& filename);
45 bool find_section(const std::string& name, section_info& info) const; 45 bool find_section(const std::string& name, section_info& info) const;
46 bool add_section(const std::string& name, const bytes& buffer, section_info& info); 46 bool add_section(const std::string& name, const bytes& buffer, section_info& info);
47 dword get_image_base() const; 47 dword get_image_base() const;
48 dword pa_to_va(PeLib::dword pa) const; 48 dword pa_to_va(PeLib::dword pa) const;
49 49
50 protected: 50 protected:
51 template <int _Bits> 51 template <int _Bits>
52 static bool find_section(const PeLib::PeFileT<_Bits>* pef, 52 static bool find_section(const PeLib::PeFileT<_Bits>* pef,
53 const std::string& name, section_info& info); 53 const std::string& name, section_info& info);
54 template <int _Bits> 54 template <int _Bits>
55 static bool add_section(PeLib::PeFileT<_Bits>* pef, 55 static bool add_section(PeLib::PeFileT<_Bits>* pef,
56 const std::string& name, const bytes& buffer, 56 const std::string& name, const bytes& buffer,
57 section_info& info); 57 section_info& info);
58 58
59 private: 59 private:
60 PeLib::PeFile* _pef; 60 PeLib::PeFile* _pef;
61 }; //class pe_file 61 }; //class pe_file
62 62
63 63
64 template <int _Bits> 64 template <int _Bits>
65 bool pe_file::find_section(const PeLib::PeFileT<_Bits>* pef, 65 bool pe_file::find_section(const PeLib::PeFileT<_Bits>* pef,
66 const std::string& name, section_info& info) 66 const std::string& name, section_info& info)
67 { 67 {
68 for (PeLib::word i = 0; i < pef->peHeader().getNumberOfSections(); i++) 68 for (PeLib::word i = 0; i < pef->peHeader().getNumberOfSections(); i++)
69 { 69 {
70 if (pef->peHeader().getSectionName(i) == name) 70 if (pef->peHeader().getSectionName(i) == name)
71 { 71 {
72 info.index = i; 72 info.index = i;
73 info.virtual_address = pef->peHeader().getVirtualAddress(i); 73 info.virtual_address = pef->peHeader().getVirtualAddress(i);
74 info.virtual_size = pef->peHeader().getVirtualSize(i); 74 info.virtual_size = pef->peHeader().getVirtualSize(i);
75 info.raw_address = pef->peHeader().getPointerToRawData(i); 75 info.raw_address = pef->peHeader().getPointerToRawData(i);
76 info.raw_size = pef->peHeader().getSizeOfRawData(i); 76 info.raw_size = pef->peHeader().getSizeOfRawData(i);
77 info.characteristics = pef->peHeader().getCharacteristics(i); 77 info.characteristics = pef->peHeader().getCharacteristics(i);
78 return true; 78 return true;
79 } 79 }
80 } 80 }
81 return false; 81 return false;
82 } 82 }
83 83
84 template <int _Bits> 84 template <int _Bits>
85 bool pe_file::add_section(PeLib::PeFileT<_Bits>* pef, 85 bool pe_file::add_section(PeLib::PeFileT<_Bits>* pef,
86 const std::string& name, const bytes& buffer, 86 const std::string& name, const bytes& buffer,
87 section_info& info) 87 section_info& info)
88 { 88 {
89 using namespace PeLib; 89 using namespace PeLib;
90 90
91 // Check if the last section has the same name as the one being added. 91 // Check if the last section has the same name as the one being added.
92 PeLib::word secnum = pef->peHeader().getNumberOfSections(); 92 PeLib::word secnum = pef->peHeader().getNumberOfSections();
93 if (pef->peHeader().getSectionName(secnum-1) == name) 93 if (pef->peHeader().getSectionName(secnum-1) == name)
94 { 94 {
95 // If it is, we change the attributes of the existing section. 95 // If it is, we change the attributes of the existing section.
96 secnum = secnum - 1; 96 secnum = secnum - 1;
97 pef->peHeader().setSizeOfRawData(secnum, 97 pef->peHeader().setSizeOfRawData(secnum,
98 alignOffset(buffer.size(), 98 alignOffset(buffer.size(),
99 pef->peHeader().getFileAlignment())); 99 pef->peHeader().getFileAlignment()));
100 pef->peHeader().setVirtualSize(secnum, 100 pef->peHeader().setVirtualSize(secnum,
101 alignOffset(buffer.size(), 101 alignOffset(buffer.size(),
102 pef->peHeader().getSectionAlignment())); 102 pef->peHeader().getSectionAlignment()));
103 PeLib::dword chars = pef->peHeader().getCharacteristics(secnum-1); 103 PeLib::dword chars = pef->peHeader().getCharacteristics(secnum-1);
104 pef->peHeader().setCharacteristics(secnum, 104 pef->peHeader().setCharacteristics(secnum,
105 chars | PELIB_IMAGE_SCN_MEM_WRITE | PELIB_IMAGE_SCN_MEM_READ); 105 chars | PELIB_IMAGE_SCN_MEM_WRITE | PELIB_IMAGE_SCN_MEM_READ);
106 } 106 }
107 else 107 else
108 { 108 {
109 // Otherwise we add a new section. 109 // Otherwise we add a new section.
110 if (pef->peHeader().addSection(name, buffer.size()) != NO_ERROR) 110 if (pef->peHeader().addSection(name, buffer.size()) != NO_ERROR)
111 { 111 {
112 return false; 112 return false;
113 } 113 }
114 pef->peHeader().makeValid(pef->mzHeader().getAddressOfPeHeader()); 114 pef->peHeader().makeValid(pef->mzHeader().getAddressOfPeHeader());
115 pef->peHeader().write(pef->getFileName(), pef->mzHeader().getAddressOfPeHeader()); 115 pef->peHeader().write(pef->getFileName(), pef->mzHeader().getAddressOfPeHeader());
116 } 116 }
117 117
118 // Save the section headers to the file. 118 // Save the section headers to the file.
119 if (pef->peHeader().writeSections(pef->getFileName()) != NO_ERROR) 119 if (pef->peHeader().writeSections(pef->getFileName()) != NO_ERROR)
120 { 120 {
121 return false; 121 return false;
122 } 122 }
123 123
124 // Save the section data to the file. 124 // Save the section data to the file.
125 if (pef->peHeader().writeSectionData(pef->getFileName(), secnum, buffer) != NO_ERROR) 125 if (pef->peHeader().writeSectionData(pef->getFileName(), secnum, buffer) != NO_ERROR)
126 { 126 {
127 return false; 127 return false;
128 } 128 }
129 129
130 // Fill out the section information. 130 // Fill out the section information.
131 info.index = secnum; 131 info.index = secnum;
132 info.virtual_address = pef->peHeader().getVirtualAddress(secnum); 132 info.virtual_address = pef->peHeader().getVirtualAddress(secnum);
133 info.virtual_size = pef->peHeader().getVirtualSize(secnum); 133 info.virtual_size = pef->peHeader().getVirtualSize(secnum);
134 info.raw_address = pef->peHeader().getPointerToRawData(secnum); 134 info.raw_address = pef->peHeader().getPointerToRawData(secnum);
135 info.raw_size = pef->peHeader().getSizeOfRawData(secnum); 135 info.raw_size = pef->peHeader().getSizeOfRawData(secnum);
136 info.characteristics = pef->peHeader().getCharacteristics(secnum); 136 info.characteristics = pef->peHeader().getCharacteristics(secnum);
137 137
138 return true; 138 return true;
139 } 139 }
140}; //namespace shared 140}; //namespace shared
141 141
142#endif //SHARED_PE_H_INCLUDED 142#endif //SHARED_PE_H_INCLUDED
diff --git a/utils/zenutils/source/shared/shared.cpp b/utils/zenutils/source/shared/shared.cpp
index e69de29bb2..e69de29bb2 100755..100644
--- a/utils/zenutils/source/shared/shared.cpp
+++ b/utils/zenutils/source/shared/shared.cpp
diff --git a/utils/zenutils/source/shared/updater.cpp b/utils/zenutils/source/shared/updater.cpp
index 77d3f2876c..25d8452992 100755..100644
--- a/utils/zenutils/source/shared/updater.cpp
+++ b/utils/zenutils/source/shared/updater.cpp
@@ -1,151 +1,151 @@
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 "updater.h" 19#include "updater.h"
20#include <file.h> 20#include <file.h>
21#include <pe.h> 21#include <pe.h>
22#include <utils.h> 22#include <utils.h>
23 23
24 24
25const char* zen::find_firmware_key(const byte* buffer, size_t len) 25const char* zen::find_firmware_key(const byte* buffer, size_t len)
26{ 26{
27 char szkey1[] = "34d1"; 27 char szkey1[] = "34d1";
28 size_t cchkey1 = strlen(szkey1); 28 size_t cchkey1 = strlen(szkey1);
29 char szkey2[] = "TbnCboEbn"; 29 char szkey2[] = "TbnCboEbn";
30 size_t cchkey2 = strlen(szkey2); 30 size_t cchkey2 = strlen(szkey2);
31 for (int i = 0; i < static_cast<int>(len); i++) 31 for (int i = 0; i < static_cast<int>(len); i++)
32 { 32 {
33 if (len >= cchkey1) 33 if (len >= cchkey1)
34 { 34 {
35 if (!strncmp((char*)&buffer[i], szkey1, cchkey1)) 35 if (!strncmp((char*)&buffer[i], szkey1, cchkey1))
36 { 36 {
37 return (const char*)&buffer[i]; 37 return (const char*)&buffer[i];
38 } 38 }
39 } 39 }
40 if (len >= cchkey2) 40 if (len >= cchkey2)
41 { 41 {
42 if (!strncmp((char*)&buffer[i], szkey2, cchkey2)) 42 if (!strncmp((char*)&buffer[i], szkey2, cchkey2))
43 { 43 {
44 return (const char*)&buffer[i]; 44 return (const char*)&buffer[i];
45 } 45 }
46 } 46 }
47 } 47 }
48 return NULL; 48 return NULL;
49} 49}
50 50
51dword zen::find_firmware_offset(byte* buffer, size_t len) 51dword zen::find_firmware_offset(byte* buffer, size_t len)
52{ 52{
53 for (dword i = 0; i < static_cast<dword>(len); i += 0x10) 53 for (dword i = 0; i < static_cast<dword>(len); i += 0x10)
54 { 54 {
55 dword size = *(dword*)&buffer[i]; 55 dword size = *(dword*)&buffer[i];
56 if (size < (i + len) && size > (len >> 1)) 56 if (size < (i + len) && size > (len >> 1))
57 { 57 {
58 if (buffer[i + sizeof(dword)] != 0 58 if (buffer[i + sizeof(dword)] != 0
59 && buffer[i + sizeof(dword) + 1] != 0 59 && buffer[i + sizeof(dword) + 1] != 0
60 && buffer[i + sizeof(dword) + 2] != 0 60 && buffer[i + sizeof(dword) + 2] != 0
61 && buffer[i + sizeof(dword) + 3] != 0) 61 && buffer[i + sizeof(dword) + 3] != 0)
62 { 62 {
63 return i; 63 return i;
64 } 64 }
65 } 65 }
66 } 66 }
67 return 0; 67 return 0;
68} 68}
69 69
70bool zen::find_firmware_archive(const std::string& filename, dword& va, dword& pa) 70bool zen::find_firmware_archive(const std::string& filename, dword& va, dword& pa)
71{ 71{
72 shared::pe_file pef; 72 shared::pe_file pef;
73 if (!pef.read(filename)) 73 if (!pef.read(filename))
74 { 74 {
75 return false; 75 return false;
76 } 76 }
77 shared::section_info data_section; 77 shared::section_info data_section;
78 if (!pef.find_section(".data", data_section)) 78 if (!pef.find_section(".data", data_section))
79 { 79 {
80 return false; 80 return false;
81 } 81 }
82 shared::bytes buffer; 82 shared::bytes buffer;
83 if (!shared::read_file(filename, buffer, data_section.raw_address, 83 if (!shared::read_file(filename, buffer, data_section.raw_address,
84 data_section.raw_size)) 84 data_section.raw_size))
85 { 85 {
86 return false; 86 return false;
87 } 87 }
88 dword offset = find_firmware_offset(&buffer[0], buffer.size()); 88 dword offset = find_firmware_offset(&buffer[0], buffer.size());
89 if (!offset) 89 if (!offset)
90 { 90 {
91 return false; 91 return false;
92 } 92 }
93 va = data_section.virtual_address + offset; 93 va = data_section.virtual_address + offset;
94 pa = data_section.raw_address + offset; 94 pa = data_section.raw_address + offset;
95 95
96 return true; 96 return true;
97} 97}
98 98
99 99
100bool zen::crypt_firmware(const char* key, byte* buffer, size_t len) 100bool zen::crypt_firmware(const char* key, byte* buffer, size_t len)
101{ 101{
102 // Determine if the key length is dword aligned. 102 // Determine if the key length is dword aligned.
103 int keylen = strlen(key); 103 int keylen = strlen(key);
104 int keylen_rem = keylen % sizeof(dword); 104 int keylen_rem = keylen % sizeof(dword);
105 105
106 // Determine how many times the key must be repeated to be dword aligned. 106 // Determine how many times the key must be repeated to be dword aligned.
107 int keycycle = keylen_rem ? (sizeof(dword) / keylen_rem) : 1; 107 int keycycle = keylen_rem ? (sizeof(dword) / keylen_rem) : 1;
108 int keyscount = (keylen * keycycle) / sizeof(dword); 108 int keyscount = (keylen * keycycle) / sizeof(dword);
109 109
110 // Allocate a buffer to hold the key as an array of dwords. 110 // Allocate a buffer to hold the key as an array of dwords.
111 dword* keys = new dword[keyscount]; 111 dword* keys = new dword[keyscount];
112 112
113 // Copy the key into the key array, whilst mutating it. 113 // Copy the key into the key array, whilst mutating it.
114 for (int i = 0; i < keyscount; i++) 114 for (int i = 0; i < keyscount; i++)
115 { 115 {
116 dword val; 116 dword val;
117 int keyoffset = (i * sizeof(dword)) % keylen; 117 int keyoffset = (i * sizeof(dword)) % keylen;
118 if ((keyoffset+sizeof(dword)) < keylen) 118 if ((keyoffset+sizeof(dword)) < keylen)
119 { 119 {
120 val = *(dword*)&key[keyoffset]; 120 val = *(dword*)&key[keyoffset];
121 } 121 }
122 else 122 else
123 { 123 {
124 val = key[keyoffset] 124 val = key[keyoffset]
125 | (key[(keyoffset + 1) % keylen] << 8) 125 | (key[(keyoffset + 1) % keylen] << 8)
126 | (key[(keyoffset + 2) % keylen] << 16) 126 | (key[(keyoffset + 2) % keylen] << 16)
127 | (key[(keyoffset + 3) % keylen] << 24); 127 | (key[(keyoffset + 3) % keylen] << 24);
128 } 128 }
129 keys[i] = (val - 0x01010101) | 0x80808080; 129 keys[i] = (val - 0x01010101) | 0x80808080;
130 } 130 }
131 131
132 // Determine the number of dwords in the buffer. 132 // Determine the number of dwords in the buffer.
133 int len_div = len / sizeof(dword); 133 int len_div = len / sizeof(dword);
134 134
135 // Decrypt all dwords of the buffer. 135 // Decrypt all dwords of the buffer.
136 for (int i = 0; i < len_div; i++) 136 for (int i = 0; i < len_div; i++)
137 { 137 {
138 ((dword*)buffer)[i] ^= keys[i % keyscount]; 138 ((dword*)buffer)[i] ^= keys[i % keyscount];
139 } 139 }
140 140
141 // Determine the remaining number of bytes in the buffer. 141 // Determine the remaining number of bytes in the buffer.
142 int len_rem = len % sizeof(dword); 142 int len_rem = len % sizeof(dword);
143 143
144 // Decrypt the remaining number of bytes in the buffer. 144 // Decrypt the remaining number of bytes in the buffer.
145 for (int i = len_div * sizeof(dword); i < len; i++) 145 for (int i = len_div * sizeof(dword); i < len; i++)
146 { 146 {
147 buffer[i] ^= ((key[i % keylen] - 0x01) | 0x80); 147 buffer[i] ^= ((key[i % keylen] - 0x01) | 0x80);
148 } 148 }
149 149
150 return true; 150 return true;
151} 151}
diff --git a/utils/zenutils/source/shared/updater.h b/utils/zenutils/source/shared/updater.h
index 57f9979c30..884fe9568c 100755..100644
--- a/utils/zenutils/source/shared/updater.h
+++ b/utils/zenutils/source/shared/updater.h
@@ -1,32 +1,32 @@
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#ifndef ZEN_UPDATER_H_INCLUDED 19#ifndef ZEN_UPDATER_H_INCLUDED
20#define ZEN_UPDATER_H_INCLUDED 20#define ZEN_UPDATER_H_INCLUDED
21 21
22#include <pelib/PeLib.h> 22#include <pelib/PeLib.h>
23#include <utils.h> 23#include <utils.h>
24 24
25namespace zen { 25namespace zen {
26 const char* find_firmware_key(const byte* buffer, size_t len); 26 const char* find_firmware_key(const byte* buffer, size_t len);
27 dword find_firmware_offset(byte* buffer, size_t len); 27 dword find_firmware_offset(byte* buffer, size_t len);
28 bool find_firmware_archive(const std::string& filename, dword& va, dword& pa); 28 bool find_firmware_archive(const std::string& filename, dword& va, dword& pa);
29 bool crypt_firmware(const char* key, byte* buffer, size_t len); 29 bool crypt_firmware(const char* key, byte* buffer, size_t len);
30}; //namespace zen 30}; //namespace zen
31 31
32#endif //ZEN_UPDATER_H_INCLUDED 32#endif //ZEN_UPDATER_H_INCLUDED
diff --git a/utils/zenutils/source/shared/utils.cpp b/utils/zenutils/source/shared/utils.cpp
index 8f45de5d3f..fbb223b42b 100755..100644
--- a/utils/zenutils/source/shared/utils.cpp
+++ b/utils/zenutils/source/shared/utils.cpp
@@ -1,211 +1,211 @@
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 "utils.h" 19#include "utils.h"
20#include <fstream> 20#include <fstream>
21#include <zlib/zlib.h> 21#include <zlib/zlib.h>
22 22
23 23
24std::string shared::replace_extension(const std::string& filename, const std::string& extension) 24std::string shared::replace_extension(const std::string& filename, const std::string& extension)
25{ 25{
26 std::string newname; 26 std::string newname;
27 const char* name = filename.c_str(); 27 const char* name = filename.c_str();
28 const char* ext = strrchr(name, '.'); 28 const char* ext = strrchr(name, '.');
29 if (ext) 29 if (ext)
30 { 30 {
31 // If an extension was found, replace it. 31 // If an extension was found, replace it.
32 newname.assign(name, ext-name); 32 newname.assign(name, ext-name);
33 newname += extension; 33 newname += extension;
34 } 34 }
35 else 35 else
36 { 36 {
37 // If an extension was not found, append it. 37 // If an extension was not found, append it.
38 newname = name; 38 newname = name;
39 newname += extension; 39 newname += extension;
40 } 40 }
41 return newname; 41 return newname;
42} 42}
43 43
44std::string shared::remove_extension(const std::string& filename) 44std::string shared::remove_extension(const std::string& filename)
45{ 45{
46 std::string newname; 46 std::string newname;
47 const char* name = filename.c_str(); 47 const char* name = filename.c_str();
48 const char* ext = strrchr(name, '.'); 48 const char* ext = strrchr(name, '.');
49 if (ext) 49 if (ext)
50 { 50 {
51 newname.assign(name, ext-name); 51 newname.assign(name, ext-name);
52 } 52 }
53 else 53 else
54 { 54 {
55 newname = name; 55 newname = name;
56 } 56 }
57 return newname; 57 return newname;
58} 58}
59 59
60std::string shared::double_quote(const std::string& str) 60std::string shared::double_quote(const std::string& str)
61{ 61{
62 std::string out; 62 std::string out;
63 for (int i = 0, j = str.length(); i < j; i++) 63 for (int i = 0, j = str.length(); i < j; i++)
64 { 64 {
65 if (str[i] == '\\') 65 if (str[i] == '\\')
66 out += "\\\\"; 66 out += "\\\\";
67 else 67 else
68 out += str[i]; 68 out += str[i];
69 } 69 }
70 return out; 70 return out;
71} 71}
72 72
73bool shared::inflate_to_file(const bytes& buffer, const char* filename) 73bool shared::inflate_to_file(const bytes& buffer, const char* filename)
74{ 74{
75 // Open output file. 75 // Open output file.
76 std::ofstream ofs; 76 std::ofstream ofs;
77 ofs.open(filename, std::ios::binary); 77 ofs.open(filename, std::ios::binary);
78 if (!ofs) 78 if (!ofs)
79 { 79 {
80 return false; 80 return false;
81 } 81 }
82 82
83 // Initialize zlib. 83 // Initialize zlib.
84 z_stream d_stream; // decompression stream 84 z_stream d_stream; // decompression stream
85 85
86 d_stream.zalloc = Z_NULL; 86 d_stream.zalloc = Z_NULL;
87 d_stream.zfree = Z_NULL; 87 d_stream.zfree = Z_NULL;
88 d_stream.opaque = Z_NULL; 88 d_stream.opaque = Z_NULL;
89 89
90 d_stream.next_in = const_cast<bytes::value_type*>(&buffer[0]); 90 d_stream.next_in = const_cast<bytes::value_type*>(&buffer[0]);
91 d_stream.avail_in = static_cast<uInt>(buffer.size()); 91 d_stream.avail_in = static_cast<uInt>(buffer.size());
92 92
93 int ret = inflateInit(&d_stream); 93 int ret = inflateInit(&d_stream);
94 if (ret != Z_OK) 94 if (ret != Z_OK)
95 return false; 95 return false;
96 96
97 // Allocate buffer to hold the inflated data. 97 // Allocate buffer to hold the inflated data.
98 const size_t BUFSIZE = 1048576; 98 const size_t BUFSIZE = 1048576;
99 Bytef* infbuf = new Bytef[BUFSIZE]; 99 Bytef* infbuf = new Bytef[BUFSIZE];
100 if (!infbuf) 100 if (!infbuf)
101 return false; 101 return false;
102 102
103 // Decompress untill the end of the input buffer. 103 // Decompress untill the end of the input buffer.
104 uLong totalout = 0; 104 uLong totalout = 0;
105 bool bLoop = true; 105 bool bLoop = true;
106 while (bLoop) 106 while (bLoop)
107 { 107 {
108 d_stream.next_out = infbuf; 108 d_stream.next_out = infbuf;
109 d_stream.avail_out = BUFSIZE; 109 d_stream.avail_out = BUFSIZE;
110 110
111 ret = inflate(&d_stream, Z_NO_FLUSH); 111 ret = inflate(&d_stream, Z_NO_FLUSH);
112 if (ret == Z_STREAM_END) 112 if (ret == Z_STREAM_END)
113 { 113 {
114 bLoop = false; 114 bLoop = false;
115 } 115 }
116 else if (ret != Z_OK) 116 else if (ret != Z_OK)
117 { 117 {
118 inflateEnd(&d_stream); 118 inflateEnd(&d_stream);
119 delete [] infbuf; 119 delete [] infbuf;
120 return false; 120 return false;
121 } 121 }
122 122
123 // Write the inflated data to the output file. 123 // Write the inflated data to the output file.
124 if (!ofs.write((const char*)infbuf, d_stream.total_out-totalout)) 124 if (!ofs.write((const char*)infbuf, d_stream.total_out-totalout))
125 { 125 {
126 inflateEnd(&d_stream); 126 inflateEnd(&d_stream);
127 delete [] infbuf; 127 delete [] infbuf;
128 return false; 128 return false;
129 } 129 }
130 totalout = d_stream.total_out; 130 totalout = d_stream.total_out;
131 } 131 }
132 132
133 // Cleanup and return. 133 // Cleanup and return.
134 inflateEnd(&d_stream); 134 inflateEnd(&d_stream);
135 delete [] infbuf; 135 delete [] infbuf;
136 136
137 return true; 137 return true;
138} 138}
139 139
140bool shared::deflate_to_file(const bytes& buffer, const char* filename) 140bool shared::deflate_to_file(const bytes& buffer, const char* filename)
141{ 141{
142 // Open output file. 142 // Open output file.
143 std::ofstream ofs; 143 std::ofstream ofs;
144 ofs.open(filename, std::ios::binary); 144 ofs.open(filename, std::ios::binary);
145 if (!ofs) 145 if (!ofs)
146 { 146 {
147 return false; 147 return false;
148 } 148 }
149 149
150 // Initialize zlib. 150 // Initialize zlib.
151 z_stream c_stream; // compression stream. 151 z_stream c_stream; // compression stream.
152 152
153 c_stream.zalloc = Z_NULL; 153 c_stream.zalloc = Z_NULL;
154 c_stream.zfree = Z_NULL; 154 c_stream.zfree = Z_NULL;
155 c_stream.opaque = Z_NULL; 155 c_stream.opaque = Z_NULL;
156 156
157 int ret = deflateInit(&c_stream, Z_BEST_COMPRESSION); 157 int ret = deflateInit(&c_stream, Z_BEST_COMPRESSION);
158 if (ret != Z_OK) 158 if (ret != Z_OK)
159 return false; 159 return false;
160 160
161 // Allocate buffer to hold the deflated data. 161 // Allocate buffer to hold the deflated data.
162 const size_t BUFSIZE = 1048576; 162 const size_t BUFSIZE = 1048576;
163 Bytef* defbuf = new Bytef[BUFSIZE]; 163 Bytef* defbuf = new Bytef[BUFSIZE];
164 if (!defbuf) 164 if (!defbuf)
165 return false; 165 return false;
166 166
167 c_stream.avail_in = static_cast<uInt>(buffer.size()); 167 c_stream.avail_in = static_cast<uInt>(buffer.size());
168 c_stream.next_in = const_cast<bytes::value_type*>(&buffer[0]); 168 c_stream.next_in = const_cast<bytes::value_type*>(&buffer[0]);
169 169
170 // Compress until end of the buffer. 170 // Compress until end of the buffer.
171 uLong totalout = 0; 171 uLong totalout = 0;
172 bool bLoop = true; 172 bool bLoop = true;
173 while (bLoop) 173 while (bLoop)
174 { 174 {
175 c_stream.avail_out = BUFSIZE; 175 c_stream.avail_out = BUFSIZE;
176 c_stream.next_out = defbuf; 176 c_stream.next_out = defbuf;
177 177
178 ret = deflate(&c_stream, Z_NO_FLUSH); // no bad return value 178 ret = deflate(&c_stream, Z_NO_FLUSH); // no bad return value
179 if (ret == Z_STREAM_END) 179 if (ret == Z_STREAM_END)
180 { 180 {
181 bLoop = false; 181 bLoop = false;
182 } 182 }
183 else if (ret == Z_BUF_ERROR && !c_stream.avail_in) 183 else if (ret == Z_BUF_ERROR && !c_stream.avail_in)
184 { 184 {
185 ret = deflate(&c_stream, Z_FINISH); // no bad return value 185 ret = deflate(&c_stream, Z_FINISH); // no bad return value
186 bLoop = false; 186 bLoop = false;
187 } 187 }
188 else if (ret != Z_OK) 188 else if (ret != Z_OK)
189 { 189 {
190 deflateEnd(&c_stream); 190 deflateEnd(&c_stream);
191 delete [] defbuf; 191 delete [] defbuf;
192 return false; 192 return false;
193 } 193 }
194 194
195 // Write the inflated data to the output file. 195 // Write the inflated data to the output file.
196 if (!ofs.write((const char*)defbuf, c_stream.total_out-totalout)) 196 if (!ofs.write((const char*)defbuf, c_stream.total_out-totalout))
197 { 197 {
198 deflateEnd(&c_stream); 198 deflateEnd(&c_stream);
199 delete [] defbuf; 199 delete [] defbuf;
200 return false; 200 return false;
201 } 201 }
202 202
203 totalout = c_stream.total_out; 203 totalout = c_stream.total_out;
204 } 204 }
205 205
206 // Clean up and return. 206 // Clean up and return.
207 deflateEnd(&c_stream); 207 deflateEnd(&c_stream);
208 delete [] defbuf; 208 delete [] defbuf;
209 209
210 return true; 210 return true;
211} 211}
diff --git a/utils/zenutils/source/shared/utils.h b/utils/zenutils/source/shared/utils.h
index ca9e291514..694cb9c8b1 100755..100644
--- a/utils/zenutils/source/shared/utils.h
+++ b/utils/zenutils/source/shared/utils.h
@@ -1,68 +1,68 @@
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#ifndef SHARED_UTILS_H_INCLUDED 19#ifndef SHARED_UTILS_H_INCLUDED
20#define SHARED_UTILS_H_INCLUDED 20#define SHARED_UTILS_H_INCLUDED
21 21
22#include <vector> 22#include <vector>
23#include <pelib/PeLib.h> 23#include <pelib/PeLib.h>
24 24
25#ifndef byte 25#ifndef byte
26typedef PeLib::byte byte; 26typedef PeLib::byte byte;
27#endif 27#endif
28#ifndef word 28#ifndef word
29typedef PeLib::word word; 29typedef PeLib::word word;
30#endif 30#endif
31#ifndef dword 31#ifndef dword
32typedef PeLib::dword dword; 32typedef PeLib::dword dword;
33#endif 33#endif
34 34
35namespace shared { 35namespace shared {
36 typedef std::vector<byte> bytes; 36 typedef std::vector<byte> bytes;
37 37
38 inline dword swap(dword val) 38 inline dword swap(dword val)
39 { 39 {
40 return ((val & 0xFF) << 24) 40 return ((val & 0xFF) << 24)
41 | ((val & 0xFF00) << 8) 41 | ((val & 0xFF00) << 8)
42 | ((val & 0xFF0000) >> 8) 42 | ((val & 0xFF0000) >> 8)
43 | ((val & 0xFF000000) >> 24); 43 | ((val & 0xFF000000) >> 24);
44 } 44 }
45 45
46 template <typename _Type> 46 template <typename _Type>
47 inline void reverse(_Type* start, _Type* end) 47 inline void reverse(_Type* start, _Type* end)
48 { 48 {
49 while (start < end) 49 while (start < end)
50 { 50 {
51 *start ^= *end; 51 *start ^= *end;
52 *end ^= *start; 52 *end ^= *start;
53 *start ^= *end; 53 *start ^= *end;
54 start++; 54 start++;
55 end--; 55 end--;
56 } 56 }
57 } 57 }
58 58
59 std::string replace_extension(const std::string& filename, const std::string& extension); 59 std::string replace_extension(const std::string& filename, const std::string& extension);
60 std::string remove_extension(const std::string& filename); 60 std::string remove_extension(const std::string& filename);
61 std::string get_path(const std::string& filename); 61 std::string get_path(const std::string& filename);
62 std::string double_quote(const std::string& str); 62 std::string double_quote(const std::string& str);
63 63
64 bool inflate_to_file(const bytes& buffer, const char* filename); 64 bool inflate_to_file(const bytes& buffer, const char* filename);
65 bool deflate_to_file(const bytes& buffer, const char* filename); 65 bool deflate_to_file(const bytes& buffer, const char* filename);
66}; //namespace shared 66}; //namespace shared
67 67
68#endif //SHARED_UTILS_H_INCLUDED 68#endif //SHARED_UTILS_H_INCLUDED
diff --git a/utils/zenutils/source/update_extract/CMakeLists.txt b/utils/zenutils/source/update_extract/CMakeLists.txt
index 813e389bed..60d298be11 100755..100644
--- a/utils/zenutils/source/update_extract/CMakeLists.txt
+++ b/utils/zenutils/source/update_extract/CMakeLists.txt
@@ -1,3 +1,3 @@
1ADD_EXECUTABLE(update_extract main.cpp) 1ADD_EXECUTABLE(update_extract main.cpp)
2 2
3TARGET_LINK_LIBRARIES (update_extract shared) 3TARGET_LINK_LIBRARIES (update_extract shared)
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
28static const char VERSION[] = "0.1"; 28static const char VERSION[] = "0.1";
29 29
30void print_version() 30void 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
39void print_help() 39void 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
65std::string options_name(const std::string& name) 65std::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
70std::string default_firmware_name(const std::string& name) 70std::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
75int process_arguments(int argc, char* argv[]) 75int 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
262int main(int argc, char* argv[]) 262int 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}
diff --git a/utils/zenutils/source/update_patch/CMakeLists.txt b/utils/zenutils/source/update_patch/CMakeLists.txt
index 11474b7ff8..7b509dc40d 100755..100644
--- a/utils/zenutils/source/update_patch/CMakeLists.txt
+++ b/utils/zenutils/source/update_patch/CMakeLists.txt
@@ -1,3 +1,3 @@
1ADD_EXECUTABLE(update_patch main.cpp) 1ADD_EXECUTABLE(update_patch main.cpp)
2 2
3TARGET_LINK_LIBRARIES (update_patch shared) 3TARGET_LINK_LIBRARIES (update_patch shared)
diff --git a/utils/zenutils/source/update_patch/main.cpp b/utils/zenutils/source/update_patch/main.cpp
index d48797b46d..5467694728 100755..100644
--- a/utils/zenutils/source/update_patch/main.cpp
+++ b/utils/zenutils/source/update_patch/main.cpp
@@ -1,409 +1,409 @@
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 <cstdio> 21#include <cstdio>
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#include <pe.h> 26#include <pe.h>
27 27
28 28
29static const char VERSION[] = "0.1"; 29static const char VERSION[] = "0.1";
30 30
31void print_version() 31void print_version()
32{ 32{
33 std::cout 33 std::cout
34 << "update_patch - Patches a Creative firmware into an updater" 34 << "update_patch - Patches a Creative firmware into an updater"
35 " executable." << std::endl 35 " executable." << std::endl
36 << "Version " << VERSION << std::endl 36 << "Version " << VERSION << std::endl
37 << "Copyright (c) 2007 Rasmus Ry" << std::endl; 37 << "Copyright (c) 2007 Rasmus Ry" << std::endl;
38} 38}
39 39
40void print_help() 40void print_help()
41{ 41{
42 print_version(); 42 print_version();
43 std::cout << std::endl 43 std::cout << std::endl
44 << "Usage: update_patch [command] [options]" << std::endl 44 << "Usage: update_patch [command] [options]" << std::endl
45 << std::endl 45 << std::endl
46 << " Commands:" << std::endl 46 << " Commands:" << std::endl
47 << " -h,--help" << std::endl 47 << " -h,--help" << std::endl
48 << " prints this message." << std::endl 48 << " prints this message." << std::endl
49 << " -u,--updater [file]" << std::endl 49 << " -u,--updater [file]" << std::endl
50 << " specifies the updater executable." << std::endl 50 << " specifies the updater executable." << std::endl
51 << std::endl 51 << std::endl
52 << " Options:" << std::endl 52 << " Options:" << std::endl
53 << " -V,--verbose" << std::endl 53 << " -V,--verbose" << std::endl
54 << " prints verbose messages." << std::endl 54 << " prints verbose messages." << std::endl
55 << " -f,--firmware [file]" << std::endl 55 << " -f,--firmware [file]" << std::endl
56 << " specifies the firmware arhive file name." << std::endl 56 << " specifies the firmware arhive file name." << std::endl
57 << " -k,--key [key]" << std::endl 57 << " -k,--key [key]" << std::endl
58 << " specifies the firmware archive key." << std::endl 58 << " specifies the firmware archive key." << std::endl
59 << " -o,--offset [offset]" << std::endl 59 << " -o,--offset [offset]" << std::endl
60 << " specifies the firmware archive offset in c-style" 60 << " specifies the firmware archive offset in c-style"
61 " hexadecimal." << std::endl 61 " hexadecimal." << std::endl
62 << std::endl 62 << std::endl
63 ; 63 ;
64} 64}
65 65
66std::string options_name(const std::string& name) 66std::string options_name(const std::string& name)
67{ 67{
68 return shared::replace_extension(name, ".opt"); 68 return shared::replace_extension(name, ".opt");
69} 69}
70 70
71std::string default_firmware_name(const std::string& name) 71std::string default_firmware_name(const std::string& name)
72{ 72{
73 return shared::replace_extension(name, "_rk.bin"); 73 return shared::replace_extension(name, "_rk.bin");
74} 74}
75 75
76int process_arguments(int argc, char* argv[]) 76int process_arguments(int argc, char* argv[])
77{ 77{
78 //-------------------------------------------------------------------- 78 //--------------------------------------------------------------------
79 // Parse input variables. 79 // Parse input variables.
80 //-------------------------------------------------------------------- 80 //--------------------------------------------------------------------
81 81
82 GetPot cl(argc, argv); 82 GetPot cl(argc, argv);
83 if (cl.size() == 1 || cl.search(2, "-h", "--help")) 83 if (cl.size() == 1 || cl.search(2, "-h", "--help"))
84 { 84 {
85 print_help(); 85 print_help();
86 return 1; 86 return 1;
87 } 87 }
88 88
89 std::string updatername; 89 std::string updatername;
90 if (cl.search("-u") || cl.search("--updater")) 90 if (cl.search("-u") || cl.search("--updater"))
91 updatername = cl.next(""); 91 updatername = cl.next("");
92 if (updatername.empty()) 92 if (updatername.empty())
93 { 93 {
94 std::cerr << "Updater executable must be specified." << std::endl; 94 std::cerr << "Updater executable must be specified." << std::endl;
95 return 2; 95 return 2;
96 } 96 }
97 97
98 bool verbose = false; 98 bool verbose = false;
99 if (cl.search("-V") || cl.search("--verbose")) 99 if (cl.search("-V") || cl.search("--verbose"))
100 verbose = true; 100 verbose = true;
101 101
102 if (verbose) 102 if (verbose)
103 std::cout << "[*] Parsing options file..." << std::endl; 103 std::cout << "[*] Parsing options file..." << std::endl;
104 104
105 GetPot optfile(options_name(updatername.c_str()).c_str()); 105 GetPot optfile(options_name(updatername.c_str()).c_str());
106 if (verbose) 106 if (verbose)
107 optfile.print(); 107 optfile.print();
108 108
109 std::string firmwarename = optfile("firmware", 109 std::string firmwarename = optfile("firmware",
110 default_firmware_name(updatername).c_str()); 110 default_firmware_name(updatername).c_str());
111 dword offset_pa = optfile("offset", 0); 111 dword offset_pa = optfile("offset", 0);
112 dword size = optfile("size", 0); 112 dword size = optfile("size", 0);
113 std::string key = optfile("key", ""); 113 std::string key = optfile("key", "");
114 114
115 if (cl.search("-f") || cl.search("--firmware")) 115 if (cl.search("-f") || cl.search("--firmware"))
116 firmwarename = cl.next(firmwarename.c_str()); 116 firmwarename = cl.next(firmwarename.c_str());
117 117
118 std::string offset; 118 std::string offset;
119 if (cl.search("-o") || cl.search("--offset")) 119 if (cl.search("-o") || cl.search("--offset"))
120 offset = cl.next(""); 120 offset = cl.next("");
121 121
122 if (offset.empty() && !offset_pa) 122 if (offset.empty() && !offset_pa)
123 { 123 {
124 if (verbose) 124 if (verbose)
125 std::cout << "[*] Looking for firmware archive offset..." 125 std::cout << "[*] Looking for firmware archive offset..."
126 << std::endl; 126 << std::endl;
127 127
128 dword offset_va = 0; 128 dword offset_va = 0;
129 if (!zen::find_firmware_archive(updatername, offset_va, offset_pa)) 129 if (!zen::find_firmware_archive(updatername, offset_va, offset_pa))
130 { 130 {
131 std::cerr << "Failed to find the firmware archive offset." 131 std::cerr << "Failed to find the firmware archive offset."
132 << std::endl; 132 << std::endl;
133 return 3; 133 return 3;
134 } 134 }
135 } 135 }
136 else if (!offset_pa) 136 else if (!offset_pa)
137 { 137 {
138 int offset_val; 138 int offset_val;
139 if (!sscanf(offset.c_str(), "0x%x", &offset_val)) 139 if (!sscanf(offset.c_str(), "0x%x", &offset_val))
140 { 140 {
141 if (!sscanf(offset.c_str(), "0x%X", &offset_val)) 141 if (!sscanf(offset.c_str(), "0x%X", &offset_val))
142 { 142 {
143 std::cerr << "\'" << offset 143 std::cerr << "\'" << offset
144 << "\' is not a valid c-style hexadecimal value." 144 << "\' is not a valid c-style hexadecimal value."
145 << std::endl; 145 << std::endl;
146 return 4; 146 return 4;
147 } 147 }
148 } 148 }
149 offset_pa = static_cast<dword>(offset_val); 149 offset_pa = static_cast<dword>(offset_val);
150 } 150 }
151 151
152 if (key.empty()) 152 if (key.empty())
153 { 153 {
154 if (verbose) 154 if (verbose)
155 std::cout << "[*] Looking for firmware archive key..." 155 std::cout << "[*] Looking for firmware archive key..."
156 << std::endl; 156 << std::endl;
157 shared::bytes buffer; 157 shared::bytes buffer;
158 if (!shared::read_file(updatername, buffer)) 158 if (!shared::read_file(updatername, buffer))
159 { 159 {
160 std::cerr << "Failed to read the firmware updater executable." 160 std::cerr << "Failed to read the firmware updater executable."
161 << std::endl; 161 << std::endl;
162 return 5; 162 return 5;
163 } 163 }
164 key = zen::find_firmware_key(&buffer[0], buffer.size()); 164 key = zen::find_firmware_key(&buffer[0], buffer.size());
165 if (key.empty()) 165 if (key.empty())
166 { 166 {
167 std::cerr << "Failed to find the firmware archive key." 167 std::cerr << "Failed to find the firmware archive key."
168 << std::endl; 168 << std::endl;
169 return 6; 169 return 6;
170 } 170 }
171 } 171 }
172 172
173 if (verbose) 173 if (verbose)
174 { 174 {
175 std::cout << "[*] Printing input variables..." << std::endl; 175 std::cout << "[*] Printing input variables..." << std::endl;
176 std::cout << " Updater executable: " << updatername << std::endl; 176 std::cout << " Updater executable: " << updatername << std::endl;
177 std::cout << " Firmware archive: " << firmwarename << std::endl; 177 std::cout << " Firmware archive: " << firmwarename << std::endl;
178 std::cout << " Key: " << key << std::endl; 178 std::cout << " Key: " << key << std::endl;
179 std::cout << " Offset: " 179 std::cout << " Offset: "
180 << std::hex << std::showbase << std::setw(10) 180 << std::hex << std::showbase << std::setw(10)
181 << std::setfill('0') << std::internal 181 << std::setfill('0') << std::internal
182 << offset_pa << std::endl; 182 << offset_pa << std::endl;
183 std::cout << " Size: " 183 std::cout << " Size: "
184 << std::hex << std::showbase << std::setw(10) 184 << std::hex << std::showbase << std::setw(10)
185 << std::setfill('0') << std::internal 185 << std::setfill('0') << std::internal
186 << size << std::endl; 186 << size << std::endl;
187 } 187 }
188 188
189 189
190 //-------------------------------------------------------------------- 190 //--------------------------------------------------------------------
191 // Prepare the firmware archive for being patched into the updater. 191 // Prepare the firmware archive for being patched into the updater.
192 //-------------------------------------------------------------------- 192 //--------------------------------------------------------------------
193 193
194 if (verbose) 194 if (verbose)
195 std::cout << "[*] Reading firmware archive..." << std::endl; 195 std::cout << "[*] Reading firmware archive..." << std::endl;
196 196
197 shared::bytes buffer; 197 shared::bytes buffer;
198 if (!shared::read_file(firmwarename, buffer)) 198 if (!shared::read_file(firmwarename, buffer))
199 { 199 {
200 std::cerr << "Failed to read the firmware archive." << std::endl; 200 std::cerr << "Failed to read the firmware archive." << std::endl;
201 return 7; 201 return 7;
202 } 202 }
203 203
204 if (verbose) 204 if (verbose)
205 std::cout << " Bytes read: " 205 std::cout << " Bytes read: "
206 << std::hex << std::showbase << std::setw(10) 206 << std::hex << std::showbase << std::setw(10)
207 << std::setfill('0') << std::internal 207 << std::setfill('0') << std::internal
208 << buffer.size() << std::endl; 208 << buffer.size() << std::endl;
209 209
210 if (verbose) 210 if (verbose)
211 std::cout << "[*] Compressing firmware archive..." << std::endl; 211 std::cout << "[*] Compressing firmware archive..." << std::endl;
212 212
213 std::string compfirmware = shared::replace_extension(firmwarename, ".def"); 213 std::string compfirmware = shared::replace_extension(firmwarename, ".def");
214 if (!shared::deflate_to_file(buffer, compfirmware.c_str())) 214 if (!shared::deflate_to_file(buffer, compfirmware.c_str()))
215 { 215 {
216 std::cerr << "Failed to compress the firmware archive." << std::endl; 216 std::cerr << "Failed to compress the firmware archive." << std::endl;
217 return 8; 217 return 8;
218 } 218 }
219 219
220 if (verbose) 220 if (verbose)
221 std::cout << "[*] Reading compressed firmware archive..." << std::endl; 221 std::cout << "[*] Reading compressed firmware archive..." << std::endl;
222 222
223 if (!shared::read_file(compfirmware, buffer)) 223 if (!shared::read_file(compfirmware, buffer))
224 { 224 {
225 std::cerr << "Failed to read the compressed firmware archive." 225 std::cerr << "Failed to read the compressed firmware archive."
226 << std::endl; 226 << std::endl;
227 return 9; 227 return 9;
228 } 228 }
229 229
230 if (verbose) 230 if (verbose)
231 std::cout << " Bytes read: " 231 std::cout << " Bytes read: "
232 << std::hex << std::showbase << std::setw(10) 232 << std::hex << std::showbase << std::setw(10)
233 << std::setfill('0') << std::internal 233 << std::setfill('0') << std::internal
234 << buffer.size() << std::endl; 234 << buffer.size() << std::endl;
235 235
236 // Delete the temporary firmware file. 236 // Delete the temporary firmware file.
237 std::remove(compfirmware.c_str()); 237 std::remove(compfirmware.c_str());
238 238
239 if (verbose) 239 if (verbose)
240 std::cout << "[*] Encrypting compressed firmware archive..." 240 std::cout << "[*] Encrypting compressed firmware archive..."
241 << std::endl; 241 << std::endl;
242 242
243 if (!zen::crypt_firmware(key.c_str(), &buffer[0], buffer.size())) 243 if (!zen::crypt_firmware(key.c_str(), &buffer[0], buffer.size()))
244 { 244 {
245 std::cerr << "Failed to encrypt the compressed firmware archive." 245 std::cerr << "Failed to encrypt the compressed firmware archive."
246 << std::endl; 246 << std::endl;
247 return 10; 247 return 10;
248 } 248 }
249 249
250 250
251 //-------------------------------------------------------------------- 251 //--------------------------------------------------------------------
252 // Backup the updater and patch the firmware archive into it. 252 // Backup the updater and patch the firmware archive into it.
253 //-------------------------------------------------------------------- 253 //--------------------------------------------------------------------
254 254
255 if (verbose) 255 if (verbose)
256 std::cout << "[*] Backing up the updater executable..." << std::endl; 256 std::cout << "[*] Backing up the updater executable..." << std::endl;
257 257
258 if (!shared::backup_file(updatername)) 258 if (!shared::backup_file(updatername))
259 { 259 {
260 std::cerr << "Failed to backup the updater executable." << std::endl; 260 std::cerr << "Failed to backup the updater executable." << std::endl;
261 return 11; 261 return 11;
262 } 262 }
263 263
264 // Is there enough space within the existing firmware archive 264 // Is there enough space within the existing firmware archive
265 // to hold the new one? 265 // to hold the new one?
266 if (size < buffer.size()) 266 if (size < buffer.size())
267 { 267 {
268 // No, we need to add a new section to hold the new firmware archive. 268 // No, we need to add a new section to hold the new firmware archive.
269 if (verbose) 269 if (verbose)
270 std::cout << "[*] Adding new section to the updater executable..." 270 std::cout << "[*] Adding new section to the updater executable..."
271 << std::endl; 271 << std::endl;
272 272
273 // Construct a new buffer with the archive size prepended. 273 // Construct a new buffer with the archive size prepended.
274 shared::bytes newbuffer(buffer.size() + sizeof(dword)); 274 shared::bytes newbuffer(buffer.size() + sizeof(dword));
275 *(dword*)&newbuffer[0] = static_cast<dword>(buffer.size()); 275 *(dword*)&newbuffer[0] = static_cast<dword>(buffer.size());
276 std::copy(buffer.begin(), buffer.end(), &newbuffer[4]); 276 std::copy(buffer.begin(), buffer.end(), &newbuffer[4]);
277 277
278 // Read the updater portable executable. 278 // Read the updater portable executable.
279 shared::pe_file pef; 279 shared::pe_file pef;
280 if (!pef.read(updatername)) 280 if (!pef.read(updatername))
281 { 281 {
282 std::cerr << "Failed to read the updater portable executable" 282 std::cerr << "Failed to read the updater portable executable"
283 " structure." << std::endl; 283 " structure." << std::endl;
284 return 12; 284 return 12;
285 } 285 }
286 286
287 // Add a new section to the updater, containing the encrypted 287 // Add a new section to the updater, containing the encrypted
288 // firmware archive. 288 // firmware archive.
289 shared::section_info newsection; 289 shared::section_info newsection;
290 if (!pef.add_section(".firm", newbuffer, newsection)) 290 if (!pef.add_section(".firm", newbuffer, newsection))
291 { 291 {
292 std::cerr << "Failed to add an extra section to the updater" 292 std::cerr << "Failed to add an extra section to the updater"
293 " executable." << std::endl; 293 " executable." << std::endl;
294 return 13; 294 return 13;
295 } 295 }
296 296
297 if (verbose) 297 if (verbose)
298 std::cout << "[*] Relocating code references to the firmware" 298 std::cout << "[*] Relocating code references to the firmware"
299 " archive..." << std::endl; 299 " archive..." << std::endl;
300 300
301 // Locate the code section. 301 // Locate the code section.
302 shared::section_info textsection; 302 shared::section_info textsection;
303 if (!pef.find_section(".text", textsection)) 303 if (!pef.find_section(".text", textsection))
304 { 304 {
305 std::cerr << "Failed to find the code section in the updater" 305 std::cerr << "Failed to find the code section in the updater"
306 " executable." << std::endl; 306 " executable." << std::endl;
307 return 14; 307 return 14;
308 } 308 }
309 309
310 // Read the code section data. 310 // Read the code section data.
311 if (!shared::read_file(updatername, buffer, textsection.raw_address, 311 if (!shared::read_file(updatername, buffer, textsection.raw_address,
312 textsection.raw_size)) 312 textsection.raw_size))
313 { 313 {
314 std::cerr << "Failed to read the code section from the updater" 314 std::cerr << "Failed to read the code section from the updater"
315 " executable." << std::endl; 315 " executable." << std::endl;
316 return 15; 316 return 15;
317 } 317 }
318 318
319 // Determine the addresses of the new and old firmware archives. 319 // Determine the addresses of the new and old firmware archives.
320 dword oldva = pef.pa_to_va(offset_pa); 320 dword oldva = pef.pa_to_va(offset_pa);
321 dword newva = pef.pa_to_va(newsection.raw_address); 321 dword newva = pef.pa_to_va(newsection.raw_address);
322 if (!oldva || !newva) 322 if (!oldva || !newva)
323 { 323 {
324 std::cerr << "Failed to compute address of the new or old" 324 std::cerr << "Failed to compute address of the new or old"
325 " archive." << std::endl; 325 " archive." << std::endl;
326 return 16; 326 return 16;
327 } 327 }
328 328
329 // Relocate references to the old firmware archive. 329 // Relocate references to the old firmware archive.
330 dword imgbase = pef.get_image_base(); 330 dword imgbase = pef.get_image_base();
331 for (int i = 0, j = buffer.size() - sizeof(dword) + 1; i < j; i++) 331 for (int i = 0, j = buffer.size() - sizeof(dword) + 1; i < j; i++)
332 { 332 {
333 dword val = *(dword*)&buffer[i]; 333 dword val = *(dword*)&buffer[i];
334 if (val >= oldva && val <= (oldva + 3)) 334 if (val >= oldva && val <= (oldva + 3))
335 { 335 {
336 *(dword*)&buffer[i] = newva + (val - oldva); 336 *(dword*)&buffer[i] = newva + (val - oldva);
337 if (verbose) 337 if (verbose)
338 std::cout << " " 338 std::cout << " "
339 << std::hex << std::showbase << std::setw(10) 339 << std::hex << std::showbase << std::setw(10)
340 << std::setfill('0') << std::internal 340 << std::setfill('0') << std::internal
341 << (imgbase + textsection.virtual_address + i) 341 << (imgbase + textsection.virtual_address + i)
342 << ": " 342 << ": "
343 << std::hex << std::showbase << std::setw(10) 343 << std::hex << std::showbase << std::setw(10)
344 << std::setfill('0') << std::internal 344 << std::setfill('0') << std::internal
345 << val 345 << val
346 << " -> " 346 << " -> "
347 << std::hex << std::showbase << std::setw(10) 347 << std::hex << std::showbase << std::setw(10)
348 << std::setfill('0') << std::internal 348 << std::setfill('0') << std::internal
349 << (newva + (val - oldva)) << std::endl; 349 << (newva + (val - oldva)) << std::endl;
350 } 350 }
351 } 351 }
352 352
353 // Write the relocated code section data. 353 // Write the relocated code section data.
354 if (!shared::write_file(updatername, buffer, false, textsection.raw_address, 354 if (!shared::write_file(updatername, buffer, false, textsection.raw_address,
355 buffer.size())) 355 buffer.size()))
356 { 356 {
357 std::cerr << "Failed to write the relocated code section to the" 357 std::cerr << "Failed to write the relocated code section to the"
358 " updater executable." << std::endl; 358 " updater executable." << std::endl;
359 return 17; 359 return 17;
360 } 360 }
361 } //if (size < buffer.size()) 361 } //if (size < buffer.size())
362 else 362 else
363 { 363 {
364 // Yes, overwrite the existing firmware archive. 364 // Yes, overwrite the existing firmware archive.
365 if (verbose) 365 if (verbose)
366 std::cout << "[*] Overwriting existing firmware archive..." 366 std::cout << "[*] Overwriting existing firmware archive..."
367 << std::endl; 367 << std::endl;
368 368
369 shared::bytes archive_size(sizeof(dword)); 369 shared::bytes archive_size(sizeof(dword));
370 *(dword*)&archive_size[0] = buffer.size(); 370 *(dword*)&archive_size[0] = buffer.size();
371 371
372 if (!shared::write_file(updatername, archive_size, false, offset_pa, 372 if (!shared::write_file(updatername, archive_size, false, offset_pa,
373 archive_size.size())) 373 archive_size.size()))
374 { 374 {
375 std::cerr << "Failed to write archive size to the updater" 375 std::cerr << "Failed to write archive size to the updater"
376 " executable." << std::endl; 376 " executable." << std::endl;
377 return 18; 377 return 18;
378 } 378 }
379 379
380 if (!shared::write_file(updatername, buffer, false, 380 if (!shared::write_file(updatername, buffer, false,
381 offset_pa+archive_size.size(), buffer.size())) 381 offset_pa+archive_size.size(), buffer.size()))
382 { 382 {
383 std::cerr << "Failed to write the new archive to the updater" 383 std::cerr << "Failed to write the new archive to the updater"
384 " exectuable." << std::endl; 384 " exectuable." << std::endl;
385 return 19; 385 return 19;
386 } 386 }
387 } 387 }
388 388
389 return 0; 389 return 0;
390} 390}
391 391
392int main(int argc, char* argv[]) 392int main(int argc, char* argv[])
393{ 393{
394 try 394 try
395 { 395 {
396 return process_arguments(argc, argv); 396 return process_arguments(argc, argv);
397 } 397 }
398 catch (const std::exception& xcpt) 398 catch (const std::exception& xcpt)
399 { 399 {
400 std::cerr << "Exception caught: " << xcpt.what() << std::endl; 400 std::cerr << "Exception caught: " << xcpt.what() << std::endl;
401 return -1; 401 return -1;
402 } 402 }
403 catch (...) 403 catch (...)
404 { 404 {
405 std::cerr << "Unknown exception caught." << std::endl; 405 std::cerr << "Unknown exception caught." << std::endl;
406 return -2; 406 return -2;
407 } 407 }
408 return -3; 408 return -3;
409} 409}
diff --git a/utils/zenutils/source/zen_crypt/CMakeLists.txt b/utils/zenutils/source/zen_crypt/CMakeLists.txt
index e88e8951a5..5721bbfa06 100755..100644
--- a/utils/zenutils/source/zen_crypt/CMakeLists.txt
+++ b/utils/zenutils/source/zen_crypt/CMakeLists.txt
@@ -1,4 +1,4 @@
1ADD_EXECUTABLE(zen_crypt main.cpp) 1ADD_EXECUTABLE(zen_crypt main.cpp)
2 2
3TARGET_LINK_LIBRARIES(zen_crypt shared) 3TARGET_LINK_LIBRARIES(zen_crypt shared)
4TARGET_LINK_LIBRARIES(zen_crypt beecrypt) 4TARGET_LINK_LIBRARIES(zen_crypt beecrypt)
diff --git a/utils/zenutils/source/zen_crypt/main.cpp b/utils/zenutils/source/zen_crypt/main.cpp
index 8301cbbea5..9944ba97f8 100755..100644
--- a/utils/zenutils/source/zen_crypt/main.cpp
+++ b/utils/zenutils/source/zen_crypt/main.cpp
@@ -1,687 +1,687 @@
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 <getpot/getpot.hpp> 20#include <getpot/getpot.hpp>
21#include <cenc.h> 21#include <cenc.h>
22#include <crypt.h> 22#include <crypt.h>
23#include <file.h> 23#include <file.h>
24#include <firmware.h> 24#include <firmware.h>
25#include <utils.h> 25#include <utils.h>
26 26
27 27
28namespace { 28namespace {
29enum command_t 29enum command_t
30{ 30{
31 cmd_none = 0, 31 cmd_none = 0,
32 cmd_sign, 32 cmd_sign,
33 cmd_verify, 33 cmd_verify,
34 cmd_encrypt, 34 cmd_encrypt,
35 cmd_decrypt 35 cmd_decrypt
36}; 36};
37 37
38enum mode_t 38enum mode_t
39{ 39{
40 mode_none = 0, 40 mode_none = 0,
41 mode_cenc, 41 mode_cenc,
42 mode_fresc, 42 mode_fresc,
43 mode_tl 43 mode_tl
44}; 44};
45 45
46struct player_info_t 46struct player_info_t
47{ 47{
48 const char* name; 48 const char* name;
49 const char* null_key; // HMAC-SHA1 key 49 const char* null_key; // HMAC-SHA1 key
50 const char* fresc_key; // BlowFish key 50 const char* fresc_key; // BlowFish key
51 const char* tl_key; // BlowFish key 51 const char* tl_key; // BlowFish key
52 bool big_endian; 52 bool big_endian;
53}; 53};
54}; //namespace 54}; //namespace
55 55
56 56
57static const char VERSION[] = "0.1"; 57static const char VERSION[] = "0.1";
58 58
59static const char null_key_v1[] = "CTL:N0MAD|PDE0.SIGN."; 59static const char null_key_v1[] = "CTL:N0MAD|PDE0.SIGN.";
60static const char null_key_v2[] = "CTL:N0MAD|PDE0.DPMP."; 60static const char null_key_v2[] = "CTL:N0MAD|PDE0.DPMP.";
61 61
62static const char fresc_key[] = "Copyright (C) CTL. -" 62static const char fresc_key[] = "Copyright (C) CTL. -"
63 " zN0MAD iz v~p0wderful!"; 63 " zN0MAD iz v~p0wderful!";
64 64
65static const char tl_zvm_key[] = "1sN0TM3D az u~may th1nk*" 65static const char tl_zvm_key[] = "1sN0TM3D az u~may th1nk*"
66 "Creative Zen Vision:M"; 66 "Creative Zen Vision:M";
67static const char tl_zvw_key[] = "1sN0TM3D az u~may th1nk*" 67static const char tl_zvw_key[] = "1sN0TM3D az u~may th1nk*"
68 "Creative ZEN Vision W"; 68 "Creative ZEN Vision W";
69static const char tl_zm_key[] = "1sN0TM3D az u~may th1nk*" 69static const char tl_zm_key[] = "1sN0TM3D az u~may th1nk*"
70 "Creative Zen Micro"; 70 "Creative Zen Micro";
71static const char tl_zmp_key[] = "1sN0TM3D az u~may th1nk*" 71static const char tl_zmp_key[] = "1sN0TM3D az u~may th1nk*"
72 "Creative Zen MicroPhoto"; 72 "Creative Zen MicroPhoto";
73static const char tl_zs_key[] = "1sN0TM3D az u~may th1nk*" 73static const char tl_zs_key[] = "1sN0TM3D az u~may th1nk*"
74 "Creative Zen Sleek"; 74 "Creative Zen Sleek";
75static const char tl_zsp_key[] = "1sN0TM3D az u~may th1nk*" 75static const char tl_zsp_key[] = "1sN0TM3D az u~may th1nk*"
76 "Creative Zen Sleek Photo"; 76 "Creative Zen Sleek Photo";
77static const char tl_zt_key[] = "1sN0TM3D az u~may th1nk*" 77static const char tl_zt_key[] = "1sN0TM3D az u~may th1nk*"
78 "Creative Zen Touch"; 78 "Creative Zen Touch";
79static const char tl_zx_key[] = "1sN0TM3D az u~may th1nk*" 79static const char tl_zx_key[] = "1sN0TM3D az u~may th1nk*"
80 "NOMAD Jukebox Zen Xtra"; 80 "NOMAD Jukebox Zen Xtra";
81 81
82player_info_t players[] = { 82player_info_t players[] = {
83 {"Vision:M", null_key_v2, fresc_key, tl_zvm_key, false}, 83 {"Vision:M", null_key_v2, fresc_key, tl_zvm_key, false},
84 {"Vision W", null_key_v2, fresc_key, tl_zvw_key, false}, 84 {"Vision W", null_key_v2, fresc_key, tl_zvw_key, false},
85 {"Micro", null_key_v1, fresc_key, tl_zm_key, true}, 85 {"Micro", null_key_v1, fresc_key, tl_zm_key, true},
86 {"MicroPhoto", null_key_v1, fresc_key, tl_zmp_key, true}, 86 {"MicroPhoto", null_key_v1, fresc_key, tl_zmp_key, true},
87 {"Sleek", null_key_v1, fresc_key, tl_zs_key, true}, 87 {"Sleek", null_key_v1, fresc_key, tl_zs_key, true},
88 {"SleekPhoto", null_key_v1, fresc_key, tl_zsp_key, true}, 88 {"SleekPhoto", null_key_v1, fresc_key, tl_zsp_key, true},
89 {"Touch", null_key_v1, fresc_key, tl_zt_key, true}, 89 {"Touch", null_key_v1, fresc_key, tl_zt_key, true},
90 {"Xtra", null_key_v1, fresc_key, tl_zx_key, true}, 90 {"Xtra", null_key_v1, fresc_key, tl_zx_key, true},
91 {NULL, NULL, NULL, NULL, false} 91 {NULL, NULL, NULL, NULL, false}
92}; 92};
93 93
94 94
95player_info_t* find_player_info(std::string player) 95player_info_t* find_player_info(std::string player)
96{ 96{
97 for (int i = 0; players[i].name != NULL; i++) 97 for (int i = 0; players[i].name != NULL; i++)
98 { 98 {
99 if (!stricmp(players[i].name, player.c_str())) 99 if (!stricmp(players[i].name, player.c_str()))
100 { 100 {
101 return &players[i]; 101 return &players[i];
102 } 102 }
103 } 103 }
104 return NULL; 104 return NULL;
105} 105}
106 106
107void print_version() 107void print_version()
108{ 108{
109 std::cout 109 std::cout
110 << "zen_crypt - A utility for encrypting, decrypting or signing" 110 << "zen_crypt - A utility for encrypting, decrypting or signing"
111 " Creative firmwares." << std::endl 111 " Creative firmwares." << std::endl
112 << "Version " << VERSION << std::endl 112 << "Version " << VERSION << std::endl
113 << "Copyright (c) 2007 Rasmus Ry" << std::endl; 113 << "Copyright (c) 2007 Rasmus Ry" << std::endl;
114} 114}
115 115
116void print_help() 116void print_help()
117{ 117{
118 print_version(); 118 print_version();
119 std::cout << std::endl 119 std::cout << std::endl
120 << "Usage: zen_crypt [command] [options]" << std::endl 120 << "Usage: zen_crypt [command] [options]" << std::endl
121 << std::endl 121 << std::endl
122 << " Commands:" << std::endl 122 << " Commands:" << std::endl
123 << " -h,--help" << std::endl 123 << " -h,--help" << std::endl
124 << " prints this message." << std::endl 124 << " prints this message." << std::endl
125 << " -s,--sign" << std::endl 125 << " -s,--sign" << std::endl
126 << " signs a given input file." << std::endl 126 << " signs a given input file." << std::endl
127 << " -v,--verify" << std::endl 127 << " -v,--verify" << std::endl
128 << " verifies a signed input file." << std::endl 128 << " verifies a signed input file." << std::endl
129 << " -e,--encrypt" << std::endl 129 << " -e,--encrypt" << std::endl
130 << " encrypts a given input file." << std::endl 130 << " encrypts a given input file." << std::endl
131 << " -d,--decrypt" << std::endl 131 << " -d,--decrypt" << std::endl
132 << " decrypts a given input file." << std::endl 132 << " decrypts a given input file." << std::endl
133 << std::endl 133 << std::endl
134 << " Options:" << std::endl 134 << " Options:" << std::endl
135 << " -V,--verbose" << std::endl 135 << " -V,--verbose" << std::endl
136 << " prints verbose messages." << std::endl 136 << " prints verbose messages." << std::endl
137 << " -b,--big-endian" << std::endl 137 << " -b,--big-endian" << std::endl
138 << " specifies that the input is big-endian, default is" 138 << " specifies that the input is big-endian, default is"
139 " little-endian." << std::endl 139 " little-endian." << std::endl
140 << " -i,--input [file]" << std::endl 140 << " -i,--input [file]" << std::endl
141 << " specifies the input file." << std::endl 141 << " specifies the input file." << std::endl
142 << " -o,--output [file]" << std::endl 142 << " -o,--output [file]" << std::endl
143 << " specifies the output file." << std::endl 143 << " specifies the output file." << std::endl
144 << " -m,--mode [CENC|FRESC|TL]" << std::endl 144 << " -m,--mode [CENC|FRESC|TL]" << std::endl
145 << " specifies which algorithm to use." << std::endl 145 << " specifies which algorithm to use." << std::endl
146 << " -k,--key [player|key]" << std::endl 146 << " -k,--key [player|key]" << std::endl
147 << " specifies which key to use." << std::endl 147 << " specifies which key to use." << std::endl
148 << std::endl 148 << std::endl
149 ; 149 ;
150 std::cout << " Players:" << std::endl; 150 std::cout << " Players:" << std::endl;
151 for (int i = 0; players[i].name != NULL; i++) 151 for (int i = 0; players[i].name != NULL; i++)
152 { 152 {
153 std::cout << " " << players[i].name; 153 std::cout << " " << players[i].name;
154 if (!i) 154 if (!i)
155 std::cout << " (default)"; 155 std::cout << " (default)";
156 std::cout << std::endl; 156 std::cout << std::endl;
157 } 157 }
158} 158}
159 159
160size_t find_null_signature(shared::bytes& data) 160size_t find_null_signature(shared::bytes& data)
161{ 161{
162 size_t index = data.size(); 162 size_t index = data.size();
163 if (index < (20 + 8 + 7)) 163 if (index < (20 + 8 + 7))
164 return 0; 164 return 0;
165 index -= 20 + 8; 165 index -= 20 + 8;
166 for (int i = 0; i < 7; i++) 166 for (int i = 0; i < 7; i++)
167 { 167 {
168 if (*(dword*)&data[index-i] == 'NULL' || 168 if (*(dword*)&data[index-i] == 'NULL' ||
169 *(dword*)&data[index-i] == 'LLUN') 169 *(dword*)&data[index-i] == 'LLUN')
170 { 170 {
171 return index-i; 171 return index-i;
172 } 172 }
173 } 173 }
174 return 0; 174 return 0;
175} 175}
176 176
177 177
178bool sign(shared::bytes& data, player_info_t* pi, const std::string& file, 178bool sign(shared::bytes& data, player_info_t* pi, const std::string& file,
179 bool verbose) 179 bool verbose)
180{ 180{
181 if (verbose) 181 if (verbose)
182 std::cout << "[*] Checking for the presence of an existing" 182 std::cout << "[*] Checking for the presence of an existing"
183 " NULL signature..." << std::endl; 183 " NULL signature..." << std::endl;
184 size_t index = find_null_signature(data); 184 size_t index = find_null_signature(data);
185 if (index) 185 if (index)
186 { 186 {
187 if (verbose) 187 if (verbose)
188 std::cout << "[*] Found NULL signature at: " 188 std::cout << "[*] Found NULL signature at: "
189 << std::hex << index << std::endl; 189 << std::hex << index << std::endl;
190 190
191 if (verbose) 191 if (verbose)
192 std::cout << "[*] Computing digest..." << std::endl; 192 std::cout << "[*] Computing digest..." << std::endl;
193 193
194 shared::bytes digest(20); 194 shared::bytes digest(20);
195 if (!zen::hmac_sha1_calc((const byte*)pi->null_key, 195 if (!zen::hmac_sha1_calc((const byte*)pi->null_key,
196 strlen(pi->null_key)+1, &data[0], index, 196 strlen(pi->null_key)+1, &data[0], index,
197 &digest[0], NULL)) 197 &digest[0], NULL))
198 { 198 {
199 std::cerr << "Failed to compute digest." << std::endl; 199 std::cerr << "Failed to compute digest." << std::endl;
200 return false; 200 return false;
201 } 201 }
202 202
203 if (verbose) 203 if (verbose)
204 std::cout << "[*] Writing file data..." << std::endl; 204 std::cout << "[*] Writing file data..." << std::endl;
205 205
206 if (!shared::write_file(file, data, true)) 206 if (!shared::write_file(file, data, true))
207 { 207 {
208 std::cerr << "Failed to write file data." << std::endl; 208 std::cerr << "Failed to write file data." << std::endl;
209 return false; 209 return false;
210 } 210 }
211 211
212 if (verbose) 212 if (verbose)
213 std::cout << "[*] Writing digest data..." << std::endl; 213 std::cout << "[*] Writing digest data..." << std::endl;
214 214
215 if (!shared::write_file(file, digest, false, index+8)) 215 if (!shared::write_file(file, digest, false, index+8))
216 { 216 {
217 std::cerr << "Failed to write digest data." << std::endl; 217 std::cerr << "Failed to write digest data." << std::endl;
218 return false; 218 return false;
219 } 219 }
220 } 220 }
221 else 221 else
222 { 222 {
223 if (verbose) 223 if (verbose)
224 std::cout << "[*] Computing digest..." << std::endl; 224 std::cout << "[*] Computing digest..." << std::endl;
225 225
226 shared::bytes signature(20+8); 226 shared::bytes signature(20+8);
227 if (!zen::hmac_sha1_calc((const byte*)pi->null_key, 227 if (!zen::hmac_sha1_calc((const byte*)pi->null_key,
228 strlen(pi->null_key)+1, &data[0], data.size(), 228 strlen(pi->null_key)+1, &data[0], data.size(),
229 &signature[8], NULL)) 229 &signature[8], NULL))
230 { 230 {
231 std::cerr << "Failed to compute digest." << std::endl; 231 std::cerr << "Failed to compute digest." << std::endl;
232 return false; 232 return false;
233 } 233 }
234 234
235 235
236 zen::firmware_header_t header = {'NULL', 20}; 236 zen::firmware_header_t header = {'NULL', 20};
237 if (pi->big_endian) 237 if (pi->big_endian)
238 { 238 {
239 header.tag = shared::swap(header.tag); 239 header.tag = shared::swap(header.tag);
240 header.size = shared::swap(header.size); 240 header.size = shared::swap(header.size);
241 } 241 }
242 memcpy(&signature[0], &header, sizeof(zen::firmware_header_t)); 242 memcpy(&signature[0], &header, sizeof(zen::firmware_header_t));
243 243
244 if (verbose) 244 if (verbose)
245 std::cout << "[*] Writing file data..." << std::endl; 245 std::cout << "[*] Writing file data..." << std::endl;
246 246
247 if (!shared::write_file(file, data, true)) 247 if (!shared::write_file(file, data, true))
248 { 248 {
249 std::cerr << "Failed to write file data." << std::endl; 249 std::cerr << "Failed to write file data." << std::endl;
250 return false; 250 return false;
251 } 251 }
252 252
253 if (verbose) 253 if (verbose)
254 std::cout << "[*] Writing signature data..." << std::endl; 254 std::cout << "[*] Writing signature data..." << std::endl;
255 255
256 if (!shared::write_file(file, signature, false, data.size())) 256 if (!shared::write_file(file, signature, false, data.size()))
257 { 257 {
258 std::cerr << "Failed to write signature data." << std::endl; 258 std::cerr << "Failed to write signature data." << std::endl;
259 return false; 259 return false;
260 } 260 }
261 261
262 if (verbose) 262 if (verbose)
263 std::cout << "[*] Ensuring that the file length is" 263 std::cout << "[*] Ensuring that the file length is"
264 " 32-bit aligned..." << std::endl; 264 " 32-bit aligned..." << std::endl;
265 265
266 int length = data.size() + signature.size(); 266 int length = data.size() + signature.size();
267 int align = length % 4; 267 int align = length % 4;
268 if (align) 268 if (align)
269 { 269 {
270 shared::bytes padding(4 - align, 0); 270 shared::bytes padding(4 - align, 0);
271 if (!shared::write_file(file, padding, false, length)) 271 if (!shared::write_file(file, padding, false, length))
272 { 272 {
273 std::cerr << "Failed to write padding data." << std::endl; 273 std::cerr << "Failed to write padding data." << std::endl;
274 return false; 274 return false;
275 } 275 }
276 } 276 }
277 } 277 }
278 278
279 return true; 279 return true;
280} 280}
281 281
282bool verify(shared::bytes& data, player_info_t* pi, bool verbose) 282bool verify(shared::bytes& data, player_info_t* pi, bool verbose)
283{ 283{
284 if (verbose) 284 if (verbose)
285 std::cout << "[*] Checking for the presence of an existing" 285 std::cout << "[*] Checking for the presence of an existing"
286 " NULL signature..." << std::endl; 286 " NULL signature..." << std::endl;
287 size_t index = find_null_signature(data); 287 size_t index = find_null_signature(data);
288 if (!index) 288 if (!index)
289 { 289 {
290 std::cerr << "No NULL signature present in the input file." 290 std::cerr << "No NULL signature present in the input file."
291 << std::endl; 291 << std::endl;
292 return false; 292 return false;
293 } 293 }
294 if (verbose) 294 if (verbose)
295 std::cout << "[*] Found NULL signature at: " 295 std::cout << "[*] Found NULL signature at: "
296 << std::hex << index << std::endl; 296 << std::hex << index << std::endl;
297 297
298 if (verbose) 298 if (verbose)
299 std::cout << "[*] Computing digest..." << std::endl; 299 std::cout << "[*] Computing digest..." << std::endl;
300 300
301 byte digest[20]; 301 byte digest[20];
302 if (!zen::hmac_sha1_calc((const byte*)pi->null_key, strlen(pi->null_key)+1, 302 if (!zen::hmac_sha1_calc((const byte*)pi->null_key, strlen(pi->null_key)+1,
303 &data[0], index, digest, NULL)) 303 &data[0], index, digest, NULL))
304 { 304 {
305 std::cerr << "Failed to compute digest." << std::endl; 305 std::cerr << "Failed to compute digest." << std::endl;
306 return false; 306 return false;
307 } 307 }
308 308
309 if (verbose) 309 if (verbose)
310 std::cout << "[*] Verifying NULL signature digest..." << std::endl; 310 std::cout << "[*] Verifying NULL signature digest..." << std::endl;
311 311
312 if (memcmp(&digest[0], &data[index+8], 20)) 312 if (memcmp(&digest[0], &data[index+8], 20))
313 { 313 {
314 std::cerr << "The NULL signature contains an incorrect digest." 314 std::cerr << "The NULL signature contains an incorrect digest."
315 << std::endl; 315 << std::endl;
316 return false; 316 return false;
317 } 317 }
318 318
319 return true; 319 return true;
320} 320}
321 321
322bool encrypt(shared::bytes& data, int mode, player_info_t* pi, 322bool encrypt(shared::bytes& data, int mode, player_info_t* pi,
323 const std::string& file, bool verbose) 323 const std::string& file, bool verbose)
324{ 324{
325 if (mode == mode_cenc) 325 if (mode == mode_cenc)
326 { 326 {
327 if (verbose) 327 if (verbose)
328 std::cout << "[*] Encoding input file..." << std::endl; 328 std::cout << "[*] Encoding input file..." << std::endl;
329 329
330 shared::bytes outbuf(data.size() * 2); 330 shared::bytes outbuf(data.size() * 2);
331 int len = zen::cenc_encode(&data[0], data.size(), &outbuf[0], outbuf.size()); 331 int len = zen::cenc_encode(&data[0], data.size(), &outbuf[0], outbuf.size());
332 if (!len) 332 if (!len)
333 { 333 {
334 std::cerr << "Failed to encode the input file." << std::endl; 334 std::cerr << "Failed to encode the input file." << std::endl;
335 return false; 335 return false;
336 } 336 }
337 337
338 if (verbose) 338 if (verbose)
339 std::cout << "[*] Writing decoded length to file..." << std::endl; 339 std::cout << "[*] Writing decoded length to file..." << std::endl;
340 340
341 shared::bytes length(sizeof(dword)); 341 shared::bytes length(sizeof(dword));
342 *(dword*)&length[0] = pi->big_endian ? shared::swap(data.size()) : data.size(); 342 *(dword*)&length[0] = pi->big_endian ? shared::swap(data.size()) : data.size();
343 if (!shared::write_file(file, length, true)) 343 if (!shared::write_file(file, length, true))
344 { 344 {
345 std::cerr << "Failed to write the file data." << std::endl; 345 std::cerr << "Failed to write the file data." << std::endl;
346 return false; 346 return false;
347 } 347 }
348 348
349 if (verbose) 349 if (verbose)
350 std::cout << "[*] Writing file data..." << std::endl; 350 std::cout << "[*] Writing file data..." << std::endl;
351 351
352 if (!shared::write_file(file, outbuf, sizeof(dword), len)) 352 if (!shared::write_file(file, outbuf, sizeof(dword), len))
353 { 353 {
354 std::cerr << "Failed to write the file data." << std::endl; 354 std::cerr << "Failed to write the file data." << std::endl;
355 return false; 355 return false;
356 } 356 }
357 } 357 }
358 else if (mode == mode_fresc) 358 else if (mode == mode_fresc)
359 { 359 {
360 std::cerr << "FRESC mode is not supported." << std::endl; 360 std::cerr << "FRESC mode is not supported." << std::endl;
361 return false; 361 return false;
362 } 362 }
363 else if (mode == mode_tl) 363 else if (mode == mode_tl)
364 { 364 {
365 if (verbose) 365 if (verbose)
366 std::cout << "[*] Encoding input file..." << std::endl; 366 std::cout << "[*] Encoding input file..." << std::endl;
367 367
368 shared::bytes outbuf(data.size() * 2); 368 shared::bytes outbuf(data.size() * 2);
369 *(dword*)&outbuf[0] = pi->big_endian ? shared::swap(data.size()) : data.size(); 369 *(dword*)&outbuf[0] = pi->big_endian ? shared::swap(data.size()) : data.size();
370 int len = zen::cenc_encode(&data[0], data.size(), 370 int len = zen::cenc_encode(&data[0], data.size(),
371 &outbuf[sizeof(dword)], 371 &outbuf[sizeof(dword)],
372 outbuf.size()-sizeof(dword)); 372 outbuf.size()-sizeof(dword));
373 if (!len) 373 if (!len)
374 { 374 {
375 std::cerr << "Failed to encode the input file." << std::endl; 375 std::cerr << "Failed to encode the input file." << std::endl;
376 return false; 376 return false;
377 } 377 }
378 len += sizeof(dword); 378 len += sizeof(dword);
379 379
380 int align = len % 8; 380 int align = len % 8;
381 align = align ? (8 - align) : 0; 381 align = align ? (8 - align) : 0;
382 len += align; 382 len += align;
383 383
384 if (verbose) 384 if (verbose)
385 std::cout << "[*] Encrypting encoded data..." << std::endl; 385 std::cout << "[*] Encrypting encoded data..." << std::endl;
386 386
387 dword iv[2] = {0, shared::swap(len)}; 387 dword iv[2] = {0, shared::swap(len)};
388 if (!zen::bf_cbc_encrypt((const byte*)pi->tl_key, strlen(pi->tl_key)+1, 388 if (!zen::bf_cbc_encrypt((const byte*)pi->tl_key, strlen(pi->tl_key)+1,
389 &outbuf[0], len, (const byte*)iv)) 389 &outbuf[0], len, (const byte*)iv))
390 { 390 {
391 std::cerr << "Failed to decrypt the input file." << std::endl; 391 std::cerr << "Failed to decrypt the input file." << std::endl;
392 return false; 392 return false;
393 } 393 }
394 394
395 if (verbose) 395 if (verbose)
396 std::cout << "[*] Writing file data..." << std::endl; 396 std::cout << "[*] Writing file data..." << std::endl;
397 397
398 if (!shared::write_file(file, outbuf, true, 0, len)) 398 if (!shared::write_file(file, outbuf, true, 0, len))
399 { 399 {
400 std::cerr << "Failed to save the output file." << std::endl; 400 std::cerr << "Failed to save the output file." << std::endl;
401 return false; 401 return false;
402 } 402 }
403 } 403 }
404 else 404 else
405 { 405 {
406 std::cerr << "Invalid mode specified." << std::endl; 406 std::cerr << "Invalid mode specified." << std::endl;
407 return false; 407 return false;
408 } 408 }
409 409
410 return true; 410 return true;
411} 411}
412 412
413bool decrypt(shared::bytes& data, int mode, player_info_t* pi, 413bool decrypt(shared::bytes& data, int mode, player_info_t* pi,
414 const std::string& file, bool verbose) 414 const std::string& file, bool verbose)
415{ 415{
416 if (mode == mode_cenc) 416 if (mode == mode_cenc)
417 { 417 {
418 dword length = *(dword*)&data[0]; 418 dword length = *(dword*)&data[0];
419 length = pi->big_endian ? shared::swap(length) : length; 419 length = pi->big_endian ? shared::swap(length) : length;
420 420
421 if (verbose) 421 if (verbose)
422 std::cout << "[*] Decoding input file..." << std::endl; 422 std::cout << "[*] Decoding input file..." << std::endl;
423 423
424 shared::bytes outbuf(length); 424 shared::bytes outbuf(length);
425 if (!zen::cenc_decode(&data[sizeof(dword)], data.size()-sizeof(dword), 425 if (!zen::cenc_decode(&data[sizeof(dword)], data.size()-sizeof(dword),
426 &outbuf[0], length)) 426 &outbuf[0], length))
427 { 427 {
428 std::cerr << "Failed to decode the input file." << std::endl; 428 std::cerr << "Failed to decode the input file." << std::endl;
429 return false; 429 return false;
430 } 430 }
431 431
432 if (verbose) 432 if (verbose)
433 std::cout << "[*] Writing file data..." << std::endl; 433 std::cout << "[*] Writing file data..." << std::endl;
434 434
435 if (!shared::write_file(file, outbuf, true)) 435 if (!shared::write_file(file, outbuf, true))
436 { 436 {
437 std::cerr << "Failed to write the file data." << std::endl; 437 std::cerr << "Failed to write the file data." << std::endl;
438 return false; 438 return false;
439 } 439 }
440 } 440 }
441 else if (mode == mode_fresc) 441 else if (mode == mode_fresc)
442 { 442 {
443 if (verbose) 443 if (verbose)
444 std::cout << "[*] Decrypting input file..." << std::endl; 444 std::cout << "[*] Decrypting input file..." << std::endl;
445 445
446 dword iv[2] = {shared::swap(data.size()), 0}; 446 dword iv[2] = {shared::swap(data.size()), 0};
447 if (!zen::bf_cbc_decrypt((const byte*)pi->fresc_key, 447 if (!zen::bf_cbc_decrypt((const byte*)pi->fresc_key,
448 strlen(pi->fresc_key)+1, &data[0], 448 strlen(pi->fresc_key)+1, &data[0],
449 data.size(), (const byte*)iv)) 449 data.size(), (const byte*)iv))
450 { 450 {
451 std::cerr << "Failed to decrypt the input file." << std::endl; 451 std::cerr << "Failed to decrypt the input file." << std::endl;
452 return false; 452 return false;
453 } 453 }
454 454
455 if (verbose) 455 if (verbose)
456 std::cout << "[*] Writing file data..." << std::endl; 456 std::cout << "[*] Writing file data..." << std::endl;
457 457
458 if (!shared::write_file(file, data, true)) 458 if (!shared::write_file(file, data, true))
459 { 459 {
460 std::cerr << "Failed to save the output file." << std::endl; 460 std::cerr << "Failed to save the output file." << std::endl;
461 return false; 461 return false;
462 } 462 }
463 } 463 }
464 else if (mode == mode_tl) 464 else if (mode == mode_tl)
465 { 465 {
466 if (verbose) 466 if (verbose)
467 std::cout << "[*] Decrypting input file..." << std::endl; 467 std::cout << "[*] Decrypting input file..." << std::endl;
468 468
469 dword iv[2] = {0, shared::swap(data.size())}; 469 dword iv[2] = {0, shared::swap(data.size())};
470 if (!zen::bf_cbc_decrypt((const byte*)pi->tl_key, strlen(pi->tl_key)+1, 470 if (!zen::bf_cbc_decrypt((const byte*)pi->tl_key, strlen(pi->tl_key)+1,
471 &data[0], data.size(), (const byte*)iv)) 471 &data[0], data.size(), (const byte*)iv))
472 { 472 {
473 std::cerr << "Failed to decrypt the input file." << std::endl; 473 std::cerr << "Failed to decrypt the input file." << std::endl;
474 return false; 474 return false;
475 } 475 }
476 476
477 dword length = *(dword*)&data[0]; 477 dword length = *(dword*)&data[0];
478 length = pi->big_endian ? shared::swap(length) : length; 478 length = pi->big_endian ? shared::swap(length) : length;
479 if (length > (data.size() * 3)) 479 if (length > (data.size() * 3))
480 { 480 {
481 std::cerr << "Decrypted length is unexpectedly large: " 481 std::cerr << "Decrypted length is unexpectedly large: "
482 << std::hex << length 482 << std::hex << length
483 << " Check the endian and key settings." << std::endl; 483 << " Check the endian and key settings." << std::endl;
484 return false; 484 return false;
485 } 485 }
486 486
487 if (verbose) 487 if (verbose)
488 std::cout << "[*] Decoding decrypted data..." << std::endl; 488 std::cout << "[*] Decoding decrypted data..." << std::endl;
489 489
490 shared::bytes outbuf(length); 490 shared::bytes outbuf(length);
491 if (!zen::cenc_decode(&data[sizeof(dword)], data.size()-sizeof(dword), 491 if (!zen::cenc_decode(&data[sizeof(dword)], data.size()-sizeof(dword),
492 &outbuf[0], length)) 492 &outbuf[0], length))
493 { 493 {
494 std::cerr << "Failed to decode the input file." << std::endl; 494 std::cerr << "Failed to decode the input file." << std::endl;
495 return false; 495 return false;
496 } 496 }
497 497
498 if (verbose) 498 if (verbose)
499 std::cout << "[*] Writing file data..." << std::endl; 499 std::cout << "[*] Writing file data..." << std::endl;
500 500
501 if (!shared::write_file(file, outbuf, true)) 501 if (!shared::write_file(file, outbuf, true))
502 { 502 {
503 std::cerr << "Failed to save the output file." << std::endl; 503 std::cerr << "Failed to save the output file." << std::endl;
504 return false; 504 return false;
505 } 505 }
506 } 506 }
507 else 507 else
508 { 508 {
509 std::cerr << "Invalid mode specified." << std::endl; 509 std::cerr << "Invalid mode specified." << std::endl;
510 return false; 510 return false;
511 } 511 }
512 512
513 return true; 513 return true;
514} 514}
515 515
516int process_arguments(int argc, char*argv[]) 516int process_arguments(int argc, char*argv[])
517{ 517{
518 //-------------------------------------------------------------------- 518 //--------------------------------------------------------------------
519 // Parse input variables. 519 // Parse input variables.
520 //-------------------------------------------------------------------- 520 //--------------------------------------------------------------------
521 521
522 GetPot cl(argc, argv); 522 GetPot cl(argc, argv);
523 if (cl.size() == 1 || cl.search(2, "-h", "--help")) 523 if (cl.size() == 1 || cl.search(2, "-h", "--help"))
524 { 524 {
525 print_help(); 525 print_help();
526 return 1; 526 return 1;
527 } 527 }
528 528
529 int command = cmd_none; 529 int command = cmd_none;
530 if (cl.search(2, "-s", "--sign")) 530 if (cl.search(2, "-s", "--sign"))
531 command = cmd_sign; 531 command = cmd_sign;
532 else if (cl.search(2, "-v", "--verify")) 532 else if (cl.search(2, "-v", "--verify"))
533 command = cmd_verify; 533 command = cmd_verify;
534 else if (cl.search(2, "-e", "--encrypt")) 534 else if (cl.search(2, "-e", "--encrypt"))
535 command = cmd_encrypt; 535 command = cmd_encrypt;
536 else if (cl.search(2, "-d", "--decrypt")) 536 else if (cl.search(2, "-d", "--decrypt"))
537 command = cmd_decrypt; 537 command = cmd_decrypt;
538 538
539 if (command == cmd_none) 539 if (command == cmd_none)
540 { 540 {
541 std::cerr << "No command specified." << std::endl; 541 std::cerr << "No command specified." << std::endl;
542 return 2; 542 return 2;
543 } 543 }
544 544
545 int mode = mode_none; 545 int mode = mode_none;
546 if (command == cmd_encrypt || command == cmd_decrypt) 546 if (command == cmd_encrypt || command == cmd_decrypt)
547 { 547 {
548 if (!cl.search(2, "-m", "--mode")) 548 if (!cl.search(2, "-m", "--mode"))
549 { 549 {
550 std::cerr << "The specified command requires that" 550 std::cerr << "The specified command requires that"
551 " a mode is specified." 551 " a mode is specified."
552 << std::endl; 552 << std::endl;
553 return 3; 553 return 3;
554 } 554 }
555 std::string name = cl.next(""); 555 std::string name = cl.next("");
556 if (!name.empty()) 556 if (!name.empty())
557 { 557 {
558 if (!stricmp(name.c_str(), "CENC")) 558 if (!stricmp(name.c_str(), "CENC"))
559 mode = mode_cenc; 559 mode = mode_cenc;
560 else if (!stricmp(name.c_str(), "FRESC")) 560 else if (!stricmp(name.c_str(), "FRESC"))
561 mode = mode_fresc; 561 mode = mode_fresc;
562 else if (!stricmp(name.c_str(), "TL")) 562 else if (!stricmp(name.c_str(), "TL"))
563 mode = mode_tl; 563 mode = mode_tl;
564 } 564 }
565 if (mode == mode_none) 565 if (mode == mode_none)
566 { 566 {
567 std::cerr << "Invalid mode specified." << std::endl; 567 std::cerr << "Invalid mode specified." << std::endl;
568 return 4; 568 return 4;
569 } 569 }
570 } 570 }
571 571
572 bool verbose = false; 572 bool verbose = false;
573 if (cl.search(2, "-V", "--verbose")) 573 if (cl.search(2, "-V", "--verbose"))
574 verbose = true; 574 verbose = true;
575 575
576 bool big_endian = false; 576 bool big_endian = false;
577 if (cl.search(2, "-b", "--big-endian")) 577 if (cl.search(2, "-b", "--big-endian"))
578 big_endian = true; 578 big_endian = true;
579 579
580 std::string infile; 580 std::string infile;
581 if (cl.search(2, "-i", "--input")) 581 if (cl.search(2, "-i", "--input"))
582 infile = cl.next(""); 582 infile = cl.next("");
583 if (infile.empty()) 583 if (infile.empty())
584 { 584 {
585 std::cerr << "An input file must be specified." << std::endl; 585 std::cerr << "An input file must be specified." << std::endl;
586 return 5; 586 return 5;
587 } 587 }
588 588
589 std::string outfile = infile; 589 std::string outfile = infile;
590 if (cl.search(2, "-o", "--output")) 590 if (cl.search(2, "-o", "--output"))
591 outfile = cl.next(outfile.c_str()); 591 outfile = cl.next(outfile.c_str());
592 592
593 player_info_t* pi = &players[0]; 593 player_info_t* pi = &players[0];
594 std::string key; 594 std::string key;
595 if (cl.search(2, "-k", "--key")) 595 if (cl.search(2, "-k", "--key"))
596 key = cl.next(""); 596 key = cl.next("");
597 if (!key.empty()) 597 if (!key.empty())
598 { 598 {
599 player_info_t* pitmp = find_player_info(key); 599 player_info_t* pitmp = find_player_info(key);
600 if (pitmp != NULL) 600 if (pitmp != NULL)
601 pi = pitmp; 601 pi = pitmp;
602 else 602 else
603 { 603 {
604 static player_info_t player = { 604 static player_info_t player = {
605 NULL, key.c_str(), key.c_str(), key.c_str(), false 605 NULL, key.c_str(), key.c_str(), key.c_str(), false
606 }; 606 };
607 pi = &player; 607 pi = &player;
608 } 608 }
609 } 609 }
610 if (big_endian) 610 if (big_endian)
611 pi->big_endian = big_endian; 611 pi->big_endian = big_endian;
612 612
613 613
614 //-------------------------------------------------------------------- 614 //--------------------------------------------------------------------
615 // Read the input file. 615 // Read the input file.
616 //-------------------------------------------------------------------- 616 //--------------------------------------------------------------------
617 617
618 if (verbose) 618 if (verbose)
619 std::cout << "[*] Reading input file..." << std::endl; 619 std::cout << "[*] Reading input file..." << std::endl;
620 620
621 shared::bytes buffer; 621 shared::bytes buffer;
622 if (!shared::read_file(infile, buffer)) 622 if (!shared::read_file(infile, buffer))
623 { 623 {
624 std::cerr << "Failed to read the input file." << std::endl; 624 std::cerr << "Failed to read the input file." << std::endl;
625 return 6; 625 return 6;
626 } 626 }
627 627
628 628
629 //-------------------------------------------------------------------- 629 //--------------------------------------------------------------------
630 // Process the input file. 630 // Process the input file.
631 //-------------------------------------------------------------------- 631 //--------------------------------------------------------------------
632 632
633 switch (command) 633 switch (command)
634 { 634 {
635 case cmd_sign: 635 case cmd_sign:
636 if (verbose) 636 if (verbose)
637 std::cout << "[*] Signing input file..." << std::endl; 637 std::cout << "[*] Signing input file..." << std::endl;
638 if (!sign(buffer, pi, outfile, verbose)) 638 if (!sign(buffer, pi, outfile, verbose))
639 return 7; 639 return 7;
640 std::cout << "Successfully signed the input file." << std::endl; 640 std::cout << "Successfully signed the input file." << std::endl;
641 break; 641 break;
642 case cmd_verify: 642 case cmd_verify:
643 if (verbose) 643 if (verbose)
644 std::cout << "[*] Verifying signature on input file..." 644 std::cout << "[*] Verifying signature on input file..."
645 << std::endl; 645 << std::endl;
646 if (!verify(buffer, pi, verbose)) 646 if (!verify(buffer, pi, verbose))
647 return 8; 647 return 8;
648 std::cout << "Successfully verified the input file signature." 648 std::cout << "Successfully verified the input file signature."
649 << std::endl; 649 << std::endl;
650 break; 650 break;
651 case cmd_encrypt: 651 case cmd_encrypt:
652 if (verbose) 652 if (verbose)
653 std::cout << "[*] Encrypting input file..." << std::endl; 653 std::cout << "[*] Encrypting input file..." << std::endl;
654 if (!encrypt(buffer, mode, pi, outfile, verbose)) 654 if (!encrypt(buffer, mode, pi, outfile, verbose))
655 return 9; 655 return 9;
656 std::cout << "Successfully encrypted the input file." << std::endl; 656 std::cout << "Successfully encrypted the input file." << std::endl;
657 break; 657 break;
658 case cmd_decrypt: 658 case cmd_decrypt:
659 if (verbose) 659 if (verbose)
660 std::cout << "[*] Decrypting input file..." << std::endl; 660 std::cout << "[*] Decrypting input file..." << std::endl;
661 if (!decrypt(buffer, mode, pi, outfile, verbose)) 661 if (!decrypt(buffer, mode, pi, outfile, verbose))
662 return 10; 662 return 10;
663 std::cout << "Successfully decrypted the input file." << std::endl; 663 std::cout << "Successfully decrypted the input file." << std::endl;
664 break; 664 break;
665 }; 665 };
666 666
667 return 0; 667 return 0;
668} 668}
669 669
670int main(int argc, char* argv[]) 670int main(int argc, char* argv[])
671{ 671{
672 try 672 try
673 { 673 {
674 return process_arguments(argc, argv); 674 return process_arguments(argc, argv);
675 } 675 }
676 catch (const std::exception& xcpt) 676 catch (const std::exception& xcpt)
677 { 677 {
678 std::cerr << "Exception caught: " << xcpt.what() << std::endl; 678 std::cerr << "Exception caught: " << xcpt.what() << std::endl;
679 return -1; 679 return -1;
680 } 680 }
681 catch (...) 681 catch (...)
682 { 682 {
683 std::cerr << "Unknown exception caught." << std::endl; 683 std::cerr << "Unknown exception caught." << std::endl;
684 return -2; 684 return -2;
685 } 685 }
686 return -3; 686 return -3;
687} 687}