forked from WerWolv/ImHex-Patterns
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathupk-ue3.hexpat
More file actions
156 lines (128 loc) · 3.19 KB
/
upk-ue3.hexpat
File metadata and controls
156 lines (128 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#pragma description Unreal Engine 3 UPK
#pragma endian little
#pragma magic [ c1 83 2a 9e ] @ 0x00
import std.io;
#define HEADER_LOCATION 0x00
#define FILE_SIGNATURE 0x9E2A83C1
#define VER_GIGANTIC 867
#define VER_BATMAN_CITY 805
using offset = u32;
bool isCompressed = false;
// Generations Info
struct FGenerationInfo {
u32 exportcount;
u32 namecount;
u32 netobjectcount;
};
// Compressed Chunk Info
struct CompressedChunkInfo {
offset uncompressedoffset;
u32 uncompressedsize;
offset compressedoffset;
u32 compressedsize;
};
// Name Table Entry
struct FNameEntry {
s32 namelength;
char name[];
u64 nameflags;
};
// Import Table Entry
struct FObjectImport {
u64 packageid;
u64 typeid;
u32 ownerref;
u64 nameid;
};
// Export Table Entry
struct FObjectExport {
u32 typeref;
u32 parentclassref;
u32 ownerref;
u64 nameid;
u32 archetyperef;
u32 objectflagsh;
u32 objectflagsl;
u32 serialsize;
offset serialoffset;
u32 exportflags;
u32 netobjectcount;
u128 guid;
u32 unknown1;
u8 unknown2[netobjectcount * 4];
};
// Main File Header
struct FileHeader {
// File signature
u32 signature;
// Version
u16 version;
// Licensee
u16 licensee;
// Header Size
u32 headersize;
// FolderName
u32 foldername ;
// PackageInfo
char packagegroup[];
u32 packageflags; // todo: properly expand this
// GigUnknown
if (version == VER_GIGANTIC) {
u32 gigunknown1; // this seems to be unique to gig's upk format
}
// Name Table Info
u32 namecount;
offset nameoffset;
// Export Table Info
u32 exportcount;
offset exportoffset;
// Import Table Info
u32 importcount;
offset importoffset;
// Depends Info
offset dependsoffset;
// Unknown
if (version >= VER_BATMAN_CITY) {
offset serialoffset;
u32 ueunknown1; // these are present in other ue3 upks
u32 ueunknown2;
u32 ueunknown3;
}
// GUID
u128 packageguid;
// Generations Info
u32 generationscount;
FGenerationInfo generations[generationscount];
// Engine Info
u32 engineversion;
u32 cookerversion;
// Compression Info
u32 compressionflags;
u32 compressedchunks;
CompressedChunkInfo chunks[compressedchunks];
};
// Print Info
fn print_info(FileHeader header) {
if(header.signature == FILE_SIGNATURE){
std::print("UPK: Yes");
} else {
std::print("UPK: No");
}
std::print("Version: {} ",header.version);
std::print("Licensee: {} ",header.licensee);
std::print("Compressed: {} ",isCompressed);
std::print("Name Count: {} ",header.namecount);
std::print("Import Count: {} ",header.importcount);
std::print("Export Count: {} ",header.exportcount);
};
FileHeader header @ HEADER_LOCATION;
// Check Compression
if (header.compressionflags != 0 || header.compressedchunks > 0) {
isCompressed = true;
print_info(header);
return;
}
FNameEntry NameTable[header.namecount] @ header.nameoffset;
FObjectImport ImportTable[header.importcount] @ header.importoffset;
FObjectExport ExportTable[header.exportcount] @ header.exportoffset;
print_info(header);