Seregon/ShadPKG

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

C++/47.3 KB/No license
core/decompiler/analysis/SymbolAnalysis.h
ShadPKG / core / decompiler / analysis / SymbolAnalysis.h
1#pragma once
2 
3#include "../ir/IR.h"
4#include "SymbolDatabase.h"
5#include <cstdint>
6#include <map>
7#include <optional>
8#include <string>
9#include <vector>
10 
11namespace ShadPKG::Decompiler::Analysis {
12 
13// ╔═══════════════════════════════════════════════════════════════════════════╗
14// ║ SYMBOL ANALYSIS ║
15// ║ ║
16// ║ Parses ELF structures to resolve function names and data literals. ║
17// ║ - Dynamic Symbols (.dynsym) ║
18// ║ - PLT Relocations (.rela.plt) -> External calls ║
19// ║ - String Literals (.rodata) ║
20// ╚═══════════════════════════════════════════════════════════════════════════╝
21 
22class SymbolAnalysis {
23public:
24 explicit SymbolAnalysis(const std::vector<uint8_t> &rawData,
25 uint64_t baseAddress,
26 std::shared_ptr<SymbolDatabase> db);
27 
28 void analyze();
29 
30 // ═══════════════════════════════════════════════════════════════════════
31 // Queries
32 // ═══════════════════════════════════════════════════════════════════════
33 
34 // Get function name for a given address (internal or PLT)
35 // Returns std::nullopt if not found
36 std::optional<std::string> getFunctionName(uint64_t address) const;
37 
38 // Check if an address points to a C-string in .rodata
39 std::optional<std::string> getStringLiteral(uint64_t address) const;
40 
41 // Get full symbol info
42 std::optional<SymbolInfo> getSymbol(uint64_t address) const;
43 
44 // Check if address is a known PLT stub
45 bool isPLTStub(uint64_t address) const;
46 
47private:
48 const std::vector<uint8_t> &data_;
49 uint64_t baseAddress_;
50 std::shared_ptr<SymbolDatabase> db_;
51 
52 // Address -> Name
53 std::map<uint64_t, std::string> symbols_;
54 
55 // PLT Address -> Target Name (e.g. 0x400560 -> "malloc")
56 std::map<uint64_t, std::string> pltEntries_;
57 
58 // Read-only data sections
59 struct RodataSection {
60 uint64_t va;
61 uint64_t size;
62 uint64_t fileOffset;
63 };
64 std::vector<RodataSection> rodataSections_;
65 
66 // Helpers
67 void parseELF();
68 void parseSections(uint64_t shoff, uint16_t shnum, uint16_t shstrndx);
69 void parseSymbols(uint64_t symOffset, uint64_t strOffset, uint64_t size,
70 uint64_t entSize);
71 void parseRelocations(uint64_t relOffset, uint64_t size, uint64_t entSize,
72 uint64_t dynStrOffset, uint64_t dynSymOffset,
73 bool isRela);
74 
75 std::string readString(uint64_t offset) const;
76 
77 // Minimal ELF structures
78 struct Elf64_Ehdr {
79 unsigned char e_ident[16];
80 uint16_t e_type;
81 uint16_t e_machine;
82 uint32_t e_version;
83 uint64_t e_entry;
84 uint64_t e_phoff;
85 uint64_t e_shoff;
86 uint32_t e_flags;
87 uint16_t e_ehsize;
88 uint16_t e_phentsize;
89 uint16_t e_phnum;
90 uint16_t e_shentsize;
91 uint16_t e_shnum;
92 uint16_t e_shstrndx;
93 };
94 
95 struct Elf64_Shdr {
96 uint32_t sh_name;
97 uint32_t sh_type;
98 uint64_t sh_flags;
99 uint64_t sh_addr;
100 uint64_t sh_offset;
101 uint64_t sh_size;
102 uint32_t sh_link;
103 uint32_t sh_info;
104 uint64_t sh_addralign;
105 uint64_t sh_entsize;
106 };
107 
108 struct Elf64_Sym {
109 uint32_t st_name;
110 unsigned char st_info;
111 unsigned char st_other;
112 uint16_t st_shndx;
113 uint64_t st_value;
114 uint64_t st_size;
115 };
116 
117 struct Elf64_Rela {
118 uint64_t r_offset;
119 uint64_t r_info;
120 int64_t r_addend;
121 };
122};
123 
124} // namespace ShadPKG::Decompiler::Analysis
125