Skip to content

Commit

Permalink
add ps4 MGS5 support
Browse files Browse the repository at this point in the history
add mgs5
  • Loading branch information
bucanero committed Sep 8, 2023
1 parent a30b997 commit 188a99a
Show file tree
Hide file tree
Showing 14 changed files with 102 additions and 20 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build-win.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ jobs:
mv lego-checksum-fixer/lego-checksum-fixer lego-checksum-fixer.exe
mv mgs-hd-decrypter/mgs-hd-decrypter mgs-hd-decrypter.exe
mv mgs-pw-decrypter/mgs-pw-decrypter mgs-pw-decrypter.exe
mv mgs5-tpp-decrypter/mgs5-tpp-decrypter mgs5-tpp-decrypter.exe
mv naughtydog-decrypter/naughtydog-ps3save-decrypter naughtydog-save-decrypter.exe
mv nfs-rivals-decrypter/nfsrivals-ps3save-decrypter nfsrivals-ps3save-decrypter.exe
mv nfs-undercover-decrypter/nfs-undercover-decrypter nfs-undercover-decrypter.exe
Expand Down Expand Up @@ -99,6 +100,7 @@ jobs:
lego-checksum-fixer.exe \
mgs-hd-decrypter.exe \
mgs-pw-decrypter.exe \
mgs5-tpp-decrypter.exe \
naughtydog-save-decrypter.exe \
nfsrivals-ps3save-decrypter.exe \
nfs-undercover-decrypter.exe \
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ jobs:
lego-checksum-fixer/lego-checksum-fixer \
mgs-hd-decrypter/mgs-hd-decrypter \
mgs-pw-decrypter/mgs-pw-decrypter \
mgs5-tpp-decrypter/mgs5-tpp-decrypter \
naughtydog-decrypter/naughtydog-ps3save-decrypter \
nfs-rivals-decrypter/nfsrivals-ps3save-decrypter \
nfs-undercover-decrypter/nfs-undercover-decrypter \
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ all:
$(MAKE) -C lego-checksum-fixer
$(MAKE) -C mgs-hd-decrypter
$(MAKE) -C mgs-pw-decrypter
$(MAKE) -C mgs5-tpp-decrypter
$(MAKE) -C naughtydog-decrypter
$(MAKE) -C nfs-rivals-decrypter
$(MAKE) -C nfs-undercover-decrypter
Expand Down Expand Up @@ -53,6 +54,7 @@ clean:
$(MAKE) clean -C lego-checksum-fixer
$(MAKE) clean -C mgs-hd-decrypter
$(MAKE) clean -C mgs-pw-decrypter
$(MAKE) clean -C mgs5-tpp-decrypter
$(MAKE) clean -C naughtydog-decrypter
$(MAKE) clean -C nfs-rivals-decrypter
$(MAKE) clean -C nfs-undercover-decrypter
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Tools to decrypt specific PS3 save-games:
- Metal Gear Solid 3 HD - Snake Eater
- [mgs-pw-decrypter](./mgs-pw-decrypter)
- Metal Gear Solid: Peace Walker HD
- [mgs5-tpp-decrypter](./mgs5-tpp-decrypter)
- Metal Gear Solid V: The Phantom Pain
- [nfs-rivals-decrypter](./nfs-rivals-decrypter)
- Need For Speed: Rivals
- [nfs-undercover-decrypter](./nfs-undercover-decrypter)
Expand All @@ -48,6 +50,8 @@ Tools to decrypt specific PS4 save-games:
- Borderlands 3 (PS4)
- [gta5-decrypter](./gta5-decrypter)
- Grand Theft Auto 5 (PS4)
- [mgs5-tpp-decrypter](./mgs5-tpp-decrypter)
- Metal Gear Solid V: The Phantom Pain (PS4)
- [naughtydog-decrypter](./naughtydog-decrypter)
- The Last of Us Remastered (PS4)
- Uncharted 2 Remastered (PS4)
Expand Down
26 changes: 26 additions & 0 deletions mgs5-decrypter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# mgs5-tpp-decrypter

A tool to decrypt Metal Gear Solid V: The Phantom Pain PS3/PS4 save-games

```
USAGE: ./mgs5-tpp-decrypter [option] filename
OPTIONS Explanation:
-3 Auto-Decrypt/Encrypt PS3 File
-4 Auto-Decrypt/Encrypt PS4 File
```

### MD5 Hash

**Note:** the tool also updates the MD5 integrity hash.

```
[Update MD5 checksum (Required)]
set range:0x0010,EOF+1
set [hash]:MD5
write at 0x0000:[hash]
```

### Credits

This tool is based (reversed) on the original Xbox [MGS 5: The Phantom Pain SecFixer](https://www.360haven.com/forums/showthread.php/45050-MGS-5-The-Phantom-Pain-SecFixer) by Philymaster
41 changes: 21 additions & 20 deletions mgs5-decrypter/main.c
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
/*
*
* Metal Gear Solid V: The Phantom Pain PS3 Save Decrypter - (c) 2023 by Bucanero - www.bucanero.com.ar
* Metal Gear Solid V: The Phantom Pain PS3/PS4 Save Decrypter - (c) 2023 by Bucanero - www.bucanero.com.ar
*
* This tool is based (reversed) on the original diablo_3_save_data_decrypter by Red-EyeX32
* This tool is based (reversed) on the original Xbox "MGS: The Phantom Pain SecFixer" by Philymaster
*
*/

#include "../common/iofile.c"
#include "../common/md5.c"

#define MGSV_TPP_KEY 0x1FBAB234
#define MGSV_TPP_PS3KEY 0x1FBAB234
#define MGSV_TPP_PS4KEY 0x4131F8BE


void md5_hash(const u8* in, u32 size, u8* out)
Expand All @@ -29,46 +30,46 @@ void print_md5(const char* msg, const u8* data)
printf("\n");
}

