2019-09-23 16:46:57 +03:00
|
|
|
/*
|
2021-01-05 13:17:11 +03:00
|
|
|
* Copyright (C) 2018-2021 QuasarApp.
|
2019-09-23 16:46:57 +03:00
|
|
|
* Distributed under the lgplv3 software license, see the accompanying
|
|
|
|
* Everyone is permitted to copy and distribute verbatim copies
|
|
|
|
* of this license document, but changing it is not allowed.
|
|
|
|
*/
|
|
|
|
|
2020-09-09 14:15:54 +03:00
|
|
|
#include "pe_type.h"
|
2019-03-17 18:42:07 +03:00
|
|
|
|
|
|
|
#include <QFile>
|
2019-03-18 10:33:03 +03:00
|
|
|
#include <QFileInfo>
|
2019-03-23 20:40:33 +03:00
|
|
|
#include <QSet>
|
2019-03-22 23:36:22 +03:00
|
|
|
#include <QVector>
|
2019-12-24 11:46:11 +03:00
|
|
|
#include <quasarapp.h>
|
2019-03-17 20:16:48 +03:00
|
|
|
|
2021-01-05 21:24:36 +08:00
|
|
|
#include <set>
|
2019-03-22 23:36:22 +03:00
|
|
|
|
2021-12-09 10:39:19 +03:00
|
|
|
#ifndef DISABLE_PE
|
|
|
|
#include <pe-parse/parse.h>
|
|
|
|
|
2019-03-23 20:40:33 +03:00
|
|
|
namespace peparse {
|
2019-03-21 00:34:57 +03:00
|
|
|
|
2019-03-23 20:40:33 +03:00
|
|
|
class section;
|
2019-03-21 00:34:57 +03:00
|
|
|
|
2021-12-09 10:39:19 +03:00
|
|
|
|
2019-03-23 20:40:33 +03:00
|
|
|
struct importent {
|
|
|
|
VA addr;
|
|
|
|
std::string symbolName;
|
|
|
|
std::string moduleName;
|
|
|
|
};
|
2019-03-21 13:22:18 +03:00
|
|
|
|
2019-12-23 16:17:25 +03:00
|
|
|
struct exportent {
|
|
|
|
VA addr;
|
|
|
|
std::string symbolName;
|
|
|
|
std::string moduleName;
|
|
|
|
};
|
|
|
|
|
2019-03-23 20:40:33 +03:00
|
|
|
class reloc;
|
|
|
|
class symbol;
|
2019-03-17 20:16:48 +03:00
|
|
|
|
2019-03-23 20:40:33 +03:00
|
|
|
struct parsed_pe_internal {
|
|
|
|
std::vector<section> secs;
|
|
|
|
std::vector<resource> rsrcs;
|
|
|
|
std::vector<importent> imports;
|
|
|
|
std::vector<reloc> relocs;
|
|
|
|
std::vector<exportent> exports;
|
|
|
|
std::vector<symbol> symbols;
|
|
|
|
};
|
2019-03-17 20:16:48 +03:00
|
|
|
|
2019-03-17 18:42:07 +03:00
|
|
|
}
|
|
|
|
|
2019-08-31 22:22:26 +03:00
|
|
|
bool PE::getDep(peparse::parsed_pe_internal * internal, LibInfo &res) const {
|
2019-03-23 20:40:33 +03:00
|
|
|
auto imports = internal->imports;
|
|
|
|
std::set<std::string> filter;
|
2019-03-17 20:16:48 +03:00
|
|
|
|
2019-03-23 20:40:33 +03:00
|
|
|
for ( auto &i : imports) {
|
|
|
|
if (!filter.count(i.moduleName)) {
|
|
|
|
filter.insert(i.moduleName);
|
2019-04-05 14:23:42 +03:00
|
|
|
res.addDependncies(QString::fromStdString(i.moduleName));
|
2019-03-18 10:33:03 +03:00
|
|
|
}
|
|
|
|
}
|
2019-03-17 20:16:48 +03:00
|
|
|
|
2019-12-24 13:48:37 +03:00
|
|
|
if (res.getWinApi() != WinAPI::NoWinAPI) {
|
|
|
|
res.addDependncies(_winAPI.value(res.getWinApi()));
|
|
|
|
}
|
|
|
|
|
2019-12-19 19:15:38 +03:00
|
|
|
return res.getDependncies().size() || !imports.size();
|
2019-03-17 18:42:07 +03:00
|
|
|
}
|
2021-12-09 10:39:19 +03:00
|
|
|
#endif
|
2019-03-17 18:42:07 +03:00
|
|
|
|
2019-12-24 13:48:37 +03:00
|
|
|
QHash<WinAPI, QSet<QString> > PE::getWinAPI() const {
|
|
|
|
return _winAPI;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PE::setWinAPI(const QHash<WinAPI, QSet<QString> > &winAPI) {
|
|
|
|
_winAPI = winAPI;
|
|
|
|
}
|
|
|
|
|
2019-12-24 11:46:11 +03:00
|
|
|
WinAPI PE::getAPIModule(const QString &libName) const {
|
|
|
|
if (libName.contains(API_MS_WIN, Qt::CaseInsensitive)) {
|
|
|
|
if (libName.contains(API_MS_WIN_CORE, Qt::CaseInsensitive)) {
|
|
|
|
return WinAPI::Core;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (libName.contains(API_MS_WIN_EVENTING, Qt::CaseInsensitive)) {
|
|
|
|
return WinAPI::Eventing;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (libName.contains(API_MS_WIN_DEVICES, Qt::CaseInsensitive)) {
|
|
|
|
return WinAPI::Devices;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (libName.contains(API_MS_WIN_CRT, Qt::CaseInsensitive)) {
|
|
|
|
return WinAPI::Crt;
|
|
|
|
}
|
2019-03-18 10:33:03 +03:00
|
|
|
|
2019-12-24 11:46:11 +03:00
|
|
|
if (libName.contains(API_MS_WIN_SECURITY, Qt::CaseInsensitive)) {
|
|
|
|
return WinAPI::Security;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (libName.contains(API_MS_WIN_BASE, Qt::CaseInsensitive)) {
|
|
|
|
return WinAPI::Base;
|
|
|
|
}
|
|
|
|
|
|
|
|
return WinAPI::Other;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return WinAPI::NoWinAPI;
|
2019-03-18 10:33:03 +03:00
|
|
|
}
|
|
|
|
|
2019-03-18 16:00:39 +03:00
|
|
|
PE::PE(): IGetLibInfo () {
|
2019-03-18 10:33:03 +03:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-08-31 22:22:26 +03:00
|
|
|
bool PE::getLibInfo(const QString &lib, LibInfo &info) const {
|
2021-12-09 10:39:19 +03:00
|
|
|
#ifndef DISABLE_PE
|
2019-03-23 20:40:33 +03:00
|
|
|
auto parsedPeLib = peparse::ParsePEFromFile(lib.toLatin1());
|
2019-03-18 10:33:03 +03:00
|
|
|
|
2019-09-14 13:59:11 +03:00
|
|
|
if (!parsedPeLib)
|
|
|
|
return false;
|
|
|
|
|
2020-10-21 21:24:47 +03:00
|
|
|
if (parsedPeLib->peHeader.nt.FileHeader.Machine == peparse::IMAGE_FILE_MACHINE_ARM ||
|
|
|
|
parsedPeLib->peHeader.nt.FileHeader.Machine == peparse::IMAGE_FILE_MACHINE_ARM64 ||
|
|
|
|
parsedPeLib->peHeader.nt.FileHeader.Machine == peparse::IMAGE_FILE_MACHINE_ARMNT) {
|
|
|
|
|
|
|
|
if (parsedPeLib->peHeader.nt.OptionalMagic == peparse::NT_OPTIONAL_32_MAGIC) {
|
|
|
|
info.setPlatform(Win_ARM_32);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
info.setPlatform(win_ARM_64);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (parsedPeLib->peHeader.nt.FileHeader.Machine == peparse::IMAGE_FILE_MACHINE_I386 ||
|
|
|
|
parsedPeLib->peHeader.nt.FileHeader.Machine == peparse::IMAGE_FILE_MACHINE_AMD64) {
|
|
|
|
|
|
|
|
if (parsedPeLib->peHeader.nt.OptionalMagic == peparse::NT_OPTIONAL_32_MAGIC) {
|
|
|
|
info.setPlatform(Win32);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
info.setPlatform(Win64);
|
|
|
|
}
|
|
|
|
|
2019-03-23 20:40:33 +03:00
|
|
|
} else {
|
2020-10-21 21:24:47 +03:00
|
|
|
info.setPlatform(UnknownPlatform);
|
|
|
|
return false;
|
2019-03-18 10:33:03 +03:00
|
|
|
}
|
2021-04-21 13:08:18 +03:00
|
|
|
QFileInfo infolib(lib);
|
|
|
|
info.setName(infolib.fileName());
|
|
|
|
info.setPath(infolib.absolutePath());
|
|
|
|
|
2019-12-24 13:48:37 +03:00
|
|
|
info.setWinApi(getAPIModule(info.getName()));
|
2019-03-18 10:33:03 +03:00
|
|
|
|
2019-04-05 14:23:42 +03:00
|
|
|
if (!getDep(parsedPeLib->internal, info)) {
|
2019-12-19 19:15:38 +03:00
|
|
|
peparse::DestructParsedPE(parsedPeLib);
|
2019-03-23 20:40:33 +03:00
|
|
|
return false;
|
2019-03-18 10:33:03 +03:00
|
|
|
}
|
|
|
|
|
2019-03-23 20:40:33 +03:00
|
|
|
peparse::DestructParsedPE(parsedPeLib);
|
2019-03-17 18:42:07 +03:00
|
|
|
|
2019-12-24 11:46:11 +03:00
|
|
|
|
2019-03-19 21:50:05 +03:00
|
|
|
return info.isValid();
|
2021-12-09 10:39:19 +03:00
|
|
|
#else
|
|
|
|
Q_UNUSED(lib)
|
|
|
|
Q_UNUSED(info)
|
|
|
|
return false;
|
|
|
|
#endif
|
2019-03-17 18:42:07 +03:00
|
|
|
}
|
2019-03-18 17:12:40 +03:00
|
|
|
|
|
|
|
PE::~PE(){
|
|
|
|
|
|
|
|
}
|