From 34f5218d2022631a9820ce1d337b0020ea9b259f Mon Sep 17 00:00:00 2001 From: cuevavirus <53134627+cuevavirus@users.noreply.github.com> Date: Sat, 10 Aug 2019 02:53:41 -0400 Subject: [PATCH 1/7] fix build errors --- .../{FindLibTomCrypt.cmake => FindLIBTOMCRYPT.cmake} | 12 ++++++------ psvpfsparser/F00DKeyEncryptorFactory.cpp | 2 +- psvpfsparser/F00DKeyEncryptorFactory.h | 4 ++-- psvpfsparser/IcvPrimitives.cpp | 2 +- psvpfsparser/SecretGenerator.cpp | 1 + 5 files changed, 11 insertions(+), 10 deletions(-) rename cmake/scripts/{FindLibTomCrypt.cmake => FindLIBTOMCRYPT.cmake} (94%) diff --git a/cmake/scripts/FindLibTomCrypt.cmake b/cmake/scripts/FindLIBTOMCRYPT.cmake similarity index 94% rename from cmake/scripts/FindLibTomCrypt.cmake rename to cmake/scripts/FindLIBTOMCRYPT.cmake index 24778da..02715d8 100644 --- a/cmake/scripts/FindLibTomCrypt.cmake +++ b/cmake/scripts/FindLIBTOMCRYPT.cmake @@ -7,18 +7,18 @@ # LIBTOMCRYPT_INCLUDE_DIRS - The LIBTOMCRYPT include directories # LIBTOMCRYPT_LIBRARIES - The libraries needed to use LIBTOMCRYPT -if(${LIBTOMCRYPT_INCLUDE_DIR}) - set(LIBTOMCRYPT_LIBRARIES ${LIBTOMCRYPT_LIBRARY}) +if(LIBTOMCRYPT_INCLUDE_DIR) + set(LIBTOMCRYPT_INCLUDE_DIRS ${LIBTOMCRYPT_INCLUDE_DIR}) else() find_path(LIBTOMCRYPT_INCLUDE_DIR "tomcrypt.h") - set(LIBTOMCRYPT_LIBRARIES ${LIBTOMCRYPT_LIBRARY}) + set(LIBTOMCRYPT_INCLUDE_DIRS ${LIBTOMCRYPT_INCLUDE_DIR}) endif() -if(${LIBTOMCRYPT_LIBRARY}) - set(LIBTOMCRYPT_INCLUDE_DIRS ${LIBTOMCRYPT_INCLUDE_DIR}) +if(LIBTOMCRYPT_LIBRARY) + set(LIBTOMCRYPT_LIBRARIES ${LIBTOMCRYPT_LIBRARY}) else() find_library(LIBTOMCRYPT_LIBRARY tomcrypt) - set(LIBTOMCRYPT_INCLUDE_DIRS ${LIBTOMCRYPT_INCLUDE_DIR}) + set(LIBTOMCRYPT_LIBRARIES ${LIBTOMCRYPT_LIBRARY}) endif() include(FindPackageHandleStandardArgs) diff --git a/psvpfsparser/F00DKeyEncryptorFactory.cpp b/psvpfsparser/F00DKeyEncryptorFactory.cpp index e3e3f57..d428aac 100644 --- a/psvpfsparser/F00DKeyEncryptorFactory.cpp +++ b/psvpfsparser/F00DKeyEncryptorFactory.cpp @@ -19,7 +19,7 @@ std::shared_ptr F00DKeyEncryptorFactory::create( } template<> -static std::shared_ptr F00DKeyEncryptorFactory::create >(F00DEncryptorTypes type, std::shared_ptr arg) +std::shared_ptr F00DKeyEncryptorFactory::create >(F00DEncryptorTypes type, std::shared_ptr arg) { switch(type) { diff --git a/psvpfsparser/F00DKeyEncryptorFactory.h b/psvpfsparser/F00DKeyEncryptorFactory.h index 66cb045..b4dc9a6 100644 --- a/psvpfsparser/F00DKeyEncryptorFactory.h +++ b/psvpfsparser/F00DKeyEncryptorFactory.h @@ -21,7 +21,7 @@ class F00DKeyEncryptorFactory }; template<> -static std::shared_ptr F00DKeyEncryptorFactory::create(F00DEncryptorTypes type, std::string arg); +std::shared_ptr F00DKeyEncryptorFactory::create(F00DEncryptorTypes type, std::string arg); template<> -static std::shared_ptr F00DKeyEncryptorFactory::create >(F00DEncryptorTypes type, std::shared_ptr arg); \ No newline at end of file +std::shared_ptr F00DKeyEncryptorFactory::create >(F00DEncryptorTypes type, std::shared_ptr arg); \ No newline at end of file diff --git a/psvpfsparser/IcvPrimitives.cpp b/psvpfsparser/IcvPrimitives.cpp index db0a478..e8861fe 100644 --- a/psvpfsparser/IcvPrimitives.cpp +++ b/psvpfsparser/IcvPrimitives.cpp @@ -1,5 +1,5 @@ #include "IcvPrimitives.h" - +#include #include "SceKernelUtilsForDriver.h" int icv_set_hmac_sw(std::shared_ptr cryptops, unsigned char *dst, const unsigned char *key, const unsigned char *src, int size) diff --git a/psvpfsparser/SecretGenerator.cpp b/psvpfsparser/SecretGenerator.cpp index 0fdfacf..ce76d90 100644 --- a/psvpfsparser/SecretGenerator.cpp +++ b/psvpfsparser/SecretGenerator.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "PfsKeys.h" #include "IcvPrimitives.h" From 77558cf87460c773e123d4bb0b53af31637c3db7 Mon Sep 17 00:00:00 2001 From: cuevavirus <53134627+cuevavirus@users.noreply.github.com> Date: Sat, 10 Aug 2019 10:54:07 -0400 Subject: [PATCH 2/7] fix runtime errors --- psvpfsparser/F00DNativeKeyEncryptor.cpp | 8 ++++---- psvpfsparser/PsvPfsParserConfig.cpp | 7 +------ psvpfsparser/psvpfsparser.cpp | 4 +++- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/psvpfsparser/F00DNativeKeyEncryptor.cpp b/psvpfsparser/F00DNativeKeyEncryptor.cpp index 365bcad..37fe7d2 100644 --- a/psvpfsparser/F00DNativeKeyEncryptor.cpp +++ b/psvpfsparser/F00DNativeKeyEncryptor.cpp @@ -52,21 +52,21 @@ int F00DNativeKeyEncryptor::encrypt_key(const unsigned char* key, int key_size, key_size != 0x100) return -1; - std::string keyStr = byte_array_to_string(key, key_size / 8); + std::uint32_t nbytes = key_size / 8; + std::string keyStr = byte_array_to_string(key, nbytes); auto kit = m_keyCache.find(keyStr); if(kit != m_keyCache.end()) { - std::uint32_t nbytes = key_size / 8; string_to_byte_array(kit->second, nbytes, drv_key); return 0; } else { - if(kprx_auth_service_0x50001(key, key_size, drv_key, 0) < 0) + if(kprx_auth_service_0x50001(key, nbytes, drv_key, 0) < 0) return -1; - std::string drv_keyStr = byte_array_to_string(drv_key, key_size / 8); + std::string drv_keyStr = byte_array_to_string(drv_key, nbytes); m_keyCache.insert(std::make_pair(keyStr, drv_keyStr)); diff --git a/psvpfsparser/PsvPfsParserConfig.cpp b/psvpfsparser/PsvPfsParserConfig.cpp index 1aec137..efc1e3b 100644 --- a/psvpfsparser/PsvPfsParserConfig.cpp +++ b/psvpfsparser/PsvPfsParserConfig.cpp @@ -100,12 +100,7 @@ int parse_options(int argc, char* argv[], PsvPfsParserConfig& cfg) f00d_cache = vm[F00D_CACHE_NAME].as(); } - if(f00d_url.empty() && f00d_cache.empty()) - { - std::cout << "Missing option --" << F00D_URL_NAME << " or --" << F00D_CACHE_NAME << std::endl; - return -1; - } - else if(!f00d_url.empty() && !f00d_cache.empty()) + if(!f00d_url.empty() && !f00d_cache.empty()) { std::cout << "Can not use both --" << F00D_URL_NAME << " and --" << F00D_CACHE_NAME << std::endl; return -1; diff --git a/psvpfsparser/psvpfsparser.cpp b/psvpfsparser/psvpfsparser.cpp index baa6bfe..0541f49 100644 --- a/psvpfsparser/psvpfsparser.cpp +++ b/psvpfsparser/psvpfsparser.cpp @@ -77,10 +77,12 @@ std::shared_ptr create_F00D_encryptor(const PsvPfsParserConfi { case F00DEncryptorTypes::file: iF00D = F00DKeyEncryptorFactory::create(cfg.f00d_enc_type, cfg.f00d_arg); + break; case F00DEncryptorTypes::native: iF00D = F00DKeyEncryptorFactory::create(cfg.f00d_enc_type, cryptops); + break; default: - return std::shared_ptr(); + throw std::runtime_error("unexpected F00DEncryptorTypes value"); } return iF00D; From 69632dc918246725e994a5efb82097a5f2ab8bbf Mon Sep 17 00:00:00 2001 From: cuevavirus <53134627+cuevavirus@users.noreply.github.com> Date: Sat, 10 Aug 2019 11:30:11 -0400 Subject: [PATCH 3/7] remove stale code and curl --- README.md | 25 ---- cmake/CMakeLists.txt | 1 - cmake/build.bat | 3 - cmake/build_win32_7.bat | 3 - cmake/build_win32_xp.bat | 3 - cmake/build_win64_7.bat | 3 - cmake/build_win64_xp.bat | 3 - cmake/scripts/ConfigureDependencies.cmake | 25 ---- psvpfsparser/F00DKeyEncryptorFactory.cpp | 3 - psvpfsparser/F00DKeyEncryptorFactory.h | 1 - psvpfsparser/F00DUrlKeyEncryptor.cpp | 162 ---------------------- psvpfsparser/F00DUrlKeyEncryptor.h | 38 ----- psvpfsparser/PsvPfsParserConfig.cpp | 3 - psvpfsparser/cmake/CMakeLists.txt | 5 +- 14 files changed, 1 insertion(+), 277 deletions(-) delete mode 100644 psvpfsparser/F00DUrlKeyEncryptor.cpp delete mode 100644 psvpfsparser/F00DUrlKeyEncryptor.h diff --git a/README.md b/README.md index 5c2c594..912b07b 100644 --- a/README.md +++ b/README.md @@ -131,31 +131,6 @@ You have to set these environment variables for cmake: - LIBTOMCRYPT_INCLUDE_DIR=C:\libtomcrypt\build\include - LIBTOMCRYPT_LIBRARY=C:\libtomcrypt\build\lib\tomcrypt.lib -### curl - -#### Windows (example) -- Direct installation: https://curl.haxx.se/download.html -- Sources: https://github.com/curl/curl - -It is easier to build curl from sources if your are on Windows. By default - it does not have any additional dependencies. -However it looks like Windows binary distribution built with mingw requires openssl binaries: -- libssl-1_1.dll -- libcrypto-1_1.dll - -You have to set these environment variables for cmake: -- CURL_INCLUDE_DIR=C:\Program Files (x86)\CURL\include -- CURL_LIBRARY=C:\Program Files (x86)\CURL\lib\libcurl_imp.lib -#### Ubuntu (example) -You can install curl library with apt-get: - -``` -apt-get install libcurl4-gnutls-dev -``` -or -``` -apt-get install libcurl4-openssl-dev -``` - ### boost #### Windows (example) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index a5a6f77..e8b732a 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -24,7 +24,6 @@ set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/scripts include(scripts/ConfigureDependencies.cmake) configure_boost() -configure_curl() configure_zlib() configure_libtomcrypt() diff --git a/cmake/build.bat b/cmake/build.bat index 9c481d1..25aaf10 100644 --- a/cmake/build.bat +++ b/cmake/build.bat @@ -1,9 +1,6 @@ set BOOST_INCLUDEDIR=N:\svnroot\src\vendor\boost_1_55_0 set BOOST_LIBRARYDIR=N:\svnroot\vendor\boost_1_55_0\vc110\lib -set CURL_INCLUDE_DIR=C:\Program Files (x86)\curl_win7\include -set CURL_LIBRARY=C:\Program Files (x86)\curl_win7\lib\libcurl-d_imp.lib - set ZLIB_INCLUDE_DIR=N:\zlib set ZLIB_LIBRARY=N:\zlib\contrib\vstudio\vc11\x86\ZlibStatDebug\zlibstat.lib diff --git a/cmake/build_win32_7.bat b/cmake/build_win32_7.bat index 1897dde..f95d806 100644 --- a/cmake/build_win32_7.bat +++ b/cmake/build_win32_7.bat @@ -1,9 +1,6 @@ set BOOST_INCLUDEDIR=N:\boost_1_66_0_install\win_7\include\boost-1_66 set BOOST_LIBRARYDIR=N:\boost_1_66_0_install\win_7\lib_32 -set CURL_INCLUDE_DIR=C:\Program Files (x86)\curl_win7\include -set CURL_LIBRARY=C:\Program Files (x86)\curl_win7\lib\libcurl_imp.lib - set ZLIB_INCLUDE_DIR=N:\zlib set ZLIB_LIBRARY=N:\zlib\contrib\vstudio\vc11\x86\ZlibStatRelease\zlibstat.lib diff --git a/cmake/build_win32_xp.bat b/cmake/build_win32_xp.bat index d25d200..024e901 100644 --- a/cmake/build_win32_xp.bat +++ b/cmake/build_win32_xp.bat @@ -1,9 +1,6 @@ set BOOST_INCLUDEDIR=N:\boost_1_66_0_install\win_xp\include\boost-1_66 set BOOST_LIBRARYDIR=N:\boost_1_66_0_install\win_xp\lib_32 -set CURL_INCLUDE_DIR=C:\Program Files (x86)\curl_win_xp\include -set CURL_LIBRARY=C:\Program Files (x86)\curl_win_xp\lib\libcurl_imp.lib - set ZLIB_INCLUDE_DIR=N:\zlib set ZLIB_LIBRARY=N:\zlib\contrib\vstudio\vc11\x86\ZlibStatRelease-WinXP\zlibstat.lib diff --git a/cmake/build_win64_7.bat b/cmake/build_win64_7.bat index 84de263..68b057a 100644 --- a/cmake/build_win64_7.bat +++ b/cmake/build_win64_7.bat @@ -1,9 +1,6 @@ set BOOST_INCLUDEDIR=N:\boost_1_66_0_install\win_7\include\boost-1_66 set BOOST_LIBRARYDIR=N:\boost_1_66_0_install\win_7\lib_64 -set CURL_INCLUDE_DIR=C:\Program Files\curl_win7\include -set CURL_LIBRARY=C:\Program Files\curl_win7\lib\libcurl_imp.lib - set ZLIB_INCLUDE_DIR=N:\zlib set ZLIB_LIBRARY=N:\zlib\contrib\vstudio\vc11\x64\ZlibStatRelease\zlibstat.lib diff --git a/cmake/build_win64_xp.bat b/cmake/build_win64_xp.bat index 4f47089..1eb2536 100644 --- a/cmake/build_win64_xp.bat +++ b/cmake/build_win64_xp.bat @@ -1,9 +1,6 @@ set BOOST_INCLUDEDIR=N:\boost_1_66_0_install\win_xp\include\boost-1_66 set BOOST_LIBRARYDIR=N:\boost_1_66_0_install\win_xp\lib_64 -set CURL_INCLUDE_DIR=C:\Program Files\curl_win_xp\include -set CURL_LIBRARY=C:\Program Files\curl_win_xp\lib\libcurl_imp.lib - set ZLIB_INCLUDE_DIR=N:\zlib set ZLIB_LIBRARY=N:\zlib\contrib\vstudio\vc11\x64\ZlibStatRelease-WinXP\zlibstat.lib diff --git a/cmake/scripts/ConfigureDependencies.cmake b/cmake/scripts/ConfigureDependencies.cmake index 59f5264..a95797a 100644 --- a/cmake/scripts/ConfigureDependencies.cmake +++ b/cmake/scripts/ConfigureDependencies.cmake @@ -26,31 +26,6 @@ endif() endmacro(configure_boost) -#environment variables for configure_curl have to be set -#CURL_INCLUDE_DIR -#CURL_LIBRARY - -macro(configure_curl) - -message("configuring curl") - -if (MSVC) -set(CURL_INCLUDE_DIR "$ENV{CURL_INCLUDE_DIR}") -set(CURL_LIBRARY "$ENV{CURL_LIBRARY}") -endif() - -FIND_PACKAGE(CURL REQUIRED) - -if(CURL_FOUND) -message("Using CURL_VERSION_STRING: ${CURL_VERSION_STRING}") -message("Using CURL_INCLUDE_DIRS: ${CURL_INCLUDE_DIRS}") -message("Using CURL_LIBRARIES: ${CURL_LIBRARIES}") -else() -message("Curl library is not found") -endif() - -endmacro(configure_curl) - macro(configure_zlib) message("configuring zlib") diff --git a/psvpfsparser/F00DKeyEncryptorFactory.cpp b/psvpfsparser/F00DKeyEncryptorFactory.cpp index d428aac..5547e0f 100644 --- a/psvpfsparser/F00DKeyEncryptorFactory.cpp +++ b/psvpfsparser/F00DKeyEncryptorFactory.cpp @@ -1,6 +1,5 @@ #include "F00DKeyEncryptorFactory.h" -#include "F00DUrlKeyEncryptor.h" #include "F00DFileKeyEncryptor.h" #include "F00DNativeKeyEncryptor.h" @@ -9,8 +8,6 @@ std::shared_ptr F00DKeyEncryptorFactory::create( { switch(type) { - //case F00DEncryptorTypes::url: - // return std::make_shared(arg); case F00DEncryptorTypes::file: return std::make_shared(arg); default: diff --git a/psvpfsparser/F00DKeyEncryptorFactory.h b/psvpfsparser/F00DKeyEncryptorFactory.h index b4dc9a6..1be2236 100644 --- a/psvpfsparser/F00DKeyEncryptorFactory.h +++ b/psvpfsparser/F00DKeyEncryptorFactory.h @@ -8,7 +8,6 @@ enum class F00DEncryptorTypes { - url, file, native }; diff --git a/psvpfsparser/F00DUrlKeyEncryptor.cpp b/psvpfsparser/F00DUrlKeyEncryptor.cpp deleted file mode 100644 index c9592ac..0000000 --- a/psvpfsparser/F00DUrlKeyEncryptor.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include "F00DUrlKeyEncryptor.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include "Utils.h" - -F00DUrlKeyEncryptor::F00DUrlKeyEncryptor(const std::string& F00D_url) - : m_F00D_url(F00D_url) -{ -} - -std::string F00DUrlKeyEncryptor::create_url(unsigned const char* key, int key_size) -{ - std::stringstream ss; - - ss << m_F00D_url << "/?key="; - - int nbytes = key_size / 8; - for(int i = 0; i < nbytes; i++) - { - ss << std::setfill('0') << std::setw(2) << std::hex << (int)key[i]; - } - - return ss.str(); -} - -size_t F00DUrlKeyEncryptor::write_callback(char* ptr, size_t size, size_t nmemb, void* userdata) -{ - size_t realsize = size * nmemb; - - F00DUrlKeyEncryptor* inst = (F00DUrlKeyEncryptor*)userdata; - inst->m_response = std::string(ptr); - - return realsize; -} - -int F00DUrlKeyEncryptor::execute_url(std::string url) -{ - CURL *curl; - CURLcode res; - - curl = curl_easy_init(); - if(curl) - { - struct curl_slist *headers=NULL; // init to NULL is important - headers = curl_slist_append(headers, "Accept: application/json"); - headers = curl_slist_append(headers, "Content-Type: application/json"); - headers = curl_slist_append(headers, "charsets: utf-8"); - - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_HTTPGET,1); - - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); - - // Perform the request, res will get the return code - res = curl_easy_perform(curl); - - //clean list - curl_slist_free_all(headers); - - // Check for errors - if(res != CURLE_OK) - { - //fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); - - //it is too time consuming to write a code to throw up an error code from all crypto functions - //much easier to throw an exception - throw std::runtime_error("Unable to get response from F00D service"); - } - - // always cleanup - curl_easy_cleanup(curl); - - return 0; - } - - return -1; -} - -int F00DUrlKeyEncryptor::parse_key_base(unsigned const char* key, unsigned char* dest, int key_size, std::string jkey, std::string jdrv_key) -{ - std::uint32_t nbytes = key_size / 8; - - unsigned char key_check[0x20]; - string_to_byte_array(jkey, nbytes, key_check); - - if(memcmp(key, key_check, nbytes) != 0) - return -1; - - string_to_byte_array(jdrv_key, nbytes, dest); - - m_keyCache.insert(std::make_pair(jkey, jdrv_key)); - - return 0; -} - -int F00DUrlKeyEncryptor::parse_key(unsigned const char* key, unsigned char* dest, int key_size) -{ - std::string json(m_response); - boost::trim(json); - - std::stringstream ss; - ss << json; - - boost::property_tree::ptree pt; - boost::property_tree::read_json(ss, pt); - - std::string jkey = pt.get_child("key").data(); - std::string jdrv_key = pt.get_child("drv_key").data(); - - return parse_key_base(key, dest, key_size, jkey, jdrv_key); -} - -int F00DUrlKeyEncryptor::encrypt_key(unsigned const char* key, int key_size, unsigned char* drv_key) -{ - if(key_size != 0x80 && - // key_size != 0xC0 && //TODO: need to implement padding - key_size != 0x100) - return -1; - - std::string keyStr = byte_array_to_string(key, key_size / 8); - - auto kit = m_keyCache.find(keyStr); - if(kit != m_keyCache.end()) - { - std::uint32_t nbytes = key_size / 8; - string_to_byte_array(kit->second, nbytes, drv_key); - return 0; - } - else - { - std::string url = create_url(key, key_size); - if(execute_url(url) < 0) - return -1; - - if(parse_key(key, drv_key, key_size) < 0) - return -1; - - return 0; - } -} - -void F00DUrlKeyEncryptor::print_cache(std::ostream& os, std::string sep) const -{ - os << "Number of items in cache: " << m_keyCache.size() << std::endl; - - //its ok to print whole cache since we only expect one item anyway - - for(auto& item : m_keyCache) - { - os << item.first << sep << item.second << std::endl; - } -} \ No newline at end of file diff --git a/psvpfsparser/F00DUrlKeyEncryptor.h b/psvpfsparser/F00DUrlKeyEncryptor.h deleted file mode 100644 index 85e3845..0000000 --- a/psvpfsparser/F00DUrlKeyEncryptor.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include - -#include -#include - -#include "IF00DKeyEncryptor.h" - -class F00DUrlKeyEncryptor : public IF00DKeyEncryptor -{ -private: - std::string m_F00D_url; - - std::string m_response; - - std::map m_keyCache; - -public: - F00DUrlKeyEncryptor(const std::string& F00D_url); - -private: - std::string create_url(unsigned const char* key, int key_size); - -private: - static size_t write_callback(char* ptr, size_t size, size_t nmemb, void* userdata); - - int execute_url(std::string url); - -private: - int parse_key_base(unsigned const char* key, unsigned char* dest, int key_size, std::string jkey, std::string jdrv_key); - int parse_key(unsigned const char* key, unsigned char* dest, int key_size); - -public: - int encrypt_key(const unsigned char* key, int key_size, unsigned char* drv_key) override; - - void print_cache(std::ostream& os, std::string sep = "\t") const override; -}; \ No newline at end of file diff --git a/psvpfsparser/PsvPfsParserConfig.cpp b/psvpfsparser/PsvPfsParserConfig.cpp index efc1e3b..e0cc522 100644 --- a/psvpfsparser/PsvPfsParserConfig.cpp +++ b/psvpfsparser/PsvPfsParserConfig.cpp @@ -108,9 +108,6 @@ int parse_options(int argc, char* argv[], PsvPfsParserConfig& cfg) if(!f00d_url.empty()) { - //cfg.f00d_enc_type = F00DEncryptorTypes::url; - //cfg.f00d_arg = f00d_url; - std::cout << "Warning. Option " << F00D_URL_NAME << " is deprecated. Switching to native implementation of F00D" << std::endl; cfg.f00d_enc_type = F00DEncryptorTypes::native; diff --git a/psvpfsparser/cmake/CMakeLists.txt b/psvpfsparser/cmake/CMakeLists.txt index 7a33a82..35b0430 100644 --- a/psvpfsparser/cmake/CMakeLists.txt +++ b/psvpfsparser/cmake/CMakeLists.txt @@ -4,8 +4,6 @@ project (${PROJECT}) message(${PROJECT}) FILE (GLOB F00D_FILES "../IF00DKeyEncryptor.h" - "../F00DUrlKeyEncryptor.h" - "../F00DUrlKeyEncryptor.cpp" "../F00DFileKeyEncryptor.h" "../F00DFileKeyEncryptor.cpp" "../F00DKeyEncryptorFactory.h" @@ -82,12 +80,11 @@ set_property(TARGET ${PROJECT} PROPERTY FOLDER "executables") set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/output/${CMAKE_BUILD_TYPE}") install(TARGETS ${PROJECT} RUNTIME DESTINATION bin) -target_link_libraries (${PROJECT} ${Boost_LIBRARIES} ${CURL_LIBRARIES} libzRIF libb64 ${ZLIB_LIBRARIES} ${LIBTOMCRYPT_LIBRARIES}) +target_link_libraries (${PROJECT} ${Boost_LIBRARIES} libzRIF libb64 ${ZLIB_LIBRARIES} ${LIBTOMCRYPT_LIBRARIES}) include_directories(..) include_directories(../..) include_directories(${Boost_INCLUDE_DIRS}) -include_directories(${CURL_INCLUDE_DIRS}) include_directories(${ZLIB_INCLUDE_DIRS}) include_directories(${LIBTOMCRYPT_INCLUDE_DIRS}) From acc9280158afc4da776493e4d60df2eafb3c751d Mon Sep 17 00:00:00 2001 From: cuevavirus <53134627+cuevavirus@users.noreply.github.com> Date: Tue, 20 Aug 2019 21:00:15 -0400 Subject: [PATCH 4/7] fix wrong sce_sys exclusion see https://github.com/motoharu-gosuto/psvpfstools/issues/22 some titles include a second sce_sys directory containing pfs encrypted files, but they were being excluded by a filter meant to exclude the inner sce_sys directories of whole addcont directory decryption. e.g. PCSG01136/savedata/sce_sys/param.sfo was being excluded by a filter meant to exclude /<addcont id>/sce_sys --- psvpfsparser/Utils.cpp | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/psvpfsparser/Utils.cpp b/psvpfsparser/Utils.cpp index 3e80ac9..a981799 100644 --- a/psvpfsparser/Utils.cpp +++ b/psvpfsparser/Utils.cpp @@ -65,35 +65,28 @@ void getFileListNoPfs(boost::filesystem::path root_path, std::set<boost::filesys const boost::filesystem::path cp = (*i); //skip paths that are not included in files.db + //i.nopush(true) will skip recursion into directory //skip pfs directory - if(boost::starts_with(cp, (root_path / boost::filesystem::path("sce_pfs")))) + if(cp.filename() == boost::filesystem::path("sce_pfs")) { + i.no_push(true); continue; + } //skip packages - if(boost::starts_with(cp, (root_path / boost::filesystem::path("sce_sys") / boost::filesystem::path("package")))) - continue; - - //skip pfs inside sce_pfs (for ADDCONT) - if(boost::ends_with(cp, boost::filesystem::path("sce_pfs"))) - continue; - - //skip pfs inside sce_pfs (for ADDCONT) - if(boost::ends_with(cp, boost::filesystem::path("sce_pfs") / boost::filesystem::path("files.db"))) - continue; - - //skip pfs inside sce_pfs (for ADDCONT) - if(boost::ends_with(cp, boost::filesystem::path("sce_pfs") / boost::filesystem::path("unicv.db"))) + if(cp == (root_path / boost::filesystem::path("sce_sys") / boost::filesystem::path("package"))) { + i.no_push(true); continue; + } //skip pfs inside sce_sys (for ADDCONT) - if(boost::ends_with(cp, boost::filesystem::path("sce_sys"))) - { - if(cp != root_path / boost::filesystem::path("sce_sys")) - continue; + if(boost::ends_with(cp, boost::filesystem::path("sce_sys")) && + cp != root_path / boost::filesystem::path("sce_sys") && + boost::filesystem::exists(cp / boost::filesystem::path("keystone"))) { + i.no_push(true); + continue; } - //add file or directory if(boost::filesystem::is_directory(cp)) directories.insert(boost::filesystem::path(cp.generic_string())); //recreate from generic string to normalize slashes From 435d760262238c77fb7dddae34fde3db00ecab15 Mon Sep 17 00:00:00 2001 From: cuevavirus <53134627+cuevavirus@users.noreply.github.com> Date: Tue, 20 Aug 2019 22:56:42 -0400 Subject: [PATCH 5/7] fix wrong destination path see https://github.com/motoharu-gosuto/psvpfstools/issues/27 --- psvpfsparser/Utils.cpp | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/psvpfsparser/Utils.cpp b/psvpfsparser/Utils.cpp index a981799..6557ff1 100644 --- a/psvpfsparser/Utils.cpp +++ b/psvpfsparser/Utils.cpp @@ -96,6 +96,11 @@ void getFileListNoPfs(boost::filesystem::path root_path, std::set<boost::filesys } } +boost::filesystem::path source_path_to_dest_path(const boost::filesystem::path& source_root, const boost::filesystem::path& dest_root, const boost::filesystem::path& source_path) { + boost::filesystem::path dest_path = dest_root / boost::filesystem::relative(source_path, source_root); + return boost::filesystem::path(dest_path.generic_string()); +} + //=== @@ -175,11 +180,7 @@ bool sce_junction::open(std::ifstream& in) const bool sce_junction::create_empty_directory(boost::filesystem::path source_root, boost::filesystem::path destination_root) const { //construct new path - std::string old_root = source_root.generic_string(); - std::string new_root = destination_root.generic_string(); - std::string old_path = m_real.generic_string(); - boost::replace_all(old_path, old_root, new_root); - boost::filesystem::path new_path(old_path); + boost::filesystem::path new_path = source_path_to_dest_path(source_root, destination_root, m_real); //create all directories on the way @@ -193,11 +194,7 @@ bool sce_junction::create_empty_directory(boost::filesystem::path source_root, b bool sce_junction::create_empty_file(boost::filesystem::path source_root, boost::filesystem::path destination_root, std::ofstream& outputStream) const { //construct new path - std::string old_root = source_root.generic_string(); - std::string new_root = destination_root.generic_string(); - std::string old_path = m_real.generic_string(); - boost::replace_all(old_path, old_root, new_root); - boost::filesystem::path new_path(old_path); + boost::filesystem::path new_path = source_path_to_dest_path(source_root, destination_root, m_real); boost::filesystem::path new_directory = new_path; new_directory.remove_filename(); @@ -236,11 +233,7 @@ bool sce_junction::create_empty_file(boost::filesystem::path source_root, boost: bool sce_junction::copy_existing_file(boost::filesystem::path source_root, boost::filesystem::path destination_root) const { //construct new path - std::string old_root = source_root.generic_string(); - std::string new_root = destination_root.generic_string(); - std::string old_path = m_real.generic_string(); - boost::replace_all(old_path, old_root, new_root); - boost::filesystem::path new_path(old_path); + boost::filesystem::path new_path = source_path_to_dest_path(source_root, destination_root, m_real); boost::filesystem::path new_directory = new_path; new_directory.remove_filename(); From fb4d9d0109aa2c16ace3c9a514749c844fa6b49f Mon Sep 17 00:00:00 2001 From: cuevavirus <53134627+cuevavirus@users.noreply.github.com> Date: Sat, 24 Aug 2019 14:56:50 -0400 Subject: [PATCH 6/7] handle unexpected data in files.db --- psvpfsparser/FilesDbParser.cpp | 18 ++++++++++++++++-- psvpfsparser/FilesDbParser.h | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/psvpfsparser/FilesDbParser.cpp b/psvpfsparser/FilesDbParser.cpp index 9802bc6..914988d 100644 --- a/psvpfsparser/FilesDbParser.cpp +++ b/psvpfsparser/FilesDbParser.cpp @@ -265,7 +265,7 @@ bool FilesDbParser::validate_header(uint32_t dataSize) return false; } - if(m_header.unk6 != 0xFFFFFFFFFFFFFFFF) + if(m_header.unk6 != 0xFFFFFFFFFFFFFFFF && m_header.unk6 != 0x400) { m_output << "Unexpected unk6" << std::endl; return false; @@ -348,6 +348,16 @@ bool FilesDbParser::parseFilesDb(std::ifstream& inputStream, std::vector<sce_ng_ return false; } + //bad block with error or unknown format + //may occur with: + // PCSE00434 savedata + bool is_bad_block = false; + if (block.header.nFiles > MAX_FILES_IN_BLOCK) + { + is_bad_block = true; + block.header.nFiles = 0; + } + //read file records for(std::uint32_t i = 0; i < block.header.nFiles; i++) { @@ -364,7 +374,11 @@ bool FilesDbParser::parseFilesDb(std::ifstream& inputStream, std::vector<sce_ng_ std::vector<std::uint8_t> unusedData1(nUnusedSize1); inputStream.read((char*)unusedData1.data(), nUnusedSize1); - if(!isZeroVector(unusedData1)) + if (is_bad_block) + { + m_output << "[WARNING] Skipping file headers in block with error or unknown format" << std::endl; + } + else if(!isZeroVector(unusedData1)) { m_output << "Unexpected data instead of padding" << std::endl; return false; diff --git a/psvpfsparser/FilesDbParser.h b/psvpfsparser/FilesDbParser.h index 2d01739..2bd03da 100644 --- a/psvpfsparser/FilesDbParser.h +++ b/psvpfsparser/FilesDbParser.h @@ -43,7 +43,7 @@ struct sce_ng_pfs_header_t std::uint32_t bt_order; // order value of the binary tree - derived from btree_order std::uint32_t root_icv_page_number; // derived from off2pgn or btree_top std::uint32_t files_salt; // first salt value used for key derrivation - std::uint64_t unk6; // is 0xFFFFFFFFFFFFFFFF + std::uint64_t unk6; // is 0xFFFFFFFFFFFFFFFF or rarely may have other unknown value std::uint64_t tailSize; // size of data after this header std::uint64_t total_sz; // is 0 std::uint8_t root_icv[0x14]; // 0x38 hmac-sha1 of (pageSize - 4) of page (pointed by root_icv_page_number) with secret derived from klicensee From 8c93ad5a43df8276fc068f40976c3414cd3bdb6c Mon Sep 17 00:00:00 2001 From: cuevavirus <53134627+cuevavirus@users.noreply.github.com> Date: Sat, 24 Aug 2019 16:02:08 -0400 Subject: [PATCH 7/7] trim sector padding for icv.db pfs files files both encrypted and unencrypted in a icv.db pfs are padded to the nearest sector boundary and must be trimmed after decryption. (a sector is 0x8000 bytes) --- psvpfsparser/PfsFile.cpp | 6 +++++- psvpfsparser/PfsFilesystem.cpp | 2 +- psvpfsparser/Utils.cpp | 13 +++++++++++++ psvpfsparser/Utils.h | 3 +++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/psvpfsparser/PfsFile.cpp b/psvpfsparser/PfsFile.cpp index 3827504..566c1a0 100644 --- a/psvpfsparser/PfsFile.cpp +++ b/psvpfsparser/PfsFile.cpp @@ -147,6 +147,10 @@ int PfsFile::decrypt_icv_file(boost::filesystem::path destination_root) const //do decryption + // icv.db pfs files are padded to the nearest sector boundary + // so we need to get the real size from files.db + std::uintmax_t realfileSize = m_file.file.m_info.header.size; + std::uintmax_t fileSize = m_filepath.file_size(); //in icv files there are more hashes than sectors due to merkle tree @@ -177,7 +181,7 @@ int PfsFile::decrypt_icv_file(boost::filesystem::path destination_root) const } else { - outputStream.write((char*)buffer.data(), fileSize); + outputStream.write((char*)buffer.data(), realfileSize); } } else diff --git a/psvpfsparser/PfsFilesystem.cpp b/psvpfsparser/PfsFilesystem.cpp index eb6a5e1..8abef27 100644 --- a/psvpfsparser/PfsFilesystem.cpp +++ b/psvpfsparser/PfsFilesystem.cpp @@ -122,7 +122,7 @@ int PfsFilesystem::decrypt_files(boost::filesystem::path destTitleIdPath) const //copy unencrypted files else if(is_unencrypted(file->file.m_info.header.type)) { - if(!filepath.copy_existing_file(m_titleIdPath, destTitleIdPath)) + if(!filepath.copy_existing_file(m_titleIdPath, destTitleIdPath, file->file.m_info.header.size)) { m_output << "Failed to copy: " << filepath << std::endl; return -1; diff --git a/psvpfsparser/Utils.cpp b/psvpfsparser/Utils.cpp index 6557ff1..26ad561 100644 --- a/psvpfsparser/Utils.cpp +++ b/psvpfsparser/Utils.cpp @@ -257,6 +257,19 @@ bool sce_junction::copy_existing_file(boost::filesystem::path source_root, boost return true; } + +bool sce_junction::copy_existing_file(boost::filesystem::path source_root, boost::filesystem::path destination_root, std::uintmax_t size) const +{ + if (!copy_existing_file(source_root, destination_root)) + return false; + + // trim size + boost::filesystem::path new_path = source_path_to_dest_path(source_root, destination_root, m_real); + boost::filesystem::resize_file(new_path, size); + + return true; +} + std::ostream& operator<<(std::ostream& os, const sce_junction& p) { os << p.m_value.generic_string(); diff --git a/psvpfsparser/Utils.h b/psvpfsparser/Utils.h index 8e31df4..4a6f487 100644 --- a/psvpfsparser/Utils.h +++ b/psvpfsparser/Utils.h @@ -76,6 +76,9 @@ struct sce_junction //copy file in destination root using path from this junction bool copy_existing_file(boost::filesystem::path source_root, boost::filesystem::path destination_root) const; + //copy file with specific size in destination root using path from this junction + bool copy_existing_file(boost::filesystem::path source_root, boost::filesystem::path destination_root, std::uintmax_t size) const; + public: //this operator should only be used for printing to console! friend std::ostream& operator<<(std::ostream& os, const sce_junction& p);