*bin_obj = r_bin_internal_nes_load (buf, size);
return *bin_obj != NULL;
}
static void destroy(RBinFile *bf) {
r_bin_free_all_nes_obj (bf->o->bin_obj);
bf->o->bin_obj = NULL;
}
static bool check_buffer(RBuffer *b) {
if (!buf || length < 4) return false;
return (!memcmp (buf, "\x4E\x45\x53\x1A", 4));
}
static RBinInfo* info(RBinFile *arch) {
RBinInfo \*ret = R_NEW0 (RBinInfo);
if (!ret) return NULL;
if (!arch || !arch->buf) {
free (ret);
return NULL;
}
ret->file = strdup (arch->file);
ret->type = strdup ("ROM");
ret->machine = strdup ("Nintendo NES");
ret->os = strdup ("nes");
ret->arch = strdup ("6502");
ret->bits = 8;
return ret;
}
struct r_bin_plugin_t r_bin_plugin_nes = {
.name = "nes",
.desc = "NES",
.license = "BSD",
.get_sdb = NULL,
.load_buffer = &load_buffer,
.destroy = &destroy,
.check_buffer = &check_buffer,
.baddr = NULL,
.entries = NULL,
.sections = NULL,
.info = &info,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN,
.data = &r_bin_plugin_nes,
.version = R2_VERSION
};
#endif
• XBE - https://github.com/radareorg/radare2/pull/972
• COFF - https://github.com/radareorg/radare2/pull/645
• TE - https://github.com/radareorg/radare2/pull/61
• Zimgz - https://github.com/radareorg/radare2/commit/d1351cf836df3e2e63043a6dc728e880316f00eb
• OMF - https://github.com/radareorg/radare2/commit/44fd8b2555a0446ea759901a94c06f20566bbc40
• Adding the debugger registers profile into the shlr/gdb/src/core.c
• Adding the registers profile and architecture support in the libr/debug/p/debug_native.c and libr/debug/p/debug_gdb.c
• Add the code to apply the profiles into the function r_debug_gdb_attach(RDebug *dbg, int pid)
If you want to add support for the gdb, you can see the register profile in the active gdb session using command maint print registers.
• Related article: http://radare.today/posts/extending-r2-with-new-plugins/
Some commits related to "Implementing a new architecture"
• Extensa: https://github.com/radareorg/radare2/commit/6f1655c49160fe9a287020537afe0fb8049085d7
• Malbolge: https://github.com/radareorg/radare2/pull/579
• 6502: https://github.com/radareorg/radare2/pull/656
• h8300: https://github.com/radareorg/radare2/pull/664
• GBA: https://github.com/radareorg/radare2/pull/702
• CR16: https://github.com/radareorg/radare2/pull/721/ && 726
• XCore: https://github.com/radareorg/radare2/commit/bb16d1737ca5a471142f16ccfa7d444d2713a54d
• SharpLH5801: https://github.com/neuschaefer/radare2/commit/f4993cca634161ce6f82a64596fce45fe6b818e7
• MSP430: https://github.com/radareorg/radare2/pull/1426
• HP-PA-RISC: https://github.com/radareorg/radare2/commit/f8384feb6ba019b91229adb8fd6e0314b0656f7b
• V810: https://github.com/radareorg/radare2/pull/2899
• TMS320: https://github.com/radareorg/radare2/pull/596
This is an simple plugin for z80 that you may use as example:
https://github.com/radareorg/radare2/commit/8ff6a92f65331cf8ad74cd0f44a60c258b137a06
At first, to be able to write a plugins in Python for radare2 you need to install r2lang plugin: r2pm -i lang-python. Note - in the following examples there are missing functions of the actual decoding for the sake of readability!
For this you need to do this:
1. import r2lang and from r2lang import R (for constants)
2. Make a function with 2 subfunctions - assemble and disassemble and returning plugin structure - for RAsm plugin
def mycpu(a):
def assemble(s):
return [1, 2, 3, 4]
def disassemble(memview, addr):
try:
opcode = get_opcode(memview) # https://docs.python.org/3/library/stdtypes.html#memoryview
opstr = optbl[opcode][1]
return [4, opstr]
except:
return [4, "unknown"]
3. This structure should contain a pointers to these 2 functions - assemble and disassemble
return {
"name" : "mycpu",
"arch" : "mycpu",
"bits" : 32,
"endian" : R.R_SYS_ENDIAN_LITTLE,
"license" : "GPL",
"desc" : "MYCPU disasm",
"assemble" : assemble,
"disassemble" : disassemble,
}
4. Make a function with 2 subfunctions - set_reg_profile and op and returning plugin structure - for RAnal plugin
def mycpu_anal(a):
def set_reg_profile():
profile = "=PC pc\n" + \
"=SP sp\n" + \
"gpr r0 .32 0 0\n" + \
"gpr r1 .32 4 0\n" + \
"gpr r2 .32 8 0\n" + \
"gpr r3 .32 12 0\n" + \
"gpr r4 .32 16 0\n" + \
"gpr r5 .32 20 0\n" + \
"gpr sp .32 24 0\n" + \
"gpr pc .32 28 0\n"
return profile
def op(memview, pc):
analop = {
"type" : R.R_ANAL_OP_TYPE_NULL,
"cycles" : 0,
"stackop" : 0,
"stackptr" : 0,
"ptr" : -1,
"jump" : -1,
"addr" : 0,
"eob" : False,
"esil" : "",