Seregon/ShadPKG

A tool for deriving PKG packet encryption keys for ps4 written in c++

C++/47.3 KB/No license
ps4MEL/ps4_safe_memory.h
ShadPKG / ps4MEL / ps4_safe_memory.h
1/*
2 * PS4 Safe Memory Access Layer
3 * Protects against invalid memory accesses in decompiled code
4 */
5 
6#ifndef PS4_SAFE_MEMORY_H
7#define PS4_SAFE_MEMORY_H
8 
9#include <cstdint>
10#include <cstring>
11 
12// Safe memory read - returns 0 for invalid addresses
13template<typename T>
14inline T safe_read(uintptr_t addr) {
15 extern uint8_t g_ps4_memory[];
16 extern const size_t G_PS4_MEMORY_SIZE;
17
18 // Check if address is within g_ps4_memory bounds
19 if (addr < G_PS4_MEMORY_SIZE) {
20 return *reinterpret_cast<T*>(&g_ps4_memory[addr]);
21 }
22
23 // Check if it's a pointer into g_ps4_memory
24 uintptr_t memBase = reinterpret_cast<uintptr_t>(g_ps4_memory);
25 if (addr >= memBase && addr < memBase + G_PS4_MEMORY_SIZE) {
26 return *reinterpret_cast<T*>(addr);
27 }
28
29 // Invalid address - return 0
30 return T(0);
31}
32 
33// Safe memory write - ignores writes to invalid addresses
34template<typename T>
35inline void safe_write(uintptr_t addr, T value) {
36 extern uint8_t g_ps4_memory[];
37 extern const size_t G_PS4_MEMORY_SIZE;
38
39 if (addr < G_PS4_MEMORY_SIZE) {
40 *reinterpret_cast<T*>(&g_ps4_memory[addr]) = value;
41 return;
42 }
43
44 uintptr_t memBase = reinterpret_cast<uintptr_t>(g_ps4_memory);
45 if (addr >= memBase && addr < memBase + G_PS4_MEMORY_SIZE) {
46 *reinterpret_cast<T*>(addr) = value;
47 }
48 // Otherwise silently ignore
49}
50 
51// Safe pointer dereference
52template<typename T>
53inline T safe_deref(T* ptr) {
54 if (ptr == nullptr) return T(0);
55
56 extern uint8_t g_ps4_memory[];
57 extern const size_t G_PS4_MEMORY_SIZE;
58
59 uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
60 uintptr_t memBase = reinterpret_cast<uintptr_t>(g_ps4_memory);
61
62 // Check if pointer is within valid memory
63 if (addr >= memBase && addr + sizeof(T) <= memBase + G_PS4_MEMORY_SIZE) {
64 return *ptr;
65 }
66
67 // Check if it's a small offset (likely g_ps4_memory index)
68 if (addr < G_PS4_MEMORY_SIZE) {
69 return *reinterpret_cast<T*>(&g_ps4_memory[addr]);
70 }
71
72 return T(0);
73}
74 
75// Safe pointer dereference for decompiled code - used by safe_deref_ptr<T>(ptr)
76template<typename T>
77inline T safe_deref_ptr(T* ptr) {
78 if (ptr == nullptr) return T(0);
79
80 extern uint8_t g_ps4_memory[];
81
82 uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
83 uintptr_t memBase = reinterpret_cast<uintptr_t>(g_ps4_memory);
84 constexpr size_t memSize = 0x1000000; // 16MB
85
86 // Check if pointer is within g_ps4_memory bounds
87 if (addr >= memBase && addr + sizeof(T) <= memBase + memSize) {
88 return *ptr;
89 }
90
91 // Check if it's a small offset (index into g_ps4_memory)
92 if (addr < memSize) {
93 return *reinterpret_cast<T*>(&g_ps4_memory[addr]);
94 }
95
96 // Invalid pointer - return 0 to avoid crash
97 return T(0);
98}
99 
100#endif // PS4_SAFE_MEMORY_H
101