189 lines
3.9 KiB
C++
Raw Normal View History

2019-03-17 18:42:07 +03:00
#include "pe.h"
#include <QFile>
2019-03-18 10:33:03 +03:00
#include <QFileInfo>
2019-03-17 20:16:48 +03:00
2019-03-20 18:05:14 +03:00
int PE::findIndexPE(QFile &file) {
if (!file.isOpen()) {
return -1;
}
2019-03-21 00:34:57 +03:00
int limit = 0x400;
int currentSeeck = INDEX_PE_MAGIC;
2019-03-20 18:05:14 +03:00
unsigned int PE = 0x0;
2019-03-21 00:34:57 +03:00
while (currentSeeck <= limit) {
if (!file.seek(currentSeeck)) {
2019-03-20 18:05:14 +03:00
return -1;
}
file.read(reinterpret_cast<char*>(&PE), sizeof (PE));
if (PE == PE_MAGIC) {
2019-03-21 00:34:57 +03:00
return currentSeeck;
2019-03-20 18:05:14 +03:00
}
2019-03-21 00:34:57 +03:00
currentSeeck++;
2019-03-20 18:05:14 +03:00
}
return -1;
}
2019-03-17 20:16:48 +03:00
bool PE::fillMetaInfo(LIB_META_INFO &info, const QString &file) {
2019-03-17 18:42:07 +03:00
QFile f(file);
2019-03-17 20:16:48 +03:00
#define SEEK(address) \
if (!f.seek(address)) { \
f.close(); \
return false; \
}
2019-03-17 18:42:07 +03:00
if (!f.open(QIODevice::ReadOnly)) {
return false;
}
2019-03-20 18:05:14 +03:00
int peAddress = findIndexPE(f);
2019-03-17 20:16:48 +03:00
2019-03-20 18:05:14 +03:00
if (peAddress < 0) {
2019-03-17 18:42:07 +03:00
return false;
}
2019-03-17 20:16:48 +03:00
unsigned short mashine = 0x0;
2019-03-21 00:34:57 +03:00
SEEK(static_cast<unsigned int>(peAddress) + sizeof (unsigned int));
2019-03-17 18:42:07 +03:00
2019-03-17 20:16:48 +03:00
f.read(reinterpret_cast<char*>(&mashine), sizeof (mashine));
info.mashine = mashine;
2019-03-20 18:05:14 +03:00
SEEK(static_cast<unsigned int>(peAddress) + INDEX_MAGIC);
2019-03-17 20:16:48 +03:00
unsigned short magic = 0x0;
f.read(reinterpret_cast<char*>(&magic), sizeof (magic));
info.type = magic;
unsigned int importTableIndex = 0;
2019-03-21 00:34:57 +03:00
unsigned int rvaIndex = 0;
2019-03-17 20:16:48 +03:00
if (static_cast<RunType>(info.type) == RunType::_32bit) {
2019-03-20 18:05:14 +03:00
importTableIndex = static_cast<unsigned int>(peAddress) + INDEX_IMPORTS_32;
2019-03-21 00:34:57 +03:00
rvaIndex = static_cast<unsigned int>(peAddress) + NUMBER_RVA_AND_SIZES_32;
2019-03-17 20:16:48 +03:00
} else if (static_cast<RunType>(info.type) == RunType::_64bit) {
2019-03-20 18:05:14 +03:00
importTableIndex = static_cast<unsigned int>(peAddress) + INDEX_IMPORTS_64;
2019-03-21 00:34:57 +03:00
rvaIndex = static_cast<unsigned int>(peAddress) + NUMBER_RVA_AND_SIZES_64;
2019-03-17 20:16:48 +03:00
} else {
2019-03-17 18:42:07 +03:00
f.close();
return false;
}
2019-03-17 20:16:48 +03:00
2019-03-21 00:34:57 +03:00
SEEK(rvaIndex);
2019-03-17 20:16:48 +03:00
2019-03-21 00:34:57 +03:00
unsigned int NumberOfRvaAndSizes = 0;
f.read(reinterpret_cast<char*>(&NumberOfRvaAndSizes), sizeof (NumberOfRvaAndSizes));
SEEK(importTableIndex);
2019-03-17 20:16:48 +03:00
2019-03-21 00:34:57 +03:00
IMAGE_DATA_DIRECTORY import = {};
2019-03-17 20:16:48 +03:00
2019-03-21 00:34:57 +03:00
f.read(reinterpret_cast<char*>(&import), sizeof (import));
2019-03-17 20:16:48 +03:00
2019-03-21 00:34:57 +03:00
info.addressImports = import.VirtualAddress;
info.sizeImportTable = import.Size;
2019-03-17 20:16:48 +03:00
2019-03-17 18:42:07 +03:00
f.close();
return true;
}
2019-03-18 10:33:03 +03:00
bool PE::is32bit(const QString &file, const LIB_META_INFO * info) {
2019-03-17 20:16:48 +03:00
2019-03-18 10:33:03 +03:00
if (!info) {
LIB_META_INFO meta;
2019-03-17 20:16:48 +03:00
2019-03-18 10:33:03 +03:00
if (!fillMetaInfo(meta, file)) {
return false;
}
return static_cast<RunType>(meta.type) == RunType::_32bit;
2019-03-17 20:16:48 +03:00
}
2019-03-17 18:42:07 +03:00
2019-03-18 10:33:03 +03:00
return static_cast<RunType>(info->type) == RunType::_32bit;
2019-03-17 20:16:48 +03:00
}
2019-03-18 10:33:03 +03:00
bool PE::dependecies(QStringList &list, const QString &file,
const LIB_META_INFO * info) {
2019-03-17 20:16:48 +03:00
LIB_META_INFO meta;
2019-03-18 10:33:03 +03:00
if (!info) {
if (!fillMetaInfo(meta, file)) {
return false;
}
} else {
meta = std::move(*info);
2019-03-17 20:16:48 +03:00
}
QFile f(file);
if (!f.open(QIODevice::ReadOnly)) {
return false;
}
if (!f.seek(meta.addressImports)) {
f.close();
return false;
}
2019-03-18 10:33:03 +03:00
auto data = f.read(meta.sizeImportTable).split(char(0x0));
2019-03-17 20:16:48 +03:00
f.close();
if (data.isEmpty()) {
return false;
}
2019-03-18 10:33:03 +03:00
for (QString i : data) {
if (i.contains(".dll")) {
list.push_back(i);
}
}
2019-03-17 20:16:48 +03:00
return true;
2019-03-17 18:42:07 +03:00
}
2019-03-18 16:00:39 +03:00
PE::PE(): IGetLibInfo () {
2019-03-18 10:33:03 +03:00
}
2019-03-19 21:50:05 +03:00
bool PE::getLibInfo(const QString &lib, LibInfo &info) {
2019-03-18 10:33:03 +03:00
LIB_META_INFO meta;
if (!fillMetaInfo(meta, lib)) {
2019-03-19 21:50:05 +03:00
return false;
2019-03-18 10:33:03 +03:00
}
info.name = QFileInfo(lib).fileName();
2019-03-19 22:51:24 +03:00
info.path = QFileInfo(lib).absolutePath();
2019-03-18 10:33:03 +03:00
if (static_cast<RunType>(meta.type) == RunType::_32bit) {
info.platform = Platform::Win32;
} else if (static_cast<RunType>(meta.type) == RunType::_64bit) {
info.platform = Platform::Win64;
} else {
info.platform = Platform::UnknownPlatform;
}
dependecies(info.dependncies, lib, &meta);
2019-03-17 18:42:07 +03:00
2019-03-19 21:50:05 +03:00
return info.isValid();
2019-03-17 18:42:07 +03:00
}
2019-03-18 17:12:40 +03:00
PE::~PE(){
}