Skip to content
Open
2 changes: 2 additions & 0 deletions capstonebundle/plugin/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@

#include "arm/common.h"
#include "arm/arm.h"

#include "mos65xx/mos65xx.h"
73 changes: 73 additions & 0 deletions capstonebundle/plugin/mos65xx/mos65xx.cpp
Original file line number Diff line number Diff line change
@@ -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) { }
38 changes: 38 additions & 0 deletions capstonebundle/plugin/mos65xx/mos65xx.h
Original file line number Diff line number Diff line change
@@ -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 <rdapi/rdapi.h>
#include <utility>
#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); };
26 changes: 26 additions & 0 deletions capstonebundle/plugin/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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); } };
}
Expand Down Expand Up @@ -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<CS_ARCH_MOS65XX, CS_MODE_BIG_ENDIAN>;
mos65xxbe.renderinstruction = &render<CS_ARCH_MOS65XX, CS_MODE_BIG_ENDIAN>;
mos65xxbe.lift = &lift<CS_ARCH_MOS65XX, CS_MODE_BIG_ENDIAN>;
mos65xxbe.bits = 8;
RDAssembler_Register(pm, &mos65xxbe);


RD_PLUGIN_ENTRY(RDEntryAssembler, mos65xxle, "MOS65xxx (Little Endian)");
mos65xxle.emulate = &emulate<CS_ARCH_MOS65XX, CS_MODE_LITTLE_ENDIAN>;
mos65xxle.renderinstruction = &render<CS_ARCH_MOS65XX, CS_MODE_LITTLE_ENDIAN>;
mos65xxle.lift = &lift<CS_ARCH_MOS65XX, CS_MODE_LITTLE_ENDIAN>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove the lifter part, is not mandatory

mos65xxle.bits = 8;
RDAssembler_Register(pm, &mos65xxle);


// Editing Ended

RD_PLUGIN_ENTRY(RDEntryAssembler, thumble, "THUMB (Little Endian)");
thumble.emulate = &emulate<CS_ARCH_ARM, CS_MODE_THUMB | CS_MODE_LITTLE_ENDIAN>;
thumble.renderinstruction = &render<CS_ARCH_ARM, CS_MODE_THUMB | CS_MODE_LITTLE_ENDIAN>;
Expand Down