256 lines
6.4 KiB
C++
256 lines
6.4 KiB
C++
#include "winghexasm.h"
|
|
#include <QApplication>
|
|
#include <QHBoxLayout>
|
|
#include <QLabel>
|
|
#include <QMessageBox>
|
|
#include <QMetaEnum>
|
|
#include <QPushButton>
|
|
#include <QSettings>
|
|
#include <QVBoxLayout>
|
|
|
|
#define ICONRES(name) QIcon(":/WingHexAsm/img/" name ".png")
|
|
#define HOSTICONRES(name) QIcon(HOSTRESPIMG(name))
|
|
|
|
WingHexAsm::WingHexAsm(QObject *parent) { Q_UNUSED(parent) }
|
|
|
|
bool WingHexAsm::init(QList<WingPluginInfo> loadedplugin) {
|
|
Q_UNUSED(loadedplugin);
|
|
|
|
if (SDKVERSION < 8) {
|
|
QMessageBox::critical(nullptr, "Error",
|
|
"UnSupported Plugin System Version!",
|
|
QMessageBox::Ok);
|
|
return false;
|
|
}
|
|
|
|
auto translator = new QTranslator(this);
|
|
|
|
auto s = GETPLUGINQM("WingHexAsm.qm");
|
|
if (!translator->load(s) || !QApplication::installTranslator(translator)) {
|
|
QMessageBox::critical(nullptr, "Error", "Error Loading Translation File!",
|
|
QMessageBox::Ok);
|
|
return false;
|
|
}
|
|
|
|
w = new QWidget;
|
|
auto vlayout = new QVBoxLayout(w);
|
|
auto hlayout = new QHBoxLayout(w);
|
|
|
|
hlayout->addWidget(new QLabel(tr("Arch :"), w));
|
|
hlayout->addSpacing(10);
|
|
|
|
// 默认 x86_64 64 位指令
|
|
arch = new QComboBox(w);
|
|
QStringList archs(
|
|
{"ARM", "ARM64", "MIPS", "X86_64", "PPC", "SPARC", "EVM", "MOS65XX"});
|
|
arch->addItems(archs);
|
|
arch->setCurrentIndex(3);
|
|
|
|
void (QComboBox::*indexChanged)(int index) = &QComboBox::currentIndexChanged;
|
|
connect(arch, indexChanged, [=](int index) {
|
|
switch (index) {
|
|
case 0:
|
|
karch = ks_arch::KS_ARCH_ARM;
|
|
break;
|
|
case 1:
|
|
karch = ks_arch::KS_ARCH_ARM64;
|
|
break;
|
|
case 2:
|
|
karch = ks_arch::KS_ARCH_MIPS;
|
|
break;
|
|
case 3:
|
|
karch = ks_arch::KS_ARCH_X86;
|
|
break;
|
|
case 4:
|
|
karch = ks_arch::KS_ARCH_PPC;
|
|
break;
|
|
case 5:
|
|
karch = ks_arch::KS_ARCH_SPARC;
|
|
break;
|
|
case 6:
|
|
karch = ks_arch::KS_ARCH_EVM;
|
|
break;
|
|
}
|
|
});
|
|
|
|
hlayout->addWidget(arch);
|
|
hlayout->addSpacing(30);
|
|
|
|
hlayout->addWidget(new QLabel(tr("Mode :"), w));
|
|
hlayout->addSpacing(10);
|
|
|
|
mode = new QComboBox(w);
|
|
QStringList modes({"x16", "x32", "x64", "THUMB", "MIPS32", "MIPS64"});
|
|
mode->addItems(modes);
|
|
mode->setCurrentIndex(2);
|
|
|
|
connect(mode, indexChanged, [=](int index) {
|
|
switch (index) {
|
|
case 0:
|
|
kmode = ks_mode::KS_MODE_16;
|
|
break;
|
|
case 1:
|
|
kmode = ks_mode::KS_MODE_32;
|
|
break;
|
|
case 2:
|
|
kmode = ks_mode::KS_MODE_64;
|
|
break;
|
|
case 3:
|
|
kmode = ks_mode::KS_MODE_THUMB;
|
|
break;
|
|
case 4:
|
|
kmode = ks_mode::KS_MODE_MIPS32;
|
|
break;
|
|
case 5:
|
|
kmode = ks_mode::KS_MODE_MIPS64;
|
|
break;
|
|
}
|
|
});
|
|
|
|
hlayout->addWidget(mode);
|
|
hlayout->addSpacing(10);
|
|
|
|
cbintel = new QCheckBox("Intel", w);
|
|
cbintel->setChecked(true);
|
|
hlayout->addWidget(cbintel);
|
|
|
|
hlayout->addStretch();
|
|
|
|
vlayout->addSpacing(10);
|
|
|
|
txtAsm = new QTextBrowser(w);
|
|
txtAsm->setReadOnly(false);
|
|
vlayout->addItem(hlayout);
|
|
vlayout->addWidget(txtAsm);
|
|
|
|
vlayout->addSpacing(10);
|
|
auto asmbtn = new QPushButton(tr("AsmCode"), w);
|
|
connect(asmbtn, &QPushButton::clicked, this, [=] {
|
|
auto txt = txtAsm->toPlainText();
|
|
if (txt.length()) {
|
|
this->asmCode(txt);
|
|
} else {
|
|
this->toast(ICONRES("icon"), tr("No Asm"));
|
|
}
|
|
});
|
|
vlayout->addWidget(asmbtn);
|
|
|
|
PluginDockWidgetInit(dw, w, tr("AsmWindow"), "AsmWindow");
|
|
|
|
PluginMenuInitBegin(menu, tr("WingHexAsm")) {
|
|
menu->setIcon(ICONRES("icon"));
|
|
PluginMenuAddItemIconLamba(menu, tr("AsmWindow"), ICONRES("icon"), [=] {
|
|
dw->show();
|
|
dw->raise();
|
|
});
|
|
PluginMenuAddItemIconLamba(menu, tr("Author"), HOSTICONRES("author"), [=] {
|
|
auto authord =
|
|
newAboutDialog(QPixmap(), {":/WingHexAsm", ":/WingHexAsm/img"});
|
|
authord->exec();
|
|
delete authord;
|
|
});
|
|
PluginMenuAddItemIconLamba(menu, tr("Sponsor"), HOSTICONRES("sponsor"),
|
|
[=] {
|
|
auto sponsor = newSponsorDialog();
|
|
sponsor->exec();
|
|
delete sponsor;
|
|
});
|
|
}
|
|
PluginMenuInitEnd();
|
|
|
|
tbtn = new QToolButton;
|
|
tbtn->setIcon(ICONRES("icon"));
|
|
|
|
connect(tbtn, &QToolButton::clicked, this, [=] {
|
|
dw->show();
|
|
dw->raise();
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
WingHexAsm::~WingHexAsm() {}
|
|
|
|
void WingHexAsm::unload() {}
|
|
|
|
int WingHexAsm::sdkVersion() { return SDKVERSION; }
|
|
|
|
QMenu *WingHexAsm::registerMenu() { return menu; }
|
|
|
|
QToolButton *WingHexAsm::registerToolButton() { return tbtn; }
|
|
|
|
void WingHexAsm::registerDockWidget(
|
|
QMap<QDockWidget *, Qt::DockWidgetArea> &rdw) {
|
|
rdw.insert(dw, Qt::DockWidgetArea::BottomDockWidgetArea);
|
|
}
|
|
|
|
QString WingHexAsm::pluginName() { return tr("WingHexAsm"); }
|
|
|
|
QString WingHexAsm::pluginAuthor() { return WINGSUMMER; }
|
|
|
|
uint WingHexAsm::pluginVersion() { return 1; }
|
|
|
|
QString WingHexAsm::signature() { return WINGSUMMER; }
|
|
|
|
QString WingHexAsm::pluginComment() {
|
|
return tr("A small assembly plugin for WingHexExplorer.");
|
|
}
|
|
|
|
void WingHexAsm::plugin2MessagePipe(WingPluginMessage type,
|
|
QList<QVariant> msg) {
|
|
Q_UNUSED(type);
|
|
Q_UNUSED(msg);
|
|
}
|
|
|
|
void WingHexAsm::asmCode(QString code) {
|
|
ks_engine *ks;
|
|
ks_err err;
|
|
size_t count;
|
|
unsigned char *encode;
|
|
size_t size;
|
|
|
|
QIcon icon = ICONRES("icon");
|
|
|
|
err = ks_open(karch, kmode, &ks);
|
|
if (err != KS_ERR_OK) {
|
|
toast(icon, tr("ERROR: failed on ks_open()"));
|
|
return;
|
|
}
|
|
|
|
if (cbintel->isChecked()) {
|
|
ks_option(ks, KS_OPT_SYNTAX, KS_OPT_SYNTAX_INTEL);
|
|
} else {
|
|
ks_option(ks, KS_OPT_SYNTAX, KS_OPT_SYNTAX_ATT);
|
|
}
|
|
|
|
if (ks_asm(ks, code.toUtf8().constData(), 0, &encode, &size, &count)) {
|
|
toast(icon, tr("ERROR: failed on ks_asm() with count = %1, error code = %2")
|
|
.arg(count)
|
|
.arg(ks_errno(ks)));
|
|
} else {
|
|
QByteArray buffer(reinterpret_cast<char *>(encode), int(size));
|
|
if (reader.currentDoc() < 0) {
|
|
USINGCONTROL({
|
|
controller.newFile();
|
|
controller.insert(0, buffer); // 直接使用 insert 会比 append 更高效一点
|
|
});
|
|
} else {
|
|
USINGCONTROL({
|
|
auto pos = reader.currentOffset();
|
|
controller.insert(qint64(pos), buffer);
|
|
});
|
|
}
|
|
toast(icon, tr("ASMSuccessfully"));
|
|
}
|
|
|
|
// NOTE: free encode after usage to avoid leaking memory
|
|
ks_free(encode);
|
|
|
|
// close Keystone instance when done
|
|
ks_close(ks);
|
|
}
|
|
|
|
#if QT_VERSION < 0x050000
|
|
Q_EXPORT_PLUGIN2(WingHexAsm, WingHexAsm)
|
|
#endif // QT_VERSION < 0x050000
|