Add files via upload
This commit is contained in:
parent
2b8d4c67b7
commit
60a2f5a7c1
163
CHOVY-GEN/CHOVY-GEN.vcxproj
Normal file
163
CHOVY-GEN/CHOVY-GEN.vcxproj
Normal file
|
@ -0,0 +1,163 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="chovy-gen.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="key_vault.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{DCDBF747-DFB6-450E-A403-1C592D20EAEB}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>CHOVYGEN</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)CHOVY-TRANSFER\bin\$(Configuration)</OutDir>
|
||||
<TargetName>CHOVY</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IgnoreImportLibrary />
|
||||
<TargetName>CHOVY</TargetName>
|
||||
<OutDir>$(SolutionDir)CHOVY-TRANSFER\bin\$(Configuration)</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CHOVYGEN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\openssl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalLibraryDirectories>C:\openssl\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>ws2_32.lib;libsslMT.lib;Crypt32.lib;libcryptoMT.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;CHOVYGEN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CHOVYGEN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>C:\openssl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>C:\openssl\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>ws2_32.lib;libsslMT.lib;Crypt32.lib;libcryptoMT.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;CHOVYGEN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
27
CHOVY-GEN/CHOVY-GEN.vcxproj.filters
Normal file
27
CHOVY-GEN/CHOVY-GEN.vcxproj.filters
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="key_vault.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="chovy-gen.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
13
CHOVY-GEN/CHOVY-GEN.vcxproj.user
Normal file
13
CHOVY-GEN/CHOVY-GEN.vcxproj.user
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LocalDebuggerCommand>$(SolutionDir)CHOVY-TRANSFER\bin\$(Configuration)\CHOVY-TRANSFER.EXE</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerDebuggerType>Mixed</LocalDebuggerDebuggerType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerCommand>$(SolutionDir)CHOVY-TRANSFER\bin\$(Configuration)\CHOVY-TRANSFER.EXE</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerDebuggerType>Mixed</LocalDebuggerDebuggerType>
|
||||
</PropertyGroup>
|
||||
</Project>
|
289
CHOVY-GEN/chovy-gen.c
Normal file
289
CHOVY-GEN/chovy-gen.c
Normal file
|
@ -0,0 +1,289 @@
|
|||
//Project Chovy - __sce_ebootpbp generator by @dots_tb and motoharu
|
||||
// With CBPS help especially: @SiliCart, @nyaaasen, @notzecoxao (and his friends?)
|
||||
|
||||
//Check out motoharu's project: https://github.com/motoharu-gosuto/psvcmd56/blob/master/src/CMD56Reversed/F00D/GcAuthMgrService.cpp#L1102
|
||||
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) )
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/ec.h>
|
||||
|
||||
#include "key_vault.h"
|
||||
PACK(typedef struct
|
||||
{
|
||||
uint8_t r[0x1c];
|
||||
uint8_t s[0x1c];
|
||||
} ECDSA_SIG_0x1c);
|
||||
|
||||
PACK(typedef struct sce_ebootpbp {
|
||||
uint64_t magic;
|
||||
uint32_t key_type;// set to 1 (maybe keytype?)
|
||||
uint32_t type;// 03 - ps1, 02 - psp
|
||||
uint8_t np_title[0x30];
|
||||
uint64_t aid;
|
||||
uint64_t secure_tick;
|
||||
uint64_t filesz;
|
||||
uint64_t sw_ver;
|
||||
uint8_t padding[0xf8];
|
||||
ECDSA_SIG_0x1c ebootpbp_hdr_sig;
|
||||
ECDSA_SIG_0x1c NPUMDIMG_sig;
|
||||
ECDSA_SIG_0x1c sceebootpbp_sig;
|
||||
} sce_ebootpbp);
|
||||
|
||||
|
||||
typedef struct pbp_hdr {
|
||||
uint32_t magic;
|
||||
uint32_t unk;
|
||||
uint32_t sfo_offset;
|
||||
uint32_t icon0_offset;
|
||||
uint32_t icon1_offset;
|
||||
uint32_t pic0_offset;
|
||||
uint32_t pic1_offset;
|
||||
uint32_t snd0_offset;
|
||||
uint32_t data_psp_offset;
|
||||
uint32_t data_psar_offset;
|
||||
} pbp_hdr;
|
||||
|
||||
|
||||
#define PSAR_SZ 0x1C0000
|
||||
#define WORK_BUF_SZ 0x7c0
|
||||
|
||||
|
||||
//based motoharu
|
||||
__declspec(dllexport) int can_be_reversed_80C17A(const uint8_t* src, int some_size, uint8_t* iv, uint8_t* src_xored_digest)
|
||||
{
|
||||
unsigned char src_xored[0x20];
|
||||
memcpy(src_xored, iv, 0x20);
|
||||
|
||||
if (some_size > 0x20)
|
||||
return 0x12;
|
||||
|
||||
for(int i = 0; i < some_size; i++)
|
||||
src_xored[i] = src[i] ^ iv[i];
|
||||
|
||||
int r0;
|
||||
|
||||
SHA256_CTX sha256_ctx;
|
||||
SHA256_Init(&sha256_ctx);
|
||||
SHA256_Update(&sha256_ctx, src_xored, 0x20);
|
||||
r0 = SHA256_Final(src_xored_digest, &sha256_ctx);
|
||||
if(r0 != 1)
|
||||
return 0x11;
|
||||
|
||||
for(int i = 0; i < 0x20; i++)
|
||||
iv[i] = src_xored_digest[i] ^ iv[i];
|
||||
|
||||
for(int i = 0; i < 0x20; i++)
|
||||
{
|
||||
if(iv[i] != 0xFF)
|
||||
{
|
||||
iv[i] = iv[i] + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
iv[i] = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
__declspec(dllexport) int f00d_KIRK0x22(const uint8_t *hash, ECDSA_SIG_0x1c *signature, int key_sel) {
|
||||
|
||||
|
||||
uint8_t hmac_in[0x38];
|
||||
uint8_t hmac_hash_iv[0x38];
|
||||
memcpy(&hmac_in, hash, 0x1c);
|
||||
memcpy(&hmac_in[0x1c], &keyvault_ec_privkey[key_sel], 0x1c);
|
||||
|
||||
HMAC_CTX *hmac_ctx = HMAC_CTX_new();
|
||||
HMAC_Init_ex(hmac_ctx, &hmac_key_0x22, 0x40, EVP_sha256(), NULL);
|
||||
HMAC_Update(hmac_ctx, &hmac_in, 0x1c << 1);
|
||||
unsigned int len;
|
||||
HMAC_Final(hmac_ctx, &hmac_hash_iv, &len);
|
||||
HMAC_CTX_free(hmac_ctx);
|
||||
|
||||
uint8_t sha256_out[0x40];
|
||||
int ret = 0;
|
||||
do {
|
||||
ret = can_be_reversed_80C17A(hash, 0x1c, hmac_hash_iv, &sha256_out[0]);
|
||||
if(ret != 0 || (ret = can_be_reversed_80C17A(hash, 0x1c, hmac_hash_iv, &sha256_out[0x20])) != 0)
|
||||
return 0;
|
||||
|
||||
} while(ret != 0);
|
||||
|
||||
//ECDSA
|
||||
|
||||
BIGNUM *a = BN_bin2bn(keyvault_ec_a, 0x1c, NULL),
|
||||
*b = BN_bin2bn(keyvault_ec_b, 0x1c, NULL),
|
||||
*p = BN_bin2bn(keyvault_ec_p, 0x1c, NULL),
|
||||
*order = BN_bin2bn(keyvault_ec_N, 0x1c, NULL),
|
||||
*x = BN_bin2bn(keyvault_ec_Gx, 0x1c, NULL),
|
||||
*y = BN_bin2bn(keyvault_ec_Gy, 0x1c, NULL),
|
||||
*priv_key = BN_bin2bn(keyvault_ec_privkey[key_sel], 0x1c, NULL),
|
||||
*m = BN_bin2bn(sha256_out, 0x3c, NULL);
|
||||
|
||||
BN_CTX *bn_ctx = BN_CTX_new();
|
||||
BN_MONT_CTX *bn_mon_ctx = BN_MONT_CTX_new();
|
||||
BN_MONT_CTX_set(bn_mon_ctx, order, bn_ctx);
|
||||
|
||||
EC_GROUP *curve = EC_GROUP_new_curve_GFp(p, a, b, bn_ctx);
|
||||
EC_POINT *generator = EC_POINT_new(curve);
|
||||
EC_POINT_set_affine_coordinates_GFp(curve, generator, x, y, bn_ctx);
|
||||
EC_GROUP_set_generator(curve, generator, order, NULL);
|
||||
|
||||
EC_KEY *eckey=EC_KEY_new();
|
||||
EC_KEY_set_group(eckey,curve);
|
||||
EC_KEY_set_private_key(eckey, priv_key);
|
||||
|
||||
|
||||
m = BN_bin2bn(sha256_out, 0x3c, NULL);
|
||||
BN_mod(m, m, order, bn_ctx);
|
||||
|
||||
|
||||
|
||||
//Generate R in order to get custom "random number"
|
||||
BIGNUM *sig_r = BN_new();
|
||||
EC_POINT_mul(curve, generator, m, NULL, NULL, bn_ctx);
|
||||
EC_POINT_get_affine_coordinates_GFp(curve, generator, sig_r, NULL, bn_ctx);
|
||||
BN_nnmod(sig_r, sig_r, order, bn_ctx);
|
||||
|
||||
//Generate M^-1
|
||||
BIGNUM *exp = BN_new();
|
||||
BIGNUM *minv = BN_new();
|
||||
|
||||
BN_set_word(exp, (BN_ULONG)2);
|
||||
BN_sub(exp, order, exp);
|
||||
BN_mod_exp_mont(minv, m, exp, order, bn_ctx, bn_mon_ctx);
|
||||
|
||||
|
||||
ECDSA_SIG *sig = ECDSA_do_sign_ex(hash, 0x1c, minv, sig_r, eckey);
|
||||
|
||||
|
||||
if(!sig) {
|
||||
ret = 0;
|
||||
goto error;
|
||||
|
||||
}
|
||||
BIGNUM *sig_s;
|
||||
ECDSA_SIG_get0(sig, NULL, &sig_s);
|
||||
BN_bn2bin(sig_r, &signature->r);
|
||||
BN_bn2bin(sig_s, &signature->s);
|
||||
ECDSA_SIG_free(sig);
|
||||
//BN_free(sig_s);
|
||||
ret = 1;
|
||||
|
||||
error:
|
||||
BN_free(sig_r);
|
||||
|
||||
EC_POINT_free(generator);
|
||||
BN_free(y);
|
||||
BN_free(x);
|
||||
BN_free(order);
|
||||
BN_free(p);
|
||||
BN_free(b);
|
||||
BN_free(a);
|
||||
BN_free(minv);
|
||||
BN_free(exp);
|
||||
BN_free(priv_key);
|
||||
BN_CTX_free(bn_ctx);
|
||||
BN_MONT_CTX_free(bn_mon_ctx);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
__declspec(dllexport) int chovy_gen(char *ebootpbp, uint64_t signaid, char *outscefile)
|
||||
{
|
||||
|
||||
int ret = 1;
|
||||
FILE *fin = 0, *fout = 0;
|
||||
|
||||
uint8_t *work_buf = (unsigned char*) calloc (1, WORK_BUF_SZ);
|
||||
sce_ebootpbp *sceebootpbp_file = (unsigned char*) calloc (1, sizeof(sce_ebootpbp));
|
||||
|
||||
|
||||
fin = fopen(ebootpbp, "rb");
|
||||
if (!fin) {
|
||||
|
||||
goto error;
|
||||
}
|
||||
memcpy(&sceebootpbp_file->magic, "NPUMDSIG", 0x8);
|
||||
sceebootpbp_file->type = 2;
|
||||
sceebootpbp_file->key_type = 1;
|
||||
sceebootpbp_file->aid = signaid;
|
||||
|
||||
|
||||
fseek(fin, 0, SEEK_END);
|
||||
sceebootpbp_file->filesz = ftell(fin);
|
||||
|
||||
pbp_hdr hdr;
|
||||
fseek(fin, 0, SEEK_SET);
|
||||
fread(&hdr, sizeof(pbp_hdr),1,fin);
|
||||
|
||||
|
||||
fseek(fin, 0, SEEK_SET);
|
||||
fread(work_buf, hdr.icon0_offset, 1,fin);
|
||||
|
||||
uint8_t work_hash[0x1c];
|
||||
SHA256_CTX sha256_ctx;
|
||||
SHA224_Init(&sha256_ctx);
|
||||
SHA224_Update(&sha256_ctx, work_buf, hdr.icon0_offset);
|
||||
SHA224_Final(work_hash, &sha256_ctx);
|
||||
f00d_KIRK0x22(work_hash, &sceebootpbp_file->ebootpbp_hdr_sig, sceebootpbp_file->key_type);
|
||||
|
||||
SHA224_Init(&sha256_ctx);
|
||||
fseek(fin, hdr.data_psar_offset, SEEK_SET);
|
||||
|
||||
size_t size = PSAR_SZ;
|
||||
int to_read = size > WORK_BUF_SZ ? WORK_BUF_SZ : size;
|
||||
|
||||
|
||||
fread(work_buf, to_read, 1,fin);
|
||||
if(memcmp(work_buf, "NPUMDIMG", 0x8) == 0)
|
||||
memcpy(&sceebootpbp_file->np_title, work_buf + 0x10, sizeof(sceebootpbp_file->np_title));
|
||||
else {
|
||||
memcpy(&sceebootpbp_file->magic, "NPPS1SIG", sizeof(sceebootpbp_file->magic));
|
||||
sceebootpbp_file->type = 3;
|
||||
}
|
||||
|
||||
do {
|
||||
size -= to_read;
|
||||
SHA224_Update(&sha256_ctx, work_buf, to_read);
|
||||
to_read = size > WORK_BUF_SZ ? WORK_BUF_SZ : size;
|
||||
fread(work_buf, to_read, 1,fin);
|
||||
} while(size > 0);
|
||||
|
||||
SHA224_Final(work_hash, &sha256_ctx);
|
||||
|
||||
f00d_KIRK0x22(work_hash, &sceebootpbp_file->NPUMDIMG_sig, sceebootpbp_file->key_type);
|
||||
|
||||
SHA224_Init(&sha256_ctx);
|
||||
SHA224_Update(&sha256_ctx, sceebootpbp_file, 0x1C8);
|
||||
SHA224_Final(work_hash, &sha256_ctx);
|
||||
|
||||
f00d_KIRK0x22(work_hash, &sceebootpbp_file->sceebootpbp_sig, sceebootpbp_file->key_type);
|
||||
|
||||
fout = fopen(outscefile, "wb");
|
||||
if (!fout) {
|
||||
goto error;
|
||||
}
|
||||
fwrite(sceebootpbp_file, 1, sizeof(sce_ebootpbp), fout);
|
||||
|
||||
ret = 0;
|
||||
error:
|
||||
if (fin)
|
||||
fclose(fin);
|
||||
if (fout)
|
||||
fclose(fout);
|
||||
free(work_buf);
|
||||
free(sceebootpbp_file);
|
||||
return ret;
|
||||
}
|
17
CHOVY-GEN/key_vault.h
Normal file
17
CHOVY-GEN/key_vault.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
uint8_t keyvault_ec_p[0x1c] = {0xA5, 0x3E, 0x11, 0x3E, 0x46, 0xD8, 0xC9, 0xC1, 0xF0, 0x9D, 0x9B, 0xCB, 0x2A, 0x53, 0x73, 0xD3, 0x79, 0xF6, 0x9D, 0xA2, 0x8D, 0x09, 0x99, 0x9F, 0xED, 0x57, 0xA9, 0x0F};
|
||||
uint8_t keyvault_ec_a[0x1c] = {0xA5, 0x3E, 0x11, 0x3E, 0x46, 0xD8, 0xC9, 0xC1, 0xF0, 0x9D, 0x9B, 0xCB, 0x2A, 0x53, 0x73, 0xD3, 0x79, 0xF6, 0x9D, 0xA2, 0x8D, 0x09, 0x99, 0x9F, 0xED, 0x57, 0xA9, 0x0C};
|
||||
uint8_t keyvault_ec_b[0x1c] = {0x90, 0x65, 0x94, 0x1D, 0x29, 0x37, 0x4A, 0x8F, 0x11, 0xDD, 0x1E, 0x54, 0x01, 0x89, 0x43, 0x4E, 0x4A, 0x6E, 0xBF, 0xAF, 0x54, 0x77, 0xF6, 0xC1, 0x72, 0xF6, 0x85, 0x5E};
|
||||
uint8_t keyvault_ec_N[0x1c] = { 0xA5, 0x3E, 0x11, 0x3E, 0x46, 0xD8, 0xC9, 0xC1, 0xF0, 0x9D, 0x9B, 0xCB, 0x2A, 0x52, 0x26, 0x98, 0xDE, 0xEF, 0x58, 0xDB, 0x1A, 0xD9, 0xAB, 0x7F, 0x04, 0xE3, 0xAE, 0x7F};
|
||||
uint8_t keyvault_ec_Gx[0x1c] = {0x7E, 0x06, 0x09, 0x82, 0x47, 0xE6, 0xB5, 0x9F, 0x31, 0x10, 0xBC, 0xBB, 0x3A, 0xB6, 0xC2, 0x50, 0xBC, 0x5A, 0xB0, 0x6C, 0x03, 0x2D, 0xAD, 0x43, 0x68, 0x4C, 0x24, 0x8F};
|
||||
uint8_t keyvault_ec_Gy[0x1c] = {0x0B, 0xD9, 0x41, 0x8D, 0xE8, 0xE3, 0xE4, 0x5D, 0x2D, 0x70, 0x1E, 0x02, 0x37, 0xFD, 0x7F, 0x2A, 0xDE, 0x0D, 0x48, 0xB7, 0x4C, 0xEE, 0xF2, 0xF1, 0xC8, 0xAC, 0x48, 0x4E};
|
||||
uint8_t keyvault_ec_pubkey[2][0x38] = {
|
||||
{0x5F, 0x9D, 0x17, 0x1A, 0x2B, 0xDD, 0xA8, 0xD4, 0x08, 0x78, 0xBF, 0x98, 0x5A, 0xC3, 0x26, 0xED, 0x5E, 0xFF, 0x43, 0xC9, 0x37, 0x6C, 0x77, 0xEC, 0x0A, 0x00, 0xC7, 0xBB, 0xA3, 0x44, 0xE4, 0x4E, 0x6E, 0xAC, 0x25, 0x52, 0x35, 0xF9, 0x54, 0xF5, 0xB6, 0x17, 0xC7, 0xBD, 0x49, 0xF1, 0x80, 0x26, 0x24, 0x54, 0xAA, 0xE1, 0xB6, 0x2A, 0x9F, 0x2C},
|
||||
{0x67, 0x00, 0x2D, 0x9B, 0xB8, 0xE4, 0x2D, 0x2B, 0xF9, 0x61, 0x0B, 0x27, 0xFE, 0xAB, 0x9B, 0x34, 0x56, 0x15, 0x50, 0x92, 0x13, 0x12, 0xDF, 0xEE, 0x7A, 0x3A, 0x86, 0xEC, 0x6C, 0xA7, 0x14, 0x42, 0x6F, 0x6D, 0x4E, 0x96, 0x09, 0xA6, 0x38, 0xBF, 0x4A, 0xFB, 0x18, 0x2B, 0xFA, 0x50, 0xC8, 0x2F, 0xF2, 0xB4, 0xC5, 0xEC, 0x6C, 0xCD, 0x97, 0x65}
|
||||
};
|
||||
|
||||
uint8_t keyvault_ec_privkey[2][0x1c] = {
|
||||
{0x76, 0x74, 0x36, 0xA6, 0x99, 0x9D, 0x88, 0x48, 0x0E, 0xC8, 0x56, 0xF5, 0x5C, 0xEA, 0xBB, 0x43, 0x96, 0x85, 0x9E, 0x37, 0x45, 0x99, 0x40, 0x39, 0x21, 0xF5, 0x55, 0x98},
|
||||
{0x60, 0x7A, 0x2E, 0x55, 0x68, 0xB4, 0xB9, 0xA0, 0x32, 0xF4, 0x52, 0x53, 0xCF, 0xED, 0x20, 0xDB, 0x2E, 0x6E, 0x44, 0x6C, 0x37, 0x82, 0xE8, 0x2A, 0x1A, 0xB9, 0xC9, 0x23}
|
||||
};
|
||||
|
||||
uint8_t hmac_key_0x22[0x40] = {0x54, 0x88, 0xA9, 0x81, 0x1C, 0x9A, 0x2C, 0xBC, 0xCC, 0x59, 0x6B, 0x1F, 0xAD, 0x1A, 0x7E, 0x29, 0xE0, 0x75, 0x84, 0x0F, 0x47, 0x43, 0x1F, 0x37, 0xAC, 0x06, 0x02, 0x46, 0x4A, 0x27, 0x9E, 0x02, 0xDF, 0x2E, 0x71, 0x65, 0xF1, 0x13, 0x7B, 0xF6, 0x9A, 0xE6, 0xDC, 0xB9, 0xDC, 0x38, 0x8C, 0x9D, 0xCC, 0xB3, 0x64, 0xC4, 0xCA, 0x26, 0xCB, 0x8F, 0x1A, 0xF0, 0x63, 0x8A, 0x6E, 0xAD, 0xB5, 0x4D};
|
48
CHOVY-TRANSFER.sln
Normal file
48
CHOVY-TRANSFER.sln
Normal file
|
@ -0,0 +1,48 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26228.76
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CHOVY-TRANSFER", "CHOVY-TRANSFER\CHOVY-TRANSFER.csproj", "{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CHOVY-GEN", "CHOVY-GEN\CHOVY-GEN.vcxproj", "{DCDBF747-DFB6-450E-A403-1C592D20EAEB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{DCDBF747-DFB6-450E-A403-1C592D20EAEB}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{DCDBF747-DFB6-450E-A403-1C592D20EAEB}.Debug|Any CPU.Build.0 = Debug|Win32
|
||||
{DCDBF747-DFB6-450E-A403-1C592D20EAEB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DCDBF747-DFB6-450E-A403-1C592D20EAEB}.Debug|x64.Build.0 = Debug|x64
|
||||
{DCDBF747-DFB6-450E-A403-1C592D20EAEB}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{DCDBF747-DFB6-450E-A403-1C592D20EAEB}.Debug|x86.Build.0 = Debug|Win32
|
||||
{DCDBF747-DFB6-450E-A403-1C592D20EAEB}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{DCDBF747-DFB6-450E-A403-1C592D20EAEB}.Release|Any CPU.Build.0 = Release|Win32
|
||||
{DCDBF747-DFB6-450E-A403-1C592D20EAEB}.Release|x64.ActiveCfg = Release|x64
|
||||
{DCDBF747-DFB6-450E-A403-1C592D20EAEB}.Release|x64.Build.0 = Release|x64
|
||||
{DCDBF747-DFB6-450E-A403-1C592D20EAEB}.Release|x86.ActiveCfg = Release|Win32
|
||||
{DCDBF747-DFB6-450E-A403-1C592D20EAEB}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
6
CHOVY-TRANSFER/App.config
Normal file
6
CHOVY-TRANSFER/App.config
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup>
|
||||
</configuration>
|
107
CHOVY-TRANSFER/CHOVY-TRANSFER.csproj
Normal file
107
CHOVY-TRANSFER/CHOVY-TRANSFER.csproj
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{B4CAD2C0-BA54-46B6-A8D0-43A9C2390D3C}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>CHOVY_TRANSFER</RootNamespace>
|
||||
<AssemblyName>CHOVY-TRANS</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>chovy-trans.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BouncyCastle.Crypto, Version=1.8.5.0, Culture=neutral, PublicKeyToken=0e99375e54769942">
|
||||
<HintPath>..\packages\BouncyCastle.1.8.5\lib\BouncyCastle.Crypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DotNetZip, Version=1.13.4.0, Culture=neutral, PublicKeyToken=6583c7c814667745, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\DotNetZip.1.13.4\lib\net40\DotNetZip.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CHOVYTRANSFER.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CHOVYTRANSFER.Designer.cs">
|
||||
<DependentUpon>CHOVYTRANSFER.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="cmakeys.cs" />
|
||||
<Compile Include="param.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="PSVIMGBuilder.cs" />
|
||||
<Compile Include="PSVIMGStructs.cs" />
|
||||
<Compile Include="PSVMDBuilder.cs" />
|
||||
<EmbeddedResource Include="CHOVYTRANSFER.resx">
|
||||
<DependentUpon>CHOVYTRANSFER.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="chovy-trans.ico" />
|
||||
<None Include="chovytrans.gif" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
294
CHOVY-TRANSFER/CHOVYTRANSFER.Designer.cs
generated
Normal file
294
CHOVY-TRANSFER/CHOVYTRANSFER.Designer.cs
generated
Normal file
|
@ -0,0 +1,294 @@
|
|||
namespace CHOVY_TRANSFER
|
||||
{
|
||||
partial class CHOVYTRANSFER
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CHOVYTRANSFER));
|
||||
this.driveLetterSrc = new System.Windows.Forms.ComboBox();
|
||||
this.pspFolder = new System.Windows.Forms.TextBox();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.cmaDir = new System.Windows.Forms.TextBox();
|
||||
this.driveLetterDst = new System.Windows.Forms.ComboBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.pspGames = new System.Windows.Forms.ListBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.transVita = new System.Windows.Forms.Button();
|
||||
this.progressBar = new System.Windows.Forms.ProgressBar();
|
||||
this.progressStatus = new System.Windows.Forms.Label();
|
||||
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
||||
this.groupBox1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// driveLetterSrc
|
||||
//
|
||||
this.driveLetterSrc.BackColor = System.Drawing.Color.DimGray;
|
||||
this.driveLetterSrc.DisplayMember = "1";
|
||||
this.driveLetterSrc.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.driveLetterSrc.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
|
||||
this.driveLetterSrc.ForeColor = System.Drawing.Color.Lime;
|
||||
this.driveLetterSrc.FormattingEnabled = true;
|
||||
this.driveLetterSrc.Items.AddRange(new object[] {
|
||||
"A:\\",
|
||||
"B:\\",
|
||||
"C:\\",
|
||||
"D:\\",
|
||||
"E:\\",
|
||||
"F:\\",
|
||||
"G:\\",
|
||||
"H:\\",
|
||||
"I:\\",
|
||||
"J:\\",
|
||||
"K:\\",
|
||||
"L:\\",
|
||||
"M:\\",
|
||||
"N:\\",
|
||||
"O:\\",
|
||||
"P:\\",
|
||||
"Q:\\",
|
||||
"R:\\",
|
||||
"S:\\",
|
||||
"T:\\",
|
||||
"U:\\",
|
||||
"V:\\",
|
||||
"W:\\",
|
||||
"X:\\",
|
||||
"Y:\\",
|
||||
"Z:\\"});
|
||||
this.driveLetterSrc.Location = new System.Drawing.Point(74, 12);
|
||||
this.driveLetterSrc.Name = "driveLetterSrc";
|
||||
this.driveLetterSrc.Size = new System.Drawing.Size(41, 21);
|
||||
this.driveLetterSrc.TabIndex = 1;
|
||||
this.driveLetterSrc.SelectedIndexChanged += new System.EventHandler(this.driveLetterSrc_SelectedIndexChanged);
|
||||
//
|
||||
// pspFolder
|
||||
//
|
||||
this.pspFolder.BackColor = System.Drawing.Color.DimGray;
|
||||
this.pspFolder.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.pspFolder.ForeColor = System.Drawing.Color.Lime;
|
||||
this.pspFolder.Location = new System.Drawing.Point(121, 13);
|
||||
this.pspFolder.Name = "pspFolder";
|
||||
this.pspFolder.Size = new System.Drawing.Size(194, 20);
|
||||
this.pspFolder.TabIndex = 2;
|
||||
this.pspFolder.Text = "PSP";
|
||||
this.pspFolder.TextChanged += new System.EventHandler(this.pspFolder_TextChanged);
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.BackColor = System.Drawing.Color.Black;
|
||||
this.groupBox1.Controls.Add(this.cmaDir);
|
||||
this.groupBox1.Controls.Add(this.driveLetterDst);
|
||||
this.groupBox1.Controls.Add(this.label2);
|
||||
this.groupBox1.Controls.Add(this.label1);
|
||||
this.groupBox1.Controls.Add(this.driveLetterSrc);
|
||||
this.groupBox1.Controls.Add(this.pspFolder);
|
||||
this.groupBox1.ForeColor = System.Drawing.Color.Lime;
|
||||
this.groupBox1.Location = new System.Drawing.Point(162, 12);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(622, 41);
|
||||
this.groupBox1.TabIndex = 3;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "Directories";
|
||||
//
|
||||
// cmaDir
|
||||
//
|
||||
this.cmaDir.BackColor = System.Drawing.Color.DimGray;
|
||||
this.cmaDir.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.cmaDir.ForeColor = System.Drawing.Color.Lime;
|
||||
this.cmaDir.Location = new System.Drawing.Point(439, 14);
|
||||
this.cmaDir.Name = "cmaDir";
|
||||
this.cmaDir.Size = new System.Drawing.Size(177, 20);
|
||||
this.cmaDir.TabIndex = 6;
|
||||
this.cmaDir.Text = "Users\\XXX\\Documents\\PS Vita";
|
||||
this.cmaDir.TextChanged += new System.EventHandler(this.cmaDir_TextChanged);
|
||||
//
|
||||
// driveLetterDst
|
||||
//
|
||||
this.driveLetterDst.BackColor = System.Drawing.Color.DimGray;
|
||||
this.driveLetterDst.DisplayMember = "1";
|
||||
this.driveLetterDst.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.driveLetterDst.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
|
||||
this.driveLetterDst.ForeColor = System.Drawing.Color.Lime;
|
||||
this.driveLetterDst.FormattingEnabled = true;
|
||||
this.driveLetterDst.Items.AddRange(new object[] {
|
||||
"A:\\",
|
||||
"B:\\",
|
||||
"C:\\",
|
||||
"D:\\",
|
||||
"E:\\",
|
||||
"F:\\",
|
||||
"G:\\",
|
||||
"H:\\",
|
||||
"I:\\",
|
||||
"J:\\",
|
||||
"K:\\",
|
||||
"L:\\",
|
||||
"M:\\",
|
||||
"N:\\",
|
||||
"O:\\",
|
||||
"P:\\",
|
||||
"Q:\\",
|
||||
"R:\\",
|
||||
"S:\\",
|
||||
"T:\\",
|
||||
"U:\\",
|
||||
"V:\\",
|
||||
"W:\\",
|
||||
"X:\\",
|
||||
"Y:\\",
|
||||
"Z:\\"});
|
||||
this.driveLetterDst.Location = new System.Drawing.Point(392, 12);
|
||||
this.driveLetterDst.Name = "driveLetterDst";
|
||||
this.driveLetterDst.Size = new System.Drawing.Size(41, 21);
|
||||
this.driveLetterDst.TabIndex = 5;
|
||||
this.driveLetterDst.SelectedIndexChanged += new System.EventHandler(this.driveLetterDst_SelectedIndexChanged);
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(321, 16);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(65, 13);
|
||||
this.label2.TabIndex = 4;
|
||||
this.label2.Text = "CMA Folder:";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(11, 16);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(63, 13);
|
||||
this.label1.TabIndex = 3;
|
||||
this.label1.Text = "PSP Folder:";
|
||||
//
|
||||
// pspGames
|
||||
//
|
||||
this.pspGames.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.pspGames.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.pspGames.ForeColor = System.Drawing.Color.Lime;
|
||||
this.pspGames.FormattingEnabled = true;
|
||||
this.pspGames.Location = new System.Drawing.Point(162, 73);
|
||||
this.pspGames.Name = "pspGames";
|
||||
this.pspGames.Size = new System.Drawing.Size(622, 223);
|
||||
this.pspGames.TabIndex = 4;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.ForeColor = System.Drawing.Color.Lime;
|
||||
this.label3.Location = new System.Drawing.Point(159, 56);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(82, 13);
|
||||
this.label3.TabIndex = 5;
|
||||
this.label3.Text = "Games on PSP:";
|
||||
//
|
||||
// transVita
|
||||
//
|
||||
this.transVita.BackColor = System.Drawing.Color.Black;
|
||||
this.transVita.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.transVita.ForeColor = System.Drawing.Color.Red;
|
||||
this.transVita.Location = new System.Drawing.Point(649, 302);
|
||||
this.transVita.Name = "transVita";
|
||||
this.transVita.Size = new System.Drawing.Size(135, 23);
|
||||
this.transVita.TabIndex = 6;
|
||||
this.transVita.Text = "MOV 1, PSVITA";
|
||||
this.transVita.UseVisualStyleBackColor = false;
|
||||
this.transVita.EnabledChanged += new System.EventHandler(this.transVita_EnabledChanged);
|
||||
this.transVita.Click += new System.EventHandler(this.transVita_Click);
|
||||
//
|
||||
// progressBar
|
||||
//
|
||||
this.progressBar.Location = new System.Drawing.Point(202, 297);
|
||||
this.progressBar.Name = "progressBar";
|
||||
this.progressBar.Size = new System.Drawing.Size(441, 23);
|
||||
this.progressBar.TabIndex = 7;
|
||||
//
|
||||
// progressStatus
|
||||
//
|
||||
this.progressStatus.AutoSize = true;
|
||||
this.progressStatus.ForeColor = System.Drawing.Color.Lime;
|
||||
this.progressStatus.Location = new System.Drawing.Point(159, 307);
|
||||
this.progressStatus.Name = "progressStatus";
|
||||
this.progressStatus.Size = new System.Drawing.Size(21, 13);
|
||||
this.progressStatus.TabIndex = 8;
|
||||
this.progressStatus.Text = "0%";
|
||||
//
|
||||
// pictureBox1
|
||||
//
|
||||
this.pictureBox1.BackgroundImage = global::CHOVY_TRANSFER.Properties.Resources.chovytrans;
|
||||
this.pictureBox1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
|
||||
this.pictureBox1.Location = new System.Drawing.Point(9, 3);
|
||||
this.pictureBox1.Name = "pictureBox1";
|
||||
this.pictureBox1.Size = new System.Drawing.Size(144, 317);
|
||||
this.pictureBox1.TabIndex = 9;
|
||||
this.pictureBox1.TabStop = false;
|
||||
//
|
||||
// CHOVYTRANSFER
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.Black;
|
||||
this.ClientSize = new System.Drawing.Size(796, 332);
|
||||
this.Controls.Add(this.pictureBox1);
|
||||
this.Controls.Add(this.progressStatus);
|
||||
this.Controls.Add(this.progressBar);
|
||||
this.Controls.Add(this.transVita);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.pspGames);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Name = "CHOVYTRANSFER";
|
||||
this.Text = "Chovy-Transfer";
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.CHOVYTRANSFER_FormClosing);
|
||||
this.Load += new System.EventHandler(this.CHOVYTRANSFER_Load);
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private System.Windows.Forms.ComboBox driveLetterSrc;
|
||||
private System.Windows.Forms.TextBox pspFolder;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.TextBox cmaDir;
|
||||
private System.Windows.Forms.ComboBox driveLetterDst;
|
||||
private System.Windows.Forms.ListBox pspGames;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Button transVita;
|
||||
private System.Windows.Forms.ProgressBar progressBar;
|
||||
private System.Windows.Forms.Label progressStatus;
|
||||
private System.Windows.Forms.PictureBox pictureBox1;
|
||||
}
|
||||
}
|
||||
|
519
CHOVY-TRANSFER/CHOVYTRANSFER.cs
Normal file
519
CHOVY-TRANSFER/CHOVYTRANSFER.cs
Normal file
|
@ -0,0 +1,519 @@
|
|||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using Param_SFO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using KeyDerivation;
|
||||
using PSVIMGTOOLS;
|
||||
using System.Drawing;
|
||||
|
||||
namespace CHOVY_TRANSFER
|
||||
{
|
||||
public partial class CHOVYTRANSFER : Form
|
||||
{
|
||||
[DllImport("CHOVY.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int chovy_gen(string ebootpbp, UInt64 AID, string outscefile);
|
||||
|
||||
public string GetCmaDir()
|
||||
{
|
||||
string Dir = "";
|
||||
try
|
||||
{
|
||||
//try qcma
|
||||
Dir = Registry.CurrentUser.OpenSubKey(@"Software\codestation\qcma").GetValue("appsPath").ToString();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//try sony cma
|
||||
Dir = Registry.CurrentUser.OpenSubKey(@"Software\Sony Corporation\Content Manager Assistant\Settings").GetValue("ApplicationHomePath").ToString();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//try devkit cma
|
||||
Dir = Registry.CurrentUser.OpenSubKey(@"Software\SCE\PSP2\Services\Content Manager Assistant for PlayStation(R)Vita DevKit\Settings").GetValue("ApplicationHomePath").ToString();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
string DefaultDir = Path.Combine(Environment.GetEnvironmentVariable("HOMEDRIVE"), Environment.GetEnvironmentVariable("HOMEPATH"), "Documents", "PS Vita");
|
||||
if (Directory.Exists(DefaultDir))
|
||||
{
|
||||
Dir = DefaultDir;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ReadSetting("CmaDir") != "")
|
||||
{
|
||||
Dir = ReadSetting("CmaDir");
|
||||
}
|
||||
|
||||
return Dir.Replace("/","\\");
|
||||
}
|
||||
|
||||
|
||||
public string ReadSetting(string Setting)
|
||||
{
|
||||
string Value = "";
|
||||
try
|
||||
{
|
||||
|
||||
RegistryKey key;
|
||||
key = Registry.CurrentUser.CreateSubKey(@"Software\CHOVYProject\Chovy-Trans");
|
||||
Value = key.GetValue(Setting).ToString();
|
||||
key.Close();
|
||||
}
|
||||
catch (Exception) { return ""; }
|
||||
return Value;
|
||||
}
|
||||
|
||||
public void WriteSetting(string Setting, string Value)
|
||||
{
|
||||
try
|
||||
{
|
||||
RegistryKey key;
|
||||
key = Registry.CurrentUser.CreateSubKey(@"Software\CHOVYProject\Chovy-Trans");
|
||||
key.SetValue(Setting, Value);
|
||||
key.Close();
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
public void ChangeCmaDir(string newDir)
|
||||
{
|
||||
string DriveLetter = Path.GetPathRoot(newDir);
|
||||
driveLetterDst.Text = DriveLetter;
|
||||
cmaDir.Text = newDir.Remove(0, DriveLetter.Length);
|
||||
}
|
||||
|
||||
public void ChangePspDir(string newDir)
|
||||
{
|
||||
string DriveLetter = Path.GetPathRoot(newDir);
|
||||
driveLetterSrc.Text = DriveLetter;
|
||||
pspFolder.Text = newDir.Remove(0, DriveLetter.Length);
|
||||
}
|
||||
|
||||
public string FindPspDir()
|
||||
{
|
||||
for(char i = 'A'; i < 'Z'; i++)
|
||||
{
|
||||
if (Directory.Exists(Path.Combine(i + ":\\", pspFolder.Text)))
|
||||
{
|
||||
return Path.Combine(i + ":\\", pspFolder.Text);
|
||||
}
|
||||
}
|
||||
return Path.Combine("D:\\",pspFolder.Text);
|
||||
}
|
||||
|
||||
public int ReadInt32(Stream s)
|
||||
{
|
||||
byte[] IntData = new byte[0x4];
|
||||
s.Read(IntData, 0x00, 0x4);
|
||||
return BitConverter.ToInt32(IntData, 0x00);
|
||||
}
|
||||
|
||||
public void PopulatePspGameList()
|
||||
{
|
||||
string PspDir = Path.Combine(driveLetterSrc.Text, pspFolder.Text);
|
||||
pspGames.Items.Clear();
|
||||
try
|
||||
{
|
||||
string[] games = Directory.GetFileSystemEntries(Path.Combine(PspDir, "GAME"));
|
||||
|
||||
foreach (string game in games)
|
||||
{
|
||||
try
|
||||
{
|
||||
string EbootPbp = Path.Combine(game, "EBOOT.PBP");
|
||||
|
||||
|
||||
string TitleId = Path.GetFileName(game);
|
||||
string Title = GetTitleFromPbp(EbootPbp);
|
||||
string ContentId = GetContentIdFromPbp(EbootPbp);
|
||||
|
||||
string LicenseFile = Path.Combine(PspDir, "LICENSE", ContentId);
|
||||
|
||||
if (TitleId.Length == 9 && File.Exists(LicenseFile));
|
||||
{
|
||||
pspGames.Items.Add(TitleId + " - " + Title);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception) { };
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception) { };
|
||||
|
||||
}
|
||||
public string GetTitleFromPbp(string pbp)
|
||||
{
|
||||
byte[] SfoData = GetSfo(pbp);
|
||||
|
||||
using (MemoryStream ms = new MemoryStream(SfoData, 0x00, SfoData.Length))
|
||||
{
|
||||
PARAM_SFO sfo = new PARAM_SFO(ms);
|
||||
return sfo.Title;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] GetSfo(string pbp)
|
||||
{
|
||||
FileStream pbps = File.OpenRead(pbp);
|
||||
pbps.Seek(0x08, SeekOrigin.Begin);
|
||||
int sfoOffset = ReadInt32(pbps);
|
||||
int sfoSize = ReadInt32(pbps);
|
||||
|
||||
|
||||
|
||||
pbps.Seek(sfoOffset, SeekOrigin.Begin);
|
||||
sfoSize -= (int)pbps.Position;
|
||||
|
||||
byte[] SfoData = new byte[sfoSize];
|
||||
pbps.Read(SfoData, 0x00, sfoSize);
|
||||
pbps.Dispose();
|
||||
return SfoData;
|
||||
}
|
||||
|
||||
public byte[] GetIcon0(string pbp)
|
||||
{
|
||||
FileStream pbps = File.OpenRead(pbp);
|
||||
pbps.Seek(0x0C, SeekOrigin.Begin);
|
||||
int sfoOffset = ReadInt32(pbps);
|
||||
int iconSize = ReadInt32(pbps);
|
||||
|
||||
|
||||
pbps.Seek(sfoOffset, SeekOrigin.Begin);
|
||||
iconSize -= (int)pbps.Position;
|
||||
|
||||
byte[] IconData = new byte[iconSize];
|
||||
pbps.Read(IconData, 0x00, iconSize);
|
||||
pbps.Dispose();
|
||||
return IconData;
|
||||
}
|
||||
|
||||
public string GetContentIdFromPs1Pbp(string pbp)
|
||||
{
|
||||
FileStream pbps = File.OpenRead(pbp);
|
||||
pbps.Seek(0x20, SeekOrigin.Begin);
|
||||
Int64 PSPData = ReadInt32(pbps);
|
||||
pbps.Seek(PSPData + 0x560, SeekOrigin.Begin);
|
||||
byte[] ContentId = new byte[0x24];
|
||||
pbps.Read(ContentId, 0x00, 0x24);
|
||||
pbps.Close();
|
||||
return Encoding.UTF8.GetString(ContentId);
|
||||
}
|
||||
|
||||
public bool IsPs1(string pbp)
|
||||
{
|
||||
FileStream pbps = File.OpenRead(pbp);
|
||||
pbps.Seek(0x24, SeekOrigin.Begin);
|
||||
Int64 NPUMDIMGOffest = ReadInt32(pbps);
|
||||
pbps.Seek(NPUMDIMGOffest, SeekOrigin.Begin);
|
||||
byte[] Header = new byte[0x8];
|
||||
pbps.Read(Header, 0x00, 0x8);
|
||||
pbps.Close();
|
||||
if(Encoding.UTF8.GetString(Header) == "PSISOIMG")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
public string GetContentIdFromPbp(string pbp)
|
||||
{
|
||||
if(IsPs1(pbp))
|
||||
{
|
||||
return GetContentIdFromPs1Pbp(pbp);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetContentIdFromPspPbp(pbp);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetContentIdFromPspPbp(string pbp)
|
||||
{
|
||||
FileStream pbps = File.OpenRead(pbp);
|
||||
pbps.Seek(0x24, SeekOrigin.Begin);
|
||||
Int64 NPUMDIMGOffest = ReadInt32(pbps);
|
||||
pbps.Seek(NPUMDIMGOffest + 0x10, SeekOrigin.Begin);
|
||||
byte[] ContentId = new byte[0x24];
|
||||
pbps.Read(ContentId, 0x00, 0x24);
|
||||
pbps.Close();
|
||||
return Encoding.UTF8.GetString(ContentId);
|
||||
}
|
||||
|
||||
public CHOVYTRANSFER()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void CHOVYTRANSFER_Load(object sender, EventArgs e)
|
||||
{
|
||||
string PspDir = ReadSetting("PspFolder");
|
||||
if (PspDir != "")
|
||||
{
|
||||
pspFolder.Text = PspDir;
|
||||
}
|
||||
|
||||
ChangePspDir(FindPspDir());
|
||||
ChangeCmaDir(GetCmaDir());
|
||||
PopulatePspGameList();
|
||||
}
|
||||
|
||||
private void pspFolder_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
WriteSetting("PspFolder", pspFolder.Text);
|
||||
PopulatePspGameList();
|
||||
}
|
||||
|
||||
private void driveLetterSrc_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
PopulatePspGameList();
|
||||
}
|
||||
|
||||
private void cmaDir_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
WriteSetting("CmaDir", Path.Combine(driveLetterDst.Text, cmaDir.Text));
|
||||
}
|
||||
private void driveLetterDst_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
WriteSetting("CmaDir", Path.Combine(driveLetterDst.Text, cmaDir.Text));
|
||||
}
|
||||
private void transVita_EnabledChanged(object sender, EventArgs e)
|
||||
{
|
||||
Color red = Color.FromArgb(192, 0, 0);
|
||||
Color black = Color.Black;
|
||||
bool enabled = this.transVita.Enabled;
|
||||
this.transVita.ForeColor = enabled ? red : black;
|
||||
this.transVita.BackColor = enabled ? black : red;
|
||||
}
|
||||
|
||||
private void CHOVYTRANSFER_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
private void transVita_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
if(!Directory.Exists(Path.Combine(driveLetterDst.Text, cmaDir.Text)))
|
||||
{
|
||||
MessageBox.Show("CMA Folder Doesn't Exist", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(Path.Combine(driveLetterSrc.Text,pspFolder.Text)))
|
||||
{
|
||||
MessageBox.Show("PSP Folder Doesn't Exist", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pspGames.SelectedIndex < 0)
|
||||
{
|
||||
MessageBox.Show("No PSP Game Selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
transVita.Enabled = false;
|
||||
driveLetterDst.Enabled = false;
|
||||
driveLetterSrc.Enabled = false;
|
||||
pspFolder.ReadOnly = true;
|
||||
cmaDir.ReadOnly = true;
|
||||
pspGames.Enabled = false;
|
||||
|
||||
string titleId = pspGames.SelectedItem.ToString().Substring(0, 9);
|
||||
string gameFolder = Path.Combine(driveLetterSrc.Text, pspFolder.Text, "GAME", titleId);
|
||||
string ebootFile = Path.Combine(gameFolder, "EBOOT.PBP");
|
||||
string cid = GetContentIdFromPbp(ebootFile);
|
||||
string licenseFile = Path.Combine(driveLetterSrc.Text, pspFolder.Text, "LICENSE", cid + ".RIF");
|
||||
string sigFile = Path.Combine(gameFolder, "__sce_ebootpbp");
|
||||
string backupDir = Path.Combine(driveLetterDst.Text, cmaDir.Text);
|
||||
|
||||
bool isPs1 = IsPs1(ebootFile);
|
||||
|
||||
if (!File.Exists(licenseFile))
|
||||
{
|
||||
MessageBox.Show("Could not find LICENSE file!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
transVita.Enabled = true;
|
||||
driveLetterDst.Enabled = true;
|
||||
driveLetterSrc.Enabled = true;
|
||||
pspFolder.ReadOnly = false;
|
||||
cmaDir.ReadOnly = false;
|
||||
pspGames.Enabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
FileStream rif = File.OpenRead(licenseFile);
|
||||
byte[] bAid = new byte[0x08];
|
||||
rif.Seek(0x08, SeekOrigin.Begin);
|
||||
rif.Read(bAid, 0x00, 0x08);
|
||||
rif.Close();
|
||||
string sAid = BitConverter.ToString(bAid).Replace("-", "").ToLower();
|
||||
UInt64 uAid = BitConverter.ToUInt64(bAid, 0x00);
|
||||
|
||||
if(File.Exists(sigFile))
|
||||
{
|
||||
File.Delete(sigFile);
|
||||
}
|
||||
|
||||
int ChovyGenRes = chovy_gen(ebootFile, uAid, sigFile);
|
||||
|
||||
if (!File.Exists(sigFile) || ChovyGenRes != 0)
|
||||
{
|
||||
MessageBox.Show("CHOVY-GEN Failed! Please check CHOVY.DLL exists\nand that the Microsoft Visual C++ 2015 Redistributable Update 3 RC is installed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
transVita.Enabled = true;
|
||||
driveLetterDst.Enabled = true;
|
||||
driveLetterSrc.Enabled = true;
|
||||
pspFolder.ReadOnly = false;
|
||||
cmaDir.ReadOnly = false;
|
||||
pspGames.Enabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* BUILD PSVIMG FILE(s)
|
||||
*/
|
||||
|
||||
// Pacakge GAME
|
||||
|
||||
byte[] CmaKey = CmaKeys.GenerateKey(bAid);
|
||||
|
||||
string[] entrys = Directory.GetFileSystemEntries(gameFolder, "*", SearchOption.AllDirectories);
|
||||
long noEntrys = entrys.LongLength;
|
||||
string parentPath = "ux0:pspemu/temp/game/PSP/GAME/" + titleId;
|
||||
int noBlocks = 0;
|
||||
foreach (string fileName in Directory.GetFiles(gameFolder, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
noBlocks += Convert.ToInt32(new FileInfo(fileName).Length / PSVIMGConstants.PSVIMG_BLOCK_SIZE);
|
||||
}
|
||||
progressBar.Maximum = noBlocks;
|
||||
|
||||
|
||||
string pgameFolder;
|
||||
string pgameFolderl;
|
||||
string scesys;
|
||||
if (!isPs1)
|
||||
{
|
||||
pgameFolder = Path.Combine(backupDir, "PGAME", sAid, titleId, "game");
|
||||
pgameFolderl = Path.Combine(backupDir, "PGAME", sAid, titleId, "license");
|
||||
scesys = Path.Combine(backupDir, "PGAME", sAid, titleId, "sce_sys");
|
||||
}
|
||||
else
|
||||
{
|
||||
pgameFolder = Path.Combine(backupDir, "PSGAME", sAid, titleId, "game");
|
||||
pgameFolderl = Path.Combine(backupDir, "PSGAME", sAid, titleId, "license");
|
||||
scesys = Path.Combine(backupDir, "PSGAME", sAid, titleId, "sce_sys");
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(pgameFolder);
|
||||
Directory.CreateDirectory(pgameFolderl);
|
||||
Directory.CreateDirectory(scesys);
|
||||
|
||||
string psvimgFilepathl = Path.Combine(pgameFolderl, "license.psvimg");
|
||||
string psvimgFilepath = Path.Combine(pgameFolder, "game.psvimg");
|
||||
|
||||
string psvmdFilepathl = Path.Combine(pgameFolderl, "license.psvmd");
|
||||
string psvmdFilepath = Path.Combine(pgameFolder, "game.psvmd");
|
||||
|
||||
FileStream gamePsvimg = File.OpenWrite(psvimgFilepath);
|
||||
gamePsvimg.SetLength(0);
|
||||
PSVIMGBuilder builder = new PSVIMGBuilder(gamePsvimg, CmaKey);
|
||||
|
||||
foreach (string entry in entrys)
|
||||
{
|
||||
string relativePath = entry.Remove(0, gameFolder.Length);
|
||||
relativePath = relativePath.Replace('\\', '/');
|
||||
|
||||
bool isDir = File.GetAttributes(entry).HasFlag(FileAttributes.Directory);
|
||||
|
||||
if (isDir)
|
||||
{
|
||||
builder.AddDir(entry, parentPath, relativePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AddFileAsync(entry, parentPath, relativePath);
|
||||
while (!builder.HasFinished)
|
||||
{
|
||||
try
|
||||
{
|
||||
int tBlocks = builder.BlocksWritten;
|
||||
progressBar.Value = tBlocks;
|
||||
decimal progress = Math.Floor(((decimal)tBlocks / (decimal)noBlocks) * 100);
|
||||
progressStatus.Text = progress.ToString() + "%";
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
Application.DoEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long ContentSize = builder.Finish();
|
||||
gamePsvimg = File.OpenRead(psvimgFilepath);
|
||||
FileStream gamePsvmd = File.OpenWrite(psvmdFilepath);
|
||||
PSVMDBuilder.CreatePsvmd(gamePsvmd, gamePsvimg, ContentSize, "game", CmaKey);
|
||||
gamePsvmd.Close();
|
||||
gamePsvimg.Close();
|
||||
|
||||
|
||||
// Package LICENSE
|
||||
FileStream licensePsvimg = File.OpenWrite(psvimgFilepathl);
|
||||
licensePsvimg.SetLength(0);
|
||||
builder = new PSVIMGBuilder(licensePsvimg, CmaKey);
|
||||
builder.AddFile(licenseFile, "ux0:pspemu/temp/game/PSP/LICENSE", "/" + cid + ".rif");
|
||||
ContentSize = builder.Finish();
|
||||
|
||||
licensePsvimg = File.OpenRead(psvimgFilepathl);
|
||||
FileStream licensePsvmd = File.OpenWrite(psvmdFilepathl);
|
||||
PSVMDBuilder.CreatePsvmd(licensePsvmd, licensePsvimg, ContentSize, "license", CmaKey);
|
||||
licensePsvmd.Close();
|
||||
licensePsvimg.Close();
|
||||
|
||||
// Write PARAM.SFO & ICON0.PNG
|
||||
|
||||
byte[] ParamSfo = GetSfo(ebootFile);
|
||||
byte[] Icon0 = GetIcon0(ebootFile);
|
||||
File.WriteAllBytes(Path.Combine(scesys, "param.sfo"), ParamSfo);
|
||||
File.WriteAllBytes(Path.Combine(scesys, "icon0.png"), Icon0);
|
||||
|
||||
if(!isPs1)
|
||||
{
|
||||
MessageBox.Show("Success!\nYou can now Restore the game onto your PSVita from\n[Content Mannager] (Copy Content) -> (PC) -> (Applications) -> (PC -> This System) -> (PSP/Others)", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Success!\nYou can now Restore the game onto your PSVita from\n[Content Mannager] (Copy Content) -> (PC) -> (Applications) -> (PC -> This System) -> (PlayStation)", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
progressBar.Value = 0;
|
||||
progressStatus.Text = "0%";
|
||||
|
||||
transVita.Enabled = true;
|
||||
driveLetterDst.Enabled = true;
|
||||
driveLetterSrc.Enabled = true;
|
||||
pspFolder.ReadOnly = false;
|
||||
cmaDir.ReadOnly = false;
|
||||
pspGames.Enabled = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
1517
CHOVY-TRANSFER/CHOVYTRANSFER.resx
Normal file
1517
CHOVY-TRANSFER/CHOVYTRANSFER.resx
Normal file
File diff suppressed because it is too large
Load Diff
488
CHOVY-TRANSFER/PSVIMGBuilder.cs
Normal file
488
CHOVY-TRANSFER/PSVIMGBuilder.cs
Normal file
|
@ -0,0 +1,488 @@
|
|||
using Org.BouncyCastle.Crypto.Digests;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using static PSVIMGTOOLS.SceIoStat;
|
||||
|
||||
namespace PSVIMGTOOLS
|
||||
{
|
||||
class PSVIMGBuilder
|
||||
{
|
||||
private byte[] IV = new byte[0x10];
|
||||
private byte[] KEY;
|
||||
private Random rnd = new Random();
|
||||
private Stream mainStream;
|
||||
private Sha256Digest shaCtx;
|
||||
private byte[] blockData;
|
||||
private MemoryStream blockStream;
|
||||
private long contentSize = 0;
|
||||
|
||||
|
||||
//async
|
||||
private int blocksWritten = 0;
|
||||
private bool finished = false;
|
||||
|
||||
public Int64 ContentSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return contentSize;
|
||||
}
|
||||
}
|
||||
public Int32 BlocksWritten
|
||||
{
|
||||
get
|
||||
{
|
||||
return blocksWritten;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean HasFinished
|
||||
{
|
||||
get
|
||||
{
|
||||
return finished;
|
||||
}
|
||||
}
|
||||
|
||||
//Footer
|
||||
private long totalBytes = 0;
|
||||
|
||||
private byte[] aes_cbc_encrypt(byte[] plainText, byte[] IV, byte[] KEY, int size=-1)
|
||||
{
|
||||
if (size < 0)
|
||||
{
|
||||
size = plainText.Length;
|
||||
}
|
||||
|
||||
MemoryStream ms = new MemoryStream();
|
||||
/*
|
||||
*- DEBUG Disable Encryption
|
||||
ms.Write(plainText, 0x00, size);
|
||||
ms.Seek(0x00,SeekOrigin.Begin);
|
||||
return ms.ToArray();*/
|
||||
|
||||
Aes alg = Aes.Create();
|
||||
alg.Mode = CipherMode.CBC;
|
||||
alg.Padding = PaddingMode.None;
|
||||
alg.KeySize = 256;
|
||||
alg.BlockSize = 128;
|
||||
alg.Key = KEY;
|
||||
alg.IV = IV;
|
||||
CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
|
||||
cs.Write(plainText, 0, size);
|
||||
cs.Close();
|
||||
byte[] cipherText = ms.ToArray();
|
||||
return cipherText;
|
||||
}
|
||||
|
||||
private byte[] aes_ecb_encrypt(byte[] plainText, byte[] KEY, int size = -1)
|
||||
{
|
||||
if (size < 0)
|
||||
{
|
||||
size = plainText.Length;
|
||||
}
|
||||
|
||||
MemoryStream ms = new MemoryStream();
|
||||
/*
|
||||
*- DEBUG Disable Encryption
|
||||
ms.Write(plainText, 0x00, size);
|
||||
ms.Seek(0x00,SeekOrigin.Begin);
|
||||
return ms.ToArray();*/
|
||||
|
||||
Aes alg = Aes.Create();
|
||||
alg.Mode = CipherMode.ECB;
|
||||
alg.Padding = PaddingMode.None;
|
||||
alg.KeySize = 256;
|
||||
alg.BlockSize = 128;
|
||||
alg.Key = KEY;
|
||||
CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
|
||||
cs.Write(plainText, 0, size);
|
||||
cs.Close();
|
||||
byte[] cipherText = ms.ToArray();
|
||||
return cipherText;
|
||||
}
|
||||
|
||||
private void writeUInt64(Stream dst,UInt64 value)
|
||||
{
|
||||
byte[] ValueBytes = BitConverter.GetBytes(value);
|
||||
dst.Write(ValueBytes, 0x00, 0x8);
|
||||
}
|
||||
private void writeInt64(Stream dst,Int64 value)
|
||||
{
|
||||
byte[] ValueBytes = BitConverter.GetBytes(value);
|
||||
dst.Write(ValueBytes, 0x00, 0x8);
|
||||
}
|
||||
private void writeUInt16(Stream dst, UInt16 value)
|
||||
{
|
||||
byte[] ValueBytes = BitConverter.GetBytes(value);
|
||||
dst.Write(ValueBytes, 0x00, 0x2);
|
||||
}
|
||||
private void writeInt16(Stream dst, Int16 value)
|
||||
{
|
||||
byte[] ValueBytes = BitConverter.GetBytes(value);
|
||||
dst.Write(ValueBytes, 0x00, 0x2);
|
||||
}
|
||||
|
||||
private void writeInt32(Stream dst, Int32 value)
|
||||
{
|
||||
byte[] ValueBytes = BitConverter.GetBytes(value);
|
||||
dst.Write(ValueBytes, 0x00, 0x4);
|
||||
}
|
||||
private void writeUInt32(Stream dst, UInt32 value)
|
||||
{
|
||||
byte[] ValueBytes = BitConverter.GetBytes(value);
|
||||
dst.Write(ValueBytes, 0x00, 0x4);
|
||||
}
|
||||
|
||||
private SceDateTime dateTimeToSceDateTime(DateTime dt)
|
||||
{
|
||||
SceDateTime sdt = new SceDateTime();
|
||||
sdt.Day = Convert.ToUInt16(dt.Day);
|
||||
sdt.Month = Convert.ToUInt16(dt.Month);
|
||||
sdt.Year = Convert.ToUInt16(dt.Year);
|
||||
|
||||
|
||||
sdt.Hour = Convert.ToUInt16(dt.Hour);
|
||||
sdt.Minute = Convert.ToUInt16(dt.Minute);
|
||||
sdt.Second = Convert.ToUInt16(dt.Second);
|
||||
sdt.Microsecond = Convert.ToUInt32(dt.Millisecond * 1000);
|
||||
return sdt;
|
||||
}
|
||||
|
||||
private SceIoStat sceIoStat(string path)
|
||||
{
|
||||
SceIoStat stats = new SceIoStat();
|
||||
FileAttributes attrbutes = File.GetAttributes(path);
|
||||
|
||||
if (attrbutes.HasFlag(FileAttributes.Directory))
|
||||
{
|
||||
stats.Mode |= Modes.Directory;
|
||||
stats.Size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.Mode |= Modes.File;
|
||||
stats.Size = Convert.ToUInt64(new FileInfo(path).Length);
|
||||
|
||||
}
|
||||
|
||||
if(attrbutes.HasFlag(FileAttributes.ReadOnly))
|
||||
{
|
||||
stats.Mode |= Modes.GroupRead;
|
||||
|
||||
stats.Mode |= Modes.OthersRead;
|
||||
|
||||
stats.Mode |= Modes.UserRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.Mode |= Modes.GroupRead;
|
||||
stats.Mode |= Modes.GroupWrite;
|
||||
|
||||
stats.Mode |= Modes.OthersRead;
|
||||
stats.Mode |= Modes.OthersWrite;
|
||||
|
||||
stats.Mode |= Modes.UserRead;
|
||||
stats.Mode |= Modes.UserWrite;
|
||||
}
|
||||
|
||||
stats.CreationTime = dateTimeToSceDateTime(File.GetCreationTimeUtc(path));
|
||||
stats.AccessTime = dateTimeToSceDateTime(File.GetLastAccessTimeUtc(path));
|
||||
stats.ModificaionTime = dateTimeToSceDateTime(File.GetLastWriteTimeUtc(path));
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
private void writeSceDateTime(Stream dst,SceDateTime time)
|
||||
{
|
||||
writeUInt16(dst, time.Year);
|
||||
writeUInt16(dst, time.Month);
|
||||
writeUInt16(dst, time.Day);
|
||||
|
||||
writeUInt16(dst, time.Hour);
|
||||
writeUInt16(dst, time.Minute);
|
||||
writeUInt16(dst, time.Second);
|
||||
writeUInt32(dst, time.Microsecond);
|
||||
}
|
||||
|
||||
private void writeSceIoStat(Stream dst, SceIoStat stats)
|
||||
{
|
||||
writeUInt32(dst, Convert.ToUInt32(stats.Mode));
|
||||
writeUInt32(dst, Convert.ToUInt32(stats.Attributes));
|
||||
writeUInt64(dst, stats.Size);
|
||||
writeSceDateTime(dst, stats.CreationTime);
|
||||
writeSceDateTime(dst, stats.AccessTime);
|
||||
writeSceDateTime(dst, stats.ModificaionTime);
|
||||
foreach(UInt32 i in stats.Private)
|
||||
{
|
||||
writeUInt32(dst,i);
|
||||
}
|
||||
}
|
||||
|
||||
private void memset(byte[] buf, byte content, long length)
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
buf[i] = content;
|
||||
}
|
||||
}
|
||||
|
||||
private void writeStringWithPadding(Stream dst, string str, int padSize, byte padByte = 0x78)
|
||||
{
|
||||
int StrLen = str.Length;
|
||||
if(StrLen > padSize)
|
||||
{
|
||||
StrLen = padSize;
|
||||
}
|
||||
|
||||
int PaddingLen = (padSize - StrLen)-1;
|
||||
writeString(dst, str, StrLen);
|
||||
dst.WriteByte(0x00);
|
||||
writePadding(dst, padByte, PaddingLen);
|
||||
}
|
||||
|
||||
private void writeString(Stream dst, string str, int len=-1)
|
||||
{
|
||||
if(len < 0)
|
||||
{
|
||||
len = str.Length;
|
||||
}
|
||||
|
||||
byte[] StrBytes = Encoding.UTF8.GetBytes(str);
|
||||
dst.Write(StrBytes, 0x00, len);
|
||||
}
|
||||
|
||||
private void writePadding(Stream dst, byte paddingByte, long paddingLen)
|
||||
{
|
||||
byte[] paddingData = new byte[paddingLen];
|
||||
memset(paddingData, paddingByte, paddingLen);
|
||||
dst.Write(paddingData, 0x00, paddingData.Length);
|
||||
}
|
||||
private byte[] getHeader(string FilePath, string ParentPath, string PathRel)
|
||||
{
|
||||
using (MemoryStream Header = new MemoryStream())
|
||||
{
|
||||
writeInt64(Header, DateTime.UtcNow.Ticks); // SysTime
|
||||
writeInt64(Header, 0); // Flags
|
||||
writeSceIoStat(Header, sceIoStat(FilePath));
|
||||
writeStringWithPadding(Header, ParentPath, 256); // Parent Path
|
||||
writeUInt32(Header, 1); //unk_16C
|
||||
writeStringWithPadding(Header, PathRel, 256); //Relative Path
|
||||
writePadding(Header, 0x78, 904); //'x'
|
||||
writeString(Header, PSVIMGConstants.PSVIMG_HEADER_END); //EndOfHeader
|
||||
Header.Seek(0x00, SeekOrigin.Begin);
|
||||
return Header.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private void startNewBlock()
|
||||
{
|
||||
blockData = new byte[PSVIMGConstants.FULL_PSVIMG_SIZE];
|
||||
blockStream = new MemoryStream(blockData, 0x00, PSVIMGConstants.FULL_PSVIMG_SIZE);
|
||||
}
|
||||
|
||||
|
||||
private byte[] shaBlock(int length = PSVIMGConstants.PSVIMG_BLOCK_SIZE,bool final=false)
|
||||
{
|
||||
byte[] outbytes = new byte[PSVIMGConstants.SHA256_BLOCK_SIZE];
|
||||
shaCtx.BlockUpdate(blockData, 0x00, length);
|
||||
Sha256Digest shaTmp = (Sha256Digest)shaCtx.Copy();
|
||||
shaTmp.DoFinal(outbytes,0x00);
|
||||
return outbytes;
|
||||
}
|
||||
|
||||
private void finishBlock(bool final = false)
|
||||
{
|
||||
int len = Convert.ToInt32(blockStream.Position);
|
||||
byte[] shaBytes = shaBlock(len, final);
|
||||
blockStream.Write(shaBytes, 0x00, PSVIMGConstants.SHA256_BLOCK_SIZE);
|
||||
len += PSVIMGConstants.SHA256_BLOCK_SIZE;
|
||||
|
||||
//Get next IV
|
||||
byte[] encryptedBlock = aes_cbc_encrypt(blockData, IV, KEY, len);
|
||||
for (int i = 0; i < IV.Length; i++)
|
||||
{
|
||||
int encBlockOffset = (encryptedBlock.Length - IV.Length)+i;
|
||||
IV[i] = encryptedBlock[encBlockOffset];
|
||||
}
|
||||
|
||||
mainStream.Write(encryptedBlock, 0x00, encryptedBlock.Length);
|
||||
totalBytes += encryptedBlock.Length;
|
||||
|
||||
blockStream.Dispose();
|
||||
}
|
||||
|
||||
private int remainingBlockSize()
|
||||
{
|
||||
return Convert.ToInt32((PSVIMGConstants.PSVIMG_BLOCK_SIZE - blockStream.Position));
|
||||
}
|
||||
|
||||
private void writeBlock(byte[] data, bool update=false)
|
||||
{
|
||||
long dLen = data.Length;
|
||||
long writeTotal = 0;
|
||||
while (dLen > 0)
|
||||
{
|
||||
int remaining = remainingBlockSize();
|
||||
|
||||
if (dLen > remaining)
|
||||
{
|
||||
byte[] dataRemains = new byte[remaining];
|
||||
Array.Copy(data, writeTotal, dataRemains, 0, remaining);
|
||||
blockStream.Write(dataRemains, 0x00, remaining);
|
||||
|
||||
writeTotal += remaining;
|
||||
dLen -= remaining;
|
||||
|
||||
|
||||
finishBlock();
|
||||
startNewBlock();
|
||||
if (update)
|
||||
{
|
||||
blocksWritten += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] dataRemains = new byte[dLen];
|
||||
Array.Copy(data, writeTotal, dataRemains, 0, dLen);
|
||||
blockStream.Write(dataRemains, 0x00, Convert.ToInt32(dLen));
|
||||
|
||||
writeTotal += dLen;
|
||||
dLen -= dLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
private byte[] getPadding(long size)
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
long paddingSize = PSVIMGPadding.GetPadding(size);
|
||||
if(paddingSize != 0)
|
||||
{
|
||||
writePadding(ms, 0x2B, paddingSize-PSVIMGConstants.PSVIMG_PADDING_END.Length);
|
||||
writeString(ms, PSVIMGConstants.PSVIMG_PADDING_END);
|
||||
}
|
||||
ms.Seek(0x00, SeekOrigin.Begin);
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] getTailer()
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
writeUInt64(ms, 0x00);
|
||||
writePadding(ms, 0x7a, 1004);
|
||||
writeString(ms, PSVIMGConstants.PSVIMG_TAILOR_END);
|
||||
|
||||
ms.Seek(0x00, SeekOrigin.Begin);
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeStream(Stream dst)
|
||||
{
|
||||
while(dst.Position < dst.Length)
|
||||
{
|
||||
byte[] work_buf;
|
||||
Int64 bytes_remain = (dst.Length - dst.Position);
|
||||
if (bytes_remain > 0x33554432)
|
||||
{
|
||||
work_buf = new byte[0x33554432];
|
||||
}
|
||||
else
|
||||
{
|
||||
work_buf = new byte[bytes_remain];
|
||||
}
|
||||
dst.Read(work_buf, 0x00, work_buf.Length);
|
||||
writeBlock(work_buf, true);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] getFooter()
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
totalBytes += 0x10; //number of bytes used by this footer.
|
||||
|
||||
writeInt32(ms, 0x00); // int padding (idk wht this is)
|
||||
writeUInt32(ms, 0x00);
|
||||
writeInt64(ms, totalBytes);
|
||||
ms.Seek(0x00, SeekOrigin.Begin);
|
||||
return aes_cbc_encrypt(ms.ToArray(), IV, KEY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void AddFileAsync(string FilePath, string ParentPath, string PathRel)
|
||||
{
|
||||
finished = false;
|
||||
new Thread(() =>
|
||||
{
|
||||
long sz = Convert.ToInt64(sceIoStat(FilePath).Size);
|
||||
writeBlock(getHeader(FilePath, ParentPath, PathRel));
|
||||
using (FileStream fs = File.OpenRead(FilePath))
|
||||
{
|
||||
writeStream(fs);
|
||||
}
|
||||
writeBlock(getPadding(sz));
|
||||
writeBlock(getTailer());
|
||||
contentSize += sz;
|
||||
finished = true;
|
||||
}).Start();
|
||||
|
||||
}
|
||||
public void AddFile(string FilePath, string ParentPath, string PathRel)
|
||||
{
|
||||
|
||||
long sz = Convert.ToInt64(sceIoStat(FilePath).Size);
|
||||
writeBlock(getHeader(FilePath, ParentPath, PathRel));
|
||||
using (FileStream fs = File.OpenRead(FilePath))
|
||||
{
|
||||
writeStream(fs);
|
||||
}
|
||||
writeBlock(getPadding(sz));
|
||||
writeBlock(getTailer());
|
||||
contentSize += sz;
|
||||
}
|
||||
|
||||
public void AddDir(string DirPath, string ParentPath, string PathRel)
|
||||
{
|
||||
writeBlock(getHeader(DirPath, ParentPath, PathRel));
|
||||
writeBlock(getPadding(0));
|
||||
writeBlock(getTailer());
|
||||
}
|
||||
public long Finish()
|
||||
{
|
||||
finishBlock(true);
|
||||
byte[] footer = getFooter();
|
||||
mainStream.Write(footer, 0x00, footer.Length);
|
||||
|
||||
blockStream.Dispose();
|
||||
mainStream.Dispose();
|
||||
return contentSize;
|
||||
}
|
||||
|
||||
|
||||
public PSVIMGBuilder(Stream dst, byte[] Key)
|
||||
{
|
||||
totalBytes = 0;
|
||||
contentSize = 0;
|
||||
shaCtx = new Sha256Digest();
|
||||
mainStream = dst;
|
||||
KEY = Key;
|
||||
|
||||
rnd.NextBytes(IV);
|
||||
IV = aes_ecb_encrypt(IV, Key);
|
||||
|
||||
mainStream.Write(IV, 0x00, IV.Length);
|
||||
totalBytes += IV.Length;
|
||||
|
||||
startNewBlock();
|
||||
}
|
||||
}
|
||||
}
|
212
CHOVY-TRANSFER/PSVIMGStructs.cs
Normal file
212
CHOVY-TRANSFER/PSVIMGStructs.cs
Normal file
|
@ -0,0 +1,212 @@
|
|||
using System;
|
||||
|
||||
namespace PSVIMGTOOLS
|
||||
{
|
||||
|
||||
internal class PSVIMGConstants
|
||||
{
|
||||
public const int AES_BLOCK_SIZE = 0x10;
|
||||
public const int SHA256_BLOCK_SIZE = 0x20;
|
||||
public const int PSVIMG_BLOCK_SIZE = 0x8000;
|
||||
public const int PSVIMG_ENTRY_ALIGN = 0x400;
|
||||
|
||||
public const string PSVIMG_HEADER_END = "EndOfHeader\n";
|
||||
public const string PSVIMG_TAILOR_END = "EndOfTailer\n";
|
||||
public const string PSVIMG_PADDING_END = "\n";
|
||||
|
||||
public const int FULL_PSVIMG_SIZE = PSVIMG_BLOCK_SIZE + SHA256_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
internal class StringReader
|
||||
{
|
||||
internal static string ReadUntilTerminator(byte[] StringBytes)
|
||||
{
|
||||
string str = "";
|
||||
foreach (byte sByte in StringBytes)
|
||||
{
|
||||
if (sByte != 0x00)
|
||||
{
|
||||
str += (char)sByte;
|
||||
}
|
||||
else
|
||||
{
|
||||
return str;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
internal class SceDateTime
|
||||
{
|
||||
public UInt16 Year;
|
||||
public UInt16 Month;
|
||||
public UInt16 Day;
|
||||
public UInt16 Hour;
|
||||
public UInt16 Minute;
|
||||
public UInt16 Second;
|
||||
public UInt32 Microsecond;
|
||||
|
||||
public SceDateTime()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
internal class SceIoStat
|
||||
{
|
||||
public enum Modes{
|
||||
/** Format bits mask */
|
||||
FormatBits = 0xF000,
|
||||
/** Symbolic link */
|
||||
SymbLink = 0x4000,
|
||||
/** Directory */
|
||||
Directory = 0x1000,
|
||||
/** Regular file */
|
||||
File = 0x2000,
|
||||
|
||||
/** Set UID */
|
||||
SetUid = 0x0800,
|
||||
/** Set GID */
|
||||
SetGid = 0x0400,
|
||||
/** Sticky */
|
||||
Sticky = 0x0200,
|
||||
|
||||
/** Others access rights mask */
|
||||
OthersAcesssMask = 0x01C0,
|
||||
/** Others read permission */
|
||||
OthersRead = 0x0100,
|
||||
/** Others write permission */
|
||||
OthersWrite = 0x0080,
|
||||
/** Others execute permission */
|
||||
OthersExecute = 0x0040,
|
||||
|
||||
/** Group access rights mask */
|
||||
GroupAcessMask = 0x0038,
|
||||
/** Group read permission */
|
||||
GroupRead = 0x0020,
|
||||
/** Group write permission */
|
||||
GroupWrite = 0x0010,
|
||||
/** Group execute permission */
|
||||
GroupExecute = 0x0008,
|
||||
|
||||
/** User access rights mask */
|
||||
UserAcessMask = 0x0007,
|
||||
/** User read permission */
|
||||
UserRead = 0x0004,
|
||||
/** User write permission */
|
||||
UserWrite = 0x0002,
|
||||
/** User execute permission */
|
||||
UserExecute = 0x0001,
|
||||
};
|
||||
public enum AttributesEnum
|
||||
{
|
||||
/** Format mask */
|
||||
FormatMask = 0x0038, // Format mask
|
||||
/** Symlink */
|
||||
SymbLink = 0x0008, // Symbolic link
|
||||
/** Directory */
|
||||
Directory = 0x0010, // Directory
|
||||
/** Regular file */
|
||||
File = 0x0020, // Regular file
|
||||
|
||||
/** Hidden read permission */
|
||||
Read = 0x0004, // read
|
||||
/** Hidden write permission */
|
||||
Write = 0x0002, // write
|
||||
/** Hidden execute permission */
|
||||
Execute = 0x0001, // execute
|
||||
};
|
||||
|
||||
public Modes Mode;
|
||||
public AttributesEnum Attributes;
|
||||
/** Size of the file in bytes. */
|
||||
public UInt64 Size;
|
||||
/** Creation time. */
|
||||
public SceDateTime CreationTime;
|
||||
/** Access time. */
|
||||
public SceDateTime AccessTime;
|
||||
/** Modification time. */
|
||||
public SceDateTime ModificaionTime;
|
||||
/** Device-specific data. */
|
||||
public UInt32[] Private = new UInt32[6];
|
||||
public SceIoStat()
|
||||
{
|
||||
for(int i = 0; i < Private.Length; i++)
|
||||
{
|
||||
Private[i] = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
internal class PsvImgTailer
|
||||
{
|
||||
public UInt64 Flags;
|
||||
public Byte[] Padding = new Byte[1004];
|
||||
public Byte[] bEnd = new Byte[12];
|
||||
|
||||
public String End
|
||||
{
|
||||
get
|
||||
{
|
||||
return StringReader.ReadUntilTerminator(bEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
internal class PSVIMGPadding
|
||||
{
|
||||
public static long GetPadding(long size)
|
||||
{
|
||||
long padding;
|
||||
if ((size & (PSVIMGConstants.PSVIMG_ENTRY_ALIGN - 1)) >= 1)
|
||||
{
|
||||
padding = (PSVIMGConstants.PSVIMG_ENTRY_ALIGN - (size & (PSVIMGConstants.PSVIMG_ENTRY_ALIGN - 1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
padding = 0;
|
||||
}
|
||||
return padding;
|
||||
}
|
||||
}
|
||||
|
||||
internal class PsvImgHeader
|
||||
{
|
||||
public UInt64 SysTime;
|
||||
public UInt64 Flags;
|
||||
public SceIoStat Statistics;
|
||||
public Byte[] bParentPath = new Byte[256];
|
||||
public UInt32 unk_16C; // set to 1
|
||||
public Byte[] bPath = new Byte[256];
|
||||
public Byte[] Padding = new Byte[904];
|
||||
public Byte[] bEnd = new Byte[12];
|
||||
|
||||
public String Path
|
||||
{
|
||||
get
|
||||
{
|
||||
return StringReader.ReadUntilTerminator(bPath);
|
||||
}
|
||||
}
|
||||
|
||||
public String End
|
||||
{
|
||||
get
|
||||
{
|
||||
return StringReader.ReadUntilTerminator(bEnd);
|
||||
}
|
||||
}
|
||||
|
||||
public String ParentPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return StringReader.ReadUntilTerminator(bParentPath);
|
||||
}
|
||||
}
|
||||
public PsvImgHeader()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
208
CHOVY-TRANSFER/PSVMDBuilder.cs
Normal file
208
CHOVY-TRANSFER/PSVMDBuilder.cs
Normal file
|
@ -0,0 +1,208 @@
|
|||
using Ionic.Zlib;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
namespace PSVIMGTOOLS
|
||||
{
|
||||
class PSVMDBuilder
|
||||
{
|
||||
private static void memset(byte[] buf, byte content, long length)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
buf[i] = content;
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeUInt64(Stream dst, UInt64 value)
|
||||
{
|
||||
byte[] ValueBytes = BitConverter.GetBytes(value);
|
||||
dst.Write(ValueBytes, 0x00, 0x8);
|
||||
}
|
||||
private static void writeInt64(Stream dst, Int64 value)
|
||||
{
|
||||
byte[] ValueBytes = BitConverter.GetBytes(value);
|
||||
dst.Write(ValueBytes, 0x00, 0x8);
|
||||
}
|
||||
private static void writeUInt16(Stream dst, UInt16 value)
|
||||
{
|
||||
byte[] ValueBytes = BitConverter.GetBytes(value);
|
||||
dst.Write(ValueBytes, 0x00, 0x2);
|
||||
}
|
||||
private static void writeInt16(Stream dst, Int16 value)
|
||||
{
|
||||
byte[] ValueBytes = BitConverter.GetBytes(value);
|
||||
dst.Write(ValueBytes, 0x00, 0x2);
|
||||
}
|
||||
|
||||
private static void writeInt32(Stream dst, Int32 value)
|
||||
{
|
||||
byte[] ValueBytes = BitConverter.GetBytes(value);
|
||||
dst.Write(ValueBytes, 0x00, 0x4);
|
||||
}
|
||||
private static void writeUInt32(Stream dst, UInt32 value)
|
||||
{
|
||||
byte[] ValueBytes = BitConverter.GetBytes(value);
|
||||
dst.Write(ValueBytes, 0x00, 0x4);
|
||||
}
|
||||
|
||||
|
||||
private static void writeString(Stream dst, string str, int len = -1)
|
||||
{
|
||||
if (len < 0)
|
||||
{
|
||||
len = str.Length;
|
||||
}
|
||||
|
||||
byte[] StrBytes = Encoding.UTF8.GetBytes(str);
|
||||
dst.Write(StrBytes, 0x00, len);
|
||||
}
|
||||
|
||||
private static void writePadding(Stream dst, byte paddingByte, long paddingLen)
|
||||
{
|
||||
byte[] paddingData = new byte[paddingLen];
|
||||
memset(paddingData, paddingByte, paddingLen);
|
||||
dst.Write(paddingData, 0x00, paddingData.Length);
|
||||
}
|
||||
private static void writeStringWithPadding(Stream dst, string str, int padSize, byte padByte = 0x78)
|
||||
{
|
||||
int StrLen = str.Length;
|
||||
if (StrLen > padSize)
|
||||
{
|
||||
StrLen = padSize;
|
||||
}
|
||||
|
||||
int PaddingLen = (padSize - StrLen) - 1;
|
||||
writeString(dst, str, StrLen);
|
||||
dst.WriteByte(0x00);
|
||||
writePadding(dst, padByte, PaddingLen);
|
||||
}
|
||||
|
||||
private static byte[] aes_ecb_decrypt(byte[] cipherText, byte[] KEY, int size = -1)
|
||||
{
|
||||
if (size < 0)
|
||||
{
|
||||
size = cipherText.Length;
|
||||
}
|
||||
|
||||
MemoryStream ms = new MemoryStream();
|
||||
|
||||
Aes alg = Aes.Create();
|
||||
alg.Mode = CipherMode.ECB;
|
||||
alg.Padding = PaddingMode.None;
|
||||
alg.KeySize = 256;
|
||||
alg.BlockSize = 128;
|
||||
alg.Key = KEY;
|
||||
CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);
|
||||
cs.Write(cipherText, 0, size);
|
||||
cs.Close();
|
||||
byte[] plainText = ms.ToArray();
|
||||
return plainText;
|
||||
}
|
||||
|
||||
private static byte[] aes_cbc_decrypt(byte[] cipherData, byte[] IV, byte[] Key)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
Aes alg = Aes.Create();
|
||||
alg.Mode = CipherMode.CBC;
|
||||
alg.Padding = PaddingMode.None;
|
||||
alg.KeySize = 256;
|
||||
alg.BlockSize = 128;
|
||||
alg.Key = Key;
|
||||
alg.IV = IV;
|
||||
CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);
|
||||
cs.Write(cipherData, 0, cipherData.Length);
|
||||
cs.Close();
|
||||
byte[] decryptedData = ms.ToArray();
|
||||
return decryptedData;
|
||||
}
|
||||
private static byte[] aes_cbc_encrypt(byte[] plainText, byte[] IV, byte[] KEY, int size = -1)
|
||||
{
|
||||
if (size < 0)
|
||||
{
|
||||
size = plainText.Length;
|
||||
}
|
||||
|
||||
MemoryStream ms = new MemoryStream();
|
||||
|
||||
Aes alg = Aes.Create();
|
||||
alg.Mode = CipherMode.CBC;
|
||||
alg.Padding = PaddingMode.None;
|
||||
alg.KeySize = 256;
|
||||
alg.BlockSize = 128;
|
||||
alg.Key = KEY;
|
||||
alg.IV = IV;
|
||||
CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
|
||||
cs.Write(plainText, 0, size);
|
||||
cs.Close();
|
||||
byte[] cipherText = ms.ToArray();
|
||||
return cipherText;
|
||||
}
|
||||
|
||||
|
||||
public static void CreatePsvmd(Stream OutputStream, Stream EncryptedPsvimg, long ContentSize, string BackupType,byte[] Key)
|
||||
{
|
||||
byte[] IV = new byte[PSVIMGConstants.AES_BLOCK_SIZE];
|
||||
EncryptedPsvimg.Seek(0x00, SeekOrigin.Begin);
|
||||
EncryptedPsvimg.Read(IV, 0x00, IV.Length);
|
||||
IV = aes_ecb_decrypt(IV, Key);
|
||||
MemoryStream ms = new MemoryStream();
|
||||
|
||||
writeUInt32(ms, 0xFEE1900D); // magic
|
||||
writeUInt32(ms, 0x2); // type
|
||||
writeUInt64(ms, 0x03000000); // fw ver
|
||||
ms.Write(new byte[0x10], 0x00, 0x10); // PSID
|
||||
writeStringWithPadding(ms, BackupType, 0x40, 0x00); //backup type
|
||||
writeInt64(ms, EncryptedPsvimg.Length); // total size
|
||||
writeUInt64(ms, 0x2); //version
|
||||
writeInt64(ms, ContentSize); // content size
|
||||
ms.Write(IV, 0x00, 0x10); // IV
|
||||
writeUInt64(ms, 0x00); //ux0 info
|
||||
writeUInt64(ms, 0x00); //ur0 info
|
||||
writeUInt64(ms, 0x00); //unused 98
|
||||
writeUInt64(ms, 0x00); //unused A0
|
||||
writeUInt32(ms, 0x1); //add data
|
||||
|
||||
ms.Seek(0x00, SeekOrigin.Begin);
|
||||
byte[] psvMd = ms.ToArray();
|
||||
ms.Close();
|
||||
|
||||
ms = new MemoryStream();
|
||||
byte[] psvMdCompressed = ZlibStream.CompressBuffer(psvMd);
|
||||
psvMdCompressed[0x1] = 0x9C;
|
||||
ms.Write(psvMdCompressed, 0x00, psvMdCompressed.Length);
|
||||
|
||||
SHA256 sha = SHA256.Create();
|
||||
byte[] shadata = sha.ComputeHash(psvMdCompressed);
|
||||
ms.Write(shadata, 0x00, shadata.Length);
|
||||
|
||||
int PaddingLen = Convert.ToInt32(PSVIMGConstants.AES_BLOCK_SIZE - (ms.Length & (PSVIMGConstants.AES_BLOCK_SIZE - 1)));
|
||||
writePadding(ms, 0x00, PaddingLen);
|
||||
|
||||
writeInt32(ms, PaddingLen); //Padding Length
|
||||
writeUInt32(ms, 0x00);
|
||||
writeInt64(ms, (ms.Length+0x8)+IV.Length);
|
||||
ms.Seek(0x00, SeekOrigin.Begin);
|
||||
byte[] toEncrypt = ms.ToArray();
|
||||
ms.Close();
|
||||
|
||||
byte[] EncryptedData = aes_cbc_encrypt(toEncrypt, IV, Key);
|
||||
OutputStream.Write(IV, 0x00, IV.Length);
|
||||
OutputStream.Write(EncryptedData, 0x00, EncryptedData.Length);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public static byte[] DecryptPsvmd(Stream PsvMdFile, byte[] Key)
|
||||
{
|
||||
byte[] IV = new byte[PSVIMGConstants.AES_BLOCK_SIZE];
|
||||
PsvMdFile.Read(IV, 0x00, IV.Length);
|
||||
byte[] remaining = new byte[PsvMdFile.Length - IV.Length];
|
||||
PsvMdFile.Read(remaining, 0x00, remaining.Length);
|
||||
byte[] zlibCompressed = aes_cbc_decrypt(remaining, IV, Key);
|
||||
return zlibCompressed;
|
||||
// return ZlibStream.UncompressBuffer(zlibCompressed);
|
||||
}
|
||||
}
|
||||
}
|
22
CHOVY-TRANSFER/Program.cs
Normal file
22
CHOVY-TRANSFER/Program.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace CHOVY_TRANSFER
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new CHOVYTRANSFER());
|
||||
}
|
||||
}
|
||||
}
|
36
CHOVY-TRANSFER/Properties/AssemblyInfo.cs
Normal file
36
CHOVY-TRANSFER/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("CHOVY-TRANSFER")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("CHOVY-TRANSFER")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("b4cad2c0-ba54-46b6-a8d0-43a9c2390d3c")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
73
CHOVY-TRANSFER/Properties/Resources.Designer.cs
generated
Normal file
73
CHOVY-TRANSFER/Properties/Resources.Designer.cs
generated
Normal file
|
@ -0,0 +1,73 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace CHOVY_TRANSFER.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CHOVY_TRANSFER.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap chovytrans {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("chovytrans", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
124
CHOVY-TRANSFER/Properties/Resources.resx
Normal file
124
CHOVY-TRANSFER/Properties/Resources.resx
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="chovytrans" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\chovytrans.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
26
CHOVY-TRANSFER/Properties/Settings.Designer.cs
generated
Normal file
26
CHOVY-TRANSFER/Properties/Settings.Designer.cs
generated
Normal file
|
@ -0,0 +1,26 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace CHOVY_TRANSFER.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.0.1.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
CHOVY-TRANSFER/Properties/Settings.settings
Normal file
7
CHOVY-TRANSFER/Properties/Settings.settings
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
BIN
CHOVY-TRANSFER/chovy-trans.ico
Normal file
BIN
CHOVY-TRANSFER/chovy-trans.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
BIN
CHOVY-TRANSFER/chovytrans.gif
Normal file
BIN
CHOVY-TRANSFER/chovytrans.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
67
CHOVY-TRANSFER/cmakeys.cs
Normal file
67
CHOVY-TRANSFER/cmakeys.cs
Normal file
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace KeyDerivation
|
||||
{
|
||||
class CmaKeys
|
||||
{
|
||||
static Byte[] Passphrase = Encoding.ASCII.GetBytes("Sri Jayewardenepura Kotte");
|
||||
static Byte[] Key = { 0xA9, 0xFA, 0x5A, 0x62, 0x79, 0x9F, 0xCC, 0x4C, 0x72, 0x6B, 0x4E, 0x2C, 0xE3, 0x50, 0x6D, 0x38 };
|
||||
|
||||
public static string GenerateKeyStr(string Aid)
|
||||
{
|
||||
try
|
||||
{
|
||||
Int64 longlong = Convert.ToInt64(Aid, 16);
|
||||
|
||||
byte[] AidBytes = BitConverter.GetBytes(longlong);
|
||||
Array.Reverse(AidBytes);
|
||||
|
||||
byte[] DerivedKey = CmaKeys.GenerateKey(AidBytes);
|
||||
|
||||
|
||||
return BitConverter.ToString(DerivedKey).Replace("-", "");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return "INVALID_AID";
|
||||
}
|
||||
}
|
||||
public static byte[] GenerateKey(byte[] Aid)
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
ms.Write(Aid, 0, Aid.Length);
|
||||
ms.Write(Passphrase, 0, Passphrase.Length);
|
||||
Byte[] DerviedKey = ms.ToArray();
|
||||
ms.Dispose();
|
||||
|
||||
SHA256 sha = SHA256.Create();
|
||||
DerviedKey = sha.ComputeHash(DerviedKey);
|
||||
sha.Dispose();
|
||||
|
||||
DerviedKey = Decrypt(DerviedKey, Key);
|
||||
|
||||
return DerviedKey;
|
||||
}
|
||||
|
||||
private static byte[] Decrypt(byte[] cipherData,
|
||||
byte[] Key)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
Aes alg = Aes.Create();
|
||||
alg.Mode = CipherMode.ECB;
|
||||
alg.Padding = PaddingMode.None;
|
||||
alg.KeySize = 128;
|
||||
alg.Key = Key;
|
||||
CryptoStream cs = new CryptoStream(ms,
|
||||
alg.CreateDecryptor(), CryptoStreamMode.Write);
|
||||
cs.Write(cipherData, 0, cipherData.Length);
|
||||
cs.Close();
|
||||
byte[] decryptedData = ms.ToArray();
|
||||
return decryptedData;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
5
CHOVY-TRANSFER/packages.config
Normal file
5
CHOVY-TRANSFER/packages.config
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="BouncyCastle" version="1.8.5" targetFramework="net452" />
|
||||
<package id="DotNetZip" version="1.13.4" targetFramework="net452" />
|
||||
</packages>
|
569
CHOVY-TRANSFER/param.cs
Normal file
569
CHOVY-TRANSFER/param.cs
Normal file
|
@ -0,0 +1,569 @@
|
|||
/* Copyright (c) 2015 - 2018 TheDarkporgramer
|
||||
*
|
||||
* This was originally done by Jappi88 (Jappi88 at Gmail dot com) https://github.com/Jappi88
|
||||
* All modifications have been TheDarkporgramer (save sfo ext ext ) https://github.com/xXxTheDarkprogramerxXx
|
||||
*
|
||||
* This(software Is provided) 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications*, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledge in the product documentation is required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* *Contact must be made to discuses permission and terms.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
|
||||
namespace Param_SFO
|
||||
{
|
||||
public class PARAM_SFO
|
||||
{
|
||||
#region << Enums >>
|
||||
public enum DataTypes : uint
|
||||
{
|
||||
PSN_Game = 18248,
|
||||
GameData = 0x4744,
|
||||
SaveData = 0x5344,
|
||||
AppPhoto = 0x4150,
|
||||
AppMusic = 0x414D,
|
||||
AppVideo = 0x4156,
|
||||
BroadCastVideo = 0x4256,
|
||||
AppleTV = 4154,
|
||||
WebTV = 5754,
|
||||
CellBE = 0x4342,
|
||||
Home = 0x484D,
|
||||
StoreFronted = 0x5346,
|
||||
HDDGame = 0x4847,
|
||||
DiscGame = 0x4447,
|
||||
AutoInstallRoot = 0x4152,
|
||||
DiscPackage = 0x4450,
|
||||
ExtraRoot = 0x5852,
|
||||
VideoRoot = 0x5652,
|
||||
ThemeRoot = 0x5452,
|
||||
DiscMovie = 0x444D,
|
||||
Game_Digital_Application = 0x4081AC0,//GD
|
||||
PS4_Game_Application_Patch = 28775,
|
||||
Additional_Content = 25441,//PSvita PS4
|
||||
GameContent = 25447,//PSVITA
|
||||
Blu_Ray_Disc = 25698,//PS4
|
||||
None
|
||||
}
|
||||
|
||||
public enum FMT : ushort
|
||||
{
|
||||
UTF_8 = 0x0004,
|
||||
ASCII = 0x0402,
|
||||
Utf8Null = 0x0204,
|
||||
UINT32 = 0x0404,
|
||||
}
|
||||
|
||||
#endregion << Enums >>
|
||||
|
||||
#region << Vars>>
|
||||
public List<Table> Tables { get; set; }
|
||||
|
||||
#endregion << Vars>>
|
||||
|
||||
#region << Example Of Calling Functions >>
|
||||
//ypu can use this as SFO.Atribute
|
||||
public string Attribute
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tables == null)
|
||||
return "";
|
||||
foreach (Table t in Tables)
|
||||
{
|
||||
if (t.Name == "ATTRIBUTE")
|
||||
return t.Value;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public DataTypes DataType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tables == null)
|
||||
return DataTypes.None;
|
||||
foreach (Table t in Tables)
|
||||
if (t.Name == "CATEGORY")
|
||||
return ((DataTypes)BitConverter.ToUInt16(Encoding.UTF8.GetBytes(t.Value), 0));
|
||||
return DataTypes.None;
|
||||
}
|
||||
}
|
||||
|
||||
public string APP_VER
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tables == null)
|
||||
return "";
|
||||
foreach (Table t in Tables)
|
||||
{
|
||||
if (t.Name == "APP_VER")
|
||||
return t.Value;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public string Detail
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tables == null)
|
||||
return "";
|
||||
foreach (Table t in Tables)
|
||||
if (t.Name == "DETAIL")
|
||||
return t.Value;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public string ContentID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tables == null)
|
||||
return "";
|
||||
foreach (Table t in Tables)
|
||||
if (t.Name == "CONTENT_ID")
|
||||
return t.Value;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public string GetValue(string tagName)
|
||||
{
|
||||
foreach (Table t in Tables)
|
||||
if (t.Name == tagName)
|
||||
return t.Value;
|
||||
return "";
|
||||
}
|
||||
public string TITLEID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tables == null)
|
||||
return "";
|
||||
foreach (Table t in Tables)
|
||||
if (t.Name == "TITLE_ID")
|
||||
return t.Value;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public string TitleID
|
||||
{
|
||||
get
|
||||
{
|
||||
string name = TITLEID;
|
||||
if (name == "")
|
||||
return "";
|
||||
return name.Split('-')[0];
|
||||
}
|
||||
}
|
||||
|
||||
public string Title
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tables == null)
|
||||
return "";
|
||||
foreach (Table t in Tables)
|
||||
if (t.Name == "TITLE")
|
||||
return t.Value;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public string Category
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tables == null)
|
||||
return "";
|
||||
foreach (Table t in Tables)
|
||||
if (t.Name == "CATEGORY")
|
||||
return t.Value;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public enum Playstation
|
||||
{
|
||||
ps3 = 0,
|
||||
psvita = 1,
|
||||
ps4 = 2,
|
||||
psp = 3,
|
||||
unknown = 4,//there will be a time i no longer support the scene this will be for ps5+ most probabbly
|
||||
}
|
||||
|
||||
public Playstation PlaystationVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tables == null)
|
||||
return Playstation.unknown;
|
||||
foreach (Table t in Tables)
|
||||
{
|
||||
if (t.Name == "PS3_SYSTEM_VER")
|
||||
return Playstation.ps3;//this is the unique offset for ps3
|
||||
if (t.Name == "PSP2_SYSTEM_VER")
|
||||
{
|
||||
return Playstation.psvita;//this is the only flag that tells us its a psvita
|
||||
}
|
||||
if (t.Name == "PSP_SYSTEM_VER")
|
||||
{
|
||||
return Playstation.psp;//this is how we know its a psp
|
||||
}
|
||||
if (t.Name == "SYSTEM_VER")//i believe this to be only ps4
|
||||
{
|
||||
return Playstation.ps4;
|
||||
}
|
||||
}
|
||||
return Playstation.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion << Example Of Calling Functions >>
|
||||
|
||||
#region Param.SFO Struct
|
||||
|
||||
public struct Header
|
||||
{
|
||||
public static byte[] Magic = { 0, 0x50, 0x53, 0x46 };
|
||||
public static byte[] version = { 01, 01, 0, 0 };
|
||||
public static uint KeyTableStart = 0;
|
||||
public static uint DataTableStart = 0;
|
||||
public static uint IndexTableEntries = 0;
|
||||
|
||||
private static byte[] Buffer
|
||||
{
|
||||
get
|
||||
{
|
||||
var header = new byte[20];
|
||||
Array.Copy(Magic, 0, header, 0, 4);
|
||||
Array.Copy(version, 0, header, 4, 4);
|
||||
Array.Copy(BitConverter.GetBytes(KeyTableStart), 0, header, 8, 4);
|
||||
Array.Copy(BitConverter.GetBytes(DataTableStart), 0, header, 12, 4);
|
||||
Array.Copy(BitConverter.GetBytes(IndexTableEntries), 0, header, 16, 4);
|
||||
return header;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Read(BinaryReader input)
|
||||
{
|
||||
input.BaseStream.Seek(0, SeekOrigin.Begin);
|
||||
input.Read(Magic, 0, 4);
|
||||
input.Read(version, 0, 4);
|
||||
KeyTableStart = input.ReadUInt32();
|
||||
DataTableStart = input.ReadUInt32();
|
||||
IndexTableEntries = input.ReadUInt32();
|
||||
}
|
||||
|
||||
}
|
||||
[Serializable]
|
||||
public struct Table : IComparable
|
||||
{
|
||||
public index_table Indextable;
|
||||
public string Name;
|
||||
public string Value;
|
||||
public int index;
|
||||
|
||||
public byte[] NameBuffer
|
||||
{
|
||||
get
|
||||
{
|
||||
var buffer = new byte[Name.Length + 1];
|
||||
Array.Copy(Encoding.UTF8.GetBytes(Name), 0, buffer, 0, Encoding.UTF8.GetBytes(Name).Length);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] ValueBuffer
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] buffer;
|
||||
switch (Indextable.param_data_fmt)
|
||||
{
|
||||
case FMT.ASCII:
|
||||
buffer = new byte[Indextable.param_data_max_len];
|
||||
Array.Copy(Encoding.ASCII.GetBytes(Value), 0, buffer, 0, Encoding.UTF8.GetBytes(Value).Length);
|
||||
return buffer;
|
||||
case FMT.UINT32:
|
||||
return BitConverter.GetBytes(uint.Parse(Value));
|
||||
case FMT.UTF_8:
|
||||
buffer = new byte[Indextable.param_data_max_len];
|
||||
Array.Copy(Encoding.UTF8.GetBytes(Value), 0, buffer, 0, Encoding.UTF8.GetBytes(Value).Length);
|
||||
return buffer;
|
||||
case FMT.Utf8Null:
|
||||
buffer = new byte[Indextable.param_data_max_len];
|
||||
Array.Copy(Encoding.UTF8.GetBytes(Value), 0, buffer, 0, Encoding.UTF8.GetBytes(Value).Length);/*write the length of the array*/
|
||||
return buffer;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
[Serializable]
|
||||
public struct index_table
|
||||
{
|
||||
public FMT param_data_fmt; /* param_data data type */
|
||||
public uint param_data_len; /* param_data used bytes */
|
||||
public uint param_data_max_len; /* param_data total reserved bytes */
|
||||
public uint param_data_offset; /* param_data offset (relative to start offset of data_table) */
|
||||
public ushort param_key_offset; /* param_key offset (relative to start offset of key_table) */
|
||||
|
||||
|
||||
private byte[] Buffer
|
||||
{
|
||||
get
|
||||
{
|
||||
var data = new byte[16];
|
||||
Array.Copy(BitConverter.GetBytes(param_key_offset), 0, data, 0, 2);
|
||||
Array.Copy(BitConverter.GetBytes(((ushort)param_data_fmt)), 0, data, 2, 2);
|
||||
Array.Copy(BitConverter.GetBytes(param_data_len), 0, data, 4, 4);
|
||||
Array.Copy(BitConverter.GetBytes(param_data_max_len), 0, data, 8, 4);
|
||||
Array.Copy(BitConverter.GetBytes(param_data_offset), 0, data, 12, 4);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
public void Read(BinaryReader input)
|
||||
{
|
||||
param_key_offset = input.ReadUInt16();
|
||||
param_data_fmt = (FMT)input.ReadUInt16();
|
||||
param_data_len = input.ReadUInt32();
|
||||
param_data_max_len = input.ReadUInt32();
|
||||
param_data_offset = input.ReadUInt32();
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
private enum DATA_TYPE : byte
|
||||
{
|
||||
BinaryData = 0,
|
||||
Utf8Text = 2,
|
||||
Si32Integer = 4
|
||||
}
|
||||
|
||||
#endregion Param.SFO Struct
|
||||
|
||||
#region << Methods >>
|
||||
|
||||
|
||||
public PARAM_SFO()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public PARAM_SFO(string filepath)
|
||||
{
|
||||
Init(new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read));
|
||||
}
|
||||
|
||||
public PARAM_SFO(byte[] inputdata)
|
||||
{
|
||||
Init(new MemoryStream(inputdata));
|
||||
}
|
||||
|
||||
public PARAM_SFO(Stream input)
|
||||
{
|
||||
Init(input);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This is the SaveSFO Function for PS3/PS4/PSVita/And PSP no longer needed for Sony's CMD
|
||||
/// </summary>
|
||||
/// <param name="psfo">SFO That has been opened</param>
|
||||
/// <param name="filename">Save Location</param>
|
||||
public void SaveSFO(PARAM_SFO psfo, string filename)
|
||||
{
|
||||
//we start by opening the stream to the file
|
||||
using (var stream = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||
{
|
||||
if (!stream.CanSeek)
|
||||
throw new ArgumentException("Stream must be seekable");//throw this error we cant seek the stream
|
||||
|
||||
var utf8 = new UTF8Encoding(false);//encoding
|
||||
using (var writer = new BinaryWriter(stream, utf8))//start binary reader
|
||||
{
|
||||
|
||||
#region << Header Info (DevWiki) >>
|
||||
/*
|
||||
Header
|
||||
* 0x00 0x04 magic PSF
|
||||
0x04 0x04 version 01 01 00 00 1.01
|
||||
0x08 0x04 key_table_start 24 00 00 00 Absolute start offset of key_table = 0x24
|
||||
0x0C 0x04 data_table_start 30 00 00 00 Absolute start offset of data_table = 0x30
|
||||
0x10 0x04 tables_entries 01 00 00 00 Number of entries in index_table, key_table, and data_table = 1
|
||||
*/
|
||||
|
||||
#endregion <<Header Info >>
|
||||
|
||||
//so lets start writing the info
|
||||
writer.Write(Header.Magic);//write magic "\0PSF"
|
||||
writer.Write(Header.version);//write version info this is mayjor and minor (01 01 00 00 1.01)
|
||||
Header.KeyTableStart = 0x14 + Header.IndexTableEntries * 0x10;/*we can write all this lovely info from the tables back*/
|
||||
writer.Write(Header.KeyTableStart);
|
||||
|
||||
Header.DataTableStart = Convert.ToUInt32(Header.KeyTableStart + Tables.Sum(i => i.Name.Length + 1));//needs to be Uint
|
||||
if (Header.DataTableStart % 4 != 0)
|
||||
Header.DataTableStart = (Header.DataTableStart / 4 + 1) * 4;
|
||||
writer.Write(Header.DataTableStart);
|
||||
Header.IndexTableEntries = Convert.ToUInt32(Tables.Count);
|
||||
writer.Write(Header.IndexTableEntries);
|
||||
|
||||
int lastKeyOffset = Convert.ToInt32(Header.KeyTableStart);
|
||||
int lastValueOffset = Convert.ToInt32(Header.DataTableStart);
|
||||
for (var i = 0; i < Tables.Count; i++)
|
||||
{
|
||||
var entry = Tables[i];
|
||||
|
||||
writer.BaseStream.Seek(0x14 + i * 0x10, SeekOrigin.Begin);
|
||||
writer.Write((ushort)(lastKeyOffset - Header.KeyTableStart));
|
||||
|
||||
|
||||
writer.Write((ushort)entry.Indextable.param_data_fmt);
|
||||
|
||||
writer.Write(entry.Indextable.param_data_len);
|
||||
writer.Write(entry.Indextable.param_data_max_len);
|
||||
writer.Write(lastValueOffset - Header.DataTableStart);
|
||||
|
||||
writer.BaseStream.Seek(lastKeyOffset, SeekOrigin.Begin);
|
||||
writer.Write(utf8.GetBytes(entry.Name));
|
||||
writer.Write((byte)0);
|
||||
lastKeyOffset = (int)writer.BaseStream.Position;
|
||||
|
||||
writer.BaseStream.Seek(lastValueOffset, SeekOrigin.Begin);
|
||||
writer.Write(entry.ValueBuffer);
|
||||
lastValueOffset = (int)writer.BaseStream.Position;
|
||||
}
|
||||
|
||||
//I'm doing this to just rewrite the first item (Some Cleanup will be needed)
|
||||
//Or maybe not as when I checked this gives a 1 - 1 match with how the Sony tool works
|
||||
//we need to rewrite that first item (PS4/PS3/PSV should be APP-VER)
|
||||
lastKeyOffset = Convert.ToInt32(Header.KeyTableStart);
|
||||
lastValueOffset = Convert.ToInt32(Header.DataTableStart);
|
||||
|
||||
var tableentry = Tables[0];
|
||||
|
||||
writer.BaseStream.Seek(lastKeyOffset, SeekOrigin.Begin);
|
||||
writer.Write(utf8.GetBytes(tableentry.Name));
|
||||
writer.Write((byte)0);
|
||||
lastKeyOffset = (int)writer.BaseStream.Position;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private string ReadValue(BinaryReader br, index_table table)
|
||||
{
|
||||
br.BaseStream.Position = ((Header.DataTableStart) + table.param_data_offset);
|
||||
switch (table.param_data_fmt)
|
||||
{
|
||||
case FMT.ASCII:
|
||||
//return Encoding.GetEncoding(1252).GetString(br.ReadBytes((int) table.param_data_max_len)).Replace("\0", "");
|
||||
return Encoding.UTF8.GetString(br.ReadBytes((int)table.param_data_max_len)).Replace("\0", "");
|
||||
case FMT.UINT32:
|
||||
return br.ReadUInt32().ToString();
|
||||
case FMT.UTF_8:
|
||||
return Encoding.UTF8.GetString(br.ReadBytes((int)table.param_data_max_len)).Replace("\0", "");
|
||||
case FMT.Utf8Null:
|
||||
return Encoding.UTF8.GetString(br.ReadBytes((int)table.param_data_max_len)).Replace("\0", "");
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private string ReadValueSpecialChars(BinaryReader br, index_table table)
|
||||
{
|
||||
br.BaseStream.Position = ((Header.DataTableStart) + table.param_data_offset);
|
||||
switch (table.param_data_fmt)
|
||||
{
|
||||
case FMT.ASCII:
|
||||
return Encoding.UTF8.GetString(br.ReadBytes((int)table.param_data_max_len)).Replace("\0", "");
|
||||
case FMT.UINT32:
|
||||
return br.ReadUInt32().ToString();
|
||||
case FMT.UTF_8:
|
||||
return Encoding.UTF8.GetString(br.ReadBytes((int)table.param_data_max_len)).Replace("\0", "");
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private string ReadName(BinaryReader br, index_table table)
|
||||
{
|
||||
br.BaseStream.Position = (Header.KeyTableStart + table.param_key_offset);
|
||||
string name = "";
|
||||
while (((byte)br.PeekChar()) != 0)
|
||||
name += br.ReadChar();
|
||||
br.BaseStream.Position++;
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start Reading the Parameter file
|
||||
/// </summary>
|
||||
/// <param name="input">Input Stream</param>
|
||||
private void Init(Stream input)
|
||||
{
|
||||
using (var br = new BinaryReader(input))
|
||||
{
|
||||
Header.Read(br);
|
||||
var tables = new List<index_table>();
|
||||
for (int i = 0; i < Header.IndexTableEntries; i++)
|
||||
{
|
||||
var t = new index_table();
|
||||
t.Read(br);
|
||||
tables.Add(t);
|
||||
}
|
||||
var xtables = new List<Table>();
|
||||
int count = 0;
|
||||
foreach (index_table t in tables)
|
||||
{
|
||||
var x = new Table();
|
||||
x.index = count;
|
||||
x.Indextable = t;
|
||||
x.Name = ReadName(br, t);
|
||||
x.Value = ReadValue(br, t);
|
||||
count++;
|
||||
xtables.Add(x);
|
||||
}
|
||||
Tables = xtables;
|
||||
br.Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion << Methods >>
|
||||
|
||||
}
|
||||
}
|
BIN
chovy-trans.ico
Normal file
BIN
chovy-trans.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
BIN
packages/BouncyCastle.1.8.5/BouncyCastle.1.8.5.nupkg
vendored
Normal file
BIN
packages/BouncyCastle.1.8.5/BouncyCastle.1.8.5.nupkg
vendored
Normal file
Binary file not shown.
30
packages/BouncyCastle.1.8.5/README.md
vendored
Normal file
30
packages/BouncyCastle.1.8.5/README.md
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
# The Bouncy Castle Crypto Package For C Sharp
|
||||
|
||||
The Bouncy Castle Crypto package is a C\# implementation of cryptographic algorithms and protocols, it was developed by the Legion of the Bouncy Castle, a registered Australian Charity, with a little help! The Legion, and the latest goings on with this package, can be found at [http://www.bouncycastle.org](http://www.bouncycastle.org). In addition to providing basic cryptography algorithms, the package also provides support for CMS, TSP, X.509 certificate generation and a variety of other standards such as OpenPGP.
|
||||
|
||||
The Legion also gratefully acknowledges the contributions made to this package by others (see [here](http://www.bouncycastle.org/csharp/contributors.html) for the current list). If you would like to contribute to our efforts please feel free to get in touch with us or visit our [donations page](https://www.bouncycastle.org/donate), sponsor some specific work, or purchase a support contract through [Crypto Workshop](http://www.cryptoworkshop.com).
|
||||
|
||||
Except where otherwise stated, this software is distributed under a license based on the MIT X Consortium license. To view the license, [see here](http://www.bouncycastle.org/licence.html). The OpenPGP library also includes a modified BZIP2 library which is licensed under the [Apache Software License, Version 2.0](http://www.apache.org/licenses/).
|
||||
|
||||
**Note**: this source tree is not the FIPS version of the APIs - if you are interested in our FIPS version please contact us directly at [office@bouncycastle.org](mailto:office@bouncycastle.org).
|
||||
|
||||
## Mailing Lists
|
||||
|
||||
For those who are interested, there are 2 mailing lists for participation in this project. To subscribe use the links below and include the word subscribe in the message body. (To unsubscribe, replace **subscribe** with **unsubscribe** in the message body)
|
||||
|
||||
* [announce-crypto-csharp-request@bouncycastle.org](mailto:announce-crypto-csharp-request@bouncycastle.org)
|
||||
This mailing list is for new release announcements only, general subscribers cannot post to it.
|
||||
* [dev-crypto-csharp-request@bouncycastle.org](mailto:dev-crypto-csharp-request@bouncycastle.org)
|
||||
This mailing list is for discussion of development of the package. This includes bugs, comments, requests for enhancements, questions about use or operation.
|
||||
|
||||
**NOTE:**You need to be subscribed to send mail to the above mailing list.
|
||||
|
||||
## Feedback
|
||||
|
||||
If you want to provide feedback directly to the members of **The Legion** then please use [feedback-crypto@bouncycastle.org](mailto:feedback-crypto@bouncycastle.org), if you want to help this project survive please consider [donating](https://www.bouncycastle.org/donate).
|
||||
|
||||
For bug reporting/requests you can report issues here on github, via feedback-crypto if required, and we also have a [Jira issue tracker](http://www.bouncycastle.org/jira). We will accept pull requests based on this repository as well.
|
||||
|
||||
## Finally
|
||||
|
||||
Enjoy!
|
BIN
packages/BouncyCastle.1.8.5/lib/BouncyCastle.Crypto.dll
vendored
Normal file
BIN
packages/BouncyCastle.1.8.5/lib/BouncyCastle.Crypto.dll
vendored
Normal file
Binary file not shown.
BIN
packages/DotNetZip.1.13.4/DotNetZip.1.13.4.nupkg
vendored
Normal file
BIN
packages/DotNetZip.1.13.4/DotNetZip.1.13.4.nupkg
vendored
Normal file
Binary file not shown.
BIN
packages/DotNetZip.1.13.4/lib/net40/DotNetZip.dll
vendored
Normal file
BIN
packages/DotNetZip.1.13.4/lib/net40/DotNetZip.dll
vendored
Normal file
Binary file not shown.
BIN
packages/DotNetZip.1.13.4/lib/net40/DotNetZip.pdb
vendored
Normal file
BIN
packages/DotNetZip.1.13.4/lib/net40/DotNetZip.pdb
vendored
Normal file
Binary file not shown.
18529
packages/DotNetZip.1.13.4/lib/net40/DotNetZip.xml
vendored
Normal file
18529
packages/DotNetZip.1.13.4/lib/net40/DotNetZip.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
packages/DotNetZip.1.13.4/lib/netstandard2.0/DotNetZip.dll
vendored
Normal file
BIN
packages/DotNetZip.1.13.4/lib/netstandard2.0/DotNetZip.dll
vendored
Normal file
Binary file not shown.
BIN
packages/DotNetZip.1.13.4/lib/netstandard2.0/DotNetZip.pdb
vendored
Normal file
BIN
packages/DotNetZip.1.13.4/lib/netstandard2.0/DotNetZip.pdb
vendored
Normal file
Binary file not shown.
18031
packages/DotNetZip.1.13.4/lib/netstandard2.0/DotNetZip.xml
vendored
Normal file
18031
packages/DotNetZip.1.13.4/lib/netstandard2.0/DotNetZip.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user