Skip to content

Commit c4fa1e5

Browse files
committed
Integrate Path with GameTree and binary
1 parent d423c9b commit c4fa1e5

File tree

5 files changed

+103
-70
lines changed

5 files changed

+103
-70
lines changed

src/FileManager.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,10 @@ bool FileManager::extractZip(
265265
}
266266

267267
Path FileManager::getExtraPathToExe(Path path) {
268-
const QString s = path.get();
269-
qDebug() << "levelPath :" << s;
268+
qDebug() << "levelPath :" << path.get();
270269

271270
StaticTrees staticTrees;
272-
QDir dir(s);
273-
GameFileTree tree(dir);
271+
GameFileTree tree(path);
274272
tree.printTree(1);
275273

276274
QStringList extraPath;

src/GameFileTree.cpp

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -32,37 +32,27 @@
3232

3333
GameFileTree::GameFileTree(
3434
const QString &fileName, GameFileTree *parent)
35-
// cppcheck-suppress misra-c2012-12.3
3635
: m_fileName(fileName), m_parentItem(parent)
3736
{}
3837

39-
GameFileTree::~GameFileTree() {
40-
for (GameFileTree* child : m_childItems) {
41-
delete child;
42-
}
43-
}
44-
4538
GameFileTree::GameFileTree(const QStringList& pathList)
46-
// cppcheck-suppress misra-c2012-12.3
4739
: m_parentItem(nullptr) {
4840
addPathList(pathList);
4941
}
5042

51-
GameFileTree::GameFileTree(const QDir &dir)
52-
// cppcheck-suppress misra-c2012-12.3
43+
GameFileTree::GameFileTree(Path dirPath)
5344
: m_parentItem(nullptr) {
54-
if (dir.exists() == true) {
45+
if (dirPath.exists() == true && dirPath.isDir()) {
5546
QStringList pathList;
56-
// Skapa en kö för att hantera kataloger iterativt
5747
QQueue<QString> dirQueue;
58-
const QString base = dir.absolutePath();
48+
const QString base = dirPath.get(); // Inside home and absolute
49+
const QDir baseDir(base);
5950
dirQueue.enqueue(base);
6051

6152
while (!dirQueue.isEmpty()) {
6253
QString currentDirPath = dirQueue.dequeue();
6354
QDir currentDir(currentDirPath);
6455

65-
// Hämta alla filer och mappar i den aktuella katalogen
6656
QFileInfoList fileList = currentDir.entryInfoList(
6757
QDir::Files |
6858
QDir::Dirs |
@@ -71,9 +61,9 @@ GameFileTree::GameFileTree(const QDir &dir)
7161
QDir::Name);
7262

7363
for (const QFileInfo& fileInfo : fileList) {
74-
pathList << QString(fileInfo.absoluteFilePath().split(base)[1]);
64+
pathList << baseDir
65+
.relativeFilePath(fileInfo.absoluteFilePath());
7566

76-
// Om objektet är en katalog, lägg till den i kön
7767
if (fileInfo.isDir() == true) {
7868
dirQueue.enqueue(fileInfo.absoluteFilePath());
7969
}
@@ -82,7 +72,13 @@ GameFileTree::GameFileTree(const QDir &dir)
8272
addPathList(pathList);
8373
} else {
8474
QTextStream(stdout) << "Directory does not exist: "
85-
<< dir.absolutePath() << Qt::endl;
75+
<< dirPath.get() << Qt::endl;
76+
}
77+
}
78+
79+
GameFileTree::~GameFileTree() {
80+
for (GameFileTree* child : m_childItems) {
81+
delete child;
8682
}
8783
}
8884

@@ -96,7 +92,7 @@ void GameFileTree::addPathList(const QStringList& pathList) {
9692
// Check if a child node with this name already exists
9793
auto it = std::find_if(
9894
current->m_childItems.begin(), current->m_childItems.end(),
99-
[&component](GameFileTree* child) {
95+
[&component](const GameFileTree* child) {
10096
return child->m_fileName == component;
10197
});
10298

@@ -145,38 +141,57 @@ void GameFileTree::printTree(int level) const {
145141
}
146142

147143
bool GameFileTree::matchesSubtree(const GameFileTree* other) const {
148-
if (!other) return false;
144+
bool status = true;
145+
146+
if (other == nullptr) {
147+
status = false;
148+
}
149149

150-
if (m_fileName.toUpper() != other->m_fileName.toUpper())
151-
return false;
150+
// Check if first node name match
151+
if (status && (m_fileName.toUpper() != other->m_fileName.toUpper())) {
152+
status = false;
153+
}
152154

153-
for (const GameFileTree* childOther : other->m_childItems) {
154-
bool matched = false;
155-
for (const GameFileTree* childThis : m_childItems) {
156-
if (childThis->matchesSubtree(childOther)) {
157-
matched = true;
155+
/* Check other recursively from 'this'
156+
* It matches the branches like an Enarmad bandit machine
157+
* throught all child nodes at this point. This builds up the
158+
* matching "tower" on the stack by trying all Lego pieces
159+
* available at this node until ONE Lego is not found
160+
* it cancels the branch.
161+
*/
162+
if (status) {
163+
for (const GameFileTree* childOther : other->m_childItems) {
164+
bool matched = std::any_of(
165+
m_childItems.begin(), m_childItems.end(),
166+
[childOther](const GameFileTree* childThis) {
167+
return childThis->matchesSubtree(childOther);
168+
});
169+
170+
if (matched == false) {
171+
status = false;
158172
break;
159173
}
160174
}
161-
if (!matched)
162-
return false;
163175
}
164176

165-
return true;
177+
return status;
166178
}
167179

168180
QStringList GameFileTree::matchesFromAnyNode(const GameFileTree* other) {
169-
if (matchesSubtree(other)) {
170-
return QStringList{ m_fileName };
171-
}
181+
QStringList result;
172182

173-
for (GameFileTree* child : m_childItems) {
174-
QStringList childPath = child->matchesFromAnyNode(other);
175-
if (!childPath.isEmpty()) {
176-
childPath.prepend(m_fileName); // its a bit backwards
177-
return childPath;
183+
if (matchesSubtree(other)) {
184+
result.append(m_fileName);
185+
} else {
186+
for (GameFileTree* child : m_childItems) {
187+
QStringList childPath = child->matchesFromAnyNode(other);
188+
if (!childPath.isEmpty()) {
189+
childPath.prepend(m_fileName); // its a bit backwards later
190+
result = childPath;
191+
break;
192+
}
178193
}
179194
}
180195

181-
return {};
196+
return result;
182197
}

src/GameFileTree.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020
#include <QStringList>
2121
#include <QDebug>
2222
#include <QList>
23+
#include "../src/Path.hpp"
2324

2425
class GameFileTree {
2526
public:
26-
explicit GameFileTree(const QDir& fullPath);
27+
explicit GameFileTree(Path dirPath);
2728
explicit GameFileTree(const QStringList& pathList);
2829
~GameFileTree();
2930

@@ -35,7 +36,6 @@ class GameFileTree {
3536
explicit GameFileTree(
3637
const QString &fileName, GameFileTree *parentItem);
3738
void addPathList(const QStringList& pathList);
38-
void addNode(GameFileTree* node); // maybe dont need this
3939
QVector<GameFileTree*> m_childItems;
4040
QString m_fileName;
4141
GameFileTree *m_parentItem;

src/binary.cpp

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <memory>
2020
#include <string>
2121
#include <LIEF/LIEF.hpp>
22+
#include "../src/Path.hpp"
2223

2324
QString decideExe(const QDir& dir) {
2425
QString fileName;
@@ -65,9 +66,9 @@ void analyzeImportTable(const std::string& binaryPath) {
6566
}
6667
}
6768

68-
void readPEHeader(const QString &filePath) {
69-
QFile file(filePath);
70-
if (file.open(QIODevice::ReadOnly) == true) {
69+
void readPEHeader(Path filePath) {
70+
QFile file(filePath.get());
71+
if (file.open(QIODevice::ReadOnly) == true) { // flawfinder: ignore
7172
QDataStream in(&file);
7273
in.setByteOrder(QDataStream::LittleEndian);
7374

@@ -104,15 +105,15 @@ void readPEHeader(const QString &filePath) {
104105
}
105106
file.close();
106107
} else {
107-
qCritical() << "Failed to open file:" << filePath;
108+
qCritical() << "Failed to open file:" << filePath.get();
108109
}
109110
}
110111

111112

112-
void readExportTable(const QString &filePath) {
113-
QFile file(filePath);
114-
if (!file.open(QIODevice::ReadOnly)) {
115-
qCritical() << "Failed to open file:" << filePath;
113+
void readExportTable(Path filePath) {
114+
QFile file(filePath.get());
115+
if (!file.open(QIODevice::ReadOnly)) { // flawfinder: ignore
116+
qCritical() << "Failed to open file:" << filePath.get();
116117
return;
117118
}
118119

@@ -142,7 +143,8 @@ void readExportTable(const QString &filePath) {
142143
file.seek(dosHeader.e_lfanew + sizeof(PEHeader));
143144

144145
// Read Optional Header
145-
QByteArray optionalHeaderData(peHeader.sizeOfOptionalHeader, Qt::Uninitialized);
146+
QByteArray optionalHeaderData(
147+
peHeader.sizeOfOptionalHeader, Qt::Uninitialized);
146148
in.readRawData(optionalHeaderData.data(), peHeader.sizeOfOptionalHeader);
147149

148150
// Get Data Directory
@@ -152,16 +154,23 @@ void readExportTable(const QString &filePath) {
152154
};
153155

154156
constexpr int IMAGE_DIRECTORY_ENTRY_EXPORT = 0;
155-
auto dataDirectory = reinterpret_cast<DataDirectory*>(optionalHeaderData.data() + 96); // Offset 96: start of Data Directory
156-
quint32 exportTableRVA = dataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].virtualAddress;
157+
// Offset 96: start of Data Directory
158+
auto dataDirectory =
159+
reinterpret_cast<DataDirectory*>(optionalHeaderData.data() + 96);
160+
161+
quint32 exportTableRVA =
162+
dataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].virtualAddress;
157163

158164
if (exportTableRVA == 0) {
159165
qCritical() << "No Export Table found in this PE file.";
160166
return;
161167
}
162168

163169
// Find the section that contains the Export Table
164-
file.seek(dosHeader.e_lfanew + sizeof(PEHeader) + peHeader.sizeOfOptionalHeader);
170+
file.seek(dosHeader.e_lfanew +
171+
sizeof(PEHeader) +
172+
peHeader.sizeOfOptionalHeader);
173+
165174
quint16 numSections = peHeader.numSections;
166175

167176
struct SectionHeader {
@@ -181,13 +190,15 @@ void readExportTable(const QString &filePath) {
181190
quint32 exportTableFileOffset = 0;
182191

183192
for (quint16 i = 0; i < numSections; i++) {
184-
in.readRawData(reinterpret_cast<char*>(&section), sizeof(SectionHeader));
193+
in.readRawData(
194+
reinterpret_cast<char*>(&section), sizeof(SectionHeader));
185195
quint32 sectionStart = section.virtualAddress;
186196
quint32 sectionEnd = sectionStart + section.virtualSize;
187197

188198
if (exportTableRVA >= sectionStart && exportTableRVA < sectionEnd) {
189199
quint32 offsetWithinSection = exportTableRVA - sectionStart;
190-
exportTableFileOffset = section.pointerToRawData + offsetWithinSection;
200+
exportTableFileOffset =
201+
section.pointerToRawData + offsetWithinSection;
191202
break;
192203
}
193204
}
@@ -200,10 +211,13 @@ void readExportTable(const QString &filePath) {
200211
// Read Export Directory
201212
file.seek(exportTableFileOffset);
202213
ExportDirectory exportDirectory;
203-
in.readRawData(reinterpret_cast<char*>(&exportDirectory), sizeof(ExportDirectory));
214+
in.readRawData(
215+
reinterpret_cast<char*>(&exportDirectory), sizeof(ExportDirectory));
204216

205217
// Read the DLL Name
206-
file.seek(section.pointerToRawData + (exportDirectory.nameRVA - section.virtualAddress));
218+
file.seek(section.pointerToRawData +
219+
(exportDirectory.nameRVA - section.virtualAddress));
220+
207221
QByteArray dllName;
208222
char c;
209223
while (file.getChar(&c) && c != '\0') {
@@ -216,7 +230,9 @@ void readExportTable(const QString &filePath) {
216230
qDebug() << "Exported Functions:";
217231

218232
// Name Pointer Table
219-
quint32 namePointerOffset = section.pointerToRawData + (exportDirectory.namePointerRVA - section.virtualAddress);
233+
quint32 namePointerOffset = section.pointerToRawData +
234+
(exportDirectory.namePointerRVA - section.virtualAddress);
235+
220236
file.seek(namePointerOffset);
221237

222238
QVector<quint32> nameRVAs(exportDirectory.numNamePointers);
@@ -225,7 +241,9 @@ void readExportTable(const QString &filePath) {
225241
}
226242

227243
for (const quint32 &nameRVA : nameRVAs) {
228-
quint32 nameOffset = section.pointerToRawData + (nameRVA - section.virtualAddress);
244+
quint32 nameOffset = section.pointerToRawData +
245+
(nameRVA - section.virtualAddress);
246+
229247
file.seek(nameOffset);
230248

231249
QByteArray functionName;
@@ -291,14 +309,15 @@ qint64 findReplacePattern(QFile* const file) {
291309
* @retval 2 Could not preform the first read only opening of the file.
292310
* @return error qint64.
293311
*/
294-
qint64 widescreen_set(const QString& path) {
312+
qint64 widescreen_set(Path filePath) {
295313
qint64 status = 0;
296-
QFileInfo fileInfo(path);
297-
QFile file(path);
314+
QFile file(filePath.get());
298315

299316
// Open the file
300-
if (!fileInfo.exists() || !fileInfo.isFile()) {
301-
qCritical() << "Error: The exe path is not a regular file: " << path;
317+
if (!filePath.exists() || !filePath.isFile()) {
318+
qCritical()
319+
<< "Error: The exe path is not a regular file: "
320+
<< filePath.get();
302321
status = 1; // Invalid file path
303322
} else if (!file.open(QIODevice::ReadOnly)) { // flawfinder: ignore
304323
qCritical() << "Error opening file for reading!";

src/binary.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <QDebug>
2222
#include <QDataStream>
2323
#include <string>
24+
#include "../src/Path.hpp"
2425

2526
// Define structures for PE headers
2627
#pragma pack(push, 1) // Set 1-byte alignment
@@ -75,9 +76,9 @@ struct ExportDirectory {
7576

7677
QString decideExe(const QDir& dir);
7778
void analyzeImportTable(const std::string& peFilePath);
78-
void readPEHeader(const QString &filePath);
79-
void readExportTable(const QString &filePath);
79+
void readPEHeader(Path filePath);
80+
void readExportTable(Path filePath);
8081
qint64 findReplacePattern(QFile* const file);
81-
qint64 widescreen_set(const QString& path);
82+
qint64 widescreen_set(Path filePath);
8283

8384
#endif // SRC_BINARY_HPP_

0 commit comments

Comments
 (0)