write codez

This commit is contained in:
SilicaAndPina 2019-10-10 05:11:55 +13:00
parent ead7745626
commit 6bd010e50f
16 changed files with 37050 additions and 185 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
</configuration>

View File

@ -8,7 +8,7 @@
<OutputType>Exe</OutputType>
<RootNamespace>CHOVY</RootNamespace>
<AssemblyName>CHOVY-SIGN</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
@ -47,6 +47,9 @@
<Reference Include="DiscUtils.Common, Version=0.11.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Discutils.0.11.0.2\lib\net40\DiscUtils.Common.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" />
@ -82,6 +85,7 @@
<Compile Include="PSVIMGStream.cs" />
<Compile Include="PSVIMGStructs.cs" />
<Compile Include="psvimgtools.cs" />
<Compile Include="PSVMDBuilder.cs" />
<EmbeddedResource Include="CHOVY.resx">
<DependentUpon>CHOVY.cs</DependentUpon>
</EmbeddedResource>

View File

@ -9,6 +9,7 @@ using System.Drawing;
using System.IO;
using System.Media;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CHOVY
@ -222,11 +223,11 @@ namespace CHOVY
}
File.WriteAllText(GamePathFile, "ux0:pspemu/temp/game/PSP/GAME/" + TitleID + "\x00");
// File.WriteAllText(GamePathFile, "ux0:pspemu/temp/game/PSP/GAME/" + TitleID + "\x00");
TotalProgress.Style = ProgressBarStyle.Marquee;
Status.Text = "Signing the Declaration of Independance";
UInt64 IntAid = Convert.ToUInt64(Aid,16);
//TotalProgress.Style = ProgressBarStyle.Marquee;
Status.Text = "Signing the Declaration of Independance 0%";
UInt64 IntAid = BitConverter.ToUInt64(RifAid,0x00);
int ChovyGenRes = pbp.gen__sce_ebootpbp(EbootFile, IntAid, EbootSignature);
if (!File.Exists(EbootSignature) || ChovyGenRes != 0)
{
@ -242,10 +243,68 @@ namespace CHOVY
// Pacakge GAME
string BackupGameDir = Path.Combine(BackupWorkDir, "game");
Directory.CreateDirectory(BackupGameDir);
Process psvimg_create = psvimgtools.PSVIMG_CREATE(Aid, "game" ,TmpDir, Path.Combine(BackupWorkDir,"game"));
while(!psvimg_create.HasExited)
//string BackupGameDir = Path.Combine(BackupWorkDir, "game");
string[] entrys = Directory.GetFileSystemEntries(GameWorkDir, "*", SearchOption.AllDirectories);
long noEntrys = entrys.LongLength;
string parentPath = "ux0:pspemu/temp/game/PSP/GAME/" + TitleID;
int noBlocks = 0;
foreach (string fileName in Directory.GetFiles(GameWorkDir,"*",SearchOption.AllDirectories))
{
noBlocks += Convert.ToInt32(new FileInfo(fileName).Length / PSVIMGConstants.PSVIMG_BLOCK_SIZE);
}
TotalProgress.Maximum = noBlocks;
byte[] CmaKey = CmaKeys.GenerateKey(RifAid);
string BackupDir = Path.Combine(BackupWorkDir, "game");
Directory.CreateDirectory(BackupDir);
FileStream psvimg = File.OpenWrite(Path.Combine(BackupDir, "game.psvimg"));
psvimg.SetLength(0);
PSVIMGBuilder builder = new PSVIMGBuilder(psvimg, CmaKey);
foreach (string entry in entrys)
{
string relativePath = entry.Remove(0, GameWorkDir.Length);
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;
TotalProgress.Value = tBlocks;
decimal progress = Math.Floor(((decimal)tBlocks / (decimal)noBlocks) * 100);
Status.Text = "Signing the Declaration of Independance " + progress.ToString() + "%";
}
catch (Exception) { }
Application.DoEvents();
}
}
}
long ContentSize = builder.Finish();
psvimg = File.OpenRead(Path.Combine(BackupDir, "game.psvimg"));
FileStream psvmd = File.OpenWrite(Path.Combine(BackupDir, "game.psvmd"));
PSVMDBuilder.CreatePsvmd(psvmd, psvimg, ContentSize, "game", CmaKey);
psvmd.Close();
// Directory.CreateDirectory(BackupGameDir);
//Process psvimg_create = psvimgtools.PSVIMG_CREATE(Aid, "game" ,TmpDir, Path.Combine(BackupWorkDir,"game"));
/* while(!psvimg_create.HasExited)
{
Application.DoEvents();
}
@ -255,7 +314,7 @@ namespace CHOVY
enable();
return;
}
*/
// Package LICENSE
try
{
@ -266,8 +325,8 @@ namespace CHOVY
Directory.CreateDirectory(LicenseWorkDir);
File.Copy(RifPath.Text, Path.Combine(LicenseWorkDir, ContentID + ".rif"), true);
File.WriteAllText(LicensePathFile, "ux0:pspemu/temp/game/PSP/LICENSE\x00");
Directory.CreateDirectory(BackupGameDir);
psvimg_create = psvimgtools.PSVIMG_CREATE(Aid, "license", TmpDir, Path.Combine(BackupWorkDir, "license"));
/*Directory.CreateDirectory(BackupGameDir);
Process psvimg_create = psvimgtools.PSVIMG_CREATE(Aid, "license", TmpDir, Path.Combine(BackupWorkDir, "license"));
while (!psvimg_create.HasExited)
{
Application.DoEvents();
@ -277,7 +336,7 @@ namespace CHOVY
MessageBox.Show("PSVIMG-CREATE.EXE FAILED!\nArguments:\n" + psvimg_create.StartInfo.Arguments + "\nStdOut:\n" + psvimg_create.StandardOutput.ReadToEnd() + "\nStdErr:\n" + psvimg_create.StandardError.ReadToEnd());
enable();
return;
}
}*/
try
{
@ -367,10 +426,7 @@ namespace CHOVY
string CmaDir = ccs.GetCmaDir();
string CmaAid = ccs.GetCmaAid();
string Backup = ccs.GetSelectedBackup();
ccs.Hide();
this.Show();
this.Focus();
WriteSetting("CmaDir", CmaDir);
if (Backup == "")
@ -381,6 +437,10 @@ namespace CHOVY
string BackupPath = Path.Combine(CmaDir, "PGAME", CmaAid, Backup, "game", "game.psvimg");
if(!File.Exists(BackupPath))
{
MessageBox.Show("Could not find \n" + BackupPath + "\n Perhaps backup failed?", "License Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
ccs.Hide();
this.Show();
this.Focus();
return;
}
@ -393,6 +453,10 @@ namespace CHOVY
BackupPath = Path.Combine(CmaDir, "PGAME", CmaAid, Backup, "license", "license.psvimg");
if (!File.Exists(BackupPath))
{
MessageBox.Show("Could not find \n"+BackupPath+"\n Perhaps backup failed?","License Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
ccs.Hide();
this.Show();
this.Focus();
return;
}
@ -419,8 +483,10 @@ namespace CHOVY
Versionkey.Text = VerKey;
RifPath.Text = Rif;
Status.Text = "Progress %";
TotalProgress.Style = ProgressBarStyle.Continuous;
ccs.Hide();
this.Show();
this.Focus();
MessageBox.Show("KEYS HAVE BEEN EXTRACTED FROM CMA, YOU MAY NOW LIBERATE YOURSELF", "SUCCESS", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

View File

@ -3,6 +3,7 @@ using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using static PSVIMGTOOLS.SceIoStat;
namespace PSVIMGTOOLS
@ -14,13 +15,42 @@ namespace PSVIMGTOOLS
private Random rnd = new Random();
private Stream mainStream;
private Sha256Digest shaCtx;
byte[] blockData;
MemoryStream blockStream;
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_ecb_encrypt(byte[] plainText, byte[] IV, byte[] KEY, int size=-1)
private byte[] aes_cbc_encrypt(byte[] plainText, byte[] IV, byte[] KEY, int size=-1)
{
if (size < 0)
{
@ -256,7 +286,7 @@ namespace PSVIMGTOOLS
len += PSVIMGConstants.SHA256_BLOCK_SIZE;
//Get next IV
byte[] encryptedBlock = aes_ecb_encrypt(blockData, IV, KEY, len);
byte[] encryptedBlock = aes_cbc_encrypt(blockData, IV, KEY, len);
for (int i = 0; i < IV.Length; i++)
{
int encBlockOffset = (encryptedBlock.Length - IV.Length)+i;
@ -272,7 +302,7 @@ namespace PSVIMGTOOLS
return Convert.ToInt32((PSVIMGConstants.PSVIMG_BLOCK_SIZE - blockStream.Position));
}
private void writeBlock(byte[] data)
private void writeBlock(byte[] data, bool update=false)
{
long dLen = data.Length;
while (dLen > 0)
@ -285,7 +315,10 @@ namespace PSVIMGTOOLS
dLen -= remaining;
finishBlock();
startNewBlock();
if(update)
{
blocksWritten += 1;
}
}
else
{
@ -342,6 +375,28 @@ namespace PSVIMGTOOLS
}
}
private void writeStreamAsync(Stream dst)
{
long numberOfBlocks = dst.Length / PSVIMGConstants.PSVIMG_BLOCK_SIZE;
while (dst.Position < dst.Length)
{
byte[] work_buf;
Int64 bytes_remain = (dst.Length - dst.Position);
if (bytes_remain > 0x10485760)
{
work_buf = new byte[0x10485760];
}
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())
@ -355,11 +410,26 @@ namespace PSVIMGTOOLS
writeUInt32(ms, 0x00);
writeInt64(ms, totalBytes);
ms.Seek(0x00, SeekOrigin.Begin);
return aes_ecb_encrypt(ms.ToArray(), IV, KEY);
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));
writeStreamAsync(File.OpenRead(FilePath));
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);
@ -367,6 +437,7 @@ namespace PSVIMGTOOLS
writeStream(File.OpenRead(FilePath));
writeBlock(getPadding(sz));
writeBlock(getTailer());
contentSize += sz;
}
public void AddDir(string DirPath, string ParentPath, string PathRel)
@ -375,7 +446,7 @@ namespace PSVIMGTOOLS
writeBlock(getPadding(0));
writeBlock(getTailer());
}
public void Finish()
public long Finish()
{
finishBlock(true);
byte[] footer = getFooter();
@ -383,11 +454,13 @@ namespace PSVIMGTOOLS
blockStream.Close();
mainStream.Close();
return contentSize;
}
public PSVIMGBuilder(Stream dst, byte[] Key)
{
totalBytes = 0;
contentSize = 0;
shaCtx = new Sha256Digest();
mainStream = dst;
KEY = Key;

View File

@ -7,10 +7,8 @@ namespace PSVIMGTOOLS
{
class PSVIMGStream : Stream
{
private Stream baseStream;
private MemoryStream blockStream;
private long _position = 0;
private byte[] key;
public Stream BaseStream
{
@ -20,29 +18,6 @@ namespace PSVIMGTOOLS
}
}
private long position
{
get
{
return _position;
}
set
{
if (value > this.Length)
{
_position = this.Length;
}
else if(value < 0)
{
_position = 0;
}
else
{
_position = value;
}
}
}
public Byte[] Key
{
get
@ -122,7 +97,7 @@ namespace PSVIMGTOOLS
{
get
{
return position;
return baseStream.Position - PSVIMGConstants.AES_BLOCK_SIZE;
}
set
{
@ -131,94 +106,65 @@ namespace PSVIMGTOOLS
}
private bool verifyFooter()
{
byte[] Footer = new byte[0x10];
byte[] IV = new byte[PSVIMGConstants.AES_BLOCK_SIZE];
baseStream.Seek(baseStream.Length - (Footer.Length + IV.Length), SeekOrigin.Begin);
baseStream.Read(IV, 0x00, PSVIMGConstants.AES_BLOCK_SIZE);
baseStream.Read(Footer, 0x00, 0x10);
byte[] FooterDec = aes_ecb_decrypt(Footer, IV);
UInt64 FooterLen;
using (MemoryStream ms = new MemoryStream(FooterDec))
{
ms.Seek(0x4, SeekOrigin.Current);
ms.Seek(0x4, SeekOrigin.Current);
byte[] LenInt = new byte[0x8];
ms.Read(LenInt, 0x00, 0x8);
FooterLen = BitConverter.ToUInt64(LenInt, 0x00);
}
if(Convert.ToUInt64(baseStream.Length) == FooterLen)
{
return true;
}
else
{
return false;
}
}
public PSVIMGStream(Stream file, byte[] KEY)
{
baseStream = file;
key = KEY;
if(!verifyFooter())
if (!verifyFooter())
{
throw new Exception("Invalid KEY!");
}
blockStream = new MemoryStream();
this.Seek(0x00, SeekOrigin.Begin);
baseStream.Seek(PSVIMGConstants.AES_BLOCK_SIZE, SeekOrigin.Begin);
update();
}
public override int Read(byte[] buffer, int offset, int count)
{
long totalRead = 0;
using (MemoryStream ms = new MemoryStream())
int remaining = (int)getRemainingBlock();
int read = 0;
if (count < remaining)
{
while (true)
{
if (this.Position >= this.Length)
{
break;
}
long rem = getRemainingBlock();
long totalLeft = (count - totalRead);
if (rem < totalLeft)
{
byte[] remB = new byte[rem];
long read = blockStream.Read(remB, 0x00, remB.Length);
totalRead += read;
ms.Write(remB, 0x00, remB.Length);
long indx = getBlockIndex() + 1;
seekToBlock(indx);
update();
}
else
{
byte[] remB = new byte[totalLeft];
long read = blockStream.Read(remB, 0x00, remB.Length);
totalRead += read;
ms.Write(remB, 0x00, remB.Length);
break;
}
}
ms.Seek(0x00, SeekOrigin.Begin);
totalRead = ms.Read(buffer, offset, count);
position += totalRead;
read += blockStream.Read(buffer, offset, count);
baseStream.Seek(count, SeekOrigin.Current);
}
return Convert.ToInt32(totalRead);
else
{
using (MemoryStream ms = new MemoryStream())
{
while (true)
{
update();
remaining = (int)getRemainingBlock();
int curPos = count - read;
if (curPos > remaining)
{
read += remaining;
blockStream.CopyTo(ms, remaining);
baseStream.Seek(remaining, SeekOrigin.Current);
}
else
{
read += curPos;
blockStream.CopyTo(ms, curPos);
baseStream.Seek(curPos, SeekOrigin.Current);
break;
}
}
ms.Seek(0x00, SeekOrigin.Begin);
ms.Read(buffer, offset, count);
}
}
return read;
}
public override void Flush()
{
update();
baseStream.Flush();
blockStream.Flush();
}
@ -228,24 +174,33 @@ namespace PSVIMGTOOLS
long ret = 0;
if (origin == SeekOrigin.Begin)
{
long blockNo = getBlockIndex(offset);
seekToBlock(blockNo);
update();
long onwards = offset % blockStream.Length;
ret = blockStream.Seek(onwards, SeekOrigin.Begin);
position = (baseStream.Position - PSVIMGConstants.AES_BLOCK_SIZE) + BlockPosition;
ret = baseStream.Seek(offset + PSVIMGConstants.AES_BLOCK_SIZE, SeekOrigin.Begin);
}
else if (origin == SeekOrigin.Current)
{
long currentPos = this.Position;
this.Seek(currentPos + offset, SeekOrigin.Begin);
long pos = baseStream.Position;
if ((pos + offset) >= PSVIMGConstants.AES_BLOCK_SIZE)
{
ret = baseStream.Seek(offset, SeekOrigin.Current);
}
else
{
ret = baseStream.Seek(offset + PSVIMGConstants.AES_BLOCK_SIZE, SeekOrigin.Current);
}
}
else if (origin == SeekOrigin.End)
{
long len = this.Length;
this.Seek(Length + offset, SeekOrigin.Begin);
long pos = baseStream.Length;
if ((pos + offset) >= PSVIMGConstants.AES_BLOCK_SIZE)
{
ret = baseStream.Seek(offset, SeekOrigin.End);
}
else
{
ret = baseStream.Seek(offset + PSVIMGConstants.AES_BLOCK_SIZE, SeekOrigin.End);
}
}
update();
return ret;
}
@ -268,44 +223,52 @@ namespace PSVIMGTOOLS
baseStream.Dispose();
this.Dispose();
}
private void update()
{
long offset = (this.Position % PSVIMGConstants.FULL_PSVIMG_SIZE);
long blockIndex = getBlockIndex();
byte[] decryptedBlock = getBlock(blockIndex);
blockStream.Dispose();
blockStream = new MemoryStream(decryptedBlock, 0x00, decryptedBlock.Length);
blockStream.Write(decryptedBlock, 0x00, decryptedBlock.Length);
blockStream.Seek(0x00, SeekOrigin.Begin);
blockStream.SetLength(decryptedBlock.Length);
blockStream.Write(decryptedBlock, 0x00, decryptedBlock.Length);
seekToBlock(blockIndex);
baseStream.Seek(offset, SeekOrigin.Current);
blockStream.Seek(offset, SeekOrigin.Begin);
}
private long getBlockIndex(long pos = -1)
private long getBlockIndex()
{
long blockOffset = 0;
long blockEnd = blockOffset + PSVIMGConstants.FULL_PSVIMG_SIZE;
long blockIndex = 0;
if (pos < 0)
{
pos = this.Position;
}
while (blockOffset < this.Length)
{
blockOffset = (blockIndex * PSVIMGConstants.FULL_PSVIMG_SIZE);
blockEnd = blockOffset + PSVIMGConstants.FULL_PSVIMG_SIZE;
long i = 0;
long curPos = baseStream.Position;
long fullBlock;
long blockOffset;
if (pos >= blockOffset && pos < blockEnd)
while (true)
{
blockOffset = (i * PSVIMGConstants.FULL_PSVIMG_SIZE) + PSVIMGConstants.AES_BLOCK_SIZE;
long remaining = getRemainingBase();
if (remaining < PSVIMGConstants.FULL_PSVIMG_SIZE)
{
return blockIndex;
fullBlock = blockOffset + remaining;
}
blockIndex++;
else
{
fullBlock = blockOffset + PSVIMGConstants.FULL_PSVIMG_SIZE;
}
if ((curPos >= blockOffset) && (curPos < fullBlock))
{
break;
}
if (blockOffset > baseStream.Length)
{
break;
}
i++;
}
throw new Exception("Not found somehow..");
}
return i;
}
private long getRemainingBase()
{
return baseStream.Length - baseStream.Position;
@ -322,7 +285,7 @@ namespace PSVIMGTOOLS
baseStream.Read(iv, 0x00, iv.Length);
return iv;
}
private byte[] aes_ecb_decrypt(byte[] cipherData, byte[] IV)
private byte[] aes_cbc_decrypt(byte[] cipherData, byte[] IV)
{
MemoryStream ms = new MemoryStream();
Aes alg = Aes.Create();
@ -341,14 +304,47 @@ namespace PSVIMGTOOLS
private void seekToBlock(long blockIndex)
{
long blockOffset = (blockIndex * PSVIMGConstants.FULL_PSVIMG_SIZE) + PSVIMGConstants.AES_BLOCK_SIZE;
long blockOffset;
blockOffset = (blockIndex * PSVIMGConstants.FULL_PSVIMG_SIZE) + PSVIMGConstants.AES_BLOCK_SIZE;
if (blockOffset > baseStream.Length)
{
blockOffset = baseStream.Length;
}
baseStream.Seek(blockOffset, SeekOrigin.Begin);
}
private bool verifyFooter()
{
byte[] Footer = new byte[0x10];
byte[] IV = new byte[PSVIMGConstants.AES_BLOCK_SIZE];
baseStream.Seek(baseStream.Length - (Footer.Length + IV.Length), SeekOrigin.Begin);
baseStream.Read(IV, 0x00, PSVIMGConstants.AES_BLOCK_SIZE);
baseStream.Read(Footer, 0x00, 0x10);
byte[] FooterDec = aes_cbc_decrypt(Footer, IV);
UInt64 FooterLen;
using (MemoryStream ms = new MemoryStream(FooterDec))
{
ms.Seek(0x4, SeekOrigin.Current);
ms.Seek(0x4, SeekOrigin.Current);
byte[] LenInt = new byte[0x8];
ms.Read(LenInt, 0x00, 0x8);
FooterLen = BitConverter.ToUInt64(LenInt, 0x00);
}
if (Convert.ToUInt64(baseStream.Length) == FooterLen)
{
return true;
}
else
{
return false;
}
}
private byte[] getBlock(long blockIndex)
{
byte[] iv = getIV(blockIndex);
@ -362,9 +358,11 @@ namespace PSVIMGTOOLS
{
encryptedBlock = new byte[remaining];
}
baseStream.Read(encryptedBlock, 0x00, encryptedBlock.Length);
byte[] decryptedBlock = aes_ecb_decrypt(encryptedBlock, iv);
baseStream.Read(encryptedBlock, 0x00, encryptedBlock.Length);
byte[] decryptedBlock = aes_cbc_decrypt(encryptedBlock, iv);
return decryptedBlock;
}
}
}
}

183
CHOVY/PSVMDBuilder.cs Normal file
View File

@ -0,0 +1,183 @@
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_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);
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
writeUInt32(ms, 0x2); //version
writeInt64(ms, ContentSize); // content size
ms.Write(IV, 0x00, IV.Length); // IV
writeInt64(ms, 0x00); //ux0 info
writeInt64(ms, 0x00); //ur0 info
writeInt64(ms, 0x00); //unused 98
writeInt64(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);
writeInt32(ms, 0x00);
writeUInt32(ms, 0x00);
writeInt64(ms, ms.Length+0x8);
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, toEncrypt.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);
}
}
}

