-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPazFile.cpp
More file actions
76 lines (62 loc) · 2.23 KB
/
PazFile.cpp
File metadata and controls
76 lines (62 loc) · 2.23 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
#include "PazFile.h"
#include <cassert>
#include <memory>
namespace kukdh1 {
FileInfo::FileInfo(uint8_t *buffer) {
assert(buffer != nullptr);
memcpy(&uiCRC, buffer + 0, 4);
memcpy(&uiFolderID, buffer + 4, 4);
memcpy(&uiFileID, buffer + 8, 4);
memcpy(&uiOffset, buffer + 12, 4);
memcpy(&uiCompressedSize, buffer + 16, 4);
memcpy(&uiOriginalSize, buffer + 20, 4);
}
FileInfo::FileInfo() {
// DO NOTHING
}
PazFile::PazFile(wchar_t *wpszPazFolder, uint32_t uiPazIndex, CryptICE &cipher) {
assert(wpszPazFolder != nullptr);
std::wstring path(wpszPazFolder);
std::wstringstream wss(path, std::ios_base::out | std::ios_base::in | std::ios_base::ate);
wss << L"\\PAD" << std::setw(5) << std::setfill(L'0') << uiPazIndex << L".PAZ";
path = wss.str();
std::fstream file(path, std::ios::binary | std::ios::in);
if (!file.is_open()) {
throw std::runtime_error("Failed to open PAZ file");
}
uint8_t buffer[64];
uint32_t uiFileCount;
uint32_t uiPathLength;
// Read Header
file.read((char *)buffer, 12);
memcpy(&uiCRC, buffer + 0, 4);
memcpy(&uiFileCount, buffer + 4, 4);
memcpy(&uiPathLength, buffer + 8, 4);
// Read file info
std::vector<uint8_t> infos(uiFileCount * 24);
file.read(reinterpret_cast<char *>(infos.data()), infos.size());
for (uint32_t i = 0; i < uiFileCount; i++) {
vFileInfo.push_back(FileInfo(infos.data() + i * 24));
vFileInfo.back().wsPazFullPath = path;
}
// Read encrypted file names
std::vector<uint8_t> encrypted(uiPathLength);
file.read(reinterpret_cast<char *>(encrypted.data()), uiPathLength);
// Decrypt — output is malloc'd by cipher, wrap in unique_ptr
uint8_t *decrypted_raw = nullptr;
cipher.decrypt(encrypted.data(), uiPathLength, &decrypted_raw, &uiPathLength);
auto decrypted = std::unique_ptr<uint8_t, decltype(&free)>(decrypted_raw, free);
// Parse null-separated path strings
std::vector<std::string> paths;
const char *ptr = reinterpret_cast<const char *>(decrypted.get());
const char *end = ptr + uiPathLength;
for (; ptr < end; ) {
paths.push_back(ptr);
ptr += paths.back().length() + 1;
}
for (auto &info : vFileInfo) {
info.sFullPath = paths.at(info.uiFolderID);
info.sFullPath.append(paths.at(info.uiFileID));
}
}
}