A tool for deriving PKG packet encryption keys for ps4 written in c++
| 1 | #pragma once |
| 2 | |
| 3 | #include "../ir/AST.h" |
| 4 | #include "../ir/IR.h" |
| 5 | #include <map> |
| 6 | #include <memory> |
| 7 | #include <set> |
| 8 | #include <tuple> |
| 9 | |
| 10 | namespace ShadPKG::Decompiler::Lifter { |
| 11 | |
| 12 | // ╔═══════════════════════════════════════════════════════════════════════════╗ |
| 13 | // ║ VARIABLE ANALYSIS ║ |
| 14 | // ║ ║ |
| 15 | // ║ Scans the function for stack frame accesses (RBP/RSP based). ║ |
| 16 | // ║ Creates named LocalVariables (var_4, var_8). ║ |
| 17 | // ║ Replaces low-level Memory Expressions with higher-level Variable |
| 18 | // Expressions.║ |
| 19 | // ╚═══════════════════════════════════════════════════════════════════════════╝ |
| 20 | |
| 21 | class VariableAnalysis { |
| 22 | public: |
| 23 | explicit VariableAnalysis(std::shared_ptr<IR::Function> func); |
| 24 | |
| 25 | // ═══════════════════════════════════════════════════════════════════════ |
| 26 | // Main Analysis |
| 27 | // ═══════════════════════════════════════════════════════════════════════ |
| 28 | |
| 29 | void analyze(); |
| 30 | |
| 31 | // ═══════════════════════════════════════════════════════════════════════ |
| 32 | // Lifting |
| 33 | // ═══════════════════════════════════════════════════════════════════════ |
| 34 | |
| 35 | // Updates the FunctionAST with detected locals and parameters |
| 36 | void applyToAST(std::shared_ptr<AST::FunctionAST> ast); |
| 37 | |
| 38 | // Inferred Signature |
| 39 | const std::vector<AST::LocalVariable> &getDetectedParams() const { |
| 40 | return detectedParams_; |
| 41 | } |
| 42 | std::string getInferredReturnType() const { return inferredReturnType_; } |
| 43 | std::string getParamForRegister(uint64_t regId) const; |
| 44 | |
| 45 | // ═══════════════════════════════════════════════════════════════════════ |
| 46 | // SSA Register Tracking - converts registers to temp variables |
| 47 | // ═══════════════════════════════════════════════════════════════════════ |
| 48 | |
| 49 | // Get temp name for a register at a given instruction address |
| 50 | // Returns empty if not tracked (use register name as fallback) |
| 51 | std::string getTempForRegister(uint64_t regId, uint64_t instrAddr) const; |
| 52 | |
| 53 | // Track a new definition of a register at an instruction address |
| 54 | void trackRegisterDef(uint64_t regId, uint64_t instrAddr); |
| 55 | |
| 56 | // Resolves a memory operand to a variable name if possible |
| 57 | // Returns empty string if not a known variable |
| 58 | std::string resolveVariable(const IR::Operand &op); |
| 59 | |
| 60 | private: |
| 61 | std::shared_ptr<IR::Function> func_; |
| 62 | |
| 63 | // Stack Offset -> LocalVariable |
| 64 | // Offset is usually negative for locals (rbp - x) and positive for args (rbp |
| 65 | // + x) |
| 66 | std::map<int, AST::LocalVariable> stackVariables_; |
| 67 | std::vector<AST::LocalVariable> detectedParams_; |
| 68 | std::string inferredReturnType_ = "void"; |
| 69 | |
| 70 | // Registers used for passing arguments (System V AMD64 ABI) |
| 71 | // RDI, RSI, RDX, RCX, R8, R9 |
| 72 | std::map<uint64_t, int> registerParams_; // RegID -> ParamIndex |
| 73 | std::set<uint64_t> assignedRegisters_; // To detect use-before-def |
| 74 | std::map<uint64_t, std::string> regToParam_; |
| 75 | |
| 76 | // ═══════════════════════════════════════════════════════════════════════ |
| 77 | // SSA Tracking: {register, def_addr} -> temp_N |
| 78 | // ═══════════════════════════════════════════════════════════════════════ |
| 79 | struct RegDef { |
| 80 | uint64_t regId; |
| 81 | uint64_t defAddr; |
| 82 | bool operator<(const RegDef &o) const { |
| 83 | return std::tie(regId, defAddr) < std::tie(o.regId, o.defAddr); |
| 84 | } |
| 85 | }; |
| 86 | std::map<RegDef, std::string> ssaTemps_; |
| 87 | int nextTempId_ = 0; |
| 88 | |
| 89 | void scanInstruction(const IR::Instruction &instr); |
| 90 | void createVariable(int offset, int size, bool isParam); |
| 91 | }; |
| 92 | |
| 93 | } // namespace ShadPKG::Decompiler::Lifter |
| 94 |