Выбрать главу

}

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

   • Javascript

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