Seregon/ShadPKG

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

C++/47.3 KB/No license
ps4MEL/ps4_tls.cpp
ShadPKG / ps4MEL / ps4_tls.cpp
1/*
2 * ╔═══════════════════════════════════════════════════════════════════════════╗
3 * ║ PS4 TLS - IMPLEMENTATION ║
4 * ╠═══════════════════════════════════════════════════════════════════════════╣
5 * ║ Cross-platform TLS implementation based on shadPS4 patterns. ║
6 * ╚═══════════════════════════════════════════════════════════════════════════╝
7 */
8 
9#include "ps4_tls.h"
10#include <cstring>
11#include <iostream>
12#include <mutex>
13 
14#ifdef _WIN32
15#include <windows.h>
16#elif defined(__APPLE__) || defined(__linux__)
17#include <pthread.h>
18#endif
19 
20namespace PS4Emu {
21 
22/*
23 * ┌─────────────────────────────────────────────────────────────────┐
24 * │ PLATFORM-SPECIFIC TLS │
25 * └─────────────────────────────────────────────────────────────────┘
26 */
27 
28#ifdef _WIN32
29// ═══════════════════════════════════════════════════════════════════
30// WINDOWS: Use TlsAlloc/TlsSetValue
31// ═══════════════════════════════════════════════════════════════════
32static DWORD g_tls_slot = 0;
33static bool g_tls_initialized = false;
34 
35bool InitializeTLS() {
36 if (g_tls_initialized)
37 return true;
38 
39 g_tls_slot = TlsAlloc();
40 if (g_tls_slot == TLS_OUT_OF_INDEXES) {
41 std::cerr << "[PS4Emu] ERROR: Failed to allocate TLS slot" << std::endl;
42 return false;
43 }
44 
45 g_tls_initialized = true;
46 std::cout << "[PS4Emu] TLS initialized (Windows, slot=" << g_tls_slot << ")"
47 << std::endl;
48 return true;
49}
50 
51void ShutdownTLS() {
52 if (g_tls_initialized) {
53 TlsFree(g_tls_slot);
54 g_tls_initialized = false;
55 }
56}
57 
58void SetTcbBase(Tcb *tcb) { TlsSetValue(g_tls_slot, tcb); }
59 
60Tcb *GetTcbBase() { return static_cast<Tcb *>(TlsGetValue(g_tls_slot)); }
61 
62#else
63// ═══════════════════════════════════════════════════════════════════
64// POSIX (macOS/Linux): Use pthread_key_t
65// ═══════════════════════════════════════════════════════════════════
66static pthread_key_t g_tls_key;
67static bool g_tls_initialized = false;
68static std::once_flag g_tls_init_flag;
69 
70static void TcbDestructor(void *tcb) {
71 // Called when thread exits - we don't free TCB here as it may be managed
72 // elsewhere
73}
74 
75bool InitializeTLS() {
76 bool success = false;
77 std::call_once(g_tls_init_flag, [&success]() {
78 if (pthread_key_create(&g_tls_key, TcbDestructor) != 0) {
79 std::cerr << "[PS4Emu] ERROR: Failed to create TLS key" << std::endl;
80 success = false;
81 return;
82 }
83 g_tls_initialized = true;
84 success = true;
85 std::cout << "[PS4Emu] TLS initialized (POSIX)" << std::endl;
86 });
87 return g_tls_initialized;
88}
89 
90void ShutdownTLS() {
91 if (g_tls_initialized) {
92 pthread_key_delete(g_tls_key);
93 g_tls_initialized = false;
94 }
95}
96 
97void SetTcbBase(Tcb *tcb) { pthread_setspecific(g_tls_key, tcb); }
98 
99Tcb *GetTcbBase() { return static_cast<Tcb *>(pthread_getspecific(g_tls_key)); }
100 
101#endif
102 
103/*
104 * ┌─────────────────────────────────────────────────────────────────┐
105 * │ COMMON IMPLEMENTATION │
106 * └─────────────────────────────────────────────────────────────────┘
107 */
108 
109Tcb *CreateTcb() {
110 Tcb *tcb = new Tcb();
111 std::memset(tcb, 0, sizeof(Tcb));
112 
113 // Self-pointer for FS/GS base access patterns
114 tcb->tcb_self = tcb;
115 tcb->tcb_dtv = nullptr;
116 tcb->tcb_thread = nullptr;
117 tcb->tcb_errno = 0;
118 
119 return tcb;
120}
121 
122void DestroyTcb(Tcb *tcb) { delete tcb; }
123 
124int32_t *GetErrno() {
125 Tcb *tcb = GetTcbBase();
126 if (!tcb) {
127 // Fallback: create TCB if not exists
128 static thread_local int32_t fallback_errno = 0;
129 return &fallback_errno;
130 }
131 return &tcb->tcb_errno;
132}
133 
134} // namespace PS4Emu
135