Skip to content

Writing a FormatPlugin

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

The FormatPlugin describes and validates specific file format, REDasm needs to know few basic informations:

  • Segments.
  • Supported Instruction Set.
  • Bits (8, 16, 32, 64, ...).

And, if needed, extra information can be added in order to improve analysis:

  • Entry Point.
  • Functions (Import, Exports, ...).
  • Symbols.

Creation

The first thing to do is to create a folder called custom in redasm/formats and declare a class called CustomFormat that inherits from FormatPluginT<T>, the T parameter can be our struct (or any other type) that rappresents the header.
After the creation, we need to declare our plugin with DECLARE_FORMAT_PLUGIN macro and associate a unique id to it.

NOTE: If the format doesn't provide a fixed structure FormatPluginT<T> can be replaced with FormatPluginB.

// custom.h
#include "../../plugins/plugins.h" // Import FormatPluginT
#include "custom_header.h"         // Import CustomFormat's structures

class CustomFormat: public FormatPluginT<CustomHeader>
{
  DEFINE_FORMAT_PLUGIN_TEST(CustomHeader)

  public:
    CustomFormat(AbstractBuffer* buffer);
    virtual const char* name() const;      // Format's display name
    virtual u32 bits() const;              // Format's bits
    virtual const char* assembler() const; // Supported AssemblerPlugin (IDs can be found in plugins.cpp)
    virtual bool load();                   // Validate and load the format (true=ok, false=invalid)
};

DECLARE_FORMAT_PLUGIN(CustomFormat, custom) // Declare the plugin with id: CustomFormat=custom
// custom.cpp
#include "custom.h"

FORMAT_PLUGIN_TEST(CustomFormat, CustomHeader) // Validation
{
  return format->signature == 0xDEADBEEF;
}

CustomFormat::CustomFormat(AbstractBuffer* buffer): FormatPluginT<CustomHeader>(buffer) { }
const char* CustomFormat::name() const { return "My Custom Format"; }
const char* CustomFormat::bits() const { return 32; }
const char* CustomFormat::assembler() const { return "x86"; }

void CustomFormat::load(u8* rawformat)
{
  // Define a Segment that contains code and data
  m_document->segment("s001", 0, 0x1000, 0x200, SegmentTypes::Code | SegmentTypes::Data);

  // Define an EntryPoint inside "s001" segment
  m_document->entry(0x1000);
}

Registration

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

// plugins.cpp

#include FORMAT_PLUGIN(custom) // Import CustomFormat

void init(const std::string& searchpath)
{
  ...
  REGISTER_FORMAT_PLUGIN(custom); // Register CustomFormat by using its ID
  ...
}
You can’t perform that action at this time.