}
try:
opcode = get_opcode(memview) # https://docs.python.org/3/library/stdtypes.html#memoryview
esilstr = optbl[opcode][2]
if optbl[opcode][0] == "J": # it's jump
analop["type"] = R.R_ANAL_OP_TYPE_JMP
analop["jump"] = decode_jump(opcode, j_mask)
esilstr = jump_esil(esilstr, opcode, j_mask)
except:
result = analop
# Don't forget to return proper instruction size!
return [4, result]
5. This structure should contain a pointers to these 2 functions - set_reg_profile and op
return {
"name" : "mycpu",
"arch" : "mycpu",
"bits" : 32,
"license" : "GPL",
"desc" : "MYCPU anal",
"esil" : 1,
"set_reg_profile" : set_reg_profile,
"op" : op,
}
6. Then register those using r2lang.plugin("asm") and r2lang.plugin("anal") respectively
print("Registering MYCPU disasm plugin...")
print(r2lang.plugin("asm", mycpu))
print("Registering MYCPU analysis plugin...")
print(r2lang.plugin("anal", mycpu_anal))
You can combine everything in one file and load it using -i option:
r2 -I mycpu.py some_file.bin
Or you can load it from the r2 shelclass="underline" #!python mycpu.py
See also:
• 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
2. Make a function with subfunctions:
load
load_bytes
destroy
check_bytes
baddr
entries
sections
imports
relocs
binsym
info
and returning plugin structure - for RAsm plugin
def le_format(a):
def load(binf):
return [0]
def check_bytes(buf):
try:
if buf[0] == 77 and buf[1] == 90:
lx_off, = struct.unpack("<I", buf[0x3c:0x40])
if buf[lx_off] == 76 and buf[lx_off+1] == 88:
return [1]
return [0]
except:
return [0]
and so on. Please be sure of the parameters for each function and format of returns. Note, that functions entries, sections, imports, relocs returns a list of special formed dictionaries - each with a different type. Other functions return just a list of numerical values, even if single element one. There is a special function, which returns information about the file - info:
def info(binf):
return [{
"type" : "le",
"bclass" : "le",
"rclass" : "le",
"os" : "OS/2",
"subsystem" : "CLI",
"machine" : "IBM",
"arch" : "x86",
"has_va" : 0,
"bits" : 32,
"big_endian" : 0,
"dbg_info" : 0,
}]
3. This structure should contain a pointers to the most important functions like check_bytes, load and load_bytes, entries, relocs, imports.
return {
"name" : "le",
"desc" : "OS/2 LE/LX format",
"license" : "GPL",
"load" : load,
"load_bytes" : load_bytes,
"destroy" : destroy,
"check_bytes" : check_bytes,
"baddr" : baddr,
"entries" : entries,
"sections" : sections,
"imports" : imports,
"symbols" : symbols,
"relocs" : relocs,
"binsym" : binsym,
"info" : info,
}
4. Then you need to register it as a file format plugin:
print("Registering OS/2 LE/LX plugin...")
print(r2lang.plugin("bin", le_format))
It is common to have an issues when you write a plugin, especially if you do this for the first time. This is why debugging them is very important. The first step for debugging is to set an environment variable when running radare2 instance:
R_DEBUG=yes r2 /bin/ls
Loading /usr/local/lib/radare2/2.2.0-git//bin_xtr_dyldcache.so
Cannot find symbol 'radare_plugin' in library '/usr/local/lib/radare2/2.2.0-git//bin_xtr_dyldcache.so'
Cannot open /usr/local/lib/radare2/2.2.0-git//2.2.0-git
Loading /home/user/.config/radare2/plugins/asm_mips_ks.so
PLUGIN OK 0x55b205ea6070 fcn 0x7f298de08762
Loading /home/user/.config/radare2/plugins/asm_sparc_ks.so
PLUGIN OK 0x55b205ea6070 fcn 0x7f298de08762
Cannot open /home/user/.config/radare2/plugins/pimp
Cannot open /home/user/.config/radare2/plugins/yara
Loading /home/user/.config/radare2/plugins/asm_arm_ks.so
PLUGIN OK 0x55b205ea6070 fcn 0x7f298de08762
Loading /home/user/.config/radare2/plugins/core_yara.so
Module version mismatch /home/user/.config/radare2/plugins/core_yara.so (2.1.0) vs (2.2.0-git)
Loading /home/user/.config/radare2/plugins/asm_ppc_ks.so
PLUGIN OK 0x55b205ea6070 fcn 0x7f298de08762
Loading /home/user/.config/radare2/plugins/lang_python3.so
PLUGIN OK 0x55b205ea5ed0 fcn 0x7f298de08692
Loading /usr/local/lib/radare2/2.2.0-git/bin_xtr_dyldcache.so
Cannot find symbol 'radare_plugin' in library '/usr/local/lib/radare2/2.2.0-git/bin_xtr_dyldcache.so'
Cannot open /usr/local/lib/radare2/2.2.0-git/2.2.0-git
Cannot open directory '/usr/local/lib/radare2-extras/2.2.0-git'
Cannot open directory '/usr/local/lib/radare2-bindings/2.2.0-git'
USER CONFIG loaded from /home/user/.config/radare2/radare2rc
-- In visual mode press 'c' to toggle the cursor mode. Use tab to navigate
[0x00005520]>
This plugin is used by rasm2 and r2. You can verify that the plugin is properly loaded with this command:
$ rasm2 -L | grep mycpu
_d mycpu My CPU disassembler (LGPL3)
Let's open an empty file using the 'mycpu' arch and write some random code there.
$ r2 -
-- I endians swap
[0x00000000]> e asm.arch=mycpu