mirror of
https://github.com/rvtr/ctr_test_tools.git
synced 2025-10-31 13:41:24 -04:00
FalsifyTwlBackup:BkpType Legacy に対応。
(こっちがFalsifyTwlBackup で、 r38 は TWLBackupBlock) git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_test_tools@39 6b0af911-cb57-b745-895f-eec5701120e1
This commit is contained in:
parent
12cf32bf6b
commit
279357adf6
@ -88,22 +88,30 @@ partial class Program
|
|||||||
|
|
||||||
// public save の fileSize を変更
|
// public save の fileSize を変更
|
||||||
case 209:
|
case 209:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.PUBLIC_SAVE]++;
|
header.fileSizes[prop.indexPublicSave]++;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, NONE, NC_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, NONE, NC_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// sub banner の fileSize を変更
|
// sub banner の fileSize を変更
|
||||||
case 210:
|
case 210:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.SUB_BANNER]++;
|
header.fileSizes[prop.indexSubBanner]++;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, NONE, NC_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, NONE, NC_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// コンテンツ ID を変更
|
||||||
case 211:
|
case 211:
|
||||||
for (int i = 0; i < header.contentId.Length; i++)
|
if (prop.bkpType != BkpType.LEGACY)
|
||||||
{
|
{
|
||||||
header.contentId[i]++;
|
for (int i = 0; i < header.contentId.Length; i++)
|
||||||
|
{
|
||||||
|
header.contentId[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
header.contentIdForLegacy++;
|
||||||
}
|
}
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, NONE, NC_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, NONE, NC_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
@ -123,7 +131,7 @@ partial class Program
|
|||||||
|
|
||||||
// public save の fileSize, TMD Reserved の publicSaveSize を変更
|
// public save の fileSize, TMD Reserved の publicSaveSize を変更
|
||||||
case 214:
|
case 214:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.PUBLIC_SAVE]++;
|
header.fileSizes[prop.indexPublicSave]++;
|
||||||
header.tmdReserved.publicSaveSize++;
|
header.tmdReserved.publicSaveSize++;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, NONE, NC_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, NONE, NC_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
|
|||||||
@ -72,28 +72,28 @@ partial class Program
|
|||||||
|
|
||||||
// public save の fileSize を大きくした上で、public save の前に不正なデータを入れる
|
// public save の fileSize を大きくした上で、public save の前に不正なデータを入れる
|
||||||
case 406:
|
case 406:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.PUBLIC_SAVE] += IMPROPER_DATA_SIZE;
|
header.fileSizes[prop.indexPublicSave] += IMPROPER_DATA_SIZE;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, FRONT_PUBLIC_SAVE, NC_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, FRONT_PUBLIC_SAVE, NC_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// public save の fileSize を大きくした上で、public save の後ろに不正なデータを入れる
|
// public save の fileSize を大きくした上で、public save の後ろに不正なデータを入れる
|
||||||
case 407:
|
case 407:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.PUBLIC_SAVE] += IMPROPER_DATA_SIZE;
|
header.fileSizes[prop.indexPublicSave] += IMPROPER_DATA_SIZE;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, REAR_PUBLIC_SAVE, NC_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, REAR_PUBLIC_SAVE, NC_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// サブバナーの fileSize を大きくした上で、サブバナーの前に不正なデータを入れる
|
// サブバナーの fileSize を大きくした上で、サブバナーの前に不正なデータを入れる
|
||||||
case 408:
|
case 408:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.SUB_BANNER] += IMPROPER_DATA_SIZE;
|
header.fileSizes[prop.indexPublicSave] += IMPROPER_DATA_SIZE;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, FRONT_SUB_BANNER, NC_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, FRONT_SUB_BANNER, NC_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// サブバナーの fileSize を大きくした上で、サブバナーの後ろに不正なデータを入れる
|
// サブバナーの fileSize を大きくした上で、サブバナーの後ろに不正なデータを入れる
|
||||||
case 409:
|
case 409:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.SUB_BANNER] += IMPROPER_DATA_SIZE;
|
header.fileSizes[prop.indexSubBanner] += IMPROPER_DATA_SIZE;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, REAR_SUB_BANNER, NC_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, REAR_SUB_BANNER, NC_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
break;
|
break;
|
||||||
@ -112,7 +112,7 @@ partial class Program
|
|||||||
|
|
||||||
// public save の fileSize, TMD Reserved の publicSave を変更し、public save の前にデータを入れる
|
// public save の fileSize, TMD Reserved の publicSave を変更し、public save の前にデータを入れる
|
||||||
case 412:
|
case 412:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.PUBLIC_SAVE] += IMPROPER_DATA_SIZE;
|
header.fileSizes[prop.indexPublicSave] += IMPROPER_DATA_SIZE;
|
||||||
header.tmdReserved.publicSaveSize += IMPROPER_DATA_SIZE;
|
header.tmdReserved.publicSaveSize += IMPROPER_DATA_SIZE;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, FRONT_PUBLIC_SAVE, NC_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, FRONT_PUBLIC_SAVE, NC_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
@ -120,7 +120,7 @@ partial class Program
|
|||||||
|
|
||||||
// public save の fileSize, TMD Reserved の publicSave を変更し、public save の後ろにデータを入れる
|
// public save の fileSize, TMD Reserved の publicSave を変更し、public save の後ろにデータを入れる
|
||||||
case 413:
|
case 413:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.PUBLIC_SAVE] += IMPROPER_DATA_SIZE;
|
header.fileSizes[prop.indexPublicSave] += IMPROPER_DATA_SIZE;
|
||||||
header.tmdReserved.publicSaveSize += IMPROPER_DATA_SIZE;
|
header.tmdReserved.publicSaveSize += IMPROPER_DATA_SIZE;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, REAR_PUBLIC_SAVE, NC_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, REAR_PUBLIC_SAVE, NC_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
|
|||||||
@ -77,7 +77,7 @@ partial class Program
|
|||||||
// public save の fileSize を大きくした上で、public save の前に不正なデータを入れる
|
// public save の fileSize を大きくした上で、public save の前に不正なデータを入れる
|
||||||
// public save ブロックの MAC を更新し、署名ブロック内ハッシュも更新する
|
// public save ブロックの MAC を更新し、署名ブロック内ハッシュも更新する
|
||||||
case 506:
|
case 506:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.PUBLIC_SAVE] += IMPROPER_DATA_SIZE;
|
header.fileSizes[prop.indexPublicSave] += IMPROPER_DATA_SIZE;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, FRONT_PUBLIC_SAVE, CHG_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, FRONT_PUBLIC_SAVE, CHG_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
break;
|
break;
|
||||||
@ -85,7 +85,7 @@ partial class Program
|
|||||||
// public save の fileSize を大きくした上で、public save の後ろに不正なデータを入れる
|
// public save の fileSize を大きくした上で、public save の後ろに不正なデータを入れる
|
||||||
// public save ブロックの MAC を更新し、署名ブロック内ハッシュも更新する
|
// public save ブロックの MAC を更新し、署名ブロック内ハッシュも更新する
|
||||||
case 507:
|
case 507:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.PUBLIC_SAVE] += IMPROPER_DATA_SIZE;
|
header.fileSizes[prop.indexPublicSave] += IMPROPER_DATA_SIZE;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, REAR_PUBLIC_SAVE, CHG_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, REAR_PUBLIC_SAVE, CHG_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
break;
|
break;
|
||||||
@ -93,7 +93,7 @@ partial class Program
|
|||||||
// サブバナーの fileSize を大きくした上で、サブバナーの前に不正なデータを入れる
|
// サブバナーの fileSize を大きくした上で、サブバナーの前に不正なデータを入れる
|
||||||
// サブバナーブロックの MAC を更新し、署名ブロック内ハッシュも更新する
|
// サブバナーブロックの MAC を更新し、署名ブロック内ハッシュも更新する
|
||||||
case 508:
|
case 508:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.SUB_BANNER] += IMPROPER_DATA_SIZE;
|
header.fileSizes[prop.indexSubBanner] += IMPROPER_DATA_SIZE;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, FRONT_SUB_BANNER, CHG_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, FRONT_SUB_BANNER, CHG_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
break;
|
break;
|
||||||
@ -101,7 +101,7 @@ partial class Program
|
|||||||
// サブバナーの fileSize を大きくした上で、サブバナーの後ろに不正なデータを入れる
|
// サブバナーの fileSize を大きくした上で、サブバナーの後ろに不正なデータを入れる
|
||||||
// サブバナーブロックの MAC を更新し、署名ブロック内ハッシュも更新する
|
// サブバナーブロックの MAC を更新し、署名ブロック内ハッシュも更新する
|
||||||
case 509:
|
case 509:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.SUB_BANNER] += IMPROPER_DATA_SIZE;
|
header.fileSizes[prop.indexSubBanner] += IMPROPER_DATA_SIZE;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, REAR_SUB_BANNER, CHG_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, REAR_SUB_BANNER, CHG_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
break;
|
break;
|
||||||
@ -121,7 +121,7 @@ partial class Program
|
|||||||
// public save の fileSize, TMD Reserved の publicSave を変更し、public save の前にデータを入れる
|
// public save の fileSize, TMD Reserved の publicSave を変更し、public save の前にデータを入れる
|
||||||
// public save ブロックの MAC を更新し、署名ブロック内ハッシュも更新する
|
// public save ブロックの MAC を更新し、署名ブロック内ハッシュも更新する
|
||||||
case 512:
|
case 512:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.PUBLIC_SAVE] += IMPROPER_DATA_SIZE;
|
header.fileSizes[prop.indexPublicSave] += IMPROPER_DATA_SIZE;
|
||||||
header.tmdReserved.publicSaveSize += IMPROPER_DATA_SIZE;
|
header.tmdReserved.publicSaveSize += IMPROPER_DATA_SIZE;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, FRONT_PUBLIC_SAVE, CHG_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, FRONT_PUBLIC_SAVE, CHG_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
@ -130,7 +130,7 @@ partial class Program
|
|||||||
// public save の fileSize, TMD Reserved の publicSave を変更し、public save の後ろにデータを入れる
|
// public save の fileSize, TMD Reserved の publicSave を変更し、public save の後ろにデータを入れる
|
||||||
// public save ブロックの MAC を更新し、署名ブロック内ハッシュも更新する
|
// public save ブロックの MAC を更新し、署名ブロック内ハッシュも更新する
|
||||||
case 513:
|
case 513:
|
||||||
header.fileSizes[(int)Utility.SectionIndex.PUBLIC_SAVE] += IMPROPER_DATA_SIZE;
|
header.fileSizes[prop.indexPublicSave] += IMPROPER_DATA_SIZE;
|
||||||
header.tmdReserved.publicSaveSize += IMPROPER_DATA_SIZE;
|
header.tmdReserved.publicSaveSize += IMPROPER_DATA_SIZE;
|
||||||
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, REAR_PUBLIC_SAVE, CHG_MAC_AND_HASHSET);
|
outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, REAR_PUBLIC_SAVE, CHG_MAC_AND_HASHSET);
|
||||||
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
OutputFalsifiedData(improperNo, prop.outFolderPath, outData);
|
||||||
|
|||||||
@ -71,7 +71,7 @@ partial class Program
|
|||||||
/// <param name="dataBlocks">変更対象となる署名ブロックを有するBlocks</param>
|
/// <param name="dataBlocks">変更対象となる署名ブロックを有するBlocks</param>
|
||||||
/// <param name="hash">新しいハッシュ値</param>
|
/// <param name="hash">新しいハッシュ値</param>
|
||||||
/// <param name="section">変更するブロックセクション</param>
|
/// <param name="section">変更するブロックセクション</param>
|
||||||
static void ChangeHashSet(Blocks dataBlocks, byte[] hash, int section)
|
static void ChangeHashSet(Blocks dataBlocks, byte[] hash, int section, BkpType type)
|
||||||
{
|
{
|
||||||
Debug.Assert((section <= BLOCK_NUM - 1) && (section >= 0));
|
Debug.Assert((section <= BLOCK_NUM - 1) && (section >= 0));
|
||||||
|
|
||||||
@ -98,11 +98,25 @@ partial class Program
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SECTION_PUBLIC_SAVE:
|
case SECTION_PUBLIC_SAVE:
|
||||||
hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.PUBLIC_SAVE], 0);
|
if (type != BkpType.LEGACY)
|
||||||
|
{
|
||||||
|
hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.PUBLIC_SAVE], 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hash.CopyTo(signature.digest.section[(int)Utility.SectionIndexLegacy.PUBLIC_SAVE], 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SECTION_SUB_BANNER:
|
case SECTION_SUB_BANNER:
|
||||||
hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.SUB_BANNER], 0);
|
if (type != BkpType.LEGACY)
|
||||||
|
{
|
||||||
|
hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.SUB_BANNER], 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hash.CopyTo(signature.digest.section[(int)Utility.SectionIndexLegacy.SUB_BANNER], 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SECTION_PRIVATE_SAVE:
|
case SECTION_PRIVATE_SAVE:
|
||||||
@ -227,7 +241,7 @@ partial class Program
|
|||||||
if (dataBlocks[i].body != null)
|
if (dataBlocks[i].body != null)
|
||||||
{
|
{
|
||||||
encryptedBlocks[i] = EncryptBlock(dataBlocks, i, prop, impData, insertPos, byteMac[i], byteHash[i]); // ブロックを暗号化&結合
|
encryptedBlocks[i] = EncryptBlock(dataBlocks, i, prop, impData, insertPos, byteMac[i], byteHash[i]); // ブロックを暗号化&結合
|
||||||
ChangeHashSet(dataBlocks, byteHash[i], i); // ハッシュセットを更新
|
ChangeHashSet(dataBlocks, byteHash[i], i, prop.bkpType); // ハッシュセットを更新
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -14,6 +14,8 @@ namespace FalsifyTwlBackup
|
|||||||
public byte[] macKeyData; // MAC生成のための鍵データ
|
public byte[] macKeyData; // MAC生成のための鍵データ
|
||||||
|
|
||||||
public BkpType bkpType; // バックアップの形式。
|
public BkpType bkpType; // バックアップの形式。
|
||||||
|
public int indexPublicSave; // パブリックセーブデータのインデックス
|
||||||
|
public int indexSubBanner; // サブバナーのインデックス
|
||||||
|
|
||||||
public string outFolderPath; // 出力フォルダ名
|
public string outFolderPath; // 出力フォルダ名
|
||||||
|
|
||||||
|
|||||||
@ -229,6 +229,8 @@ partial class Program
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// 拡張子の判定
|
// 拡張子の判定
|
||||||
CheckExtension(args[0], ".bin"); // 入力ファイル名
|
CheckExtension(args[0], ".bin"); // 入力ファイル名
|
||||||
@ -258,10 +260,17 @@ partial class Program
|
|||||||
|
|
||||||
int argTypeIndex = (isSpecifyMode) ? 6 : 4;
|
int argTypeIndex = (isSpecifyMode) ? 6 : 4;
|
||||||
prop.bkpType = BkpType.NORMAL;
|
prop.bkpType = BkpType.NORMAL;
|
||||||
|
prop.indexPublicSave = (int)Utility.SectionIndex.PUBLIC_SAVE;
|
||||||
|
prop.indexSubBanner = (int)Utility.SectionIndex.SUB_BANNER;
|
||||||
if (args.Length >= argTypeIndex + 1 && args[argTypeIndex - 1].ToUpper().TrimStart('-') == "TYPE")
|
if (args.Length >= argTypeIndex + 1 && args[argTypeIndex - 1].ToUpper().TrimStart('-') == "TYPE")
|
||||||
{
|
{
|
||||||
prop.bkpType = GetBackupType(args[argTypeIndex]);
|
prop.bkpType = GetBackupType(args[argTypeIndex]);
|
||||||
}
|
}
|
||||||
|
if (prop.bkpType == BkpType.LEGACY)
|
||||||
|
{
|
||||||
|
prop.indexPublicSave = (int)Utility.SectionIndexLegacy.PUBLIC_SAVE;
|
||||||
|
prop.indexSubBanner = (int)Utility.SectionIndexLegacy.SUB_BANNER;
|
||||||
|
}
|
||||||
|
|
||||||
// バックアップデータの読み込み
|
// バックアップデータの読み込み
|
||||||
byte[] twlBackupData = File.ReadAllBytes(twlBackupName);
|
byte[] twlBackupData = File.ReadAllBytes(twlBackupName);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user