From ca5bb76d2b8f65aa97e50b633f828c1deb241526 Mon Sep 17 00:00:00 2001 From: Nicolas Pennequin Date: Fri, 11 Jul 2008 16:51:25 +0000 Subject: Delete the svn:executable property and set svn:eol-style to native for all those text files. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18012 a1c6a512-1295-4272-9138-f99709370657 --- utils/zenutils/source/CMakeLists.txt | 12 +- .../source/firmware_extract/CMakeLists.txt | 6 +- utils/zenutils/source/firmware_extract/main.cpp | 486 +++---- utils/zenutils/source/firmware_make/CMakeLists.txt | 6 +- utils/zenutils/source/firmware_make/main.cpp | 522 ++++---- utils/zenutils/source/shared/CMakeLists.txt | 32 +- utils/zenutils/source/shared/cenc.cpp | 666 +++++----- utils/zenutils/source/shared/cenc.h | 58 +- utils/zenutils/source/shared/crypt.cpp | 182 +-- utils/zenutils/source/shared/crypt.h | 60 +- utils/zenutils/source/shared/file.cpp | 212 +-- utils/zenutils/source/shared/file.h | 72 +- utils/zenutils/source/shared/firmware.cpp | 774 +++++------ utils/zenutils/source/shared/firmware.h | 184 +-- utils/zenutils/source/shared/pe.cpp | 256 ++-- utils/zenutils/source/shared/pe.h | 284 ++-- utils/zenutils/source/shared/shared.cpp | 0 utils/zenutils/source/shared/updater.cpp | 302 ++--- utils/zenutils/source/shared/updater.h | 64 +- utils/zenutils/source/shared/utils.cpp | 422 +++--- utils/zenutils/source/shared/utils.h | 136 +- .../zenutils/source/update_extract/CMakeLists.txt | 6 +- utils/zenutils/source/update_extract/main.cpp | 558 ++++---- utils/zenutils/source/update_patch/CMakeLists.txt | 6 +- utils/zenutils/source/update_patch/main.cpp | 818 ++++++------ utils/zenutils/source/zen_crypt/CMakeLists.txt | 8 +- utils/zenutils/source/zen_crypt/main.cpp | 1374 ++++++++++---------- 27 files changed, 3753 insertions(+), 3753 deletions(-) mode change 100755 => 100644 utils/zenutils/source/CMakeLists.txt mode change 100755 => 100644 utils/zenutils/source/firmware_extract/CMakeLists.txt mode change 100755 => 100644 utils/zenutils/source/firmware_extract/main.cpp mode change 100755 => 100644 utils/zenutils/source/firmware_make/CMakeLists.txt mode change 100755 => 100644 utils/zenutils/source/firmware_make/main.cpp mode change 100755 => 100644 utils/zenutils/source/shared/CMakeLists.txt mode change 100755 => 100644 utils/zenutils/source/shared/cenc.cpp mode change 100755 => 100644 utils/zenutils/source/shared/cenc.h mode change 100755 => 100644 utils/zenutils/source/shared/crypt.cpp mode change 100755 => 100644 utils/zenutils/source/shared/crypt.h mode change 100755 => 100644 utils/zenutils/source/shared/file.cpp mode change 100755 => 100644 utils/zenutils/source/shared/file.h mode change 100755 => 100644 utils/zenutils/source/shared/firmware.cpp mode change 100755 => 100644 utils/zenutils/source/shared/firmware.h mode change 100755 => 100644 utils/zenutils/source/shared/pe.cpp mode change 100755 => 100644 utils/zenutils/source/shared/pe.h mode change 100755 => 100644 utils/zenutils/source/shared/shared.cpp mode change 100755 => 100644 utils/zenutils/source/shared/updater.cpp mode change 100755 => 100644 utils/zenutils/source/shared/updater.h mode change 100755 => 100644 utils/zenutils/source/shared/utils.cpp mode change 100755 => 100644 utils/zenutils/source/shared/utils.h mode change 100755 => 100644 utils/zenutils/source/update_extract/CMakeLists.txt mode change 100755 => 100644 utils/zenutils/source/update_extract/main.cpp mode change 100755 => 100644 utils/zenutils/source/update_patch/CMakeLists.txt mode change 100755 => 100644 utils/zenutils/source/update_patch/main.cpp mode change 100755 => 100644 utils/zenutils/source/zen_crypt/CMakeLists.txt mode change 100755 => 100644 utils/zenutils/source/zen_crypt/main.cpp (limited to 'utils/zenutils/source') diff --git a/utils/zenutils/source/CMakeLists.txt b/utils/zenutils/source/CMakeLists.txt old mode 100755 new mode 100644 index e3d44fd036..e7a4bcf63b --- a/utils/zenutils/source/CMakeLists.txt +++ b/utils/zenutils/source/CMakeLists.txt @@ -1,6 +1,6 @@ -ADD_SUBDIRECTORY(firmware_extract) -ADD_SUBDIRECTORY(firmware_make) -ADD_SUBDIRECTORY(shared) -ADD_SUBDIRECTORY(update_extract) -ADD_SUBDIRECTORY(update_patch) -ADD_SUBDIRECTORY(zen_crypt) +ADD_SUBDIRECTORY(firmware_extract) +ADD_SUBDIRECTORY(firmware_make) +ADD_SUBDIRECTORY(shared) +ADD_SUBDIRECTORY(update_extract) +ADD_SUBDIRECTORY(update_patch) +ADD_SUBDIRECTORY(zen_crypt) diff --git a/utils/zenutils/source/firmware_extract/CMakeLists.txt b/utils/zenutils/source/firmware_extract/CMakeLists.txt old mode 100755 new mode 100644 index 3814f03612..43af3e3235 --- a/utils/zenutils/source/firmware_extract/CMakeLists.txt +++ b/utils/zenutils/source/firmware_extract/CMakeLists.txt @@ -1,3 +1,3 @@ -ADD_EXECUTABLE(firmware_extract main.cpp) - -TARGET_LINK_LIBRARIES(firmware_extract shared) +ADD_EXECUTABLE(firmware_extract main.cpp) + +TARGET_LINK_LIBRARIES(firmware_extract shared) diff --git a/utils/zenutils/source/firmware_extract/main.cpp b/utils/zenutils/source/firmware_extract/main.cpp old mode 100755 new mode 100644 index c677a91a75..bcd77afdfc --- a/utils/zenutils/source/firmware_extract/main.cpp +++ b/utils/zenutils/source/firmware_extract/main.cpp @@ -1,243 +1,243 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - - -static const char VERSION[] = "0.1"; - - -void print_version() -{ - std::cout - << "firmware_extract - Extracts files from a Creative firmware." - << std::endl - << "Version " << VERSION << std::endl - << "Copyright (c) 2007 Rasmus Ry" << std::endl; -} - -void print_help() -{ - print_version(); - std::cout - << "Usage: firmware_extract [command] [options]" << std::endl - << std::endl - << " Commands:" << std::endl - << " -h,--help" << std::endl - << " prints this message." << std::endl - << " -f,--firmware [file]" << std::endl - << " specifies the firmware arhive file name." << std::endl - << std::endl - << " Options:" << std::endl - << " -V,--verbose" << std::endl - << " prints verbose messages." << std::endl - << " -p,--prefix [prefix]" << std::endl - << " specifies a file name prefix for the extracted files." << std::endl - << std::endl - ; -} - - -struct save_entry_functor -{ - save_entry_functor(const std::string& fileprefix) - : _fileprefix(fileprefix) {} - - bool operator()(const zen::firmware_entry& entry) - { - std::string filename = _fileprefix + entry.get_content_name(); - std::ofstream ofs; - ofs.open(filename.c_str(), std::ios::binary); - if (!ofs) - false; - - size_t off = entry.get_content_offset(); - std::streamsize size = entry.get_bytes().size() - off; - ofs.write((const char*)&entry.get_bytes()[off], size); - - return ofs.good(); - } - - const std::string& _fileprefix; -}; //struct save_entry_functor - -struct print_entry_functor -{ - print_entry_functor(std::ostream& os, const std::string& fileprefix) - : _os(os), _fileprefix(fileprefix), num(0) {} - - bool operator()(const zen::firmware_entry& entry) - { - std::string filename = _fileprefix + entry.get_content_name(); - if (!num) - _os << "[./" << num++ << "]" << std::endl; - else - _os << "[../" << num++ << "]" << std::endl; - _os << "tag = " << entry.get_name() << std::endl; - - if (entry.get_content_offset()) - _os << "name = " << entry.get_content_name() << std::endl; - - _os << "file = \'" << shared::double_quote(filename) << "\'" - << std::endl; - - return _os.good(); - } - - std::ostream& _os; - const std::string& _fileprefix; - int num; -}; //struct print_entry_functor - - -int process_arguments(int argc, char* argv[]) -{ - //-------------------------------------------------------------------- - // Parse input variables. - //-------------------------------------------------------------------- - - GetPot cl(argc, argv); - if (cl.size() == 1 || cl.search(2, "-h", "--help")) - { - print_help(); - return 1; - } - - std::string firmwarename; - if (cl.search("-f") || cl.search("--firmware")) - firmwarename = cl.next(""); - if (firmwarename.empty()) - { - std::cerr << "Firmware archive must be specified." << std::endl; - return 2; - } - - bool verbose = false; - if (cl.search("-V") || cl.search("--verbose")) - verbose = true; - - std::string prefixname = shared::remove_extension(firmwarename) + "_"; - if (cl.search("-p") || cl.search("--prefix")) - prefixname = cl.next(prefixname.c_str()); - - - //-------------------------------------------------------------------- - // Read the firmware archive. - //-------------------------------------------------------------------- - - if (verbose) - std::cout << "[*] Reading firmware archive..." << std::endl; - - zen::firmware_archive archive(false); - std::ifstream ifs; - ifs.open(firmwarename.c_str(), std::ios::binary); - if (!ifs) - { - std::cerr << "Failed to open the firmware archive." << std::endl; - return 3; - } - - if (!archive.read(ifs)) - { - std::cerr << "Failed to read the firmware archive." << std::endl; - return 4; - } - - - //-------------------------------------------------------------------- - // Generate a make file for the extracted firmware archive. - //-------------------------------------------------------------------- - - // Get make filename for the given input file. - std::string makefile = shared::replace_extension(firmwarename, ".mk"); - - if (verbose) - std::cout << "[*] Producing make file..." << std::endl; - - - // Produce make file for the given input file. - std::ofstream ofs; - ofs.open(makefile.c_str(), std::ios::binary); - if (!ofs) - { - std::cerr << "Failed to create firmware archive make file." - << std::endl; - return 5; - } - - time_t timeval = time(NULL); - ofs << "# Make file generated at: " << ctime(&timeval); - ofs << "endian = " << (archive.is_big_endian() ? "big" : "little") - << std::endl; - ofs << "signed = " << (archive.is_signed() ? "true" : "false") - << std::endl; - - ofs << "[children]" << std::endl; - ofs << "count = " << archive.get_children().size() << std::endl; - - std::for_each(archive.get_children().begin(), - archive.get_children().end(), - print_entry_functor(ofs, prefixname)); - - ofs << "[neighbours]" << std::endl; - ofs << "count = " << archive.get_neighbours().size() << std::endl; - std::for_each(archive.get_neighbours().begin(), - archive.get_neighbours().end(), - print_entry_functor(ofs, prefixname)); - - - //-------------------------------------------------------------------- - // Save firmware entries. - //-------------------------------------------------------------------- - - if (verbose) - std::cout << "[*] Saving firmware entries..." << std::endl; - - std::for_each(archive.get_children().begin(), - archive.get_children().end(), - save_entry_functor(prefixname)); - - std::for_each(archive.get_neighbours().begin(), - archive.get_neighbours().end(), - save_entry_functor(prefixname)); - - return 0; -} - -int main(int argc, char* argv[]) -{ - try - { - return process_arguments(argc, argv); - } - catch (const std::exception& xcpt) - { - std::cerr << "Exception caught: " << xcpt.what() << std::endl; - return -1; - } - catch (...) - { - std::cerr << "Unknown exception caught." << std::endl; - return -2; - } - return -3; -} +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + + +static const char VERSION[] = "0.1"; + + +void print_version() +{ + std::cout + << "firmware_extract - Extracts files from a Creative firmware." + << std::endl + << "Version " << VERSION << std::endl + << "Copyright (c) 2007 Rasmus Ry" << std::endl; +} + +void print_help() +{ + print_version(); + std::cout + << "Usage: firmware_extract [command] [options]" << std::endl + << std::endl + << " Commands:" << std::endl + << " -h,--help" << std::endl + << " prints this message." << std::endl + << " -f,--firmware [file]" << std::endl + << " specifies the firmware arhive file name." << std::endl + << std::endl + << " Options:" << std::endl + << " -V,--verbose" << std::endl + << " prints verbose messages." << std::endl + << " -p,--prefix [prefix]" << std::endl + << " specifies a file name prefix for the extracted files." << std::endl + << std::endl + ; +} + + +struct save_entry_functor +{ + save_entry_functor(const std::string& fileprefix) + : _fileprefix(fileprefix) {} + + bool operator()(const zen::firmware_entry& entry) + { + std::string filename = _fileprefix + entry.get_content_name(); + std::ofstream ofs; + ofs.open(filename.c_str(), std::ios::binary); + if (!ofs) + false; + + size_t off = entry.get_content_offset(); + std::streamsize size = entry.get_bytes().size() - off; + ofs.write((const char*)&entry.get_bytes()[off], size); + + return ofs.good(); + } + + const std::string& _fileprefix; +}; //struct save_entry_functor + +struct print_entry_functor +{ + print_entry_functor(std::ostream& os, const std::string& fileprefix) + : _os(os), _fileprefix(fileprefix), num(0) {} + + bool operator()(const zen::firmware_entry& entry) + { + std::string filename = _fileprefix + entry.get_content_name(); + if (!num) + _os << "[./" << num++ << "]" << std::endl; + else + _os << "[../" << num++ << "]" << std::endl; + _os << "tag = " << entry.get_name() << std::endl; + + if (entry.get_content_offset()) + _os << "name = " << entry.get_content_name() << std::endl; + + _os << "file = \'" << shared::double_quote(filename) << "\'" + << std::endl; + + return _os.good(); + } + + std::ostream& _os; + const std::string& _fileprefix; + int num; +}; //struct print_entry_functor + + +int process_arguments(int argc, char* argv[]) +{ + //-------------------------------------------------------------------- + // Parse input variables. + //-------------------------------------------------------------------- + + GetPot cl(argc, argv); + if (cl.size() == 1 || cl.search(2, "-h", "--help")) + { + print_help(); + return 1; + } + + std::string firmwarename; + if (cl.search("-f") || cl.search("--firmware")) + firmwarename = cl.next(""); + if (firmwarename.empty()) + { + std::cerr << "Firmware archive must be specified." << std::endl; + return 2; + } + + bool verbose = false; + if (cl.search("-V") || cl.search("--verbose")) + verbose = true; + + std::string prefixname = shared::remove_extension(firmwarename) + "_"; + if (cl.search("-p") || cl.search("--prefix")) + prefixname = cl.next(prefixname.c_str()); + + + //-------------------------------------------------------------------- + // Read the firmware archive. + //-------------------------------------------------------------------- + + if (verbose) + std::cout << "[*] Reading firmware archive..." << std::endl; + + zen::firmware_archive archive(false); + std::ifstream ifs; + ifs.open(firmwarename.c_str(), std::ios::binary); + if (!ifs) + { + std::cerr << "Failed to open the firmware archive." << std::endl; + return 3; + } + + if (!archive.read(ifs)) + { + std::cerr << "Failed to read the firmware archive." << std::endl; + return 4; + } + + + //-------------------------------------------------------------------- + // Generate a make file for the extracted firmware archive. + //-------------------------------------------------------------------- + + // Get make filename for the given input file. + std::string makefile = shared::replace_extension(firmwarename, ".mk"); + + if (verbose) + std::cout << "[*] Producing make file..." << std::endl; + + + // Produce make file for the given input file. + std::ofstream ofs; + ofs.open(makefile.c_str(), std::ios::binary); + if (!ofs) + { + std::cerr << "Failed to create firmware archive make file." + << std::endl; + return 5; + } + + time_t timeval = time(NULL); + ofs << "# Make file generated at: " << ctime(&timeval); + ofs << "endian = " << (archive.is_big_endian() ? "big" : "little") + << std::endl; + ofs << "signed = " << (archive.is_signed() ? "true" : "false") + << std::endl; + + ofs << "[children]" << std::endl; + ofs << "count = " << archive.get_children().size() << std::endl; + + std::for_each(archive.get_children().begin(), + archive.get_children().end(), + print_entry_functor(ofs, prefixname)); + + ofs << "[neighbours]" << std::endl; + ofs << "count = " << archive.get_neighbours().size() << std::endl; + std::for_each(archive.get_neighbours().begin(), + archive.get_neighbours().end(), + print_entry_functor(ofs, prefixname)); + + + //-------------------------------------------------------------------- + // Save firmware entries. + //-------------------------------------------------------------------- + + if (verbose) + std::cout << "[*] Saving firmware entries..." << std::endl; + + std::for_each(archive.get_children().begin(), + archive.get_children().end(), + save_entry_functor(prefixname)); + + std::for_each(archive.get_neighbours().begin(), + archive.get_neighbours().end(), + save_entry_functor(prefixname)); + + return 0; +} + +int main(int argc, char* argv[]) +{ + try + { + return process_arguments(argc, argv); + } + catch (const std::exception& xcpt) + { + std::cerr << "Exception caught: " << xcpt.what() << std::endl; + return -1; + } + catch (...) + { + std::cerr << "Unknown exception caught." << std::endl; + return -2; + } + return -3; +} diff --git a/utils/zenutils/source/firmware_make/CMakeLists.txt b/utils/zenutils/source/firmware_make/CMakeLists.txt old mode 100755 new mode 100644 index 518a008730..39197e2f07 --- a/utils/zenutils/source/firmware_make/CMakeLists.txt +++ b/utils/zenutils/source/firmware_make/CMakeLists.txt @@ -1,3 +1,3 @@ -ADD_EXECUTABLE(firmware_make main.cpp) - -TARGET_LINK_LIBRARIES (firmware_make shared) +ADD_EXECUTABLE(firmware_make main.cpp) + +TARGET_LINK_LIBRARIES (firmware_make shared) diff --git a/utils/zenutils/source/firmware_make/main.cpp b/utils/zenutils/source/firmware_make/main.cpp old mode 100755 new mode 100644 index b0602b6ffe..35d036e601 --- a/utils/zenutils/source/firmware_make/main.cpp +++ b/utils/zenutils/source/firmware_make/main.cpp @@ -1,261 +1,261 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - - -static const char VERSION[] = "0.1"; - -void print_version() -{ - std::cout - << "firmware_make - Creates a Creative firmware archive." << std::endl - << "Version " << VERSION << std::endl - << "Copyright (c) 2007 Rasmus Ry" << std::endl; -} - -void print_help() -{ - print_version(); - std::cout << std::endl - << "Usage: firmware_make [command] [options]" << std::endl - << std::endl - << " Commands:" << std::endl - << " -h,--help" << std::endl - << " prints this message." << std::endl - << " -m,--makefile [file]" << std::endl - << " specifies the .mk file to build the firmware archive from." - << std::endl << std::endl - << " Options:" << std::endl - << " -V,--verbose" << std::endl - << " prints verbose messages." << std::endl - << " -f,--firmware [file]" << std::endl - << " specifies the output firmware file name" << std::endl - << std::endl - ; -} - -dword get_tag_value(std::string tag) -{ - if (tag[0] == '0' && tag[1] == 'x') - { - dword val = 0; - if (sscanf(tag.c_str(), "0x%08X", &val) == 1) - return val; - if (sscanf(tag.c_str(), "0x%08x", &val) == 1) - return val; - } - else - { - return shared::swap(*(dword*)&tag[0]); - } - return 0; -} - -bool process_child(const GetPot& mkfile, const std::string& root, int index, - zen::firmware_entry& entry) -{ - std::stringstream sstm; - sstm << root << "/" << index; - std::string var = sstm.str() + "/tag"; - std::string tag = mkfile(var.c_str(), ""); - var = sstm.str() + "/name"; - std::string name = mkfile(var.c_str(), ""); - var = sstm.str() + "/file"; - std::string file = mkfile(var.c_str(), ""); - - if (file.empty() || tag.empty()) - { - std::cerr << "Invalid file or tag for var: " << sstm.str() - << std::endl; - return false; - } - - shared::bytes buffer; - if (!shared::read_file(file, buffer)) - { - std::cerr << "Failed to read the file: " << file << std::endl; - return false; - } - - entry.get_bytes().clear(); - entry.get_header().tag = get_tag_value(tag); - size_t contoff = entry.get_content_offset(); - if (contoff) - { - entry.get_bytes().resize(contoff, 0); - if (!name.empty()) - { - size_t endoff = entry.is_big_endian() ? 1 : 0; - for (int i = 0; i < name.size(); ++i) - entry.get_bytes()[i * 2 + endoff] = name[i]; - } - } - entry.get_bytes().insert(entry.get_bytes().end(), buffer.begin(), - buffer.end()); - - entry.get_header().size = entry.get_bytes().size(); - - return true; -} - -int process_arguments(int argc, char* argv[]) -{ - //-------------------------------------------------------------------- - // Parse input variables. - //-------------------------------------------------------------------- - - GetPot cl(argc, argv); - if (cl.size() == 1 || cl.search(2, "-h", "--help")) - { - print_help(); - return 1; - } - - std::string makefile; - if (cl.search("-m") || cl.search("--makefile")) - makefile = cl.next(""); - if (makefile.empty()) - { - std::cerr << "Makefile must be specified." << std::endl; - return 2; - } - - std::string firmware; - if (cl.search("-f") || cl.search("--firmware")) - firmware = cl.next(""); - if (firmware.empty()) - { - std::cerr << "Firmware must be specified." << std::endl; - return 3; - } - - bool verbose = false; - if (cl.search("-V") || cl.search("--verbose")) - verbose = true; - - GetPot mkfile(makefile.c_str()); - if (verbose) - mkfile.print(); - - bool big_endian; - std::string endian = mkfile("endian", "little"); - if (endian == "little") - { - big_endian = false; - } - else if (endian == "big") - { - big_endian = true; - } - else - { - std::cerr << "Invalid value of 'endian'" << std::endl; - return 4; - } - - zen::firmware_archive archive(big_endian); - int childcount = mkfile("children/count", 0); - if (!childcount) - { - std::cerr << "A firmware archive must have at least one child entry." - << std::endl; - return 5; - } - - for (int i = 0; i < childcount; i++) - { - zen::firmware_entry entry(big_endian); - if (!process_child(mkfile, "children", i, entry)) - { - return 6; - } - archive.get_children().push_back(entry); - } - - int neighbourcount = mkfile("neighbours/count", 0); - for (int i = 0; i < neighbourcount; i++) - { - zen::firmware_entry entry(big_endian); - if (!process_child(mkfile, "neighbours", i, entry)) - { - return 7; - } - archive.get_neighbours().push_back(entry); - } - - std::ofstream ofs; - ofs.open(firmware.c_str(), std::ios::out|std::ios::binary|std::ios::trunc); - if (!ofs) - { - std::cerr << "Failed to create the firmware file." << std::endl; - return 8; - } - - if (!archive.write(ofs)) - { - std::cerr << "Failed to save the firmware archive." << std::endl; - return 9; - } - ofs.close(); - - size_t length = archive.calc_size(); - if (!length) - { - std::cerr << "Failed to determine the size of the firmware archive." - << std::endl; - return 10; - } - - int align = length % 4; - if (align) - { - shared::bytes padding(4 - align, 0); - if (!shared::write_file(firmware, padding, false, length)) - { - std::cerr << "Failed to write padding data." << std::endl; - return 11; - } - } - - return 0; -} - -int main(int argc, char* argv[]) -{ - try - { - return process_arguments(argc, argv); - } - catch (const std::exception& xcpt) - { - std::cerr << "Exception caught: " << xcpt.what() << std::endl; - return -1; - } - catch (...) - { - std::cerr << "Unknown exception caught." << std::endl; - return -2; - } - return -3; -} +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + + +static const char VERSION[] = "0.1"; + +void print_version() +{ + std::cout + << "firmware_make - Creates a Creative firmware archive." << std::endl + << "Version " << VERSION << std::endl + << "Copyright (c) 2007 Rasmus Ry" << std::endl; +} + +void print_help() +{ + print_version(); + std::cout << std::endl + << "Usage: firmware_make [command] [options]" << std::endl + << std::endl + << " Commands:" << std::endl + << " -h,--help" << std::endl + << " prints this message." << std::endl + << " -m,--makefile [file]" << std::endl + << " specifies the .mk file to build the firmware archive from." + << std::endl << std::endl + << " Options:" << std::endl + << " -V,--verbose" << std::endl + << " prints verbose messages." << std::endl + << " -f,--firmware [file]" << std::endl + << " specifies the output firmware file name" << std::endl + << std::endl + ; +} + +dword get_tag_value(std::string tag) +{ + if (tag[0] == '0' && tag[1] == 'x') + { + dword val = 0; + if (sscanf(tag.c_str(), "0x%08X", &val) == 1) + return val; + if (sscanf(tag.c_str(), "0x%08x", &val) == 1) + return val; + } + else + { + return shared::swap(*(dword*)&tag[0]); + } + return 0; +} + +bool process_child(const GetPot& mkfile, const std::string& root, int index, + zen::firmware_entry& entry) +{ + std::stringstream sstm; + sstm << root << "/" << index; + std::string var = sstm.str() + "/tag"; + std::string tag = mkfile(var.c_str(), ""); + var = sstm.str() + "/name"; + std::string name = mkfile(var.c_str(), ""); + var = sstm.str() + "/file"; + std::string file = mkfile(var.c_str(), ""); + + if (file.empty() || tag.empty()) + { + std::cerr << "Invalid file or tag for var: " << sstm.str() + << std::endl; + return false; + } + + shared::bytes buffer; + if (!shared::read_file(file, buffer)) + { + std::cerr << "Failed to read the file: " << file << std::endl; + return false; + } + + entry.get_bytes().clear(); + entry.get_header().tag = get_tag_value(tag); + size_t contoff = entry.get_content_offset(); + if (contoff) + { + entry.get_bytes().resize(contoff, 0); + if (!name.empty()) + { + size_t endoff = entry.is_big_endian() ? 1 : 0; + for (int i = 0; i < name.size(); ++i) + entry.get_bytes()[i * 2 + endoff] = name[i]; + } + } + entry.get_bytes().insert(entry.get_bytes().end(), buffer.begin(), + buffer.end()); + + entry.get_header().size = entry.get_bytes().size(); + + return true; +} + +int process_arguments(int argc, char* argv[]) +{ + //-------------------------------------------------------------------- + // Parse input variables. + //-------------------------------------------------------------------- + + GetPot cl(argc, argv); + if (cl.size() == 1 || cl.search(2, "-h", "--help")) + { + print_help(); + return 1; + } + + std::string makefile; + if (cl.search("-m") || cl.search("--makefile")) + makefile = cl.next(""); + if (makefile.empty()) + { + std::cerr << "Makefile must be specified." << std::endl; + return 2; + } + + std::string firmware; + if (cl.search("-f") || cl.search("--firmware")) + firmware = cl.next(""); + if (firmware.empty()) + { + std::cerr << "Firmware must be specified." << std::endl; + return 3; + } + + bool verbose = false; + if (cl.search("-V") || cl.search("--verbose")) + verbose = true; + + GetPot mkfile(makefile.c_str()); + if (verbose) + mkfile.print(); + + bool big_endian; + std::string endian = mkfile("endian", "little"); + if (endian == "little") + { + big_endian = false; + } + else if (endian == "big") + { + big_endian = true; + } + else + { + std::cerr << "Invalid value of 'endian'" << std::endl; + return 4; + } + + zen::firmware_archive archive(big_endian); + int childcount = mkfile("children/count", 0); + if (!childcount) + { + std::cerr << "A firmware archive must have at least one child entry." + << std::endl; + return 5; + } + + for (int i = 0; i < childcount; i++) + { + zen::firmware_entry entry(big_endian); + if (!process_child(mkfile, "children", i, entry)) + { + return 6; + } + archive.get_children().push_back(entry); + } + + int neighbourcount = mkfile("neighbours/count", 0); + for (int i = 0; i < neighbourcount; i++) + { + zen::firmware_entry entry(big_endian); + if (!process_child(mkfile, "neighbours", i, entry)) + { + return 7; + } + archive.get_neighbours().push_back(entry); + } + + std::ofstream ofs; + ofs.open(firmware.c_str(), std::ios::out|std::ios::binary|std::ios::trunc); + if (!ofs) + { + std::cerr << "Failed to create the firmware file." << std::endl; + return 8; + } + + if (!archive.write(ofs)) + { + std::cerr << "Failed to save the firmware archive." << std::endl; + return 9; + } + ofs.close(); + + size_t length = archive.calc_size(); + if (!length) + { + std::cerr << "Failed to determine the size of the firmware archive." + << std::endl; + return 10; + } + + int align = length % 4; + if (align) + { + shared::bytes padding(4 - align, 0); + if (!shared::write_file(firmware, padding, false, length)) + { + std::cerr << "Failed to write padding data." << std::endl; + return 11; + } + } + + return 0; +} + +int main(int argc, char* argv[]) +{ + try + { + return process_arguments(argc, argv); + } + catch (const std::exception& xcpt) + { + std::cerr << "Exception caught: " << xcpt.what() << std::endl; + return -1; + } + catch (...) + { + std::cerr << "Unknown exception caught." << std::endl; + return -2; + } + return -3; +} diff --git a/utils/zenutils/source/shared/CMakeLists.txt b/utils/zenutils/source/shared/CMakeLists.txt old mode 100755 new mode 100644 index 2e42dbbe74..751257f64f --- a/utils/zenutils/source/shared/CMakeLists.txt +++ b/utils/zenutils/source/shared/CMakeLists.txt @@ -1,16 +1,16 @@ -PROJECT(shared) - -# source files for shared -SET(shared_srcs - cenc.cpp - crypt.cpp - file.cpp - firmware.cpp - pe.cpp - updater.cpp - utils.cpp -) - -ADD_LIBRARY(shared ${shared_srcs}) -TARGET_LINK_LIBRARIES(shared pelib) -TARGET_LINK_LIBRARIES(shared zlib) +PROJECT(shared) + +# source files for shared +SET(shared_srcs + cenc.cpp + crypt.cpp + file.cpp + firmware.cpp + pe.cpp + updater.cpp + utils.cpp +) + +ADD_LIBRARY(shared ${shared_srcs}) +TARGET_LINK_LIBRARIES(shared pelib) +TARGET_LINK_LIBRARIES(shared zlib) diff --git a/utils/zenutils/source/shared/cenc.cpp b/utils/zenutils/source/shared/cenc.cpp old mode 100755 new mode 100644 index 932bee4625..929a59b64d --- a/utils/zenutils/source/shared/cenc.cpp +++ b/utils/zenutils/source/shared/cenc.cpp @@ -1,333 +1,333 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "cenc.h" -#include -#include - - -namespace { -const byte CODE_MASK = 0xC0; -const byte ARGS_MASK = 0x3F; - -const byte REPEAT_CODE = 0x00; -const byte BLOCK_CODE = 0x40; -const byte LONG_RUN_CODE = 0x80; -const byte SHORT_RUN_CODE = 0xC0; - -const byte BLOCK_ARGS = 0x1F; -const byte BLOCK_MODE = 0x20; - - -void decode_run(byte* dst, word len, byte val, - int& dstidx) -{ - memset(dst + dstidx, val, len); - dstidx += len; -} - -void decode_pattern(byte* src, byte* dst, - word len, int& srcidx, int& dstidx, - bool bdecode, int npasses) -{ - for (int i = 0; i < npasses; i++) - { - if (bdecode) - { - for (int j = 0; j < len; j++) - { - word c, d; - c = src[srcidx + j]; - d = (c >> 5) & 7; - c = (c << 3) & 0xF8; - src[srcidx + j] = static_cast(c | d); - } - bdecode = false; - } - memcpy(dst + dstidx, src + srcidx, len); - dstidx += len; - } - srcidx += len; -} -}; //namespace - -int zen::cenc_decode(byte* src, int srclen, byte* dst, int dstlen) -{ - if (!src || !srclen || !dst || !dstlen) - { - throw std::invalid_argument("Invalid argument(s)."); - } - - int i = 0, j = 0; - do - { - word c, d, e; - c = src[i++]; - switch (c & CODE_MASK) - { - case REPEAT_CODE: // 2 bytes - d = src[i++]; - d = d + 2; - - e = (c & ARGS_MASK) + 2; - - decode_pattern(src, dst, e, i, j, false, d); - break; - - case BLOCK_CODE: // 1/2/3 bytes - d = c & BLOCK_ARGS; - if (!(c & BLOCK_MODE)) - { - e = src[i++]; - e = (d << 8) + (e + 0x21); - - d = static_cast(i ^ j); - } - else - { - e = d + 1; - - d = static_cast(i ^ j); - } - if (d & 1) - { - i++; - } - - decode_pattern(src, dst, e, i, j, true, 1); - break; - - case LONG_RUN_CODE: // 3 bytes - d = src[i++]; - e = ((c & ARGS_MASK) << 8) + (d + 0x42); - - d = src[i++]; - d = ((d & 7) << 5) | ((d >> 3) & 0x1F); - - decode_run(dst, e, static_cast(d), j); - break; - - case SHORT_RUN_CODE: // 2 bytes - d = src[i++]; - d = ((d & 3) << 6) | ((d >> 2) & 0x3F); - - e = (c & ARGS_MASK) + 2; - - decode_run(dst, e, static_cast(d), j); - break; - }; - } while (i < srclen && j < dstlen); - - return j; -} - -namespace { -int encode_run(byte* dst, int& dstidx, byte val, int len, int dstlen) -{ - if (len < 2) - throw std::invalid_argument("Length is too small."); - - int ret = 0; - if (len <= 0x41) - { - if ((dstidx + 2) > dstlen) - throw std::runtime_error("Not enough space to store run."); - - dst[dstidx++] = SHORT_RUN_CODE | (((len - 2) & ARGS_MASK)); - dst[dstidx++] = ((val >> 6) & 3) | ((val & 0x3F) << 2); - - ret = 2; - } - else if (len <= 0x4041) - { - if ((dstidx + 3) > dstlen) - throw std::runtime_error("Not enough space to store run."); - - byte b1 = (len - 0x42) >> 8; - byte b2 = (len - 0x42) & 0xFF; - - dst[dstidx++] = LONG_RUN_CODE | ((b1 & ARGS_MASK)); - dst[dstidx++] = b2; - dst[dstidx++] = ((val >> 5) & 7) | ((val & 0x1F) << 3); - - ret = 3; - } - else - { - int long_count = len / 0x4041; - int short_len = len % 0x4041; - bool toosmall = short_len == 1; - - int run_len = 0x4041; - for (int i = 0; i < long_count; i++) - { - if (toosmall && (i == (long_count-1))) - { - run_len--; - toosmall = false; - } - int tmp = encode_run(dst, dstidx, val, run_len, dstlen); - if (!tmp) return 0; - ret += tmp; - len -= run_len; - } - - if (len) - { - int short_count = len / 0x41; - int short_rest = short_count ? (len % 0x41) : 0; - toosmall = short_rest == 1; - - run_len = 0x41; - for (int i = 0; i < short_count; i++) - { - if (toosmall && (i == (short_count-1))) - { - run_len--; - toosmall = false; - } - int tmp = encode_run(dst, dstidx, val, run_len, dstlen); - if (!tmp) return 0; - ret += tmp; - len -= run_len; - } - int tmp = encode_run(dst, dstidx, val, len, dstlen); - if (!tmp) return 0; - ret += tmp; - len -= len; - } - } - - return ret; -} - -int encode_block(byte* dst, int& dstidx, byte* src, int& srcidx, int len, - int dstlen) -{ - if (len < 1) - throw std::invalid_argument("Length is too small."); - - int startidx = dstidx; - if (len < 0x21) - { - if ((dstidx + 2 + len) > dstlen) - throw std::runtime_error("Not enough space to store block."); - - dst[dstidx++] = BLOCK_CODE | BLOCK_MODE | ((len - 1) & BLOCK_ARGS); - if ((dstidx ^ srcidx) & 1) - dst[dstidx++] = 0; - - for (int i = 0; i < len; i++) - { - byte c = src[srcidx++]; - byte d = (c & 7) << 5; - c = (c & 0xF8) >> 3; - dst[dstidx++] = c | d; - } - } - else if (len < 0x2021) - { - if ((dstidx + 3 + len) > dstlen) - throw std::runtime_error("Not enough space to store block."); - - dst[dstidx++] = BLOCK_CODE | (((len - 0x21) >> 8) & BLOCK_ARGS); - dst[dstidx++] = (len - 0x21) & 0xFF; - if ((dstidx ^ srcidx) & 1) - dst[dstidx++] = 0; - - for (int i = 0; i < len; i++) - { - byte c = src[srcidx++]; - byte d = (c & 7) << 5; - c = (c & 0xF8) >> 3; - dst[dstidx++] = c | d; - } - } - else - { - int longblocks = len / 0x2020; - int rest = len % 0x2020; - for (int i = 0; i < longblocks; i++) - { - int tmp = encode_block(dst, dstidx, src, srcidx, 0x2020, dstlen); - if (!tmp) return 0; - } - if (rest) - { - int shortblocks = rest / 0x20; - for (int i = 0; i < shortblocks; i++) - { - int tmp = encode_block(dst, dstidx, src, srcidx, 0x20, dstlen); - if (!tmp) return 0; - } - rest = rest % 0x20; - int tmp = encode_block(dst, dstidx, src, srcidx, rest, dstlen); - if (!tmp) return 0; - } - } - - return (dstidx - startidx); -} -}; //namespace - -int zen::cenc_encode(byte* src, int srclen, byte* dst, int dstlen) -{ - if (!src || !srclen || !dst || !dstlen) - { - throw std::invalid_argument("Invalid argument(s)."); - } - - int i = 0, j = 0, k = 0; - word c, d, e; - int runlen = 0; - while (i < srclen && j < dstlen) - { - k = i; - c = src[i++]; - runlen = 1; - while (i < srclen && src[i] == c) - { - runlen++; - i++; - } - if (runlen >= 2) - { - if (!encode_run(dst, j, c, runlen, dstlen)) - return 0; - } - else - { - runlen = 0; - i = k; - while (i < (srclen - 1) && (src[i] != src[i + 1])) - { - runlen++; - i++; - } - if (i == (srclen - 1)) - { - runlen++; - i++; - } - if (!encode_block(dst, j, src, k, runlen, dstlen)) - return 0; - } - } - - return j; -} +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "cenc.h" +#include +#include + + +namespace { +const byte CODE_MASK = 0xC0; +const byte ARGS_MASK = 0x3F; + +const byte REPEAT_CODE = 0x00; +const byte BLOCK_CODE = 0x40; +const byte LONG_RUN_CODE = 0x80; +const byte SHORT_RUN_CODE = 0xC0; + +const byte BLOCK_ARGS = 0x1F; +const byte BLOCK_MODE = 0x20; + + +void decode_run(byte* dst, word len, byte val, + int& dstidx) +{ + memset(dst + dstidx, val, len); + dstidx += len; +} + +void decode_pattern(byte* src, byte* dst, + word len, int& srcidx, int& dstidx, + bool bdecode, int npasses) +{ + for (int i = 0; i < npasses; i++) + { + if (bdecode) + { + for (int j = 0; j < len; j++) + { + word c, d; + c = src[srcidx + j]; + d = (c >> 5) & 7; + c = (c << 3) & 0xF8; + src[srcidx + j] = static_cast(c | d); + } + bdecode = false; + } + memcpy(dst + dstidx, src + srcidx, len); + dstidx += len; + } + srcidx += len; +} +}; //namespace + +int zen::cenc_decode(byte* src, int srclen, byte* dst, int dstlen) +{ + if (!src || !srclen || !dst || !dstlen) + { + throw std::invalid_argument("Invalid argument(s)."); + } + + int i = 0, j = 0; + do + { + word c, d, e; + c = src[i++]; + switch (c & CODE_MASK) + { + case REPEAT_CODE: // 2 bytes + d = src[i++]; + d = d + 2; + + e = (c & ARGS_MASK) + 2; + + decode_pattern(src, dst, e, i, j, false, d); + break; + + case BLOCK_CODE: // 1/2/3 bytes + d = c & BLOCK_ARGS; + if (!(c & BLOCK_MODE)) + { + e = src[i++]; + e = (d << 8) + (e + 0x21); + + d = static_cast(i ^ j); + } + else + { + e = d + 1; + + d = static_cast(i ^ j); + } + if (d & 1) + { + i++; + } + + decode_pattern(src, dst, e, i, j, true, 1); + break; + + case LONG_RUN_CODE: // 3 bytes + d = src[i++]; + e = ((c & ARGS_MASK) << 8) + (d + 0x42); + + d = src[i++]; + d = ((d & 7) << 5) | ((d >> 3) & 0x1F); + + decode_run(dst, e, static_cast(d), j); + break; + + case SHORT_RUN_CODE: // 2 bytes + d = src[i++]; + d = ((d & 3) << 6) | ((d >> 2) & 0x3F); + + e = (c & ARGS_MASK) + 2; + + decode_run(dst, e, static_cast(d), j); + break; + }; + } while (i < srclen && j < dstlen); + + return j; +} + +namespace { +int encode_run(byte* dst, int& dstidx, byte val, int len, int dstlen) +{ + if (len < 2) + throw std::invalid_argument("Length is too small."); + + int ret = 0; + if (len <= 0x41) + { + if ((dstidx + 2) > dstlen) + throw std::runtime_error("Not enough space to store run."); + + dst[dstidx++] = SHORT_RUN_CODE | (((len - 2) & ARGS_MASK)); + dst[dstidx++] = ((val >> 6) & 3) | ((val & 0x3F) << 2); + + ret = 2; + } + else if (len <= 0x4041) + { + if ((dstidx + 3) > dstlen) + throw std::runtime_error("Not enough space to store run."); + + byte b1 = (len - 0x42) >> 8; + byte b2 = (len - 0x42) & 0xFF; + + dst[dstidx++] = LONG_RUN_CODE | ((b1 & ARGS_MASK)); + dst[dstidx++] = b2; + dst[dstidx++] = ((val >> 5) & 7) | ((val & 0x1F) << 3); + + ret = 3; + } + else + { + int long_count = len / 0x4041; + int short_len = len % 0x4041; + bool toosmall = short_len == 1; + + int run_len = 0x4041; + for (int i = 0; i < long_count; i++) + { + if (toosmall && (i == (long_count-1))) + { + run_len--; + toosmall = false; + } + int tmp = encode_run(dst, dstidx, val, run_len, dstlen); + if (!tmp) return 0; + ret += tmp; + len -= run_len; + } + + if (len) + { + int short_count = len / 0x41; + int short_rest = short_count ? (len % 0x41) : 0; + toosmall = short_rest == 1; + + run_len = 0x41; + for (int i = 0; i < short_count; i++) + { + if (toosmall && (i == (short_count-1))) + { + run_len--; + toosmall = false; + } + int tmp = encode_run(dst, dstidx, val, run_len, dstlen); + if (!tmp) return 0; + ret += tmp; + len -= run_len; + } + int tmp = encode_run(dst, dstidx, val, len, dstlen); + if (!tmp) return 0; + ret += tmp; + len -= len; + } + } + + return ret; +} + +int encode_block(byte* dst, int& dstidx, byte* src, int& srcidx, int len, + int dstlen) +{ + if (len < 1) + throw std::invalid_argument("Length is too small."); + + int startidx = dstidx; + if (len < 0x21) + { + if ((dstidx + 2 + len) > dstlen) + throw std::runtime_error("Not enough space to store block."); + + dst[dstidx++] = BLOCK_CODE | BLOCK_MODE | ((len - 1) & BLOCK_ARGS); + if ((dstidx ^ srcidx) & 1) + dst[dstidx++] = 0; + + for (int i = 0; i < len; i++) + { + byte c = src[srcidx++]; + byte d = (c & 7) << 5; + c = (c & 0xF8) >> 3; + dst[dstidx++] = c | d; + } + } + else if (len < 0x2021) + { + if ((dstidx + 3 + len) > dstlen) + throw std::runtime_error("Not enough space to store block."); + + dst[dstidx++] = BLOCK_CODE | (((len - 0x21) >> 8) & BLOCK_ARGS); + dst[dstidx++] = (len - 0x21) & 0xFF; + if ((dstidx ^ srcidx) & 1) + dst[dstidx++] = 0; + + for (int i = 0; i < len; i++) + { + byte c = src[srcidx++]; + byte d = (c & 7) << 5; + c = (c & 0xF8) >> 3; + dst[dstidx++] = c | d; + } + } + else + { + int longblocks = len / 0x2020; + int rest = len % 0x2020; + for (int i = 0; i < longblocks; i++) + { + int tmp = encode_block(dst, dstidx, src, srcidx, 0x2020, dstlen); + if (!tmp) return 0; + } + if (rest) + { + int shortblocks = rest / 0x20; + for (int i = 0; i < shortblocks; i++) + { + int tmp = encode_block(dst, dstidx, src, srcidx, 0x20, dstlen); + if (!tmp) return 0; + } + rest = rest % 0x20; + int tmp = encode_block(dst, dstidx, src, srcidx, rest, dstlen); + if (!tmp) return 0; + } + } + + return (dstidx - startidx); +} +}; //namespace + +int zen::cenc_encode(byte* src, int srclen, byte* dst, int dstlen) +{ + if (!src || !srclen || !dst || !dstlen) + { + throw std::invalid_argument("Invalid argument(s)."); + } + + int i = 0, j = 0, k = 0; + word c, d, e; + int runlen = 0; + while (i < srclen && j < dstlen) + { + k = i; + c = src[i++]; + runlen = 1; + while (i < srclen && src[i] == c) + { + runlen++; + i++; + } + if (runlen >= 2) + { + if (!encode_run(dst, j, c, runlen, dstlen)) + return 0; + } + else + { + runlen = 0; + i = k; + while (i < (srclen - 1) && (src[i] != src[i + 1])) + { + runlen++; + i++; + } + if (i == (srclen - 1)) + { + runlen++; + i++; + } + if (!encode_block(dst, j, src, k, runlen, dstlen)) + return 0; + } + } + + return j; +} diff --git a/utils/zenutils/source/shared/cenc.h b/utils/zenutils/source/shared/cenc.h old mode 100755 new mode 100644 index 12a7c92516..e96794dcc4 --- a/utils/zenutils/source/shared/cenc.h +++ b/utils/zenutils/source/shared/cenc.h @@ -1,29 +1,29 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef ZEN_CENC_H_INCLUDED -#define ZEN_CENC_H_INCLUDED - -#include - -namespace zen { - int cenc_decode(byte* src, int srclen, byte* dst, int dstlen); - int cenc_encode(byte* src, int srclen, byte* dst, int dstlen); -}; //namespace zen - -#endif //CENC_H_INCLUDED +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef ZEN_CENC_H_INCLUDED +#define ZEN_CENC_H_INCLUDED + +#include + +namespace zen { + int cenc_decode(byte* src, int srclen, byte* dst, int dstlen); + int cenc_encode(byte* src, int srclen, byte* dst, int dstlen); +}; //namespace zen + +#endif //CENC_H_INCLUDED diff --git a/utils/zenutils/source/shared/crypt.cpp b/utils/zenutils/source/shared/crypt.cpp old mode 100755 new mode 100644 index 9c2d33870c..3f15ac64f1 --- a/utils/zenutils/source/shared/crypt.cpp +++ b/utils/zenutils/source/shared/crypt.cpp @@ -1,91 +1,91 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "crypt.h" -#include -#include -#include -#include - - -bool zen::hmac_sha1_calc(const byte* key, size_t keylen, const byte* data, - size_t datalen, byte* sig, size_t* siglen) -{ - hmacsha1Param param; - if (hmacsha1Setup(¶m, key, keylen * 8)) - return false; - if (hmacsha1Update(¶m, data, datalen)) - return false; - if (hmacsha1Digest(¶m, sig)) - return false; - return true; -} - -bool zen::bf_cbc_encrypt(const byte* key, size_t keylen, byte* data, - size_t datalen, const byte* iv) -{ - if (datalen % blowfish.blocksize) - throw std::invalid_argument( - "The length must be aligned on a 8 byte boundary."); - - blowfishParam param; - if (blowfishSetup(¶m, key, keylen * 8, ENCRYPT)) - return false; - if (blowfishSetIV(¶m, iv)) - return false; - - byte* plain = new byte[datalen]; - memcpy(plain, data, datalen); - - unsigned int nblocks = datalen / blowfish.blocksize; - if (blockEncryptCBC(&blowfish, ¶m, (uint32_t*)data, (uint32_t*)plain, - nblocks)) - { - delete [] plain; - return false; - } - - return true; -} - -bool zen::bf_cbc_decrypt(const byte* key, size_t keylen, byte* data, - size_t datalen, const byte* iv) -{ - if (datalen % blowfish.blocksize) - throw std::invalid_argument( - "The length must be aligned on a 8 byte boundary."); - - blowfishParam param; - if (blowfishSetup(¶m, key, keylen * 8, ENCRYPT)) - return false; - if (blowfishSetIV(¶m, iv)) - return false; - - byte* cipher = new byte[datalen]; - memcpy(cipher, data, datalen); - - unsigned int nblocks = datalen / blowfish.blocksize; - if (blockDecryptCBC(&blowfish, ¶m, (uint32_t*)data, (uint32_t*)cipher, - nblocks)) - { - delete [] cipher; - return false; - } - - return true; -} +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "crypt.h" +#include +#include +#include +#include + + +bool zen::hmac_sha1_calc(const byte* key, size_t keylen, const byte* data, + size_t datalen, byte* sig, size_t* siglen) +{ + hmacsha1Param param; + if (hmacsha1Setup(¶m, key, keylen * 8)) + return false; + if (hmacsha1Update(¶m, data, datalen)) + return false; + if (hmacsha1Digest(¶m, sig)) + return false; + return true; +} + +bool zen::bf_cbc_encrypt(const byte* key, size_t keylen, byte* data, + size_t datalen, const byte* iv) +{ + if (datalen % blowfish.blocksize) + throw std::invalid_argument( + "The length must be aligned on a 8 byte boundary."); + + blowfishParam param; + if (blowfishSetup(¶m, key, keylen * 8, ENCRYPT)) + return false; + if (blowfishSetIV(¶m, iv)) + return false; + + byte* plain = new byte[datalen]; + memcpy(plain, data, datalen); + + unsigned int nblocks = datalen / blowfish.blocksize; + if (blockEncryptCBC(&blowfish, ¶m, (uint32_t*)data, (uint32_t*)plain, + nblocks)) + { + delete [] plain; + return false; + } + + return true; +} + +bool zen::bf_cbc_decrypt(const byte* key, size_t keylen, byte* data, + size_t datalen, const byte* iv) +{ + if (datalen % blowfish.blocksize) + throw std::invalid_argument( + "The length must be aligned on a 8 byte boundary."); + + blowfishParam param; + if (blowfishSetup(¶m, key, keylen * 8, ENCRYPT)) + return false; + if (blowfishSetIV(¶m, iv)) + return false; + + byte* cipher = new byte[datalen]; + memcpy(cipher, data, datalen); + + unsigned int nblocks = datalen / blowfish.blocksize; + if (blockDecryptCBC(&blowfish, ¶m, (uint32_t*)data, (uint32_t*)cipher, + nblocks)) + { + delete [] cipher; + return false; + } + + return true; +} diff --git a/utils/zenutils/source/shared/crypt.h b/utils/zenutils/source/shared/crypt.h old mode 100755 new mode 100644 index a057055b70..a357fef042 --- a/utils/zenutils/source/shared/crypt.h +++ b/utils/zenutils/source/shared/crypt.h @@ -1,30 +1,30 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef ZEN_CRYPT_H_INCLUDED -#define ZEN_CRYPT_H_INCLUDED - -#include - -namespace zen { - bool hmac_sha1_calc(const byte* key, size_t keylen, const byte* data, size_t datalen, byte* sig, size_t* siglen); - bool bf_cbc_encrypt(const byte* key, size_t keylen, byte* data, size_t datalen, const byte* iv); - bool bf_cbc_decrypt(const byte* key, size_t keylen, byte* data, size_t datalen, const byte* iv); -}; //namespace zen - -#endif //ZEN_CRYPT_H_INCLUDED +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef ZEN_CRYPT_H_INCLUDED +#define ZEN_CRYPT_H_INCLUDED + +#include + +namespace zen { + bool hmac_sha1_calc(const byte* key, size_t keylen, const byte* data, size_t datalen, byte* sig, size_t* siglen); + bool bf_cbc_encrypt(const byte* key, size_t keylen, byte* data, size_t datalen, const byte* iv); + bool bf_cbc_decrypt(const byte* key, size_t keylen, byte* data, size_t datalen, const byte* iv); +}; //namespace zen + +#endif //ZEN_CRYPT_H_INCLUDED diff --git a/utils/zenutils/source/shared/file.cpp b/utils/zenutils/source/shared/file.cpp old mode 100755 new mode 100644 index 2c31498972..b1b1093170 --- a/utils/zenutils/source/shared/file.cpp +++ b/utils/zenutils/source/shared/file.cpp @@ -1,106 +1,106 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "file.h" -#include - - -bool shared::read_file(const std::string& filename, bytes& buffer, - std::streampos offset, std::streamsize count) -{ - std::ifstream ifs; - ifs.open(filename.c_str(), std::ios::binary); - if (!ifs) - { - return false; - } - - std::ifstream::pos_type startpos = offset; - ifs.seekg(offset, std::ios::beg); - if (count == -1) - ifs.seekg(0, std::ios::end); - else - ifs.seekg(count, std::ios::cur); - std::ifstream::pos_type endpos = ifs.tellg(); - - buffer.resize(endpos-startpos); - ifs.seekg(offset, std::ios::beg); - - ifs.read((char*)&buffer[0], endpos-startpos); - - ifs.close(); - return ifs.good(); -} - - -bool shared::write_file(const std::string& filename, bytes& buffer, - bool truncate, std::streampos offset, - std::streamsize count) -{ - std::ios::openmode mode = std::ios::in|std::ios::out|std::ios::binary; - if (truncate) - mode |= std::ios::trunc; - - std::fstream ofs; - ofs.open(filename.c_str(), mode); - if (!ofs) - { - return false; - } - - if (count == -1) - count = buffer.size(); - else if (count > buffer.size()) - return false; - - ofs.seekg(offset, std::ios::beg); - - ofs.write((char*)&buffer[0], count); - - ofs.close(); - return ofs.good(); -} - -bool shared::file_exists(const std::string& filename) -{ - std::ifstream ifs; - ifs.open(filename.c_str(), std::ios::in); - if (ifs.is_open()) - { - ifs.close(); - return true; - } - return false; -} - -bool shared::copy_file(const std::string& srcname, const std::string& dstname) -{ - bytes buffer; - if (!read_file(srcname, buffer)) - return false; - return write_file(dstname, buffer, true); -} - -bool shared::backup_file(const std::string& filename, bool force) -{ - std::string backupname = filename + ".bak"; - if (!force) - if (file_exists(backupname)) - return true; - return copy_file(filename, backupname); -} +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "file.h" +#include + + +bool shared::read_file(const std::string& filename, bytes& buffer, + std::streampos offset, std::streamsize count) +{ + std::ifstream ifs; + ifs.open(filename.c_str(), std::ios::binary); + if (!ifs) + { + return false; + } + + std::ifstream::pos_type startpos = offset; + ifs.seekg(offset, std::ios::beg); + if (count == -1) + ifs.seekg(0, std::ios::end); + else + ifs.seekg(count, std::ios::cur); + std::ifstream::pos_type endpos = ifs.tellg(); + + buffer.resize(endpos-startpos); + ifs.seekg(offset, std::ios::beg); + + ifs.read((char*)&buffer[0], endpos-startpos); + + ifs.close(); + return ifs.good(); +} + + +bool shared::write_file(const std::string& filename, bytes& buffer, + bool truncate, std::streampos offset, + std::streamsize count) +{ + std::ios::openmode mode = std::ios::in|std::ios::out|std::ios::binary; + if (truncate) + mode |= std::ios::trunc; + + std::fstream ofs; + ofs.open(filename.c_str(), mode); + if (!ofs) + { + return false; + } + + if (count == -1) + count = buffer.size(); + else if (count > buffer.size()) + return false; + + ofs.seekg(offset, std::ios::beg); + + ofs.write((char*)&buffer[0], count); + + ofs.close(); + return ofs.good(); +} + +bool shared::file_exists(const std::string& filename) +{ + std::ifstream ifs; + ifs.open(filename.c_str(), std::ios::in); + if (ifs.is_open()) + { + ifs.close(); + return true; + } + return false; +} + +bool shared::copy_file(const std::string& srcname, const std::string& dstname) +{ + bytes buffer; + if (!read_file(srcname, buffer)) + return false; + return write_file(dstname, buffer, true); +} + +bool shared::backup_file(const std::string& filename, bool force) +{ + std::string backupname = filename + ".bak"; + if (!force) + if (file_exists(backupname)) + return true; + return copy_file(filename, backupname); +} diff --git a/utils/zenutils/source/shared/file.h b/utils/zenutils/source/shared/file.h old mode 100755 new mode 100644 index 8fa533c981..770f39a900 --- a/utils/zenutils/source/shared/file.h +++ b/utils/zenutils/source/shared/file.h @@ -1,36 +1,36 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SHARED_FILE_H_INCLUDED -#define SHARED_FILE_H_INCLUDED - -#include -#include -#include "utils.h" - -namespace shared { - bool read_file(const std::string& filename, bytes& buffer, - std::streampos offset = 0, std::streamsize count = -1); - bool write_file(const std::string& filename, bytes& buffer, bool truncate, - std::streampos offset = 0, std::streamsize count = -1); - bool file_exists(const std::string& filename); - bool copy_file(const std::string& srcname, const std::string& dstname); - bool backup_file(const std::string& filename, bool force = false); -}; //namespace shared - -#endif //SHARED_FILE_H_INCLUDED +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SHARED_FILE_H_INCLUDED +#define SHARED_FILE_H_INCLUDED + +#include +#include +#include "utils.h" + +namespace shared { + bool read_file(const std::string& filename, bytes& buffer, + std::streampos offset = 0, std::streamsize count = -1); + bool write_file(const std::string& filename, bytes& buffer, bool truncate, + std::streampos offset = 0, std::streamsize count = -1); + bool file_exists(const std::string& filename); + bool copy_file(const std::string& srcname, const std::string& dstname); + bool backup_file(const std::string& filename, bool force = false); +}; //namespace shared + +#endif //SHARED_FILE_H_INCLUDED diff --git a/utils/zenutils/source/shared/firmware.cpp b/utils/zenutils/source/shared/firmware.cpp old mode 100755 new mode 100644 index 7767b55d8f..811b8146b4 --- a/utils/zenutils/source/shared/firmware.cpp +++ b/utils/zenutils/source/shared/firmware.cpp @@ -1,387 +1,387 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "firmware.h" -#include -#include - - -zen::firmware_entry::firmware_entry(bool big_endian) - : _big_endian(big_endian) -{ -} - -zen::firmware_entry::firmware_entry(const firmware_entry& copy) -{ - assign(copy); -} - -zen::firmware_entry& zen::firmware_entry::operator=(const firmware_entry& right) -{ - assign(right); - return *this; -} - - -bool zen::firmware_entry::read(std::istream& is) -{ - // Read the header. - is.read((char*)&_header, sizeof(firmware_header_t)); - if (!is.good()) - return false; - - // If the firmware is big-endian, swap the header values to little-endian. - if (_big_endian) - { - _header.tag = shared::swap(_header.tag); - if (_header.tag != 'NULL') - { - _header.size = shared::swap(_header.size); - } - } - - // Resize the bytes buffer to the size specified in the header. - _bytes.resize(_header.size); - - // Read the entry contents. - is.read(reinterpret_cast(&_bytes[0]), - _header.size); - - return is.good(); -} - -bool zen::firmware_entry::write(std::ostream& os) const -{ - // Form a header using the current size of the bytes buffer. - firmware_header_t header = { - _header.tag, - static_cast(_bytes.size()) - }; - - // If the firmware is big-endian, swap the header values back into big-endian. - if (_big_endian) - { - if (header.tag != 'NULL') - { - header.size = shared::swap(header.size); - } - header.tag = shared::swap(header.tag); - } - - // Write the header. - os.write((const char*)&header, sizeof(firmware_header_t)); - if (!os.good()) - return false; - - // Write the entry contents. - os.write(reinterpret_cast(&_bytes[0]), - static_cast(_bytes.size())); - - return os.good(); -} - - -bool zen::firmware_entry::is_big_endian() const -{ - return _big_endian; -} - -const zen::firmware_header_t& zen::firmware_entry::get_header() const -{ - return _header; -} -zen::firmware_header_t& zen::firmware_entry::get_header() -{ - return _header; -} - -const shared::bytes& zen::firmware_entry::get_bytes() const -{ - return _bytes; -} -shared::bytes& zen::firmware_entry::get_bytes() -{ - return _bytes; -} - - -std::string zen::firmware_entry::get_name() const -{ - char name[5]; - *(dword*)name = shared::swap(_header.tag); - name[4] = '\0'; - - // Determine if all characters in the tag are printable. - bool isprintable = true; - for (int i = 0; i < 4; i++) - { - if (!isprint((byte)name[i])) - { - isprintable = false; - break; - } - } - - // If they are, simply return the tag as a string. - if (isprintable) - { - return std::string(name); - } - - // Otherwise, encode the tag into a hexadecimal string. - char buffer[11]; - sprintf(buffer, "0x%08x", _header.tag); - return std::string(buffer); -} - -std::string zen::firmware_entry::get_content_name() const -{ - std::string name = get_name(); - if (name == "DATA") - { - name = ""; - int nameoff = is_big_endian() ? 1 : 0; - for (int i = 0; i < 16; i++) - { - char c = get_bytes()[i * 2 + nameoff]; - if (!c) - break; - name += c; - } - } - else if (name == "EXT0") - { - name = ""; - int nameoff = is_big_endian() ? 1 : 0; - for (int i = 0; i < 12; i++) - { - char c = get_bytes()[i * 2 + nameoff]; - if (!c) - break; - name += c; - } - } - return name; -} - -size_t zen::firmware_entry::get_content_offset() const -{ - std::string name = get_name(); - if (name == "DATA") - { - return 32; - } - else if (name == "EXT0") - { - return 24; - } - return 0; -} - -size_t zen::firmware_entry::calc_size() const -{ - return _bytes.size() + sizeof(firmware_header_t); -} - - -void zen::firmware_entry::assign(const firmware_entry& copy) -{ - _big_endian = copy._big_endian; - _header.tag = copy._header.tag; - _header.size = copy._header.size; - _bytes.assign(copy._bytes.begin(), copy._bytes.end()); -} - - - -zen::firmware_archive::firmware_archive(bool big_endian) - : _big_endian(big_endian) -{ -} - -zen::firmware_archive::firmware_archive(const firmware_archive& copy) -{ - assign(copy); -} - -zen::firmware_archive& zen::firmware_archive::operator=(const firmware_archive& right) -{ - assign(right); - return *this; -} - - -bool zen::firmware_archive::read(std::istream& is) -{ - // Read the root entry's header. - firmware_header_t root; - is.read((char*)&root, sizeof(firmware_header_t)); - if (!is.good()) - return false; - - if ((root.tag != 'CIFF') && (root.tag != 'FFIC')) - { - throw std::runtime_error("Invalid firmware archive format!"); - } - - _big_endian = root.tag == 'FFIC' ? true : false; - if (_big_endian) - { - root.tag = shared::swap(root.tag); - root.size = shared::swap(root.size); - } - - // Save the current stream position. - std::istream::pos_type endpos = is.tellg(); - std::istream::pos_type curpos = endpos; - endpos += std::istream::pos_type(root.size); - - // Read untill the end of the root entry contents. - while (curpos < endpos) - { - firmware_entry entry(_big_endian); - if (!entry.read(is)) - return false; - - _children.push_back(entry); - curpos = is.tellg(); - } - - curpos = is.tellg(); - is.seekg(0, std::ios::end); - endpos = is.tellg(); - is.seekg(curpos); - - // Read untill the end of the file. - while (((size_t)curpos + sizeof(firmware_header_t)) < endpos) - { - firmware_entry entry(_big_endian); - if (!entry.read(is)) - return false; - - _neighbours.push_back(entry); - curpos = is.tellg(); - } - - return true; -} - -bool zen::firmware_archive::write(std::ostream& os) const -{ - // Read the root entry's header. - firmware_header_t root = {'CIFF', 0}; - - // Calculate the total size of all the children entries. - for (firmware_entries::const_iterator i = _children.begin(); - i != _children.end(); ++i) - { - root.size += i->calc_size(); - } - - // If the firmware is big-endian, swap the header values back into big-endian. - if (_big_endian) - { - root.tag = shared::swap(root.tag); - root.size = shared::swap(root.size); - } - - // Write the header. - os.write((const char*)&root, sizeof(firmware_header_t)); - if (!os.good()) - return false; - - // Write all the child entries. - for (firmware_entries::const_iterator i = _children.begin(); - i != _children.end(); ++i) - { - if (!i->write(os)) - return false; - } - - // Write all the neighbour entries. - for (firmware_entries::const_iterator i = _neighbours.begin(); - i != _neighbours.end(); ++i) - { - if (!i->write(os)) - return false; - } - - return true; -} - - -bool zen::firmware_archive::is_big_endian() const -{ - return _big_endian; -} - -const zen::firmware_entries& zen::firmware_archive::get_children() const -{ - return _children; -} -zen::firmware_entries& zen::firmware_archive::get_children() -{ - return _children; -} - -const zen::firmware_entries& zen::firmware_archive::get_neighbours() const -{ - return _neighbours; -} -zen::firmware_entries& zen::firmware_archive::get_neighbours() -{ - return _neighbours; -} - -bool zen::firmware_archive::is_signed() const -{ - for (firmware_entries::const_iterator i = _neighbours.begin(); - i != _neighbours.end(); i++) - { - if (i->get_name() == "NULL") - return true; - } - return false; -} - -size_t zen::firmware_archive::calc_size() const -{ - size_t size = sizeof(firmware_header_t); - - for (firmware_entries::const_iterator i = _children.begin(); - i != _children.end(); i++) - { - size += i->calc_size(); - } - - for (firmware_entries::const_iterator i = _neighbours.begin(); - i != _neighbours.end(); i++) - { - size += i->calc_size(); - } - - return size; -} - - -void zen::firmware_archive::assign(const firmware_archive& copy) -{ - _big_endian = copy._big_endian; - _children.assign(copy._children.begin(), copy._children.end()); - _neighbours.assign(copy._neighbours.begin(), copy._neighbours.end()); -} +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "firmware.h" +#include +#include + + +zen::firmware_entry::firmware_entry(bool big_endian) + : _big_endian(big_endian) +{ +} + +zen::firmware_entry::firmware_entry(const firmware_entry& copy) +{ + assign(copy); +} + +zen::firmware_entry& zen::firmware_entry::operator=(const firmware_entry& right) +{ + assign(right); + return *this; +} + + +bool zen::firmware_entry::read(std::istream& is) +{ + // Read the header. + is.read((char*)&_header, sizeof(firmware_header_t)); + if (!is.good()) + return false; + + // If the firmware is big-endian, swap the header values to little-endian. + if (_big_endian) + { + _header.tag = shared::swap(_header.tag); + if (_header.tag != 'NULL') + { + _header.size = shared::swap(_header.size); + } + } + + // Resize the bytes buffer to the size specified in the header. + _bytes.resize(_header.size); + + // Read the entry contents. + is.read(reinterpret_cast(&_bytes[0]), + _header.size); + + return is.good(); +} + +bool zen::firmware_entry::write(std::ostream& os) const +{ + // Form a header using the current size of the bytes buffer. + firmware_header_t header = { + _header.tag, + static_cast(_bytes.size()) + }; + + // If the firmware is big-endian, swap the header values back into big-endian. + if (_big_endian) + { + if (header.tag != 'NULL') + { + header.size = shared::swap(header.size); + } + header.tag = shared::swap(header.tag); + } + + // Write the header. + os.write((const char*)&header, sizeof(firmware_header_t)); + if (!os.good()) + return false; + + // Write the entry contents. + os.write(reinterpret_cast(&_bytes[0]), + static_cast(_bytes.size())); + + return os.good(); +} + + +bool zen::firmware_entry::is_big_endian() const +{ + return _big_endian; +} + +const zen::firmware_header_t& zen::firmware_entry::get_header() const +{ + return _header; +} +zen::firmware_header_t& zen::firmware_entry::get_header() +{ + return _header; +} + +const shared::bytes& zen::firmware_entry::get_bytes() const +{ + return _bytes; +} +shared::bytes& zen::firmware_entry::get_bytes() +{ + return _bytes; +} + + +std::string zen::firmware_entry::get_name() const +{ + char name[5]; + *(dword*)name = shared::swap(_header.tag); + name[4] = '\0'; + + // Determine if all characters in the tag are printable. + bool isprintable = true; + for (int i = 0; i < 4; i++) + { + if (!isprint((byte)name[i])) + { + isprintable = false; + break; + } + } + + // If they are, simply return the tag as a string. + if (isprintable) + { + return std::string(name); + } + + // Otherwise, encode the tag into a hexadecimal string. + char buffer[11]; + sprintf(buffer, "0x%08x", _header.tag); + return std::string(buffer); +} + +std::string zen::firmware_entry::get_content_name() const +{ + std::string name = get_name(); + if (name == "DATA") + { + name = ""; + int nameoff = is_big_endian() ? 1 : 0; + for (int i = 0; i < 16; i++) + { + char c = get_bytes()[i * 2 + nameoff]; + if (!c) + break; + name += c; + } + } + else if (name == "EXT0") + { + name = ""; + int nameoff = is_big_endian() ? 1 : 0; + for (int i = 0; i < 12; i++) + { + char c = get_bytes()[i * 2 + nameoff]; + if (!c) + break; + name += c; + } + } + return name; +} + +size_t zen::firmware_entry::get_content_offset() const +{ + std::string name = get_name(); + if (name == "DATA") + { + return 32; + } + else if (name == "EXT0") + { + return 24; + } + return 0; +} + +size_t zen::firmware_entry::calc_size() const +{ + return _bytes.size() + sizeof(firmware_header_t); +} + + +void zen::firmware_entry::assign(const firmware_entry& copy) +{ + _big_endian = copy._big_endian; + _header.tag = copy._header.tag; + _header.size = copy._header.size; + _bytes.assign(copy._bytes.begin(), copy._bytes.end()); +} + + + +zen::firmware_archive::firmware_archive(bool big_endian) + : _big_endian(big_endian) +{ +} + +zen::firmware_archive::firmware_archive(const firmware_archive& copy) +{ + assign(copy); +} + +zen::firmware_archive& zen::firmware_archive::operator=(const firmware_archive& right) +{ + assign(right); + return *this; +} + + +bool zen::firmware_archive::read(std::istream& is) +{ + // Read the root entry's header. + firmware_header_t root; + is.read((char*)&root, sizeof(firmware_header_t)); + if (!is.good()) + return false; + + if ((root.tag != 'CIFF') && (root.tag != 'FFIC')) + { + throw std::runtime_error("Invalid firmware archive format!"); + } + + _big_endian = root.tag == 'FFIC' ? true : false; + if (_big_endian) + { + root.tag = shared::swap(root.tag); + root.size = shared::swap(root.size); + } + + // Save the current stream position. + std::istream::pos_type endpos = is.tellg(); + std::istream::pos_type curpos = endpos; + endpos += std::istream::pos_type(root.size); + + // Read untill the end of the root entry contents. + while (curpos < endpos) + { + firmware_entry entry(_big_endian); + if (!entry.read(is)) + return false; + + _children.push_back(entry); + curpos = is.tellg(); + } + + curpos = is.tellg(); + is.seekg(0, std::ios::end); + endpos = is.tellg(); + is.seekg(curpos); + + // Read untill the end of the file. + while (((size_t)curpos + sizeof(firmware_header_t)) < endpos) + { + firmware_entry entry(_big_endian); + if (!entry.read(is)) + return false; + + _neighbours.push_back(entry); + curpos = is.tellg(); + } + + return true; +} + +bool zen::firmware_archive::write(std::ostream& os) const +{ + // Read the root entry's header. + firmware_header_t root = {'CIFF', 0}; + + // Calculate the total size of all the children entries. + for (firmware_entries::const_iterator i = _children.begin(); + i != _children.end(); ++i) + { + root.size += i->calc_size(); + } + + // If the firmware is big-endian, swap the header values back into big-endian. + if (_big_endian) + { + root.tag = shared::swap(root.tag); + root.size = shared::swap(root.size); + } + + // Write the header. + os.write((const char*)&root, sizeof(firmware_header_t)); + if (!os.good()) + return false; + + // Write all the child entries. + for (firmware_entries::const_iterator i = _children.begin(); + i != _children.end(); ++i) + { + if (!i->write(os)) + return false; + } + + // Write all the neighbour entries. + for (firmware_entries::const_iterator i = _neighbours.begin(); + i != _neighbours.end(); ++i) + { + if (!i->write(os)) + return false; + } + + return true; +} + + +bool zen::firmware_archive::is_big_endian() const +{ + return _big_endian; +} + +const zen::firmware_entries& zen::firmware_archive::get_children() const +{ + return _children; +} +zen::firmware_entries& zen::firmware_archive::get_children() +{ + return _children; +} + +const zen::firmware_entries& zen::firmware_archive::get_neighbours() const +{ + return _neighbours; +} +zen::firmware_entries& zen::firmware_archive::get_neighbours() +{ + return _neighbours; +} + +bool zen::firmware_archive::is_signed() const +{ + for (firmware_entries::const_iterator i = _neighbours.begin(); + i != _neighbours.end(); i++) + { + if (i->get_name() == "NULL") + return true; + } + return false; +} + +size_t zen::firmware_archive::calc_size() const +{ + size_t size = sizeof(firmware_header_t); + + for (firmware_entries::const_iterator i = _children.begin(); + i != _children.end(); i++) + { + size += i->calc_size(); + } + + for (firmware_entries::const_iterator i = _neighbours.begin(); + i != _neighbours.end(); i++) + { + size += i->calc_size(); + } + + return size; +} + + +void zen::firmware_archive::assign(const firmware_archive& copy) +{ + _big_endian = copy._big_endian; + _children.assign(copy._children.begin(), copy._children.end()); + _neighbours.assign(copy._neighbours.begin(), copy._neighbours.end()); +} diff --git a/utils/zenutils/source/shared/firmware.h b/utils/zenutils/source/shared/firmware.h old mode 100755 new mode 100644 index 3542186590..3cd233c3b6 --- a/utils/zenutils/source/shared/firmware.h +++ b/utils/zenutils/source/shared/firmware.h @@ -1,92 +1,92 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef ZEN_FIRMWARE_H_INCLUDED -#define ZEN_FIRMWARE_H_INCLUDED - -#include -#include - -namespace zen { - struct firmware_header_t - { - dword tag; - dword size; - }; //struct firmware_header_t - - class firmware_entry - { - public: - firmware_entry(bool big_endian); - firmware_entry(const firmware_entry& copy); - firmware_entry& operator=(const firmware_entry& right); - - bool read(std::istream& is); - bool write(std::ostream& os) const; - - bool is_big_endian() const; - const firmware_header_t& get_header() const; - firmware_header_t& get_header(); - const shared::bytes& get_bytes() const; - shared::bytes& get_bytes(); - - std::string get_name() const; - std::string get_content_name() const; - size_t get_content_offset() const; - size_t calc_size() const; - - protected: - void assign(const firmware_entry& copy); - - private: - bool _big_endian; - firmware_header_t _header; - shared::bytes _bytes; - }; //class firmware_entry - - typedef std::list firmware_entries; - - class firmware_archive - { - public: - firmware_archive(bool big_endian); - firmware_archive(const firmware_archive& copy); - firmware_archive& operator=(const firmware_archive& right); - - bool read(std::istream& is); - bool write(std::ostream& os) const; - - bool is_big_endian() const; - const firmware_entries& get_children() const; - firmware_entries& get_children(); - const firmware_entries& get_neighbours() const; - firmware_entries& get_neighbours(); - bool is_signed() const; - size_t calc_size() const; - - protected: - void assign(const firmware_archive& copy); - - private: - firmware_entries _children; - firmware_entries _neighbours; - bool _big_endian; - }; //class firmware_archive -}; //namespace zen - -#endif //ZEN_FIRMWARE_ARCHIVE_H_INCLUDED +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef ZEN_FIRMWARE_H_INCLUDED +#define ZEN_FIRMWARE_H_INCLUDED + +#include +#include + +namespace zen { + struct firmware_header_t + { + dword tag; + dword size; + }; //struct firmware_header_t + + class firmware_entry + { + public: + firmware_entry(bool big_endian); + firmware_entry(const firmware_entry& copy); + firmware_entry& operator=(const firmware_entry& right); + + bool read(std::istream& is); + bool write(std::ostream& os) const; + + bool is_big_endian() const; + const firmware_header_t& get_header() const; + firmware_header_t& get_header(); + const shared::bytes& get_bytes() const; + shared::bytes& get_bytes(); + + std::string get_name() const; + std::string get_content_name() const; + size_t get_content_offset() const; + size_t calc_size() const; + + protected: + void assign(const firmware_entry& copy); + + private: + bool _big_endian; + firmware_header_t _header; + shared::bytes _bytes; + }; //class firmware_entry + + typedef std::list firmware_entries; + + class firmware_archive + { + public: + firmware_archive(bool big_endian); + firmware_archive(const firmware_archive& copy); + firmware_archive& operator=(const firmware_archive& right); + + bool read(std::istream& is); + bool write(std::ostream& os) const; + + bool is_big_endian() const; + const firmware_entries& get_children() const; + firmware_entries& get_children(); + const firmware_entries& get_neighbours() const; + firmware_entries& get_neighbours(); + bool is_signed() const; + size_t calc_size() const; + + protected: + void assign(const firmware_archive& copy); + + private: + firmware_entries _children; + firmware_entries _neighbours; + bool _big_endian; + }; //class firmware_archive +}; //namespace zen + +#endif //ZEN_FIRMWARE_ARCHIVE_H_INCLUDED diff --git a/utils/zenutils/source/shared/pe.cpp b/utils/zenutils/source/shared/pe.cpp old mode 100755 new mode 100644 index c86ec6c8cc..10070074dd --- a/utils/zenutils/source/shared/pe.cpp +++ b/utils/zenutils/source/shared/pe.cpp @@ -1,128 +1,128 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "pe.h" - - -shared::pe_file::pe_file(PeLib::PeFile* pef) : _pef(pef) -{ -} -shared::pe_file::~pe_file() -{ - if (_pef != NULL) - delete _pef; -} - -bool shared::pe_file::is_valid() const -{ - if (_pef->getBits() == 32) - { - PeLib::PeHeader32& pef32 = static_cast(_pef)->peHeader(); - if (!pef32.isValid()) - return false; - return true; - } - else if (_pef->getBits() == 64) - { - PeLib::PeHeader64& pef64 = static_cast(_pef)->peHeader(); - if (!pef64.isValid()) - return false; - return true; - } - return false; -} - -bool shared::pe_file::read(const std::string& filename) -{ - if (_pef != NULL) - { - delete _pef; - _pef = NULL; - } - - _pef = PeLib::openPeFile(filename); - if (!_pef) - { - return false; - } - if (_pef->readMzHeader()) - { - delete _pef; - return false; - } - if (!_pef->mzHeader().isValid()) - { - delete _pef; - return false; - } - if (_pef->readPeHeader()) - { - delete _pef; - return false; - } - if (!is_valid()) - { - delete _pef; - return false; - } - return true; -} - -bool shared::pe_file::find_section(const std::string& name, section_info& info) const -{ - if (_pef->getBits() == 32) - return find_section(static_cast(_pef), - name, info); - else if (_pef->getBits() == 64) - return find_section(static_cast(_pef), - name, info); - return false; -} - -bool shared::pe_file::add_section(const std::string& name, - const bytes& buffer, section_info& info) -{ - if (_pef->getBits() == 32) - { - return add_section(static_cast(_pef), - name, buffer, info); - } - else if (_pef->getBits() == 64) - { - return add_section(static_cast(_pef), - name, buffer, info); - } - return false; -} - -dword shared::pe_file::get_image_base() const -{ - if (_pef->getBits() == 32) - return static_cast(_pef)->peHeader().getImageBase(); - else - return static_cast(_pef)->peHeader().getImageBase(); - return 0; -} -dword shared::pe_file::pa_to_va(dword pa) const -{ - if (_pef->getBits() == 32) - return static_cast(_pef)->peHeader().offsetToVa(pa); - else - return static_cast(_pef)->peHeader().offsetToVa(pa); - return 0; -} +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "pe.h" + + +shared::pe_file::pe_file(PeLib::PeFile* pef) : _pef(pef) +{ +} +shared::pe_file::~pe_file() +{ + if (_pef != NULL) + delete _pef; +} + +bool shared::pe_file::is_valid() const +{ + if (_pef->getBits() == 32) + { + PeLib::PeHeader32& pef32 = static_cast(_pef)->peHeader(); + if (!pef32.isValid()) + return false; + return true; + } + else if (_pef->getBits() == 64) + { + PeLib::PeHeader64& pef64 = static_cast(_pef)->peHeader(); + if (!pef64.isValid()) + return false; + return true; + } + return false; +} + +bool shared::pe_file::read(const std::string& filename) +{ + if (_pef != NULL) + { + delete _pef; + _pef = NULL; + } + + _pef = PeLib::openPeFile(filename); + if (!_pef) + { + return false; + } + if (_pef->readMzHeader()) + { + delete _pef; + return false; + } + if (!_pef->mzHeader().isValid()) + { + delete _pef; + return false; + } + if (_pef->readPeHeader()) + { + delete _pef; + return false; + } + if (!is_valid()) + { + delete _pef; + return false; + } + return true; +} + +bool shared::pe_file::find_section(const std::string& name, section_info& info) const +{ + if (_pef->getBits() == 32) + return find_section(static_cast(_pef), + name, info); + else if (_pef->getBits() == 64) + return find_section(static_cast(_pef), + name, info); + return false; +} + +bool shared::pe_file::add_section(const std::string& name, + const bytes& buffer, section_info& info) +{ + if (_pef->getBits() == 32) + { + return add_section(static_cast(_pef), + name, buffer, info); + } + else if (_pef->getBits() == 64) + { + return add_section(static_cast(_pef), + name, buffer, info); + } + return false; +} + +dword shared::pe_file::get_image_base() const +{ + if (_pef->getBits() == 32) + return static_cast(_pef)->peHeader().getImageBase(); + else + return static_cast(_pef)->peHeader().getImageBase(); + return 0; +} +dword shared::pe_file::pa_to_va(dword pa) const +{ + if (_pef->getBits() == 32) + return static_cast(_pef)->peHeader().offsetToVa(pa); + else + return static_cast(_pef)->peHeader().offsetToVa(pa); + return 0; +} diff --git a/utils/zenutils/source/shared/pe.h b/utils/zenutils/source/shared/pe.h old mode 100755 new mode 100644 index 92a272d3c7..f2f3aa48e8 --- a/utils/zenutils/source/shared/pe.h +++ b/utils/zenutils/source/shared/pe.h @@ -1,142 +1,142 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SHARED_PE_H_INCLUDED -#define SHARED_PE_H_INCLUDED - -#include -#include -#include - -namespace shared { - struct section_info - { - word index; - dword virtual_address; - dword virtual_size; - dword raw_address; - dword raw_size; - dword characteristics; - }; //struct section_info - - class pe_file - { - public: - pe_file(PeLib::PeFile* pef = NULL); - ~pe_file(); - - bool is_valid() const; - bool read(const std::string& filename); - bool find_section(const std::string& name, section_info& info) const; - bool add_section(const std::string& name, const bytes& buffer, section_info& info); - dword get_image_base() const; - dword pa_to_va(PeLib::dword pa) const; - - protected: - template - static bool find_section(const PeLib::PeFileT<_Bits>* pef, - const std::string& name, section_info& info); - template - static bool add_section(PeLib::PeFileT<_Bits>* pef, - const std::string& name, const bytes& buffer, - section_info& info); - - private: - PeLib::PeFile* _pef; - }; //class pe_file - - - template - bool pe_file::find_section(const PeLib::PeFileT<_Bits>* pef, - const std::string& name, section_info& info) - { - for (PeLib::word i = 0; i < pef->peHeader().getNumberOfSections(); i++) - { - if (pef->peHeader().getSectionName(i) == name) - { - info.index = i; - info.virtual_address = pef->peHeader().getVirtualAddress(i); - info.virtual_size = pef->peHeader().getVirtualSize(i); - info.raw_address = pef->peHeader().getPointerToRawData(i); - info.raw_size = pef->peHeader().getSizeOfRawData(i); - info.characteristics = pef->peHeader().getCharacteristics(i); - return true; - } - } - return false; - } - - template - bool pe_file::add_section(PeLib::PeFileT<_Bits>* pef, - const std::string& name, const bytes& buffer, - section_info& info) - { - using namespace PeLib; - - // Check if the last section has the same name as the one being added. - PeLib::word secnum = pef->peHeader().getNumberOfSections(); - if (pef->peHeader().getSectionName(secnum-1) == name) - { - // If it is, we change the attributes of the existing section. - secnum = secnum - 1; - pef->peHeader().setSizeOfRawData(secnum, - alignOffset(buffer.size(), - pef->peHeader().getFileAlignment())); - pef->peHeader().setVirtualSize(secnum, - alignOffset(buffer.size(), - pef->peHeader().getSectionAlignment())); - PeLib::dword chars = pef->peHeader().getCharacteristics(secnum-1); - pef->peHeader().setCharacteristics(secnum, - chars | PELIB_IMAGE_SCN_MEM_WRITE | PELIB_IMAGE_SCN_MEM_READ); - } - else - { - // Otherwise we add a new section. - if (pef->peHeader().addSection(name, buffer.size()) != NO_ERROR) - { - return false; - } - pef->peHeader().makeValid(pef->mzHeader().getAddressOfPeHeader()); - pef->peHeader().write(pef->getFileName(), pef->mzHeader().getAddressOfPeHeader()); - } - - // Save the section headers to the file. - if (pef->peHeader().writeSections(pef->getFileName()) != NO_ERROR) - { - return false; - } - - // Save the section data to the file. - if (pef->peHeader().writeSectionData(pef->getFileName(), secnum, buffer) != NO_ERROR) - { - return false; - } - - // Fill out the section information. - info.index = secnum; - info.virtual_address = pef->peHeader().getVirtualAddress(secnum); - info.virtual_size = pef->peHeader().getVirtualSize(secnum); - info.raw_address = pef->peHeader().getPointerToRawData(secnum); - info.raw_size = pef->peHeader().getSizeOfRawData(secnum); - info.characteristics = pef->peHeader().getCharacteristics(secnum); - - return true; - } -}; //namespace shared - -#endif //SHARED_PE_H_INCLUDED +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SHARED_PE_H_INCLUDED +#define SHARED_PE_H_INCLUDED + +#include +#include +#include + +namespace shared { + struct section_info + { + word index; + dword virtual_address; + dword virtual_size; + dword raw_address; + dword raw_size; + dword characteristics; + }; //struct section_info + + class pe_file + { + public: + pe_file(PeLib::PeFile* pef = NULL); + ~pe_file(); + + bool is_valid() const; + bool read(const std::string& filename); + bool find_section(const std::string& name, section_info& info) const; + bool add_section(const std::string& name, const bytes& buffer, section_info& info); + dword get_image_base() const; + dword pa_to_va(PeLib::dword pa) const; + + protected: + template + static bool find_section(const PeLib::PeFileT<_Bits>* pef, + const std::string& name, section_info& info); + template + static bool add_section(PeLib::PeFileT<_Bits>* pef, + const std::string& name, const bytes& buffer, + section_info& info); + + private: + PeLib::PeFile* _pef; + }; //class pe_file + + + template + bool pe_file::find_section(const PeLib::PeFileT<_Bits>* pef, + const std::string& name, section_info& info) + { + for (PeLib::word i = 0; i < pef->peHeader().getNumberOfSections(); i++) + { + if (pef->peHeader().getSectionName(i) == name) + { + info.index = i; + info.virtual_address = pef->peHeader().getVirtualAddress(i); + info.virtual_size = pef->peHeader().getVirtualSize(i); + info.raw_address = pef->peHeader().getPointerToRawData(i); + info.raw_size = pef->peHeader().getSizeOfRawData(i); + info.characteristics = pef->peHeader().getCharacteristics(i); + return true; + } + } + return false; + } + + template + bool pe_file::add_section(PeLib::PeFileT<_Bits>* pef, + const std::string& name, const bytes& buffer, + section_info& info) + { + using namespace PeLib; + + // Check if the last section has the same name as the one being added. + PeLib::word secnum = pef->peHeader().getNumberOfSections(); + if (pef->peHeader().getSectionName(secnum-1) == name) + { + // If it is, we change the attributes of the existing section. + secnum = secnum - 1; + pef->peHeader().setSizeOfRawData(secnum, + alignOffset(buffer.size(), + pef->peHeader().getFileAlignment())); + pef->peHeader().setVirtualSize(secnum, + alignOffset(buffer.size(), + pef->peHeader().getSectionAlignment())); + PeLib::dword chars = pef->peHeader().getCharacteristics(secnum-1); + pef->peHeader().setCharacteristics(secnum, + chars | PELIB_IMAGE_SCN_MEM_WRITE | PELIB_IMAGE_SCN_MEM_READ); + } + else + { + // Otherwise we add a new section. + if (pef->peHeader().addSection(name, buffer.size()) != NO_ERROR) + { + return false; + } + pef->peHeader().makeValid(pef->mzHeader().getAddressOfPeHeader()); + pef->peHeader().write(pef->getFileName(), pef->mzHeader().getAddressOfPeHeader()); + } + + // Save the section headers to the file. + if (pef->peHeader().writeSections(pef->getFileName()) != NO_ERROR) + { + return false; + } + + // Save the section data to the file. + if (pef->peHeader().writeSectionData(pef->getFileName(), secnum, buffer) != NO_ERROR) + { + return false; + } + + // Fill out the section information. + info.index = secnum; + info.virtual_address = pef->peHeader().getVirtualAddress(secnum); + info.virtual_size = pef->peHeader().getVirtualSize(secnum); + info.raw_address = pef->peHeader().getPointerToRawData(secnum); + info.raw_size = pef->peHeader().getSizeOfRawData(secnum); + info.characteristics = pef->peHeader().getCharacteristics(secnum); + + return true; + } +}; //namespace shared + +#endif //SHARED_PE_H_INCLUDED diff --git a/utils/zenutils/source/shared/shared.cpp b/utils/zenutils/source/shared/shared.cpp old mode 100755 new mode 100644 diff --git a/utils/zenutils/source/shared/updater.cpp b/utils/zenutils/source/shared/updater.cpp old mode 100755 new mode 100644 index 77d3f2876c..25d8452992 --- a/utils/zenutils/source/shared/updater.cpp +++ b/utils/zenutils/source/shared/updater.cpp @@ -1,151 +1,151 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "updater.h" -#include -#include -#include - - -const char* zen::find_firmware_key(const byte* buffer, size_t len) -{ - char szkey1[] = "34d1"; - size_t cchkey1 = strlen(szkey1); - char szkey2[] = "TbnCboEbn"; - size_t cchkey2 = strlen(szkey2); - for (int i = 0; i < static_cast(len); i++) - { - if (len >= cchkey1) - { - if (!strncmp((char*)&buffer[i], szkey1, cchkey1)) - { - return (const char*)&buffer[i]; - } - } - if (len >= cchkey2) - { - if (!strncmp((char*)&buffer[i], szkey2, cchkey2)) - { - return (const char*)&buffer[i]; - } - } - } - return NULL; -} - -dword zen::find_firmware_offset(byte* buffer, size_t len) -{ - for (dword i = 0; i < static_cast(len); i += 0x10) - { - dword size = *(dword*)&buffer[i]; - if (size < (i + len) && size > (len >> 1)) - { - if (buffer[i + sizeof(dword)] != 0 - && buffer[i + sizeof(dword) + 1] != 0 - && buffer[i + sizeof(dword) + 2] != 0 - && buffer[i + sizeof(dword) + 3] != 0) - { - return i; - } - } - } - return 0; -} - -bool zen::find_firmware_archive(const std::string& filename, dword& va, dword& pa) -{ - shared::pe_file pef; - if (!pef.read(filename)) - { - return false; - } - shared::section_info data_section; - if (!pef.find_section(".data", data_section)) - { - return false; - } - shared::bytes buffer; - if (!shared::read_file(filename, buffer, data_section.raw_address, - data_section.raw_size)) - { - return false; - } - dword offset = find_firmware_offset(&buffer[0], buffer.size()); - if (!offset) - { - return false; - } - va = data_section.virtual_address + offset; - pa = data_section.raw_address + offset; - - return true; -} - - -bool zen::crypt_firmware(const char* key, byte* buffer, size_t len) -{ - // Determine if the key length is dword aligned. - int keylen = strlen(key); - int keylen_rem = keylen % sizeof(dword); - - // Determine how many times the key must be repeated to be dword aligned. - int keycycle = keylen_rem ? (sizeof(dword) / keylen_rem) : 1; - int keyscount = (keylen * keycycle) / sizeof(dword); - - // Allocate a buffer to hold the key as an array of dwords. - dword* keys = new dword[keyscount]; - - // Copy the key into the key array, whilst mutating it. - for (int i = 0; i < keyscount; i++) - { - dword val; - int keyoffset = (i * sizeof(dword)) % keylen; - if ((keyoffset+sizeof(dword)) < keylen) - { - val = *(dword*)&key[keyoffset]; - } - else - { - val = key[keyoffset] - | (key[(keyoffset + 1) % keylen] << 8) - | (key[(keyoffset + 2) % keylen] << 16) - | (key[(keyoffset + 3) % keylen] << 24); - } - keys[i] = (val - 0x01010101) | 0x80808080; - } - - // Determine the number of dwords in the buffer. - int len_div = len / sizeof(dword); - - // Decrypt all dwords of the buffer. - for (int i = 0; i < len_div; i++) - { - ((dword*)buffer)[i] ^= keys[i % keyscount]; - } - - // Determine the remaining number of bytes in the buffer. - int len_rem = len % sizeof(dword); - - // Decrypt the remaining number of bytes in the buffer. - for (int i = len_div * sizeof(dword); i < len; i++) - { - buffer[i] ^= ((key[i % keylen] - 0x01) | 0x80); - } - - return true; -} +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "updater.h" +#include +#include +#include + + +const char* zen::find_firmware_key(const byte* buffer, size_t len) +{ + char szkey1[] = "34d1"; + size_t cchkey1 = strlen(szkey1); + char szkey2[] = "TbnCboEbn"; + size_t cchkey2 = strlen(szkey2); + for (int i = 0; i < static_cast(len); i++) + { + if (len >= cchkey1) + { + if (!strncmp((char*)&buffer[i], szkey1, cchkey1)) + { + return (const char*)&buffer[i]; + } + } + if (len >= cchkey2) + { + if (!strncmp((char*)&buffer[i], szkey2, cchkey2)) + { + return (const char*)&buffer[i]; + } + } + } + return NULL; +} + +dword zen::find_firmware_offset(byte* buffer, size_t len) +{ + for (dword i = 0; i < static_cast(len); i += 0x10) + { + dword size = *(dword*)&buffer[i]; + if (size < (i + len) && size > (len >> 1)) + { + if (buffer[i + sizeof(dword)] != 0 + && buffer[i + sizeof(dword) + 1] != 0 + && buffer[i + sizeof(dword) + 2] != 0 + && buffer[i + sizeof(dword) + 3] != 0) + { + return i; + } + } + } + return 0; +} + +bool zen::find_firmware_archive(const std::string& filename, dword& va, dword& pa) +{ + shared::pe_file pef; + if (!pef.read(filename)) + { + return false; + } + shared::section_info data_section; + if (!pef.find_section(".data", data_section)) + { + return false; + } + shared::bytes buffer; + if (!shared::read_file(filename, buffer, data_section.raw_address, + data_section.raw_size)) + { + return false; + } + dword offset = find_firmware_offset(&buffer[0], buffer.size()); + if (!offset) + { + return false; + } + va = data_section.virtual_address + offset; + pa = data_section.raw_address + offset; + + return true; +} + + +bool zen::crypt_firmware(const char* key, byte* buffer, size_t len) +{ + // Determine if the key length is dword aligned. + int keylen = strlen(key); + int keylen_rem = keylen % sizeof(dword); + + // Determine how many times the key must be repeated to be dword aligned. + int keycycle = keylen_rem ? (sizeof(dword) / keylen_rem) : 1; + int keyscount = (keylen * keycycle) / sizeof(dword); + + // Allocate a buffer to hold the key as an array of dwords. + dword* keys = new dword[keyscount]; + + // Copy the key into the key array, whilst mutating it. + for (int i = 0; i < keyscount; i++) + { + dword val; + int keyoffset = (i * sizeof(dword)) % keylen; + if ((keyoffset+sizeof(dword)) < keylen) + { + val = *(dword*)&key[keyoffset]; + } + else + { + val = key[keyoffset] + | (key[(keyoffset + 1) % keylen] << 8) + | (key[(keyoffset + 2) % keylen] << 16) + | (key[(keyoffset + 3) % keylen] << 24); + } + keys[i] = (val - 0x01010101) | 0x80808080; + } + + // Determine the number of dwords in the buffer. + int len_div = len / sizeof(dword); + + // Decrypt all dwords of the buffer. + for (int i = 0; i < len_div; i++) + { + ((dword*)buffer)[i] ^= keys[i % keyscount]; + } + + // Determine the remaining number of bytes in the buffer. + int len_rem = len % sizeof(dword); + + // Decrypt the remaining number of bytes in the buffer. + for (int i = len_div * sizeof(dword); i < len; i++) + { + buffer[i] ^= ((key[i % keylen] - 0x01) | 0x80); + } + + return true; +} diff --git a/utils/zenutils/source/shared/updater.h b/utils/zenutils/source/shared/updater.h old mode 100755 new mode 100644 index 57f9979c30..884fe9568c --- a/utils/zenutils/source/shared/updater.h +++ b/utils/zenutils/source/shared/updater.h @@ -1,32 +1,32 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef ZEN_UPDATER_H_INCLUDED -#define ZEN_UPDATER_H_INCLUDED - -#include -#include - -namespace zen { - const char* find_firmware_key(const byte* buffer, size_t len); - dword find_firmware_offset(byte* buffer, size_t len); - bool find_firmware_archive(const std::string& filename, dword& va, dword& pa); - bool crypt_firmware(const char* key, byte* buffer, size_t len); -}; //namespace zen - -#endif //ZEN_UPDATER_H_INCLUDED +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef ZEN_UPDATER_H_INCLUDED +#define ZEN_UPDATER_H_INCLUDED + +#include +#include + +namespace zen { + const char* find_firmware_key(const byte* buffer, size_t len); + dword find_firmware_offset(byte* buffer, size_t len); + bool find_firmware_archive(const std::string& filename, dword& va, dword& pa); + bool crypt_firmware(const char* key, byte* buffer, size_t len); +}; //namespace zen + +#endif //ZEN_UPDATER_H_INCLUDED diff --git a/utils/zenutils/source/shared/utils.cpp b/utils/zenutils/source/shared/utils.cpp old mode 100755 new mode 100644 index 8f45de5d3f..fbb223b42b --- a/utils/zenutils/source/shared/utils.cpp +++ b/utils/zenutils/source/shared/utils.cpp @@ -1,211 +1,211 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "utils.h" -#include -#include - - -std::string shared::replace_extension(const std::string& filename, const std::string& extension) -{ - std::string newname; - const char* name = filename.c_str(); - const char* ext = strrchr(name, '.'); - if (ext) - { - // If an extension was found, replace it. - newname.assign(name, ext-name); - newname += extension; - } - else - { - // If an extension was not found, append it. - newname = name; - newname += extension; - } - return newname; -} - -std::string shared::remove_extension(const std::string& filename) -{ - std::string newname; - const char* name = filename.c_str(); - const char* ext = strrchr(name, '.'); - if (ext) - { - newname.assign(name, ext-name); - } - else - { - newname = name; - } - return newname; -} - -std::string shared::double_quote(const std::string& str) -{ - std::string out; - for (int i = 0, j = str.length(); i < j; i++) - { - if (str[i] == '\\') - out += "\\\\"; - else - out += str[i]; - } - return out; -} - -bool shared::inflate_to_file(const bytes& buffer, const char* filename) -{ - // Open output file. - std::ofstream ofs; - ofs.open(filename, std::ios::binary); - if (!ofs) - { - return false; - } - - // Initialize zlib. - z_stream d_stream; // decompression stream - - d_stream.zalloc = Z_NULL; - d_stream.zfree = Z_NULL; - d_stream.opaque = Z_NULL; - - d_stream.next_in = const_cast(&buffer[0]); - d_stream.avail_in = static_cast(buffer.size()); - - int ret = inflateInit(&d_stream); - if (ret != Z_OK) - return false; - - // Allocate buffer to hold the inflated data. - const size_t BUFSIZE = 1048576; - Bytef* infbuf = new Bytef[BUFSIZE]; - if (!infbuf) - return false; - - // Decompress untill the end of the input buffer. - uLong totalout = 0; - bool bLoop = true; - while (bLoop) - { - d_stream.next_out = infbuf; - d_stream.avail_out = BUFSIZE; - - ret = inflate(&d_stream, Z_NO_FLUSH); - if (ret == Z_STREAM_END) - { - bLoop = false; - } - else if (ret != Z_OK) - { - inflateEnd(&d_stream); - delete [] infbuf; - return false; - } - - // Write the inflated data to the output file. - if (!ofs.write((const char*)infbuf, d_stream.total_out-totalout)) - { - inflateEnd(&d_stream); - delete [] infbuf; - return false; - } - totalout = d_stream.total_out; - } - - // Cleanup and return. - inflateEnd(&d_stream); - delete [] infbuf; - - return true; -} - -bool shared::deflate_to_file(const bytes& buffer, const char* filename) -{ - // Open output file. - std::ofstream ofs; - ofs.open(filename, std::ios::binary); - if (!ofs) - { - return false; - } - - // Initialize zlib. - z_stream c_stream; // compression stream. - - c_stream.zalloc = Z_NULL; - c_stream.zfree = Z_NULL; - c_stream.opaque = Z_NULL; - - int ret = deflateInit(&c_stream, Z_BEST_COMPRESSION); - if (ret != Z_OK) - return false; - - // Allocate buffer to hold the deflated data. - const size_t BUFSIZE = 1048576; - Bytef* defbuf = new Bytef[BUFSIZE]; - if (!defbuf) - return false; - - c_stream.avail_in = static_cast(buffer.size()); - c_stream.next_in = const_cast(&buffer[0]); - - // Compress until end of the buffer. - uLong totalout = 0; - bool bLoop = true; - while (bLoop) - { - c_stream.avail_out = BUFSIZE; - c_stream.next_out = defbuf; - - ret = deflate(&c_stream, Z_NO_FLUSH); // no bad return value - if (ret == Z_STREAM_END) - { - bLoop = false; - } - else if (ret == Z_BUF_ERROR && !c_stream.avail_in) - { - ret = deflate(&c_stream, Z_FINISH); // no bad return value - bLoop = false; - } - else if (ret != Z_OK) - { - deflateEnd(&c_stream); - delete [] defbuf; - return false; - } - - // Write the inflated data to the output file. - if (!ofs.write((const char*)defbuf, c_stream.total_out-totalout)) - { - deflateEnd(&c_stream); - delete [] defbuf; - return false; - } - - totalout = c_stream.total_out; - } - - // Clean up and return. - deflateEnd(&c_stream); - delete [] defbuf; - - return true; -} +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "utils.h" +#include +#include + + +std::string shared::replace_extension(const std::string& filename, const std::string& extension) +{ + std::string newname; + const char* name = filename.c_str(); + const char* ext = strrchr(name, '.'); + if (ext) + { + // If an extension was found, replace it. + newname.assign(name, ext-name); + newname += extension; + } + else + { + // If an extension was not found, append it. + newname = name; + newname += extension; + } + return newname; +} + +std::string shared::remove_extension(const std::string& filename) +{ + std::string newname; + const char* name = filename.c_str(); + const char* ext = strrchr(name, '.'); + if (ext) + { + newname.assign(name, ext-name); + } + else + { + newname = name; + } + return newname; +} + +std::string shared::double_quote(const std::string& str) +{ + std::string out; + for (int i = 0, j = str.length(); i < j; i++) + { + if (str[i] == '\\') + out += "\\\\"; + else + out += str[i]; + } + return out; +} + +bool shared::inflate_to_file(const bytes& buffer, const char* filename) +{ + // Open output file. + std::ofstream ofs; + ofs.open(filename, std::ios::binary); + if (!ofs) + { + return false; + } + + // Initialize zlib. + z_stream d_stream; // decompression stream + + d_stream.zalloc = Z_NULL; + d_stream.zfree = Z_NULL; + d_stream.opaque = Z_NULL; + + d_stream.next_in = const_cast(&buffer[0]); + d_stream.avail_in = static_cast(buffer.size()); + + int ret = inflateInit(&d_stream); + if (ret != Z_OK) + return false; + + // Allocate buffer to hold the inflated data. + const size_t BUFSIZE = 1048576; + Bytef* infbuf = new Bytef[BUFSIZE]; + if (!infbuf) + return false; + + // Decompress untill the end of the input buffer. + uLong totalout = 0; + bool bLoop = true; + while (bLoop) + { + d_stream.next_out = infbuf; + d_stream.avail_out = BUFSIZE; + + ret = inflate(&d_stream, Z_NO_FLUSH); + if (ret == Z_STREAM_END) + { + bLoop = false; + } + else if (ret != Z_OK) + { + inflateEnd(&d_stream); + delete [] infbuf; + return false; + } + + // Write the inflated data to the output file. + if (!ofs.write((const char*)infbuf, d_stream.total_out-totalout)) + { + inflateEnd(&d_stream); + delete [] infbuf; + return false; + } + totalout = d_stream.total_out; + } + + // Cleanup and return. + inflateEnd(&d_stream); + delete [] infbuf; + + return true; +} + +bool shared::deflate_to_file(const bytes& buffer, const char* filename) +{ + // Open output file. + std::ofstream ofs; + ofs.open(filename, std::ios::binary); + if (!ofs) + { + return false; + } + + // Initialize zlib. + z_stream c_stream; // compression stream. + + c_stream.zalloc = Z_NULL; + c_stream.zfree = Z_NULL; + c_stream.opaque = Z_NULL; + + int ret = deflateInit(&c_stream, Z_BEST_COMPRESSION); + if (ret != Z_OK) + return false; + + // Allocate buffer to hold the deflated data. + const size_t BUFSIZE = 1048576; + Bytef* defbuf = new Bytef[BUFSIZE]; + if (!defbuf) + return false; + + c_stream.avail_in = static_cast(buffer.size()); + c_stream.next_in = const_cast(&buffer[0]); + + // Compress until end of the buffer. + uLong totalout = 0; + bool bLoop = true; + while (bLoop) + { + c_stream.avail_out = BUFSIZE; + c_stream.next_out = defbuf; + + ret = deflate(&c_stream, Z_NO_FLUSH); // no bad return value + if (ret == Z_STREAM_END) + { + bLoop = false; + } + else if (ret == Z_BUF_ERROR && !c_stream.avail_in) + { + ret = deflate(&c_stream, Z_FINISH); // no bad return value + bLoop = false; + } + else if (ret != Z_OK) + { + deflateEnd(&c_stream); + delete [] defbuf; + return false; + } + + // Write the inflated data to the output file. + if (!ofs.write((const char*)defbuf, c_stream.total_out-totalout)) + { + deflateEnd(&c_stream); + delete [] defbuf; + return false; + } + + totalout = c_stream.total_out; + } + + // Clean up and return. + deflateEnd(&c_stream); + delete [] defbuf; + + return true; +} diff --git a/utils/zenutils/source/shared/utils.h b/utils/zenutils/source/shared/utils.h old mode 100755 new mode 100644 index ca9e291514..694cb9c8b1 --- a/utils/zenutils/source/shared/utils.h +++ b/utils/zenutils/source/shared/utils.h @@ -1,68 +1,68 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SHARED_UTILS_H_INCLUDED -#define SHARED_UTILS_H_INCLUDED - -#include -#include - -#ifndef byte -typedef PeLib::byte byte; -#endif -#ifndef word -typedef PeLib::word word; -#endif -#ifndef dword -typedef PeLib::dword dword; -#endif - -namespace shared { - typedef std::vector bytes; - - inline dword swap(dword val) - { - return ((val & 0xFF) << 24) - | ((val & 0xFF00) << 8) - | ((val & 0xFF0000) >> 8) - | ((val & 0xFF000000) >> 24); - } - - template - inline void reverse(_Type* start, _Type* end) - { - while (start < end) - { - *start ^= *end; - *end ^= *start; - *start ^= *end; - start++; - end--; - } - } - - std::string replace_extension(const std::string& filename, const std::string& extension); - std::string remove_extension(const std::string& filename); - std::string get_path(const std::string& filename); - std::string double_quote(const std::string& str); - - bool inflate_to_file(const bytes& buffer, const char* filename); - bool deflate_to_file(const bytes& buffer, const char* filename); -}; //namespace shared - -#endif //SHARED_UTILS_H_INCLUDED +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SHARED_UTILS_H_INCLUDED +#define SHARED_UTILS_H_INCLUDED + +#include +#include + +#ifndef byte +typedef PeLib::byte byte; +#endif +#ifndef word +typedef PeLib::word word; +#endif +#ifndef dword +typedef PeLib::dword dword; +#endif + +namespace shared { + typedef std::vector bytes; + + inline dword swap(dword val) + { + return ((val & 0xFF) << 24) + | ((val & 0xFF00) << 8) + | ((val & 0xFF0000) >> 8) + | ((val & 0xFF000000) >> 24); + } + + template + inline void reverse(_Type* start, _Type* end) + { + while (start < end) + { + *start ^= *end; + *end ^= *start; + *start ^= *end; + start++; + end--; + } + } + + std::string replace_extension(const std::string& filename, const std::string& extension); + std::string remove_extension(const std::string& filename); + std::string get_path(const std::string& filename); + std::string double_quote(const std::string& str); + + bool inflate_to_file(const bytes& buffer, const char* filename); + bool deflate_to_file(const bytes& buffer, const char* filename); +}; //namespace shared + +#endif //SHARED_UTILS_H_INCLUDED diff --git a/utils/zenutils/source/update_extract/CMakeLists.txt b/utils/zenutils/source/update_extract/CMakeLists.txt old mode 100755 new mode 100644 index 813e389bed..60d298be11 --- a/utils/zenutils/source/update_extract/CMakeLists.txt +++ b/utils/zenutils/source/update_extract/CMakeLists.txt @@ -1,3 +1,3 @@ -ADD_EXECUTABLE(update_extract main.cpp) - -TARGET_LINK_LIBRARIES (update_extract shared) +ADD_EXECUTABLE(update_extract main.cpp) + +TARGET_LINK_LIBRARIES (update_extract shared) diff --git a/utils/zenutils/source/update_extract/main.cpp b/utils/zenutils/source/update_extract/main.cpp old mode 100755 new mode 100644 index 0fae29e00c..4891329397 --- a/utils/zenutils/source/update_extract/main.cpp +++ b/utils/zenutils/source/update_extract/main.cpp @@ -1,279 +1,279 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include - - -static const char VERSION[] = "0.1"; - -void print_version() -{ - std::cout - << "update_extract - Extracts a Creative firmware from an updater" - " executable." << std::endl - << "Version " << VERSION << std::endl - << "Copyright (c) 2007 Rasmus Ry" << std::endl; -} - -void print_help() -{ - print_version(); - std::cout << std::endl - << "Usage: update_extract [command] [options]" << std::endl - << std::endl - << " Commands:" << std::endl - << " -h,--help" << std::endl - << " prints this message." << std::endl - << " -u,--updater [file]" << std::endl - << " specifies the updater executable." << std::endl - << std::endl - << " Options:" << std::endl - << " -V,--verbose" << std::endl - << " prints verbose messages." << std::endl - << " -f,--firmware [file]" << std::endl - << " specifies the firmware arhive file name." << std::endl - << " -k,--key [key]" << std::endl - << " specifies the firmware archive key." << std::endl - << " -o,--offset [offset]" << std::endl - << " specifies the firmware archive offset in c-style" - " hexadecimal." << std::endl - << std::endl - ; -} - -std::string options_name(const std::string& name) -{ - return shared::replace_extension(name, ".opt"); -} - -std::string default_firmware_name(const std::string& name) -{ - return shared::replace_extension(name, "_rk.bin"); -} - -int process_arguments(int argc, char* argv[]) -{ - //-------------------------------------------------------------------- - // Parse input variables. - //-------------------------------------------------------------------- - - GetPot cl(argc, argv); - if (cl.size() == 1 || cl.search(2, "-h", "--help")) - { - print_help(); - return 1; - } - - std::string updatername; - if (cl.search("-u") || cl.search("--updater")) - updatername = cl.next(""); - if (updatername.empty()) - { - std::cerr << "Updater executable must be specified." << std::endl; - return 2; - } - - std::string firmarename = default_firmware_name(updatername); - if (cl.search("-f") || cl.search("--firmware")) - firmarename = cl.next(firmarename.c_str()); - - bool verbose = false; - if (cl.search("-V") || cl.search("--verbose")) - verbose = true; - - // Get or find the firmware archive key. - std::string key; - if (cl.search("-k") || cl.search("--key")) - key = cl.next(""); - - if (key.empty()) - { - if (verbose) - std::cout << "[*] Looking for firmware archive key..." - << std::endl; - shared::bytes buffer; - if (!shared::read_file(updatername, buffer)) - { - std::cerr << "Failed to read the firmware updater executable." - << std::endl; - return 3; - } - key = zen::find_firmware_key(&buffer[0], buffer.size()); - if (key.empty()) - { - std::cerr << "Failed to find the firmware archive key." - << std::endl; - return 4; - } - } - - // Get or find the firmware archive offset. - std::string offset; - dword offset_pa = 0; - if (cl.search("-o") || cl.search("--ofset")) - offset = cl.next(""); - - if (offset.empty()) - { - if (verbose) - std::cout << "[*] Looking for firmware archive offset..." - << std::endl; - - dword offset_va = 0; - if (!zen::find_firmware_archive(updatername, offset_va, offset_pa)) - { - std::cerr << "Failed to find the firmware archive offset." - << std::endl; - return 5; - } - } - else - { - int offset_val; - if (!sscanf(offset.c_str(), "0x%x", &offset_val)) - { - if (!sscanf(offset.c_str(), "0x%X", &offset_val)) - { - std::cerr << "\'" << offset - << "\' is not a valid c-style hexadecimal value." - << std::endl; - return 6; - } - } - offset_pa = static_cast(offset_val); - } - - // Read firmware archive size. - shared::bytes buffer; - if (!shared::read_file(updatername, buffer, offset_pa, sizeof(dword))) - { - std::cerr << "Failed to read the firmware archive size." << std::endl; - return 7; - } - dword archive_size = *(dword*)&buffer[0]; - - if (verbose) - { - std::cout << "[*] Printing input variables..." << std::endl; - std::cout << " Updater executable: " << updatername << std::endl; - std::cout << " Firmware archive: " << firmarename << std::endl; - std::cout << " Key: " << key << std::endl; - std::cout << " Offset: " - << std::hex << std::showbase << std::setw(10) - << std::setfill('0') << std::internal - << offset_pa << std::endl; - std::cout << " Size: " - << std::hex << std::showbase << std::setw(10) - << std::setfill('0') << std::internal - << archive_size << std::endl; - } - - - //-------------------------------------------------------------------- - // Extract the firmware archive from the updater. - //-------------------------------------------------------------------- - - if (verbose) - std::cout << "[*] Reading firmware archive..." << std::endl; - - // Read the firmware archive. - offset_pa += sizeof(dword); - if (!shared::read_file(updatername, buffer, offset_pa, archive_size)) - { - std::cerr << "Failed to read the firmware archive." << std::endl; - return 8; - } - - if (verbose) - std::cout << "[*] Decrypting firmware archive..." << std::endl; - - // Decrypt the firmware archive. - if (!zen::crypt_firmware(key.c_str(), &buffer[0], buffer.size())) - { - std::cerr << "Failed to decrypt the firmware archive." << std::endl; - return 9; - } - - if (verbose) - std::cout << "[*] Decompressing firmware archive..." << std::endl; - - // Inflate the firmware archive to the output file. - if (!shared::inflate_to_file(buffer, firmarename.c_str())) - { - std::cerr << "Failed to decompress the firmware archive." << std::endl; - return 10; - } - - - //-------------------------------------------------------------------- - // Generate an options file for the extracted firmware archive. - //-------------------------------------------------------------------- - - // Get options filename for the given input file. - std::string optionsname = options_name(updatername); - - if (verbose) - std::cout << "[*] Producing options file..." << std::endl; - - // Produce options file for the given input file. - std::ofstream ofs; - ofs.open(optionsname.c_str(), std::ios::binary); - if (!ofs) - { - std::cerr << "Failed to create firmware archive options file." - << std::endl; - return 11; - } - - time_t timeval = time(NULL); - ofs << "# Options file generated at: " << ctime(&timeval) - << "updater = \'" << shared::double_quote(updatername) << "\'" - << std::endl - << "firmware = \'" << shared::double_quote(firmarename) << "\'" - << std::endl - << "offset = " << (offset_pa - sizeof(dword)) << std::endl - << "size = " << archive_size << std::endl - << "key = \'" << key << "\'" << std::endl; - - return 0; -} - -int main(int argc, char* argv[]) -{ - try - { - return process_arguments(argc, argv); - } - catch (const std::exception& xcpt) - { - std::cerr << "Exception caught: " << xcpt.what() << std::endl; - return -1; - } - catch (...) - { - std::cerr << "Unknown exception caught." << std::endl; - return -2; - } - return -3; -} +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + + +static const char VERSION[] = "0.1"; + +void print_version() +{ + std::cout + << "update_extract - Extracts a Creative firmware from an updater" + " executable." << std::endl + << "Version " << VERSION << std::endl + << "Copyright (c) 2007 Rasmus Ry" << std::endl; +} + +void print_help() +{ + print_version(); + std::cout << std::endl + << "Usage: update_extract [command] [options]" << std::endl + << std::endl + << " Commands:" << std::endl + << " -h,--help" << std::endl + << " prints this message." << std::endl + << " -u,--updater [file]" << std::endl + << " specifies the updater executable." << std::endl + << std::endl + << " Options:" << std::endl + << " -V,--verbose" << std::endl + << " prints verbose messages." << std::endl + << " -f,--firmware [file]" << std::endl + << " specifies the firmware arhive file name." << std::endl + << " -k,--key [key]" << std::endl + << " specifies the firmware archive key." << std::endl + << " -o,--offset [offset]" << std::endl + << " specifies the firmware archive offset in c-style" + " hexadecimal." << std::endl + << std::endl + ; +} + +std::string options_name(const std::string& name) +{ + return shared::replace_extension(name, ".opt"); +} + +std::string default_firmware_name(const std::string& name) +{ + return shared::replace_extension(name, "_rk.bin"); +} + +int process_arguments(int argc, char* argv[]) +{ + //-------------------------------------------------------------------- + // Parse input variables. + //-------------------------------------------------------------------- + + GetPot cl(argc, argv); + if (cl.size() == 1 || cl.search(2, "-h", "--help")) + { + print_help(); + return 1; + } + + std::string updatername; + if (cl.search("-u") || cl.search("--updater")) + updatername = cl.next(""); + if (updatername.empty()) + { + std::cerr << "Updater executable must be specified." << std::endl; + return 2; + } + + std::string firmarename = default_firmware_name(updatername); + if (cl.search("-f") || cl.search("--firmware")) + firmarename = cl.next(firmarename.c_str()); + + bool verbose = false; + if (cl.search("-V") || cl.search("--verbose")) + verbose = true; + + // Get or find the firmware archive key. + std::string key; + if (cl.search("-k") || cl.search("--key")) + key = cl.next(""); + + if (key.empty()) + { + if (verbose) + std::cout << "[*] Looking for firmware archive key..." + << std::endl; + shared::bytes buffer; + if (!shared::read_file(updatername, buffer)) + { + std::cerr << "Failed to read the firmware updater executable." + << std::endl; + return 3; + } + key = zen::find_firmware_key(&buffer[0], buffer.size()); + if (key.empty()) + { + std::cerr << "Failed to find the firmware archive key." + << std::endl; + return 4; + } + } + + // Get or find the firmware archive offset. + std::string offset; + dword offset_pa = 0; + if (cl.search("-o") || cl.search("--ofset")) + offset = cl.next(""); + + if (offset.empty()) + { + if (verbose) + std::cout << "[*] Looking for firmware archive offset..." + << std::endl; + + dword offset_va = 0; + if (!zen::find_firmware_archive(updatername, offset_va, offset_pa)) + { + std::cerr << "Failed to find the firmware archive offset." + << std::endl; + return 5; + } + } + else + { + int offset_val; + if (!sscanf(offset.c_str(), "0x%x", &offset_val)) + { + if (!sscanf(offset.c_str(), "0x%X", &offset_val)) + { + std::cerr << "\'" << offset + << "\' is not a valid c-style hexadecimal value." + << std::endl; + return 6; + } + } + offset_pa = static_cast(offset_val); + } + + // Read firmware archive size. + shared::bytes buffer; + if (!shared::read_file(updatername, buffer, offset_pa, sizeof(dword))) + { + std::cerr << "Failed to read the firmware archive size." << std::endl; + return 7; + } + dword archive_size = *(dword*)&buffer[0]; + + if (verbose) + { + std::cout << "[*] Printing input variables..." << std::endl; + std::cout << " Updater executable: " << updatername << std::endl; + std::cout << " Firmware archive: " << firmarename << std::endl; + std::cout << " Key: " << key << std::endl; + std::cout << " Offset: " + << std::hex << std::showbase << std::setw(10) + << std::setfill('0') << std::internal + << offset_pa << std::endl; + std::cout << " Size: " + << std::hex << std::showbase << std::setw(10) + << std::setfill('0') << std::internal + << archive_size << std::endl; + } + + + //-------------------------------------------------------------------- + // Extract the firmware archive from the updater. + //-------------------------------------------------------------------- + + if (verbose) + std::cout << "[*] Reading firmware archive..." << std::endl; + + // Read the firmware archive. + offset_pa += sizeof(dword); + if (!shared::read_file(updatername, buffer, offset_pa, archive_size)) + { + std::cerr << "Failed to read the firmware archive." << std::endl; + return 8; + } + + if (verbose) + std::cout << "[*] Decrypting firmware archive..." << std::endl; + + // Decrypt the firmware archive. + if (!zen::crypt_firmware(key.c_str(), &buffer[0], buffer.size())) + { + std::cerr << "Failed to decrypt the firmware archive." << std::endl; + return 9; + } + + if (verbose) + std::cout << "[*] Decompressing firmware archive..." << std::endl; + + // Inflate the firmware archive to the output file. + if (!shared::inflate_to_file(buffer, firmarename.c_str())) + { + std::cerr << "Failed to decompress the firmware archive." << std::endl; + return 10; + } + + + //-------------------------------------------------------------------- + // Generate an options file for the extracted firmware archive. + //-------------------------------------------------------------------- + + // Get options filename for the given input file. + std::string optionsname = options_name(updatername); + + if (verbose) + std::cout << "[*] Producing options file..." << std::endl; + + // Produce options file for the given input file. + std::ofstream ofs; + ofs.open(optionsname.c_str(), std::ios::binary); + if (!ofs) + { + std::cerr << "Failed to create firmware archive options file." + << std::endl; + return 11; + } + + time_t timeval = time(NULL); + ofs << "# Options file generated at: " << ctime(&timeval) + << "updater = \'" << shared::double_quote(updatername) << "\'" + << std::endl + << "firmware = \'" << shared::double_quote(firmarename) << "\'" + << std::endl + << "offset = " << (offset_pa - sizeof(dword)) << std::endl + << "size = " << archive_size << std::endl + << "key = \'" << key << "\'" << std::endl; + + return 0; +} + +int main(int argc, char* argv[]) +{ + try + { + return process_arguments(argc, argv); + } + catch (const std::exception& xcpt) + { + std::cerr << "Exception caught: " << xcpt.what() << std::endl; + return -1; + } + catch (...) + { + std::cerr << "Unknown exception caught." << std::endl; + return -2; + } + return -3; +} diff --git a/utils/zenutils/source/update_patch/CMakeLists.txt b/utils/zenutils/source/update_patch/CMakeLists.txt old mode 100755 new mode 100644 index 11474b7ff8..7b509dc40d --- a/utils/zenutils/source/update_patch/CMakeLists.txt +++ b/utils/zenutils/source/update_patch/CMakeLists.txt @@ -1,3 +1,3 @@ -ADD_EXECUTABLE(update_patch main.cpp) - -TARGET_LINK_LIBRARIES (update_patch shared) +ADD_EXECUTABLE(update_patch main.cpp) + +TARGET_LINK_LIBRARIES (update_patch shared) diff --git a/utils/zenutils/source/update_patch/main.cpp b/utils/zenutils/source/update_patch/main.cpp old mode 100755 new mode 100644 index d48797b46d..5467694728 --- a/utils/zenutils/source/update_patch/main.cpp +++ b/utils/zenutils/source/update_patch/main.cpp @@ -1,409 +1,409 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -static const char VERSION[] = "0.1"; - -void print_version() -{ - std::cout - << "update_patch - Patches a Creative firmware into an updater" - " executable." << std::endl - << "Version " << VERSION << std::endl - << "Copyright (c) 2007 Rasmus Ry" << std::endl; -} - -void print_help() -{ - print_version(); - std::cout << std::endl - << "Usage: update_patch [command] [options]" << std::endl - << std::endl - << " Commands:" << std::endl - << " -h,--help" << std::endl - << " prints this message." << std::endl - << " -u,--updater [file]" << std::endl - << " specifies the updater executable." << std::endl - << std::endl - << " Options:" << std::endl - << " -V,--verbose" << std::endl - << " prints verbose messages." << std::endl - << " -f,--firmware [file]" << std::endl - << " specifies the firmware arhive file name." << std::endl - << " -k,--key [key]" << std::endl - << " specifies the firmware archive key." << std::endl - << " -o,--offset [offset]" << std::endl - << " specifies the firmware archive offset in c-style" - " hexadecimal." << std::endl - << std::endl - ; -} - -std::string options_name(const std::string& name) -{ - return shared::replace_extension(name, ".opt"); -} - -std::string default_firmware_name(const std::string& name) -{ - return shared::replace_extension(name, "_rk.bin"); -} - -int process_arguments(int argc, char* argv[]) -{ - //-------------------------------------------------------------------- - // Parse input variables. - //-------------------------------------------------------------------- - - GetPot cl(argc, argv); - if (cl.size() == 1 || cl.search(2, "-h", "--help")) - { - print_help(); - return 1; - } - - std::string updatername; - if (cl.search("-u") || cl.search("--updater")) - updatername = cl.next(""); - if (updatername.empty()) - { - std::cerr << "Updater executable must be specified." << std::endl; - return 2; - } - - bool verbose = false; - if (cl.search("-V") || cl.search("--verbose")) - verbose = true; - - if (verbose) - std::cout << "[*] Parsing options file..." << std::endl; - - GetPot optfile(options_name(updatername.c_str()).c_str()); - if (verbose) - optfile.print(); - - std::string firmwarename = optfile("firmware", - default_firmware_name(updatername).c_str()); - dword offset_pa = optfile("offset", 0); - dword size = optfile("size", 0); - std::string key = optfile("key", ""); - - if (cl.search("-f") || cl.search("--firmware")) - firmwarename = cl.next(firmwarename.c_str()); - - std::string offset; - if (cl.search("-o") || cl.search("--offset")) - offset = cl.next(""); - - if (offset.empty() && !offset_pa) - { - if (verbose) - std::cout << "[*] Looking for firmware archive offset..." - << std::endl; - - dword offset_va = 0; - if (!zen::find_firmware_archive(updatername, offset_va, offset_pa)) - { - std::cerr << "Failed to find the firmware archive offset." - << std::endl; - return 3; - } - } - else if (!offset_pa) - { - int offset_val; - if (!sscanf(offset.c_str(), "0x%x", &offset_val)) - { - if (!sscanf(offset.c_str(), "0x%X", &offset_val)) - { - std::cerr << "\'" << offset - << "\' is not a valid c-style hexadecimal value." - << std::endl; - return 4; - } - } - offset_pa = static_cast(offset_val); - } - - if (key.empty()) - { - if (verbose) - std::cout << "[*] Looking for firmware archive key..." - << std::endl; - shared::bytes buffer; - if (!shared::read_file(updatername, buffer)) - { - std::cerr << "Failed to read the firmware updater executable." - << std::endl; - return 5; - } - key = zen::find_firmware_key(&buffer[0], buffer.size()); - if (key.empty()) - { - std::cerr << "Failed to find the firmware archive key." - << std::endl; - return 6; - } - } - - if (verbose) - { - std::cout << "[*] Printing input variables..." << std::endl; - std::cout << " Updater executable: " << updatername << std::endl; - std::cout << " Firmware archive: " << firmwarename << std::endl; - std::cout << " Key: " << key << std::endl; - std::cout << " Offset: " - << std::hex << std::showbase << std::setw(10) - << std::setfill('0') << std::internal - << offset_pa << std::endl; - std::cout << " Size: " - << std::hex << std::showbase << std::setw(10) - << std::setfill('0') << std::internal - << size << std::endl; - } - - - //-------------------------------------------------------------------- - // Prepare the firmware archive for being patched into the updater. - //-------------------------------------------------------------------- - - if (verbose) - std::cout << "[*] Reading firmware archive..." << std::endl; - - shared::bytes buffer; - if (!shared::read_file(firmwarename, buffer)) - { - std::cerr << "Failed to read the firmware archive." << std::endl; - return 7; - } - - if (verbose) - std::cout << " Bytes read: " - << std::hex << std::showbase << std::setw(10) - << std::setfill('0') << std::internal - << buffer.size() << std::endl; - - if (verbose) - std::cout << "[*] Compressing firmware archive..." << std::endl; - - std::string compfirmware = shared::replace_extension(firmwarename, ".def"); - if (!shared::deflate_to_file(buffer, compfirmware.c_str())) - { - std::cerr << "Failed to compress the firmware archive." << std::endl; - return 8; - } - - if (verbose) - std::cout << "[*] Reading compressed firmware archive..." << std::endl; - - if (!shared::read_file(compfirmware, buffer)) - { - std::cerr << "Failed to read the compressed firmware archive." - << std::endl; - return 9; - } - - if (verbose) - std::cout << " Bytes read: " - << std::hex << std::showbase << std::setw(10) - << std::setfill('0') << std::internal - << buffer.size() << std::endl; - - // Delete the temporary firmware file. - std::remove(compfirmware.c_str()); - - if (verbose) - std::cout << "[*] Encrypting compressed firmware archive..." - << std::endl; - - if (!zen::crypt_firmware(key.c_str(), &buffer[0], buffer.size())) - { - std::cerr << "Failed to encrypt the compressed firmware archive." - << std::endl; - return 10; - } - - - //-------------------------------------------------------------------- - // Backup the updater and patch the firmware archive into it. - //-------------------------------------------------------------------- - - if (verbose) - std::cout << "[*] Backing up the updater executable..." << std::endl; - - if (!shared::backup_file(updatername)) - { - std::cerr << "Failed to backup the updater executable." << std::endl; - return 11; - } - - // Is there enough space within the existing firmware archive - // to hold the new one? - if (size < buffer.size()) - { - // No, we need to add a new section to hold the new firmware archive. - if (verbose) - std::cout << "[*] Adding new section to the updater executable..." - << std::endl; - - // Construct a new buffer with the archive size prepended. - shared::bytes newbuffer(buffer.size() + sizeof(dword)); - *(dword*)&newbuffer[0] = static_cast(buffer.size()); - std::copy(buffer.begin(), buffer.end(), &newbuffer[4]); - - // Read the updater portable executable. - shared::pe_file pef; - if (!pef.read(updatername)) - { - std::cerr << "Failed to read the updater portable executable" - " structure." << std::endl; - return 12; - } - - // Add a new section to the updater, containing the encrypted - // firmware archive. - shared::section_info newsection; - if (!pef.add_section(".firm", newbuffer, newsection)) - { - std::cerr << "Failed to add an extra section to the updater" - " executable." << std::endl; - return 13; - } - - if (verbose) - std::cout << "[*] Relocating code references to the firmware" - " archive..." << std::endl; - - // Locate the code section. - shared::section_info textsection; - if (!pef.find_section(".text", textsection)) - { - std::cerr << "Failed to find the code section in the updater" - " executable." << std::endl; - return 14; - } - - // Read the code section data. - if (!shared::read_file(updatername, buffer, textsection.raw_address, - textsection.raw_size)) - { - std::cerr << "Failed to read the code section from the updater" - " executable." << std::endl; - return 15; - } - - // Determine the addresses of the new and old firmware archives. - dword oldva = pef.pa_to_va(offset_pa); - dword newva = pef.pa_to_va(newsection.raw_address); - if (!oldva || !newva) - { - std::cerr << "Failed to compute address of the new or old" - " archive." << std::endl; - return 16; - } - - // Relocate references to the old firmware archive. - dword imgbase = pef.get_image_base(); - for (int i = 0, j = buffer.size() - sizeof(dword) + 1; i < j; i++) - { - dword val = *(dword*)&buffer[i]; - if (val >= oldva && val <= (oldva + 3)) - { - *(dword*)&buffer[i] = newva + (val - oldva); - if (verbose) - std::cout << " " - << std::hex << std::showbase << std::setw(10) - << std::setfill('0') << std::internal - << (imgbase + textsection.virtual_address + i) - << ": " - << std::hex << std::showbase << std::setw(10) - << std::setfill('0') << std::internal - << val - << " -> " - << std::hex << std::showbase << std::setw(10) - << std::setfill('0') << std::internal - << (newva + (val - oldva)) << std::endl; - } - } - - // Write the relocated code section data. - if (!shared::write_file(updatername, buffer, false, textsection.raw_address, - buffer.size())) - { - std::cerr << "Failed to write the relocated code section to the" - " updater executable." << std::endl; - return 17; - } - } //if (size < buffer.size()) - else - { - // Yes, overwrite the existing firmware archive. - if (verbose) - std::cout << "[*] Overwriting existing firmware archive..." - << std::endl; - - shared::bytes archive_size(sizeof(dword)); - *(dword*)&archive_size[0] = buffer.size(); - - if (!shared::write_file(updatername, archive_size, false, offset_pa, - archive_size.size())) - { - std::cerr << "Failed to write archive size to the updater" - " executable." << std::endl; - return 18; - } - - if (!shared::write_file(updatername, buffer, false, - offset_pa+archive_size.size(), buffer.size())) - { - std::cerr << "Failed to write the new archive to the updater" - " exectuable." << std::endl; - return 19; - } - } - - return 0; -} - -int main(int argc, char* argv[]) -{ - try - { - return process_arguments(argc, argv); - } - catch (const std::exception& xcpt) - { - std::cerr << "Exception caught: " << xcpt.what() << std::endl; - return -1; - } - catch (...) - { - std::cerr << "Unknown exception caught." << std::endl; - return -2; - } - return -3; -} +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +static const char VERSION[] = "0.1"; + +void print_version() +{ + std::cout + << "update_patch - Patches a Creative firmware into an updater" + " executable." << std::endl + << "Version " << VERSION << std::endl + << "Copyright (c) 2007 Rasmus Ry" << std::endl; +} + +void print_help() +{ + print_version(); + std::cout << std::endl + << "Usage: update_patch [command] [options]" << std::endl + << std::endl + << " Commands:" << std::endl + << " -h,--help" << std::endl + << " prints this message." << std::endl + << " -u,--updater [file]" << std::endl + << " specifies the updater executable." << std::endl + << std::endl + << " Options:" << std::endl + << " -V,--verbose" << std::endl + << " prints verbose messages." << std::endl + << " -f,--firmware [file]" << std::endl + << " specifies the firmware arhive file name." << std::endl + << " -k,--key [key]" << std::endl + << " specifies the firmware archive key." << std::endl + << " -o,--offset [offset]" << std::endl + << " specifies the firmware archive offset in c-style" + " hexadecimal." << std::endl + << std::endl + ; +} + +std::string options_name(const std::string& name) +{ + return shared::replace_extension(name, ".opt"); +} + +std::string default_firmware_name(const std::string& name) +{ + return shared::replace_extension(name, "_rk.bin"); +} + +int process_arguments(int argc, char* argv[]) +{ + //-------------------------------------------------------------------- + // Parse input variables. + //-------------------------------------------------------------------- + + GetPot cl(argc, argv); + if (cl.size() == 1 || cl.search(2, "-h", "--help")) + { + print_help(); + return 1; + } + + std::string updatername; + if (cl.search("-u") || cl.search("--updater")) + updatername = cl.next(""); + if (updatername.empty()) + { + std::cerr << "Updater executable must be specified." << std::endl; + return 2; + } + + bool verbose = false; + if (cl.search("-V") || cl.search("--verbose")) + verbose = true; + + if (verbose) + std::cout << "[*] Parsing options file..." << std::endl; + + GetPot optfile(options_name(updatername.c_str()).c_str()); + if (verbose) + optfile.print(); + + std::string firmwarename = optfile("firmware", + default_firmware_name(updatername).c_str()); + dword offset_pa = optfile("offset", 0); + dword size = optfile("size", 0); + std::string key = optfile("key", ""); + + if (cl.search("-f") || cl.search("--firmware")) + firmwarename = cl.next(firmwarename.c_str()); + + std::string offset; + if (cl.search("-o") || cl.search("--offset")) + offset = cl.next(""); + + if (offset.empty() && !offset_pa) + { + if (verbose) + std::cout << "[*] Looking for firmware archive offset..." + << std::endl; + + dword offset_va = 0; + if (!zen::find_firmware_archive(updatername, offset_va, offset_pa)) + { + std::cerr << "Failed to find the firmware archive offset." + << std::endl; + return 3; + } + } + else if (!offset_pa) + { + int offset_val; + if (!sscanf(offset.c_str(), "0x%x", &offset_val)) + { + if (!sscanf(offset.c_str(), "0x%X", &offset_val)) + { + std::cerr << "\'" << offset + << "\' is not a valid c-style hexadecimal value." + << std::endl; + return 4; + } + } + offset_pa = static_cast(offset_val); + } + + if (key.empty()) + { + if (verbose) + std::cout << "[*] Looking for firmware archive key..." + << std::endl; + shared::bytes buffer; + if (!shared::read_file(updatername, buffer)) + { + std::cerr << "Failed to read the firmware updater executable." + << std::endl; + return 5; + } + key = zen::find_firmware_key(&buffer[0], buffer.size()); + if (key.empty()) + { + std::cerr << "Failed to find the firmware archive key." + << std::endl; + return 6; + } + } + + if (verbose) + { + std::cout << "[*] Printing input variables..." << std::endl; + std::cout << " Updater executable: " << updatername << std::endl; + std::cout << " Firmware archive: " << firmwarename << std::endl; + std::cout << " Key: " << key << std::endl; + std::cout << " Offset: " + << std::hex << std::showbase << std::setw(10) + << std::setfill('0') << std::internal + << offset_pa << std::endl; + std::cout << " Size: " + << std::hex << std::showbase << std::setw(10) + << std::setfill('0') << std::internal + << size << std::endl; + } + + + //-------------------------------------------------------------------- + // Prepare the firmware archive for being patched into the updater. + //-------------------------------------------------------------------- + + if (verbose) + std::cout << "[*] Reading firmware archive..." << std::endl; + + shared::bytes buffer; + if (!shared::read_file(firmwarename, buffer)) + { + std::cerr << "Failed to read the firmware archive." << std::endl; + return 7; + } + + if (verbose) + std::cout << " Bytes read: " + << std::hex << std::showbase << std::setw(10) + << std::setfill('0') << std::internal + << buffer.size() << std::endl; + + if (verbose) + std::cout << "[*] Compressing firmware archive..." << std::endl; + + std::string compfirmware = shared::replace_extension(firmwarename, ".def"); + if (!shared::deflate_to_file(buffer, compfirmware.c_str())) + { + std::cerr << "Failed to compress the firmware archive." << std::endl; + return 8; + } + + if (verbose) + std::cout << "[*] Reading compressed firmware archive..." << std::endl; + + if (!shared::read_file(compfirmware, buffer)) + { + std::cerr << "Failed to read the compressed firmware archive." + << std::endl; + return 9; + } + + if (verbose) + std::cout << " Bytes read: " + << std::hex << std::showbase << std::setw(10) + << std::setfill('0') << std::internal + << buffer.size() << std::endl; + + // Delete the temporary firmware file. + std::remove(compfirmware.c_str()); + + if (verbose) + std::cout << "[*] Encrypting compressed firmware archive..." + << std::endl; + + if (!zen::crypt_firmware(key.c_str(), &buffer[0], buffer.size())) + { + std::cerr << "Failed to encrypt the compressed firmware archive." + << std::endl; + return 10; + } + + + //-------------------------------------------------------------------- + // Backup the updater and patch the firmware archive into it. + //-------------------------------------------------------------------- + + if (verbose) + std::cout << "[*] Backing up the updater executable..." << std::endl; + + if (!shared::backup_file(updatername)) + { + std::cerr << "Failed to backup the updater executable." << std::endl; + return 11; + } + + // Is there enough space within the existing firmware archive + // to hold the new one? + if (size < buffer.size()) + { + // No, we need to add a new section to hold the new firmware archive. + if (verbose) + std::cout << "[*] Adding new section to the updater executable..." + << std::endl; + + // Construct a new buffer with the archive size prepended. + shared::bytes newbuffer(buffer.size() + sizeof(dword)); + *(dword*)&newbuffer[0] = static_cast(buffer.size()); + std::copy(buffer.begin(), buffer.end(), &newbuffer[4]); + + // Read the updater portable executable. + shared::pe_file pef; + if (!pef.read(updatername)) + { + std::cerr << "Failed to read the updater portable executable" + " structure." << std::endl; + return 12; + } + + // Add a new section to the updater, containing the encrypted + // firmware archive. + shared::section_info newsection; + if (!pef.add_section(".firm", newbuffer, newsection)) + { + std::cerr << "Failed to add an extra section to the updater" + " executable." << std::endl; + return 13; + } + + if (verbose) + std::cout << "[*] Relocating code references to the firmware" + " archive..." << std::endl; + + // Locate the code section. + shared::section_info textsection; + if (!pef.find_section(".text", textsection)) + { + std::cerr << "Failed to find the code section in the updater" + " executable." << std::endl; + return 14; + } + + // Read the code section data. + if (!shared::read_file(updatername, buffer, textsection.raw_address, + textsection.raw_size)) + { + std::cerr << "Failed to read the code section from the updater" + " executable." << std::endl; + return 15; + } + + // Determine the addresses of the new and old firmware archives. + dword oldva = pef.pa_to_va(offset_pa); + dword newva = pef.pa_to_va(newsection.raw_address); + if (!oldva || !newva) + { + std::cerr << "Failed to compute address of the new or old" + " archive." << std::endl; + return 16; + } + + // Relocate references to the old firmware archive. + dword imgbase = pef.get_image_base(); + for (int i = 0, j = buffer.size() - sizeof(dword) + 1; i < j; i++) + { + dword val = *(dword*)&buffer[i]; + if (val >= oldva && val <= (oldva + 3)) + { + *(dword*)&buffer[i] = newva + (val - oldva); + if (verbose) + std::cout << " " + << std::hex << std::showbase << std::setw(10) + << std::setfill('0') << std::internal + << (imgbase + textsection.virtual_address + i) + << ": " + << std::hex << std::showbase << std::setw(10) + << std::setfill('0') << std::internal + << val + << " -> " + << std::hex << std::showbase << std::setw(10) + << std::setfill('0') << std::internal + << (newva + (val - oldva)) << std::endl; + } + } + + // Write the relocated code section data. + if (!shared::write_file(updatername, buffer, false, textsection.raw_address, + buffer.size())) + { + std::cerr << "Failed to write the relocated code section to the" + " updater executable." << std::endl; + return 17; + } + } //if (size < buffer.size()) + else + { + // Yes, overwrite the existing firmware archive. + if (verbose) + std::cout << "[*] Overwriting existing firmware archive..." + << std::endl; + + shared::bytes archive_size(sizeof(dword)); + *(dword*)&archive_size[0] = buffer.size(); + + if (!shared::write_file(updatername, archive_size, false, offset_pa, + archive_size.size())) + { + std::cerr << "Failed to write archive size to the updater" + " executable." << std::endl; + return 18; + } + + if (!shared::write_file(updatername, buffer, false, + offset_pa+archive_size.size(), buffer.size())) + { + std::cerr << "Failed to write the new archive to the updater" + " exectuable." << std::endl; + return 19; + } + } + + return 0; +} + +int main(int argc, char* argv[]) +{ + try + { + return process_arguments(argc, argv); + } + catch (const std::exception& xcpt) + { + std::cerr << "Exception caught: " << xcpt.what() << std::endl; + return -1; + } + catch (...) + { + std::cerr << "Unknown exception caught." << std::endl; + return -2; + } + return -3; +} diff --git a/utils/zenutils/source/zen_crypt/CMakeLists.txt b/utils/zenutils/source/zen_crypt/CMakeLists.txt old mode 100755 new mode 100644 index e88e8951a5..5721bbfa06 --- a/utils/zenutils/source/zen_crypt/CMakeLists.txt +++ b/utils/zenutils/source/zen_crypt/CMakeLists.txt @@ -1,4 +1,4 @@ -ADD_EXECUTABLE(zen_crypt main.cpp) - -TARGET_LINK_LIBRARIES(zen_crypt shared) -TARGET_LINK_LIBRARIES(zen_crypt beecrypt) +ADD_EXECUTABLE(zen_crypt main.cpp) + +TARGET_LINK_LIBRARIES(zen_crypt shared) +TARGET_LINK_LIBRARIES(zen_crypt beecrypt) diff --git a/utils/zenutils/source/zen_crypt/main.cpp b/utils/zenutils/source/zen_crypt/main.cpp old mode 100755 new mode 100644 index 8301cbbea5..9944ba97f8 --- a/utils/zenutils/source/zen_crypt/main.cpp +++ b/utils/zenutils/source/zen_crypt/main.cpp @@ -1,687 +1,687 @@ -/* zenutils - Utilities for working with creative firmwares. - * Copyright 2007 (c) Rasmus Ry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include - - -namespace { -enum command_t -{ - cmd_none = 0, - cmd_sign, - cmd_verify, - cmd_encrypt, - cmd_decrypt -}; - -enum mode_t -{ - mode_none = 0, - mode_cenc, - mode_fresc, - mode_tl -}; - -struct player_info_t -{ - const char* name; - const char* null_key; // HMAC-SHA1 key - const char* fresc_key; // BlowFish key - const char* tl_key; // BlowFish key - bool big_endian; -}; -}; //namespace - - -static const char VERSION[] = "0.1"; - -static const char null_key_v1[] = "CTL:N0MAD|PDE0.SIGN."; -static const char null_key_v2[] = "CTL:N0MAD|PDE0.DPMP."; - -static const char fresc_key[] = "Copyright (C) CTL. -" - " zN0MAD iz v~p0wderful!"; - -static const char tl_zvm_key[] = "1sN0TM3D az u~may th1nk*" - "Creative Zen Vision:M"; -static const char tl_zvw_key[] = "1sN0TM3D az u~may th1nk*" - "Creative ZEN Vision W"; -static const char tl_zm_key[] = "1sN0TM3D az u~may th1nk*" - "Creative Zen Micro"; -static const char tl_zmp_key[] = "1sN0TM3D az u~may th1nk*" - "Creative Zen MicroPhoto"; -static const char tl_zs_key[] = "1sN0TM3D az u~may th1nk*" - "Creative Zen Sleek"; -static const char tl_zsp_key[] = "1sN0TM3D az u~may th1nk*" - "Creative Zen Sleek Photo"; -static const char tl_zt_key[] = "1sN0TM3D az u~may th1nk*" - "Creative Zen Touch"; -static const char tl_zx_key[] = "1sN0TM3D az u~may th1nk*" - "NOMAD Jukebox Zen Xtra"; - -player_info_t players[] = { - {"Vision:M", null_key_v2, fresc_key, tl_zvm_key, false}, - {"Vision W", null_key_v2, fresc_key, tl_zvw_key, false}, - {"Micro", null_key_v1, fresc_key, tl_zm_key, true}, - {"MicroPhoto", null_key_v1, fresc_key, tl_zmp_key, true}, - {"Sleek", null_key_v1, fresc_key, tl_zs_key, true}, - {"SleekPhoto", null_key_v1, fresc_key, tl_zsp_key, true}, - {"Touch", null_key_v1, fresc_key, tl_zt_key, true}, - {"Xtra", null_key_v1, fresc_key, tl_zx_key, true}, - {NULL, NULL, NULL, NULL, false} -}; - - -player_info_t* find_player_info(std::string player) -{ - for (int i = 0; players[i].name != NULL; i++) - { - if (!stricmp(players[i].name, player.c_str())) - { - return &players[i]; - } - } - return NULL; -} - -void print_version() -{ - std::cout - << "zen_crypt - A utility for encrypting, decrypting or signing" - " Creative firmwares." << std::endl - << "Version " << VERSION << std::endl - << "Copyright (c) 2007 Rasmus Ry" << std::endl; -} - -void print_help() -{ - print_version(); - std::cout << std::endl - << "Usage: zen_crypt [command] [options]" << std::endl - << std::endl - << " Commands:" << std::endl - << " -h,--help" << std::endl - << " prints this message." << std::endl - << " -s,--sign" << std::endl - << " signs a given input file." << std::endl - << " -v,--verify" << std::endl - << " verifies a signed input file." << std::endl - << " -e,--encrypt" << std::endl - << " encrypts a given input file." << std::endl - << " -d,--decrypt" << std::endl - << " decrypts a given input file." << std::endl - << std::endl - << " Options:" << std::endl - << " -V,--verbose" << std::endl - << " prints verbose messages." << std::endl - << " -b,--big-endian" << std::endl - << " specifies that the input is big-endian, default is" - " little-endian." << std::endl - << " -i,--input [file]" << std::endl - << " specifies the input file." << std::endl - << " -o,--output [file]" << std::endl - << " specifies the output file." << std::endl - << " -m,--mode [CENC|FRESC|TL]" << std::endl - << " specifies which algorithm to use." << std::endl - << " -k,--key [player|key]" << std::endl - << " specifies which key to use." << std::endl - << std::endl - ; - std::cout << " Players:" << std::endl; - for (int i = 0; players[i].name != NULL; i++) - { - std::cout << " " << players[i].name; - if (!i) - std::cout << " (default)"; - std::cout << std::endl; - } -} - -size_t find_null_signature(shared::bytes& data) -{ - size_t index = data.size(); - if (index < (20 + 8 + 7)) - return 0; - index -= 20 + 8; - for (int i = 0; i < 7; i++) - { - if (*(dword*)&data[index-i] == 'NULL' || - *(dword*)&data[index-i] == 'LLUN') - { - return index-i; - } - } - return 0; -} - - -bool sign(shared::bytes& data, player_info_t* pi, const std::string& file, - bool verbose) -{ - if (verbose) - std::cout << "[*] Checking for the presence of an existing" - " NULL signature..." << std::endl; - size_t index = find_null_signature(data); - if (index) - { - if (verbose) - std::cout << "[*] Found NULL signature at: " - << std::hex << index << std::endl; - - if (verbose) - std::cout << "[*] Computing digest..." << std::endl; - - shared::bytes digest(20); - if (!zen::hmac_sha1_calc((const byte*)pi->null_key, - strlen(pi->null_key)+1, &data[0], index, - &digest[0], NULL)) - { - std::cerr << "Failed to compute digest." << std::endl; - return false; - } - - if (verbose) - std::cout << "[*] Writing file data..." << std::endl; - - if (!shared::write_file(file, data, true)) - { - std::cerr << "Failed to write file data." << std::endl; - return false; - } - - if (verbose) - std::cout << "[*] Writing digest data..." << std::endl; - - if (!shared::write_file(file, digest, false, index+8)) - { - std::cerr << "Failed to write digest data." << std::endl; - return false; - } - } - else - { - if (verbose) - std::cout << "[*] Computing digest..." << std::endl; - - shared::bytes signature(20+8); - if (!zen::hmac_sha1_calc((const byte*)pi->null_key, - strlen(pi->null_key)+1, &data[0], data.size(), - &signature[8], NULL)) - { - std::cerr << "Failed to compute digest." << std::endl; - return false; - } - - - zen::firmware_header_t header = {'NULL', 20}; - if (pi->big_endian) - { - header.tag = shared::swap(header.tag); - header.size = shared::swap(header.size); - } - memcpy(&signature[0], &header, sizeof(zen::firmware_header_t)); - - if (verbose) - std::cout << "[*] Writing file data..." << std::endl; - - if (!shared::write_file(file, data, true)) - { - std::cerr << "Failed to write file data." << std::endl; - return false; - } - - if (verbose) - std::cout << "[*] Writing signature data..." << std::endl; - - if (!shared::write_file(file, signature, false, data.size())) - { - std::cerr << "Failed to write signature data." << std::endl; - return false; - } - - if (verbose) - std::cout << "[*] Ensuring that the file length is" - " 32-bit aligned..." << std::endl; - - int length = data.size() + signature.size(); - int align = length % 4; - if (align) - { - shared::bytes padding(4 - align, 0); - if (!shared::write_file(file, padding, false, length)) - { - std::cerr << "Failed to write padding data." << std::endl; - return false; - } - } - } - - return true; -} - -bool verify(shared::bytes& data, player_info_t* pi, bool verbose) -{ - if (verbose) - std::cout << "[*] Checking for the presence of an existing" - " NULL signature..." << std::endl; - size_t index = find_null_signature(data); - if (!index) - { - std::cerr << "No NULL signature present in the input file." - << std::endl; - return false; - } - if (verbose) - std::cout << "[*] Found NULL signature at: " - << std::hex << index << std::endl; - - if (verbose) - std::cout << "[*] Computing digest..." << std::endl; - - byte digest[20]; - if (!zen::hmac_sha1_calc((const byte*)pi->null_key, strlen(pi->null_key)+1, - &data[0], index, digest, NULL)) - { - std::cerr << "Failed to compute digest." << std::endl; - return false; - } - - if (verbose) - std::cout << "[*] Verifying NULL signature digest..." << std::endl; - - if (memcmp(&digest[0], &data[index+8], 20)) - { - std::cerr << "The NULL signature contains an incorrect digest." - << std::endl; - return false; - } - - return true; -} - -bool encrypt(shared::bytes& data, int mode, player_info_t* pi, - const std::string& file, bool verbose) -{ - if (mode == mode_cenc) - { - if (verbose) - std::cout << "[*] Encoding input file..." << std::endl; - - shared::bytes outbuf(data.size() * 2); - int len = zen::cenc_encode(&data[0], data.size(), &outbuf[0], outbuf.size()); - if (!len) - { - std::cerr << "Failed to encode the input file." << std::endl; - return false; - } - - if (verbose) - std::cout << "[*] Writing decoded length to file..." << std::endl; - - shared::bytes length(sizeof(dword)); - *(dword*)&length[0] = pi->big_endian ? shared::swap(data.size()) : data.size(); - if (!shared::write_file(file, length, true)) - { - std::cerr << "Failed to write the file data." << std::endl; - return false; - } - - if (verbose) - std::cout << "[*] Writing file data..." << std::endl; - - if (!shared::write_file(file, outbuf, sizeof(dword), len)) - { - std::cerr << "Failed to write the file data." << std::endl; - return false; - } - } - else if (mode == mode_fresc) - { - std::cerr << "FRESC mode is not supported." << std::endl; - return false; - } - else if (mode == mode_tl) - { - if (verbose) - std::cout << "[*] Encoding input file..." << std::endl; - - shared::bytes outbuf(data.size() * 2); - *(dword*)&outbuf[0] = pi->big_endian ? shared::swap(data.size()) : data.size(); - int len = zen::cenc_encode(&data[0], data.size(), - &outbuf[sizeof(dword)], - outbuf.size()-sizeof(dword)); - if (!len) - { - std::cerr << "Failed to encode the input file." << std::endl; - return false; - } - len += sizeof(dword); - - int align = len % 8; - align = align ? (8 - align) : 0; - len += align; - - if (verbose) - std::cout << "[*] Encrypting encoded data..." << std::endl; - - dword iv[2] = {0, shared::swap(len)}; - if (!zen::bf_cbc_encrypt((const byte*)pi->tl_key, strlen(pi->tl_key)+1, - &outbuf[0], len, (const byte*)iv)) - { - std::cerr << "Failed to decrypt the input file." << std::endl; - return false; - } - - if (verbose) - std::cout << "[*] Writing file data..." << std::endl; - - if (!shared::write_file(file, outbuf, true, 0, len)) - { - std::cerr << "Failed to save the output file." << std::endl; - return false; - } - } - else - { - std::cerr << "Invalid mode specified." << std::endl; - return false; - } - - return true; -} - -bool decrypt(shared::bytes& data, int mode, player_info_t* pi, - const std::string& file, bool verbose) -{ - if (mode == mode_cenc) - { - dword length = *(dword*)&data[0]; - length = pi->big_endian ? shared::swap(length) : length; - - if (verbose) - std::cout << "[*] Decoding input file..." << std::endl; - - shared::bytes outbuf(length); - if (!zen::cenc_decode(&data[sizeof(dword)], data.size()-sizeof(dword), - &outbuf[0], length)) - { - std::cerr << "Failed to decode the input file." << std::endl; - return false; - } - - if (verbose) - std::cout << "[*] Writing file data..." << std::endl; - - if (!shared::write_file(file, outbuf, true)) - { - std::cerr << "Failed to write the file data." << std::endl; - return false; - } - } - else if (mode == mode_fresc) - { - if (verbose) - std::cout << "[*] Decrypting input file..." << std::endl; - - dword iv[2] = {shared::swap(data.size()), 0}; - if (!zen::bf_cbc_decrypt((const byte*)pi->fresc_key, - strlen(pi->fresc_key)+1, &data[0], - data.size(), (const byte*)iv)) - { - std::cerr << "Failed to decrypt the input file." << std::endl; - return false; - } - - if (verbose) - std::cout << "[*] Writing file data..." << std::endl; - - if (!shared::write_file(file, data, true)) - { - std::cerr << "Failed to save the output file." << std::endl; - return false; - } - } - else if (mode == mode_tl) - { - if (verbose) - std::cout << "[*] Decrypting input file..." << std::endl; - - dword iv[2] = {0, shared::swap(data.size())}; - if (!zen::bf_cbc_decrypt((const byte*)pi->tl_key, strlen(pi->tl_key)+1, - &data[0], data.size(), (const byte*)iv)) - { - std::cerr << "Failed to decrypt the input file." << std::endl; - return false; - } - - dword length = *(dword*)&data[0]; - length = pi->big_endian ? shared::swap(length) : length; - if (length > (data.size() * 3)) - { - std::cerr << "Decrypted length is unexpectedly large: " - << std::hex << length - << " Check the endian and key settings." << std::endl; - return false; - } - - if (verbose) - std::cout << "[*] Decoding decrypted data..." << std::endl; - - shared::bytes outbuf(length); - if (!zen::cenc_decode(&data[sizeof(dword)], data.size()-sizeof(dword), - &outbuf[0], length)) - { - std::cerr << "Failed to decode the input file." << std::endl; - return false; - } - - if (verbose) - std::cout << "[*] Writing file data..." << std::endl; - - if (!shared::write_file(file, outbuf, true)) - { - std::cerr << "Failed to save the output file." << std::endl; - return false; - } - } - else - { - std::cerr << "Invalid mode specified." << std::endl; - return false; - } - - return true; -} - -int process_arguments(int argc, char*argv[]) -{ - //-------------------------------------------------------------------- - // Parse input variables. - //-------------------------------------------------------------------- - - GetPot cl(argc, argv); - if (cl.size() == 1 || cl.search(2, "-h", "--help")) - { - print_help(); - return 1; - } - - int command = cmd_none; - if (cl.search(2, "-s", "--sign")) - command = cmd_sign; - else if (cl.search(2, "-v", "--verify")) - command = cmd_verify; - else if (cl.search(2, "-e", "--encrypt")) - command = cmd_encrypt; - else if (cl.search(2, "-d", "--decrypt")) - command = cmd_decrypt; - - if (command == cmd_none) - { - std::cerr << "No command specified." << std::endl; - return 2; - } - - int mode = mode_none; - if (command == cmd_encrypt || command == cmd_decrypt) - { - if (!cl.search(2, "-m", "--mode")) - { - std::cerr << "The specified command requires that" - " a mode is specified." - << std::endl; - return 3; - } - std::string name = cl.next(""); - if (!name.empty()) - { - if (!stricmp(name.c_str(), "CENC")) - mode = mode_cenc; - else if (!stricmp(name.c_str(), "FRESC")) - mode = mode_fresc; - else if (!stricmp(name.c_str(), "TL")) - mode = mode_tl; - } - if (mode == mode_none) - { - std::cerr << "Invalid mode specified." << std::endl; - return 4; - } - } - - bool verbose = false; - if (cl.search(2, "-V", "--verbose")) - verbose = true; - - bool big_endian = false; - if (cl.search(2, "-b", "--big-endian")) - big_endian = true; - - std::string infile; - if (cl.search(2, "-i", "--input")) - infile = cl.next(""); - if (infile.empty()) - { - std::cerr << "An input file must be specified." << std::endl; - return 5; - } - - std::string outfile = infile; - if (cl.search(2, "-o", "--output")) - outfile = cl.next(outfile.c_str()); - - player_info_t* pi = &players[0]; - std::string key; - if (cl.search(2, "-k", "--key")) - key = cl.next(""); - if (!key.empty()) - { - player_info_t* pitmp = find_player_info(key); - if (pitmp != NULL) - pi = pitmp; - else - { - static player_info_t player = { - NULL, key.c_str(), key.c_str(), key.c_str(), false - }; - pi = &player; - } - } - if (big_endian) - pi->big_endian = big_endian; - - - //-------------------------------------------------------------------- - // Read the input file. - //-------------------------------------------------------------------- - - if (verbose) - std::cout << "[*] Reading input file..." << std::endl; - - shared::bytes buffer; - if (!shared::read_file(infile, buffer)) - { - std::cerr << "Failed to read the input file." << std::endl; - return 6; - } - - - //-------------------------------------------------------------------- - // Process the input file. - //-------------------------------------------------------------------- - - switch (command) - { - case cmd_sign: - if (verbose) - std::cout << "[*] Signing input file..." << std::endl; - if (!sign(buffer, pi, outfile, verbose)) - return 7; - std::cout << "Successfully signed the input file." << std::endl; - break; - case cmd_verify: - if (verbose) - std::cout << "[*] Verifying signature on input file..." - << std::endl; - if (!verify(buffer, pi, verbose)) - return 8; - std::cout << "Successfully verified the input file signature." - << std::endl; - break; - case cmd_encrypt: - if (verbose) - std::cout << "[*] Encrypting input file..." << std::endl; - if (!encrypt(buffer, mode, pi, outfile, verbose)) - return 9; - std::cout << "Successfully encrypted the input file." << std::endl; - break; - case cmd_decrypt: - if (verbose) - std::cout << "[*] Decrypting input file..." << std::endl; - if (!decrypt(buffer, mode, pi, outfile, verbose)) - return 10; - std::cout << "Successfully decrypted the input file." << std::endl; - break; - }; - - return 0; -} - -int main(int argc, char* argv[]) -{ - try - { - return process_arguments(argc, argv); - } - catch (const std::exception& xcpt) - { - std::cerr << "Exception caught: " << xcpt.what() << std::endl; - return -1; - } - catch (...) - { - std::cerr << "Unknown exception caught." << std::endl; - return -2; - } - return -3; -} +/* zenutils - Utilities for working with creative firmwares. + * Copyright 2007 (c) Rasmus Ry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + + +namespace { +enum command_t +{ + cmd_none = 0, + cmd_sign, + cmd_verify, + cmd_encrypt, + cmd_decrypt +}; + +enum mode_t +{ + mode_none = 0, + mode_cenc, + mode_fresc, + mode_tl +}; + +struct player_info_t +{ + const char* name; + const char* null_key; // HMAC-SHA1 key + const char* fresc_key; // BlowFish key + const char* tl_key; // BlowFish key + bool big_endian; +}; +}; //namespace + + +static const char VERSION[] = "0.1"; + +static const char null_key_v1[] = "CTL:N0MAD|PDE0.SIGN."; +static const char null_key_v2[] = "CTL:N0MAD|PDE0.DPMP."; + +static const char fresc_key[] = "Copyright (C) CTL. -" + " zN0MAD iz v~p0wderful!"; + +static const char tl_zvm_key[] = "1sN0TM3D az u~may th1nk*" + "Creative Zen Vision:M"; +static const char tl_zvw_key[] = "1sN0TM3D az u~may th1nk*" + "Creative ZEN Vision W"; +static const char tl_zm_key[] = "1sN0TM3D az u~may th1nk*" + "Creative Zen Micro"; +static const char tl_zmp_key[] = "1sN0TM3D az u~may th1nk*" + "Creative Zen MicroPhoto"; +static const char tl_zs_key[] = "1sN0TM3D az u~may th1nk*" + "Creative Zen Sleek"; +static const char tl_zsp_key[] = "1sN0TM3D az u~may th1nk*" + "Creative Zen Sleek Photo"; +static const char tl_zt_key[] = "1sN0TM3D az u~may th1nk*" + "Creative Zen Touch"; +static const char tl_zx_key[] = "1sN0TM3D az u~may th1nk*" + "NOMAD Jukebox Zen Xtra"; + +player_info_t players[] = { + {"Vision:M", null_key_v2, fresc_key, tl_zvm_key, false}, + {"Vision W", null_key_v2, fresc_key, tl_zvw_key, false}, + {"Micro", null_key_v1, fresc_key, tl_zm_key, true}, + {"MicroPhoto", null_key_v1, fresc_key, tl_zmp_key, true}, + {"Sleek", null_key_v1, fresc_key, tl_zs_key, true}, + {"SleekPhoto", null_key_v1, fresc_key, tl_zsp_key, true}, + {"Touch", null_key_v1, fresc_key, tl_zt_key, true}, + {"Xtra", null_key_v1, fresc_key, tl_zx_key, true}, + {NULL, NULL, NULL, NULL, false} +}; + + +player_info_t* find_player_info(std::string player) +{ + for (int i = 0; players[i].name != NULL; i++) + { + if (!stricmp(players[i].name, player.c_str())) + { + return &players[i]; + } + } + return NULL; +} + +void print_version() +{ + std::cout + << "zen_crypt - A utility for encrypting, decrypting or signing" + " Creative firmwares." << std::endl + << "Version " << VERSION << std::endl + << "Copyright (c) 2007 Rasmus Ry" << std::endl; +} + +void print_help() +{ + print_version(); + std::cout << std::endl + << "Usage: zen_crypt [command] [options]" << std::endl + << std::endl + << " Commands:" << std::endl + << " -h,--help" << std::endl + << " prints this message." << std::endl + << " -s,--sign" << std::endl + << " signs a given input file." << std::endl + << " -v,--verify" << std::endl + << " verifies a signed input file." << std::endl + << " -e,--encrypt" << std::endl + << " encrypts a given input file." << std::endl + << " -d,--decrypt" << std::endl + << " decrypts a given input file." << std::endl + << std::endl + << " Options:" << std::endl + << " -V,--verbose" << std::endl + << " prints verbose messages." << std::endl + << " -b,--big-endian" << std::endl + << " specifies that the input is big-endian, default is" + " little-endian." << std::endl + << " -i,--input [file]" << std::endl + << " specifies the input file." << std::endl + << " -o,--output [file]" << std::endl + << " specifies the output file." << std::endl + << " -m,--mode [CENC|FRESC|TL]" << std::endl + << " specifies which algorithm to use." << std::endl + << " -k,--key [player|key]" << std::endl + << " specifies which key to use." << std::endl + << std::endl + ; + std::cout << " Players:" << std::endl; + for (int i = 0; players[i].name != NULL; i++) + { + std::cout << " " << players[i].name; + if (!i) + std::cout << " (default)"; + std::cout << std::endl; + } +} + +size_t find_null_signature(shared::bytes& data) +{ + size_t index = data.size(); + if (index < (20 + 8 + 7)) + return 0; + index -= 20 + 8; + for (int i = 0; i < 7; i++) + { + if (*(dword*)&data[index-i] == 'NULL' || + *(dword*)&data[index-i] == 'LLUN') + { + return index-i; + } + } + return 0; +} + + +bool sign(shared::bytes& data, player_info_t* pi, const std::string& file, + bool verbose) +{ + if (verbose) + std::cout << "[*] Checking for the presence of an existing" + " NULL signature..." << std::endl; + size_t index = find_null_signature(data); + if (index) + { + if (verbose) + std::cout << "[*] Found NULL signature at: " + << std::hex << index << std::endl; + + if (verbose) + std::cout << "[*] Computing digest..." << std::endl; + + shared::bytes digest(20); + if (!zen::hmac_sha1_calc((const byte*)pi->null_key, + strlen(pi->null_key)+1, &data[0], index, + &digest[0], NULL)) + { + std::cerr << "Failed to compute digest." << std::endl; + return false; + } + + if (verbose) + std::cout << "[*] Writing file data..." << std::endl; + + if (!shared::write_file(file, data, true)) + { + std::cerr << "Failed to write file data." << std::endl; + return false; + } + + if (verbose) + std::cout << "[*] Writing digest data..." << std::endl; + + if (!shared::write_file(file, digest, false, index+8)) + { + std::cerr << "Failed to write digest data." << std::endl; + return false; + } + } + else + { + if (verbose) + std::cout << "[*] Computing digest..." << std::endl; + + shared::bytes signature(20+8); + if (!zen::hmac_sha1_calc((const byte*)pi->null_key, + strlen(pi->null_key)+1, &data[0], data.size(), + &signature[8], NULL)) + { + std::cerr << "Failed to compute digest." << std::endl; + return false; + } + + + zen::firmware_header_t header = {'NULL', 20}; + if (pi->big_endian) + { + header.tag = shared::swap(header.tag); + header.size = shared::swap(header.size); + } + memcpy(&signature[0], &header, sizeof(zen::firmware_header_t)); + + if (verbose) + std::cout << "[*] Writing file data..." << std::endl; + + if (!shared::write_file(file, data, true)) + { + std::cerr << "Failed to write file data." << std::endl; + return false; + } + + if (verbose) + std::cout << "[*] Writing signature data..." << std::endl; + + if (!shared::write_file(file, signature, false, data.size())) + { + std::cerr << "Failed to write signature data." << std::endl; + return false; + } + + if (verbose) + std::cout << "[*] Ensuring that the file length is" + " 32-bit aligned..." << std::endl; + + int length = data.size() + signature.size(); + int align = length % 4; + if (align) + { + shared::bytes padding(4 - align, 0); + if (!shared::write_file(file, padding, false, length)) + { + std::cerr << "Failed to write padding data." << std::endl; + return false; + } + } + } + + return true; +} + +bool verify(shared::bytes& data, player_info_t* pi, bool verbose) +{ + if (verbose) + std::cout << "[*] Checking for the presence of an existing" + " NULL signature..." << std::endl; + size_t index = find_null_signature(data); + if (!index) + { + std::cerr << "No NULL signature present in the input file." + << std::endl; + return false; + } + if (verbose) + std::cout << "[*] Found NULL signature at: " + << std::hex << index << std::endl; + + if (verbose) + std::cout << "[*] Computing digest..." << std::endl; + + byte digest[20]; + if (!zen::hmac_sha1_calc((const byte*)pi->null_key, strlen(pi->null_key)+1, + &data[0], index, digest, NULL)) + { + std::cerr << "Failed to compute digest." << std::endl; + return false; + } + + if (verbose) + std::cout << "[*] Verifying NULL signature digest..." << std::endl; + + if (memcmp(&digest[0], &data[index+8], 20)) + { + std::cerr << "The NULL signature contains an incorrect digest." + << std::endl; + return false; + } + + return true; +} + +bool encrypt(shared::bytes& data, int mode, player_info_t* pi, + const std::string& file, bool verbose) +{ + if (mode == mode_cenc) + { + if (verbose) + std::cout << "[*] Encoding input file..." << std::endl; + + shared::bytes outbuf(data.size() * 2); + int len = zen::cenc_encode(&data[0], data.size(), &outbuf[0], outbuf.size()); + if (!len) + { + std::cerr << "Failed to encode the input file." << std::endl; + return false; + } + + if (verbose) + std::cout << "[*] Writing decoded length to file..." << std::endl; + + shared::bytes length(sizeof(dword)); + *(dword*)&length[0] = pi->big_endian ? shared::swap(data.size()) : data.size(); + if (!shared::write_file(file, length, true)) + { + std::cerr << "Failed to write the file data." << std::endl; + return false; + } + + if (verbose) + std::cout << "[*] Writing file data..." << std::endl; + + if (!shared::write_file(file, outbuf, sizeof(dword), len)) + { + std::cerr << "Failed to write the file data." << std::endl; + return false; + } + } + else if (mode == mode_fresc) + { + std::cerr << "FRESC mode is not supported." << std::endl; + return false; + } + else if (mode == mode_tl) + { + if (verbose) + std::cout << "[*] Encoding input file..." << std::endl; + + shared::bytes outbuf(data.size() * 2); + *(dword*)&outbuf[0] = pi->big_endian ? shared::swap(data.size()) : data.size(); + int len = zen::cenc_encode(&data[0], data.size(), + &outbuf[sizeof(dword)], + outbuf.size()-sizeof(dword)); + if (!len) + { + std::cerr << "Failed to encode the input file." << std::endl; + return false; + } + len += sizeof(dword); + + int align = len % 8; + align = align ? (8 - align) : 0; + len += align; + + if (verbose) + std::cout << "[*] Encrypting encoded data..." << std::endl; + + dword iv[2] = {0, shared::swap(len)}; + if (!zen::bf_cbc_encrypt((const byte*)pi->tl_key, strlen(pi->tl_key)+1, + &outbuf[0], len, (const byte*)iv)) + { + std::cerr << "Failed to decrypt the input file." << std::endl; + return false; + } + + if (verbose) + std::cout << "[*] Writing file data..." << std::endl; + + if (!shared::write_file(file, outbuf, true, 0, len)) + { + std::cerr << "Failed to save the output file." << std::endl; + return false; + } + } + else + { + std::cerr << "Invalid mode specified." << std::endl; + return false; + } + + return true; +} + +bool decrypt(shared::bytes& data, int mode, player_info_t* pi, + const std::string& file, bool verbose) +{ + if (mode == mode_cenc) + { + dword length = *(dword*)&data[0]; + length = pi->big_endian ? shared::swap(length) : length; + + if (verbose) + std::cout << "[*] Decoding input file..." << std::endl; + + shared::bytes outbuf(length); + if (!zen::cenc_decode(&data[sizeof(dword)], data.size()-sizeof(dword), + &outbuf[0], length)) + { + std::cerr << "Failed to decode the input file." << std::endl; + return false; + } + + if (verbose) + std::cout << "[*] Writing file data..." << std::endl; + + if (!shared::write_file(file, outbuf, true)) + { + std::cerr << "Failed to write the file data." << std::endl; + return false; + } + } + else if (mode == mode_fresc) + { + if (verbose) + std::cout << "[*] Decrypting input file..." << std::endl; + + dword iv[2] = {shared::swap(data.size()), 0}; + if (!zen::bf_cbc_decrypt((const byte*)pi->fresc_key, + strlen(pi->fresc_key)+1, &data[0], + data.size(), (const byte*)iv)) + { + std::cerr << "Failed to decrypt the input file." << std::endl; + return false; + } + + if (verbose) + std::cout << "[*] Writing file data..." << std::endl; + + if (!shared::write_file(file, data, true)) + { + std::cerr << "Failed to save the output file." << std::endl; + return false; + } + } + else if (mode == mode_tl) + { + if (verbose) + std::cout << "[*] Decrypting input file..." << std::endl; + + dword iv[2] = {0, shared::swap(data.size())}; + if (!zen::bf_cbc_decrypt((const byte*)pi->tl_key, strlen(pi->tl_key)+1, + &data[0], data.size(), (const byte*)iv)) + { + std::cerr << "Failed to decrypt the input file." << std::endl; + return false; + } + + dword length = *(dword*)&data[0]; + length = pi->big_endian ? shared::swap(length) : length; + if (length > (data.size() * 3)) + { + std::cerr << "Decrypted length is unexpectedly large: " + << std::hex << length + << " Check the endian and key settings." << std::endl; + return false; + } + + if (verbose) + std::cout << "[*] Decoding decrypted data..." << std::endl; + + shared::bytes outbuf(length); + if (!zen::cenc_decode(&data[sizeof(dword)], data.size()-sizeof(dword), + &outbuf[0], length)) + { + std::cerr << "Failed to decode the input file." << std::endl; + return false; + } + + if (verbose) + std::cout << "[*] Writing file data..." << std::endl; + + if (!shared::write_file(file, outbuf, true)) + { + std::cerr << "Failed to save the output file." << std::endl; + return false; + } + } + else + { + std::cerr << "Invalid mode specified." << std::endl; + return false; + } + + return true; +} + +int process_arguments(int argc, char*argv[]) +{ + //-------------------------------------------------------------------- + // Parse input variables. + //-------------------------------------------------------------------- + + GetPot cl(argc, argv); + if (cl.size() == 1 || cl.search(2, "-h", "--help")) + { + print_help(); + return 1; + } + + int command = cmd_none; + if (cl.search(2, "-s", "--sign")) + command = cmd_sign; + else if (cl.search(2, "-v", "--verify")) + command = cmd_verify; + else if (cl.search(2, "-e", "--encrypt")) + command = cmd_encrypt; + else if (cl.search(2, "-d", "--decrypt")) + command = cmd_decrypt; + + if (command == cmd_none) + { + std::cerr << "No command specified." << std::endl; + return 2; + } + + int mode = mode_none; + if (command == cmd_encrypt || command == cmd_decrypt) + { + if (!cl.search(2, "-m", "--mode")) + { + std::cerr << "The specified command requires that" + " a mode is specified." + << std::endl; + return 3; + } + std::string name = cl.next(""); + if (!name.empty()) + { + if (!stricmp(name.c_str(), "CENC")) + mode = mode_cenc; + else if (!stricmp(name.c_str(), "FRESC")) + mode = mode_fresc; + else if (!stricmp(name.c_str(), "TL")) + mode = mode_tl; + } + if (mode == mode_none) + { + std::cerr << "Invalid mode specified." << std::endl; + return 4; + } + } + + bool verbose = false; + if (cl.search(2, "-V", "--verbose")) + verbose = true; + + bool big_endian = false; + if (cl.search(2, "-b", "--big-endian")) + big_endian = true; + + std::string infile; + if (cl.search(2, "-i", "--input")) + infile = cl.next(""); + if (infile.empty()) + { + std::cerr << "An input file must be specified." << std::endl; + return 5; + } + + std::string outfile = infile; + if (cl.search(2, "-o", "--output")) + outfile = cl.next(outfile.c_str()); + + player_info_t* pi = &players[0]; + std::string key; + if (cl.search(2, "-k", "--key")) + key = cl.next(""); + if (!key.empty()) + { + player_info_t* pitmp = find_player_info(key); + if (pitmp != NULL) + pi = pitmp; + else + { + static player_info_t player = { + NULL, key.c_str(), key.c_str(), key.c_str(), false + }; + pi = &player; + } + } + if (big_endian) + pi->big_endian = big_endian; + + + //-------------------------------------------------------------------- + // Read the input file. + //-------------------------------------------------------------------- + + if (verbose) + std::cout << "[*] Reading input file..." << std::endl; + + shared::bytes buffer; + if (!shared::read_file(infile, buffer)) + { + std::cerr << "Failed to read the input file." << std::endl; + return 6; + } + + + //-------------------------------------------------------------------- + // Process the input file. + //-------------------------------------------------------------------- + + switch (command) + { + case cmd_sign: + if (verbose) + std::cout << "[*] Signing input file..." << std::endl; + if (!sign(buffer, pi, outfile, verbose)) + return 7; + std::cout << "Successfully signed the input file." << std::endl; + break; + case cmd_verify: + if (verbose) + std::cout << "[*] Verifying signature on input file..." + << std::endl; + if (!verify(buffer, pi, verbose)) + return 8; + std::cout << "Successfully verified the input file signature." + << std::endl; + break; + case cmd_encrypt: + if (verbose) + std::cout << "[*] Encrypting input file..." << std::endl; + if (!encrypt(buffer, mode, pi, outfile, verbose)) + return 9; + std::cout << "Successfully encrypted the input file." << std::endl; + break; + case cmd_decrypt: + if (verbose) + std::cout << "[*] Decrypting input file..." << std::endl; + if (!decrypt(buffer, mode, pi, outfile, verbose)) + return 10; + std::cout << "Successfully decrypted the input file." << std::endl; + break; + }; + + return 0; +} + +int main(int argc, char* argv[]) +{ + try + { + return process_arguments(argc, argv); + } + catch (const std::exception& xcpt) + { + std::cerr << "Exception caught: " << xcpt.what() << std::endl; + return -1; + } + catch (...) + { + std::cerr << "Unknown exception caught." << std::endl; + return -2; + } + return -3; +} -- cgit v1.2.3