WingElfParser/wingelfparser.cpp

1053 lines
35 KiB
C++

#include "wingelfparser.h"
#include "settingdialog.h"
#include "settings.h"
#include <QApplication>
#include <QMessageBox>
#include <QTreeWidgetItem>
#include <elf.h>
#define ICONRES(name) QIcon(":/WingElfParser/image/" name ".png")
#define HOSTICONRES(name) QIcon(HOSTRESPIMG(name))
#define QTWI(parent, title, offset, len) \
p = new QTreeWidgetItem(parent, {title}); \
p->setData(0, Qt::UserRole, QVariant::fromValue(Analysis{offset, len}));
#define TOINT64(BYTES) (*reinterpret_cast<qint64 *>(BYTES.data()))
#define TOUINT(BYTES) (*reinterpret_cast<uint *>(BYTES.data()))
#define TOUSHORT(BYTES) (*reinterpret_cast<ushort *>(BYTES.data()))
#define TOINT(BYTES) (*reinterpret_cast<int *>(BYTES.data()))
#define TOCHARINT(BYTES) (int(BYTES[0]))
WingElfPlugin::WingElfPlugin(QObject *parent) { Q_UNUSED(parent); }
WingElfPlugin::~WingElfPlugin() {}
#if QT_VERSION < 0x050000
Q_EXPORT_PLUGIN2(WingElfParser, GenericPlugin)
#endif // QT_VERSION < 0x050000
int WingElfPlugin::sdkVersion() { return SDKVERSION; }
const QString WingElfPlugin::signature() { return WINGSUMMER; }
const QString WingElfPlugin::pluginName() { return tr("WingElfParser"); }
const QString WingElfPlugin::pluginAuthor() { return WINGSUMMER; }
const QString WingElfPlugin::pluginComment() {
return tr("A Marker plugin for Elf");
}
bool WingElfPlugin::init(QList<WingPluginInfo> loadedplugin) {
Q_UNUSED(loadedplugin);
if (SDKVERSION < 8) {
QMessageBox::critical(nullptr, "Error",
"UnSupported Plugin System Version!",
QMessageBox::Ok);
return false;
}
auto s = GETPLUGINQM("WingElfParser.qm");
if (!translator.load(s) || !QApplication::installTranslator(&translator)) {
QMessageBox::critical(nullptr, "Error", "Error Loading Translation File!",
QMessageBox::Ok);
return false;
}
auto icon = ICONRES("icon");
PluginMenuInitBegin(menu, tr("WingElfParser")) {
menu->setIcon(icon);
PluginMenuAddItemCheckLamba(
menu, tr("AddMetaData"), Settings::instance()->addMetadata(), [=] {
auto settings = Settings::instance();
settings->setAddMetadata(!settings->addMetadata());
});
PluginMenuAddItemIconAction(menu, tr("Analyse"), ICONRES("analyse"),
WingElfPlugin::analyse);
menu->addSeparator();
PluginMenuAddItemIconAction(menu, tr("Setting"), HOSTICONRES("setting"),
WingElfPlugin::on_setting);
PluginMenuAddItemIconLamba(menu, tr("Author"), HOSTICONRES("author"), [=] {
auto authord = newAboutDialog(
QPixmap(), {":/WingElfParser", ":/WingElfParser/image"});
authord->exec();
delete authord;
});
PluginMenuAddItemIconLamba(menu, tr("Sponsor"), HOSTICONRES("sponsor"),
[=] {
auto sponsor = newSponsorDialog();
sponsor->exec();
delete sponsor;
});
}
PluginMenuInitEnd();
tw = new QTreeWidget;
tw->setEditTriggers(QTreeWidget::NoEditTriggers);
tw->setHeaderLabels({QString(10, ' '), tr("Value")});
tw->setColumnCount(2);
QMenu *tmenu;
PluginMenuInitBegin(tmenu, "") {
PluginMenuAddItemIconAction(tmenu, tr("Analyse"), ICONRES("analyse"),
WingElfPlugin::analyse);
PluginMenuAddItemIconAction(tmenu, tr("Setting"), HOSTICONRES("setting"),
WingElfPlugin::on_setting);
}
PluginMenuInitEnd();
PluginToolButtonInit(tbtn, tmenu, icon);
connect(tw, &QTreeWidget::itemSelectionChanged, this, [=] {
if (reader.currentDocFilename() != filename)
return;
auto s = tw->selectedItems();
if (s.count()) {
auto item = s.first();
auto id = item->data(0, Qt::UserRole).value<Analysis>();
USINGCONTROL({
controller.enabledCursor(true);
controller.select(id.offset, int(id.length));
});
}
});
PluginDockWidgetInit(dw, tw, tr("WingElfParser"), "wingelf");
return true;
}
void WingElfPlugin::plugin2MessagePipe(WingPluginMessage type,
QList<QVariant> msg) {
Q_UNUSED(type);
Q_UNUSED(msg);
}
void WingElfPlugin::on_setting() {
SettingDialog s(this);
s.show();
}
void WingElfPlugin::analyse() {
if (reader.currentDoc() < 0) {
toast(ICONRES("icon"), tr("NoFile"));
} else {
if (this->parse()) {
toast(ICONRES("icon"), tr("Success"));
} else {
QMessageBox::critical(nullptr, tr("WingElfParser"), tr("Error"));
}
}
}
bool WingElfPlugin::parse() {
auto totalbytes = reader.documentBytes();
if (totalbytes <= sizeof(Elf32_Ehdr))
return false;
auto id = reader.read(0, EI_NIDENT);
if (!id.startsWith(ELFMAG))
return false;
auto clsbit = int(reader.read(EI_CLASS, 1)[0]);
tw->clear();
filename = reader.currentDocFilename();
tw->setHeaderLabel(filename);
switch (clsbit) {
case ELFCLASS32:
return parse32();
break;
case ELFCLASS64:
return parse64();
break;
}
return false;
}
bool WingElfPlugin::parse32() {
auto totalb = reader.documentBytes();
auto settings = Settings::instance();
auto addmeta = settings->addMetadata();
if (requestControl()) {
QTreeWidgetItem *p;
if (addmeta)
controller.setMetaVisible(false);
QTWI(tw, "struct elf_header", 0, sizeof(Elf32_Ehdr));
if (addmeta)
controller.metadata(0, sizeof(Elf32_Ehdr),
settings->getColor(SettingColor::elf_header_color),
Qt::transparent, QString());
auto h = p;
QTWI(p, "struct e_ident_t e_ident", 0, EI_NIDENT);
auto hh = p;
QTWI(hh, "char file_identification[4]", 0, 4);
p->setText(1, reader.read(0, 4));
auto off = 4;
auto str = reader.read(off, 1);
QTWI(hh, "enum ei_class_2_e ei_class_2", off++, 1);
auto m = QMetaEnum::fromType<ELFHelper::ei_class_2_e>();
p->setText(1, m.valueToKey(str[0]));
str = reader.read(off, 1);
QTWI(hh, "enum ei_data_e ei_data", off++, 1);
m = QMetaEnum::fromType<ELFHelper::ei_data_e>();
p->setText(1, m.valueToKey(str[0]));
str = reader.read(off, 1);
QTWI(hh, "enum ei_version_e ei_version", off++, 1);
m = QMetaEnum::fromType<ELFHelper::ei_version_e>();
p->setText(1, m.valueToKey(str[0]));
str = reader.read(off, 1);
QTWI(hh, "enum ei_osabi_e ei_osabi", off++, 1);
m = QMetaEnum::fromType<ELFHelper::ei_osabi_e>();
p->setText(1, m.valueToKey(str[0]));
str = reader.read(off, 1);
QTWI(hh, "uchar ei_abiversion", off++, 1);
p->setText(1, QString("%1").arg(TOCHARINT(str)));
str = reader.read(off, 6).toHex(' ');
QTWI(hh, "uchar ei_pad[6]", off, 6);
p->setText(1, str);
off += 6;
str = reader.read(off, 1);
QTWI(hh, "uchar ei_nident_SIZE", off++, 1);
p->setText(1, QString("%1").arg(TOCHARINT(str)));
str = reader.read(off, 2);
QTWI(h, "enum e_type32_e e_type", off, 2);
m = QMetaEnum::fromType<ELFHelper::e_type_e>();
p->setText(1, m.valueToKey(TOUSHORT(str)));
off += 2;
str = reader.read(off, 2);
QTWI(h, "enum e_machine32_e e_machine", off, 2);
m = QMetaEnum::fromType<ELFHelper::e_machine_e>();
p->setText(1, m.valueToKey(TOUSHORT(str)));
off += 2;
str = reader.read(off, 4);
QTWI(h, "enum e_version64_e e_version", off, 4);
m = QMetaEnum::fromType<ELFHelper::e_version_e>();
p->setText(1, m.valueToKey(TOINT(str)));
off += 4;
QTWI(h, "Elf32_Addr e_entry_START_ADDRESS", off, 4);
p->setText(1, QString("0x%1").arg(TOUINT(reader.read(off, 4)), 0, 16));
off += 4;
auto e_phoff = TOUINT(reader.read(off, 4));
QTWI(h, "Elf32_Off e_phoff_PROGRAM_HEADER_OFFSET_IN_FILE", off, 4);
p->setText(1, QString("%1").arg(e_phoff));
off += 4;
auto e_shoff = TOUINT(reader.read(off, 4));
QTWI(h, "Elf32_Off e_shoff_SECTION_HEADER_OFFSET_IN_FILE", off, 4);
p->setText(1, QString("%1").arg(e_shoff));
off += 4;
QTWI(h, "Elf32_Word e_flags", off, 4);
p->setText(1, QString("0x%1").arg(TOUINT(reader.read(off, 4)), 0, 16));
off += 4;
QTWI(h, "Elf32_Half e_ehsize_ELF_HEADER_SIZE", off, 2);
p->setText(1, QString("%1").arg(TOUINT(reader.read(off, 4))));
off += 2;
auto e_phentsize = TOUSHORT(reader.read(off, 2));
QTWI(h, "Elf32_Half e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE", off, 2);
p->setText(1, QString("%1").arg(TOUSHORT(reader.read(off, 2))));
off += 2;
auto e_phnum = TOUSHORT(reader.read(off, 2));
QTWI(h, "Elf32_Half e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES", off, 2);
p->setText(1, QString("%1").arg(TOUSHORT(reader.read(off, 2))));
off += 2;
auto e_shentsize = TOUSHORT(reader.read(off, 2));
QTWI(h, "Elf32_Half e_shentsize_SECTION_HEADER_ENTRY_SIZE", off, 2);
p->setText(1, QString("%1").arg(TOUSHORT(reader.read(off, 2))));
off += 2;
auto e_shnum = TOUSHORT(reader.read(off, 2));
QTWI(h, "Elf32_Half e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES", off, 2);
p->setText(1, QString("%1").arg(TOUSHORT(reader.read(off, 2))));
off += 2;
auto e_shtrndx = TOUSHORT(reader.read(off, 2));
QTWI(h, "Elf64_Half e_shtrndx_STRING_TABLE_INDEX", off, 2);
p->setText(1, QString("%1").arg(e_shtrndx));
off += 2;
if (e_phoff > totalb || e_phoff + e_phnum * e_phentsize > totalb)
goto err;
if (e_phoff && e_phnum) {
QTWI(tw, "struct program_header_table", e_phoff, e_phentsize * e_phnum);
auto pr = p;
auto o = e_phoff;
auto color = settings->getColor(SettingColor::program_table_color);
auto dcolor = color.darker();
auto b = false;
for (int i = 0; i < e_phnum; i++, o += e_phentsize) {
QTWI(pr,
QString("struct program_table_entry32_t program_table_element[%1]")
.arg(i),
o, e_phentsize);
if (addmeta)
controller.metadata(o, o + e_phentsize, b ? color : dcolor,
Qt::transparent, QString());
auto ph = p;
auto oo = o;
QTWI(ph, "enum p_type32_e p_type", oo, 4);
m = QMetaEnum::fromType<ELFHelper::p_type_e>();
auto type = m.valueToKey(TOINT(reader.read(oo, 4)));
auto t = type ? type : "Unknown";
b = !b;
p->setText(1, t);
oo += 4;
QTWI(ph, "Elf32_Off p_offset_FROM_FILE_BEGIN", oo, 4);
p->setText(1, QString("0x%1").arg(TOUINT(reader.read(off, 4)), 0, 16));
oo += 4;
QTWI(ph, "Elf32_Addr p_vaddr_VIRTUAL_ADDRESS", oo, 4);
p->setText(1, QString("0x%1").arg(TOUINT(reader.read(off, 4)), 0, 16));
oo += 4;
QTWI(ph, "Elf32_Addr p_paddr_PHYSICAL_ADDRESS", oo, 4);
p->setText(1, QString("0x%1").arg(TOUINT(reader.read(off, 4)), 0, 16));
oo += 4;
QTWI(ph, "Elf32_Word p_filesz_SEGMENT_FILE_LENGTH", oo, 4);
p->setText(1, QString("%1").arg(TOINT(reader.read(off, 4))));
oo += 4;
QTWI(ph, "Elf32_Word p_memsz_SEGMENT_RAM_LENGTH", oo, 4);
p->setText(1, QString("%1").arg(TOINT(reader.read(off, 4))));
oo += 4;
QTWI(ph, "enum p_flags32_e p_flags", oo, 4);
m = QMetaEnum::fromType<ELFHelper::p_flags_e>();
auto rwx = TOINT(reader.read(oo, 4));
p->setText(1, m.valueToKey(rwx));
QString _rwx;
switch (rwx) {
case ELFHelper::p_flags_e::PF_None:
_rwx = "___";
break;
case ELFHelper::p_flags_e::PF_Exec:
_rwx = "__X";
break;
case ELFHelper::p_flags_e::PF_Write:
_rwx = "_W_";
break;
case ELFHelper::p_flags_e::PF_Write_Exec:
_rwx = "_WX";
break;
case ELFHelper::p_flags_e::PF_Read:
_rwx = "R__";
break;
case ELFHelper::p_flags_e::PF_Read_Exec:
_rwx = "R_X";
break;
case ELFHelper::p_flags_e::PF_Read_Write:
_rwx = "RW_";
break;
case ELFHelper::p_flags_e::PF_Read_Write_Exec:
_rwx = "RWX";
break;
}
oo += 4;
QTWI(ph, "Elf32_Word p_align", oo, 4);
p->setText(1, QString("%1").arg(TOINT(reader.read(oo, 4))));
oo += 4;
ph->setText(1, QString("(%1) %2").arg(_rwx).arg(t));
}
}
if (e_shoff > totalb || e_shoff + e_shnum * e_shentsize > totalb)
goto err;
qint64 symoff = 0, dysymoff = 0;
int symlink = 0, dysymlink = 0;
int symsize = 0, dysymsize = 0;
QList<qint64> soffs;
if (e_shoff && e_shnum) {
QTWI(tw, "struct section_header_table", e_shoff, e_shentsize * e_shnum);
auto sr = p;
auto o = e_shoff;
auto nameoff =
TOUINT(reader.read(e_shoff + (e_shentsize * e_shtrndx) + 16, 4));
auto color = settings->getColor(SettingColor::section_header_color);
auto dcolor = color.darker();
auto b = false;
for (int i = 0; i < e_shnum; i++, o += e_shentsize) {
QTWI(sr,
QString("struct section_table_entry32_t section_table_element[%1]")
.arg(i),
o, e_shentsize);
auto sh = p;
auto oo = o;
if (addmeta)
controller.metadata(o, o + e_shentsize, b ? color : dcolor,
Qt::transparent, QString());
QTWI(sh, "s_name32_t s_name", oo, 4);
auto off = TOUINT(reader.read(oo, 4));
QString l;
if (off) {
auto of = nameoff + off;
auto pos = reader.searchForward(of, QByteArray(1, '\0'));
l = reader.read(of, int(pos - of));
} else {
l = "<Undefined>";
}
p->setText(1, l);
sh->setText(1, l);
oo += 4;
str = reader.read(oo, 4);
QTWI(sh, "enum s_type32_e s_type", oo, 4);
m = QMetaEnum::fromType<ELFHelper::s_type_e>();
p->setText(1, m.valueToKey(TOINT(str)));
oo += 4;
str = reader.read(oo, 4);
QTWI(sh, "enum s_flags32_e s_flags", oo, 4);
m = QMetaEnum::fromType<ELFHelper::s_flags32_e>();
p->setText(1, m.valueToKey(TOINT(str)));
oo += 4;
QTWI(sh, "Elf32_Addr s_addr", oo, 4);
p->setText(1, QString("0x%1").arg(TOUINT(reader.read(oo, 4)), 0, 16));
oo += 4;
QTWI(sh, "Elf32_Off s_offset", oo, 4);
off = TOUINT(reader.read(oo, 4));
soffs.push_back(off);
p->setText(1, QString("0x%1").arg(off, 0, 16));
oo += 4;
QTWI(sh, "Elf32_Xword s_size", oo, 4);
auto off0 = TOINT(reader.read(oo, 4));
p->setText(1, QString("%1").arg(off0));
oo += 4;
QTWI(sh, "Elf32_Word s_link", oo, 4);
auto off1 = TOINT(reader.read(oo, 4));
p->setText(1, QString("0x%1").arg(off1, 0, 16));
if (!l.compare(".symtab")) {
symoff = off;
symsize = off0;
symlink = off1;
} else if (!l.compare(".dynsym")) {
dysymoff = off;
dysymsize = off0;
dysymlink = off1;
}
oo += 4;
QTWI(sh, "Elf32_Word s_info", oo, 4);
p->setText(1, QString("0x%1").arg(TOUINT(reader.read(oo, 4)), 0, 16));
oo += 4;
QTWI(sh, "Elf32_Xword s_addralign", oo, 4);
p->setText(1, QString("%1").arg(TOINT(reader.read(oo, 4))));
oo += 4;
QTWI(sh, "Elf32_Xword s_entsize", oo, 4);
p->setText(1, QString("%1").arg(TOINT(reader.read(oo, 4))));
oo += 4;
}
}
if (symoff && symsize) {
QTWI(tw, "struct symbol_table", symoff, symsize);
auto nameoff = soffs[symlink];
auto length = ulong(symsize) / sizeof(Elf32_Sym);
auto sr = p;
auto o = symoff;
auto color = settings->getColor(SettingColor::symbol_color);
auto dcolor = color.darker();
auto b = false;
for (ulong i = 0; i < length; i++, o += sizeof(Elf32_Sym)) {
QTWI(sr, QString("struct Elf32_Sym symtab[%1]").arg(i), o,
sizeof(Elf32_Sym));
auto sh = p;
auto oo = o;
if (addmeta)
controller.metadata(o, o + qint64(sizeof(Elf32_Sym)),
b ? color : dcolor, Qt::transparent, QString());
QTWI(sh, "sym_name32_t sym_name", oo, 4);
auto off = TOUINT(reader.read(oo, 4));
QString l;
if (off) {
auto of = nameoff + off;
auto pos = reader.searchForward(of, QByteArray(1, '\0'));
l = reader.read(of, int(pos - of));
} else {
l = "<Undefined>";
}
p->setText(1, l);
sh->setText(1, l);
oo += 4;
QTWI(sh, "Elf32_Addr sym_value", oo, 4);
p->setText(1, QString("0x%1").arg(TOUINT(reader.read(oo, 4)), 0, 16));
oo += 4;
QTWI(sh, "Elf32_Xword sym_size", oo, 4);
p->setText(1, QString("%1").arg(TOINT(reader.read(oo, 4))));
oo += 4;
str = reader.read(oo, 1);
auto in = TOCHARINT(str);
QTWI(sh, "sym_info_t sym_info", oo, 1);
auto shh = p;
QTWI(shh, "uchar sym_info_type : 4", oo, 1);
m = QMetaEnum::fromType<ELFHelper::sym_info_type_e>();
auto t0 = m.valueToKey(in & 0xF);
p->setText(1, t0);
QTWI(shh, "uchar sym_info_bind : 4", oo++, 1);
m = QMetaEnum::fromType<ELFHelper::sym_info_bind_e>();
auto t1 = m.valueToKey((in & 0xF0) >> 4);
p->setText(1, t1);
shh->setText(1, QString("%1 | %2").arg(t0).arg(t1));
str = reader.read(oo, 1);
QTWI(sh, "unsigned char sym_other", oo++, 1);
p->setText(1, QString("%1").arg(TOCHARINT(str)));
QTWI(sh, "Elf32_Half sym_shndx", oo, 2);
p->setText(1, QString("%1").arg(TOUSHORT(reader.read(oo, 2))));
oo += 2;
}
}
if (dysymoff && dysymsize) {
QTWI(tw, "struct dynamic_symbol_table", dysymoff, dysymsize);
auto nameoff = soffs[dysymlink];
auto length = ulong(dysymsize) / sizeof(Elf32_Sym);
auto sr = p;
auto o = dysymoff;
auto color = settings->getColor(SettingColor::dysymbol_color);
auto dcolor = color.darker();
auto b = false;
for (ulong i = 0; i < length; i++, o += sizeof(Elf32_Sym)) {
QTWI(sr, QString("struct Elf32_Sym symtab[%1]").arg(i), o,
sizeof(Elf32_Sym));
auto sh = p;
auto oo = o;
if (addmeta)
controller.metadata(o, o + qint64(sizeof(Elf32_Sym)),
b ? color : dcolor, Qt::transparent, QString());
QTWI(sh, "sym_name32_t sym_name", oo, 4);
auto off = TOUINT(reader.read(oo, 4));
QString l;
if (off) {
auto of = nameoff + off;
auto pos = reader.searchForward(of, QByteArray(1, '\0'));
l = reader.read(of, int(pos - of));
} else {
l = "<Undefined>";
}
p->setText(1, l);
sh->setText(1, l);
oo += 4;
QTWI(sh, "Elf32_Addr sym_value", oo, 4);
p->setText(1, QString("0x%1").arg(TOUINT(reader.read(oo, 4)), 0, 16));
oo += 4;
QTWI(sh, "Elf32_Xword sym_size", oo, 4);
p->setText(1, QString("%1").arg(TOINT(reader.read(oo, 4))));
oo += 4;
str = reader.read(oo, 1);
auto in = TOCHARINT(str);
QTWI(sh, "sym_info_t sym_info", oo, 1);
auto shh = p;
QTWI(shh, "uchar sym_info_type : 4", oo, 1);
m = QMetaEnum::fromType<ELFHelper::sym_info_type_e>();
auto t0 = m.valueToKey(in & 0xF);
p->setText(1, t0);
QTWI(shh, "uchar sym_info_bind : 4", oo++, 1);
m = QMetaEnum::fromType<ELFHelper::sym_info_bind_e>();
auto t1 = m.valueToKey((in & 0xF0) >> 4);
p->setText(1, t1);
shh->setText(1, QString("%1 | %2").arg(t0).arg(t1));
str = reader.read(oo, 1);
QTWI(sh, "unsigned char sym_other", oo++, 1);
p->setText(1, QString("%1").arg(TOCHARINT(str)));
QTWI(sh, "Elf32_Half sym_shndx", oo, 2);
p->setText(1, QString("%1").arg(TOUSHORT(reader.read(oo, 2))));
oo += 2;
}
}
goto inf;
}
err:
return false;
inf:
if (addmeta)
controller.setMetaVisible(true);
requestRelease();
return true;
}
bool WingElfPlugin::parse64() {
auto totalb = reader.documentBytes();
auto settings = Settings::instance();
auto addmeta = settings->addMetadata();
if (requestControl()) {
QTreeWidgetItem *p;
if (addmeta)
controller.setMetaVisible(false);
QTWI(tw, "struct elf_header", 0, sizeof(Elf64_Ehdr));
if (addmeta)
controller.metadata(0, sizeof(Elf64_Ehdr),
settings->getColor(SettingColor::elf_header_color),
Qt::transparent, QString());
auto h = p;
QTWI(p, "struct e_ident_t e_ident", 0, EI_NIDENT);
auto hh = p;
QTWI(hh, "char file_identification[4]", 0, 4);
p->setText(1, reader.read(0, 4));
auto off = 4;
auto str = reader.read(off, 1);
QTWI(hh, "enum ei_class_2_e ei_class_2", off++, 1);
auto m = QMetaEnum::fromType<ELFHelper::ei_class_2_e>();
p->setText(1, m.valueToKey(str[0]));
str = reader.read(off, 1);
QTWI(hh, "enum ei_data_e ei_data", off++, 1);
m = QMetaEnum::fromType<ELFHelper::ei_data_e>();
p->setText(1, m.valueToKey(str[0]));
str = reader.read(off, 1);
QTWI(hh, "enum ei_version_e ei_version", off++, 1);
m = QMetaEnum::fromType<ELFHelper::ei_version_e>();
p->setText(1, m.valueToKey(str[0]));
str = reader.read(off, 1);
QTWI(hh, "enum ei_osabi_e ei_osabi", off++, 1);
m = QMetaEnum::fromType<ELFHelper::ei_osabi_e>();
p->setText(1, m.valueToKey(str[0]));
str = reader.read(off, 1);
QTWI(hh, "uchar ei_abiversion", off++, 1);
p->setText(1, QString("%1").arg(TOCHARINT(str)));
str = reader.read(off, 6).toHex(' ');
QTWI(hh, "uchar ei_pad[6]", off, 6);
p->setText(1, str);
off += 6;
str = reader.read(off, 1);
QTWI(hh, "uchar ei_nident_SIZE", off++, 1);
p->setText(1, QString("%1").arg(TOCHARINT(str)));
str = reader.read(off, 2);
QTWI(h, "enum e_type64_e e_type", off, 2);
m = QMetaEnum::fromType<ELFHelper::e_type_e>();
p->setText(1, m.valueToKey(TOUSHORT(str)));
off += 2;
str = reader.read(off, 2);
QTWI(h, "enum e_machine64_e e_machine", off, 2);
m = QMetaEnum::fromType<ELFHelper::e_machine_e>();
p->setText(1, m.valueToKey(TOUSHORT(str)));
off += 2;
str = reader.read(off, 4);
QTWI(h, "enum e_version64_e e_version", off, 4);
m = QMetaEnum::fromType<ELFHelper::e_version_e>();
p->setText(1, m.valueToKey(TOINT(str)));
off += 4;
QTWI(h, "Elf64_Addr e_entry_START_ADDRESS", off, 8);
p->setText(1, QString("0x%1").arg(TOINT64(reader.read(off, 8)), 0, 16));
off += 8;
auto e_phoff = TOINT64(reader.read(off, 8));
QTWI(h, "Elf64_Off e_phoff_PROGRAM_HEADER_OFFSET_IN_FILE", off, 8);
p->setText(1, QString("%1").arg(e_phoff));
off += 8;
auto e_shoff = TOINT64(reader.read(off, 8));
QTWI(h, "Elf64_Off e_shoff_SECTION_HEADER_OFFSET_IN_FILE", off, 8);
p->setText(1, QString("%1").arg(e_shoff));
off += 8;
QTWI(h, "Elf64_Word e_flags", off, 4);
p->setText(1, QString("0x%1").arg(TOUINT(reader.read(off, 4)), 0, 16));
off += 4;
QTWI(h, "Elf64_Half e_ehsize_ELF_HEADER_SIZE", off, 2);
p->setText(1, QString("%1").arg(TOUINT(reader.read(off, 4))));
off += 2;
auto e_phentsize = TOUSHORT(reader.read(off, 2));
QTWI(h, "Elf32_Half e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE", off, 2);
p->setText(1, QString("%1").arg(TOUSHORT(reader.read(off, 2))));
off += 2;
auto e_phnum = TOUSHORT(reader.read(off, 2));
QTWI(h, "Elf32_Half e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES", off, 2);
p->setText(1, QString("%1").arg(TOUSHORT(reader.read(off, 2))));
off += 2;
auto e_shentsize = TOUSHORT(reader.read(off, 2));
QTWI(h, "Elf32_Half e_shentsize_SECTION_HEADER_ENTRY_SIZE", off, 2);
p->setText(1, QString("%1").arg(TOUSHORT(reader.read(off, 2))));
off += 2;
auto e_shnum = TOUSHORT(reader.read(off, 2));
QTWI(h, "Elf32_Half e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES", off, 2);
p->setText(1, QString("%1").arg(TOUSHORT(reader.read(off, 2))));
off += 2;
auto e_shtrndx = TOUSHORT(reader.read(off, 2));
QTWI(h, "Elf64_Half e_shtrndx_STRING_TABLE_INDEX", off, 2);
p->setText(1, QString("%1").arg(e_shtrndx));
off += 2;
if (quint64(e_phoff) > totalb ||
quint64(e_phoff + e_phnum * e_phentsize) > totalb)
goto err;
if (e_phoff && e_phnum) {
QTWI(tw, "struct program_header_table", e_phoff, e_phentsize * e_phnum);
auto pr = p;
auto o = e_phoff;
auto color = settings->getColor(SettingColor::program_table_color);
auto dcolor = color.darker();
auto b = false;
for (int i = 0; i < e_phnum; i++, o += e_phentsize) {
QTWI(pr,
QString("struct program_table_entry64_t program_table_element[%1]")
.arg(i),
o, e_phentsize);
if (addmeta)
controller.metadata(o, o + e_phentsize, b ? color : dcolor,
Qt::transparent, QString());
auto ph = p;
auto oo = o;
QTWI(ph, "enum p_type64_e p_type", oo, 4);
m = QMetaEnum::fromType<ELFHelper::p_type_e>();
auto type = m.valueToKey(TOINT(reader.read(oo, 4)));
auto t = type ? type : "Unknown";
b = !b;
p->setText(1, t);
oo += 4;
QTWI(ph, "enum p_flags64_e p_flags", oo, 4);
m = QMetaEnum::fromType<ELFHelper::p_flags_e>();
auto rwx = TOINT(reader.read(oo, 4));
p->setText(1, m.valueToKey(rwx));
QString _rwx;
switch (rwx) {
case ELFHelper::p_flags_e::PF_None:
_rwx = "___";
break;
case ELFHelper::p_flags_e::PF_Exec:
_rwx = "__X";
break;
case ELFHelper::p_flags_e::PF_Write:
_rwx = "_W_";
break;
case ELFHelper::p_flags_e::PF_Write_Exec:
_rwx = "_WX";
break;
case ELFHelper::p_flags_e::PF_Read:
_rwx = "R__";
break;
case ELFHelper::p_flags_e::PF_Read_Exec:
_rwx = "R_X";
break;
case ELFHelper::p_flags_e::PF_Read_Write:
_rwx = "RW_";
break;
case ELFHelper::p_flags_e::PF_Read_Write_Exec:
_rwx = "RWX";
break;
}
oo += 4;
QTWI(ph, "Elf64_Off p_offset_FROM_FILE_BEGIN", oo, 8);
p->setText(1, QString("0x%1").arg(TOINT64(reader.read(off, 8)), 0, 16));
oo += 8;
QTWI(ph, "Elf64_Addr p_vaddr_VIRTUAL_ADDRESS", oo, 8);
p->setText(1, QString("0x%1").arg(TOINT64(reader.read(off, 8)), 0, 16));
oo += 8;
QTWI(ph, "Elf64_Addr p_paddr_PHYSICAL_ADDRESS", oo, 8);
p->setText(1, QString("0x%1").arg(TOINT64(reader.read(off, 8)), 0, 16));
oo += 8;
QTWI(ph, "Elf64_XWord p_filesz_SEGMENT_FILE_LENGTH", oo, 8);
p->setText(1, QString("%1").arg(TOINT64(reader.read(off, 8))));
oo += 8;
QTWI(ph, "Elf64_XWord p_memsz_SEGMENT_RAM_LENGTH", oo, 8);
p->setText(1, QString("%1").arg(TOINT64(reader.read(off, 8))));
oo += 8;
QTWI(ph, "Elf64_XXWord p_align", oo, 8);
p->setText(1, QString("%1").arg(TOINT64(reader.read(oo, 8))));
oo += 8;
ph->setText(1, QString("(%1) %2").arg(_rwx).arg(t));
}
}
if (quint64(e_shoff) > totalb ||
quint64(e_shoff + e_shnum * e_shentsize) > totalb)
goto err;
qint64 symoff = 0, dysymoff = 0;
int symlink = 0, dysymlink = 0;
qint64 symsize = 0, dysymsize = 0;
QList<qint64> soffs;
if (e_shoff && e_shnum) {
QTWI(tw, "struct section_header_table", e_shoff, e_shentsize * e_shnum);
auto sr = p;
auto o = e_shoff;
auto nameoff =
TOINT64(reader.read(e_shoff + (e_shentsize * e_shtrndx) + 24, 8));
auto color = settings->getColor(SettingColor::section_header_color);
auto dcolor = color.darker();
auto b = false;
for (int i = 0; i < e_shnum; i++, o += e_shentsize) {
QTWI(sr,
QString("struct section_table_entry64_t section_table_element[%1]")
.arg(i),
o, e_shentsize);
auto sh = p;
auto oo = o;
if (addmeta)
controller.metadata(o, o + e_shentsize, b ? color : dcolor,
Qt::transparent, QString());
QTWI(sh, "s_name64_t s_name", oo, 4);
auto off = TOUINT(reader.read(oo, 4));
QString l;
if (off) {
auto of = nameoff + off;
auto pos = reader.searchForward(of, QByteArray(1, '\0'));
l = reader.read(of, int(pos - of));
} else {
l = "<Undefined>";
}
p->setText(1, l);
sh->setText(1, l);
oo += 4;
str = reader.read(oo, 4);
QTWI(sh, "enum s_type64_e s_type", oo, 4);
m = QMetaEnum::fromType<ELFHelper::s_type_e>();
p->setText(1, m.valueToKey(TOINT(str)));
oo += 4;
str = reader.read(oo, 4);
QTWI(sh, "enum s_flags64_e s_flags", oo, 8);
m = QMetaEnum::fromType<ELFHelper::s_flags64_e>();
p->setText(1, m.valueToKey(TOINT(str)));
oo += 8;
QTWI(sh, "Elf64_Addr s_addr", oo, 8);
p->setText(1, QString("0x%1").arg(TOINT64(reader.read(oo, 8)), 0, 16));
oo += 8;
QTWI(sh, "Elf64_Off s_offset", oo, 8);
auto off00 = TOINT64(reader.read(oo, 8));
soffs.push_back(off00);
p->setText(1, QString("0x%1").arg(off00, 0, 16));
oo += 8;
QTWI(sh, "Elf64_Xword s_size", oo, 8);
auto off0 = TOINT64(reader.read(oo, 8));
p->setText(1, QString("%1").arg(off0));
oo += 8;
QTWI(sh, "Elf64_Word s_link", oo, 4);
auto off1 = TOINT(reader.read(oo, 4));
p->setText(1, QString("0x%1").arg(off1, 0, 16));
if (!l.compare(".symtab")) {
symoff = off00;
symsize = off0;
symlink = off1;
} else if (!l.compare(".dynsym")) {
dysymoff = off00;
dysymsize = off0;
dysymlink = off1;
}
oo += 4;
QTWI(sh, "Elf64_Word s_info", oo, 4);
p->setText(1, QString("0x%1").arg(TOUINT(reader.read(oo, 4)), 0, 16));
oo += 4;
QTWI(sh, "Elf64_Xword s_addralign", oo, 8);
p->setText(1, QString("%1").arg(TOINT64(reader.read(oo, 8))));
oo += 8;
QTWI(sh, "Elf64_Xword s_entsize", oo, 8);
p->setText(1, QString("%1").arg(TOINT64(reader.read(oo, 8))));
oo += 8;
}
}
if (symoff && symsize) {
QTWI(tw, "struct symbol_table", symoff, symsize);
auto nameoff = soffs[symlink];
auto length = ulong(symsize) / sizeof(Elf64_Sym);
auto sr = p;
auto o = symoff;
auto color = settings->getColor(SettingColor::symbol_color);
auto dcolor = color.darker();
auto b = false;
for (ulong i = 0; i < length; i++, o += sizeof(Elf64_Sym)) {
QTWI(sr, QString("struct Elf64_Sym symtab[%1]").arg(i), o,
sizeof(Elf64_Sym));
auto sh = p;
auto oo = o;
if (addmeta)
controller.metadata(o, o + qint64(sizeof(Elf64_Sym)),
b ? color : dcolor, Qt::transparent, QString());
QTWI(sh, "sym_name64_t sym_name", oo, 4);
auto off = TOUINT(reader.read(oo, 4));
QString l;
if (off) {
auto of = nameoff + off;
auto pos = reader.searchForward(of, QByteArray(1, '\0'));
l = reader.read(of, int(pos - of));
} else {
l = "<Undefined>";
}
p->setText(1, l);
sh->setText(1, l);
oo += 4;
str = reader.read(oo, 1);
auto in = TOCHARINT(str);
QTWI(sh, "sym_info_t sym_info", oo, 1);
auto shh = p;
QTWI(shh, "uchar sym_info_type : 4", oo, 1);
m = QMetaEnum::fromType<ELFHelper::sym_info_type_e>();
auto t0 = m.valueToKey(in & 0xF);
p->setText(1, t0);
QTWI(shh, "uchar sym_info_bind : 4", oo++, 1);
m = QMetaEnum::fromType<ELFHelper::sym_info_bind_e>();
auto t1 = m.valueToKey((in & 0xF0) >> 4);
p->setText(1, t1);
shh->setText(1, QString("%1 | %2").arg(t0).arg(t1));
str = reader.read(oo, 1);
QTWI(sh, "unsigned char sym_other", oo++, 1);
p->setText(1, QString("%1").arg(TOCHARINT(str)));
QTWI(sh, "Elf64_Half sym_shndx", oo, 2);
p->setText(1, QString("%1").arg(TOUSHORT(reader.read(oo, 2))));
oo += 2;
QTWI(sh, "Elf64_Addr sym_value", oo, 8);
p->setText(1, QString("0x%1").arg(TOINT64(reader.read(oo, 8)), 0, 16));
oo += 8;
QTWI(sh, "Elf64_Xword sym_size", oo, 8);
p->setText(1, QString("%1").arg(TOINT(reader.read(oo, 8))));
oo += 8;
}
}
if (dysymoff && dysymsize) {
QTWI(tw, "struct dynamic_symbol_table", dysymoff, dysymsize);
auto nameoff = soffs[dysymlink];
auto length = ulong(dysymsize) / sizeof(Elf64_Sym);
auto sr = p;
auto o = dysymoff;
auto color = settings->getColor(SettingColor::dysymbol_color);
auto dcolor = color.darker();
auto b = false;
for (ulong i = 0; i < length; i++, o += sizeof(Elf64_Sym)) {
QTWI(sr, QString("struct Elf64_Sym symtab[%1]").arg(i), o,
sizeof(Elf32_Sym));
auto sh = p;
auto oo = o;
if (addmeta)
controller.metadata(o, o + qint64(sizeof(Elf64_Sym)),
b ? color : dcolor, Qt::transparent, QString());
QTWI(sh, "sym_name64_t sym_name", oo, 4);
auto off = TOUINT(reader.read(oo, 4));
QString l;
if (off) {
auto of = nameoff + off;
auto pos = reader.searchForward(of, QByteArray(1, '\0'));
l = reader.read(of, int(pos - of));
} else {
l = "<Undefined>";
}
p->setText(1, l);
sh->setText(1, l);
oo += 4;
str = reader.read(oo, 1);
auto in = TOCHARINT(str);
QTWI(sh, "sym_info_t sym_info", oo, 1);
auto shh = p;
QTWI(shh, "uchar sym_info_type : 4", oo, 1);
m = QMetaEnum::fromType<ELFHelper::sym_info_type_e>();
auto t0 = m.valueToKey(in & 0xF);
p->setText(1, t0);
QTWI(shh, "uchar sym_info_bind : 4", oo++, 1);
m = QMetaEnum::fromType<ELFHelper::sym_info_bind_e>();
auto t1 = m.valueToKey((in & 0xF0) >> 4);
p->setText(1, t1);
shh->setText(1, QString("%1 | %2").arg(t0).arg(t1));
str = reader.read(oo, 1);
QTWI(sh, "unsigned char sym_other", oo++, 1);
p->setText(1, QString("%1").arg(TOCHARINT(str)));
QTWI(sh, "Elf64_Half sym_shndx", oo, 2);
p->setText(1, QString("%1").arg(TOUSHORT(reader.read(oo, 2))));
oo += 2;
QTWI(sh, "Elf64_Addr sym_value", oo, 8);
p->setText(1, QString("0x%1").arg(TOINT64(reader.read(oo, 8)), 0, 16));
oo += 8;
QTWI(sh, "Elf64_Xword sym_size", oo, 8);
p->setText(1, QString("%1").arg(TOINT(reader.read(oo, 8))));
oo += 8;
}
}
goto inf;
}
err:
return false;
inf:
if (addmeta)
controller.setMetaVisible(true);
requestRelease();
return true;
}
HookIndex WingElfPlugin::getHookSubscribe() { return HookIndex::None; }
void WingElfPlugin::unload() {}
uint WingElfPlugin::pluginVersion() { return 2; }
QMenu *WingElfPlugin::registerMenu() { return menu; }
void WingElfPlugin::registerDockWidget(
QHash<QDockWidget *, Qt::DockWidgetArea> &rdw) {
rdw.insert(dw, Qt::DockWidgetArea::BottomDockWidgetArea);
}
QToolButton *WingElfPlugin::registerToolButton() { return tbtn; }