Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Python arch plugin #40

Merged
merged 3 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion python/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ CFILES=python.c
ifeq ($(shell pkg-config --max-version 5.8.8 r_core && echo 1),1)
CFILES+=anal.c asm.c bin.c
endif
CFILES+=python/common.c python/core.c python/io.c
CFILES+=python/common.c python/core.c python/io.c python/arch.c
OFILES=$(subst .c,.o,${CFILES})

lang_python.$(EXT_SO): $(OFILES)
Expand Down
92 changes: 92 additions & 0 deletions python/examples/test-py-arch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Example Python Arch plugin written in Python
# ============================================
#
# -- pancake @ nopcode.org
astuder marked this conversation as resolved.
Show resolved Hide resolved
#
# The r2lang.plugin function exposes a way to register new plugins
# into the RCore instance. This API is only available from RLang.
# You must call with with '#!python test.py' or 'r2 -i test.py ..'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better use -I to load earlier

the resr of comments can be removed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied that from the other examples. Would be nice if -a would run after the plugin is loaded, but no difference between -i and -I for that.


import r2lang
from r2lang import R

def pyarch(a):
def regs():
return "=PC pc\n" + \
"=SP sp\n" + \
"=A0 r0\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"

def info(query):
if query == R.R_ARCH_INFO_MINOP_SIZE:
astuder marked this conversation as resolved.
Show resolved Hide resolved
return 1
if query == R.R_ARCH_INFO_MAXOP_SIZE:
return 2
if query == R.R_ARCH_INFO_INVOP_SIZE: # invalid op size
return 1
if query == R.R_ARCH_INFO_CODE_ALIGN:
return 1
if query == R.R_ANAL_INFO_DATA_ALIGN:
return 1
if query == R.R_ANAL_INFO_DATA2_ALIGN:
return 2
if query == R.R_ANAL_INFO_DATA4_ALIGN:
return 4
if query == R.R_ANAL_INFO_DATA8_ALIGN:
return 8
return 0

def decode(buf, pc):
ops = {
0: {
"op": {
"mnemonic" : "nop",
"type" : R.R_ANAL_OP_TYPE_NOP,
"cycles" : 1,
},
"size": 1
},
1: {
"op": {
"mnemonic" : "mov",
"type" : R.R_ANAL_OP_TYPE_MOV,
"cycles" : 2,
},
"size": 3
},
2: {
"op": {
"mnemonic" : "fadd",
"type" : R.R_ANAL_OP_TYPE_ADD,
"cpu_family" : R.R_ANAL_OP_FAMILY_FPU,
"cycles" : 2,
},
"size": 3
}
}
decoded_op = ops.get(buf[0])
if decoded_op is None:
return [ 2, None ]
return [ decoded_op.get("size"), decoded_op.get("op") ]

return {
"name": "MyPyArch",
"arch": "pyarch",
"bits": 32,
"license": "GPL",
"desc": "arch plugin in python",
"regs": regs,
"info": info,
"decode": decode,
}

if not r2lang.plugin("arch", pyarch):
print("Failed to register the python arch plugin.")

7 changes: 7 additions & 0 deletions python/python.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "python/anal.h"
#include "python/asm.h"
#include "python/bin.h"
#else
#include "python/arch.h"
#endif

#define PLUGIN_NAME r_lang_plugin_python
Expand All @@ -28,6 +30,8 @@ static const R2Plugins plugins[] = {
#if R2_VERSION_NUMBER < 50809
{ "anal", &Radare_plugin_anal },
{ "bin", &Radare_plugin_bin },
#else
{ "arch", &Radare_plugin_arch },
#endif
{ "io", &Radare_plugin_io },
{ NULL }
Expand Down Expand Up @@ -234,6 +238,9 @@ static PyObject *init_radare_module(void) {
#endif
#if R2_VERSION_NUMBER < 50800
py_export_asm_enum (RadareType.tp_dict);
#endif
#if R2_VERSION_NUMBER > 50808
py_export_arch_enum (RadareType.tp_dict);
#endif
PyObject *m = PyModule_Create (&EmbModule);
if (!m) {
Expand Down
Loading
Loading