Seregon/ShadPKG

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

C++/47.3 KB/No license
core/decompiler/analysis/StructuralAnalysis.h
ShadPKG / core / decompiler / analysis / StructuralAnalysis.h
1#pragma once
2 
3#include "../ir/AST.h"
4#include "../ir/IR.h"
5#include "../lifter/VariableAnalysis.h"
6#include "DominatorAnalysis.h"
7#include "SymbolAnalysis.h"
8#include <map>
9#include <memory>
10#include <set>
11#include <stack>
12 
13namespace ShadPKG::Decompiler::Analysis {
14 
15// ╔═══════════════════════════════════════════════════════════════════════════╗
16// ║ STRUCTURAL ANALYSIS ║
17// ║ ║
18// ║ Transforms the Command Flow Graph (CFG) into a high-level AST. ║
19// ║ Detects Control Structures: ║
20// ║ - Linear Sequences (Basic Blocks) ║
21// ║ - If-Then / If-Then-Else ║
22// ║ - While Loops / Do-While Loops ║
23// ║ ║
24// ║ Algorithm: Recursive Refinement / Region Structuring ║
25// ╚═══════════════════════════════════════════════════════════════════════════╝
26 
27class StructuralAnalysis {
28public:
29 StructuralAnalysis(
30 std::shared_ptr<IR::Function> func,
31 std::shared_ptr<DominatorAnalysis> domAnalysis,
32 std::shared_ptr<SymbolAnalysis> symbolAnalysis,
33 std::shared_ptr<Lifter::VariableAnalysis> varAnalysis = nullptr);
34 
35 // ═══════════════════════════════════════════════════════════════════════
36 // Main Analysis Method
37 // ═══════════════════════════════════════════════════════════════════════
38 
39 std::shared_ptr<AST::FunctionAST> analyze();
40 
41private:
42 std::shared_ptr<IR::Function> func_;
43 std::shared_ptr<DominatorAnalysis> dom_;
44 std::shared_ptr<SymbolAnalysis> symbols_;
45 std::shared_ptr<Lifter::VariableAnalysis> vars_;
46 
47 // Set of blocks already structured/visited to prevent infinite recursion
48 std::set<uint64_t> structuredBlocks_;
49 
50 // Set of loop headers currently being matched to prevent infinite recursion
51 std::set<uint64_t> activeLoops_;
52 
53 // Set of labels that have already been emitted for a goto statement
54 std::set<uint64_t> emittedLabels_;
55
56 // Set of blocks that are targets of goto statements (need labels)
57 std::set<uint64_t> gotoTargets_;
58 
59 // ═══════════════════════════════════════════════════════════════════════
60 // Recursive Structuring
61 // ═══════════════════════════════════════════════════════════════════════
62 
63 // Structure a region starting at 'entry'
64 std::shared_ptr<AST::Statement> structureRegion(uint64_t entryBlock,
65 uint64_t stopBlock = 0);
66 
67 // Structure a single basic block into a list of statements
68 std::shared_ptr<AST::CompoundStatement>
69 structureBlock(const std::shared_ptr<IR::BasicBlock> &bb);
70 
71 // ═══════════════════════════════════════════════════════════════════════
72 // Pattern Matchers
73 // ═══════════════════════════════════════════════════════════════════════
74 
75 // Try to match a loop starting at header
76 std::shared_ptr<AST::Statement> matchLoop(uint64_t header,
77 uint64_t stopBlock);
78 
79 // Try to match an If-Then-Else starting at block
80 std::shared_ptr<AST::Statement> matchIf(uint64_t block, uint64_t stopBlock);
81 
82 // Try to match a Switch starting at block
83 std::shared_ptr<AST::Statement> matchSwitch(uint64_t block,
84 uint64_t stopBlock);
85 
86 // ═══════════════════════════════════════════════════════════════════════
87 // Instruction Lifting Helpers
88 // ═══════════════════════════════════════════════════════════════════════
89 
90 // Convert IR instruction to AST statement(s)
91 std::shared_ptr<AST::Statement> liftInstruction(const IR::Instruction &instr);
92 
93 // Extract condition from a block ending in a conditional jump
94 std::shared_ptr<AST::Expression>
95 extractCondition(const std::shared_ptr<IR::BasicBlock> &bb, bool invert);
96 
97 // Helper to get basic block by ID
98 std::shared_ptr<IR::BasicBlock> getBlock(uint64_t id);
99};
100 
101} // namespace ShadPKG::Decompiler::Analysis
102