View File

@ -13,28 +13,8 @@ namespace CHOVY
[STAThread]
static void Main()
{
/*
FileStream fs = File.OpenWrite(@"C:\Users\earsy\Documents\Visual Studio 2017\Projects\CSharpImgTools\CSharpImgTools\bin\Debug\test.psvimg");
PSVIMGBuilder psvBuild = new PSVIMGBuilder(fs, CmaKeys.GenerateKey(new byte[] { 0xcf, 0x61, 0x85, 0xd5, 0xa7, 0x87, 0x0c, 0x4a }));
psvBuild.AddFile(@"C:\Users\earsy\Documents\Visual Studio 2017\Projects\CSharpImgTools\CSharpImgTools\bin\Debug\EBOOT.PBP", @"ux0:temp/game/PCSG90096/app/PCSG90096", @"/EBOOT.PBP");
psvBuild.AddDir(@"C:\Users\earsy\Documents\Visual Studio 2017\Projects\CSharpImgTools\CSharpImgTools\bin\Debug", @"ux0:temp/game/PCSG90096/app/PCSG90096", @"/sce_sys");
psvBuild.AddFile(@"C:\Users\earsy\Documents\Visual Studio 2017\Projects\CSharpImgTools\CSharpImgTools\bin\Debug\param.sfo", @"ux0:temp/game/PCSG90096/app/PCSG90096", @"/sce_sys/param.sfo");
psvBuild.Finish();
MemoryStream ms = new MemoryStream();
FileStream fs2 = File.OpenRead(@"C:\Users\earsy\Documents\Visual Studio 2017\Projects\CSharpImgTools\CSharpImgTools\bin\Debug\test.psvimg");
fs2.CopyTo(ms);
fs2.Close();
ms.Seek(0x00, SeekOrigin.Begin);
FileStream fs3 = File.OpenWrite(@"C:\Users\earsy\Documents\Visual Studio 2017\Projects\CSharpImgTools\CSharpImgTools\bin\Debug\test.psvimgd");
PSVIMGStream psv = new PSVIMGStream(ms, CmaKeys.GenerateKey(new byte[] { 0xcf, 0x61, 0x85, 0xd5, 0xa7, 0x87, 0x0c, 0x4a }));
psv.CopyTo(fs3);
fs3.Close();
psv.Close();
*/
FileStream psvmd = File.OpenRead(@"C:\Users\earsy\Documents\PS Vita\PGAME\cf6185d5a7870c4a\UCES00304\game\game.psvmd");
//File.WriteAllBytes(@"C:\Users\earsy\Documents\PS Vita\PGAME\cf6185d5a7870c4a\UCES00304\game\game.psvmdi", PSVMDBuilder.DecryptPsvmd(psvmd, CmaKeys.GenerateKey(new byte[] { 0xcf, 0x61, 0x85, 0xd5, 0xa7, 0x87, 0x0c, 0x4a })));
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new CHOVY());

View File

@ -2,4 +2,5 @@
<packages>
<package id="BouncyCastle" version="1.8.5" targetFramework="net45" />
<package id="Discutils" version="0.11.0.2" targetFramework="net452" />
<package id="DotNetZip" version="1.13.4" targetFramework="net46" />
</packages>

BIN
packages/DotNetZip.1.13.4/.signature.p7s vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff