Skip to content

Writing an AssemblerPlugin

Antonio Davide edited this page Feb 20, 2019 · 12 revisions

The AssemblerPlugin provides an instruction decoder for a specific cpu/architecture, usually it's not tied to a specific FormatPlugin (currently, only DalvikAssembler is tied to DEXFormat).

The most important function of an AssemblerPlugin is decodeInstruction(): this function decodes a single Instruction, also, this class provides methods needed for custom printing, emulation and operand analysis.
onDecoded is called only when the instruction is valid.


Like FormatPlugin, the first thing to do is to create a folder called customasm in redasm/assemblers and declare a class called CustomAssembler that inherits from AssemblerPlugin.
After the creation, we need to declare our plugin by calling DECLARE_ASSEMBLER_PLUGIN macro and associate a unique id to it.

// customasm.h

#include "../../plugins/plugins.h" // Import AssemblerPlugin
#include "../../support/dispatcher.h"

class CustomAssembler: public AssemblerPlugin
      virtual const char* name() const;                                      // Assembler's display name

      virtual bool decodeInstruction(const BufferView& view const InstructionPtr& instruction); // Our decoding function
      virtual void onDecoded(const InstructionPtr& instruction) const; // ...when instruction is decoded...

      Dispatcher<u16, void(Buffer&, const InstructionPtr&)> m_decodemap; // Our decoding map

DECLARE_ASSEMBLER_PLUGIN(CustomAssembler, customasm) // Declare the plugin with id: CustomAssembler=customasm
// customasm.cpp

#include "customasm.h"

CustomAssembler::CustomAssembler(): AssemblerPlugin()
     * Fill m_decodemap with
     * m_decodemap[opcode] = decode_callback;

const char* CustomAssembler::name() const { return "Custom Assembler"; }

bool CustomAssembler::decodeInstruction(const BufferView& view, const InstructionPtr& instruction)
    u16 opcode = *buffer;    // Read 16-bits from buffer with the right endianness
      return false; // Unknown opcode: REDasm will generate an invalid Instruction

    m_decodemap(buffer, instruction);
    return true;

void CustomAssembler::onDecoded(const InstructionPtr& instruction) const
    // Post decoding code: operand definition, instruction type, etc...


In order to make our format visible to REDasm, it needs to be registered in plugins.cpp by using REGISTER_ASSEMBLER_PLUGIN macro.

// plugins.cpp

#include ASSEMBLER_PLUGIN(customasm) // Import CustomAssembler

void init(const std::string& searchpath)
  REGISTER_ASSEMBLER_PLUGIN(customasm); // Register CustomAssembler by using its ID

Backend support

This article describes the most basic type of AssemblerPlugin, but, for example, it's possible to use the Capstone customized one called CapstoneAssemblerPlugin which provides its CapstonePrinter in order to decode registers automatically, also, decodeInstruction() function is customized and it decodes instruction automatically by calling Capstone APIs and it allows to use cs_insn* type for analysis.

You can’t perform that action at this time.