diff --git a/capstonebundle/plugin/arch.h b/capstonebundle/plugin/arch.h index 77d3f41..657c633 100644 --- a/capstonebundle/plugin/arch.h +++ b/capstonebundle/plugin/arch.h @@ -10,3 +10,5 @@ #include "arm/common.h" #include "arm/arm.h" + +#include "mos65xx/mos65xx.h" diff --git a/capstonebundle/plugin/mos65xx/mos65xx.cpp b/capstonebundle/plugin/mos65xx/mos65xx.cpp new file mode 100644 index 0000000..dad496b --- /dev/null +++ b/capstonebundle/plugin/mos65xx/mos65xx.cpp @@ -0,0 +1,73 @@ +// mos65xx.cpp +#include "mos65xx.h" + +MOS65XX::MOS65XX(RDContext* ctx, cs_mode mode): Capstone(ctx, CS_ARCH_MOS65XX, mode) { } + +void MOS65XX::emulate(RDEmulateResult* result) +{ + + //auto* insn = this->decode(address, RDEmulateResult_GetView(result)); + //if(!insn) return; + + // Instruction is decoded, you can use Capstone API to analyze it + + rd_address address = RDEmulateResult_GetAddress(result); + if(!this->decode(address, RDEmulateResult_GetView(result))) return; + RDEmulateResult_SetSize(result, m_insn->size); // Next time "emulate" is called is after insn->size bytes + + const auto& mos65xx = m_insn->detail->mos65xx; + + switch(m_insn->id) + { + case MOS65XX_INS_BVS: { + RDEmulateResult_AddBranchTrue(result, mos65xx.operands[0].imm); + RDEmulateResult_AddBranchFalse(result, address + m_insn->size); + return; + } + + default: break; + } + return; +} + +void MOS65XX::render(const RDRendererParams* rp) +{ + // You can render instructions here + // auto* insn = this->decode(rp->address, &rp->view); + + const auto& mos65xx = m_insn->detail->mos65xx; + RDRenderer_MnemonicWord(rp->renderer, m_insn->mnemonic, MOS65XX::mnemonicTheme(m_insn)); + + +} + +rd_type MOS65XX::mnemonicTheme(const cs_insn* m_insn) +{ + const auto& mos65xx = m_insn->detail->mos65xx; + + // switch(m_insn->id) + // { + // case ARM_INS_B: return (arm.cc == ARM_CC_AL) ? Theme_Jump : Theme_JumpCond; + + // case ARM_INS_BL: + // case ARM_INS_BLX: return Theme_Call; + + // case ARM_INS_LDR: { + // if(MOS65XX::isPC(insn, 0)) return Theme_Ret; + // break; + // } + + // default: break; + // } + + // return Theme_Default; +} + +void MOS65XX::lift(const Capstone* capstone, rd_address address, const RDBufferView* view, RDILFunction* il) { MOS65XXLifter::lift(capstone, address, view, il); } + + +//ARMLE::ARMLE(RDContext* ctx): ARM(ctx, CS_MODE_LITTLE_ENDIAN) { } +//ARMBE::ARMBE(RDContext* ctx): ARM(ctx, CS_MODE_BIG_ENDIAN) { } + +MOS65XXLE::MOS65XXLE(RDContext* ctx): MOS65XX(ctx, CS_MODE_LITTLE_ENDIAN) { } +MOS65XXBE::MOS65XXBE(RDContext* ctx): MOS65XX(ctx, CS_MODE_BIG_ENDIAN) { } diff --git a/capstonebundle/plugin/mos65xx/mos65xx.h b/capstonebundle/plugin/mos65xx/mos65xx.h new file mode 100644 index 0000000..46f0ea8 --- /dev/null +++ b/capstonebundle/plugin/mos65xx/mos65xx.h @@ -0,0 +1,38 @@ +// mos65xx.h +#pragma once + +#define MOS65XXLE_USERDATA "mos65xxle_userdata" +#define MOS65XXBE_USERDATA "mos65xxbe_userdata" + +#define MOS65XXLE_ID "mos65xxle" +#define MOS65XXBE_ID "mos65xxbe" + +#include +#include +#include "../capstone.h" + +class MOS65XX: public Capstone { + public: + // Capstone(RDContext* ctx); // There is also a "cs_mode" argument, I don't know if this architecture needs it + MOS65XX(RDContext* ctx, cs_mode mode); + void emulate(RDEmulateResult* result) override; // This implements the algorithm (jumps, calls etc) + void render(const RDRendererParams* rp) override; // This renders instructions visually + void lift(const Capstone* capstone, rd_address address, const RDBufferView* view, RDILFunction* il) override; + private: + static rd_type mnemonicTheme(const cs_insn* insn); +}; + + +class MOS65XXLifter +{ + public: + MOS65XXLifter() = delete; + static void lift(const Capstone* capstone, rd_address address, const RDBufferView* view, RDILFunction* il); + + private: + static RDILExpression* liftOperand(const Capstone* capstone, rd_address address, const cs_insn* insn, size_t idx, const RDILFunction* il); +}; + + +class MOS65XXLE: public MOS65XX { public: MOS65XXLE(RDContext* ctx); }; +class MOS65XXBE: public MOS65XX { public: MOS65XXBE(RDContext* ctx); }; \ No newline at end of file diff --git a/capstonebundle/plugin/plugin.cpp b/capstonebundle/plugin/plugin.cpp index a6752b0..e6f63c4 100644 --- a/capstonebundle/plugin/plugin.cpp +++ b/capstonebundle/plugin/plugin.cpp @@ -22,6 +22,12 @@ static void initUserData() CS_ITEMS[hashArch(CS_ARCH_ARM64, CS_MODE_BIG_ENDIAN)] = { ARM64BE_USERDATA, [](RDContext* ctx) { return new ARM64BE(ctx); } }; CS_ITEMS[hashArch(CS_ARCH_ARM, CS_MODE_LITTLE_ENDIAN)] = { ARM32LE_USERDATA, [](RDContext* ctx) { return new ARM32LE(ctx); } }; CS_ITEMS[hashArch(CS_ARCH_ARM, CS_MODE_BIG_ENDIAN)] = { ARM32BE_USERDATA, [](RDContext* ctx) { return new ARM32BE(ctx); } }; + + // Editing + CS_ITEMS[hashArch(CS_ARCH_MOS65XX, CS_MODE_LITTLE_ENDIAN)] = { MOS65XXLE_USERDATA, [](RDContext* ctx) { return new MOS65XXLE(ctx); } }; + CS_ITEMS[hashArch(CS_ARCH_MOS65XX, CS_MODE_BIG_ENDIAN)] = { MOS65XXBE_USERDATA, [](RDContext* ctx) { return new MOS65XXBE(ctx); } }; + // End Editing + CS_ITEMS[hashArch(CS_ARCH_ARM, CS_MODE_THUMB | CS_MODE_LITTLE_ENDIAN)] = { THUMB32LE_USERDATA, [](RDContext* ctx) { return new ThumbLE(ctx); } }; CS_ITEMS[hashArch(CS_ARCH_ARM, CS_MODE_THUMB | CS_MODE_BIG_ENDIAN)] = { THUMB32BE_USERDATA, [](RDContext* ctx) { return new ThumbBE(ctx); } }; } @@ -110,6 +116,26 @@ void rdplugin_init(RDContext*, RDPluginModule* pm) arm32be.bits = 32; RDAssembler_Register(pm, &arm32be); + // Editing + + RD_PLUGIN_ENTRY(RDEntryAssembler, mos65xxbe, "MOS65xxx (Big Endian)"); + mos65xxbe.emulate = &emulate; + mos65xxbe.renderinstruction = &render; + mos65xxbe.lift = &lift; + mos65xxbe.bits = 8; + RDAssembler_Register(pm, &mos65xxbe); + + + RD_PLUGIN_ENTRY(RDEntryAssembler, mos65xxle, "MOS65xxx (Little Endian)"); + mos65xxle.emulate = &emulate; + mos65xxle.renderinstruction = &render; + mos65xxle.lift = &lift; + mos65xxle.bits = 8; + RDAssembler_Register(pm, &mos65xxle); + + + // Editing Ended + RD_PLUGIN_ENTRY(RDEntryAssembler, thumble, "THUMB (Little Endian)"); thumble.emulate = &emulate; thumble.renderinstruction = &render;