void EncData(u32* source, int length)
void EncData(u32* source, int length, char type)
{
uint32_t key = MGSV_TPP_KEY;
uint32_t key = (type == '3') ? MGSV_TPP_PS3KEY : MGSV_TPP_PS4KEY;

for (int i = 0; i < length >> 2; i++)
{
key ^= (key << 13);
key ^= (key >> 7);
key ^= (key << 5);

source[i] = ES32(ES32(source[i]) ^ key);
source[i] = (type == '3') ? ES32(ES32(source[i]) ^ key) : (source[i] ^ key);
}
}

void decrypt_data(u8* data, u32 size)
void decrypt_data(u8* data, u32 size, char type)
{
printf("[*] Total Decrypted Size: 0x%X (%d bytes)\n", size, size);

EncData((u32*) data, size);
EncData((u32*) data, size, type);

printf("[*] Decrypted File Successfully!\n\n");
printf("[*] Decrypted PS%c File Successfully!\n\n", type);
return;
}

void encrypt_data(u8* data, u32 size)
void encrypt_data(u8* data, u32 size, char type)
{
printf("[*] Total Encrypted Size: 0x%X (%d bytes)\n", size, size);

EncData((u32*) data, size);
EncData((u32*) data, size, type);

printf("[*] Encrypted File Successfully!\n\n");
printf("[*] Encrypted PS%c File Successfully!\n\n", type);
return;
}

void print_usage(const char* argv0)
{
printf("USAGE: %s [option] filename\n\n", argv0);
printf("OPTIONS Explanation:\n");
printf(" -d Decrypt File\n");
printf(" -e Encrypt File\n\n");
printf(" -3 Auto-Decrypt/Encrypt PS3 File\n");
printf(" -4 Auto-Decrypt/Encrypt PS4 File\n\n");
return;
}

Expand All @@ -78,7 +79,7 @@ int main(int argc, char **argv)
u8* data;
char *opt, *bak;

printf("\nMetal Gear Solid V: TPP Save Decrypter 0.1.0 - (c) 2023 by Bucanero\n\n");
printf("\nMetal Gear Solid V: TPP PS3/PS4 Save Decrypter 0.1.0 - (c) 2023 by Bucanero\n\n");

if (--argc < 2)
{
Expand All @@ -87,7 +88,7 @@ int main(int argc, char **argv)
}

opt = argv[1];
if (*opt++ != '-' || (*opt != 'd' && *opt != 'e'))
if (*opt++ != '-' || (*opt != '3' && *opt != '4'))
{
print_usage(argv[0]);
return -1;
Expand All @@ -102,16 +103,16 @@ int main(int argc, char **argv)
asprintf(&bak, "%s.bak", argv[2]);
write_buffer(bak, data, len);

if (*opt == 'd')
decrypt_data(data, len);
else
if (data[0x10] == 'S' && data[0x11] == 'V')
{
print_md5("[*] Old MD5: ", data);
md5_hash(data + 0x10, len - 0x10, data);
print_md5("[*] New MD5: ", data);

encrypt_data(data, len);
encrypt_data(data, len, *opt);
}
else
decrypt_data(data, len, *opt);

write_buffer(argv[2], data, len);

Expand Down
Binary file added mgs5-decrypter/samples/PERSONAL_DATA0.dec
Binary file not shown.
Binary file added mgs5-decrypter/samples/PERSONAL_DATA0.enc
Binary file not shown.
Binary file added mgs5-decrypter/samples/TPP_CONFIG_DATA1.dec
Binary file not shown.
Binary file added mgs5-decrypter/samples/TPP_CONFIG_DATA1.enc
Binary file not shown.
Binary file added mgs5-decrypter/samples/TPP_GAME_DATA0.dec
Binary file not shown.
Binary file added mgs5-decrypter/samples/TPP_GAME_DATA0.enc
Binary file not shown.
46 changes: 46 additions & 0 deletions mgs5-decrypter/samples/findxor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import time
from multiprocessing import Pool

#desired_result = 0xDE40D74C # PS3
desired_result = 0xDF92344A # PS4
num_processes = 8 # You can adjust this based on the number of CPU cores you have.

def find_solution(start, end):
print ("ST=", hex(start), " END=", hex(end))
for x in range(start, end):
num = x
y = 0
while y < 5:
num = (num ^ ((num << 13) & 0xFFFFFFFF)) & 0xFFFFFFFF
num = (num ^ ((num >> 7) & 0xFFFFFFFF)) & 0xFFFFFFFF
num = (num ^ ((num << 5) & 0xFFFFFFFF)) & 0xFFFFFFFF
y += 1

if (num == desired_result):
print("X=", hex(x), " Y=", y) # Return the solution if found
return x # Return the solution if found

return None # Return None if no solution found in this range

def main():
start_time = time.time()

with Pool(num_processes) as pool:
# Divide the search space into equal parts for parallel processing
partition_size = 2**32 // num_processes
ranges = [(i * partition_size, (i + 1) * partition_size) for i in range(num_processes)]

results = pool.starmap(find_solution, ranges)

# Combine the results and print the solution if found
for result in results:
if result is not None:
print("Solution found: x =", result)
break

end_time = time.time()
execution_time = end_time - start_time
print("Execution time:", execution_time, "seconds")

if __name__ == "__main__":
main()
Binary file not shown.

0 comments on commit 188a99a

Please sign in to comment.