Seregon/ShadPKG

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

C++/47.3 KB/No license
core/decompiler/DecompilerContext.h
ShadPKG / core / decompiler / DecompilerContext.h
1#pragma once
2 
3#include "analysis/DataFlowAnalysis.h"
4#include "analysis/DominatorAnalysis.h"
5#include "analysis/StructuralAnalysis.h"
6#include "analysis/SymbolAnalysis.h"
7#include "codegen/CppEmitter.h"
8#include "ir/AST.h"
9#include "ir/IR.h"
10#include "lifter/VariableAnalysis.h"
11#include <map>
12#include <memory>
13#include <set>
14#include <string>
15#include <vector>
16 
17#include "analysis/SymbolDatabase.h"
18#include "analysis/TypeSystem.h"
19 
20namespace ShadPKG::Decompiler {
21 
22namespace IR {
23class Function;
24}
25 
26class DecompilerContext {
27public:
28 static DecompilerContext &Get() {
29 static DecompilerContext instance;
30 return instance;
31 }
32 
33 ~DecompilerContext() = default;
34 
35 void LoadBinary(const std::vector<uint8_t> &data, uint64_t baseAddress);
36 bool LoadELF(const std::vector<uint8_t> &data);
37 void Analyze();
38 std::string GenerateCode();
39 std::string GenerateStructuredCode();
40 void ExportProject(const std::string &outPath);
41 
42 // Project Persistence
43 bool SaveProject(const std::string &path);
44 bool LoadProject(const std::string &path);
45 
46 // Safe memory access helpers
47 uint64_t ReadPointer(uint64_t address) const;
48 int32_t ReadInt32(uint64_t address) const;
49 
50 uint64_t GetBaseAddress() const { return baseAddress_; }
51 uint64_t GetEntryPoint() const { return entryPoint_; }
52 void SetEntryPoint(uint64_t ep) { entryPoint_ = ep; }
53
54 uint64_t GetInitArrayAddr() const { return initArrayAddr_; }
55 uint64_t GetInitArraySize() const { return initArraySize_; }
56 uint64_t GetFiniArrayAddr() const { return finiArrayAddr_; }
57 uint64_t GetFiniArraySize() const { return finiArraySize_; }
58 
59 const std::vector<std::shared_ptr<IR::Function>> &GetFunctions() const {
60 return functions_;
61 }
62 const std::vector<uint8_t> &GetRawData() const { return rawData_; }
63 
64 // Helper to find a function by address
65 std::shared_ptr<IR::Function> GetFunctionAt(uint64_t address);
66 std::shared_ptr<Analysis::SymbolDatabase> GetSymbolDatabase() {
67 return symbolDatabase_;
68 }
69 
70 // Get Code Tokens for a function (populates after GenerateStructuredCode)
71 const std::vector<Codegen::CppEmitter::Token> &
72 GetFunctionTokens(uint64_t address) const;
73 
74private:
75 void AnalyzeFunction(uint64_t startAddress,
76 std::set<uint64_t> &visitedGlobal);
77 
78 std::vector<uint8_t> rawData_;
79 uint64_t baseAddress_ = 0;
80 uint64_t entryPoint_ = 0;
81 uint64_t elfOffset_ = 0;
82 uint64_t initArrayAddr_ = 0;
83 uint64_t initArraySize_ = 0;
84 uint64_t finiArrayAddr_ = 0;
85 uint64_t finiArraySize_ = 0;
86 std::vector<std::shared_ptr<IR::Function>> functions_;
87 std::shared_ptr<Analysis::SymbolDatabase> symbolDatabase_;
88 std::shared_ptr<Analysis::TypeManager> typeManager_ =
89 std::make_shared<Analysis::TypeManager>();
90 
91 // Persistence for user overrides: FunctionAddr -> (StackOffset -> Type)
92 std::map<uint64_t, std::map<int, std::shared_ptr<Analysis::Type>>>
93 userVarTypes_;
94 
95public:
96 std::shared_ptr<Analysis::TypeManager> GetTypeManager() {
97 return typeManager_;
98 }
99 
100 void SetUserVarType(uint64_t funcAddr, int stackOffset,
101 std::shared_ptr<Analysis::Type> type) {
102 userVarTypes_[funcAddr][stackOffset] = type;
103 }
104 
105 std::shared_ptr<Analysis::Type> GetUserVarType(uint64_t funcAddr,
106 int stackOffset) {
107 if (userVarTypes_.count(funcAddr) &&
108 userVarTypes_[funcAddr].count(stackOffset)) {
109 return userVarTypes_[funcAddr][stackOffset];
110 }
111 return nullptr;
112 }
113 
114private:
115 std::map<uint64_t, std::vector<Codegen::CppEmitter::Token>> functionTokens_;
116 std::map<uint64_t, int> functionParamCounts_;
117 
118public:
119 int GetFunctionParamCount(uint64_t address) const {
120 auto it = functionParamCounts_.find(address);
121 if (it != functionParamCounts_.end())
122 return it->second;
123 return 0; // Default or unknown
124 }
125 void SetFunctionParamCount(uint64_t address, int count) {
126 functionParamCounts_[address] = count;
127 }
128 
129 // ┌─────────────────────────────────────────────────────────────────────────┐
130 // │ Progress Tracking for GUI │
131 // └─────────────────────────────────────────────────────────────────────────┘
132public:
133 struct AnalysisProgress {
134 int prologuesFound = 0; // Candidates from prologue scan
135 int functionsAnalyzed = 0; // Functions fully analyzed
136 std::string currentPhase; // "scanning", "analyzing", "complete"
137 bool isComplete = false;
138 };
139 
140 const AnalysisProgress &GetProgress() const { return progress_; }
141 
142private:
143 mutable AnalysisProgress progress_;
144 
145 // Status tracking
146 bool isAnalyzed_ = false;
147 
148 struct Segment {
149 uint64_t virtualAddress;
150 uint64_t fileOffset;
151 uint64_t size; // p_filesz: bytes present in file
152 uint64_t memSize; // p_memsz: bytes to map in memory (>= size, BSS zero-pad)
153 };
154 std::vector<Segment> segments_;
155 
156 bool VirtualAddressToFileOffset(uint64_t va, uint64_t &offset) const;
157};
158 
159} // namespace ShadPKG::Decompiler
160