Compare commits

..
1 Commits
Author SHA1 Message Date
pancake 298eb199cc Release 3.2.0 2019-01-08 12:30:11 +01:00
685 changed files with 24131 additions and 649946 deletions

No files matched your search

-6
View File
@@ -1,6 +0,0 @@
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/x86iced"
schedule:
interval: "weekly"
-58
View File
@@ -1,58 +0,0 @@
name: CI
on:
push:
pull_request:
jobs:
build-extras:
name: Build radare2 extras and r2pipe
runs-on: ubuntu-22.04
env:
EXTERNAL_BUILDS: 'keystone-lib unicorn-lib'
LOCAL_BUILDS: 'asahi blackfin blessr2 keystone microblaze mn103 ppcdisasm r2svd vc4 x86iced'
TESTS: 'keystone vc4'
steps:
- uses: actions/checkout@v3
with:
repository: radareorg/radare2
ref: master
path: ./radare2
- uses: radareorg/github-actions@v3
with:
from-git: true
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
path: ./radare2-extras
- name: Init r2pm
run: r2pm -U
- name: Compile and install plugins
run: |
set -e
for p in $EXTERNAL_BUILDS ; do
echo $p
r2pm -i $p
done
R2PM_GITDIR="$(r2pm -H R2PM_GITDIR)"
for p in $LOCAL_BUILDS ; do
echo $p
ln -s "$GITHUB_WORKSPACE/radare2-extras" "$R2PM_GITDIR/$p"
R2PM_OFFLINE=1 r2pm -i $p
done
- name: Test plugins
working-directory: radare2/test
run: |
set -e
for p in $TESTS ; do
echo $p
make $p
done
r2r -u "$GITHUB_WORKSPACE/radare2-extras/test/db/extras/microblaze"
r2r -u "$GITHUB_WORKSPACE/radare2-extras/test/db/extras/ppcdisasm"
r2r -u "$GITHUB_WORKSPACE/radare2-extras/test/db/extras/asm/mn103"
r2r -u "$GITHUB_WORKSPACE/radare2-extras/test/db/extras/mn103"
set +e
-41
View File
@@ -1,41 +0,0 @@
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
schedule:
- cron: "30 16 * * 1"
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ javascript, python ]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{ matrix.language }}"
-6
View File
@@ -17,10 +17,4 @@
*.swo
*.un~
/Makefile
r2yara/Makefile
/options.mk
# misc
tags
node_modules
+118
View File
@@ -0,0 +1,118 @@
dist:
- trusty
sudo:
- false
os:
- linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-7
- llvm-dev
- libatomic-ops-dev
- mono-xbuild
- curl
- make
- tcc
- libboost-dev
- libqt4-dev
- cmake
- cmake-data
- ninja-build
- libboost-dev
- libqt4-dev
- exuberant-ctags
- libelf-dev
- libgmp-dev
- zlib1g-dev
- swig
env:
- TESTS="r2pm -i armthumb"
- TESTS="r2pm -i baleful"
# - TESTS="r2pm -i bcl" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
- TESTS="r2pm -i blackfin"
- TESTS="r2pm -i blessr2"
# - TESTS="r2pm -i bpf" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
# - TESTS="r2pm -i dlang" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
- TESTS="r2pm -i dirtycow"
- TESTS="r2pm -i lang-duktape"
- TESTS="git clone git://git.code.sf.net/p/libdwarf/code libdwarf-code && cd libdwarf-code && ./configure && make && cd .. && r2pm -i dwarf-parser && cd radare2-regressions && ./r2r dwarf && cd .. && r2pm -u libdwarf && rm -rf libdwarf-code" #need to remove libdwarf? or travis destroys the vm so no issue in that?
- TESTS="r2pm -i r2frida"
# - TESTS="r2pm -i io-ewf" # https://github.com/travis-ci/apt-package-whitelist/issues/3205
# - TESTS="r2pm -i keystone-lib && r2pm -i keystone && cd radare2-regressions && make keystone && cd .." [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
- TESTS="r2pm -i mc6809"
- TESTS="r2pm -i microblaze"
- TESTS="r2pm -i msil"
- TESTS="r2pm -i pcap"
- TESTS="r2pm -i ppcdisasm"
- TESTS="r2pm -i psosvm"
- TESTS="r2pm -i pyc"
# - TESTS="r2pm -i vala && r2pm -i valabind && r2pm -i r2api-python" [BR] https://travis-ci.org/radare/radare2-extras/builds/387043680
# - TESTS="r2pm -i r2pipe-cs" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
# - TESTS="r2pm -i r2pipe-go" [BR] https://travis-ci.org/radare/radare2-extras/builds/387043680
- TESTS="r2pm -i r2pipe-js"
- TESTS="r2pm -i r2pipe-py"
- TESTS="r2pm -i r2pipe-rb"
# - TESTS="r2pm -i r2pipe-vala" https://travis-ci.org/radare/radare2-extras/builds/157522362
- TESTS="r2pm -i radare2"
# - TESTS="r2pm -i r2snow" https://travis-ci.org/radare/radare2-extras/jobs/199500082
# - TESTS="r2pm -i radeco" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
- TESTS="r2pm -i retdec"
- TESTS="r2pm -i swf && cd radare2-regressions && make swf && cd .."
# - TESTS="r2pm -i m68k-net && cd radare2-regressions && make m68k-extras && cd .." [BR] https://travis-ci.org/radare/radare2-extras/builds/387043680
# - TESTS="r2pm -i swig" Sorry. This package cannot be installed in your home.
- TESTS="r2pm -i syms2elf"
# - TESTS="r2pm -i tcc" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
- TESTS="r2pm -i unicorn-lib && r2pm -i unicorn" # need to do this properly
- TESTS="r2pm -i vala"
# - TESTS="r2pm -i valabind" [BR] https://travis-ci.org/radare/radare2-extras/builds/387043680
# - TESTS="r2pm -i vapi" [BR] https://travis-ci.org/radare/radare2-extras/builds/387043680
- TESTS="r2pm -i vc4"
- TESTS="r2pm -i winapi"
- TESTS="r2pm -i www-enyo"
# - TESTS="r2pm -i www-m" [BR] https://travis-ci.org/radare/radare2-extras/builds/157522362
- TESTS="r2pm -i www-p"
- TESTS="r2pm -i www-t"
- TESTS="r2pm -i x86udis"
- TESTS="r2pm -i x86bea"
- TESTS="r2pm -i x86tab"
- TESTS="r2pm -i x86olly && cd radare2-regressions && make olly-extras && cd .."
- TESTS="r2pm -i z80-nc"
- TESTS="r2pm -i yara && r2pm -i yara-r2"
- TESTS="r2pm -i x86zyan"
language:
- rust
rust:
- stable
cache:
- ccache
- apt
before_script:
- export WORKING_DIR=${TRAVIS_BUILD_DIR}/..
- cd ${WORKING_DIR}
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install 7
- git clone https://github.com/radare/radare2-regressions
- git clone https://github.com/radare/radare2 && cd radare2
- export CC=gcc-7
- ./configure --prefix=${WORKING_DIR}/install > /dev/null
- make -s -j2 > /dev/null
- make install > /dev/null
- cd ..
- export PATH=${WORKING_DIR}/install/bin:${PATH}
- export LD_LIBRARY_PATH=${WORKING_DIR}/install/lib:${LD_LIBRARY_PATH}
- export LIBR_INCLUDE=${WORKING_DIR}/radare2/libr/include
- export LIBR_UTIL=${WORKING_DIR}/radare2/libr/util
- export PKG_CONFIG_PATH=${WORKING_DIR}/radare2/pkgcfg
- export GOPATH=${WORKING_DIR}/
- r2pm init
- export R2PM_GITDIR=${WORKING_DIR}
- cd radare2-extras
- ./configure --prefix=${WORKING_DIR}/install
- cd ..
script:
- eval $TESTS
+2 -6
View File
@@ -12,10 +12,9 @@ DIRS+=libr/anal/p
endif
help:
@echo "Usage make [target] .. Targets:"
@echo "Usage make [target] .. Targets:"
@echo " all - build everything"
@echo " baleful - build baleful r2 plugin"
@echo " afen - build afen r2 plugin"
@echo " asm - build armthumb, ppc, psosvm, x86bea, m68k plugins"
@echo " io - build io plugins"
@echo " anal - build analysis plugins (RAnal)"
@@ -25,10 +24,9 @@ help:
@echo " (target)-install - install given plugin"
@echo " (target)-clean - clean given plugin"
# @echo " install-yara{2,3} - install Yara 2 or 3 from Git"
afen:
$(MAKE) -C afen
baleful:
$(MAKE) -C baleful
debug unicorn:
@@ -56,8 +54,6 @@ yara:
$(MAKE) -C yara/$@
yara-clean:
$(MAKE) -C yara/yara clean
afen-install:
$(MAKE) -C afen install DESTDIR=$(DESTDIR)
baleful-install:
$(MAKE) -C baleful install DESTDIR=$(DESTDIR)
debug-install unicorn-install:
+13 -15
View File
@@ -1,8 +1,5 @@
# radare2-extras
[![GithubCI Status](https://github.com/radareorg/radare2-extras/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/radareorg/radare2-extras/actions?query=workflow%3A%22ci%22)
[![radare2](https://img.shields.io/badge/radare2-6.0.4-green)](https://github.com/radareorg/radare2)
radare2-extras [![Build Status](https://travis-ci.org/radare/radare2-extras.svg?branch=master)](https://travis-ci.org/radare/radare2-extras)
==============
This repository contains extra plugins for radare2.
The reasons why those plugins are distributed in a separate
@@ -15,6 +12,13 @@ repository are the following:
* Duplicates functionality from r2 (no need to have
multiple disassemblers for the same arch in core)
The compiled plugins will be installed at
/usr/lib/radare2-extras/$(VERSION)
Some of the plugins/code doesnt compiles, it will be reviewed
and cleaned up, merged into core, updated or removed.
In addition, this repository will be useful to new contributors,
comers who want to write his own r2 plugins for example.
@@ -23,16 +27,10 @@ repository to be as concise as possible, and reduce the
amount of unnecessary plugins to shrink the install size and
keep it usable for 99% of users.
## Building
Building
========
The recommended way to build and install those plugins for users
is to use r2pm. See the [radare2 plugins](https://github.com/radareorg/radare2#plugins) documentation for details.
is to use r2pm. See the radare2-pm repository for details:
## Notable plugins
* [`msl`](msl/) — Memory Slice (`.msl`) support: open/emulate process memory
dumps (`io`/`bin`/`debug` plugins, with ESIL reverse execution) and produce
them from a live debug session (`dgm`/`dgma`, `core` plugin).
* [`r2gg`](r2gg/) — Game Gear emulation through Z80 ESIL, with color terminal
display, controls, Sega cartridge banking, interrupts, and stereo PSG audio.
https://github.com/radare/radare2-pm
-22
View File
@@ -1,22 +0,0 @@
LIBEXT=$(shell r2 -HR2_LIBEXT)
CFLAGS+=$(shell pkg-config --cflags r_core)
LDFLAGS+=$(shell pkg-config --libs r_core)
R2_USER_PLUGINS=$(shell r2 -HR2_USER_PLUGINS)
CORE_AFEN=src/libcoreafen.$(LIBEXT)
OBJS=src/main.o
all: $(CORE_AFEN)
$(CORE_AFEN): $(OBJS)
r2pm -r $(CC) $(LDFLAGS) -shared -fPIC -o $(CORE_AFEN) $(OBJS)
clean:
rm -f $(OBJS) $(CORE_AFEN)
user-install install:
mkdir -p $(R2_USER_PLUGINS)
cp -f $(CORE_AFEN) $(R2_USER_PLUGINS)
user-uninstall uninstall:
rm -f $(R2_USER_PLUGINS)/$(CORE_AFEN)
-30
View File
@@ -1,30 +0,0 @@
# afen plugin
Author: satk0
NOTE: Making this plugin would not be possible without the help from pancake. Big thanks to him!
Radare2 plugin to rename expressions
This plugin should register a new `afen` command that should rename any expression
to any text, thus enabling a creation of variables from expressions.
## Building and installing the plugin:
Build:
r2pm -r meson setup build
Install:
meson install -C build
## Run:
r2 -e asm.parser=afen -e asm.pseudo=true <file>
## Usage:
For instance, to rename `rbp + rax - 0x1020` expression to `cwd[i]`, you could use the following command:
afen cmd[i] "rbp + rax - 0x1020"
-12
View File
@@ -1,12 +0,0 @@
project('r2-afen', 'c', license : 'MIT', meson_version : '>=1.00', version : '0.1.0')
r2_plugdir = run_command('r2', '-H', 'R2_USER_PLUGINS', check: true).stdout().strip()
sources = [ 'src/main.c' ]
lib = library('coreafen', sources,
dependencies : [
dependency('r_core')
],
install_dir: r2_plugdir,
install: true
)
-269
View File
@@ -1,269 +0,0 @@
/* radare - Copyright 2024 - satk0 */
#define R_LOG_ORIGIN "core.afen"
#include <r_core.h>
typedef struct RAfenRepl {
char *old_name;
char *new_name;
} RAfenRepl;
#if R2_VERSION_NUMBER >= 50909
#else
static R_TH_LOCAL HtUP *ht; // hash table
#endif
#if R2_VERSION_NUMBER >= 50909
static void fini(RAsmPluginSession *aps) {
RParse *p = aps->rasm->parse;
R_FREE (p->retleave_asm);
}
#endif
static char *parse(RCore *core, const char *data, HtUP *ht) {
char *out = strdup (data);
#if R2_VERSION_NUMBER >= 50909
RAnalFunction *fcn = r_anal_get_function_at (core->anal, core->addr);
#else
RAnalFunction *fcn = r_anal_get_function_at (core->anal, core->offset);
#endif
if (fcn) {
RVector *vec = ht_up_find (ht, fcn->addr, NULL);
if (vec) {
RAfenRepl *repl;
r_vector_foreach (vec, repl) {
out = r_str_replace_all (out, repl->old_name, repl->new_name);
}
}
}
return out;
}
// afen parser
#if R2_VERSION_NUMBER >= 50909
static char *r_parse_afen(RAsmPluginSession *aps, const char *data) {
char* out = parse ((RCore *) aps->rasm->user, data, aps->data);
return out;
}
#else
static int r_parse_afen(RParse *p, const char *data, char *str) {
char* out = parse ((RCore *) p->analb.anal->user, data, ht);
strcpy (str, out);
return true;
}
#endif
// RParse plugin Definition Info
#if R2_VERSION_NUMBER >= 50909
RAsmPlugin r_parse_plugin_afen = {
.meta = {
.name = "afen",
.desc = "Afen parse plugin",
},
.parse = r_parse_afen,
.fini = fini,
// .subvar = subvar,
};
#else
RParsePlugin r_parse_plugin_afen = {
.name = "afen",
.desc = "Afen parse plugin",
.parse = r_parse_afen,
};
#endif
static inline void repl_free_afen(void *e, void *user ) {
RAfenRepl *repl = (RAfenRepl *) e;
if (repl) {
R_FREE (repl->old_name);
R_FREE (repl->new_name);
}
}
static inline void vector_value_free_afen(HtUPKv *kv) {
RVector *vec = (RVector *) kv->value;
if (vec) {
r_vector_free (vec);
}
}
static bool print_afen_rules(void *user, const ut64 key, const void *value) {
RCore *core = (RCore *) user;
RVector *vec = (RVector *) value;
RAfenRepl *repl;
r_vector_foreach (vec, repl) {
r_cons_printf (core->cons, "'@0x%08"PFMT64x"'afen \"%s\" \"%s\"\n", key, repl->new_name, repl->old_name);
}
return true;
}
// setup afen parser
#if R2_VERSION_NUMBER >= 50909
static bool r_core_init_afen(RCorePluginSession *cps) {
RCore *core = (RCore *) cps->core;
r_asm_plugin_add (core->rasm, &r_parse_plugin_afen);
RAsmPluginSession *afen_aps = NULL;
RListIter *iter;
RAsmPluginSession *aps;
r_list_foreach (core->rasm->sessions, iter, aps) {
if (aps && aps->plugin && aps->plugin->meta.name &&
!strcmp(aps->plugin->meta.name, "afen")) {
afen_aps = aps;
break;
}
}
if (!afen_aps) {
R_LOG_ERROR ("Failed to find afen plugin session");
return false;
}
HtUP /*<ut64, RVector<RAfenRepl*>>*/ *ht = ht_up_new (NULL, vector_value_free_afen, NULL);
if (!ht) {
R_LOG_ERROR ("Fail to initialize hashtable");
ht_up_free (ht);
return false;
}
afen_aps->data = ht;
cps->data = ht;
return true;
}
#else
static bool r_core_init_afen(void *user, const char *input) {
RCmd *rcmd = (RCmd *) user;
RCore *core = (RCore *) rcmd->data;
r_parse_plugin_add (core->parser, &r_parse_plugin_afen);
/*<ut64, RVector<RAfenRepl*>>*/ ht = ht_up_new (NULL, vector_value_free_afen, NULL);
if (!ht) {
R_LOG_ERROR ("Fail to initialize hashtable");
ht_up_free (ht);
return false;
}
return true;
}
#endif
#if R2_VERSION_NUMBER >= 50909
static bool r_core_fini_afen(RCorePluginSession *cps) {
HtUP *ht = cps->data;
ht_up_free (ht);
ht = NULL;
return true;
}
#else
static bool r_core_fini_afen(void *user, const char *input) {
ht_up_free (ht);
ht = NULL;
return true;
}
#endif
static bool check_for_afen_command(RCore *core, const char *input, HtUP *ht) {
if (r_str_startswith (input, "afen*")) {
ht_up_foreach(ht, print_afen_rules, core);
return true;
} else if (r_str_startswith (input, "afen")) {
int argc = 0;
char **argv = r_str_argv (input, &argc);
if (!argv || argc != 3) {
R_LOG_INFO ("Usage: afen new_name old_name");
r_str_argv_free (argv);
return true;
}
#if R2_VERSION_NUMBER >= 50909
RAnalFunction *fcn = r_anal_get_function_at (core->anal, core->addr);
#else
RAnalFunction *fcn = r_anal_get_function_at (core->anal, core->offset);
#endif
if (!fcn) {
#if R2_VERSION_NUMBER >= 50909
R_LOG_ERROR ("No Function at 0x%08" PFMT64x, core->addr);
#else
R_LOG_ERROR ("No Function at 0x%08" PFMT64x, core->offset);
#endif
R_LOG_INFO ("Use afen inside a function!");
r_str_argv_free (argv);
return false;
}
RVector *vec = ht_up_find (ht, fcn->addr, NULL);
if (!vec) {
vec = r_vector_new (sizeof (RAfenRepl), repl_free_afen, NULL);
ht_up_insert (ht, fcn->addr, vec);
}
bool updated = false;
RAfenRepl *repl;
r_vector_foreach (vec, repl) {
if (repl->old_name && argv[2] && !strcmp (repl->old_name, argv[2])) {
if (repl->new_name) {
R_FREE (repl->new_name);
}
repl->new_name = strdup (argv[1]);
updated = true;
break;
}
}
if (updated) {
r_str_argv_free (argv);
return true;
}
repl = R_NEW0 (RAfenRepl);
repl->new_name = strdup (argv[1]);
repl->old_name = strdup (argv[2]);
r_vector_push (vec, repl);
r_str_argv_free (argv);
return true;
}
return false;
}
#if R2_VERSION_NUMBER >= 50909
static bool r_core_call_afen(RCorePluginSession *cps, const char *input) {
return check_for_afen_command(cps->core, input, cps->data);
}
#else
static bool r_core_call_afen(void *user, const char *input) {
return check_for_afen_command((RCore *) user, input, ht);
}
#endif
// RCore plugin Definition Info
RCorePlugin r_core_plugin_afen = {
.meta = {
.name = "core-afen",
.desc = "Rename expressions",
.author = "satk0",
.license = "GPLv3",
},
.call = r_core_call_afen,
.init = r_core_init_afen,
.fini = r_core_fini_afen
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_CORE,
.data = &r_core_plugin_afen,
.version = R2_VERSION,
#if R2_VERSION_NUMBER >= 50909
.abiversion = R2_ABIVERSION,
#endif
};
#endif
-22
View File
@@ -1,22 +0,0 @@
R2_LIBEXT=$(shell r2 -H R2_LIBEXT)
R2_USER_PLUGINS=$(shell r2 -H R2_USER_PLUGINS)
CFLAGS+=$(shell pkg-config --cflags r_core)
LDFLAGS+=$(shell pkg-config --libs r_core)
CFLAGS+=-Igpu/wrap
all: gpu
$(CC) $(CFLAGS) $(LDFLAGS) -shared -fPIC arch_asahi.c -o arch_asahi.$(R2_LIBEXT)
mrproper clean:
rm -f *.$(R2_LIBEXT)
gpu:
git clone https://github.com/AsahiLinux/gpu
install:
mkdir -p "$(R2_USER_PLUGINS)"
cp -f arch_asahi.$(R2_LIBEXT) $(R2_USER_PLUGINS)
uninstall:
rm -f $(R2_USER_PLUGINS)/arch_asahi.$(R2_LIBEXT)
-14
View File
@@ -1,14 +0,0 @@
ASAHI
=====
This is the r2 disassembler plugin for
the ASAHI GPU shipped in the Apple M1.
This plugin is just a shim on top of [AsahiLinux](https://github.com/AsahiLinux/gpu)
Installation
------------
* Install r2 from git and then type `make; make install`
Alternatively you can just `r2pm -ci asahi`
-40
View File
@@ -1,40 +0,0 @@
/* radare2 - GPL3 - Copyright 2021-2023 - pancake */
#include <r_lib.h>
#include <r_arch.h>
#include "gpu/disasm/disasm.c"
static bool decode(RArchSession *as, RAnalOp *op, RAnalOpMask mask) {
char out[128];
FILE *fp = fmemopen (out, sizeof (out), "w");
*out = 0;
bool stop = false;
int res = agx_disassemble_instr ((uint8_t*)op->bytes, &stop, false, fp);
fclose (fp);
r_str_replace_char (out, '\n', ' ');
free (op->mnemonic);
op->mnemonic = r_str_trim_dup (out);
op->size = res;
return op->size;
}
static RArchPlugin r_arch_plugin_asahi = {
.meta = {
.name = "asahi",
.license = "MIT",
.desc = "Asahi: Apple's M1 GPU",
},
.arch = "asahi",
.bits = 32,
.decode = &decode,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ARCH,
.data = &r_arch_plugin_asahi,
.version = R2_VERSION
};
#endif
+1 -30
View File
@@ -5,39 +5,10 @@
# git clone https://github.com/radare/acr
#
# -- pancake
#!/bin/sh
#
# Look for the 'acr' tool here: https://github.com/radare/acr
# Clone last version of ACR from here:
# git clone https://github.com/radare/acr
#
# -- pancake
r2pm -h >/dev/null 2>&1
if [ $? = 0 ]; then
echo "Installing the last version of 'acr'..."
r2pm -i acr > /dev/null
r2pm -r acr -h > /dev/null 2>&1
if [ $? = 0 ]; then
echo "Running 'acr -p'..."
r2pm -r acr -p
else
echo "Cannot find 'acr' in PATH"
fi
else
echo "Running acr..."
acr -p
fi
V=`./configure -qV | cut -d - -f -1`
if [ -n "$1" ]; then
echo "./configure $*"
./configure $*
fi
files=`find . -name configure.acr`
for a in ${files}; do
echo "[+] $a"
( cd `dirname $a` ; r2pm -r acr -p )
( cd `dirname $a` ; acr -p )
done
if [ -n "$1" ]; then
echo "./configure $@"
+33 -17
View File
@@ -4,33 +4,30 @@
#include <r_types.h>
#include <r_lib.h>
#include <r_asm.h>
// #include <r_arch.h>
#include <r_anal.h>
#include <stdio.h>
#include <fcntl.h>
static int ptsHandle = 0;
static int ptsHandle=0;
static bool reg_read(RAnalEsil *esil, const char *regname, ut64 *num) {
static int reg_read(RAnalEsil *esil, const char *regname, ut64 *num) {
RRegItem *reg = r_reg_get (esil->anal->reg, regname, -1);
if (reg) {
if (num) {
if (num)
*num = r_reg_get_value (esil->anal->reg, reg);
}
return true;
return 1;
}
return false;
return 0;
}
static bool reg_write(RAnalEsil *esil, const char *regname, ut64 num) {
static int reg_write(RAnalEsil *esil, const char *regname, ut64 num) {
RRegItem *reg = r_reg_get (esil->anal->reg, regname, -1);
if (reg) {
if (num) {
if (num)
r_reg_set_value (esil->anal->reg, reg,num);
}
return true;
return 1;
}
return false;
return 0;
}
/*
@@ -547,9 +544,31 @@ static int esil_baleful_intr (RAnalEsil *esil, int intr) {
}
static bool esil_bale_interrupt_wrapper_cb (RAnalEsil *esil, ut32 interrupt, void *user) { //user is always NULL, bc we has no init and fini
return !!esil_baleful_intr (esil, interrupt);
return !!esil_baleful_intr(esil, interrupt);
}
RAnalEsilInterruptHandler bale_intr_handler00 = {
.num = 0x00, //interrupt number
.cb = esil_bale_interrupt_wrapper_cb, //the actual handler
};
RAnalEsilInterruptHandler bale_intr_handler04 = {
.num = 0x04, //interrupt number
.cb = esil_bale_interrupt_wrapper_cb, //the actual handler
};
RAnalEsilInterruptHandler bale_intr_handler11 = {
.num = 0x11, //interrupt number
.cb = esil_bale_interrupt_wrapper_cb, //the actual handler
};
RAnalEsilInterruptHandler *bale_intr_handlers[] = {
&bale_intr_handler00,
&bale_intr_handler04,
&bale_intr_handler11,
NULL,
};
static int set_reg_profile(RAnal *anal) {
const char *p = \
"=PC pc\n"
@@ -608,10 +627,7 @@ static int esil_baleful_init (RAnalEsil *esil) {
if (!esil) {
return false;
}
r_anal_esil_set_interrupt(esil,0,esil_bale_interrupt_wrapper_cb, NULL);
r_anal_esil_set_interrupt(esil,4,esil_bale_interrupt_wrapper_cb, NULL);
r_anal_esil_set_interrupt(esil,11,esil_bale_interrupt_wrapper_cb, NULL);
return true;
return r_anal_esil_load_interrupts (esil, bale_intr_handlers, 0);
/*
internalMemory=malloc(4096);
if (!internalMemory) {
+4 -4
View File
@@ -37,7 +37,7 @@ static int findpair(ut64 addr, const ut8 *buf, int len, int base) {
return 0;
}
static int bcl_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
static int bcl_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
int i;
char cache[256] = {0};
ut64 dst = 0LL;
@@ -76,7 +76,7 @@ static int bcl_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
return op->size;
}
static bool set_reg_profile(RAnal *anal) {
static int set_reg_profile(RAnal *anal) {
const char *p = \
"=PC pc\n"
"=SP sp\n"
@@ -93,7 +93,7 @@ static bool set_reg_profile(RAnal *anal) {
return r_reg_set_profile_string (anal->reg, p);
}
RAnalPlugin r_anal_plugin_bcl = {
struct r_anal_plugin_t r_anal_plugin_bcl = {
.name = "bcl",
.desc = "Base Call DNA Illumina records",
.license = "BSD",
@@ -101,7 +101,7 @@ RAnalPlugin r_anal_plugin_bcl = {
.bits = 8,
.esil = true,
.op = &bcl_op,
.set_reg_profile = &set_reg_profile
.set_reg_profile = set_reg_profile,
};
#ifndef CORELIB
+3 -6
View File
@@ -9,23 +9,21 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
const char *bases = "ACGT";
if (a->pc == 0) {
ut32 *clusters = (ut32*)buf;
r_strbuf_setf (&op->buf_asm, "clusters %d", *clusters);
// snprintf (op->buf_asm, sizeof (op->buf_asm), "clusters %d\n", *clusters);
snprintf (op->buf_asm, sizeof (op->buf_asm), "clusters %d\n", *clusters);
return op->size = 4;
}
if (*buf != 0) {
char base = bases[*buf & 3];
int qual = *buf >> 2;
r_strbuf_setf (&op->buf_asm, "%c ; %d", base, qual);
snprintf (op->buf_asm, sizeof (op->buf_asm), "%c ; %d", base, qual);
op->size = 1;
return 1;
}
r_strbuf_setf (&op->buf_asm, ".");
strcpy (op->buf_asm, ".");
return 0;
}
static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
#if 0
bool qmode = false;
int quality = 0;
int outsz = 128;
@@ -78,7 +76,6 @@ static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
out[op->size] = (quality<<2) | base;
op->size ++;
}
#endif
return op->size;
}
+90 -65
View File
@@ -5,11 +5,8 @@
#include <r_lib.h>
#include <r_bin.h>
static bool __check_buffer(RBinFile *bf, RBuffer *b) {
ut8 buf[8];
int length = r_buf_size (b);
int r = r_buf_read_at (b, 0, buf, sizeof (buf));
if (r == sizeof (buf)) {
static int check_bytes(const ut8 *buf, ut64 length) {
if (buf && length >= 4) {
ut32 cls = r_mem_get_num (buf, 4);
ut32 cls2 = r_mem_get_num (buf + 4, 4);
if (cls + 4 == length && !cls2) {
@@ -19,49 +16,64 @@ static bool __check_buffer(RBinFile *bf, RBuffer *b) {
return false;
}
static bool load_buffer(RBinFile *bf, void **bin_obj, RBuffer *buf, ut64 loadaddr, Sdb *sdb) {
return __check_buffer (bf, buf);
static int check(RBinFile *arch) {
const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL;
ut64 sz = arch ? r_buf_size (arch->buf): 0;
return check_bytes (bytes, sz);
}
static ut64 baddr(RBinFile *bf) {
static Sdb* get_sdb (RBinObject *o) {
if (!o) return NULL;
//struct r_bin_[NAME]_obj_t *bin = (struct r_bin_r_bin_[NAME]_obj_t *) o->bin_obj;
//if (bin->kv) return kv;
return NULL;
}
static void * load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
return (void*)(size_t)check_bytes (buf, sz);
}
static int load(RBinFile *arch) {
return check(arch);
}
static int destroy (RBinFile *arch) {
return true;
}
static ut64 baddr(RBinFile *arch) {
return 4;
}
static RBinAddr* binsym(RBinFile *bf, int type) {
static RBinAddr* binsym(RBinFile *arch, int type) {
return NULL; // TODO
}
static ut64 findEntry(RBuffer *buf, int n) {
ut8 b;
ut64 buf_size = r_buf_size (buf);
int i;
for (i = 4; i < buf_size; i++) {
if (r_buf_read_at (buf, i, &b, 1) != 1) {
break;
}
if (b != 0) {
for (i=4;i<buf->length; i++) {
if (buf->buf[i] != 0) {
if (n == 0) {
return i;
}
n--;
for (++i; i < buf_size && b; i++) {
if (r_buf_read_at (buf, i, &b, 1) != 1) {
for (++i; i<buf->length; i++) {
if (!buf->buf[i])
break;
}
}
}
}
return 0;
}
static RList* entries(RBinFile *bf) {
static RList* entries(RBinFile *arch) {
RList* ret = r_list_newf (free);
RBinAddr *ptr = NULL;
if (ret) {
if ((ptr = R_NEW0 (RBinAddr))) {
ut64 entry = findEntry (bf->buf, 2);
if (!entry) entry = findEntry (bf->buf, 1);
if (!entry) entry = findEntry (bf->buf, 0);
ut64 entry = findEntry (arch->buf, 2);
if (!entry) entry = findEntry (arch->buf, 1);
if (!entry) entry = findEntry (arch->buf, 0);
if (!entry) entry = 4;
ptr->paddr = entry;
ptr->vaddr = entry;
@@ -74,74 +86,79 @@ static RList* entries(RBinFile *bf) {
return ret;
}
static RList* sections(RBinFile *bf) {
static RList* sections(RBinFile *arch) {
RList *ret = NULL;
RBinSection *ptr = NULL;
ut64 textsize, datasize, symssize, spszsize, pcszsize;
ut64 entry0 = findEntry (bf->buf, 0);
ut64 entry1 = findEntry (bf->buf, 1);
ut64 entry2 = findEntry (bf->buf, 2);
ut64 entry0 = findEntry (arch->buf, 0);
ut64 entry1 = findEntry (arch->buf, 1);
ut64 entry2 = findEntry (arch->buf, 2);
if (!(ret = r_list_newf (free))) {
return NULL;
}
// add text segment
ut8 str[4] = {0};
r_buf_read_at (bf->buf, 4, str, 4);
textsize = r_mem_get_num (str, 4);
textsize = r_mem_get_num (arch->buf->buf + 4, 4);
if (!(ptr = R_NEW0 (RBinSection))) {
return ret;
}
if (!entry1) {
entry1 = r_buf_size (bf->buf);
entry1 = arch->buf->length;
}
ptr->name = strdup ("init");
ptr->size = entry1 - entry0;
ptr->vsize = entry1 - entry0;
strncpy (ptr->name, "init", R_BIN_SIZEOF_STRINGS);
ptr->size = entry1-entry0;
ptr->vsize = entry1-entry0;
ptr->paddr = entry0 + 4;
ptr->vaddr = entry0;
ptr->add = true;
ptr->perm = R_PERM_RX;
ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; // r-x
r_list_append (ret, ptr);
if (entry1) {
if (entry2) {
if (!(ptr = R_NEW0 (RBinSection))) {
if (!(ptr = R_NEW0 (RBinSection)))
return ret;
}
ptr->name = strdup ("fini");
ptr->size = entry2 - entry1;
ptr->vsize = entry2 - entry1;
strncpy (ptr->name, "fini", R_BIN_SIZEOF_STRINGS);
ptr->size = entry2-entry1;
ptr->vsize = entry2-entry1;
ptr->paddr = entry1 + 4;
ptr->vaddr = entry1;
ptr->perm = R_PERM_RX;
ptr->add = true;
ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; // r-x
r_list_append (ret, ptr);
} else {
entry2 = entry1;
}
}
if (entry2) {
if (!(ptr = R_NEW0 (RBinSection))) {
if (!(ptr = R_NEW0 (RBinSection)))
return ret;
}
ptr->name = strdup ("text");
ut64 filesize = r_buf_size (bf->buf);
ptr->size = filesize - entry2;
ptr->vsize = filesize - entry2;
strncpy (ptr->name, "text", R_BIN_SIZEOF_STRINGS);
ptr->size = arch->buf->length - entry2;
ptr->vsize = arch->buf->length - entry2;
ptr->paddr = entry2 + 4;
ptr->vaddr = entry2;
ptr->perm = R_PERM_RX;
ptr->add = true;
ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; // r-x
r_list_append (ret, ptr);
}
return ret;
}
static RBinInfo* info(RBinFile *bf) {
static RList* symbols(RBinFile *arch) {
// TODO: parse symbol table
return NULL;
}
static RList* imports(RBinFile *arch) {
return NULL;
}
static RList* libs(RBinFile *arch) {
return NULL;
}
static RBinInfo* info(RBinFile *arch) {
RBinInfo *ret = R_NEW0 (RBinInfo);
if (ret) {
ret->file = strdup (bf->file);
ret->file = strdup (arch->file);
ret->bclass = strdup ("dna");
ret->rclass = strdup ("bcl");
ret->os = strdup ("Illumina DNA Sequences");
@@ -157,17 +174,18 @@ static RBinInfo* info(RBinFile *bf) {
return ret;
}
static ut64 size(RBinFile *bf) {
if (!bf->o->info) {
bf->o->info = info (bf);
static ut64 size(RBinFile *arch) {
ut64 text, data, syms, spsz;
int big_endian;
if (!arch->o->info) {
arch->o->info = info (arch);
}
ut8 str[32] = {0};
r_buf_read_at (bf->buf, 0, str, 32);
big_endian = arch->o->info->big_endian;
// TODO: reuse section list
ut64 text = r_mem_get_num (str + 4, 4);
ut64 data = r_mem_get_num (str + 8, 4);
ut64 syms = r_mem_get_num (str + 16, 4);
ut64 spsz = r_mem_get_num (str + 24, 4);
text = r_mem_get_num (arch->buf->buf + 4, 4);
data = r_mem_get_num (arch->buf->buf + 8, 4);
syms = r_mem_get_num (arch->buf->buf + 16, 4);
spsz = r_mem_get_num (arch->buf->buf + 24, 4);
return text + data + syms + spsz + (6 * 4);
}
@@ -175,18 +193,25 @@ RBinPlugin r_bin_plugin_bcl = {
.name = "bcl",
.desc = "Base Call DNA Illumina",
.license = "BSD",
.load_buffer = &load_buffer,
.check_buffer = &__check_buffer,
.get_sdb = &get_sdb,
.load = &load,
.load_bytes = &load_bytes,
.size = &size,
.destroy = &destroy,
.check = &check,
.check_bytes = &check_bytes,
.baddr = &baddr,
.binsym = &binsym,
.entries = &entries,
.sections = &sections,
.symbols = &symbols,
.imports = &imports,
.info = &info,
.libs = &libs,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_BIN,
.data = &r_bin_plugin_bcl,
.version = R2_VERSION
+2 -2
View File
@@ -5,7 +5,7 @@
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/radareorg/radare2-bindings.git"
"url": "https://github.com/radare/radare2-bindings.git"
},
"keywords": [
"radare",
@@ -24,7 +24,7 @@
},
"license": "LGPL-3.0",
"bugs": {
"url": "https://github.com/radareorg/radare2-extras/issues"
"url": "https://github.com/radare/radare2-extras/issues"
},
"homepage": "http://www.radare.org",
"devDependencies": {
+31
View File
@@ -0,0 +1,31 @@
R2_PLUGIN_PATH=$(shell r2 -hh|grep LIBR_PLUGINS|awk '{print $$2}')
R2_INCLUDE_PATH=$(shell r2 -hh|grep INCDIR|awk '{print $$2}')
R2_LIB_PATH=$(shell r2 -hh|grep LIBDIR|awk '{print $$2}')
CFLAGS=-g -fPIC
CFLAGS+=-I$(R2_INCLUDE_PATH)
SUDO=sudo
LDFLAGS=-shared -L$(R2_LIB_PATH) -lr_util -lr_parse -lr_syscall
EXT_SO=$(shell r2 -hh|grep LIBEXT|awk '{print $$2}')
CC_ASM=$(CC) $(CFLAGS) $(LDFLAGS) $(shell pkg-config --libs r_asm)
CC_ANA=$(CC) $(CFLAGS) $(LDFLAGS) $(shell pkg-config --libs r_anal)
CC_BIN=$(CC) $(CFLAGS) $(LDFLAGS) $(shell pkg-config --libs r_bin) -lr_magic
CC_COR=$(CC) $(CFLAGS) $(LDFLAGS) $(shell pkg-config --libs r_core)
all:
$(CC_ASM) -o asm_bpf.$(EXT_SO) asm_bpf.c
$(CC_ANA) -o anal_bpf.$(EXT_SO) anal_bpf.c
$(CC_BIN) -o bin_bpf.$(EXT_SO) bin_bpf.c
# $(CC_COR) -o bpf_core.$(EXT_SO) bpf_core.c
install: all
$(SUDO) cp -f *.$(EXT_SO) $(R2_PLUGIN_PATH)
uninstall:
for a in *.$(EXT_SO) ; do rm -f $(R2_PLUGIN_PATH)/$$a ; done
clean:
rm -f *.$(EXT_SO)
rm -rf *.$(EXT_SO).dSYM
+54
View File
@@ -0,0 +1,54 @@
#BPF architecture for radare2
This is meant to add support for Berkeley Packet Filter in radare2, with full [ESIL](https://radare.gitbooks.io/radare2book/content/esil.html) emulation. The main purpose is to ease the analysis of existing filters encountered in reverse engineering, but can also aid filter development through ESIL emulation.
## Components
It is composed by three plugins:
* **asm_bpf** is the disassembler, i'm planning to add also assembler functionality, but for now it's only disassembler - it is mostly ripped from bpf_dbg.c in the Linux kernel
* **anal_bpf** this is the major contribution of this package, i.e. the analysis plugin which translates everything to ESIL and permits to emulate it completely
* **bin_bpf** is a placeholder, not sure if it's useful at all since there isn't a specific file format - i'm using it just to remember that data is represented big endian by enforcing this information
## Installing using r2pm
This plugin is available in latest r2pm, therefore can be installed simply by:
```
r2pm -i bpf
```
## Building manually
In unix system (tested on mac, but should work in Linux or *BSD out of the box) it should be as easy as doing:
```bash
make install
```
There are two known warnings:
* be sure to have the latest [radare2 from git](https://github.com/radare/radare2)
* on mac systems radare2 should be installed with sys/install.sh (and not sys/user.sh) because the Makefile relies on a properly working `pkg-config`
## Example
The provided [bpf.bin](bpf.bin) is ripped from the [berkeley crackme](http://crackmes.de/users/kwisatz_haderach/berkeley/), here is an example session:
[![asciicast](https://asciinema.org/a/1q8oq25bjpp00aut5v5sd4sez.png)](https://asciinema.org/a/1q8oq25bjpp00aut5v5sd4sez)
Moreover, i wrote an [r2pipe script](https://github.com/mrmacete/r2scripts/tree/master/bpf-test/bpftest.py) able to read a pcap file, iterate packets, and test them against the filter by using ESIL emulation.
Here is a not-so-clear live action trying to explain the steps of the above python script:
[![asciicast](https://asciinema.org/a/e22kxl5wncmcnqfvseq0k6dxj.png)](https://asciinema.org/a/e22kxl5wncmcnqfvseq0k6dxj)
## Testing
There's a [python script](https://github.com/mrmacete/r2scripts/tree/master/bpf-test/testtool.py) which parses the Linux kernel's BPF test suite and runs it on radare2's emulated BPF using r2pipe. Until now, all the test which doesn't involve kernel emulation are passing (for the CLASSIC bpf test category only).
If you have collections of test cases you can disclose they're welcome, please open an issue or just PR a test script.
## License
Since most of asm_bpf.c is ripped from Linux kernel, it's licensed on GPLv2.
+538
View File
@@ -0,0 +1,538 @@
/*
*
* Copyright 2015 - mrmacete <[email protected]>
* Licensed under the GNU General Public License, version 2.0 (GPLv2)
*/
#include <string.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_asm.h>
#include <r_anal.h>
#include "bpf.h"
#define EMIT_CJMP(op, addr, f)\
(op)->type = R_ANAL_OP_TYPE_CJMP;\
(op)->jump = (addr) + 8 + (st8) (f)->jt * 8;\
(op)->fail = (addr) + 8 + (st8) (f)->jf * 8;
#define EMIT_LOAD(op, addr, size)\
(op)->type = R_ANAL_OP_TYPE_LOAD;\
(op)->ptr = (addr);\
(op)->ptrsize = (size);
#define NEW_SRC_DST(op)\
(op)->src[0] = r_anal_value_new ();\
(op)->dst = r_anal_value_new ();
#define SET_REG_SRC_DST(op, _src, _dst)\
NEW_SRC_DST ((op));\
(op)->src[0]->reg = r_reg_get (anal->reg, (_src), R_REG_TYPE_GPR);\
(op)->dst->reg = r_reg_get (anal->reg, (_dst), R_REG_TYPE_GPR);
#define SET_REG_DST_IMM(op, _dst, _imm)\
NEW_SRC_DST ((op));\
(op)->dst->reg = r_reg_get (anal->reg, (_dst), R_REG_TYPE_GPR);\
(op)->src[0]->imm = (_imm);
#define SET_A_SRC(op)\
(op)->src[0] = r_anal_value_new ();\
(op)->src[0]->reg = r_reg_get (anal->reg, "A", R_REG_TYPE_GPR);
#define SET_A_DST(op)\
(op)->dst = r_anal_value_new ();\
(op)->dst->reg = r_reg_get (anal->reg, "A", R_REG_TYPE_GPR);
#define INSIDE_M(k) ((k) >= 0 && (k) <= 16)
static bool bpf_int_exit(RAnalEsil *esil, ut32 interrupt, void *user);
RAnalEsilInterruptHandler ih = { 0, NULL, NULL, &bpf_int_exit, NULL };
static const char *M[] = {
"M[0]",
"M[1]",
"M[2]",
"M[3]",
"M[4]",
"M[5]",
"M[6]",
"M[7]",
"M[8]",
"M[9]",
"M[10]",
"M[11]",
"M[12]",
"M[13]",
"M[14]",
"M[15]"
};
static int bpf_anal(RAnal *anal, RAnalOp *op, ut64 addr,
const ut8 *data, int len) {
RBpfSockFilter *f = (RBpfSockFilter *)data;
memset (op, '\0', sizeof (RAnalOp));
op->jump = UT64_MAX;
op->fail = UT64_MAX;
op->ptr = op->val = UT64_MAX;
op->type = R_ANAL_OP_TYPE_UNK;
op->size = 8;
op->addr = addr;
r_strbuf_init (&op->esil);
switch (f->code) {
case BPF_RET | BPF_A:
op->type = R_ANAL_OP_TYPE_RET;
esilprintf (op, "A,R0,=,0,$");
break;
case BPF_RET | BPF_K:
case BPF_RET | BPF_X:
op->type = R_ANAL_OP_TYPE_RET;
if (BPF_SRC (f->code) == BPF_K) {
esilprintf (op, "%" PFMT64d ",R0,=,0,$", f->k);
} else if (BPF_SRC (f->code) == BPF_X) {
esilprintf (op, "X,R0,=,0,$");
}
break;
case BPF_MISC_TAX:
op->type = R_ANAL_OP_TYPE_MOV;
SET_REG_SRC_DST (op, "A", "X");
esilprintf (op, "A,X,=");
break;
case BPF_MISC_TXA:
op->type = R_ANAL_OP_TYPE_MOV;
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,=");
break;
case BPF_ST:
if (INSIDE_M (f->k)) {
op->type = R_ANAL_OP_TYPE_MOV;
SET_REG_SRC_DST (op, "A", M[f->k]);
esilprintf (op, "A,M[%" PFMT64d "],=", f->k);
} else {
op->type = R_ANAL_OP_TYPE_ILL;
}
break;
case BPF_STX:
if (INSIDE_M (f->k)) {
op->type = R_ANAL_OP_TYPE_MOV;
SET_REG_SRC_DST (op, "X", M[f->k]);
esilprintf (op, "X,M[%" PFMT64d "],=", f->k);
} else {
op->type = R_ANAL_OP_TYPE_ILL;
}
break;
case BPF_LD_W | BPF_LEN:
op->type = R_ANAL_OP_TYPE_MOV;
SET_REG_SRC_DST (op, "len", "A");
esilprintf (op, "len,A,=", f->k);
break;
case BPF_LDX | BPF_LEN:
op->type = R_ANAL_OP_TYPE_MOV;
SET_REG_SRC_DST (op, "len", "X");
esilprintf (op, "len,X,=", f->k);
break;
case BPF_LD_W | BPF_ABS:
EMIT_LOAD (op, anal->gp + f->k, 4);
SET_A_DST (op);
esilprintf (op,
"len,%" PFMT64d ",>,?{,0,R0,=,0,$,BREAK,},%" PFMT64d ",[4],A,=",
f->k + 4, op->ptr);
break;
case BPF_LD_H | BPF_ABS:
EMIT_LOAD (op, anal->gp + f->k, 2);
SET_A_DST (op);
esilprintf (op,
"len,%" PFMT64d ",>,?{,0,R0,=,0,$,BREAK,},"
"%" PFMT64d ",[2],A,=",
f->k + 2, op->ptr);
break;
case BPF_LD_B | BPF_ABS:
EMIT_LOAD (op, anal->gp + f->k, 1);
SET_A_DST (op);
esilprintf (op,
"len,%" PFMT64d ",>,?{,0,R0,=,0,$,BREAK,},"
"%" PFMT64d ",[1],A,=",
f->k + 1, op->ptr);
break;
case BPF_LD_W | BPF_IND:
op->type = R_ANAL_OP_TYPE_LOAD;
op->ptrsize = 4;
SET_A_DST (op);
esilprintf (op,
"len,%" PFMT64d ",X,+,0xffffffff,&,>,?{,0,R0,=,0,$,BREAK,},"
"%" PFMT64d ",X,+,0xffffffff,&,[4],A,=",
(st32)f->k + 4, anal->gp + (st32)f->k);
break;
case BPF_LD_H | BPF_IND:
op->type = R_ANAL_OP_TYPE_LOAD;
op->ptrsize = 2;
SET_A_DST (op);
esilprintf (op,
"len,%" PFMT64d ",X,+,0xffffffff,&,>,?{,0,R0,=,0,$,BREAK,},"
"%" PFMT64d ",X,+,0xffffffff,&,[2],A,=",
(st32)f->k + 2, anal->gp + (st32)f->k);
break;
case BPF_LD_B | BPF_IND:
op->type = R_ANAL_OP_TYPE_LOAD;
op->ptrsize = 1;
SET_A_DST (op);
esilprintf (op,
"len,%" PFMT64d ",X,+,0xffffffff,&,>,?{,0,R0,=,0,$,BREAK,},"
"%" PFMT64d ",X,+,0xffffffff,&,[1],A,=",
(st32)f->k + 1, anal->gp + (st32)f->k);
break;
case BPF_LD | BPF_IMM:
op->type = R_ANAL_OP_TYPE_MOV;
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "0x%08" PFMT64x ",A,=", f->k);
break;
case BPF_LDX | BPF_IMM:
op->type = R_ANAL_OP_TYPE_MOV;
op->val = f->k;
SET_REG_DST_IMM (op, "X", f->k);
esilprintf (op, "0x%08" PFMT64x ",X,=", f->k);
break;
case BPF_LDX_B | BPF_MSH:
op->type = R_ANAL_OP_TYPE_LOAD;
op->ptrsize = 1;
op->ptr = anal->gp + f->k;
SET_A_DST (op);
esilprintf (op, "%" PFMT64d ",[1],0xf,&,4,*,X,=", op->ptr);
break;
case BPF_LD | BPF_MEM:
op->type = R_ANAL_OP_TYPE_MOV;
if (INSIDE_M (f->k)) {
SET_REG_SRC_DST (op, M[f->k], "A");
esilprintf (op, "M[%" PFMT64d "],A,=", f->k);
} else {
op->type = R_ANAL_OP_TYPE_ILL;
}
break;
case BPF_LDX | BPF_MEM:
op->type = R_ANAL_OP_TYPE_MOV;
if (INSIDE_M (f->k)) {
SET_REG_SRC_DST (op, M[f->k], "X");
esilprintf (op, "M[%" PFMT64d "],X,=", f->k);
} else {
op->type = R_ANAL_OP_TYPE_ILL;
}
break;
case BPF_JMP_JA:
op->type = R_ANAL_OP_TYPE_JMP;
op->jump = addr + 8 + f->k * 8;
esilprintf (op, "%" PFMT64d ",pc,=", op->jump);
break;
case BPF_JMP_JGT | BPF_X:
case BPF_JMP_JGT | BPF_K:
EMIT_CJMP (op, addr, f);
op->cond = R_ANAL_COND_GT;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
esilprintf (op,
"%" PFMT64d ",A,>,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->val, op->jump, op->fail);
} else if (BPF_SRC (f->code) == BPF_X) {
esilprintf (op,
"X,A,>,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->jump, op->fail);
} else {
op->type = R_ANAL_OP_TYPE_ILL;
}
break;
case BPF_JMP_JGE | BPF_X:
case BPF_JMP_JGE | BPF_K:
EMIT_CJMP (op, addr, f);
op->cond = R_ANAL_COND_GE;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
esilprintf (op,
"%" PFMT64d ",A,>=,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->val, op->jump, op->fail);
} else {
esilprintf (op,
"X,A,>=,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->jump, op->fail);
}
break;
case BPF_JMP_JEQ | BPF_X:
case BPF_JMP_JEQ | BPF_K:
EMIT_CJMP (op, addr, f);
op->cond = R_ANAL_COND_EQ;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
esilprintf (op,
"%" PFMT64d ",A,==,$z,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->val, op->jump, op->fail);
} else {
esilprintf (op,
"X,A,==,$z,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->jump, op->fail);
}
break;
case BPF_JMP_JSET | BPF_X:
case BPF_JMP_JSET | BPF_K:
EMIT_CJMP (op, addr, f);
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
esilprintf (op,
"%" PFMT64d ",A,&,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->val, op->jump, op->fail);
} else {
esilprintf (op,
"X,A,&,!,?{,%" PFMT64d ",pc,=,BREAK,},%" PFMT64d ",pc,=",
op->val, op->jump, op->fail);
}
break;
case BPF_ALU_NEG:
op->type = R_ANAL_OP_TYPE_NOT;
esilprintf (op, "A,0,-,A,=");
SET_REG_SRC_DST (op, "A", "A");
break;
case BPF_ALU_LSH | BPF_X:
case BPF_ALU_LSH | BPF_K:
op->type = R_ANAL_OP_TYPE_SHL;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "%" PFMT64d ",A,<<=", f->k);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,<<=");
}
break;
case BPF_ALU_RSH | BPF_X:
case BPF_ALU_RSH | BPF_K:
op->type = R_ANAL_OP_TYPE_SHR;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "%" PFMT64d ",A,>>=", f->k);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,>>=");
}
break;
case BPF_ALU_ADD | BPF_X:
case BPF_ALU_ADD | BPF_K:
op->type = R_ANAL_OP_TYPE_ADD;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", op->val);
esilprintf (op, "%" PFMT64d ",A,+=", op->val);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,+=");
}
break;
case BPF_ALU_SUB | BPF_X:
case BPF_ALU_SUB | BPF_K:
op->type = R_ANAL_OP_TYPE_SUB;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", op->val);
esilprintf (op, "%" PFMT64d ",A,-=", op->val);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,-=");
}
break;
case BPF_ALU_MUL | BPF_X:
case BPF_ALU_MUL | BPF_K:
op->type = R_ANAL_OP_TYPE_MUL;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "%" PFMT64d ",A,*=", f->k);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,*=");
}
break;
case BPF_ALU_DIV | BPF_X:
case BPF_ALU_DIV | BPF_K:
op->type = R_ANAL_OP_TYPE_DIV;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
if (f->k == 0) {
esilprintf (op, "0,R0,=,0,$");
} else {
esilprintf (op, "%" PFMT64d ",A,/=", f->k);
}
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "0,X,==,$z,?{,0,R0,=,0,$,BREAK,},X,A,/=");
}
break;
case BPF_ALU_MOD | BPF_X:
case BPF_ALU_MOD | BPF_K:
op->type = R_ANAL_OP_TYPE_MOD;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
if (f->k == 0) {
esilprintf (op, "0,R0,=,0,$");
} else {
esilprintf (op, "%" PFMT64d ",A,%%=", f->k);
}
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "0,X,==,$z,?{,0,R0,=,0,$,BREAK,},X,A,%%=");
}
break;
case BPF_ALU_AND | BPF_X:
case BPF_ALU_AND | BPF_K:
op->type = R_ANAL_OP_TYPE_AND;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "%" PFMT64d ",A,&=", f->k);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,&=");
}
break;
case BPF_ALU_OR | BPF_X:
case BPF_ALU_OR | BPF_K:
op->type = R_ANAL_OP_TYPE_OR;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "%" PFMT64d ",A,|=", f->k);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,|,A,=");
}
break;
case BPF_ALU_XOR | BPF_X:
case BPF_ALU_XOR | BPF_K:
op->type = R_ANAL_OP_TYPE_XOR;
if (BPF_SRC (f->code) == BPF_K) {
op->val = f->k;
SET_REG_DST_IMM (op, "A", f->k);
esilprintf (op, "%" PFMT64d ",A,^=", f->k);
} else {
SET_REG_SRC_DST (op, "X", "A");
esilprintf (op, "X,A,^=");
}
break;
default:
op->type = R_ANAL_OP_TYPE_ILL;
break;
}
return op->size;
}
static int set_reg_profile(RAnal *anal) {
const char *p =
"=PC pc\n"
"gpr A .32 0 0\n"
"gpr X .32 4 0\n"
"gpr M[0] .32 8 0\n"
"gpr M[1] .32 12 0\n"
"gpr M[2] .32 16 0\n"
"gpr M[3] .32 20 0\n"
"gpr M[4] .32 24 0\n"
"gpr M[5] .32 28 0\n"
"gpr M[6] .32 32 0\n"
"gpr M[7] .32 36 0\n"
"gpr M[8] .32 40 0\n"
"gpr M[9] .32 44 0\n"
"gpr M[10] .32 48 0\n"
"gpr M[11] .32 52 0\n"
"gpr M[12] .32 56 0\n"
"gpr M[13] .32 60 0\n"
"gpr M[14] .32 64 0\n"
"gpr M[15] .32 68 0\n"
"gpr pc .32 72 0\n"
"gpr len .32 76 0\n"
"gpr R0 .32 80 0\n"
"gpr R1 .32 84 0\n"
"gpr R2 .32 88 0\n"
"gpr R3 .32 92 0\n"
"gpr R4 .32 96 0\n"
"gpr R5 .32 100 0\n";
return r_reg_set_profile_string (anal->reg, p);
}
static bool bpf_int_exit(RAnalEsil *esil, ut32 interrupt, void *user) {
int syscall;
ut64 r0;
if (!esil || (interrupt != 0x0))
return false;
r_anal_esil_reg_read (esil, "R0", &r0, NULL);
if (r0 == 0) {
esil->anal->cb_printf ("; BPF result: DROP value: %d\n", (int)r0);
eprintf ("BPF result: DROP value: %d\n", (int)r0);
} else {
esil->anal->cb_printf ("; BPF result: ACCEPT value: %d\n", (int)r0);
eprintf ("BPF result: ACCEPT value: %d\n", (int)r0);
}
return true;
}
static int esil_bpf_init(RAnalEsil *esil) {
if (!esil)
return false;
RAnalEsilInterrupt *intr = r_anal_esil_interrupt_new (esil, 0, &ih);
r_anal_esil_set_interrupt (esil, intr);
return true;
}
static int esil_bpf_fini(RAnalEsil *esil) {
return true;
}
struct r_anal_plugin_t r_anal_plugin_bpf = {
.name = "bpf",
.desc = "Berkely packet filter analysis plugin",
.license = "GPLv2",
.arch = "bpf",
.bits = 32,
.esil = true,
.init = NULL,
.fini = NULL,
.reset_counter = NULL,
.archinfo = NULL,
.op = &bpf_anal,
.bb = NULL,
.fcn = NULL,
.analyze_fns = NULL,
.op_from_buffer = NULL,
.bb_from_buffer = NULL,
.fn_from_buffer = NULL,
.analysis_algorithm = NULL,
.set_reg_profile = &set_reg_profile,
.fingerprint_bb = NULL,
.fingerprint_fcn = NULL,
.diff_bb = NULL,
.diff_fcn = NULL,
.diff_eval = NULL,
.pre_anal = NULL,
.pre_anal_fn_cb = NULL,
.pre_anal_op_cb = NULL,
.post_anal_op_cb = NULL,
.pre_anal_bb_cb = NULL,
.post_anal_bb_cb = NULL,
.post_anal_fn_cb = NULL,
.post_anal = NULL,
.revisit_bb_anal = NULL,
.cmd_ext = NULL,
.esil_init = &esil_bpf_init,
.esil_post_loop = NULL,
.esil_trap = NULL,
.esil_fini = &esil_bpf_fini
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_bpf,
.version = R2_VERSION
};
#endif
+767
View File
@@ -0,0 +1,767 @@
/*
* Most of this is copied and pasted from linux source (except
* for the assembler part).
*
* Copyright 2015 - mrmacete <[email protected]>
* Licensed under the GNU General Public License, version 2.0 (GPLv2)
*/
#include <r_types.h>
#include <r_util.h>
#include <r_lib.h>
#include <r_asm.h>
#include "bpf.h"
static int disassemble(RAsm *a, RAsmOp *r_op, const ut8 *buf, int len) {
const char *op, *fmt;
RBpfSockFilter *f = (RBpfSockFilter *)buf;
int val = f->k;
char vbuf[256];
switch (f->code) {
case BPF_RET | BPF_K:
op = r_bpf_op_table[BPF_RET];
fmt = "%#x";
break;
case BPF_RET | BPF_A:
op = r_bpf_op_table[BPF_RET];
fmt = "a";
break;
case BPF_RET | BPF_X:
op = r_bpf_op_table[BPF_RET];
fmt = "x";
break;
case BPF_MISC_TAX:
op = r_bpf_op_table[BPF_MISC_TAX];
fmt = "";
break;
case BPF_MISC_TXA:
op = r_bpf_op_table[BPF_MISC_TXA];
fmt = "";
break;
case BPF_ST:
op = r_bpf_op_table[BPF_ST];
fmt = "M[%d]";
break;
case BPF_STX:
op = r_bpf_op_table[BPF_STX];
fmt = "M[%d]";
break;
case BPF_LD_W | BPF_ABS:
op = r_bpf_op_table[BPF_LD_W];
fmt = "[%d]";
break;
case BPF_LD_H | BPF_ABS:
op = r_bpf_op_table[BPF_LD_H];
fmt = "[%d]";
break;
case BPF_LD_B | BPF_ABS:
op = r_bpf_op_table[BPF_LD_B];
fmt = "[%d]";
break;
case BPF_LD_W | BPF_LEN:
op = r_bpf_op_table[BPF_LD_W];
fmt = "len";
break;
case BPF_LD_W | BPF_IND:
op = r_bpf_op_table[BPF_LD_W];
fmt = "[x+%d]";
break;
case BPF_LD_H | BPF_IND:
op = r_bpf_op_table[BPF_LD_H];
fmt = "[x+%d]";
break;
case BPF_LD_B | BPF_IND:
op = r_bpf_op_table[BPF_LD_B];
fmt = "[x+%d]";
break;
case BPF_LD | BPF_IMM:
op = r_bpf_op_table[BPF_LD_W];
fmt = "%#x";
break;
case BPF_LDX | BPF_IMM:
op = r_bpf_op_table[BPF_LDX];
fmt = "%#x";
break;
case BPF_LDX | BPF_LEN:
op = r_bpf_op_table[BPF_LDX];
fmt = "len";
break;
case BPF_LDX | BPF_ABS:
op = r_bpf_op_table[BPF_LDX];
fmt = "[%d]";
break;
case BPF_LDX_B | BPF_MSH:
op = r_bpf_op_table[BPF_LDX_B];
fmt = "4*([%d]&0xf)";
break;
case BPF_LD | BPF_MEM:
op = r_bpf_op_table[BPF_LD_W];
fmt = "M[%d]";
break;
case BPF_LDX | BPF_MEM:
op = r_bpf_op_table[BPF_LDX];
fmt = "M[%d]";
break;
case BPF_JMP_JA:
op = r_bpf_op_table[BPF_JMP_JA];
fmt = "%d";
val = a->pc + 8 + f->k * 8;
break;
case BPF_JMP_JGT | BPF_X:
op = r_bpf_op_table[BPF_JMP_JGT];
fmt = "x";
break;
case BPF_JMP_JGT | BPF_K:
op = r_bpf_op_table[BPF_JMP_JGT];
fmt = "%#x";
break;
case BPF_JMP_JGE | BPF_X:
op = r_bpf_op_table[BPF_JMP_JGE];
fmt = "x";
break;
case BPF_JMP_JGE | BPF_K:
op = r_bpf_op_table[BPF_JMP_JGE];
fmt = "%#x";
break;
case BPF_JMP_JEQ | BPF_X:
op = r_bpf_op_table[BPF_JMP_JEQ];
fmt = "x";
break;
case BPF_JMP_JEQ | BPF_K:
op = r_bpf_op_table[BPF_JMP_JEQ];
fmt = "%#x";
break;
case BPF_JMP_JSET | BPF_X:
op = r_bpf_op_table[BPF_JMP_JSET];
fmt = "x";
break;
case BPF_JMP_JSET | BPF_K:
op = r_bpf_op_table[BPF_JMP_JSET];
fmt = "%#x";
break;
case BPF_ALU_NEG:
op = r_bpf_op_table[BPF_ALU_NEG];
fmt = "";
break;
case BPF_ALU_LSH | BPF_X:
op = r_bpf_op_table[BPF_ALU_LSH];
fmt = "x";
break;
case BPF_ALU_LSH | BPF_K:
op = r_bpf_op_table[BPF_ALU_LSH];
fmt = "%d";
break;
case BPF_ALU_RSH | BPF_X:
op = r_bpf_op_table[BPF_ALU_RSH];
fmt = "x";
break;
case BPF_ALU_RSH | BPF_K:
op = r_bpf_op_table[BPF_ALU_RSH];
fmt = "%d";
break;
case BPF_ALU_ADD | BPF_X:
op = r_bpf_op_table[BPF_ALU_ADD];
fmt = "x";
break;
case BPF_ALU_ADD | BPF_K:
op = r_bpf_op_table[BPF_ALU_ADD];
fmt = "%d";
break;
case BPF_ALU_SUB | BPF_X:
op = r_bpf_op_table[BPF_ALU_SUB];
fmt = "x";
break;
case BPF_ALU_SUB | BPF_K:
op = r_bpf_op_table[BPF_ALU_SUB];
fmt = "%d";
break;
case BPF_ALU_MUL | BPF_X:
op = r_bpf_op_table[BPF_ALU_MUL];
fmt = "x";
break;
case BPF_ALU_MUL | BPF_K:
op = r_bpf_op_table[BPF_ALU_MUL];
fmt = "%d";
break;
case BPF_ALU_DIV | BPF_X:
op = r_bpf_op_table[BPF_ALU_DIV];
fmt = "x";
break;
case BPF_ALU_DIV | BPF_K:
op = r_bpf_op_table[BPF_ALU_DIV];
fmt = "%d";
break;
case BPF_ALU_MOD | BPF_X:
op = r_bpf_op_table[BPF_ALU_MOD];
fmt = "x";
break;
case BPF_ALU_MOD | BPF_K:
op = r_bpf_op_table[BPF_ALU_MOD];
fmt = "%d";
break;
case BPF_ALU_AND | BPF_X:
op = r_bpf_op_table[BPF_ALU_AND];
fmt = "x";
break;
case BPF_ALU_AND | BPF_K:
op = r_bpf_op_table[BPF_ALU_AND];
fmt = "%#x";
break;
case BPF_ALU_OR | BPF_X:
op = r_bpf_op_table[BPF_ALU_OR];
fmt = "x";
break;
case BPF_ALU_OR | BPF_K:
op = r_bpf_op_table[BPF_ALU_OR];
fmt = "%#x";
break;
case BPF_ALU_XOR | BPF_X:
op = r_bpf_op_table[BPF_ALU_XOR];
fmt = "x";
break;
case BPF_ALU_XOR | BPF_K:
op = r_bpf_op_table[BPF_ALU_XOR];
fmt = "%#x";
break;
default:
op = "invalid";
fmt = "%#x";
val = f->code;
break;
}
memset (vbuf, 0, sizeof (vbuf));
snprintf (vbuf, sizeof (vbuf), fmt, val);
vbuf[sizeof (vbuf) - 1] = 0;
if ((BPF_CLASS (f->code) == BPF_JMP && BPF_OP (f->code) != BPF_JA))
r_strbuf_setf (&r_op->buf_asm, "%s %s, 0x%08" PFMT64x ", 0x%08" PFMT64x "", op, vbuf,
a->pc + 8 + f->jt * 8, a->pc + 8 + f->jf * 8);
else r_strbuf_setf (&r_op->buf_asm, "%s %s", op, vbuf);
return r_op->size = 8;
}
/* start of ASSEMBLER code */
#define PARSER_MAX_TOKENS 4
#define COPY_AND_RET(a, b)\
r_strbuf_setbin (&a, (const ut8 *)b, sizeof (*b) + 1);\
return 0;
#define PARSE_FAILURE(message, arg...)\
{\
eprintf ("PARSE FAILURE: " message "\n", ##arg);\
return -1;\
}
#define CMP4(tok, n, x, y, z, w)\
(tok[n][0] == x && tok[n][1] == y && tok[n][2] == z && tok[n][3] == w)
#define CMP3(tok, n, x, y, z)\
(tok[n][0] == x && tok[n][1] == y && tok[n][2] == z)
#define CMP2(tok, n, x, y)\
(tok[n][0] == x && tok[n][1] == y)
#define IS_K_TOK(tok, n)\
(tok[n][0] == '-' || R_BETWEEN ('0', tok[n][0], '9'))
#define IS_LEN(tok, n)\
CMP4 (tok, n, 'l', 'e', 'n', '\0')
#define PARSE_K_OR_FAIL(dst, tok, n)\
dst = strtol (&tok[n][0], &end, 0);\
if (*end != '\0' && *end != ',')\
PARSE_FAILURE ("could not parse k");
#define PARSE_LABEL_OR_FAIL(dst, tok, n)\
dst = strtoul (&tok[n][0], &end, 0);\
if (*end != '\0' && *end != ',') {\
return -1;\
}
#define PARSE_OFFSET_OR_FAIL(dst, tok, n, off)\
dst = strtoul (&tok[n][off], &end, 10);\
if (*end != ']')\
PARSE_FAILURE ("could not parse offset value");
#define PARSE_IND_ABS_OR_FAIL(f, tok, n)\
if (CMP3 (tok, 1, '[', 'x', '+')) {\
f->code = f->code | BPF_IND;\
PARSE_OFFSET_OR_FAIL (f->k, tok, 1, 3);\
return 0;\
} else if (tok[1][0] == '[') {\
f->code = f->code | BPF_ABS;\
PARSE_OFFSET_OR_FAIL (f->k, tok, 1, 1);\
return 0;\
}\
PARSE_FAILURE ("could not parse addressing mode");
#define PARSE_K_OR_X_OR_FAIL(f, tok)\
if (IS_K_TOK (tok, 1)) {\
PARSE_K_OR_FAIL (f->k, tok, 1);\
f->code = f->code | BPF_K;\
} else if (tok[1][0] == 'x' && (tok[1][1] == '\0' || tok[1][1] == ',')) {\
f->code = f->code | BPF_X;\
} else {\
PARSE_FAILURE ("could not parse k or x: %s", tok[1]);\
}
#define PARSE_A_OR_X_OR_FAIL(f, tok)\
if (tok[1][0] == 'x' && (tok[1][1] == '\0' || tok[1][1] == ',')) {\
f->code = f->code | BPF_X;\
} else if (tok[1][0] == 'a' && (tok[1][1] == '\0' || tok[1][1] == ',')) {\
f->code = f->code | BPF_A;\
} else {\
PARSE_FAILURE ("could not parse a or x");\
}
#define PARSE_JUMP_TARGETS(a, f, tok, count)\
PARSE_K_OR_X_OR_FAIL (f, tok);\
if (count >= 3) {\
PARSE_LABEL_OR_FAIL (label, tok, 2);\
f->jt = (st64) (label - a->pc - 8) / 8;\
f->jf = (a->pc >> 3) + 1;\
}\
if (count == 4) {\
PARSE_LABEL_OR_FAIL (label, tok, 3);\
f->jf = (st64) (label - a->pc - 8) / 8;\
}
#define SWAP_JUMP_TARGETS(f)\
temp = f->jt;\
f->jt = f->jf;\
f->jf = temp;
#define ENFORCE_COUNT(count, n)\
if (count != n)\
PARSE_FAILURE ("invalid argument count, try to omit '#'");
#define ENFORCE_COUNT_GE(count, n)\
if (count < n)\
PARSE_FAILURE ("invalid argument count, try to omit '#'");
static int assemble_ld(RAsm *a, RAsmOp *op,
char *tok[PARSER_MAX_TOKENS], int count, RBpfSockFilter *f) {
char *end;
switch (tok[0][2]) {
case '\0':
if (CMP2 (tok, 1, 'm', '[')) {
f->code = BPF_LD | BPF_MEM;
PARSE_OFFSET_OR_FAIL (f->k, tok, 1, 2);
} else if (IS_K_TOK (tok, 1)) {
f->code = BPF_LD | BPF_IMM;
PARSE_K_OR_FAIL (f->k, tok, 1);
} else if (IS_LEN (tok, 1)) {
f->code = BPF_LD | BPF_LEN;
} else {
f->code = BPF_LD_W;
PARSE_IND_ABS_OR_FAIL (f, tok, 1);
}
break;
case 'i':
if (IS_K_TOK (tok, 1)) {
f->code = BPF_LD | BPF_IMM;
PARSE_K_OR_FAIL (f->k, tok, 1);
} else {
PARSE_FAILURE ("ldi without k");
}
break;
case 'b':
f->code = BPF_LD_B;
PARSE_IND_ABS_OR_FAIL (f, tok, 1);
break;
case 'h':
f->code = BPF_LD_H;
PARSE_IND_ABS_OR_FAIL (f, tok, 1);
break;
case 'x':
switch (tok[0][3]) {
case '\0':
if (CMP2 (tok, 1, 'm', '[')) {
f->code = BPF_LDX | BPF_MEM;
PARSE_OFFSET_OR_FAIL (f->k, tok, 1, 2);
} else if (IS_K_TOK (tok, 1)) {
f->code = BPF_LDX | BPF_IMM;
PARSE_K_OR_FAIL (f->k, tok, 1);
} else if (IS_LEN (tok, 1)) {
f->code = BPF_LDX | BPF_LEN;
} else {
f->code = BPF_LDX_W;
PARSE_IND_ABS_OR_FAIL (f, tok, 1);
}
break;
case 'i':
if (IS_K_TOK (tok, 1)) {
f->code = BPF_LDX | BPF_IMM;
PARSE_K_OR_FAIL (f->k, tok, 1);
} else {
PARSE_FAILURE ("ldxi without k");
}
break;
case 'b':
f->code = BPF_LDX_B | BPF_MSH;
if (sscanf (tok[1], "4*([%d]&0xf)", &f->k) != 1) {
PARSE_FAILURE ("invalid nibble addressing");
}
break;
}
break;
default:
PARSE_FAILURE ("unsupported load instruction");
}
return 0;
}
static int assemble_j(RAsm *a, RAsmOp *op, char *tok[PARSER_MAX_TOKENS],
int count, RBpfSockFilter *f) {
int label;
ut8 temp;
char *end;
if (CMP4 (tok, 0, 'j', 'm', 'p', '\0') ||
CMP3 (tok, 0, 'j', 'a', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_JMP_JA;
PARSE_LABEL_OR_FAIL (f->k, tok, 1);
return 0;
}
if (CMP4 (tok, 0, 'j', 'n', 'e', '\0') ||
CMP4 (tok, 0, 'j', 'n', 'e', 'q')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JEQ;
PARSE_JUMP_TARGETS (a, f, tok, count);
SWAP_JUMP_TARGETS (f);
return 0;
}
if (CMP4 (tok, 0, 'j', 'e', 'q', '\0')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JEQ;
PARSE_JUMP_TARGETS (a, f, tok, count);
return 0;
}
if (CMP4 (tok, 0, 'j', 'l', 't', '\0')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JGE;
PARSE_JUMP_TARGETS (a, f, tok, count);
SWAP_JUMP_TARGETS (f);
return 0;
}
if (CMP4 (tok, 0, 'j', 'l', 'e', '\0')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JGT;
PARSE_JUMP_TARGETS (a, f, tok, count);
SWAP_JUMP_TARGETS (f);
return 0;
}
if (CMP4 (tok, 0, 'j', 'g', 't', '\0')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JGT;
PARSE_JUMP_TARGETS (a, f, tok, count);
return 0;
}
if (CMP4 (tok, 0, 'j', 'g', 'e', '\0')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JGE;
PARSE_JUMP_TARGETS (a, f, tok, count);
return 0;
}
if (CMP4 (tok, 0, 'j', 's', 'e', 't')) {
ENFORCE_COUNT_GE (count, 3);
f->code = BPF_JMP_JSET;
PARSE_JUMP_TARGETS (a, f, tok, count);
return 0;
}
return -1;
}
static int assemble_alu(RAsm *a, RAsmOp *op, char *tok[PARSER_MAX_TOKENS],
int count, RBpfSockFilter *f) {
char *end;
if (CMP4 (tok, 0, 'a', 'd', 'd', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_ADD;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 's', 'u', 'b', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_SUB;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'm', 'u', 'l', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_MUL;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'd', 'i', 'v', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_DIV;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'm', 'o', 'd', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_MOD;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'n', 'e', 'g', '\0')) {
ENFORCE_COUNT (count, 1);
f->code = BPF_ALU_NEG;
return 0;
}
if (CMP4 (tok, 0, 'a', 'n', 'd', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_AND;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP3 (tok, 0, 'o', 'r', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_OR;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'x', 'o', 'r', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_XOR;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'l', 's', 'h', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_LSH;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
if (CMP4 (tok, 0, 'r', 's', 'h', '\0')) {
ENFORCE_COUNT (count, 2);
f->code = BPF_ALU_RSH;
PARSE_K_OR_X_OR_FAIL (f, tok);
return 0;
}
return -1;
}
static int assemble_tok(RAsm *a, RAsmOp *op,
char *tok[PARSER_MAX_TOKENS], int count) {
char *end;
int oplen = 0;
RBpfSockFilter f = { 0, 0, 0, 0 };
oplen = strnlen (tok[0], 5);
if (oplen < 2 || oplen > 4) {
PARSE_FAILURE ("mnemonic length not valid");
}
if (CMP4 (tok, 0, 't', 'x', 'a', '\0')) {
ENFORCE_COUNT (count, 1);
f.code = BPF_MISC_TXA;
COPY_AND_RET (op->buf, &f);
}
if (CMP4 (tok, 0, 't', 'a', 'x', '\0')) {
ENFORCE_COUNT (count, 1);
f.code = BPF_MISC_TAX;
COPY_AND_RET (op->buf, &f);
}
if (CMP4 (tok, 0, 'r', 'e', 't', '\0')) {
ENFORCE_COUNT (count, 2);
if (IS_K_TOK (tok, 1)) {
f.code = BPF_RET | BPF_K;
PARSE_K_OR_FAIL (f.k, tok, 1);
} else if (tok[1][0] == 'x') {
f.code = BPF_RET | BPF_X;
} else if (tok[1][0] == 'a') {
f.code = BPF_RET | BPF_A;
} else {
PARSE_FAILURE ("unsupported ret instruction");
}
COPY_AND_RET (op->buf, &f);
}
if (CMP2 (tok, 0, 'l', 'd')) {
ENFORCE_COUNT (count, 2);
if (assemble_ld (a, op, tok, count, &f) == 0) {
COPY_AND_RET (op->buf, &f);
} else {
return -1;
}
}
if (CMP2 (tok, 0, 's', 't')) {
ENFORCE_COUNT (count, 2);
if (tok[0][2] == '\0') {
f.code = BPF_ST;
} else if (tok[0][2] == 'x') {
f.code = BPF_STX;
}
if (CMP2 (tok, 1, 'm', '[')) {
PARSE_OFFSET_OR_FAIL (f.k, tok, 1, 2);
if (f.k > 15) {
PARSE_FAILURE ("mem addressing out of bounds");
}
COPY_AND_RET (op->buf, &f);
} else {
PARSE_FAILURE ("invalid store addressing");
}
}
if (tok[0][0] == 'j') {
if (assemble_j (a, op, tok, count, &f) == 0) {
COPY_AND_RET (op->buf, &f);
} else {
return -1;
}
}
if (assemble_alu (a, op, tok, count, &f) == 0) {
COPY_AND_RET (op->buf, &f);
} else {
return -1;
}
}
static void lower_op(char *c) {
if ((c[0] <= 'Z') && (c[0] >= 'A')) {
c[0] += 0x20;
}
}
#define R_TRUE 1
static void normalize(RStrBuf *buf) {
int i;
char *buf_asm;
if (!buf)
return;
buf_asm = r_strbuf_get (buf);
/* this normalization step is largely sub-optimal */
i = strlen (buf_asm);
while (strstr (buf_asm, " ")) {
r_str_replace_in (buf_asm, (ut32)i, " ", " ", R_TRUE);
}
r_str_replace_in (buf_asm, (ut32)i, " ,", ",", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "[ ", "[", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, " ]", "]", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "( ", "(", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, " )", ")", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "+ ", "+", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, " +", "+", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "* ", "*", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, " *", "*", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "& ", "&", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, " &", "&", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "%", "", R_TRUE);
r_str_replace_in (buf_asm, (ut32)i, "#", "", R_TRUE);
r_str_do_until_token (lower_op, buf_asm, '\0');
r_strbuf_set (buf, buf_asm);
}
static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
char *tok[PARSER_MAX_TOKENS];
char tmp[128];
int i, j, l;
const char *p = NULL;
if (!a || !op || !buf) {
return 0;
}
r_strbuf_set (&op->buf_asm, buf);
normalize (&op->buf_asm);
// tokenization, copied from profile.c
j = 0;
p = r_strbuf_get (&op->buf_asm);
// For every word
while (*p) {
// Skip the whitespace
while (*p == ' ' || *p == '\t') {
p++;
}
// Skip the rest of the line is a comment is encountered
if (*p == ';') {
while (*p != '\0') {
p++;
}
}
// EOL ?
if (*p == '\0') {
break;
}
// Gather a handful of chars
// Use isgraph instead of isprint because the latter considers ' ' printable
for (i = 0; isgraph ((const unsigned char)*p) && i < sizeof (tmp) - 1;) {
tmp[i++] = *p++;
}
tmp[i] = '\0';
// Limit the number of tokens
if (j > PARSER_MAX_TOKENS - 1) {
break;
}
// Save the token
tok[j++] = strdup (tmp);
}
if (j) {
if (assemble_tok (a, op, tok, j) < 0) {
return -1;
}
// Clean up
for (i = 0; i < j; i++) {
free (tok[i]);
}
}
return op->size = 8;
}
RAsmPlugin r_asm_plugin_bpf = {
.name = "bpf",
.desc = "Berkeley Packet Filter disassembler",
.license = "GPLv2",
.arch = "bpf",
.bits = 32,
.disassemble = &disassemble,
.assemble = &assemble
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_bpf,
.version = R2_VERSION
};
#endif
+98
View File
@@ -0,0 +1,98 @@
/* LGPL3 - Copyright 2015 - mrmacete */
/* it's a blatant copy of "any" bin plugin from radare, big_endian = 1 */
#include <r_types.h>
#include <r_util.h>
#include <r_lib.h>
#include <r_bin.h>
#include <r_magic.h>
static char *get_filetype(RBinFile *arch) {
ut8 buf[4096] = { 0 };
char *res = NULL;
RMagic *ck;
if (!arch)
return NULL;
ck = r_magic_new (0);
if (ck && arch && arch->buf) {
const char *tmp = NULL;
r_magic_load (ck, R2_SDB_MAGIC);
r_buf_read_at (arch->buf, 0, buf, sizeof (buf));
tmp = r_magic_buffer (ck, buf, sizeof (buf));
if (tmp)
res = strdup (tmp);
}
r_magic_free (ck);
return res;
}
static RBinInfo *info(RBinFile *arch) {
RBinInfo *ret = R_NEW0 (RBinInfo);
if (!ret)
return NULL;
ret->lang = "";
ret->file = arch->file ? strdup (arch->file) : NULL;
ret->type = get_filetype (arch);
ret->has_pi = 0;
ret->has_canary = 0;
if (R_SYS_BITS & R_SYS_BITS_64) {
ret->bits = 64;
} else {
ret->bits = 32;
}
ret->big_endian = 1;
ret->has_va = 0;
ret->has_nx = 0;
ret->dbg_info = 0;
ret->dbg_info = 0;
ret->dbg_info = 0;
return ret;
}
static bool load(RBinFile *arch) {
return true;
}
static int destroy(RBinFile *arch) {
return true;
}
static ut64 baddr(RBinFile *arch) {
return 0LL;
}
struct r_bin_plugin_t r_bin_plugin_bpf = {
.name = "bpf",
.desc = "Berkeley Packet Filter - raw binary",
.license = "LGPL3",
.init = NULL,
.fini = NULL,
.get_sdb = NULL,
.load = &load,
.load_bytes = NULL,
.destroy = &destroy,
.baddr = &baddr,
.boffset = NULL,
.binsym = NULL,
.entries = NULL,
.sections = NULL,
.symbols = NULL,
.imports = NULL,
.strings = NULL,
.info = info,
.fields = NULL,
.libs = NULL,
.relocs = NULL,
.dbginfo = NULL,
.create = NULL,
.write = NULL,
.minstrlen = 0,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_BIN,
.data = &r_bin_plugin_bpf,
.version = R2_VERSION
};
#endif
BIN
View File
Binary file not shown.
+82
View File
@@ -0,0 +1,82 @@
/*
* Most of this is copied and pasted from linux kernel source
*
* Copyright 2015 - mrmacete <[email protected]>
* Licensed under the GNU General Public License, version 2.0 (GPLv2)
*/
#ifndef _BPF_H_
#define _BPF_H_
#include "bpf_common.h"
/* defines ripped from linux/filter.h : */
#define BPF_A 0x10
#define BPF_TAX 0x00
#define BPF_TXA 0x80
/* defines ripped from bpf_dbg.c : */
#define BPF_LDX_B (BPF_LDX | BPF_B)
#define BPF_LDX_W (BPF_LDX | BPF_W)
#define BPF_JMP_JA (BPF_JMP | BPF_JA)
#define BPF_JMP_JEQ (BPF_JMP | BPF_JEQ)
#define BPF_JMP_JGT (BPF_JMP | BPF_JGT)
#define BPF_JMP_JGE (BPF_JMP | BPF_JGE)
#define BPF_JMP_JSET (BPF_JMP | BPF_JSET)
#define BPF_ALU_ADD (BPF_ALU | BPF_ADD)
#define BPF_ALU_SUB (BPF_ALU | BPF_SUB)
#define BPF_ALU_MUL (BPF_ALU | BPF_MUL)
#define BPF_ALU_DIV (BPF_ALU | BPF_DIV)
#define BPF_ALU_MOD (BPF_ALU | BPF_MOD)
#define BPF_ALU_NEG (BPF_ALU | BPF_NEG)
#define BPF_ALU_AND (BPF_ALU | BPF_AND)
#define BPF_ALU_OR (BPF_ALU | BPF_OR)
#define BPF_ALU_XOR (BPF_ALU | BPF_XOR)
#define BPF_ALU_LSH (BPF_ALU | BPF_LSH)
#define BPF_ALU_RSH (BPF_ALU | BPF_RSH)
#define BPF_MISC_TAX (BPF_MISC | BPF_TAX)
#define BPF_MISC_TXA (BPF_MISC | BPF_TXA)
#define BPF_LD_B (BPF_LD | BPF_B)
#define BPF_LD_H (BPF_LD | BPF_H)
#define BPF_LD_W (BPF_LD | BPF_W)
static const char * const r_bpf_op_table[] = {
[BPF_ST] = "st",
[BPF_STX] = "stx",
[BPF_LD_B] = "ldb",
[BPF_LD_H] = "ldh",
[BPF_LD_W] = "ld",
[BPF_LDX] = "ldx",
[BPF_LDX_B] = "ldxb",
[BPF_JMP_JA] = "ja",
[BPF_JMP_JEQ] = "jeq",
[BPF_JMP_JGT] = "jgt",
[BPF_JMP_JGE] = "jge",
[BPF_JMP_JSET] = "jset",
[BPF_ALU_ADD] = "add",
[BPF_ALU_SUB] = "sub",
[BPF_ALU_MUL] = "mul",
[BPF_ALU_DIV] = "div",
[BPF_ALU_MOD] = "mod",
[BPF_ALU_NEG] = "neg",
[BPF_ALU_AND] = "and",
[BPF_ALU_OR] = "or",
[BPF_ALU_XOR] = "xor",
[BPF_ALU_LSH] = "lsh",
[BPF_ALU_RSH] = "rsh",
[BPF_MISC_TAX] = "tax",
[BPF_MISC_TXA] = "txa",
[BPF_RET] = "ret",
};
typedef struct r_bpf_sock_filter { /* Filter block */
ut16 code; /* Actual filter code */
st8 jt; /* Jump true */
st8 jf; /* Jump false */
ut32 k; /* Generic multiuse field */
} RBpfSockFilter;
#endif
+60
View File
@@ -0,0 +1,60 @@
/*
* this file is directly copied from linux source
* Licensed under the GNU General Public License, version 2.0 (GPLv2)
*/
#ifndef _UAPI__LINUX_BPF_COMMON_H__
#define _UAPI__LINUX_BPF_COMMON_H__
/* Instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
/* alu/jmp fields */
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_MOD 0x90
#define BPF_XOR 0xa0
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
#ifndef BPF_MAXINSNS
#define BPF_MAXINSNS 4096
#endif
#endif /* _UAPI__LINUX_BPF_COMMON_H__ */
-11
View File
@@ -1,11 +0,0 @@
This is the r2 plugin to read/write memory using the checkm8 exploit.
1. Clone https://github.com/axi0mX/ipwndfu
2. Copy this file into the root directory of this repository
3. r2 -I r2io.py ipwndfu://
4. enjoy
NOTES
* This is very unstable, reading on unallocated regions results in device reboot
* Requires python3 .. so maybe better use @geohot's fork
-65
View File
@@ -1,65 +0,0 @@
# iOS pwndfu checkm8 io plugin for radare2
# ========================================
#
# -- pancake @ nopcode.org
#
# Usage:
# r2 -I test-py-io.py pwndfu://
#
# 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 ..'
import r2lang
from dfuexec import *
FAKESIZE = 512
device = None
def pyio(a):
def _open(path, rw, perm):
global device
device = dfu.acquire_device()
serial_number = device.serial_number
dfu.release_device(device)
device = PwnedDFUDevice()
print("MyPyIO Opening %s"%(path))
return 1234
def _check(path, many):
print("python-check %s"%(path))
return path[0:9] == "pwndfu://"
def _read(offset, length):
global device
res = device.read_memory(address, length)
print("python-read")
return res
def _seek(offset, whence):
print("python-seek")
if whence == 0: # SET
return offset
if whence == 1: # CUR
return offset
if whence == 2: # END
return ROM_SIZE
return ROM_SIZE
def _write(offset, data, length):
print("TODO: python-write")
return True
def _system(cmd):
print("pwndfu://%s"%(cmd))
return True
return {
"name": "pwndfu",
"license": "GPL",
"desc": "pwndfu IO plugin (pwndfu://3)",
"check": _check,
"open": _open,
"read": _read,
"seek": _seek,
"write": _write,
"system": _system,
}
print("Registering Python IO plugin...")
print(r2lang.plugin("io", pyio))
Vendored
+37 -128
View File
@@ -1,5 +1,5 @@
#!/bin/sh
# This script was automatically generated by ACR v2.2.4
# This script was automatically generated by ACR v1.7.0
# @author: pancake <nopcode.org>
# @url: http://www.nopcode.org
# @repo: git clone https://github.com/radare/acr
@@ -41,11 +41,6 @@ shift
done
}
QUIET=0
be_quiet() {
QUIET=1
}
VPATH=`dirname ${0}`
if [ "${VPATH}" = "." ]; then
WODIS=current
@@ -67,27 +62,12 @@ if [ -e "${VPATH}/config.guess" ]; then
sh ${VPATH}/config.guess
return
fi
CPU="`uname -m | tr 'A-Z' 'a-z' | sed -e 's, ,,g' | cut -d - -f 1`"
CPU="`uname -m|sed -e 's, ,,g'|cut -d - -f 1`"
OS="`uname -s|tr A-Z a-z`"
uname -r | grep -qE "(Microsoft|WSL)" 2>/dev/null && OS="wsl"
GNU="`uname --help 2>&1 | grep gnu`"
[ "${GNU}" ] && OS="${OS}-gnu"
# normalize CPU
case "${CPU}" in
ppc*|powermac*|powermacintosh*|powerpc*)
if echo "${CPU}" | grep -q '64'; then
CPU=powerpc64
else
CPU=powerpc
fi
;;
*) ;;
esac
VENDOR="unknown"
if [ "${OS}" = "darwin" ]; then
VENDOR=apple
fi
echo "${CPU}-${VENDOR}-${OS}"
[ "${CPU}" = ppc ] && CPU="powerpc"
echo "${CPU}-unknown-${OS}"
}
SEARCHPATH="/usr /usr/local /usr/pkg /sw"
@@ -97,19 +77,15 @@ CROSSBUILD=0
BUILD=`guess_os`
HOST="${BUILD}"
TARGET="${HOST}"
ETCDIR="/etc"
SYSCONFDIR=""
DESCRIPTION=""
create_environ() {
: ${EPREFIX:="${PREFIX}"}
: ${SPREFIX:="${PREFIX}"}
: ${BINDIR:="${SPREFIX}/bin"}
: ${SBINDIR:="${PREFIX}/sbin"}
: ${ETCDIR:="${SPREFIX}/etc"}
: ${SYSCONFDIR:="${SPREFIX}/etc"}
: ${LIBDIR:="${SPREFIX}/lib"}
: ${PKGCFG_LIBDIR:='${exec_prefix}/lib'}
: ${PKGCFG_INCDIR:='${prefix}/include'}
: ${LIBEXECDIR:="${SPREFIX}/libexec"}
: ${INCLUDEDIR:="${SPREFIX}/include"}
: ${DATADIR:="${SPREFIX}/share"}
@@ -128,12 +104,12 @@ done
: ${INSTALL_PROGRAM_STRIP:=${INSTALL} -m 755 -s}
: ${INSTALL_MAN:=${INSTALL} -m 444}
: ${INSTALL_LIB:=${INSTALL} -m 755 -c}
PKGNAME='radare2-extras' ; VERSION='6.0.0' ; VERSION_MAJOR=6; VERSION_MINOR=0; VERSION_PATCH=0; VERSION_NUMBER=60000; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
PKGNAME='radare2-extras' ; VERSION='3.2.0' ; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
}
show_usage() {
cat <<EOF2
'configure' configures radare2-extras-6.0.0 to adapt to many kinds of systems.
'configure' configures radare2-extras-3.2.0 to adapt to many kinds of systems.
Usage: ./configure [OPTION]... [VAR=VALUE]...
@@ -145,7 +121,6 @@ Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit
-r, --report show what libs/programs require to work
-q, --quiet be quiet, less verbose (see ./configure -qV)
-V, --version display version information and exit
Installation directories:
@@ -165,7 +140,6 @@ Fine tuning of the installation directories:
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--mandir=DIR man documentation [DATADIR/man]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--etcdir=DIR same as --sysconfdir (/etc)
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
@@ -184,6 +158,7 @@ printf "
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
CPPFLAGS C preprocessor flags
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
nonstandard directory <lib dir>
CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
@@ -203,22 +178,8 @@ take_environ() {
: ${PREFIX:=/usr/local/}
}
ochof() {
[ "$QUIET" = 1 ] && return
printf "$*"
}
ocho() {
[ "$QUIET" = 1 ] && return
echo "$*"
}
show_version() {
if [ "$QUIET" = 1 ]; then
echo "6.0.0"
exit 0
fi
echo "radare2-extras-6.0.0 configuration script done with acr v2.2.4.
echo "radare2-extras-3.2.0 configuration script done with acr v1.7.0.
The 'Free Software Foundation' message is only for autodetection.
Originally written by pancake <nopcode.org>."
exit 0
@@ -238,22 +199,15 @@ fi
case $flag in
-h|--help|--hel|--h|--he|-help)
show_usage ; ;;
-qV|-quiet-version|--quiet-version)
be_quiet
show_version ; ;;
-q|-quiet|--quiet)
be_quiet ; ;;
-V|-version|--version)
show_version ; ;;
-r|--r|--report)
echo "PKGNAME: radare2-extras"
echo "VERSION: 6.0.0"
echo "AUTHOR: pancake"
echo "EMAIL: [email protected]"
echo "LANGS: c"
echo "OPTIONAL: libewf libyara"
echo "PKGCONFIG: r_core libewf unicorn yara"
echo "FLAGS: --with-ostype=auto --without-ewf"
echo "PKGNAME: radare2-extras"
echo "VERSION: 3.2.0"
echo "LANGS: c"
echo "OPTIONAL: libewf libyara"
echo "PKG-CONFIG: r_core libewf unicorn yara"
echo "FLAGS: --with-ostype=auto --without-ewf"
exit 0
;;
--cache-file)
@@ -283,22 +237,16 @@ echo "FLAGS: --with-ostype=auto --without-ewf"
--datadir)
DATADIR="$value"; ;;
--sysconfdir)
SYSCONFDIR="$value"
ETCDIR="$value"; ;;
--etcdir)
SYSCONFDIR="$value"
ETCDIR="$value"; ;;
SYSCONFDIR="$value"; ;;
--sharedstatedir)
SHAREDSTATEDIR="$value"; ;;
--localstatedir)
LOCALSTATEDIR="$value"; ;;
--libdir)
LIBDIR="$value"
PKGCFG_LIBDIR="$value"; ;;
LIBDIR="$value"; ;;
--libpath)
LDFLAGS="${LDFLAGS} ${LIBPATH}$value"; ;;
--includedir)
PKGCFG_INCDIR="$value"
INCLUDEDIR="$value"; CFLAGS="${CFLAGS} -I$value"; ;;
--infodir)
INFODIR="$value"; ;;
@@ -324,68 +272,38 @@ parse_options "$1"
shift
done
ENVWORDS="MANDIR DESCRIPTION INFODIR LIBDIR INCLUDEDIR LOCALSTATEDIR ETCDIR SYSCONFDIR DATADIR DOCDIR LIBEXECDIR SBINDIR BINDIR EPREFIX PREFIX SPREFIX TARGET HOST BUILD INSTALL INSTALL_LIB INSTALL_MAN INSTALL_PROGRAM INSTALL_PROGRAM_STRIP INSTALL_DIR INSTALL_SCRIPT INSTALL_DATA HOST_OS HOST_CPU BUILD_OS BUILD_CPU TARGET_OS TARGET_CPU VERSION VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_NUMBER PKGCFG_LIBDIR PKGCFG_INCDIR PKGNAME VPATH CONTACT CONTACT_NAME CONTACT_MAIL PKGCONFIG CC CFLAGS CPPFLAGS LDFLAGS HAVE_LANG_C R2_CFLAGS R2_LDFLAGS HAVE_PKGCFG_R_CORE USEROSTYPE HAVE_LIB_EWF EWF_CFLAGS EWF_LDFLAGS HAVE_PKGCFG_LIBEWF WANT_EWF UC_CFLAGS UC_LDFLAGS HAVE_PKGCFG_UNICORN HAVE_LIB_YARA YARA_CFLAGS YARA_LDFLAGS HAVE_PKGCFG_YARA"
ENVWORDS="MANDIR INFODIR LIBDIR INCLUDEDIR LOCALSTATEDIR SYSCONFDIR DATADIR DOCDIR LIBEXECDIR SBINDIR BINDIR EPREFIX PREFIX SPREFIX TARGET HOST BUILD INSTALL INSTALL_LIB INSTALL_MAN INSTALL_PROGRAM INSTALL_PROGRAM_STRIP INSTALL_DIR INSTALL_SCRIPT INSTALL_DATA HOST_OS HOST_CPU BUILD_OS BUILD_CPU TARGET_OS TARGET_CPU PKGNAME VPATH VERSION CONTACT CONTACT_NAME CONTACT_MAIL CC CFLAGS CPPFLAGS LDFLAGS HAVE_LANG_C R2_CFLAGS R2_LDFLAGS HAVE_PKGCFG_R_CORE USEROSTYPE HAVE_LIB_EWF EWF_CFLAGS EWF_LDFLAGS HAVE_PKGCFG_LIBEWF WANT_EWF UC_CFLAGS UC_LDFLAGS HAVE_PKGCFG_UNICORN HAVE_LIB_YARA YARA_CFLAGS YARA_LDFLAGS HAVE_PKGCFG_YARA"
create_environ
ocho "checking build system type... ${BUILD}"
ocho "checking host system type... ${HOST}"
ocho "checking target system type... ${TARGET}"
echo "checking build system type... ${BUILD}"
echo "checking host system type... ${HOST}"
echo "checking target system type... ${TARGET}"
[ "${CROSSBUILD}" = 1 ] && echo "using crosscompilation mode."
#split_host BUILD HOST TARGET
[ -n "${prefix}" ] && PREFIX="${prefix}"
ocho "checking for working directories... ${WODIS}"
ocho "using prefix '${PREFIX}'"
echo "checking for working directories... ${WODIS}"
echo "using prefix '${PREFIX}'"
ACR_RMFILES=" test.c a.out a.exe"
ochof "checking for pkg-config... "
ENVWORDS="${ENVWORDS} HAVE_PKGCONFIG"
if [ -n "$PKGCONFIG" ]; then
if [ -x "$PKGCONFIG" ]; then
_HAVE_PKGCONFIG="${PKGCONFIG}"
else
ocho "PKGCONFIG env is not executable"
PKGCONFIG=""
fi
else
IFS=:
for A in ${PATH} ; do
if [ -x "${A}/pkg-config" ]; then
PKGCONFIG="${A}/pkg-config"
elif [ -x "${A}/pkgconf" ]; then
PKGCONFIG="${A}/pkgconf"
else
continue
fi
break
done
unset IFS
fi
if [ -n "${PKGCONFIG}" ]; then
ocho ${PKGCONFIG}
HAVE_PKGCONFIG=1
else
HAVE_PKGCONFIG=0
echo "Cannot find pkg-config or pkgconf in PATH" >&2
exit 1
ocho no; fi
COMPILER=CC
ochof "checking for c compiler... "
printf "checking for c compiler... "
HAVE_LANG_C=1
if [ "${CROSSBUILD}" = 1 ]; then
(command -v ${HOST}-${CC} >/dev/null 2>&1)
if [ $? = 0 ]; then CC="${HOST}-${CC}"; fi
fi
echo "int main(int argc, char **argv){return 0;}" > test.c
(exec ${CC} -o a.out ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} test.c >/dev/null 2>&1)
(exec ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} test.c >/dev/null 2>&1)
if [ $? = 0 ]; then echo ${CC}; else
echo no ; HAVE_LANG_C=0
do_remove
echo "ERROR: ${CC} cannot create executables" >&2 ;
exit 1 ; fi
if [ -z "${PKGCONFIG}" ]; then pkg-config --version >/dev/null 2>&1 ; if [ 0 = 0 ]; then PKGCONFIG=pkg-config ; else PKGCONFIG=pkgconf ; fi; fi
type ${PKGCONFIG} > /dev/null 2>&1 || echo "ERROR: Cannot find valid PKGCONFIG, pkg-config or pkgconf in PATH"
[ -z "${PKGCONFIG}" ] && PKGCONFIG=pkg-config
type ${PKGCONFIG} > /dev/null 2>&1 || echo "ERROR: Cannot find PKGCONFIG ${PKGCONFIG}"
echo 'Using PKGCONFIG: '${PKGCONFIG}
printf 'checking pkg-config flags for r_core... '
tmp=`${PKGCONFIG} --cflags r_core 2>/dev/null`
@@ -405,7 +323,7 @@ S="$"
_REQUIRED=$3
_CHKLIB_NAME=$2
_CHKLIB_LIBS=$(echo "-l${_CHKLIB_NAME}" | sed 's,+, -l,g')
ochof "checking for lib${_CHKLIB_NAME} ... "
printf "checking for lib${_CHKLIB_NAME} ... "
echo "int main(int ac, char **av){return 0;}" > test.c
eval ${S}${COMPILER} ${CFLAGS} ${CPPFLAGS} ${CXXFLAGS} ${LDFLAGS} ${_CHKLIB_LIBS} test.c >/dev/null 2>&1
if [ $? = 0 ]; then
@@ -423,7 +341,7 @@ fi
}
check_library HAVE_LIB_EWF ewf 0
if [ -z "${PKGCONFIG}" ]; then pkg-config --version >/dev/null 2>&1 ; if [ 0 = 0 ]; then PKGCONFIG=pkg-config ; else PKGCONFIG=pkgconf ; fi; fi
[ -z "${PKGCONFIG}" ] && PKGCONFIG=pkg-config
printf 'checking pkg-config flags for libewf... '
tmp=`${PKGCONFIG} --cflags libewf 2>/dev/null`
if [ $? != 0 ]; then echo no ; HAVE_PKGCFG_LIBEWF=0;
@@ -440,7 +358,7 @@ else
HAVE_LIB_EWF="0"; fi
if [ "$WANT_EWF" = "0" ]; then
HAVE_LIB_EWF="0"; fi
if [ -z "${PKGCONFIG}" ]; then pkg-config --version >/dev/null 2>&1 ; if [ 0 = 0 ]; then PKGCONFIG=pkg-config ; else PKGCONFIG=pkgconf ; fi; fi
[ -z "${PKGCONFIG}" ] && PKGCONFIG=pkg-config
printf 'checking pkg-config flags for unicorn... '
tmp=`${PKGCONFIG} --cflags unicorn 2>/dev/null`
if [ $? != 0 ]; then echo no ; HAVE_PKGCFG_UNICORN=0;
@@ -452,7 +370,7 @@ if [ $? = 0 ]; then
echo yes; HAVE_PKGCFG_UNICORN=1;
UC_LDFLAGS=$tmp; fi; fi
check_library HAVE_LIB_YARA yara 0
if [ -z "${PKGCONFIG}" ]; then pkg-config --version >/dev/null 2>&1 ; if [ 0 = 0 ]; then PKGCONFIG=pkg-config ; else PKGCONFIG=pkgconf ; fi; fi
[ -z "${PKGCONFIG}" ] && PKGCONFIG=pkg-config
printf 'checking pkg-config flags for yara... '
tmp=`${PKGCONFIG} --cflags yara 2>/dev/null`
if [ $? != 0 ]; then echo no ; HAVE_PKGCFG_YARA=0;
@@ -469,14 +387,7 @@ for A in ${ENVWORDS} ; do
[ "${A}" = VPATH ] && continue
[ "${A}" = srcdir ] && continue
eval "VAR=\$${A}"
case "" in
mingw*|cygwin*|msys*)
VAR="`echo ${VAR} | sed -e 's/\\/\\\\/g' -e 's/\,/\\\,/g'`"
;;
*)
VAR="`echo ${VAR} | sed -e 's/\,/\\\,/g'`"
;;
esac
VAR="`echo ${VAR} | sed -e 's/\,/\\\,/g'`"
[ $COUNT = 10 ] && COUNT=0 && SEDFLAGS="${SEDFLAGS}' -e '"
COUNT=$(($COUNT+1))
SEDFLAGS="${SEDFLAGS}s,@${A}@,${VAR},g;"
@@ -494,8 +405,8 @@ if [ -f "${VPATH}/${A}.acr" ]; then
exit 1
fi
fi
ocho "creating ${SD_TARGET}"
[ "${VPATH}" != '.' ] && mkdir -p $(echo ${A} | sed -e "s,/`basename ${A}`$,,g")
echo "creating ${SD_TARGET}"
mkdir -p $(echo ${A} | sed -e "s,/`basename ${A}`$,,g")
cat ${VPATH}/${SD_TARGET}.acr | \
eval sed -e "s,@VPATH@,${VPATH}/${A},g" ${SEDFLAGS} > ${SD_TARGET}.tmp
@@ -514,12 +425,10 @@ done
done
do_remove
if [ "$QUIET" = 0 ]; then
echo
echo "Final report:"
for A in PREFIX ; do
for A in PREFIX ; do # REPORT
eval VAL="\$${A}"
[ -z "${VAL}" ] && VAL="\"\""
[ -z "${VAL}" ] && VAL="(null)"
echo " - ${A} = ${VAL}"
done
fi
+1 -3
View File
@@ -1,9 +1,7 @@
PKGNAME radare2-extras
VERSION 6.0.0
VERSION 3.2.0
CONTACT pancake ; [email protected]
USE_PKGCONFIG!
REPORT PREFIX ;
LANG_C!
+1 -1
View File
@@ -51,7 +51,7 @@ RUN cd /opt/code && \
tar -Jxf ${VALA_TAR}.tar.xz
RUN cd /opt/code/${VALA_TAR}; ./configure --prefix=/usr ; make && make install
# compile radare and bindings
RUN cd /opt/code; git clone https://github.com/radareorg/radare2.git; cd radare2; ./sys/all.sh
RUN cd /opt/code; git clone https://github.com/radare/radare2.git; cd radare2; ./sys/all.sh
#install Go
+1 -1
View File
@@ -28,7 +28,7 @@ RUN cd /opt/code && \
tar -Jxf ${VALA_TAR}.tar.xz
RUN cd /opt/code/${VALA_TAR}; ./configure --prefix=/usr ; make && make install
# compile radare and bindings
RUN cd /opt/code; git clone https://github.com/radareorg/radare2.git; cd radare2; ./sys/all.sh
RUN cd /opt/code; git clone https://github.com/radare/radare2.git; cd radare2; ./sys/all.sh
#install Go
+2 -2
View File
@@ -39,7 +39,7 @@ RUN apt-get install -y python-pip jython
RUN cd /opt/code; wget http://download.gnome.org/sources/vala/0.24/vala-0.24.0.tar.xz; tar -Jxf vala-0.24.0.tar.xz
RUN cd /opt/code/vala-0.24.0; ./configure --prefix=/usr ; make && make install
# compile radare
RUN cd /opt/code; git clone https://github.com/radareorg/radare2.git; cd radare2; ./sys/all.sh
RUN cd /opt/code; git clone https://github.com/radare/radare2.git; cd radare2; ./sys/all.sh
# Clean up APT when done.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
@@ -48,7 +48,7 @@ RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN cd /opt/code; wget http://download.gnome.org/sources/vala/0.24/vala-0.24.0.tar.xz; tar -Jxf vala-0.24.0.tar.xz
RUN cd /opt/code/vala-0.24.0; ./configure --prefix=/usr ; make && make install
# compile radare
RUN cd /opt/code; git clone https://github.com/radareorg/radare2.git; cd radare2; ./sys/all.sh
RUN cd /opt/code; git clone https://github.com/radare/radare2.git; cd radare2; ./sys/all.sh
#install oracle jre stuffs
+2 -2
View File
@@ -23,7 +23,7 @@ RUN apt-get install -y python-pip jython
RUN cd /opt/code; wget http://download.gnome.org/sources/vala/0.24/vala-0.24.0.tar.xz; tar -Jxf vala-0.24.0.tar.xz
RUN cd /opt/code/vala-0.24.0; ./configure --prefix=/usr ; make && make install
# compile radare
RUN cd /opt/code; git clone https://github.com/radareorg/radare2.git; cd radare2; ./sys/all.sh
RUN cd /opt/code; git clone https://github.com/radare/radare2.git; cd radare2; ./sys/all.sh
# Clean up APT when done.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
@@ -32,7 +32,7 @@ RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN cd /opt/code; wget http://download.gnome.org/sources/vala/0.24/vala-0.24.0.tar.xz; tar -Jxf vala-0.24.0.tar.xz
RUN cd /opt/code/vala-0.24.0; ./configure --prefix=/usr ; make && make install
# compile radare
RUN cd /opt/code; git clone https://github.com/radareorg/radare2.git; cd radare2; ./sys/all.sh
RUN cd /opt/code; git clone https://github.com/radare/radare2.git; cd radare2; ./sys/all.sh
#install oracle jre stuffs
-10
View File
@@ -1,10 +0,0 @@
#!/bin/sh
FILE=$1
type addr2line > /dev/null 2>&1
if [ $? = 0 ]; then
ADDRS=`objdump -d "$FILE" |grep :| grep -v 0000000| grep -v Disas|cut -d : -f1`
addr2line -pa -e "$FILE" $ADDRS | sed -e 's,:,,' -e 's,^,CL ,' | grep -v '?'
else
echo "Unable to find 'addr2line' executable in PATH"
exit 1
fi
-23
View File
@@ -1,23 +0,0 @@
R2_PLUGDIR=$(shell r2 -H R2_USER_PLUGINS)
R2_LIBEXT=$(shell r2 -H R2_LIBEXT)
LDFLAGS=-L/opt/homebrew/lib
# VFLAGS+=-gc none
ifeq ($(R2_LIBEXT),)
all:
@echo Cannot find r2
else
all:
v install --once
v fmt -w pdv.v main.v east
v -o a.c -shared pdv.v
LDFLAGS=$(LDFLAGS) v -o pdv.$(R2_LIBEXT) -shared pdv.v
install -m 0755 pdv.$(R2_LIBEXT) $(R2_PLUGDIR)
v $(VFLAGS) -g main.v
./main
setup:
v install
endif
-48
View File
@@ -1,48 +0,0 @@
# VESIL
## Description
V library to provide high level analysis on top of esil
## Usage
See the `main.v` and run it with `make`.
## Known bugs
There are some r2 instances that arent killed somehow by v-r2pipe
## Random
```
paπcake, [3/29/2022 7:03 PM]
typedef struct {
char *name;
void *ref;
} Symbol;
// hook memory reads to find access to variables
// hook register names to track transfers of symbols
"0,rax,:="
:= will trigger reg_write, if 'rax' is associated to a symbol then we can name that operation
for example if rax is associated to the symbol containing the return value of a function
the esil box can create that symbol and handle the function call expression like foo = call()
symbols can be invalidated at any time and their meaning can change backwards.
using esilbox;
int main() {
Symbol *argc = r_esil_box_symbol_new ("argc", "rbp,10,-");
EsilBox *eb = r_esil_box_new ();
r_esil_box_add_symbol (eb, argc);
r_esil_box_set_address (eb, 0x8048000);
do {
r_esil_box_step (eb);
} white (r_esil_box_running (eb));
// eb := esilbox.new()
// eb.set_address(0x80488)
// eb.step()
}
```
-12
View File
@@ -1,12 +0,0 @@
# EAST
Esil Abstract Structured Tree
## Description
This is a work in progress project that aims to provide work in progress
and experimental development towards getting a decompiler on top of the
R2 intermediate language (ESIL).
The main objective of this project is to raise esil to the level where
we can use it for decompilation, type propagation and advanced analysis.
-168
View File
@@ -1,168 +0,0 @@
module east
pub enum NodeStatement {
_none
_break
_switch
_comment
_case
_block
_if
_condition
_symbol
_register
_string
_local
_operation // + - < > << || ...
_return
_function
_else
_for
_argument
_while
_dowhile
_call
_number // number
_goto // symbol or label
_label // symbol
_assign // dst, src
_oparen
_cparen
}
pub struct Node {
pub mut:
name string
typ NodeStatement
// typ EsilType
addr string
pos int
parent int
children []NodeIndex
}
type NodeIndex = int
pub fn (mut e Program) add_name(typ NodeStatement, name string, nodes []NodeIndex) NodeIndex {
ni := e.new_node(name)
mut n := e.node(ni)
n.typ = typ
n.children = nodes
return ni
}
pub fn (mut e Program) add(typ NodeStatement, nodes []NodeIndex) NodeIndex {
return e.add_name(typ, '?', nodes)
}
pub fn (mut e Program) add_operation(name string) NodeIndex {
ni := e.new_node(name)
mut n := e.node(ni)
n.typ = ._operation
return ni
}
pub fn (mut e Program) add_block(addr string) NodeIndex {
ni := e.new_node(addr)
mut n := e.node(ni)
n.typ = ._block
return ni
}
pub fn (mut e Program) add_goto(addr string) NodeIndex {
ni := e.new_node(addr)
mut n := e.node(ni)
n.typ = ._goto
return ni
}
pub fn (mut e Program) add_return(arg string) NodeIndex {
ni := e.new_node(arg)
mut n := e.node(ni)
n.typ = ._return
return ni
}
pub fn (mut e Program) add_label(addr string) NodeIndex {
ni := e.new_node(addr)
mut n := e.node(ni)
n.typ = ._label
return ni
}
pub fn (mut e Program) add_number(addr u64) NodeIndex {
ni := e.new_node('$addr')
mut n := e.node(ni)
n.typ = ._number
return ni
}
pub fn (mut e Program) add_argument(addr u64, name string) NodeIndex {
ni := e.new_node('$name')
mut n := e.node(ni)
n.typ = ._argument
return ni
}
pub fn (mut e Program) add_symbol(addr u64, name string) NodeIndex {
ni := e.new_node('$name')
mut n := e.node(ni)
n.typ = ._symbol
return ni
}
pub fn (mut e Program) add_string(addr u64, name string) NodeIndex {
ni := e.new_node('$name')
mut n := e.node(ni)
n.typ = ._string
return ni
}
pub fn (mut e Program) new_local(addr u64, name string) NodeIndex {
ni := e.new_node('$name')
mut n := e.node(ni)
n.typ = ._local
// f := e.node(e.state().in_function)
return ni
}
pub fn (mut e Program) new_node(name string) NodeIndex {
mut n := &Node{}
n.parent = e.state().last_node
n.name = name
n.addr = e.pc()
n.pos = e.state().pos
e.ast.nodes << n
return e.ast.nodes.len - 1
}
pub fn (mut e Program) node(n int) &Node {
return &e.ast.nodes[n]
}
// XXX not working as expected
pub fn (mut e Program) del_child(n int, c int) {
if n < 0 || n >= e.ast.nodes.len {
return
}
for i, _ in e.node(n).children {
cn := e.node(n).children[int(i)]
if cn == c {
eprintln('$cn vs $c')
mut nn := e.node(n)
if nn.children.len < 1 {
eprintln('delete')
// nn.children.delete(idx)
}
// dump(e.node(e.ast.nodes[n].children)
// break
}
}
}
pub fn (mut e Program) add_child(n int, c int) {
e.ast.nodes[n].children << c
}
pub fn (mut e Program) new_node_condition(name string, a int, b int) {
}
-347
View File
@@ -1,347 +0,0 @@
module east
/*
struct EsilOperation {
name string
}
*/
type EsilOperationCallback = fn (e Program) bool
struct EsilOperation {
mut:
cb EsilOperationCallback
}
enum EsilType {
number
register
command
}
struct EsilState {
mut:
// esil
pos int
last_node int
tokens []string
}
struct East {
pub mut:
// ast
nodes []Node
in_function int
find_type NodeStatement
}
pub interface R2PipeInterface {
cmd(a string) string
}
// TODO: rename to Program
struct Program {
a int
r2 R2PipeInterface
mut:
deep int
stack []string
stack_index []NodeIndex
states []EsilState
ops map[string]EsilOperation
// codegen
ast East
indent_level int
}
pub fn new_program(r2 R2PipeInterface) Program {
mut e := Program{0, r2, 0, []string{}, []NodeIndex{}, []EsilState{}, map[string]EsilOperation{}, East{}, 0}
// XXX unused ops
e.ops['+'] = EsilOperation{fn (e Program) bool {
// pop 2
println('add')
return true
}}
e.ops['-'] = EsilOperation{fn (e Program) bool {
// pop 2
println('sub')
return true
}}
return e
}
pub fn (mut e Program) load_instruction(ni NodeIndex, addr string, expr string) NodeIndex {
// add label
return e.eval(ni, expr)
}
pub fn (mut program Program) new_statement(addr string, esil string) NodeIndex {
block := program.add_name(._block, addr, [])
program.add_child(block, program.add_name(._comment, esil, []))
program.add_child(block, program.add_label(addr))
return program.load_instruction(block, addr, esil)
}
pub fn (mut e Program) new_function(name string, statements []NodeIndex) NodeIndex {
return e.add_name(._function, name, statements)
}
pub fn (mut e Program) load_function(name string) NodeIndex {
e.load_at(name)
mut statements := []NodeIndex{}
for expr in e.r2.cmd('pief').split('\n') {
addr := expr.split(' ')
esil := if addr.len > 1 { addr[1] } else { '' }
statements << e.new_statement(addr[0], esil)
}
return e.new_function(name, statements)
}
pub fn (mut e Program) load_function2(name string) NodeIndex {
mut statements := []NodeIndex{}
e.load_at(name)
bbs := e.r2.cmd('afb@$name').trim_space()
for bb in bbs.split('\n') {
bbw := bb.split(' ')
addr := bbw[0]
mut addr_j := ''
mut addr_f := ''
for j in 0 .. bbw.len {
if bbw[j] == 'j' {
addr_j = bbw[j + 1]
}
if bbw[j] == 'f' {
addr_f = bbw[j + 1]
}
}
println('$addr -> $addr_j -> $addr_f ')
ni := e.add_block(addr)
if addr_j == '' {
// return basic block
e.add_child(ni, e.add_return(''))
} else if addr_f == '' {
// only true jump
e.add_child(ni, e.add_goto(addr_j))
} else {
// have true and false jumps
e.add_child(ni, e.add_goto(addr_j))
e.add_child(ni, e.add_goto(addr_f))
}
statements << ni
}
eprintln(statements)
return e.new_function(name, statements)
}
pub fn (mut e Program) load_at(a string) bool {
e.r2.cmd('aeim;ar0;aei')
e.r2.cmd('s $a;af;aepc $$')
return true
}
pub fn (mut e Program) is_operation(op string) ?EsilOperation {
if op in e.ops {
return e.ops[op]
}
return error('no op')
}
pub fn (mut e Program) step() bool {
expr := e.r2.cmd('aoeq@r:PC')
for tok in expr.split(',') {
println('$tok')
op := e.is_operation(tok) or {
eprintln('oops')
eprintln(err)
break
}
eprintln(op)
}
e.r2.cmd('ar PC=PC+\$l@r:PC')
// e.r2.cmd('aes')
return true
}
pub fn (mut e Program) expr(addr string) string {
return e.r2.cmd('aoeq@$addr').trim_space()
}
pub fn (mut e Program) find_type() EsilType {
s := e.state().tokens[e.state().pos]
// b := if s.len > 0 { s[0] } else { 0 }
if s != '' && s[0] >= `0` && s[0] <= `9` {
return .number
}
return match s {
'+', '-' {
.command
}
else {
.register
}
}
}
pub fn (mut e Program) find_statement_type() NodeStatement {
s := e.state().tokens[e.state().pos]
// b := if s.len > 0 { s[0] } else { 0 }
if s != '' && s[0] >= `0` && s[0] <= `9` {
return ._number
}
return match s {
'+', '+=', '!', '-', '|', '&', '&=', '-=', '*', '*=', '/', '%', '^', '^=', '<<', '>>',
'<<<', '<<<<', '>>>', '>>>>' {
._operation
}
'=[8]', '=[4]', '=[2]', '=[1]' {
._operation
}
'[8]', '[4]', '[2]', '[1]' {
._assign
}
'=', ':=' {
._assign
}
'GOTO' {
._goto
}
'==', '!=' {
._condition
}
else {
._symbol
}
}
}
pub fn (mut e Program) push_state() {
e.states << EsilState{}
}
pub fn (mut e Program) pop_state() {
e.states.pop()
}
pub fn (mut e Program) pop_index() NodeIndex {
if e.stack_index.len == 0 {
return 0
}
return e.stack_index.pop()
}
pub fn (mut e Program) pop() string {
if e.stack.len == 0 {
return ''
}
return e.stack.pop()
}
pub fn (mut e Program) push_index(s NodeIndex) {
e.stack_index << s
}
pub fn (mut e Program) push(s string) {
e.stack << s
}
pub fn (mut e Program) state() &EsilState {
if e.states.len == 0 {
e.push_state()
}
return &e.states[e.states.len - 1]
}
pub fn (mut e Program) eval(ni NodeIndex, esil string) NodeIndex {
e.push_state()
e.state().pos = 0
e.stack = []
e.state().tokens = esil.split(',')
pc := e.pc().u64()
for pos in 0 .. e.state().tokens.len {
e.state().pos = pos
// create node for token nth
node := e.cur_node()
// dump(node)
match node.typ {
._operation {
if false {
dst := e.pop_index()
src := e.pop_index()
// pc := '${e.pc()}.$e.state().pos'.u64()
eqop := e.add_name(._operation, node.name, [
dst,
src,
])
// e.add_symbol(pc, dst), e.add_symbol(pc, src), ])
e.add_child(ni, eqop)
} else {
dst := e.pop()
src := e.pop()
// pc := '${e.pc()}.$e.state().pos'.u64()
eqop := e.add_name(._operation, node.name, [
e.add_symbol(pc, dst),
e.add_symbol(pc, src),
])
// e.add_symbol(pc, dst), e.add_symbol(pc, src), ])
e.add_child(ni, eqop)
}
}
._condition {}
._assign {
dst := e.pop()
src := e.pop()
// eprintln('assign $src $dst')
if false {
_ := e.add_name(._register, dst, [])
_ := e.add_name(._register, src, [])
var_res := e.new_local(4, 'res')
var_rus := e.new_local(4, 'rus')
res_byebye := e.add(._assign, [var_res, var_rus])
e.add_child(ni, res_byebye)
}
eqop := e.add(._assign, [
e.add_symbol(pc, dst),
e.add_symbol(pc, src),
])
e.add_child(ni, eqop)
}
._symbol {
//
e.push(node.name)
e.push_index(pos)
}
._goto {
// process and convert
}
._number {
//
e.push(node.name)
e.push_index(pos)
}
else {
eprintln('unk $node.name')
}
}
// dump(node)
e.state().pos++
}
e.pop_state()
return ni
}
pub fn (mut e Program) cur_node() &Node {
mut n := &Node{}
n.typ = e.find_statement_type()
/*
e.state().push('')
e.state().pop()
*/
n.addr = e.pc()
n.pos = e.state().pos
n.name = e.state().tokens[n.pos]
return n
}
pub fn (e Program) pc() string {
return e.r2.cmd('ar?PC').trim_space()
}
-28
View File
@@ -1,28 +0,0 @@
module east
pub fn (mut e Program) optimize(ni NodeIndex) {
// run different levels of optimizations starting on given node
// this function must replicate the code in print() to walk the ast
// and find optimizations and modify the ast accordingly
e.optimize_const(ni)
// e.optimize_empty(ni)
}
pub fn (mut e Program) optimize_const(ni NodeIndex) {
// propagate constant values and fold unnecessary nodes
}
pub fn (mut e Program) optimize_empty(ni NodeIndex) {
mut n := e.node(ni)
mut children := []NodeIndex{}
for c in n.children {
cn := e.node(c)
if cn.children.len >= 0 {
e.del_child(ni, c)
// children << c
children << c
}
// e.optimize_empty(c)
}
n.children = children
}
-265
View File
@@ -1,265 +0,0 @@
module east
pub fn (mut e Program) str() string {
return e.str_node(0)
}
pub fn (mut e Program) incdent(inc int) {
e.indent_level += inc
}
pub fn (mut e Program) indent() string {
mut s := []string{}
for _ in 0 .. e.indent_level {
s << ''
}
return s.join(' ')
}
pub fn (mut e Program) str_args(idx int) string {
e.ast.find_type = ._argument
s := e.str_code(idx)
e.ast.find_type = ._none
return s.trim_space().split('\n').join(', ')
}
pub fn (mut e Program) str_locals(idx int) string {
e.ast.find_type = ._local
s := e.str_code(idx)
e.ast.find_type = ._none
return s
}
pub fn (mut e Program) str_code(idx int) string {
e.deep++
if e.deep > 10 {
eprintln('yamete kudasai')
e.deep--
return ''
}
mut s := []string{}
n := e.node(idx)
typ := e.ast.find_type
match n.typ {
._call {
sym := e.str_code(n.children[0]).trim_space()
arg := e.str_code(n.children[1]).trim_space()
if typ == ._none {
// s << e.indent()
s << '$sym ($arg)'
} else {
s << sym
s << arg
}
}
._block {
if n.children.len == 0 {
// nothing
} else if typ == ._none {
s << '{\n'
e.incdent(2)
for c in n.children {
e.indent()
s << e.str_code(c) + '\n'
}
e.incdent(-2)
s << e.indent() + '}\n'
} else {
for c in n.children {
s << e.str_code(c)
}
}
}
._function {
if typ == ._none {
args := e.str_args(idx)
s << 'fn ${n.name}($args) {\n'
e.incdent(2)
mut locals := []string{}
for loc in e.str_locals(idx).split('\n') {
if loc !in locals {
if loc != '' {
// TODO: use r2 to resolve type for this variable
locals << loc
}
}
}
for loc in locals {
s << e.indent()
s << 'var $loc\n'
}
for c in n.children {
s << e.indent()
s << e.str_code(c) + '\n'
}
e.incdent(-2)
s << '}\n'
} else {
for c in n.children {
s << e.str_code(c)
}
}
}
._if {
if typ == ._none {
s << 'if '
s << e.str_code(n.children[0])
s << ' {\n'
e.incdent(2)
s << e.str_code(n.children[1])
if n.children.len > 2 {
// TODO: handle else if
e.incdent(-2)
s << e.indent()
s << '} else {\n'
e.incdent(2)
s << e.str_code(n.children[2])
e.incdent(-2)
s << e.indent()
s << '}\n'
} else {
e.incdent(-2)
s << e.indent()
s << '}\n'
}
} else {
s << e.str_code(n.children[0])
s << e.str_code(n.children[1])
if n.children.len > 2 {
s << e.str_code(n.children[2])
}
}
}
._comment {
if typ == ._none {
if n.name != '' {
s << e.indent()
s << '// $n.name '
}
}
}
._operation {
if typ == ._none {
s << e.indent()
if _ := n.name.index('=') {
s << e.str_code(n.children[0])
s << ' $n.name '
s << 'tmp'
} else {
s << 'tmp = '
s << e.str_code(n.children[0])
s << ' $n.name '
// nn := e.node(n.children[1])
// s << ' ($nn) '
dos := e.str_code(n.children[1])
if dos == '' {
s << 'tmp'
} else {
s << dos
}
}
}
}
._condition {
if typ != ._none {
for c in n.children {
s << e.str_code(c)
}
} else {
s << '('
for c in n.children {
s << e.str_code(c).trim_space()
}
s << ')'
}
}
._while {
if typ == ._none {
s << 'while $n.name {\n'
e.incdent(2)
for c in n.children {
s << e.indent()
s << e.str_code(c) + '\n'
}
e.incdent(-2)
s << '}\n'
} else {
for c in n.children {
s << e.str_code(c)
}
}
}
._argument {
if typ == ._none || typ == ._argument {
s << '$n.name\n'
}
}
._assign {
if typ == ._none {
s << e.indent()
s << e.str_code(n.children[0]).trim_space()
s << ' = '
s << e.str_code(n.children[1]).trim_space()
} else {
s << e.str_code(n.children[0])
s << e.str_code(n.children[1])
}
}
._register, ._symbol {
if typ == ._none {
s << '$n.name'
}
}
._number {
if typ == ._none {
s << '$n.name'
}
}
._label {
if typ == ._none && n.name != '' {
s << e.indent() + '$n.name:\n'
}
}
._string {
if typ == ._none {
s << '"$n.name"'
}
}
._local {
if typ == ._none || typ == ._local {
name := '$n.name\n'
if name !in s {
s << name
}
}
}
else {
// eprintln('Unhandled node $n')
}
}
e.deep--
return s.join('')
}
pub fn (mut e Program) str_node(idx int) string {
n := e.node(idx)
mut s := []string{}
/*
s << 'node_name: $n.name\n'
for c in n.children {
s << '- $c\n'
}
s << '## Nodes\n'
for c in e.state().nodes {
s << '- $c\n'
}
s << '## Decompilation\n'
*/
if n.typ == ._function {
//
s << e.str_code(idx)
} else {
eprintln('We can only start decompiling from a function')
}
return s.join('')
}
-194
View File
@@ -1,194 +0,0 @@
import east
import os
import cli { Command, Flag }
import radare.r2pipe
struct Options {
esil string
file string
arch string
}
fn pdvtool() Options {
mut cmd := Command{
name: 'east'
description: 'esil-ast based decompiler on top of r2'
version: '0.0.1'
}
cmd.add_flag(Flag{
flag: .string
name: 'file'
abbrev: 'f'
description: 'program file to open'
})
cmd.add_flag(Flag{
flag: .string
name: 'esil'
abbrev: 'e'
description: 'esil expression to decompile'
})
/*
mut test_cmd := Command{
name: 'test'
description: 'decompile an esil expression'
}
cmd.add_command(test_cmd)
*/
cmd.setup()
cmd.parse(os.args)
if os.args.len == 1 {
exit(1)
}
mut arch := ''
if e := cmd.flags.get_string('arch') {
if e != '' {
arch = e
}
}
mut file := '-'
if e := cmd.flags.get_string('file') {
if e != '' {
file = e
}
}
mut esil := ''
if e := cmd.flags.get_string('esil') {
if e != '' {
esil = e
}
}
return Options{
arch: arch
esil: esil
file: file
}
}
fn main() {
mut opt := pdvtool()
println(opt)
if opt.esil != '' {
main_hello(opt)
} else {
main_hello(opt)
main_hello2()
main_hello3()
}
}
fn main_hello(opt Options) {
r2 := r2pipe.spawn(opt.file, '') or {
eprintln('r2pipe.spawn: $err')
exit(1)
}
if opt.arch != '' {
r2.cmd('e asm.arch=$opt.arch')
}
esil := if opt.esil == '' { '1,eax,:=' } else { opt.esil }
mut program := east.new_program(r2)
mut statements := []east.NodeIndex{}
statements << program.new_statement('0x1000', esil)
mut function := program.new_function('test', statements)
kode := program.str_node(function)
println(kode)
}
fn main_hello2() {
r2 := r2pipe.spawn('test/bins/hello', '') or {
eprintln('r2pipe.spawn: $err')
exit(1)
}
mut program := east.new_program(r2)
func := program.load_function('main')
// test adding node
{
var_res := program.new_local(4, 'res')
var_rus := program.new_local(4, 'rus')
res_byebye := program.add(._assign, [var_res, var_rus])
program.add_child(func, res_byebye)
}
kode := program.str_node(func)
println(kode)
exit(0)
}
fn main_hello3() {
r2 := r2pipe.spawn('test/bins/hello', '') or {
eprintln('r2pipe.spawn: $err')
exit(1)
}
mut e := east.new_program(r2)
// e.on('reg_read', fn (name) => { if name == 'PC' { } })
/*
e.add_symbol('esi', 'arg0')
e.add_symbol('rsi', 'arg0')
e.add_symbol('esi', 'arg1')
e.add_symbol('rsi', 'arg1')
if s := e.find_symbol('rsi') {
println('arg0 is accessed')
// e.propagate_symbol()
}
*/
for _ in 0 .. 10 {
pc := e.pc()
e.step()
expr := e.expr(pc)
e.eval(0, expr)
eprintln('before($pc) now($e.pc()) $expr')
}
/*
e.add_type('int', 'int')
e.add_type('hello_t', 'struct { int msg; }')
*/
sym_puts := e.add_symbol(0x808080, 'puts')
sym_win := e.add_string(0, 'win')
sym_fail := e.add_string(0, 'fail')
cn_bb_true := e.add(._block, [
e.add(._call, [sym_puts, sym_win]),
])
cn_bb_false := e.add(._block, [
e.add(._call, [sym_puts, sym_fail]),
])
arg_argc := e.add_argument(0, 'argc')
cn_cmp := e.add(._condition, [
arg_argc,
e.add_operation('<'),
e.add_number(10),
])
ifelse := e.add(._if, [
cn_cmp,
cn_bb_true,
cn_bb_false,
])
sym_byebye := e.add_string(0, 'byebye')
call_byebye := e.add(._call, [sym_puts, sym_byebye])
var_res := e.new_local(4, 'tmp')
res_byebye := e.add(._assign, [var_res, call_byebye])
sym_exit := e.add_symbol(0, 'exit')
call_exit := e.add(._call, [sym_exit, var_res])
n_func := e.add(._function, [
ifelse,
res_byebye,
call_exit,
])
e.node(n_func).name = 'main'
// optimize function
e.optimize(n_func)
code := e.str_node(n_func)
println(code)
r2.cmd('q')
}
-75
View File
@@ -1,75 +0,0 @@
module pdv
import east
import json
import radare.r2
struct R2ijcore {
file string
size int
fd int
}
struct R2ij {
core R2ijcore
}
pub struct RCore {}
fn plugin_call(coreptr voidptr, cmd &char) int {
// eprintln('cal')
core := r2.cast(coreptr)
c := unsafe { cmd.vstring() }
if c.starts_with('pdv') {
core.cmd('?E decompiler not yet integrated')
ij := core.cmd('ij')
a := json.decode(R2ij, ij) or {
eprintln('failed to decode ij JSON')
return 0
}
eprintln(a.core.file)
//
r2p := r2.cast(core)
mut e := east.new_program(r2p)
fname := r2p.cmd('afi.')
if fname.len > 0 {
func := e.load_function(fname)
e.optimize(func)
kode := e.str_node(func)
println(kode)
} else {
eprintln('No function?')
}
// e.free ()
return 1
}
return 0
}
// definition
// ignored
[export: 'radare_plugin_function']
[manual_free]
fn radare_plugin_function() &C.r_lib_struct_t {
pdv_plugin := &C.r_core_plugin_t{
name: 'pdv'.str
desc: 'the v decompiler for r2'.str
license: 'MIT'.str
call: plugin_call
}
unsafe {
pp := C.malloc(1024) // too large
C.memcpy(pp, pdv_plugin, 1024)
p := &C.r_lib_struct_t{
@type: C.R_LIB_TYPE_CORE
data: pp // &pdv_plugin
pkgname: 'pdv'.str
}
ppp := C.malloc(1024) // too large
C.memcpy(ppp, p, 1024)
return ppp
}
// C.fprintf(C.stderr, '%p\n'.str, p)
// return p
}
Binary file not shown.
-19
View File
@@ -1,19 +0,0 @@
#include <stdio.h>
void fn_hello(void) {
puts ("Hello World");
}
int fn_ifelse(int argc) {
if (argc < 3) {
puts ("one");
return 1;
}
return 0;
}
int main(int argc) {
fn_hello ();
int res = fn_ifelse (argc);
return res;
}
Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
Module {
name: 'east'
description: 'An ESIL-based decommpiler for r2 written in V'
version: '0.1.0'
author: 'pancake'
license: 'MIT'
repo_url: 'https://github.com/vlang/v'
dependencies: ['radare.r2', 'radare.r2pipe']
}
-29
View File
@@ -1,29 +0,0 @@
D=$(DESTDIR)/$(shell r2 -H R2_USER_PLUGINS)/iref-db
BINDIR=$(shell r2pm -H R2PM_BINDIR)
B=$(DESTDIR)/$(BINDIR)/
all:
clean:
install: user-install
user-uninstall uninstall:
rm -f "$(B)/iref"
rm -rf "$(D)"
user-install:
mkdir -p "$(B)"
cp iref.sh $(B)/iref
chmod +x $(B)/iref
mkdir -p "$(D)"
tar xJvf iref-db.txz -C $(D)
sync: cutterref
rm -rf iref-db
cd cutterref/archs && tar cJvf ../../iref-db.txz *.sql
cutterref:
git clone https://github.com/yossizap/cutterref
.PHONY: sync all install user-install user-uninstall uninstall clean
-24
View File
@@ -1,24 +0,0 @@
iref
====
This is a commandline version of the cutterref tool.
Installation
------------
```
$ r2pm -ci iref
```
Usage
-----
See this video demo: [https://youtu.be/jne9e_kBS8E](https://youtu.be/jne9e_kBS8E)
```
$ r2 /bin/ls
> "$a=!!iref x86-64 `ao~mnemonic[1]`"
> $a
> !iref x86-64 nop
```
BIN
View File
Binary file not shown.
-28
View File
@@ -1,28 +0,0 @@
#!/bin/sh
A="$1"
M="`echo $2 |tr '[a-z]' '[A-Z]'`"
R2_USER_PLUGINS=$(r2 -H R2_USER_PLUGINS)
if [ -z "$A" ]; then
echo "Usage: iref [arch] ([insn])"
if [ ! -d iref-db ]; then
cd "$R2_USER_PLUGINS" || exit 1
fi
cd iref-db
ls |sed -e 's,.sql,,'
exit 1
fi
if [ ! -f "iref-db/$A.sql" ]; then
cd "$R2_USER_PLUGINS" || exit 1
if [ ! -f "iref-db/$A.sql" ]; then
echo "Cannot load $A"
exit 1
fi
fi
if [ -z "$M" ]; then
echo "select mnem from instructions" | sqlite3 -init iref-db/$A.sql | tr 'A-Z' 'a-z'
else
echo "select description from instructions where mnem = '$M'" | sqlite3 -init iref-db/$A.sql
fi
+8 -11
View File
@@ -1,8 +1,8 @@
include build.mk
PLUGINS=arm x86 mips sparc ppc hexagon s390x evm
PLUGINS=arm x86 mips sparc ppc hexagon sysz
LIBS=$(addsuffix _ks.$(SO_EXT),$(addprefix arch_,${PLUGINS}))
LIBS=$(addsuffix _ks.$(SO_EXT),$(addprefix asm_,${PLUGINS}))
#R2PM_PLUGDIR?=${LIBDIR}/radare2/last/
R2PM_PLUGDIR?=~/.config/radare2/plugins
R2PM_PREFIX?=~/.config/radare2/prefix
@@ -23,30 +23,27 @@ all: $(PLUGINS)
define kscc
$(CC) -c -fPIC -Wall\
$(R2_CFLAGS) $(KS_CFLAGS)\
-o arch_$(1)_ks.$(O_EXT) arch_$(1)_ks.c
-o asm_$(1)_ks.$(O_EXT) asm_$(1)_ks.c
$(CXX) $(LDFLAGS_SHARED)\
$(R2_LDFLAGS) $(KS_LDFLAGS)\
-o arch_$(1)_ks.$(SO_EXT) arch_$(1)_ks.$(O_EXT) $(KS_LINK)
rm arch_$(1)_ks.$(O_EXT)
-o asm_$(1)_ks.$(SO_EXT) asm_$(1)_ks.$(O_EXT) $(KS_LINK)
rm asm_$(1)_ks.$(O_EXT)
endef
define ksmake
arch_$(1)_ks.$(SO_EXT): arch_$(1)_ks.c keystone.c
asm_$(1)_ks.$(SO_EXT): asm_$(1)_ks.c keystone.c
$$(call kscc,$(1))
endef
$(foreach lib,$(PLUGINS),$(eval $(call ksmake,$(lib))))
$(PLUGINS):
$(MAKE) arch_$@_ks.$(SO_EXT)
$(MAKE) asm_$@_ks.$(SO_EXT)
install:
$(foreach lib,$(LIBS),$(INSTALL_LIB) $(lib) $(R2PM_PLUGDIR);)
user-install:
$(foreach lib,$(LIBS),$(INSTALL_LIB) $(lib) $(R2PM_PLUGDIR);)
user-uninstall uninstall:
uninstall:
rm -rf $(R2PM_PLUGDIR)/*_ks.*
test:
-46
View File
@@ -1,46 +0,0 @@
/* radare2-keystone - GPL - Copyright 2016-2023 - pancake */
#include <r_arch.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/arm.h>
#include "keystone.c"
static bool assemble(RArchSession *a, RAnalOp *ao, RArchEncodeMask mask) {
ks_arch arch = KS_ARCH_ARM;
ks_mode mode = KS_MODE_ARM;
switch (a->config->bits) {
case 16:
mode = KS_MODE_THUMB;
break;
case 64:
arch = KS_ARCH_ARM64;
mode = KS_MODE_LITTLE_ENDIAN;
a->config->big_endian = false;
break;
}
if (a->config->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, ao->mnemonic, arch, mode);
}
RArchPlugin r_arch_plugin_arm_ks = {
.meta = {
.name = "arm.ks",
.desc = "ARM keystone assembler",
.license = "GPL",
},
.arch = "arm",
.bits = R_SYS_BITS_PACK3 (16, 32, 64),
.encode = &assemble,
.decode = NULL,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ARCH,
.data = &r_arch_plugin_arm_ks,
.version = R2_VERSION
};
#endif
-34
View File
@@ -1,34 +0,0 @@
/* radare2-keystone - GPL - Copyright 2016-2023 - pancake */
#include <r_arch.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/evm.h>
#include "keystone.c"
static bool assemble(RArchSession *a, RAnalOp *ao, RArchEncodeMask mask) {
ks_mode mode = (ks_mode)0;
if (a->config->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, ao->mnemonic, KS_ARCH_SYSTEMZ, mode);
}
RArchPlugin r_arch_plugin_evm_ks = {
.meta = {
.name = "evm.ks",
.desc = "EVM keystone assembler",
.license = "GPL",
},
.arch = "evm",
.bits = 32,
.encode = &assemble,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ARCH,
.data = &r_arch_plugin_evm_ks,
.version = R2_VERSION
};
#endif
-34
View File
@@ -1,34 +0,0 @@
/* radare2-keystone - GPL - Copyright 2016 - pancake */
#include <r_arch.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/hexagon.h>
#include "keystone.c"
static bool assemble(RArchSession *a, RAnalOp *ao, RArchEncodeMask mask) {
ks_mode mode = (ks_mode)0;
if (a->config->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, ao->mnemonic, KS_ARCH_HEXAGON, mode);
}
RArchPlugin r_arch_plugin_hexagon_ks = {
.meta = {
.name = "hexagon.ks",
.desc = "Hexagon keystone assembler",
.license = "GPL",
},
.arch = "hexagon",
.bits = 32,
.encode = &assemble,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ARCH,
.data = &r_arch_plugin_hexagon_ks,
.version = R2_VERSION
};
#endif
-45
View File
@@ -1,45 +0,0 @@
/* radare2-keystone - GPL - Copyright 2016-2023 - pancake */
#include <r_arch.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/mips.h>
#include "keystone.c"
static bool assemble(RArchSession *a, RAnalOp *ao, RArchEncodeMask mask) {
ks_mode mode;
switch (a->config->bits) {
case 16:
mode = KS_MODE_MICRO; // micromips mode
break;
case 32:
mode = KS_MODE_MIPS32;
break;
case 64:
mode = KS_MODE_MIPS64;
break;
}
if (a->config->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, ao->mnemonic, KS_ARCH_MIPS, mode);
}
RArchPlugin r_arch_plugin_mips_ks = {
.meta = {
.name = "mips.ks",
.desc = "MIPS keystone assembler",
.license = "GPL",
},
.arch = "mips",
.bits = R_SYS_BITS_PACK3 (16, 32, 64),
.encode = &assemble,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ARCH,
.data = &r_arch_plugin_mips_ks,
.version = R2_VERSION
};
#endif
-42
View File
@@ -1,42 +0,0 @@
/* radare2-keystone - GPL - Copyright 2016-2023 - pancake */
#include <r_arch.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/ppc.h>
#include "keystone.c"
static bool assemble(RArchSession *a, RAnalOp *ao, RArchEncodeMask mask) {
ks_mode mode = (ks_mode)0;
switch (a->config->bits) {
case 32:
mode = KS_MODE_PPC32;
break;
case 64:
mode = KS_MODE_PPC64;
break;
}
if (a->config->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, ao->mnemonic, KS_ARCH_PPC, mode);
}
RArchPlugin r_arch_plugin_ppc_ks = {
.meta = {
.name = "ppc.ks",
.desc = "powerpc keystone assembler",
.license = "GPL",
},
.arch = "ppc",
.bits = R_SYS_BITS_PACK2 (32,64),
.encode = &assemble,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ARCH,
.data = &r_arch_plugin_ppc_ks,
.version = R2_VERSION
};
#endif
-34
View File
@@ -1,34 +0,0 @@
/* radare2-keystone - GPL - Copyright 2016-2023 - pancake */
#include <r_arch.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/systemz.h>
#include "keystone.c"
static bool assemble(RArchSession *a, RAnalOp *ao, RArchEncodeMask mask) {
ks_mode mode = (ks_mode)0;
if (a->config->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, ao->mnemonic, KS_ARCH_SYSTEMZ, mode);
}
RArchPlugin r_arch_plugin_s390x_ks = {
.meta = {
.name = "s390x.ks",
.desc = "SystemZ keystone assembler (S390X)",
.license = "GPL",
},
.arch = "s390x",
.bits = 32,
.encode = &assemble,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ARCH,
.data = &r_arch_plugin_s390x_ks,
.version = R2_VERSION
};
#endif
-42
View File
@@ -1,42 +0,0 @@
/* radare2-keystone - GPL - Copyright 2016 - pancake */
#include <r_arch.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/sparc.h>
#include "keystone.c"
static bool assemble(RArchSession *a, RAnalOp *ao, RArchEncodeMask mask) {
ks_mode mode = (ks_mode)0;
switch (a->config->bits) {
case 32:
mode = KS_MODE_SPARC32;
break;
case 64:
mode = KS_MODE_SPARC64;
break;
}
if (a->config->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, ao->mnemonic, KS_ARCH_SPARC, mode);
}
RArchPlugin r_arch_plugin_sparc_ks = {
.meta = {
.name = "sparc.ks",
.desc = "sparc keystone assembler",
.license = "GPL",
},
.arch = "sparc",
.bits = R_SYS_BITS_PACK2 (32, 64),
.encode = &assemble,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ARCH,
.data = &r_arch_plugin_sparc_ks,
.version = R2_VERSION
};
#endif
-42
View File
@@ -1,42 +0,0 @@
/* radare2-keystone - GPL - Copyright 2016-2023 - pancake */
#include <r_arch.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/x86.h>
#include "keystone.c"
static bool assemble(RArchSession *a, RAnalOp *ao, RArchEncodeMask mask) {
ks_mode mode = (ks_mode)0;
switch (a->config->bits) {
case 16:
mode = KS_MODE_16;
break;
case 32:
mode = KS_MODE_32;
break;
case 64:
mode = KS_MODE_64;
break;
}
return keystone_assemble (a, ao, ao->mnemonic, KS_ARCH_X86, mode);
}
RArchPlugin r_arch_plugin_x86_ks = {
.meta = {
.name = "x86.ks",
.desc = "x86 keystone assembler",
.license = "GPL",
},
.arch = "x86",
.bits = R_SYS_BITS_PACK3 (16, 32, 64),
.encode = &assemble,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ARCH,
.data = &r_arch_plugin_x86_ks,
.version = R2_VERSION
};
#endif
+43
View File
@@ -0,0 +1,43 @@
/* radare2-keystone - GPL - Copyright 2016 - pancake */
#include <r_asm.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/arm.h>
#include "keystone.c"
static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
ks_arch arch = KS_ARCH_ARM;
ks_mode mode = KS_MODE_ARM;
switch (a->bits) {
case 16:
mode = KS_MODE_THUMB;
break;
case 64:
arch = KS_ARCH_ARM64;
mode = KS_MODE_LITTLE_ENDIAN;
a->big_endian = false;
break;
}
if (a->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, str, arch, mode);
}
RAsmPlugin r_asm_plugin_arm_ks = {
.name = "arm.ks",
.desc = "ARM keystone assembler",
.license = "GPL",
.arch = "arm",
.bits = 16|32|64,
.assemble = &assemble,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_arm_ks,
.version = R2_VERSION
};
#endif
+32
View File
@@ -0,0 +1,32 @@
/* radare2-keystone - GPL - Copyright 2016 - pancake */
#include <r_asm.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/hexagon.h>
#include "keystone.c"
static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
ks_mode mode = (ks_mode)0;
if (a->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, str, KS_ARCH_HEXAGON, mode);
}
RAsmPlugin r_asm_plugin_hexagon_ks = {
.name = "hexagon.ks",
.desc = "Hexagon keystone assembler",
.license = "GPL",
.arch = "hexagon",
.bits = 32,
.assemble = &assemble,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_hexagon_ks,
.version = R2_VERSION
};
#endif
+43
View File
@@ -0,0 +1,43 @@
/* radare2-keystone - GPL - Copyright 2016 - pancake */
#include <r_asm.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/mips.h>
#include "keystone.c"
static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
ks_mode mode;
switch (a->bits) {
case 16:
mode = KS_MODE_MICRO; // micromips mode
break;
case 32:
mode = KS_MODE_MIPS32;
break;
case 64:
mode = KS_MODE_MIPS64;
break;
}
if (a->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, str, KS_ARCH_MIPS, mode);
}
RAsmPlugin r_asm_plugin_mips_ks = {
.name = "mips.ks",
.desc = "MIPS keystone assembler",
.license = "GPL",
.arch = "mips",
.bits = 16|32|64,
.assemble = &assemble,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_mips_ks,
.version = R2_VERSION
};
#endif
+40
View File
@@ -0,0 +1,40 @@
/* radare2-keystone - GPL - Copyright 2016 - pancake */
#include <r_asm.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/ppc.h>
#include "keystone.c"
static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
ks_mode mode = (ks_mode)0;
switch (a->bits) {
case 32:
mode = KS_MODE_PPC32;
break;
case 64:
mode = KS_MODE_PPC64;
break;
}
if (a->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, str, KS_ARCH_PPC, mode);
}
RAsmPlugin r_asm_plugin_ppc_ks = {
.name = "ppc.ks",
.desc = "powerpc keystone assembler",
.license = "GPL",
.arch = "ppc",
.bits = 32|64,
.assemble = &assemble,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_ppc_ks,
.version = R2_VERSION
};
#endif
+40
View File
@@ -0,0 +1,40 @@
/* radare2-keystone - GPL - Copyright 2016 - pancake */
#include <r_asm.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/sparc.h>
#include "keystone.c"
static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
ks_mode mode = (ks_mode)0;
switch (a->bits) {
case 32:
mode = KS_MODE_SPARC32;
break;
case 64:
mode = KS_MODE_SPARC64;
break;
}
if (a->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, str, KS_ARCH_SPARC, mode);
}
RAsmPlugin r_asm_plugin_sparc_ks = {
.name = "sparc.ks",
.desc = "sparc keystone assembler",
.license = "GPL",
.arch = "sparc",
.bits = 32|64,
.assemble = &assemble,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_sparc_ks,
.version = R2_VERSION
};
#endif
+32
View File
@@ -0,0 +1,32 @@
/* radare2-keystone - GPL - Copyright 2016 - pancake */
#include <r_asm.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/systemz.h>
#include "keystone.c"
static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
ks_mode mode = (ks_mode)0;
if (a->big_endian) {
mode = (ks_mode)((int)mode | KS_MODE_BIG_ENDIAN);
}
return keystone_assemble (a, ao, str, KS_ARCH_SYSTEMZ, mode);
}
RAsmPlugin r_asm_plugin_sysz_ks = {
.name = "sysz.ks",
.desc = "SystemZ keystone assembler (S390X)",
.license = "GPL",
.arch = "sysz",
.bits = 32,
.assemble = &assemble,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_sysz_ks,
.version = R2_VERSION
};
#endif
+40
View File
@@ -0,0 +1,40 @@
/* radare2-keystone - GPL - Copyright 2016 - pancake */
#include <r_asm.h>
#include <r_lib.h>
#include <keystone/keystone.h>
#include <keystone/x86.h>
#include "keystone.c"
static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
ks_mode mode = (ks_mode)0;
switch (a->bits) {
case 16:
mode = KS_MODE_16;
break;
case 32:
mode = KS_MODE_32;
break;
case 64:
mode = KS_MODE_64;
break;
}
return keystone_assemble (a, ao, str, KS_ARCH_X86, mode);
}
RAsmPlugin r_asm_plugin_x86_ks = {
.name = "x86.ks",
.desc = "x86 keystone assembler",
.license = "GPL",
.arch = "x86",
.bits = 16 | 32 | 64,
.assemble = &assemble,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_x86_ks,
.version = R2_VERSION
};
#endif
+2 -2
View File
@@ -4,8 +4,8 @@ LDFLAGS=@LDFLAGS@
R2_CFLAGS=@R2_CFLAGS@
R2_LDFLAGS=@R2_LDFLAGS@
KS_CFLAGS=@KS_CFLAGS@
KS_LDFLAGS=@KS_LDFLAGS@
HAVE_LIB_KEYSTONE=@HAVE_LIB_KEYSTONE@
BUILD_OS=@BUILD_OS@
+56 -131
View File
@@ -1,5 +1,5 @@
#!/bin/sh
# This script was automatically generated by ACR v2.2.4
# This script was automatically generated by ACR v1.7.0
# @author: pancake <nopcode.org>
# @url: http://www.nopcode.org
# @repo: git clone https://github.com/radare/acr
@@ -39,11 +39,6 @@ shift
done
}
QUIET=0
be_quiet() {
QUIET=1
}
VPATH=`dirname ${0}`
if [ "${VPATH}" = "." ]; then
WODIS=current
@@ -65,27 +60,12 @@ if [ -e "${VPATH}/config.guess" ]; then
sh ${VPATH}/config.guess
return
fi
CPU="`uname -m | tr 'A-Z' 'a-z' | sed -e 's, ,,g' | cut -d - -f 1`"
CPU="`uname -m|sed -e 's, ,,g'|cut -d - -f 1`"
OS="`uname -s|tr A-Z a-z`"
uname -r | grep -qE "(Microsoft|WSL)" 2>/dev/null && OS="wsl"
GNU="`uname --help 2>&1 | grep gnu`"
[ "${GNU}" ] && OS="${OS}-gnu"
# normalize CPU
case "${CPU}" in
ppc*|powermac*|powermacintosh*|powerpc*)
if echo "${CPU}" | grep -q '64'; then
CPU=powerpc64
else
CPU=powerpc
fi
;;
*) ;;
esac
VENDOR="unknown"
if [ "${OS}" = "darwin" ]; then
VENDOR=apple
fi
echo "${CPU}-${VENDOR}-${OS}"
[ "${CPU}" = ppc ] && CPU="powerpc"
echo "${CPU}-unknown-${OS}"
}
SEARCHPATH="/usr /usr/local /usr/pkg /sw"
@@ -95,19 +75,15 @@ CROSSBUILD=0
BUILD=`guess_os`
HOST="${BUILD}"
TARGET="${HOST}"
ETCDIR="/etc"
SYSCONFDIR=""
DESCRIPTION=""
create_environ() {
: ${EPREFIX:="${PREFIX}"}
: ${SPREFIX:="${PREFIX}"}
: ${BINDIR:="${SPREFIX}/bin"}
: ${SBINDIR:="${PREFIX}/sbin"}
: ${ETCDIR:="${SPREFIX}/etc"}
: ${SYSCONFDIR:="${SPREFIX}/etc"}
: ${LIBDIR:="${SPREFIX}/lib"}
: ${PKGCFG_LIBDIR:='${exec_prefix}/lib'}
: ${PKGCFG_INCDIR:='${prefix}/include'}
: ${LIBEXECDIR:="${SPREFIX}/libexec"}
: ${INCLUDEDIR:="${SPREFIX}/include"}
: ${DATADIR:="${SPREFIX}/share"}
@@ -126,12 +102,12 @@ done
: ${INSTALL_PROGRAM_STRIP:=${INSTALL} -m 755 -s}
: ${INSTALL_MAN:=${INSTALL} -m 444}
: ${INSTALL_LIB:=${INSTALL} -m 755 -c}
PKGNAME='radare2-keystone' ; VERSION='0.2' ; VERSION_MAJOR=0; VERSION_MINOR=2; VERSION_PATCH=0; VERSION_NUMBER=00200; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
PKGNAME='radare2-keystone' ; VERSION='0.1' ; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
}
show_usage() {
cat <<EOF2
'configure' configures radare2-keystone-0.2 to adapt to many kinds of systems.
'configure' configures radare2-keystone-0.1 to adapt to many kinds of systems.
Usage: ./configure [OPTION]... [VAR=VALUE]...
@@ -143,7 +119,6 @@ Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit
-r, --report show what libs/programs require to work
-q, --quiet be quiet, less verbose (see ./configure -qV)
-V, --version display version information and exit
Installation directories:
@@ -163,7 +138,6 @@ Fine tuning of the installation directories:
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--mandir=DIR man documentation [DATADIR/man]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--etcdir=DIR same as --sysconfdir (/etc)
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
@@ -177,6 +151,7 @@ printf "
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
CPPFLAGS C preprocessor flags
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
nonstandard directory <lib dir>
CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
@@ -196,26 +171,12 @@ take_environ() {
: ${CPP:=cpp}
: ${CC:=gcc}
: ${CPP:=cpp}
: ${CXX:=c++}
: ${CXX:=g++}
: ${PREFIX:=/usr/local/}
}
ochof() {
[ "$QUIET" = 1 ] && return
printf "$*"
}
ocho() {
[ "$QUIET" = 1 ] && return
echo "$*"
}
show_version() {
if [ "$QUIET" = 1 ]; then
echo "0.2"
exit 0
fi
echo "radare2-keystone-0.2 configuration script done with acr v2.2.4.
echo "radare2-keystone-0.1 configuration script done with acr v1.7.0.
The 'Free Software Foundation' message is only for autodetection.
Originally written by pancake <nopcode.org>."
exit 0
@@ -235,20 +196,14 @@ fi
case $flag in
-h|--help|--hel|--h|--he|-help)
show_usage ; ;;
-qV|-quiet-version|--quiet-version)
be_quiet
show_version ; ;;
-q|-quiet|--quiet)
be_quiet ; ;;
-V|-version|--version)
show_version ; ;;
-r|--r|--report)
echo "PKGNAME: radare2-keystone"
echo "VERSION: 0.2"
echo "AUTHOR: pancake"
echo "EMAIL: [email protected]"
echo "LANGS: c c++"
echo "PKGCONFIG: r_asm keystone"
echo "PKGNAME: radare2-keystone"
echo "VERSION: 0.1"
echo "LANGS: c c++"
echo "REQUIRED: libkeystone"
echo "PKG-CONFIG: r_asm"
exit 0
;;
--cache-file)
@@ -278,22 +233,16 @@ echo "PKGCONFIG: r_asm keystone"
--datadir)
DATADIR="$value"; ;;
--sysconfdir)
SYSCONFDIR="$value"
ETCDIR="$value"; ;;
--etcdir)
SYSCONFDIR="$value"
ETCDIR="$value"; ;;
SYSCONFDIR="$value"; ;;
--sharedstatedir)
SHAREDSTATEDIR="$value"; ;;
--localstatedir)
LOCALSTATEDIR="$value"; ;;
--libdir)
LIBDIR="$value"
PKGCFG_LIBDIR="$value"; ;;
LIBDIR="$value"; ;;
--libpath)
LDFLAGS="${LDFLAGS} ${LIBPATH}$value"; ;;
--includedir)
PKGCFG_INCDIR="$value"
INCLUDEDIR="$value"; CFLAGS="${CFLAGS} -I$value"; ;;
--infodir)
INFODIR="$value"; ;;
@@ -317,30 +266,33 @@ parse_options "$1"
shift
done
ENVWORDS="MANDIR DESCRIPTION INFODIR LIBDIR INCLUDEDIR LOCALSTATEDIR ETCDIR SYSCONFDIR DATADIR DOCDIR LIBEXECDIR SBINDIR BINDIR EPREFIX PREFIX SPREFIX TARGET HOST BUILD INSTALL INSTALL_LIB INSTALL_MAN INSTALL_PROGRAM INSTALL_PROGRAM_STRIP INSTALL_DIR INSTALL_SCRIPT INSTALL_DATA HOST_OS HOST_CPU BUILD_OS BUILD_CPU TARGET_OS TARGET_CPU VERSION VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_NUMBER PKGCFG_LIBDIR PKGCFG_INCDIR PKGNAME VPATH CONTACT CONTACT_NAME CONTACT_MAIL CC CFLAGS CPPFLAGS LDFLAGS HAVE_LANG_C CXX CXXFLAGS HAVE_LANG_CXX PKGCONFIG R2_CFLAGS R2_LDFLAGS HAVE_PKGCFG_R_ASM KS_CFLAGS KS_LDFLAGS HAVE_PKGCFG_KEYSTONE"
ENVWORDS="MANDIR INFODIR LIBDIR INCLUDEDIR LOCALSTATEDIR SYSCONFDIR DATADIR DOCDIR LIBEXECDIR SBINDIR BINDIR EPREFIX PREFIX SPREFIX TARGET HOST BUILD INSTALL INSTALL_LIB INSTALL_MAN INSTALL_PROGRAM INSTALL_PROGRAM_STRIP INSTALL_DIR INSTALL_SCRIPT INSTALL_DATA HOST_OS HOST_CPU BUILD_OS BUILD_CPU TARGET_OS TARGET_CPU PKGNAME VPATH VERSION CONTACT CONTACT_NAME CONTACT_MAIL CC CFLAGS CPPFLAGS LDFLAGS HAVE_LANG_C CXX CXXFLAGS HAVE_LANG_CXX HAVE_LIB_KEYSTONE R2_CFLAGS R2_LDFLAGS HAVE_PKGCFG_R_ASM"
create_environ
ocho "checking build system type... ${BUILD}"
ocho "checking host system type... ${HOST}"
ocho "checking target system type... ${TARGET}"
echo "checking build system type... ${BUILD}"
echo "checking host system type... ${HOST}"
echo "checking target system type... ${TARGET}"
[ "${CROSSBUILD}" = 1 ] && echo "using crosscompilation mode."
#split_host BUILD HOST TARGET
[ -n "${prefix}" ] && PREFIX="${prefix}"
ocho "checking for working directories... ${WODIS}"
ocho "using prefix '${PREFIX}'"
echo "checking for working directories... ${WODIS}"
echo "using prefix '${PREFIX}'"
ACR_RMFILES=" test.c a.out a.exe test.c test.cxx a.out a.exe"
COMPILER=CC
ochof "checking for c compiler... "
printf "checking for c compiler... "
HAVE_LANG_C=1
if [ "${CROSSBUILD}" = 1 ]; then
(command -v ${HOST}-${CC} >/dev/null 2>&1)
if [ $? = 0 ]; then CC="${HOST}-${CC}"; fi
fi
echo "int main(int argc, char **argv){return 0;}" > test.c
(exec ${CC} -o a.out ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} test.c >/dev/null 2>&1)
(exec ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} test.c >/dev/null 2>&1)
if [ $? = 0 ]; then echo ${CC}; else
echo no ; HAVE_LANG_C=0
do_remove
@@ -348,7 +300,7 @@ echo "ERROR: ${CC} cannot create executables" >&2 ;
exit 1 ; fi
COMPILER=CXX
HAVE_LANG_CXX=1
ochof "checking for c++ compiler... "
printf "checking for c++ compiler... "
if [ "${CROSSBUILD}" = 1 ]; then
(command -v ${HOST}-${CXX} 2>&1 >/dev/null)
if [ "$?" = 0 ]; then CXX="${HOST}-${CXX}"; fi
@@ -364,39 +316,32 @@ echo "ERROR: ${CXX} cannot create executables" >&2 ;
do_remove
exit 1
fi
ochof "checking for pkg-config... "
ENVWORDS="${ENVWORDS} HAVE_PKGCONFIG"
if [ -n "$PKGCONFIG" ]; then
if [ -x "$PKGCONFIG" ]; then
_HAVE_PKGCONFIG="${PKGCONFIG}"
else
ocho "PKGCONFIG env is not executable"
PKGCONFIG=""
check_library() {
VAR=$1
S="$"
_REQUIRED=$3
_CHKLIB_NAME=$2
_CHKLIB_LIBS=$(echo "-l${_CHKLIB_NAME}" | sed 's,+, -l,g')
printf "checking for lib${_CHKLIB_NAME} ... "
echo "int main(int ac, char **av){return 0;}" > test.c
eval ${S}${COMPILER} ${CFLAGS} ${CPPFLAGS} ${CXXFLAGS} ${LDFLAGS} ${_CHKLIB_LIBS} test.c >/dev/null 2>&1
if [ $? = 0 ]; then
eval ${VAR}=1
echo yes
else
eval ${VAR}=0
echo no
if [ "${_REQUIRED}" = 1 ]; then
echo "this library is required."
do_remove
exit 1
fi
else
IFS=:
for A in ${PATH} ; do
if [ -x "${A}/pkg-config" ]; then
PKGCONFIG="${A}/pkg-config"
elif [ -x "${A}/pkgconf" ]; then
PKGCONFIG="${A}/pkgconf"
else
continue
fi
break
done
unset IFS
fi
if [ -n "${PKGCONFIG}" ]; then
ocho ${PKGCONFIG}
HAVE_PKGCONFIG=1
else
HAVE_PKGCONFIG=0
echo "Cannot find pkg-config or pkgconf in PATH" >&2
exit 1
ocho no; fi
if [ -z "${PKGCONFIG}" ]; then pkg-config --version >/dev/null 2>&1 ; if [ 0 = 0 ]; then PKGCONFIG=pkg-config ; else PKGCONFIG=pkgconf ; fi; fi
type ${PKGCONFIG} > /dev/null 2>&1 || echo "ERROR: Cannot find valid PKGCONFIG, pkg-config or pkgconf in PATH"
}
check_library HAVE_LIB_KEYSTONE keystone 1
[ -z "${PKGCONFIG}" ] && PKGCONFIG=pkg-config
type ${PKGCONFIG} > /dev/null 2>&1 || echo "ERROR: Cannot find PKGCONFIG ${PKGCONFIG}"
echo 'Using PKGCONFIG: '${PKGCONFIG}
printf 'checking pkg-config flags for r_asm... '
tmp=`${PKGCONFIG} --cflags r_asm 2>/dev/null`
@@ -410,33 +355,13 @@ tmp=`${PKGCONFIG} --libs r_asm 2>/dev/null`
if [ $? = 0 ]; then
echo yes; HAVE_PKGCFG_R_ASM=1;
R2_LDFLAGS=$tmp; fi; fi
if [ -z "${PKGCONFIG}" ]; then pkg-config --version >/dev/null 2>&1 ; if [ 0 = 0 ]; then PKGCONFIG=pkg-config ; else PKGCONFIG=pkgconf ; fi; fi
printf 'checking pkg-config flags for keystone... '
tmp=`${PKGCONFIG} --cflags keystone 2>/dev/null`
if [ $? != 0 ]; then echo no ; HAVE_PKGCFG_KEYSTONE=0;
KS_CFLAGS='';KS_LDFLAGS='';
echo 'This package is required'
exit 1
else
KS_CFLAGS=$tmp;
tmp=`${PKGCONFIG} --libs keystone 2>/dev/null`
if [ $? = 0 ]; then
echo yes; HAVE_PKGCFG_KEYSTONE=1;
KS_LDFLAGS=$tmp; fi; fi
SEDFLAGS=" -e '"
COUNT=0
for A in ${ENVWORDS} ; do
[ "${A}" = VPATH ] && continue
[ "${A}" = srcdir ] && continue
eval "VAR=\$${A}"
case "" in
mingw*|cygwin*|msys*)
VAR="`echo ${VAR} | sed -e 's/\\/\\\\/g' -e 's/\,/\\\,/g'`"
;;
*)
VAR="`echo ${VAR} | sed -e 's/\,/\\\,/g'`"
;;
esac
VAR="`echo ${VAR} | sed -e 's/\,/\\\,/g'`"
[ $COUNT = 10 ] && COUNT=0 && SEDFLAGS="${SEDFLAGS}' -e '"
COUNT=$(($COUNT+1))
SEDFLAGS="${SEDFLAGS}s,@${A}@,${VAR},g;"
@@ -454,8 +379,8 @@ if [ -f "${VPATH}/${A}.acr" ]; then
exit 1
fi
fi
ocho "creating ${SD_TARGET}"
[ "${VPATH}" != '.' ] && mkdir -p $(echo ${A} | sed -e "s,/`basename ${A}`$,,g")
echo "creating ${SD_TARGET}"
mkdir -p $(echo ${A} | sed -e "s,/`basename ${A}`$,,g")
cat ${VPATH}/${SD_TARGET}.acr | \
eval sed -e "s,@VPATH@,${VPATH}/${A},g" ${SEDFLAGS} > ${SD_TARGET}.tmp
+3 -4
View File
@@ -1,13 +1,12 @@
PKGNAME radare2-keystone
VERSION 0.2
VERSION 0.1
CONTACT pancake ; [email protected]
LANG_C!
LANG_CXX!
USE_PKGCONFIG!
(( CHKLIB! keystone ))
CHKLIB! keystone
PKGCFG! R2_CFLAGS R2_LDFLAGS r_asm
PKGCFG! KS_CFLAGS KS_LDFLAGS keystone
SUBDIRS ./config.mk ;
+15 -24
View File
@@ -1,30 +1,22 @@
/* radare2-keystone - GPL - Copyright 2016 - pancake */
#if R2_VERSION_NUMBER >= 50709
#define ATTSYNTAX R_ARCH_SYNTAX_ATT
#else
#define ATTSYNTAX R_ASM_SYNTAX_ATT
#endif
static void *oldcur = NULL;
static ks_engine *ks = NULL;
static int oldbit = 0;
#include <r_th.h>
static R_TH_LOCAL void *oldcur = NULL;
static R_TH_LOCAL ks_engine *ks = NULL;
static R_TH_LOCAL int oldbit = 0;
static bool keystone_assemble(RArchSession *a, RAnalOp *ao, const char *str, ks_arch arch, ks_mode mode) {
static int keystone_assemble(RAsm *a, RAsmOp *ao, const char *str, ks_arch arch, ks_mode mode) {
ks_err err = KS_ERR_ARCH;
bool must_init = false;
size_t count, size;
ut8 *insn = NULL;
if (!ks_arch_supported (arch)) {
return false;
return -1;
}
must_init = true; //!oldcur || (a->cur != oldcur || oldbit != a->bits);
// oldcur = a->cur;
oldbit = a->config->bits;
oldcur = a->cur;
oldbit = a->bits;
if (must_init) {
if (ks) {
@@ -33,13 +25,13 @@ static bool keystone_assemble(RArchSession *a, RAnalOp *ao, const char *str, ks_
}
err = ks_open (arch, mode, &ks);
if (err || !ks) {
R_LOG_ERROR ("Cannot initialize keystone");
eprintf ("Cannot initialize keystone\n");
ks_free (insn);
if (ks) {
ks_close (ks);
ks = NULL;
}
return false;
return -1;
}
}
@@ -49,14 +41,14 @@ static bool keystone_assemble(RArchSession *a, RAnalOp *ao, const char *str, ks_
ks_close (ks);
ks = NULL;
}
return false;
return -1;
}
if (a->config->syntax == ATTSYNTAX) {
if (a->syntax == R_ASM_SYNTAX_ATT) {
ks_option (ks, KS_OPT_SYNTAX, KS_OPT_SYNTAX_ATT);
} else {
ks_option (ks, KS_OPT_SYNTAX, KS_OPT_SYNTAX_NASM);
}
int rc = ks_asm (ks, str, ao->addr, &insn, &size, &count);
int rc = ks_asm (ks, str, a->pc, &insn, &size, &count);
if (rc) {
eprintf ("ks_asm: (%s) %s\n", str, ks_strerror ((ks_err)ks_errno (ks)));
ks_free (insn);
@@ -64,14 +56,13 @@ static bool keystone_assemble(RArchSession *a, RAnalOp *ao, const char *str, ks_
ks_close (ks);
ks = NULL;
}
return false;
return -1;
}
ao->size = size;
ao->bytes = r_mem_dup (insn, size);
r_asm_op_set_buf (ao, insn, size);
ks_free (insn);
if (ks) {
ks_close (ks);
ks = NULL;
}
return size > 0;
return size;
}
+8 -10
View File
@@ -9,10 +9,6 @@ atombios:
$(MAKE) -C anal atombios
$(MAKE) -C bin atombios
ba2:
$(MAKE) -C asm ba2
$(MAKE) -C anal ba2
blackfin:
$(MAKE) -C asm blackfin
@@ -34,9 +30,13 @@ zyan:
$(MAKE) -C asm zyan
evm:
$(MAKE) -C asm evm
$(MAKE) -C anal evm
$(MAKE) -C io evm
$(MAKE) -C debug evm
nios:
$(MAKE) -C anal nios
$(MAKE) -C asm nios
clean:
$(MAKE) -C asm clean
@@ -47,10 +47,6 @@ atombios-install:
cp -f anal/p/anal_atombios.$(LIBEXT) $(R2PM_PLUGDIR)
cp -f bin/p/bin_atombios.$(LIBEXT) $(R2PM_PLUGDIR)
ba2-install:
cp -f asm/p/asm_ba2.$(LIBEXT) $(R2PM_PLUGDIR)
cp -f anal/p/anal_ba2.$(LIBEXT) $(R2PM_PLUGDIR)
bea-install:
cp -f asm/p/asm_x86_bea.$(LIBEXT) $(R2PM_PLUGDIR)
cp -f anal/p/anal_x86_bea.$(LIBEXT) $(R2PM_PLUGDIR)
@@ -73,10 +69,12 @@ zyan-install:
cp -f asm/p/asm_x86_zyan.$(LIBEXT) $(R2PM_PLUGDIR)
evm-install:
cp -f asm/p/asm_evm.$(LIBEXT) $(R2PM_PLUGDIR)
cp -f anal/p/anal_evm.$(LIBEXT) $(R2PM_PLUGDIR)
cp -f io/p/io_evm.$(LIBEXT) $(R2PM_PLUGDIR)
cp -f debug/p/debug_evm.$(LIBEXT) $(R2PM_PLUGDIR)
nios-install:
cp -f asm/p/asm_nios.$(LIBEXT) $(R2PM_PLUGDIR)
cp -f anal/p/anal_nios.$(LIBEXT) $(R2PM_PLUGDIR)
include ../options.mk
+2 -11
View File
@@ -1,10 +1,3 @@
rl78:
$(MAKE) -C p anal_rl78.$(LIBEXT)
cp -f p/anal_rl78.$(LIBEXT) $(shell r2 -H R2_USER_PLUGINS)
ba2:
cd p ; $(MAKE) anal_ba2.$(LIBEXT)
bea:
cd p ; $(MAKE) anal_x86_bea.$(LIBEXT)
@@ -17,14 +10,12 @@ m68k_net:
atombios:
cd p ; $(MAKE) anal_atombios.$(LIBEXT)
nios:
cd p ; $(MAKE) anal_nios.$(LIBEXT)
evm:
cd p ; $(MAKE) anal_evm.$(LIBEXT)
clean:
rm -f p/anal_ba2.$(LIBEXT)
rm -f p/anal_x86_bea.$(LIBEXT)
rm -f p/anal_m68k_net.$(LIBEXT)
rm -f p/anal_atombios.{$(LIBEXT),o}
rm -f p/anal_nios.$(LIBEXT)
include ../../options.mk
File diff suppressed because it is too large. Load diff
-433
View File
@@ -1,433 +0,0 @@
/* Disassembler code for Renesas RL78.
Copyright (C) 2011-2022 Free Software Foundation, Inc.
Contributed by Red Hat.
Written by DJ Delorie.
This file is part of the GNU opcodes library.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
#include "sysdep.h"
#include <stdio.h>
#include "bfd.h"
#include "elf-bfd.h"
#include "dis-asm.h"
#include "opcode/rl78.h"
// #include "elf/rl78.h"
#include <setjmp.h>
#define DEBUG_SEMANTICS 0
typedef struct
{
bfd_vma pc;
disassemble_info * dis;
} RL78_Data;
#if 0
struct private
{
OPCODES_SIGJMP_BUF bailout;
};
#endif
static int
rl78_get_byte (void * vdata)
{
bfd_byte buf[1];
RL78_Data *rl78_data = (RL78_Data *) vdata;
int status;
status = rl78_data->dis->read_memory_func (rl78_data->pc,
buf,
1,
rl78_data->dis);
#if 0
if (status != 0)
{
struct private *priv = (struct private *) rl78_data->dis->private_data;
rl78_data->dis->memory_error_func (status, rl78_data->pc,
rl78_data->dis);
OPCODES_SIGLONGJMP (priv->bailout, 1);
}
#endif
rl78_data->pc ++;
return buf[0];
}
static char const *
register_names[] =
{
"",
"x", "a", "c", "b", "e", "d", "l", "h",
"ax", "bc", "de", "hl",
"sp", "psw", "cs", "es", "pmc", "mem"
};
static char const *
condition_names[] =
{
"t", "f", "c", "nc", "h", "nh", "z", "nz"
};
static int
indirect_type (int t)
{
switch (t)
{
case RL78_Operand_Indirect:
case RL78_Operand_BitIndirect:
case RL78_Operand_PostInc:
case RL78_Operand_PreDec:
return 1;
default:
return 0;
}
}
static int
print_insn_rl78_common (bfd_vma addr, disassemble_info * dis, RL78_Dis_Isa isa)
{
int rv;
RL78_Data rl78_data;
RL78_Opcode_Decoded opcode;
const char * s;
#if DEBUG_SEMANTICS
static char buf[200];
#endif
// struct private priv;
// dis->private_data = (PTR) &priv;
rl78_data.pc = addr;
rl78_data.dis = dis;
#if 0
if (OPCODES_SIGSETJMP (priv.bailout) != 0)
{
/* Error return. */
return -1;
}
#endif
rv = rl78_decode_opcode (addr, &opcode, rl78_get_byte, &rl78_data, isa);
dis->bytes_per_line = 10;
#define PR (dis->fprintf_func)
#define PS (dis->stream)
#define PC(c) PR (PS, "%c", c)
s = opcode.syntax;
#if DEBUG_SEMANTICS
switch (opcode.id)
{
case RLO_unknown: s = "uknown"; break;
case RLO_add: s = "add: %e0%0 += %e1%1"; break;
case RLO_addc: s = "addc: %e0%0 += %e1%1 + CY"; break;
case RLO_and: s = "and: %e0%0 &= %e1%1"; break;
case RLO_branch: s = "branch: pc = %e0%0"; break;
case RLO_branch_cond: s = "branch_cond: pc = %e0%0 if %c1 / %e1%1"; break;
case RLO_branch_cond_clear: s = "branch_cond_clear: pc = %e0%0 if %c1 / %e1%1, %e1%1 = 0"; break;
case RLO_call: s = "call: pc = %e1%0"; break;
case RLO_cmp: s = "cmp: %e0%0 - %e1%1"; break;
case RLO_mov: s = "mov: %e0%0 = %e1%1"; break;
case RLO_or: s = "or: %e0%0 |= %e1%1"; break;
case RLO_rol: s = "rol: %e0%0 <<= %e1%1"; break;
case RLO_rolc: s = "rol: %e0%0 <<= %e1%1,CY"; break;
case RLO_ror: s = "ror: %e0%0 >>= %e1%1"; break;
case RLO_rorc: s = "ror: %e0%0 >>= %e1%1,CY"; break;
case RLO_sar: s = "sar: %e0%0 >>= %e1%1 signed"; break;
case RLO_sel: s = "sel: rb = %1"; break;
case RLO_shr: s = "shr: %e0%0 >>= %e1%1 unsigned"; break;
case RLO_shl: s = "shl: %e0%0 <<= %e1%1"; break;
case RLO_skip: s = "skip: if %c1"; break;
case RLO_sub: s = "sub: %e0%0 -= %e1%1"; break;
case RLO_subc: s = "subc: %e0%0 -= %e1%1 - CY"; break;
case RLO_xch: s = "xch: %e0%0 <-> %e1%1"; break;
case RLO_xor: s = "xor: %e0%0 ^= %e1%1"; break;
}
sprintf(buf, "%s%%W%%f\t\033[32m%s\033[0m", s, opcode.syntax);
s = buf;
#endif
for (; *s; s++)
{
if (*s != '%')
{
PC (*s);
}
else
{
RL78_Opcode_Operand * oper;
int do_hex = 0;
int do_addr = 0;
int do_es = 0;
int do_sfr = 0;
int do_cond = 0;
int do_bang = 0;
while (1)
{
s ++;
switch (*s)
{
case 'x':
do_hex = 1;
break;
case '!':
do_bang = 1;
break;
case 'e':
do_es = 1;
break;
case 'a':
do_addr = 1;
break;
case 's':
do_sfr = 1;
break;
case 'c':
do_cond = 1;
break;
default:
goto no_more_modifiers;
}
}
no_more_modifiers:;
switch (*s)
{
case '%':
PC ('%');
break;
#if DEBUG_SEMANTICS
case 'W':
if (opcode.size == RL78_Word)
PR (PS, " \033[33mW\033[0m");
break;
case 'f':
if (opcode.flags)
{
char *comma = "";
PR (PS, " \033[35m");
if (opcode.flags & RL78_PSW_Z)
{ PR (PS, "Z"); comma = ","; }
if (opcode.flags & RL78_PSW_AC)
{ PR (PS, "%sAC", comma); comma = ","; }
if (opcode.flags & RL78_PSW_CY)
{ PR (PS, "%sCY", comma); comma = ","; }
PR (PS, "\033[0m");
}
break;
#endif
case '0':
case '1':
oper = *s == '0' ? &opcode.op[0] : &opcode.op[1];
if (do_es)
{
if (oper->use_es && indirect_type (oper->type))
PR (PS, "es:");
}
if (do_bang)
{
/* If we are going to display SP by name, we must omit the bang. */
if ((oper->type == RL78_Operand_Indirect
|| oper->type == RL78_Operand_BitIndirect)
&& oper->reg == RL78_Reg_None
&& do_sfr
&& ((oper->addend == 0xffff8 && opcode.size == RL78_Word)
|| (oper->addend == 0x0fff8 && do_es && opcode.size == RL78_Word)))
;
else
PC ('!');
}
if (do_cond)
{
PR (PS, "%s", condition_names[oper->condition]);
break;
}
switch (oper->type)
{
case RL78_Operand_Immediate:
if (do_addr)
dis->print_address_func (oper->addend, dis);
else if (do_hex
|| oper->addend > 999
|| oper->addend < -999)
PR (PS, "%#x", oper->addend);
else
PR (PS, "%d", oper->addend);
break;
case RL78_Operand_Register:
PR (PS, "%s", register_names[oper->reg]);
break;
case RL78_Operand_Bit:
PR (PS, "%s.%d", register_names[oper->reg], oper->bit_number);
break;
case RL78_Operand_Indirect:
case RL78_Operand_BitIndirect:
switch (oper->reg)
{
case RL78_Reg_None:
if (oper->addend == 0xffffa && do_sfr && opcode.size == RL78_Byte)
PR (PS, "psw");
else if (oper->addend == 0xffff8 && do_sfr && opcode.size == RL78_Word)
PR (PS, "sp");
else if (oper->addend == 0x0fff8 && do_sfr && do_es && opcode.size == RL78_Word)
PR (PS, "sp");
else if (oper->addend == 0xffff8 && do_sfr && opcode.size == RL78_Byte)
PR (PS, "spl");
else if (oper->addend == 0xffff9 && do_sfr && opcode.size == RL78_Byte)
PR (PS, "sph");
else if (oper->addend == 0xffffc && do_sfr && opcode.size == RL78_Byte)
PR (PS, "cs");
else if (oper->addend == 0xffffd && do_sfr && opcode.size == RL78_Byte)
PR (PS, "es");
else if (oper->addend == 0xffffe && do_sfr && opcode.size == RL78_Byte)
PR (PS, "pmc");
else if (oper->addend == 0xfffff && do_sfr && opcode.size == RL78_Byte)
PR (PS, "mem");
else if (oper->addend >= 0xffe20)
PR (PS, "%#x", oper->addend);
else
{
int faddr = oper->addend;
if (do_es && ! oper->use_es)
faddr += 0xf0000;
dis->print_address_func (faddr, dis);
}
break;
case RL78_Reg_B:
case RL78_Reg_C:
case RL78_Reg_BC:
PR (PS, "%d[%s]", oper->addend, register_names[oper->reg]);
break;
default:
PR (PS, "[%s", register_names[oper->reg]);
if (oper->reg2 != RL78_Reg_None)
PR (PS, "+%s", register_names[oper->reg2]);
if (oper->addend || do_addr)
PR (PS, "+%d", oper->addend);
PC (']');
break;
}
if (oper->type == RL78_Operand_BitIndirect)
PR (PS, ".%d", oper->bit_number);
break;
#if DEBUG_SEMANTICS
/* Shouldn't happen - push and pop don't print
[SP] directly. But we *do* use them for
semantic debugging. */
case RL78_Operand_PostInc:
PR (PS, "[%s++]", register_names[oper->reg]);
break;
case RL78_Operand_PreDec:
PR (PS, "[--%s]", register_names[oper->reg]);
break;
#endif
default:
/* If we ever print this, that means the
programmer tried to print an operand with a
type we don't expect. Print the line and
operand number from rl78-decode.opc for
them. */
PR (PS, "???%d.%d", opcode.lineno, *s - '0');
break;
}
}
}
}
#if DEBUG_SEMANTICS
PR (PS, "\t\033[34m(line %d)\033[0m", opcode.lineno);
#endif
return rv;
}
int
print_insn_rl78 (bfd_vma addr, disassemble_info * dis)
{
return print_insn_rl78_common (addr, dis, RL78_ISA_DEFAULT);
}
int
print_insn_rl78_g10 (bfd_vma addr, disassemble_info * dis)
{
return print_insn_rl78_common (addr, dis, RL78_ISA_G10);
}
int
print_insn_rl78_g13 (bfd_vma addr, disassemble_info * dis)
{
return print_insn_rl78_common (addr, dis, RL78_ISA_G13);
}
int
print_insn_rl78_g14 (bfd_vma addr, disassemble_info * dis)
{
return print_insn_rl78_common (addr, dis, RL78_ISA_G14);
}
#if 0
disassembler_ftype
rl78_get_disassembler (bfd *abfd)
{
int cpu = E_FLAG_RL78_ANY_CPU;
if (abfd != NULL)
cpu = abfd->tdata.elf_obj_data->elf_header->e_flags & E_FLAG_RL78_CPU_MASK;
switch (cpu)
{
case E_FLAG_RL78_G10:
return print_insn_rl78_g10;
case E_FLAG_RL78_G13:
return print_insn_rl78_g13;
case E_FLAG_RL78_G14:
return print_insn_rl78_g14;
default:
return print_insn_rl78;
}
}
#endif
+1 -3
View File
@@ -1,13 +1,11 @@
ARCHS=
ARCHS+=ba2.mk
ARCHS+=x86_bea.mk
#ARCHS+=x86_im.mk
ARCHS+=x86_simple.mk
ARCHS+=x86_udis.mk
ARCHS+=m68k_net.mk
ARCHS+=evm.mk
ARCHS+=atombios.mk
ARCHS+=rl78.mk
ARCHS+=nios.mk
include ../../plugs.mk
+77 -24
View File
@@ -8,6 +8,8 @@
#include "../../asm/arch/atombios/atombios.h"
#define R_IPI static
typedef struct {
_RAnalOpType optype;
const char *reg;
@@ -153,17 +155,66 @@ atombios_ops_t atombios_ops[256] = {
[0xff] = { R_ANAL_OP_TYPE_ILL, NULL }, // not implemented (reserved)
};
static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len, RAnalOpMask unused) {
static int atombios_analyze_fns(RAnal *anal, ut64 start, ut64 end, int reftype, int depth) {
ut8 i;
const RList *sects;
char name[256] = {0};
char namesym[256] = {0};
if (!(sects = r_bin_get_sections(anal->binb.bin))) {
return 0;
}
for (i = 0; i < N_TABLES_CMD; i++) {
RBinSection *sect = (RBinSection *)r_list_get_n(sects, i);
if (!sect)
continue;
else if (!sect->paddr)
continue;
sprintf (name, "fcn.%s", index_command_table[i]);
r_anal_fcn_add(anal, sect->paddr, sect->size, name, R_ANAL_FCN_TYPE_FCN, NULL);
// Add locs for local data blocks:
// eg:
// 0x0000c236 5b ret
// 0x0000c237 7a2600000000. bindata 38 bytes
// ;end section
ut32 paddr = 0;
ut32 size = 0;
ut8 *buf = r_buf_get_at (anal->binb.bin->cur->buf, sect->paddr + sect->size - 1, NULL);
ut8 *orig = r_buf_get_at (anal->binb.bin->cur->buf, 0, NULL);
if (*buf == 0x5b) {
// No data here
continue;
} else {
// We have a data block at the end of the fcn.
while (r_read_le16(buf) != 0x7a5b) {
--buf;
++size;
}
if (buf - orig < sect->paddr) {
// WTF not in function
continue;
}
buf += 2;
--size;
paddr = buf - orig;
sprintf (namesym, "sym.%s", index_command_table[i]);
r_anal_fcn_add (anal, paddr, size, namesym, R_ANAL_FCN_TYPE_SYM, NULL);
}
}
return 0;
}
static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
if (!op)
return -1;
return 1;
memset (op, 0, sizeof (RAnalOp));
op->nopcode = 1;
op->size = atombios_inst_len (b);
op->type = atombios_ops[*b].optype;
if (len < op->size) {
op->type = R_ANAL_OP_TYPE_ILL;
return -1;
}
if (*b > 0x7a) {
op->type = R_ANAL_OP_TYPE_ILL;
@@ -367,8 +418,9 @@ static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int le
// op ds (imm data table)
case 0x7a:
op->size = 3;// + r_read_at_le16(b, 1);
break;
{
} break;
// op imm8
case 0x50:
@@ -399,7 +451,7 @@ static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int le
op->cond = R_ANAL_COND_AL;
op->jump = sect->paddr;
op->eob = true;
esilprintf (op, "0x%" PFMT64d ",pc,4,sp,-=,sp,=[],pc,=", op->jump);
esilprintf (op, "0x%08x,pc,4,sp,-=,sp,=[],pc,=", op->jump);
} break;
// jmp imm16
@@ -411,9 +463,9 @@ static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int le
return op->size;
}
op->cond = R_ANAL_COND_AL;
op->jump = cursect->paddr + r_read_at_le16(b, 1);
op->jump = cursect->paddr - 6 + r_read_at_le16(b, 1);
op->eob = true;
esilprintf (op, "0x%" PFMT64d ",pc,=", op->jump);
esilprintf (op, "0x%08x,pc,=", op->jump);
} break;
case 0x44:
{
@@ -423,10 +475,10 @@ static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int le
return op->size;
}
op->cond = R_ANAL_COND_EQ;
op->jump = cursect->paddr + r_read_at_le16(b, 1);
op->jump = cursect->paddr - 6 + r_read_at_le16(b, 1);
op->fail = addr + op->size;
op->eob = true;
esilprintf (op, "$z,?{,0x%" PFMT64d ",pc,=,}", op->jump);
esilprintf (op, "$z,?{,0x%08x,pc,=,}", op->jump);
} break;
case 0x45:
{
@@ -436,10 +488,10 @@ static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int le
return op->size;
}
op->cond = R_ANAL_COND_LT;
op->jump = cursect->paddr + r_read_at_le16(b, 1);
op->jump = cursect->paddr - 6 + r_read_at_le16(b, 1);
op->fail = addr + op->size;
op->eob = true;
esilprintf (op, "$of,$sf,!=,?{,0x%" PFMT64d ",pc,=,}", op->jump);
esilprintf (op, "$of,$sf,!=,?{,0x%08x,pc,=,}", op->jump);
} break;
case 0x46:
{
@@ -449,10 +501,10 @@ static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int le
return op->size;
}
op->cond = R_ANAL_COND_GT;
op->jump = cursect->paddr + r_read_at_le16(b, 1);
op->jump = cursect->paddr - 6 + r_read_at_le16(b, 1);
op->fail = addr + op->size;
op->eob = true;
esilprintf (op, "$z,!,$of,$sf,==,&,?{,0x%" PFMT64d ",pc,=,}", op->jump);
esilprintf (op, "$z,!,$of,$sf,==,&,?{,0x%08x,pc,=,}", op->jump);
} break;
case 0x47:
{
@@ -462,10 +514,10 @@ static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int le
return op->size;
}
op->cond = R_ANAL_COND_LE;
op->jump = cursect->paddr + r_read_at_le16(b, 1);
op->jump = cursect->paddr - 6 + r_read_at_le16(b, 1);
op->fail = addr + op->size;
op->eob = true;
esilprintf (op, "$z,$of,$sf,!=,|,?{,0x%" PFMT64d ",pc,=,}", op->jump);
esilprintf (op, "$z,$of,$sf,!=,|,?{,0x%08x,pc,=,}", op->jump);
} break;
case 0x48:
{
@@ -475,10 +527,10 @@ static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int le
return op->size;
}
op->cond = R_ANAL_COND_GE;
op->jump = cursect->paddr + r_read_at_le16(b, 1);
op->jump = cursect->paddr - 6 + r_read_at_le16(b, 1);
op->fail = addr + op->size;
op->eob = true;
esilprintf (op, "$of,$sf,==,?{,0x%" PFMT64d ",pc,=,}", op->jump);
esilprintf (op, "$of,$sf,==,?{,0x%08x,pc,=,}", op->jump);
} break;
case 0x49:
{
@@ -488,10 +540,10 @@ static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int le
return op->size;
}
op->cond = R_ANAL_COND_NE;
op->jump = cursect->paddr + r_read_at_le16(b, 1);
op->jump = cursect->paddr - 6 + r_read_at_le16(b, 1);
op->fail = addr + op->size;
op->eob = true;
esilprintf (op, "$z,!,?{,0x%" PFMT64d ",pc,=,}", op->jump);
esilprintf (op, "$z,!,?{,0x%08x,pc,=,}", op->jump);
} break;
// SET DATA BLOCK imm8 dataptr = &data[datatable[imm8]]
@@ -840,7 +892,7 @@ static int archinfo(RAnal *anal, int query) {
}
}
static bool set_reg_profile(RAnal *anal) {
static int set_reg_profile(RAnal *anal) {
const char *p =
"=PC pc\n"
"=SP sp\n"
@@ -1062,6 +1114,7 @@ RAnalPlugin r_anal_plugin_atombios = {
.arch = "atombios",
.bits = 32 | 64,
.op = &atombios_op,
.analyze_fns = atombios_analyze_fns,
.archinfo = archinfo,
};
-129
View File
@@ -1,129 +0,0 @@
/* radare - LGPL - Copyright 2020 - Jerome-PS */
#include <r_lib.h>
#include <r_anal.h>
#include "../../asm/arch/ba2/ba2_disas.c"
static int ba2_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
struct op_cmd cmd = {
.instr = "",
.operands = ""
};
op->cycles = 0;
op->failcycles = 0;
op->nopcode = 1;
// op->size = ;
// op->type = ;
op->family = R_ANAL_OP_FAMILY_CPU; // maybe also FAMILY_IO...
// op->id = ;
int ret = ba2_decode_opcode (addr, buf, len, &cmd, &op->esil, op);
if((len < ret) || (!ret && len<6)){
op->size = 0;
return 0;
}
if (ret <= 0) {
return -1;
}
return op->size = ret;
}
static bool set_reg_profile(RAnal *anal) {
const char *p =
"=PC pc\n"
"=SP r1\n"
"=BP r2\n"
"=A0 r0\n"
"=A1 r1\n"
"=A2 r2\n"
"=A3 r3\n"
"=A4 r4\n"
"=A5 r5\n"
"=A6 r6\n"
"=A7 r7\n"
"=A8 r8\n"
"=SN r8\n" ///! TODO: ??? Which register ???
"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 r6 .32 24 0\n"
"gpr r7 .32 28 0\n"
"gpr r8 .32 32 0\n"
"gpr r9 .32 36 0\n"
"gpr r10 .32 40 0\n"
"gpr r11 .32 44 0\n"
"gpr r12 .32 48 0\n"
"gpr r13 .32 52 0\n"
"gpr r14 .32 56 0\n"
"gpr r15 .32 60 0\n"
"gpr r16 .32 64 0\n"
"gpr r17 .32 68 0\n"
"gpr r18 .32 72 0\n"
"gpr r19 .32 76 0\n"
"gpr r20 .32 80 0\n"
"gpr r21 .32 84 0\n"
"gpr r22 .32 88 0\n"
"gpr r23 .32 92 0\n"
"gpr r24 .32 96 0\n"
"gpr r25 .32 100 0\n"
"gpr r26 .32 104 0\n"
"gpr r27 .32 108 0\n"
"gpr r28 .32 112 0\n"
"gpr r29 .32 116 0\n"
"gpr r30 .32 120 0\n"
"gpr r31 .32 124 0\n"
"gpr sp .32 4 0\n"
"gpr fp .32 8 0\n"
"gpr lr .32 36 0\n"
"gpr pc .32 128 0\n"
"gpr fl .1 132 0\n"
"gpr mac .64 136 0\n";
return r_reg_set_profile_string (anal->reg, p);
}
static int archinfo(RAnal *anal, int q) {
// fprintf(stderr, "archinfo:%d\r\n", q);
if (q == R_ANAL_ARCHINFO_ALIGN) {
return 0;
}
if (q == R_ANAL_ARCHINFO_MAX_OP_SIZE) {
return 6;
}
if (q == R_ANAL_ARCHINFO_MIN_OP_SIZE) {
return 2;
}
// if (q == R_ANAL_ARCHINFO_DATA_ALIGN) {
// return 0;
// }
return 0; // XXX
}
RAnalPlugin r_anal_plugin_ba2 = {
.name = "ba2",
.arch = "ba2",
.esil = true,
.bits = 32,
.desc = "Beyond Architecture 2 CPU code analysis plugin",
.license = "LGPL3",
.archinfo = archinfo,
.op = &ba2_op,
.set_reg_profile = &set_reg_profile,
// .esil_init = esil_ba2_init,
// .esil_fini = esil_ba2_fini
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_ba2,
.version = R2_VERSION
};
#endif
+638
View File
@@ -0,0 +1,638 @@
#include <string.h>
#include <errno.h>
#include <jansson.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_asm.h>
#include <r_anal.h>
#include <r_util.h>
#include <sdb.h>
#include "evm.h"
struct evm_anal_info {
Sdb *pushs_db;
};
static struct evm_anal_info *evm_ai = NULL;
static unsigned opcodes_types[] = {
[EVM_OP_STOP] = R_ANAL_OP_TYPE_RET,
[EVM_OP_ADD] = R_ANAL_OP_TYPE_ADD,
[EVM_OP_MUL] = R_ANAL_OP_TYPE_MUL,
[EVM_OP_SUB] = R_ANAL_OP_TYPE_SUB,
[EVM_OP_DIV] = R_ANAL_OP_TYPE_DIV,
[EVM_OP_SDIV] = R_ANAL_OP_TYPE_DIV,
[EVM_OP_MOD] = R_ANAL_OP_TYPE_MOD,
[EVM_OP_SMOD] = R_ANAL_OP_TYPE_MOD,
[EVM_OP_ADDMOD] = R_ANAL_OP_TYPE_ADD,
[EVM_OP_MULMOD] = R_ANAL_OP_TYPE_MUL,
[EVM_OP_EXP] = R_ANAL_OP_TYPE_MUL,
[EVM_OP_SIGNEXTEND] = R_ANAL_OP_TYPE_CAST,
[EVM_OP_LT] = R_ANAL_OP_TYPE_COND,
[EVM_OP_GT] = R_ANAL_OP_TYPE_COND,
[EVM_OP_SLT] = R_ANAL_OP_TYPE_COND,
[EVM_OP_SGT] = R_ANAL_OP_TYPE_COND,
[EVM_OP_EQ] = R_ANAL_OP_TYPE_CMP,
[EVM_OP_ISZERO] = R_ANAL_OP_TYPE_CMP,
[EVM_OP_AND] = R_ANAL_OP_TYPE_AND,
[EVM_OP_OR] = R_ANAL_OP_TYPE_OR,
[EVM_OP_XOR] = R_ANAL_OP_TYPE_XOR,
[EVM_OP_NOT] = R_ANAL_OP_TYPE_NOT,
[EVM_OP_BYTE] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SHA3] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_ADDRESS] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_BALANCE] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_ORIGIN] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_CALLER] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_CALLVALUE] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_CALLDATALOAD] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_CALLDATASIZE] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_CALLDATACOPY] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_CODESIZE] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_CODECOPY] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_GASPRICE] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_EXTCODESIZE] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_EXTCODECOPY] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_RETURNDATASIZE] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_RETURNDATACOPY] = R_ANAL_OP_TYPE_STORE,
[EVM_OP_BLOCKHASH] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_COINBASE] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_TIMESTAMP] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_NUMBER] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_DIFFICULTY] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_GASLIMIT] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_POP] = R_ANAL_OP_TYPE_POP,
[EVM_OP_MLOAD] = R_ANAL_OP_TYPE_LOAD,
[EVM_OP_MSTORE] = R_ANAL_OP_TYPE_STORE,
[EVM_OP_MSTORE8] = R_ANAL_OP_TYPE_STORE,
[EVM_OP_SLOAD] = R_ANAL_OP_TYPE_LOAD,
[EVM_OP_SSTORE] = R_ANAL_OP_TYPE_STORE,
[EVM_OP_JUMP] = R_ANAL_OP_TYPE_JMP,
[EVM_OP_JUMPI] = R_ANAL_OP_TYPE_JMP,
[EVM_OP_PC] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_MSIZE] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_GAS] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_JUMPDEST] = R_ANAL_OP_TYPE_NOP,
[EVM_OP_PUSH1] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH2] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH3] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH4] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH5] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH6] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH7] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH8] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH9] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH10] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH11] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH12] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH13] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH14] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH15] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH16] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH17] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH18] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH19] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH20] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH21] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH22] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH23] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH24] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH25] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH26] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH27] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH28] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH29] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH30] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH31] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_PUSH32] = R_ANAL_OP_TYPE_PUSH,
[EVM_OP_DUP1] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP2] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP3] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP4] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP5] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP6] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP7] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP8] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP9] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP10] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP11] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP12] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP13] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP14] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP15] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_DUP16] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP1] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP2] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP3] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP4] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP5] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP6] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP7] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP8] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP9] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP10] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP11] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP12] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP13] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP14] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP15] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_SWAP16] = R_ANAL_OP_TYPE_MOV,
[EVM_OP_LOG0] = R_ANAL_OP_TYPE_TRAP,
[EVM_OP_LOG1] = R_ANAL_OP_TYPE_TRAP,
[EVM_OP_LOG2] = R_ANAL_OP_TYPE_TRAP,
[EVM_OP_LOG3] = R_ANAL_OP_TYPE_TRAP,
[EVM_OP_LOG4] = R_ANAL_OP_TYPE_TRAP,
[EVM_OP_CREATE] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_CALL] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_CALLCODE] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_RETURN] = R_ANAL_OP_TYPE_RET,
[EVM_OP_DELEGATECALL] = R_ANAL_OP_TYPE_CRYPTO,
[EVM_OP_REVERT] = R_ANAL_OP_TYPE_RET,
[EVM_OP_SELFDESTRUCT] = R_ANAL_OP_TYPE_CRYPTO,
};
struct evm_sigs_info {
RIO *rio;
RIODesc *riodesc;
ut8 *contents;
size_t contents_len;
json_t *root;
Sdb *sigs_db;
Sdb *found_sigs_db;
};
static struct evm_sigs_info *sigs_info = 0;
static int evm_oplen(ut8 opcode) {
int ret;
const EvmOpDef *opdef = &opcodes[opcode];
if (opdef->txt) {
return opdef->len;
}
switch (opcode) {
case EVM_OP_PUSH1:
case EVM_OP_PUSH2:
case EVM_OP_PUSH3:
case EVM_OP_PUSH4:
case EVM_OP_PUSH5:
case EVM_OP_PUSH6:
case EVM_OP_PUSH7:
case EVM_OP_PUSH8:
case EVM_OP_PUSH9:
case EVM_OP_PUSH10:
case EVM_OP_PUSH11:
case EVM_OP_PUSH12:
case EVM_OP_PUSH13:
case EVM_OP_PUSH14:
case EVM_OP_PUSH15:
case EVM_OP_PUSH16:
case EVM_OP_PUSH17:
case EVM_OP_PUSH18:
case EVM_OP_PUSH19:
case EVM_OP_PUSH20:
case EVM_OP_PUSH21:
case EVM_OP_PUSH22:
case EVM_OP_PUSH23:
case EVM_OP_PUSH24:
case EVM_OP_PUSH25:
case EVM_OP_PUSH26:
case EVM_OP_PUSH27:
case EVM_OP_PUSH28:
case EVM_OP_PUSH29:
case EVM_OP_PUSH30:
case EVM_OP_PUSH31:
case EVM_OP_PUSH32:
{
int pushSize = opcode - EVM_OP_PUSH1;
/*
op->imm = 0;
for (i = 0; i < pushSize + 1; i++) {
op->imm <<= 8;
op->imm |= buf[i + 1];
}
settxtf (op, "push%d 0x%x", pushSize + 1, op->imm);
*/
ret = 2 + pushSize;
}
break;
case EVM_OP_DUP1:
case EVM_OP_DUP2:
case EVM_OP_DUP3:
case EVM_OP_DUP4:
case EVM_OP_DUP5:
case EVM_OP_DUP6:
case EVM_OP_DUP7:
case EVM_OP_DUP8:
case EVM_OP_DUP9:
case EVM_OP_DUP10:
case EVM_OP_DUP11:
case EVM_OP_DUP12:
case EVM_OP_DUP13:
case EVM_OP_DUP14:
case EVM_OP_DUP15:
case EVM_OP_DUP16:
{
// settxtf (op, "dup%d", dupSize);
ret = 1;
}
break;
case EVM_OP_SWAP1:
case EVM_OP_SWAP2:
case EVM_OP_SWAP3:
case EVM_OP_SWAP4:
case EVM_OP_SWAP5:
case EVM_OP_SWAP6:
case EVM_OP_SWAP7:
case EVM_OP_SWAP8:
case EVM_OP_SWAP9:
case EVM_OP_SWAP10:
case EVM_OP_SWAP11:
case EVM_OP_SWAP12:
case EVM_OP_SWAP13:
case EVM_OP_SWAP14:
case EVM_OP_SWAP15:
case EVM_OP_SWAP16:
{
// settxtf (op, "swap%d", swapSize);
ret = 1;
}
break;
case EVM_OP_LOG0:
case EVM_OP_LOG1:
case EVM_OP_LOG2:
case EVM_OP_LOG3:
case EVM_OP_LOG4:
{
// settxtf (op, "log%d", logSize);
ret = 1;
}
break;
default:
// settxtf (op, "invalid");
ret = 1;
break;
}
return ret;
}
/* Jumps/calls in EVM are done via first pushing dst value
* on the stack, and then calling a jump/jumpi instruction, for example:
* 0x0000000d push 0x42
* 0x0000000f jumpi
*
* we are storing the value in push instruction to db, but not at the
* addr of the push instruction, but at the addr of next jumpi instruction.
* So in our example we are inserting (0xf, 0x42)
*/
static int evm_add_push_to_db(ut64 addr, const ut8 *buf, int len) {
ut8 opcode = buf[0];
ut64 next_cmd_addr = addr + evm_oplen (opcode);
ut64 dst_addr = 0;
size_t i, push_size;
char key[16] = {0}, value[16] = {0};
push_size = opcode - EVM_OP_PUSH1;
for (i = 0; i < push_size + 1; i++) {
dst_addr <<= 8;
dst_addr |= buf[i + 1];
}
if (evm_ai) {
snprintf (key, sizeof(key) - 1, "%08x", (unsigned) next_cmd_addr);
snprintf (value, sizeof(value) - 1, "%08x", (unsigned) dst_addr);
sdb_set (evm_ai->pushs_db, key, value, 0);
}
return 0;
}
static st64 evm_get_jmp_addr(ut64 addr) {
char key[16] = {0};
const char *value;
unsigned ret;
snprintf (key, sizeof(key) - 1, "%08x", (unsigned) addr);
value = sdb_const_get (evm_ai->pushs_db, key, 0);
if (value) {
sscanf(value, "%08x", &ret);
return ret;
} else {
return -1;
}
}
static int evm_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
ut32 *push4op;
st64 ret;
ut8 opcode;
char sig[64] = {0};
opcode = buf[0];
memset (op, 0, sizeof(RAnalOp));
op->type = opcodes_types[opcode];
if (!op->type) {
op->type = R_ANAL_OP_TYPE_UNK;
}
op->addr = addr;
op->jump = op->fail = -1;
op->ptr = op->val = -1;
r_strbuf_init (&op->esil);
switch (opcode) {
case EVM_OP_JUMP:
case EVM_OP_JUMPI:
op->fail = addr + 1;
if (opcode == EVM_OP_JUMP) {
op->type = R_ANAL_OP_TYPE_JMP;
} else {
op->type = R_ANAL_OP_TYPE_CJMP;
}
ret = evm_get_jmp_addr(addr);
if (ret >= 0) {
op->jump = ret;
} else {
op->type = R_ANAL_OP_TYPE_UJMP;
}
op->eob = true;
break;
case EVM_OP_PC:
break;
case EVM_OP_MSIZE:
break;
case EVM_OP_GAS:
break;
case EVM_OP_JUMPDEST:
break;
case EVM_OP_PUSH1:
case EVM_OP_PUSH2:
case EVM_OP_PUSH3:
case EVM_OP_PUSH4:
evm_add_push_to_db (addr, buf, len);
if (opcode == EVM_OP_PUSH4 && sigs_info && sigs_info->sigs_db) {
push4op = (ut32 *)(buf + 1);
snprintf(sig, sizeof(sig) - 1, "0x%08x", ntohl((unsigned)(*push4op)));
const char *data = sdb_const_get (sigs_info->sigs_db, sig, 0);
if (data) {
char addr_str[16];
char value[1024];
snprintf(addr_str, sizeof(addr_str) - 1, "0x%08x", (unsigned int)addr);
addr_str[16 - 1] = '\0';
snprintf(value, sizeof(value) - 1, "calls a function %s with signature %s",
data, sig);
value[1023] = '\0';
sdb_set(sigs_info->found_sigs_db, addr_str, value, 0);
r_meta_set_string(anal, 'C', addr, data);
}
}
break;
default:
break;
}
op->size = evm_oplen (opcode);
return evm_oplen (opcode);
}
static int evm_load_symbol_map (RAnal *anal, const char *file) {
size_t i;
int ret = 0;
bool rc;
if (sigs_info) {
r_io_close (sigs_info->rio);
r_io_free (sigs_info->rio);
sdb_free (sigs_info->sigs_db);
sdb_free (sigs_info->found_sigs_db);
free (sigs_info->contents);
free (sigs_info);
}
sigs_info = malloc(sizeof(*sigs_info));
memset(sigs_info, 0, sizeof(*sigs_info));
if (!sigs_info) {
ret = -1;
goto out;
}
if (sigs_info) {
sigs_info->rio = r_io_new ();
sigs_info->riodesc = r_io_open (sigs_info->rio, file, R_PERM_R, 0644);
if (!sigs_info->riodesc) {
printf ("Failed to open %s: %s\n", file, strerror (errno));
ret = -1;
goto out_free;
} else {
json_error_t error;
sigs_info->contents_len = r_io_size (sigs_info->rio);
sigs_info->contents = malloc(sigs_info->contents_len + 1);
rc = r_io_read (sigs_info->rio, sigs_info->contents, sigs_info->contents_len);
if (rc == false) {
printf ("Failed to read file\n");
ret = -1;
goto out_close;
}
sigs_info->contents[sigs_info->contents_len] = '\0';
sigs_info->root = json_loads ((const char*)sigs_info->contents, 0, &error);
if (!sigs_info->root) {
printf ("Failed to parse json document on line %d: %s\n",
error.line, error.text);
} else {
printf ("Parsed successfully\n");
sigs_info->sigs_db = sdb_new0 ();
sigs_info->found_sigs_db = sdb_new0 ();
for (i = 0; i < json_array_size (sigs_info->root); i++) {
json_t *elem, *sig, *args, *name;
char *name_str, *sig_str, *args_str, *value;
size_t value_size;
elem = json_array_get (sigs_info->root, i);
if (!elem) {
continue;
}
sig = json_object_get (elem, "sig");
name = json_object_get (elem, "name");
args = json_object_get (elem, "args");
if (!sig || !name || !args) {
continue;
}
sig_str = strdup (json_string_value (sig));
name_str = strdup (json_string_value (name));
args_str = strdup (json_string_value (args));
value_size = strlen(name_str) + strlen(args_str) + 8;
value = malloc(sizeof(char) * value_size);
snprintf(value, value_size - 1, "%s(%s)", name_str, args_str);
sdb_set (sigs_info->sigs_db, sig_str, value, 0);
free (value);
free (args_str);
free (name_str);
free (sig_str);
}
json_decref (sigs_info->root);
free (sigs_info->contents);
sigs_info->root = 0;
sigs_info->contents = 0;
}
}
}
goto out;
out_close:
r_io_close (sigs_info->rio);
out_free:
r_io_free (sigs_info->rio);
sigs_info->rio = NULL;
free (sigs_info);
sigs_info = NULL;
out:
return ret;
}
static int evm_list_found_symbols_cb (void *user, const char *k, const char *v) {
printf ("%s | %s\n", k, v);
return 1;
}
static int evm_list_found_symbols (RAnal *anal) {
if (sigs_info && sigs_info->found_sigs_db) {
sdb_foreach (sigs_info->found_sigs_db, evm_list_found_symbols_cb, NULL);
}
return 0;
}
static void evm_cmd_ext_help () {
printf ("a!l <file path> - Read a JSON file with function signatures\n"
"a!f - List found function signatures\n"
"a!h - Show this help message\n");
}
static int evm_cmd_ext (RAnal *anal, const char *input) {
const char *arg = input;
arg++;
while (*arg == ' ') {
arg++;
}
switch (input[0]) {
case 'l':
printf("here %s\n", arg);
evm_load_symbol_map (anal, arg);
break;
case 'f':
evm_list_found_symbols (anal);
break;
case 'h':
default:
evm_cmd_ext_help ();
return -1;
}
return 0;
}
static int evm_anal_init (void *user) {
if (!evm_ai) {
evm_ai = (struct evm_anal_info*)malloc (sizeof(*evm_ai));
evm_ai->pushs_db = sdb_new0 ();
}
return 0;
}
static int evm_anal_fini (void *user) {
if (evm_ai) {
if (evm_ai->pushs_db) {
sdb_free (evm_ai->pushs_db);
}
free(evm_ai);
evm_ai = NULL;
}
return 0;
}
RAnalPlugin r_anal_plugin_evm = {
.name = "evm",
.desc = "ETHEREUM VM code analysis plugin",
.license = "LGPL3",
.arch = "evm",
.bits = 8,
.op = evm_op,
.init = evm_anal_init,
.fini = evm_anal_fini,
.esil = false,
.cmd_ext = evm_cmd_ext,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_evm,
.version = R2_VERSION
};
#endif
-799
View File
@@ -1,799 +0,0 @@
/* nios plugin by hewittc at 2018-2020 */
#include <string.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_asm.h>
#include <r_anal.h>
#include <sdb.h>
#include "dis-asm.h"
#include "nios/gnu/nios-desc.h"
#define f_op11(i) ((i >> 5))
#define f_op9(i) ((i >> 7))
#define f_op8(i) ((i >> 8))
#define f_op6(i) ((i >> 10))
#define f_op5w(i) ((i >> 5) & 0x001f)
#define f_op5(i) ((i >> 11))
#define f_op4(i) ((i >> 12))
#define f_op3u(i) ((i >> 7) & 0x0007)
#define f_op3(i) ((i >> 13))
#define f_op2v(i) ((i >> 8) & 0x0003)
#define f_IMM11(i) ((i >> 0) & 0x07ff)
#define f_IMM10(i) ((i >> 0) & 0x03ff)
#define f_IMM9(i) ((i >> 1) & 0x01ff)
#define f_IMM8v(i) ((i >> 0) & 0x00ff)
#define f_IMM8(i) ((i >> 5) & 0x00ff)
#define f_IMM6v(i) ((i >> 0) & 0x003f)
#define f_IMM6(i) ((i >> 5) & 0x003f)
#define f_IMM5(i) ((i >> 5) & 0x001f)
#define f_IMM4w(i) ((i >> 0) & 0x00ff)
#define f_IMM4(i) ((i >> 5) & 0x000f)
#define f_IMM2u(i) ((i >> 5) & 0x0003)
#define f_IMM1u(i) ((i >> 6) & 0x0001)
#define f_P(i) ((i >> 10) & 0x0003)
#define f_B(i) ((i >> 5) & 0x001f)
#define f_A(i) ((i >> 0) & 0x001f)
enum insn_format {
FMT_RR,
FMT_Ri5,
FMT_Ri4,
FMT_RPi5,
FMT_Ri6,
FMT_Ri8,
FMT_i9,
FMT_i10,
FMT_i11,
FMT_Ri1u,
FMT_Ri2u,
FMT_i8v,
FMT_i6v,
FMT_Rw,
FMT_i4w,
FMT_w
};
enum insn_type {
TYPE_OP6,
TYPE_OP9,
TYPE_OP8,
TYPE_OP11,
TYPE_OP5,
TYPE_OP4,
TYPE_OP3,
TYPE_OPS
};
struct insn_fields {
ut16 op11 : 11;
ut16 op9 : 9;
ut16 op8 : 8;
ut16 op6 : 6;
ut16 op5w : 5;
ut16 op5 : 5;
ut16 op4 : 4;
ut16 op3u : 3;
ut16 op3 : 3;
ut16 op2v : 2;
st16 IMM11 : 11;
st16 IMM10 : 10;
st16 IMM9 : 9;
st16 IMM8v : 8;
st16 IMM8 : 8;
st16 IMM6v : 6;
st16 IMM6 : 6;
st16 IMM5 : 5;
st16 IMM4w : 4;
st16 IMM4 : 4;
st16 IMM2u : 2;
st16 IMM1u : 1;
st16 P : 2;
st16 B : 5;
st16 A : 5;
};
struct insn_op {
enum mach_attr mach;
enum insn_type type;
ut16 opcode;
enum insn_format format;
_RAnalOpType r_op_type;
};
#define INSN_OPS_MAX 131
static const struct insn_op insn_ops[INSN_OPS_MAX] = {
{ MACH_NIOS16, TYPE_OP6, OP_ADD, FMT_RR, R_ANAL_OP_TYPE_ADD },
{ MACH_NIOS16, TYPE_OP6, OP_ADDI, FMT_Ri5, R_ANAL_OP_TYPE_ADD },
{ MACH_NIOS16, TYPE_OP6, OP_SUB, FMT_RR, R_ANAL_OP_TYPE_SUB },
{ MACH_NIOS16, TYPE_OP6, OP_SUBI, FMT_Ri5, R_ANAL_OP_TYPE_SUB },
{ MACH_NIOS16, TYPE_OP6, OP_CMP, FMT_RR, R_ANAL_OP_TYPE_CMP },
{ MACH_NIOS16, TYPE_OP6, OP_CMPI, FMT_Ri5, R_ANAL_OP_TYPE_CMP },
{ MACH_NIOS16, TYPE_OP6, OP_LSL, FMT_RR, R_ANAL_OP_TYPE_SHL },
{ MACH_NIOS16, TYPE_OP6, OP_LSLI, FMT_Ri4, R_ANAL_OP_TYPE_SHL },
{ MACH_NIOS16, TYPE_OP6, OP_LSR, FMT_RR, R_ANAL_OP_TYPE_SHR },
{ MACH_NIOS16, TYPE_OP6, OP_LSRI, FMT_Ri4, R_ANAL_OP_TYPE_SHR },
{ MACH_NIOS16, TYPE_OP6, OP_ASR, FMT_RR, R_ANAL_OP_TYPE_SAR },
{ MACH_NIOS16, TYPE_OP6, OP_ASRI, FMT_Ri4, R_ANAL_OP_TYPE_SAR },
{ MACH_NIOS16, TYPE_OP6, OP_MOV, FMT_RR, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS16, TYPE_OP6, OP_MOVI, FMT_Ri5, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS16, TYPE_OP6, OP_AND, FMT_RR, R_ANAL_OP_TYPE_AND },
{ MACH_NIOS16, TYPE_OP6, OP_ANDN, FMT_RR, R_ANAL_OP_TYPE_AND },
{ MACH_NIOS16, TYPE_OP6, OP_OR, FMT_RR, R_ANAL_OP_TYPE_OR },
{ MACH_NIOS16, TYPE_OP6, OP_XOR, FMT_RR, R_ANAL_OP_TYPE_XOR },
{ MACH_NIOS16, TYPE_OP6, OP_BGEN, FMT_Ri4, R_ANAL_OP_TYPE_MUL },
{ MACH_NIOS16, TYPE_OP6, OP_EXT8D, FMT_RR, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS16, TYPE_OP6, OP_SKP0, FMT_Ri4, R_ANAL_OP_TYPE_CJMP },
{ MACH_NIOS16, TYPE_OP6, OP_SKP1, FMT_Ri4, R_ANAL_OP_TYPE_CJMP },
{ MACH_NIOS16, TYPE_OP6, OP_LD, FMT_RR, R_ANAL_OP_TYPE_LOAD },
{ MACH_NIOS16, TYPE_OP6, OP_ST, FMT_RR, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS16, TYPE_OP6, OP_STS8S, FMT_i10, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS16, TYPE_OP6, OP_ADDC, FMT_RR, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS16, TYPE_OP6, OP_SUBC, FMT_Ri5, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS16, TYPE_OP6, OP_USR0, FMT_RR, R_ANAL_OP_TYPE_IO },
{ MACH_NIOS16, TYPE_OP3, OP_STS, FMT_Ri8, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS16, TYPE_OP3, OP_LDS, FMT_Ri8, R_ANAL_OP_TYPE_LOAD },
{ MACH_NIOS16, TYPE_OP4, OP_STP, FMT_RPi5, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS16, TYPE_OP4, OP_LDP, FMT_RPi5, R_ANAL_OP_TYPE_LOAD },
{ MACH_NIOS16, TYPE_OP5, OP_BR, FMT_i11, R_ANAL_OP_TYPE_JMP },
{ MACH_NIOS16, TYPE_OP5, OP_BSR, FMT_i11, R_ANAL_OP_TYPE_JMP },
{ MACH_NIOS16, TYPE_OP5, OP_PFX, FMT_i11, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS16, TYPE_OP8, OP_SAVE, FMT_i8v, R_ANAL_OP_TYPE_PUSH },
{ MACH_NIOS16, TYPE_OP8, OP_TRAP, FMT_i6v, R_ANAL_OP_TYPE_TRAP },
{ MACH_NIOS16, TYPE_OP9, OP_EXT8S, FMT_Ri1u, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS16, TYPE_OP9, OP_ST8S, FMT_Ri1u, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS16, TYPE_OP11, OP_NOT, FMT_Rw, R_ANAL_OP_TYPE_NOT },
{ MACH_NIOS16, TYPE_OP11, OP_NEG, FMT_Rw, R_ANAL_OP_TYPE_SUB },
{ MACH_NIOS16, TYPE_OP11, OP_ABS, FMT_Rw, R_ANAL_OP_TYPE_ABS },
{ MACH_NIOS16, TYPE_OP11, OP_SEXT8, FMT_Rw, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS16, TYPE_OP11, OP_RLC, FMT_Rw, R_ANAL_OP_TYPE_ROL },
{ MACH_NIOS16, TYPE_OP11, OP_RRC, FMT_Rw, R_ANAL_OP_TYPE_ROR },
{ MACH_NIOS16, TYPE_OP11, OP_TRET, FMT_Rw, R_ANAL_OP_TYPE_UJMP },
{ MACH_NIOS16, TYPE_OP11, OP_RESTORE, FMT_w, R_ANAL_OP_TYPE_POP },
{ MACH_NIOS16, TYPE_OP11, OP_ST8D, FMT_Rw, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS16, TYPE_OP11, OP_FILL8, FMT_Rw, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS16, TYPE_OP11, OP_SKPRZ, FMT_Rw, R_ANAL_OP_TYPE_CJMP },
{ MACH_NIOS16, TYPE_OP11, OP_SKPS, FMT_Rw, R_ANAL_OP_TYPE_CJMP },
{ MACH_NIOS16, TYPE_OP11, OP_WRCTL, FMT_Rw, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS16, TYPE_OP11, OP_RDCTL, FMT_Rw, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS16, TYPE_OP11, OP_SKPRNZ, FMT_Rw, R_ANAL_OP_TYPE_CJMP },
{ MACH_NIOS16, TYPE_OP11, OP_JMP, FMT_Rw, R_ANAL_OP_TYPE_JMP },
{ MACH_NIOS16, TYPE_OP11, OP_CALL, FMT_Rw, R_ANAL_OP_TYPE_CALL },
{ MACH_NIOS16, TYPE_OP11, OP_SWAP, FMT_Rw, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS16, TYPE_OP11, OP_USR1, FMT_Rw, R_ANAL_OP_TYPE_IO },
{ MACH_NIOS16, TYPE_OP11, OP_USR2, FMT_Rw, R_ANAL_OP_TYPE_IO },
{ MACH_NIOS16, TYPE_OP11, OP_USR3, FMT_Rw, R_ANAL_OP_TYPE_IO },
{ MACH_NIOS16, TYPE_OP11, OP_USR4, FMT_Rw, R_ANAL_OP_TYPE_IO },
{ MACH_NIOS32, TYPE_OP6, OP_ADD, FMT_RR, R_ANAL_OP_TYPE_ADD },
{ MACH_NIOS32, TYPE_OP6, OP_ADDI, FMT_Ri5, R_ANAL_OP_TYPE_ADD },
{ MACH_NIOS32, TYPE_OP6, OP_SUB, FMT_RR, R_ANAL_OP_TYPE_SUB },
{ MACH_NIOS32, TYPE_OP6, OP_SUBI, FMT_Ri5, R_ANAL_OP_TYPE_SUB },
{ MACH_NIOS32, TYPE_OP6, OP_CMP, FMT_RR, R_ANAL_OP_TYPE_CMP },
{ MACH_NIOS32, TYPE_OP6, OP_CMPI, FMT_Ri5, R_ANAL_OP_TYPE_CMP },
{ MACH_NIOS32, TYPE_OP6, OP_LSL, FMT_RR, R_ANAL_OP_TYPE_SHL },
{ MACH_NIOS32, TYPE_OP6, OP_LSLI, FMT_Ri5, R_ANAL_OP_TYPE_SHL },
{ MACH_NIOS32, TYPE_OP6, OP_LSR, FMT_RR, R_ANAL_OP_TYPE_SHR },
{ MACH_NIOS32, TYPE_OP6, OP_LSRI, FMT_Ri5, R_ANAL_OP_TYPE_SHR },
{ MACH_NIOS32, TYPE_OP6, OP_ASR, FMT_RR, R_ANAL_OP_TYPE_SAR },
{ MACH_NIOS32, TYPE_OP6, OP_ASRI, FMT_Ri5, R_ANAL_OP_TYPE_SAR },
{ MACH_NIOS32, TYPE_OP6, OP_MOV, FMT_RR, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP6, OP_MOVI, FMT_Ri5, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP6, OP_AND, FMT_RR, R_ANAL_OP_TYPE_AND },
{ MACH_NIOS32, TYPE_OP6, OP_ANDN, FMT_RR, R_ANAL_OP_TYPE_AND },
{ MACH_NIOS32, TYPE_OP6, OP_OR, FMT_RR, R_ANAL_OP_TYPE_OR },
{ MACH_NIOS32, TYPE_OP6, OP_XOR, FMT_RR, R_ANAL_OP_TYPE_XOR },
{ MACH_NIOS32, TYPE_OP6, OP_BGEN, FMT_Ri5, R_ANAL_OP_TYPE_MUL },
{ MACH_NIOS32, TYPE_OP6, OP_EXT8D, FMT_RR, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP6, OP_SKP0, FMT_Ri5, R_ANAL_OP_TYPE_CJMP },
{ MACH_NIOS32, TYPE_OP6, OP_SKP1, FMT_Ri5, R_ANAL_OP_TYPE_CJMP },
{ MACH_NIOS32, TYPE_OP6, OP_LD, FMT_RR, R_ANAL_OP_TYPE_LOAD },
{ MACH_NIOS32, TYPE_OP6, OP_ST, FMT_RR, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS32, TYPE_OP6, OP_STS8S, FMT_i10, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS32, TYPE_OP6, OP_STS16S, FMT_i9, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS32, TYPE_OP6, OP_EXT16D, FMT_RR, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP6, OP_MOVHI, FMT_Ri5, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP6, OP_USR0, FMT_RR, R_ANAL_OP_TYPE_IO },
{ MACH_NIOS32, TYPE_OP3, OP_STS, FMT_Ri8, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS32, TYPE_OP3, OP_LDS, FMT_Ri8, R_ANAL_OP_TYPE_LOAD },
{ MACH_NIOS32, TYPE_OP4, OP_STP, FMT_RPi5, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS32, TYPE_OP4, OP_LDP, FMT_RPi5, R_ANAL_OP_TYPE_LOAD },
{ MACH_NIOS32, TYPE_OP5, OP_BR, FMT_i11, R_ANAL_OP_TYPE_JMP },
{ MACH_NIOS32, TYPE_OP5, OP_BSR, FMT_i11, R_ANAL_OP_TYPE_JMP },
{ MACH_NIOS32, TYPE_OP5, OP_PFXIO, FMT_i11, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP5, OP_PFX, FMT_i11, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP8, OP_SAVE, FMT_i8v, R_ANAL_OP_TYPE_PUSH },
{ MACH_NIOS32, TYPE_OP8, OP_TRAP, FMT_i6v, R_ANAL_OP_TYPE_TRAP },
{ MACH_NIOS32, TYPE_OP9, OP_EXT8S, FMT_Ri1u, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP9, OP_EXT16S, FMT_Ri1u, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP9, OP_ST8S, FMT_Ri1u, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS32, TYPE_OP9, OP_ST16S, FMT_Ri1u, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS32, TYPE_OP11, OP_NOT, FMT_Rw, R_ANAL_OP_TYPE_NOT },
{ MACH_NIOS32, TYPE_OP11, OP_NEG, FMT_Rw, R_ANAL_OP_TYPE_SUB },
{ MACH_NIOS32, TYPE_OP11, OP_ABS, FMT_Rw, R_ANAL_OP_TYPE_ABS },
{ MACH_NIOS32, TYPE_OP11, OP_SEXT8, FMT_Rw, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP11, OP_SEXT16, FMT_Rw, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP11, OP_RLC, FMT_Rw, R_ANAL_OP_TYPE_ROL },
{ MACH_NIOS32, TYPE_OP11, OP_RRC, FMT_Rw, R_ANAL_OP_TYPE_ROR },
{ MACH_NIOS32, TYPE_OP11, OP_TRET, FMT_Rw, R_ANAL_OP_TYPE_UJMP },
{ MACH_NIOS32, TYPE_OP11, OP_RESTORE, FMT_w, R_ANAL_OP_TYPE_POP },
{ MACH_NIOS32, TYPE_OP11, OP_ST8D, FMT_Rw, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS32, TYPE_OP11, OP_ST16D, FMT_Rw, R_ANAL_OP_TYPE_STORE },
{ MACH_NIOS32, TYPE_OP11, OP_FILL8, FMT_Rw, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP11, OP_FILL16, FMT_Rw, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP11, OP_SKPRZ, FMT_Rw, R_ANAL_OP_TYPE_CJMP },
{ MACH_NIOS32, TYPE_OP11, OP_SKPS, FMT_Rw, R_ANAL_OP_TYPE_CJMP },
{ MACH_NIOS32, TYPE_OP11, OP_WRCTL, FMT_Rw, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP11, OP_RDCTL, FMT_Rw, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP11, OP_SKPRNZ, FMT_Rw, R_ANAL_OP_TYPE_CJMP },
{ MACH_NIOS32, TYPE_OP11, OP_JMP, FMT_Rw, R_ANAL_OP_TYPE_JMP },
{ MACH_NIOS32, TYPE_OP11, OP_CALL, FMT_Rw, R_ANAL_OP_TYPE_CALL },
{ MACH_NIOS32, TYPE_OP11, OP_SWAP, FMT_Rw, R_ANAL_OP_TYPE_MOV },
{ MACH_NIOS32, TYPE_OP11, OP_USR1, FMT_Rw, R_ANAL_OP_TYPE_IO },
{ MACH_NIOS32, TYPE_OP11, OP_USR2, FMT_Rw, R_ANAL_OP_TYPE_IO },
{ MACH_NIOS32, TYPE_OP11, OP_USR3, FMT_Rw, R_ANAL_OP_TYPE_IO },
{ MACH_NIOS32, TYPE_OP11, OP_USR4, FMT_Rw, R_ANAL_OP_TYPE_IO },
{ MACH_NIOS32, TYPE_OP11, OP_MSTEP, FMT_Rw, R_ANAL_OP_TYPE_MUL },
{ MACH_NIOS32, TYPE_OP11, OP_MUL, FMT_Rw, R_ANAL_OP_TYPE_MUL }
};
struct nios_info {
HtPP *ops;
};
static struct nios_info *nios;
static const char *nios16_reg_profile = \
"=SR ctl0\n"
"=PC pc\n"
"=SP r14\n"
"=LR r15\n"
"=BP r30\n"
/* control registers */
"gpr ctl0 .16 0 0\n"
"gpr ctl1 .16 2 0\n"
"gpr ctl2 .16 4 0\n"
"gpr ctl3 .16 6 0\n"
"gpr ctl4 .16 8 0\n"
"gpr ctl5 .16 10 0\n"
"gpr ctl6 .16 12 0\n"
"gpr ctl7 .16 14 0\n"
"gpr ctl8 .16 16 0\n"
"gpr ctl9 .16 18 0\n"
"gpr pc .16 20 0\n"
"gpr k .16 22 0\n"
/* r0-r7 are global (g0-g7) */
"gpr r0 .16 24 0\n"
"gpr r1 .16 26 0\n"
"gpr r2 .16 28 0\n"
"gpr r3 .16 30 0\n"
"gpr r4 .16 32 0\n"
"gpr r5 .16 34 0\n"
"gpr r6 .16 36 0\n"
"gpr r7 .16 38 0\n"
/* r8-15 are out (o0-o7) */
"gpr r8 .16 40 0\n"
"gpr r9 .16 42 0\n"
"gpr r10 .16 44 0\n"
"gpr r11 .16 46 0\n"
"gpr r12 .16 48 0\n"
"gpr r13 .16 50 0\n"
"gpr r14 .16 52 0\n"
"gpr r15 .16 54 0\n"
/* r16-23 are local (l0-l7) */
"gpr r16 .16 56 0\n"
"gpr r17 .16 58 0\n"
"gpr r18 .16 60 0\n"
"gpr r19 .16 62 0\n"
"gpr r20 .16 64 0\n"
"gpr r21 .16 66 0\n"
"gpr r22 .16 68 0\n"
"gpr r23 .16 70 0\n"
/* r24-31 are in (i0-i7) */
"gpr r24 .16 72 0\n"
"gpr r25 .16 74 0\n"
"gpr r26 .16 76 0\n"
"gpr r27 .16 78 0\n"
"gpr r28 .16 80 0\n"
"gpr r29 .16 82 0\n"
"gpr r30 .16 84 0\n"
"gpr r31 .16 86 0\n";
static const char *nios32_reg_profile = \
"=SR ctl0\n"
"=PC pc\n"
"=SP r14\n"
"=LR r15\n"
"=BP r30\n"
/* control registers */
"gpr ctl0 .32 0 0\n"
"gpr ctl1 .32 4 0\n"
"gpr ctl2 .32 8 0\n"
"gpr ctl3 .32 12 0\n"
"gpr ctl4 .32 16 0\n"
"gpr ctl5 .32 20 0\n"
"gpr ctl6 .32 24 0\n"
"gpr ctl7 .32 28 0\n"
"gpr ctl8 .32 32 0\n"
"gpr ctl9 .32 36 0\n"
"gpr pc .32 40 0\n"
"gpr k .16 44 0\n"
/* r0-r7 are global (g0-g7) */
"gpr r0 .32 48 0\n"
"gpr r1 .32 52 0\n"
"gpr r2 .32 56 0\n"
"gpr r3 .32 60 0\n"
"gpr r4 .32 64 0\n"
"gpr r5 .32 68 0\n"
"gpr r6 .32 72 0\n"
"gpr r7 .32 76 0\n"
/* r8-15 are out (o0-o7) */
"gpr r8 .32 80 0\n"
"gpr r9 .32 84 0\n"
"gpr r10 .32 88 0\n"
"gpr r11 .32 92 0\n"
"gpr r12 .32 96 0\n"
"gpr r13 .32 100 0\n"
"gpr r14 .32 104 0\n"
"gpr r15 .32 108 0\n"
/* r16-23 are local (l0-l7) */
"gpr r16 .32 112 0\n"
"gpr r17 .32 116 0\n"
"gpr r18 .32 120 0\n"
"gpr r19 .32 124 0\n"
"gpr r20 .32 128 0\n"
"gpr r21 .32 132 0\n"
"gpr r22 .32 136 0\n"
"gpr r23 .32 140 0\n"
/* r24-31 are in (i0-i7) */
"gpr r24 .32 144 0\n"
"gpr r25 .32 148 0\n"
"gpr r26 .32 152 0\n"
"gpr r27 .32 156 0\n"
"gpr r28 .32 160 0\n"
"gpr r29 .32 164 0\n"
"gpr r30 .32 168 0\n"
"gpr r31 .32 172 0\n";
static int parse_insn(enum mach_attr mach, ut16 insn, struct insn_op **op, struct insn_fields *f) {
ut16 insns[TYPE_OPS] = {
f_op6(insn),
f_op9(insn),
f_op8(insn),
f_op11(insn),
f_op5(insn),
f_op4(insn),
f_op3(insn),
};
bool found;
int opcode;
for (int type = TYPE_OP6; type < TYPE_OPS; type++) {
r_strf_var (key, 128, "%d %d %d", mach, type, insns[type]);
*op = ht_pp_find(nios->ops, key, &found);
if (found) {
opcode = (*op)->opcode;
break;
}
}
if (!found) {
return -1;
}
switch ((*op)->format) {
case FMT_RR:
f->op6 = f_op6(insn);
f->B = f_B(insn);
f->A = f_A(insn);
break;
case FMT_Ri5:
f->op6 = f_op6(insn);
f->IMM5 = f_IMM5(insn);
f->A = f_A(insn);
break;
case FMT_Ri4:
f->op6 = f_op6(insn);
f->IMM4 = f_IMM4(insn);
f->A = f_A(insn);
break;
case FMT_RPi5:
f->op4 = f_op4(insn);
f->P = f_P(insn);
f->B = f_B(insn);
f->A = f_A(insn);
break;
case FMT_Ri6:
f->op5 = f_op5(insn);
f->IMM6 = f_IMM6(insn);
f->A = f_A(insn);
break;
case FMT_Ri8:
f->op3 = f_op3(insn);
f->IMM8 = f_IMM8(insn);
f->A = f_A(insn);
break;
case FMT_i9:
f->op6 = f_op6(insn);
f->IMM9 = f_IMM9(insn);
break;
case FMT_i10:
f->op6 = f_op6(insn);
f->IMM10 = f_IMM10(insn);
break;
case FMT_i11:
f->op5 = f_op5(insn);
f->IMM11 = f_IMM11(insn);
break;
case FMT_Ri1u:
f->op6 = f_op6(insn);
f->op3u = f_op3u(insn);
f->IMM1u = f_IMM1u(insn);
f->A = f_A(insn);
break;
case FMT_Ri2u:
f->op6 = f_op6(insn);
f->op3u = f_op3u(insn);
f->IMM2u = f_IMM2u(insn);
f->A = f_A(insn);
break;
case FMT_i8v:
f->op6 = f_op6(insn);
f->op2v = f_op2v(insn);
f->IMM8v = f_IMM8v(insn);
break;
case FMT_i6v:
f->op6 = f_op6(insn);
f->op2v = f_op2v(insn);
f->IMM6v = f_IMM6v(insn);
break;
case FMT_Rw:
f->op6 = f_op6(insn);
f->op5w = f_op5w(insn);
f->A = f_A(insn);
break;
case FMT_i4w:
f->op6 = f_op6(insn);
f->op5w = f_op5w(insn);
f->IMM4w = f_IMM4w(insn);
break;
case FMT_w:
f->op6 = f_op6(insn);
f->op5w = f_op5w(insn);
break;
default:
break;
}
return opcode;
}
static void nios16_anal(RAnalOp *op, ut16 opcode, enum insn_type type, struct insn_fields *f) {
if (type == TYPE_OP6) {
switch (opcode) {
case OP_ADD:
case OP_ADDI:
case OP_SUB:
case OP_SUBI:
case OP_CMP:
case OP_CMPI:
case OP_LSL:
case OP_LSLI:
case OP_LSR:
case OP_LSRI:
case OP_ASR:
case OP_ASRI:
case OP_MOV:
case OP_MOVI:
case OP_AND:
case OP_ANDN:
case OP_OR:
case OP_XOR:
case OP_BGEN:
case OP_EXT8D:
case OP_SKP0:
case OP_SKP1:
case OP_LD:
case OP_ST:
case OP_STS8S:
case OP_ADDC:
case OP_SUBC:
case OP_USR0:
default:
break;
}
} else if (type == TYPE_OP3) {
switch (opcode) {
case OP_STS:
case OP_LDS:
default:
break;
}
} else if (type == TYPE_OP4) {
switch (opcode) {
case OP_STP:
case OP_LDP:
default:
break;
}
} else if (type == TYPE_OP5) {
switch (opcode) {
case OP_BR:
case OP_BSR:
op->jump = op->addr + ((f->IMM11 + 1) * 2);
break;
case OP_PFX:
default:
break;
}
} else if (type == TYPE_OP8) {
switch (opcode) {
case OP_SAVE:
case OP_TRAP:
break;
}
} else if (type == TYPE_OP9) {
switch (opcode) {
case OP_EXT8S:
case OP_ST8S:
default:
break;
}
} else if (type == TYPE_OP11) {
switch (opcode) {
case OP_NOT:
case OP_NEG:
case OP_ABS:
case OP_SEXT8:
case OP_RLC:
case OP_RRC:
case OP_TRET:
case OP_RESTORE:
case OP_ST8D:
case OP_FILL8:
case OP_SKPRZ:
case OP_SKPS:
case OP_WRCTL:
case OP_RDCTL:
case OP_SKPRNZ:
case OP_JMP:
case OP_CALL:
case OP_SWAP:
case OP_USR1:
case OP_USR2:
case OP_USR3:
case OP_USR4:
default:
break;
}
}
}
static void nios32_anal(RAnalOp *op, ut16 opcode, enum insn_type type, struct insn_fields *f) {
if (type == TYPE_OP6) {
switch (opcode) {
case OP_ADD:
case OP_ADDI:
case OP_SUB:
case OP_SUBI:
case OP_CMP:
case OP_CMPI:
case OP_LSL:
case OP_LSLI:
case OP_LSR:
case OP_LSRI:
case OP_ASR:
case OP_ASRI:
case OP_MOV:
case OP_MOVI:
case OP_AND:
case OP_ANDN:
case OP_OR:
case OP_XOR:
case OP_BGEN:
case OP_EXT8D:
case OP_SKP0:
case OP_SKP1:
case OP_LD:
case OP_ST:
case OP_STS8S:
case OP_STS16S:
case OP_EXT16D:
case OP_MOVHI:
case OP_USR0:
default:
break;
}
} else if (type == TYPE_OP3) {
switch (opcode) {
case OP_STS:
case OP_LDS:
default:
break;
}
} else if (type == TYPE_OP4) {
switch (opcode) {
case OP_STP:
case OP_LDP:
default:
break;
}
} else if (type == TYPE_OP5) {
switch (opcode) {
case OP_BR:
case OP_BSR:
op->jump = op->addr + ((f->IMM11 + 1) * 2);
break;
case OP_PFXIO:
case OP_PFX:
default:
break;
}
} else if (type == TYPE_OP8) {
switch (opcode) {
case OP_SAVE:
case OP_TRAP:
default:
break;
}
} else if (type == TYPE_OP9) {
switch (opcode) {
case OP_EXT8S:
case OP_EXT16S:
case OP_ST8S:
case OP_ST16S:
default:
break;
}
} else if (type == TYPE_OP11) {
switch (opcode) {
case OP_NOT:
case OP_NEG:
case OP_ABS:
case OP_SEXT8:
case OP_SEXT16:
case OP_RLC:
case OP_RRC:
case OP_TRET:
case OP_RESTORE:
case OP_ST8D:
case OP_ST16D:
case OP_FILL8:
case OP_FILL16:
case OP_SKPRZ:
case OP_SKPS:
case OP_WRCTL:
case OP_RDCTL:
case OP_SKPRNZ:
case OP_JMP:
case OP_CALL:
case OP_SWAP:
case OP_USR1:
case OP_USR2:
case OP_USR3:
case OP_USR4:
case OP_MSTEP:
case OP_MUL:
default:
break;
}
}
}
static int nios_op(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *data, int len, RAnalOpMask mask) {
if (!op) {
return -1;
}
memset(op, 0, sizeof (RAnalOp));
op->size = CGEN_MAX_INSN_SIZE;
op->addr = addr;
op->type = R_ANAL_OP_TYPE_UNK;
enum mach_attr arch;
void (*nios_anal)(RAnalOp *, ut16, enum insn_type, struct insn_fields *);
if (a->bits == 16) {
arch = MACH_NIOS16;
nios_anal = &nios16_anal;
} else {
arch = MACH_NIOS32;
nios_anal = &nios32_anal;
}
ut16 insn;
insn = r_read_ble16(data, a->big_endian);
struct insn_op *insn_op;
struct insn_fields insn_fields = { 0 };
int opcode;
opcode = parse_insn(arch, insn, &insn_op, &insn_fields);
if (opcode >= 0) {
op->type = insn_op->r_op_type;
(*nios_anal)(op, opcode, insn_op->type, &insn_fields);
}
return op->size;
}
static bool set_reg_profile(RAnal *a) {
const char *nios_reg_profile;
if (a->bits == 16) {
nios_reg_profile = nios16_reg_profile;
} else {
nios_reg_profile = nios32_reg_profile;
}
return r_reg_set_profile_string(a->reg, nios_reg_profile);
}
static void nios_free_kv(HtPPKv *kv) {
if (kv && kv->key) {
free(kv->key);
}
}
static int nios_init(void *user) {
if (!nios) {
nios = calloc(1, sizeof (*nios));
nios->ops = ht_pp_new(NULL, nios_free_kv, NULL);
if (!nios->ops) {
return -1;
}
}
for (int i = 0; i < INSN_OPS_MAX; i++) {
const struct insn_op *op = &insn_ops[i];
r_strf_var (key, 64, "%d %d %d", op->mach, op->type, op->opcode);
ht_pp_insert(nios->ops, key, (void *) op);
}
return 0;
}
static int nios_fini(void *user) {
if (nios && nios->ops) {
ht_pp_free(nios->ops);
}
if (nios) {
free(nios);
}
return 0;
}
RAnalPlugin r_anal_plugin_nios = {
.name = "nios",
.desc = "Altera Nios code analysis plugin",
.license = "LGPL3",
.arch = "nios",
.bits = 16 | 32,
.esil = false,
.init = &nios_init,
.fini = &nios_fini,
.op = &nios_op,
.cmd_ext = NULL,
.set_reg_profile = &set_reg_profile,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_nios,
.version = R2_VERSION
};
#endif
-207
View File
@@ -1,207 +0,0 @@
/* rl78 plugin by pancake, using binutils ripped code from 2022 */
#include <string.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_asm.h>
#include <r_anal.h>
#include <sdb.h>
#include "disas-asm.h"
#include "../arch/rl78/rl78-decode.c"
#include "../arch/rl78/rl78-dis.c"
static const char *rl78_reg_profile = \
"=SR ctl0\n"
"=PC pc\n"
"=SP r14\n"
"=LR r15\n"
"=BP r30\n"
/* control registers */
"gpr ctl0 .16 0 0\n"
"gpr ctl1 .16 2 0\n"
"gpr ctl2 .16 4 0\n"
"gpr ctl3 .16 6 0\n"
"gpr ctl4 .16 8 0\n"
"gpr ctl5 .16 10 0\n"
"gpr ctl6 .16 12 0\n"
"gpr ctl7 .16 14 0\n"
"gpr ctl8 .16 16 0\n"
"gpr ctl9 .16 18 0\n"
"gpr pc .16 20 0\n"
"gpr k .16 22 0\n"
/* r0-r7 are global (g0-g7) */
"gpr r0 .16 24 0\n"
"gpr r1 .16 26 0\n"
"gpr r2 .16 28 0\n"
"gpr r3 .16 30 0\n"
"gpr r4 .16 32 0\n"
"gpr r5 .16 34 0\n"
"gpr r6 .16 36 0\n"
"gpr r7 .16 38 0\n"
/* r8-15 are out (o0-o7) */
"gpr r8 .16 40 0\n"
"gpr r9 .16 42 0\n"
"gpr r10 .16 44 0\n"
"gpr r11 .16 46 0\n"
"gpr r12 .16 48 0\n"
"gpr r13 .16 50 0\n"
"gpr r14 .16 52 0\n"
"gpr r15 .16 54 0\n"
/* r16-23 are local (l0-l7) */
"gpr r16 .16 56 0\n"
"gpr r17 .16 58 0\n"
"gpr r18 .16 60 0\n"
"gpr r19 .16 62 0\n"
"gpr r20 .16 64 0\n"
"gpr r21 .16 66 0\n"
"gpr r22 .16 68 0\n"
"gpr r23 .16 70 0\n"
/* r24-31 are in (i0-i7) */
"gpr r24 .16 72 0\n"
"gpr r25 .16 74 0\n"
"gpr r26 .16 76 0\n"
"gpr r27 .16 78 0\n"
"gpr r28 .16 80 0\n"
"gpr r29 .16 82 0\n"
"gpr r30 .16 84 0\n"
"gpr r31 .16 86 0\n";
static const char *rl7832_reg_profile = \
"=SR ctl0\n"
"=PC pc\n"
"=SP r14\n"
"=LR r15\n"
"=BP r30\n"
/* control registers */
"gpr ctl0 .32 0 0\n"
"gpr ctl1 .32 4 0\n"
"gpr ctl2 .32 8 0\n"
"gpr ctl3 .32 12 0\n"
"gpr ctl4 .32 16 0\n"
"gpr ctl5 .32 20 0\n"
"gpr ctl6 .32 24 0\n"
"gpr ctl7 .32 28 0\n"
"gpr ctl8 .32 32 0\n"
"gpr ctl9 .32 36 0\n"
"gpr pc .32 40 0\n"
"gpr k .16 44 0\n"
/* r0-r7 are global (g0-g7) */
"gpr r0 .32 48 0\n"
"gpr r1 .32 52 0\n"
"gpr r2 .32 56 0\n"
"gpr r3 .32 60 0\n"
"gpr r4 .32 64 0\n"
"gpr r5 .32 68 0\n"
"gpr r6 .32 72 0\n"
"gpr r7 .32 76 0\n"
/* r8-15 are out (o0-o7) */
"gpr r8 .32 80 0\n"
"gpr r9 .32 84 0\n"
"gpr r10 .32 88 0\n"
"gpr r11 .32 92 0\n"
"gpr r12 .32 96 0\n"
"gpr r13 .32 100 0\n"
"gpr r14 .32 104 0\n"
"gpr r15 .32 108 0\n"
/* r16-23 are local (l0-l7) */
"gpr r16 .32 112 0\n"
"gpr r17 .32 116 0\n"
"gpr r18 .32 120 0\n"
"gpr r19 .32 124 0\n"
"gpr r20 .32 128 0\n"
"gpr r21 .32 132 0\n"
"gpr r22 .32 136 0\n"
"gpr r23 .32 140 0\n"
/* r24-31 are in (i0-i7) */
"gpr r24 .32 144 0\n"
"gpr r25 .32 148 0\n"
"gpr r26 .32 152 0\n"
"gpr r27 .32 156 0\n"
"gpr r28 .32 160 0\n"
"gpr r29 .32 164 0\n"
"gpr r30 .32 168 0\n"
"gpr r31 .32 172 0\n";
static unsigned long Offset = 0;
static RStrBuf *buf_global = NULL;
static const ut8 *bytes = NULL;
static int bytes_size = 0;
static int rl78_buffer_read_memory(bfd_vma memaddr, bfd_byte *myaddr, ut32 length, struct disassemble_info *info) {
int delta = (memaddr - Offset);
if (delta < 0) {
return -1; // disable backward reads
}
memcpy (myaddr, bytes + delta, R_MIN (length, bytes_size));
return 0;
}
static int symbol_at_address(bfd_vma addr, struct disassemble_info *info) {
return 0;
}
static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_info *info) {
//--
}
DECLARE_GENERIC_PRINT_ADDRESS_FUNC()
DECLARE_GENERIC_FPRINTF_FUNC()
static int rl78_op(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *data, int len, RAnalOpMask mask) {
if (!op) {
return -1;
}
memset (op, 0, sizeof (RAnalOp));
// RL78_ISA_G10
// RL78_ISA_G13
// RL78_ISA_G14
disassemble_info disasm_obj = {0};
memset (&disasm_obj, '\0', sizeof (struct disassemble_info));
buf_global = r_strbuf_new ("");
bytes = data;
bytes_size = len;
Offset = 0; // a->pc;
disasm_obj.buffer = (ut8*)bytes;
disasm_obj.read_memory_func = &rl78_buffer_read_memory;
disasm_obj.symbol_at_address_func = &symbol_at_address;
disasm_obj.memory_error_func = &memory_error_func;
disasm_obj.print_address_func = &generic_print_address_func;
disasm_obj.endian = BFD_ENDIAN_LITTLE;
disasm_obj.fprintf_func = &generic_fprintf_func;
disasm_obj.stream = stdout;
op->size = print_insn_rl78 ((bfd_vma)Offset, &disasm_obj);
int res = print_insn_rl78_common (addr, &disasm_obj, RL78_ISA_DEFAULT);
if (mask & R_ANAL_OP_MASK_DISASM) {
op->mnemonic = r_strbuf_drain (buf_global);
}
op->size = 1; // CGEN_MAX_INSN_SIZE;
op->addr = addr;
op->type = R_ANAL_OP_TYPE_UNK;
return op->size;
}
RAnalPlugin r_anal_plugin_rl78 = {
.name = "rl78",
.desc = "Renesas RL78 8 bit CPU",
.license = "LGPL3",
.arch = "rl78",
.bits = 8,
.esil = false,
.op = &rl78_op,
// .set_reg_profile = &set_reg_profile,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_rl78,
.version = R2_VERSION
};
#endif
+1 -1
View File
@@ -19,7 +19,7 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
memset(&disasm_obj, '\0', sizeof(DISASM));
disasm_obj.EIP = (long long)(data);
disasm_obj.VirtualAddr = addr;
disasm_obj.Archi = ((anal->config->bits == 64) ? 64 : 0);
disasm_obj.Archi = ((anal->bits == 64) ? 64 : 0);
disasm_obj.SecurityBlock = 128;
memset(aop, 0, sizeof(RAnalOp));
+9 -11
View File
@@ -161,13 +161,13 @@ static st64 getval(ud_operand_t *op) {
}
int x86_udis86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
const char *pc = anal->config->bits==64? "rip": anal->config->bits==32? "eip": "ip";
const char *sp = anal->config->bits==64? "rsp": anal->config->bits==32? "esp": "sp";
const char *bp = anal->config->bits==64? "rbp": anal->config->bits==32? "ebp": "bp";
const char *pc = anal->bits==64? "rip": anal->bits==32? "eip": "ip";
const char *sp = anal->bits==64? "rsp": anal->bits==32? "esp": "sp";
const char *bp = anal->bits==64? "rbp": anal->bits==32? "ebp": "bp";
int delta, oplen, regsz = 4;
char str[64], src[32], dst[32];
struct ud u;
switch (anal->config->bits) {
switch (anal->bits) {
case 64: regsz = 8; break;
case 16: regsz = 2; break;
default:
@@ -175,7 +175,7 @@ int x86_udis86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
}
UDis86Esil *handler;
UDis86OPInfo info = {0, anal->config->bits, (1LL << anal->config->bits) - 1, regsz, 0, pc, sp, bp};
UDis86OPInfo info = {0, anal->bits, (1LL << anal->bits) - 1, regsz, 0, pc, sp, bp};
memset (op, '\0', sizeof (RAnalOp));
op->addr = addr;
op->jump = op->fail = -1;
@@ -183,7 +183,7 @@ int x86_udis86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
ud_init (&u);
ud_set_pc (&u, addr);
ud_set_mode (&u, anal->config->bits);
ud_set_mode (&u, anal->bits);
ud_set_syntax (&u, NULL);
ud_set_input_buffer (&u, data, len);
ud_disassemble (&u);
@@ -191,9 +191,7 @@ int x86_udis86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
op->id = u.mnemonic;
oplen = op->size = ud_insn_len (&u);
r_strbuf_init (&op->esil);
const bool decode = true;
if (decode && (handler = udis86_esil_get_handler (u.mnemonic))) {
if (anal->decode && (handler = udis86_esil_get_handler (u.mnemonic))) {
info.oplen = oplen;
//if (anal->bits==32)
info.bitmask = UT32_MAX;
@@ -479,7 +477,7 @@ int x86_udis86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
if (u.operand[0].type==UD_OP_PTR) {
op->jump = getval (&u.operand[0]);
} else {
if (anal->config->bits==16) {
if (anal->bits==16) {
// honor segment
op->jump = (addr&0xf0000) + oplen + \
((((addr&0xffff)+getval (&u.operand[0]))&0xffff));
@@ -557,7 +555,7 @@ int x86_udis86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
static int set_reg_profile(RAnal *anal) {
const char *p = NULL;
switch (anal->config->bits) {
switch (anal->bits) {
case 16: p =
"=PC ip\n"
"=SP sp\n"
-16
View File
@@ -1,16 +0,0 @@
OBJ_BA2=anal_ba2.o
STATIC_OBJ+=${OBJ_BA2}
TARGET_BA2=anal_ba2.${LIBEXT}
ALL_TARGETS+=${TARGET_BA2}
CFLAGS_BA2=$(R2_CFLAGS)
CFLAGS_BA2+=-I../../asm/arch/ba2
CFLAGS_BA2+=-Wall -shared -fPIC ${LDFLAGS_LIB}
$(OBJ_BA2): %.o : %.c
$(CC) -c $(CFLAGS_BA2) $< -o $@
${TARGET_BA2}: ${OBJ_BA2}
${CC} $(call libname,anal_ba2) ${LDFLAGS} ${CFLAGS_BA2} -o ${TARGET_BA2} ${OBJ_BA2}
+12
View File
@@ -0,0 +1,12 @@
OBJ_evm=anal_evm.o
OBJ_evm+=../../asm/arch/evm/evm.o
CFLAGS+=-I../../asm/arch/evm/
STATIC_OBJ+=${OBJ_evm}
TARGET_evm=anal_evm.${LIBEXT}
ALL_TARGETS+=${TARGET_evm}
LINKFLAGS+=-ljansson
${TARGET_evm}: ${OBJ_evm} ${SHARED_OBJ}
${CC} $(call libname,anal_evm) ${LDFLAGS} ${CFLAGS} -o ${TARGET_evm} ${OBJ_evm} ${LINKFLAGS}
-14
View File
@@ -1,14 +0,0 @@
OBJ_NIOS=anal_nios.o
STATIC_OBJ+=${OBJ_NIOS}
TARGET_NIOS=anal_nios.${LIBEXT}
ALL_TARGETS+=${TARGET_NIOS}
CFLAGS+=-I../../asm/arch
CFLAGS+=-I../../asm/arch/include
${TARGET_NIOS}: ${OBJ_NIOS}
${CC} $(call libname,anal_nios) ${LDFLAGS} ${CFLAGS} \
-o anal_nios.${LIBEXT} ${OBJ_NIOS}
-14
View File
@@ -1,14 +0,0 @@
OBJ_RL78=anal_rl78.o
STATIC_OBJ+=${OBJ_RL78}
TARGET_RL78=anal_rl78.${LIBEXT}
ALL_TARGETS+=${TARGET_RL78}
CFLAGS+=-I../../asm/arch
CFLAGS+=-I../../asm/arch/include
${TARGET_RL78}: ${OBJ_RL78}
${CC} $(call libname,anal_rl78) ${LDFLAGS} ${CFLAGS} \
-o anal_rl78.${LIBEXT} ${OBJ_RL78}
+5 -10
View File
@@ -5,16 +5,11 @@ STATIC_OBJ+=${OBJ_X86_BEA}
TARGET_X86_BEA=anal_x86_bea.${LIBEXT}
ALL_TARGETS+=${TARGET_X86_BEA}
CFLAGS_BEA=$(CFLAGS)
CFLAGS_BEA+=-I../../asm/arch/x86/bea/
CFLAGS_BEA+=-I../../asm/arch/x86/bea/src
CFLAGS_BEA+=-I../../asm/arch/x86/bea/include
CFLAGS_BEA+=-DUint64=uint64_t
$(OBJ_X86_BEA): %.o : %.c
$(CC) -c $(CFLAGS_BEA) $< -o $@
CFLAGS+=-I../../asm/arch/x86/bea/
CFLAGS+=-I../../asm/arch/x86/bea/src
CFLAGS+=-I../../asm/arch/x86/bea/include
CFLAGS+=-DUint64=uint64_t
${TARGET_X86_BEA}: ${OBJ_X86_BEA}
${CC} ${CFLAGS_BEA} -o anal_x86_bea.${LIBEXT} ${OBJ_X86_BEA}
${CC} ${CFLAGS} -o anal_x86_bea.${LIBEXT} ${OBJ_X86_BEA}
@#strip -s anal_x86_bea.${LIBEXT}
+4 -8
View File
@@ -1,5 +1,5 @@
OBJ_X86_UDIS86=anal_x86_udis.o
OBJ_X86_UDIS86+=esil_x86_udis.o
OBJ_ESIL_UDIS86=esil_x86_udis.o
SHARED_X86_UDIS86=../../asm/arch/x86/udis86/decode.o
SHARED_X86_UDIS86+=../../asm/arch/x86/udis86/itab.o
SHARED_X86_UDIS86+=../../asm/arch/x86/udis86/syn-att.o
@@ -16,12 +16,8 @@ SHARED_OBJ+=${SHARED_X86_UDIS86}
TARGET_X86_UDIS86=anal_x86_udis.${EXT_SO}
ALL_TARGETS+=${TARGET_X86_UDIS86}
CFLAGS_UDIS86=$(CFLAGS)
CFLAGS_UDIS86+=-I../../asm/arch/x86 -I../../asm/arch/x86/udis86 -DHAVE_STRING_H=1
$(OBJ_X86_UDIS86): %.o : %.c
$(CC) -c $(CFLAGS_UDIS86) $< -o $@
CFLAGS+=-I../../asm/arch/x86 -I../../asm/arch/x86/udis86 -DHAVE_STRING_H=1
${TARGET_X86_UDIS86}: ${OBJ_X86_UDIS86} ${OBJ_ESIL_UDIS86}
${CC} ${CFLAGS_UDIS86} ${LDFLAGS} $(call libname,anal_x86) -lr_reg -lr_anal -lr_util \
$(SRC_X86_UDIS86) -o anal_x86_udis.${EXT_SO} ${OBJ_X86_UDIS86}
${CC} ${CFLAGS} ${LDFLAGS} $(call libname,anal_x86) -lr_reg -lr_anal -lr_util \
$(SRC_X86_UDIS86) -o anal_x86_udis.${EXT_SO} ${OBJ_X86_UDIS86} ${OBJ_ESIL_UDIS86}
-23
View File
@@ -1,23 +0,0 @@
SO=$(shell r2 -H R2_LIBEXT)
PD=$(shell r2 -H R2_USER_PLUGINS)
CFLAGS+=$(shell pkg-config --cflags r_util r_arch) -fPIC
LDFLAGS+=$(shell pkg-config --libs r_util r_arch)
CFLAGS+=-g
OBJS=arch_hexagon.o
OBJS+=hexagon.o
OBJS+=hexagon_anal.o
OBJS+=hexagon_disas.o
all: arch_hexagon.${SO}
arch_hexagon.$(SO): $(OBJS)
$(CC) -shared -fPIC -o arch_hexagon.$(SO) $(OBJS) $(LDFLAGS)
rm -f $(PD)/arch_hexagon.$(SO)
mkdir -p $(PD)
cp -f arch_hexagon.$(SO) $(PD)/arch_hexagon.$(SO)
clean:
rm -f arch_hexagon.$(SO) $(OBJS)
-116
View File
@@ -1,116 +0,0 @@
#if 0
/* radare - LGPL - Copyright 2018-2021 - xvilka, pancake */
#include <r_types.h>
#include <r_util.h>
#include <r_asm.h>
#include <r_anal.h>
#include <r_lib.h>
#include "hexagon.h"
#include "hexagon_insn.h"
#include "hexagon_anal.h"
static int hexagon_v6_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
if (len < 4) {
return 0;
}
ut32 data = r_read_le32 (buf);
HexInsn hi = {0};
int size = hexagon_disasm_instruction (data, &hi, (ut32) addr);
if (size > 0 && mask & R_ANAL_OP_MASK_DISASM) {
op->mnemonic = strdup (hi.mnem);
}
op->size = size;
if (size < 1) {
return size;
}
op->vliw = hi.op_count;
op->addr = addr;
return hexagon_anal_instruction (&hi, op);
}
static bool set_reg_profile(RAnal *anal) {
// TODO: Add missing registers
const char *p =
"=PC pc\n"
"=SP r29\n"
"=A0 r0\n"
"=A1 r1\n"
"=A2 r2\n"
"=A3 r3\n"
"=A4 r4\n"
"=A5 r5\n"
"=BP r30\n"
"=LR r31\n"
"=SN r6\n"
"=ZF z\n"
"=SF s\n"
"=OF ov\n"
"=CF cy\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 r6 .32 24 0\n"
"gpr r7 .32 28 0\n"
"gpr r8 .32 32 0\n"
"gpr r9 .32 36 0\n"
"gpr r10 .32 40 0\n"
"gpr r11 .32 44 0\n"
"gpr r12 .32 48 0\n"
"gpr r13 .32 52 0\n"
"gpr r14 .32 56 0\n"
"gpr r15 .32 60 0\n"
"gpr r16 .32 64 0\n"
"gpr r17 .32 68 0\n"
"gpr r18 .32 72 0\n"
"gpr r19 .32 76 0\n"
"gpr r20 .32 80 0\n"
"gpr r21 .32 84 0\n"
"gpr r22 .32 88 0\n"
"gpr r23 .32 92 0\n"
"gpr r24 .32 96 0\n"
"gpr r25 .32 100 0\n"
"gpr r26 .32 104 0\n"
"gpr r27 .32 108 0\n"
"gpr r28 .32 112 0\n"
"gpr r29 .32 116 0\n"
"gpr r30 .32 120 0\n"
"gpr r31 .32 124 0\n"
"gpr pc .32 128 0\n"
"gpr psw .32 132 0\n"
"gpr np .1 132.16 0\n"
"gpr ep .1 132.17 0\n"
"gpr ae .1 132.18 0\n"
"gpr id .1 132.19 0\n"
"flg cy .1 132.28 0\n"
"flg ov .1 132.29 0\n"
"flg s .1 132.30 0\n"
"flg z .1 132.31 0\n";
return r_reg_set_profile_string (anal->reg, p);
}
RAnalPlugin r_anal_plugin_hexagon = {
.name = "hexagon",
.desc = "Qualcomm Hexagon (QDSP6) V6",
.license = "LGPL3",
.arch = "hexagon",
.bits = 32,
.op = hexagon_v6_op,
.esil = false,
.set_reg_profile = set_reg_profile,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_hexagon,
.version = R2_VERSION
};
#endif
#endif
-113
View File
@@ -1,113 +0,0 @@
/* radare - LGPL - Copyright 2015-2023 - condret */
#include <r_arch.h>
#include <r_lib.h>
#include "hexagon.h"
#include "hexagon_insn.h"
#include "hexagon_anal.h"
static bool mal_decode(RArchSession *s, RAnalOp *op, RArchEncodeMask mask) {
if (op->size < 4 || !op->bytes) {
return false;
}
ut32 data = r_read_le32 (op->bytes);
HexInsn hi = {0};
int size = hexagon_disasm_instruction (data, &hi, (ut32) (op->addr & UT32_MAX));
if (size > 0 && mask & R_ARCH_OP_MASK_DISASM) {
op->mnemonic = strdup (hi.mnem);
}
op->size = size;
if (size < 1) {
return false;
}
op->vliw = hi.op_count;
int res = hexagon_anal_instruction (&hi, op);
if (op->size != res) {
R_LOG_DEBUG ("shouldnt happen invalid instruction at 0x%08"PFMT64x, op->addr);
}
op->size = res;
return true;
}
static char* regs(RArchSession *as) {
return strdup (
"=PC pc\n"
"=SP r29\n"
"=A0 r0\n"
"=A1 r1\n"
"=A2 r2\n"
"=A3 r3\n"
"=A4 r4\n"
"=A5 r5\n"
"=BP r30\n"
"=LR r31\n"
"=SN r6\n"
"=ZF z\n"
"=SF s\n"
"=OF ov\n"
"=CF cy\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 r6 .32 24 0\n"
"gpr r7 .32 28 0\n"
"gpr r8 .32 32 0\n"
"gpr r9 .32 36 0\n"
"gpr r10 .32 40 0\n"
"gpr r11 .32 44 0\n"
"gpr r12 .32 48 0\n"
"gpr r13 .32 52 0\n"
"gpr r14 .32 56 0\n"
"gpr r15 .32 60 0\n"
"gpr r16 .32 64 0\n"
"gpr r17 .32 68 0\n"
"gpr r18 .32 72 0\n"
"gpr r19 .32 76 0\n"
"gpr r20 .32 80 0\n"
"gpr r21 .32 84 0\n"
"gpr r22 .32 88 0\n"
"gpr r23 .32 92 0\n"
"gpr r24 .32 96 0\n"
"gpr r25 .32 100 0\n"
"gpr r26 .32 104 0\n"
"gpr r27 .32 108 0\n"
"gpr r28 .32 112 0\n"
"gpr r29 .32 116 0\n"
"gpr r30 .32 120 0\n"
"gpr r31 .32 124 0\n"
"gpr pc .32 128 0\n"
"gpr psw .32 132 0\n"
"gpr np .1 132.16 0\n"
"gpr ep .1 132.17 0\n"
"gpr ae .1 132.18 0\n"
"gpr id .1 132.19 0\n"
"flg cy .1 132.28 0\n"
"flg ov .1 132.29 0\n"
"flg s .1 132.30 0\n"
"flg z .1 132.31 0\n");
}
RArchPlugin r_arch_plugin_hexagon = {
.meta = {
.name = "hexagon",
.desc = "Qualcomm Hexagon (QDSP6) V6",
.author = "pancake,condret,xvilka",
.license = "LGPL3",
},
.regs = regs,
.arch = "hexagon",
.bits = 32,
.decode = &mal_decode,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ARCH,
.data = &r_arch_plugin_hexagon,
.version = R2_VERSION
};
#endif
-91
View File
@@ -1,91 +0,0 @@
/* radare - LGPL - Copyright 2017 - pancake */
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_util.h>
#include <r_asm.h>
#include "disas-asm.h"
#include <mybfd.h>
disassembler_ftype
hexagon_get_disassembler_from_mach(
unsigned long machine,
unsigned long big_p
);
static unsigned long Offset = 0;
static RStrBuf *buf_global = NULL;
static unsigned char bytes[4];
static int hexagon_buffer_read_memory (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, struct disassemble_info *info) {
memcpy (myaddr, bytes, length);
return 0;
}
static int symbol_at_address(bfd_vma addr, struct disassemble_info * info) {
return 0;
}
static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_info *info) {
//--
}
DECLARE_GENERIC_PRINT_ADDRESS_FUNC()
DECLARE_GENERIC_FPRINTF_FUNC()
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
static int (*print_insn_hexagon)(bfd_vma, struct disassemble_info *);
static struct disassemble_info disasm_obj;
if (len < 4) {
return -1;
}
buf_global = &op->buf_asm;
Offset = a->pc;
// disasm inverted
r_mem_swapendian (bytes, buf, 4); // TODO handle thumb
/* prepare disassembler */
memset (&disasm_obj,'\0', sizeof (struct disassemble_info));
disasm_obj.buffer = bytes;
disasm_obj.read_memory_func = &hexagon_buffer_read_memory;
disasm_obj.symbol_at_address_func = &symbol_at_address;
disasm_obj.memory_error_func = &memory_error_func;
disasm_obj.print_address_func = &generic_print_address_func;
disasm_obj.endian = a->big_endian;
disasm_obj.fprintf_func = &generic_fprintf_func;
disasm_obj.stream = stdout;
disasm_obj.mach = 0;
r_strbuf_set (&op->buf_asm, "");
print_insn_hexagon = hexagon_get_disassembler_from_mach (0, 0);
op->size = print_insn_hexagon ((bfd_vma)Offset, &disasm_obj);
if (!strncmp ( r_strbuf_get (&op->buf_asm), "unknown", 7)) {
r_strbuf_set (&op->buf_asm, "invalid");
}
if (op->size == -1) {
r_strbuf_set (&op->buf_asm, "(data)");
}
return op->size;
}
RAsmPlugin r_asm_plugin_hexagon_gnu = {
.name = "hexagon.gnu",
.arch = "hexagon.gnu",
.bits = 32,
.endian = R_SYS_ENDIAN_BIG | R_SYS_ENDIAN_LITTLE,
.license = "GPL3",
.desc = "Qualcomm DSPv5",
.disassemble = &disassemble,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_hexagon_gnu,
.version = R2_VERSION
};
#endif
-239
View File
@@ -1,239 +0,0 @@
/* radare - LGPL - Copyright 2018-2021 - xvilka */
#include <stdio.h>
#include <stdbool.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_util.h>
#include <r_asm.h>
#include "hexagon.h"
// TODO: Handle also control reg pairs
char* hex_get_cntl_reg(int opreg) {
switch (opreg) {
case HEX_REG_SA0:
return "SA0";
case HEX_REG_LC0:
return "LC0";
case HEX_REG_SA1:
return "SA1";
case HEX_REG_LC1:
return "LC1";
case HEX_REG_P:
return "P";
case HEX_REG_M0:
return "M0";
case HEX_REG_M1:
return "M1";
case HEX_REG_USR:
return "USR";
case HEX_REG_PC:
return "PC";
case HEX_REG_UGP:
return "UGP";
case HEX_REG_GP:
return "GP";
case HEX_REG_CS0:
return "CS0";
case HEX_REG_CS1:
return "CS1";
case HEX_REG_UPCYCLELO:
return "UPCYCLELO";
case HEX_REG_UPCYCLEHI:
return "UPCYCLEHI";
case HEX_REG_FRAMELIMIT:
return "FRAMELIMIT";
case HEX_REG_FRAMEKEY:
return "FRAMEKEY";
case HEX_REG_PKTCOUNTLO:
return "PKTCOUNTLO";
case HEX_REG_PKTCOUNTHI:
return "PKTCOUNTHI";
case HEX_REG_UTIMERLO:
return "UTIMERLO";
case HEX_REG_UTIMERHI:
return "UTIMERHI";
default:
return "<CRerr>";
}
}
char* hex_get_sys_reg(int opreg) {
static char tmp[5];
switch (opreg) {
case HEX_REG_SGP0:
return "SGP0";
case HEX_REG_SGP1:
return "SGP1";
case HEX_REG_STID:
return "STID";
case HEX_REG_ELR:
return "ELR";
case HEX_REG_BADVA0:
return "BADVA0";
case HEX_REG_BADVA1:
return "BADVA1";
case HEX_REG_SSR:
return "SSR";
case HEX_REG_CCR:
return "CCR";
case HEX_REG_HTID:
return "HTID";
case HEX_REG_BADVA:
return "BADVA";
case HEX_REG_IMASK:
return "IMASK";
case HEX_REG_EVB:
return "EVB";
case HEX_REG_MODECTL:
return "MODECTL";
case HEX_REG_SYSCFG:
return "SYSCFG";
case HEX_REG_IPEND:
return "IPEND";
case HEX_REG_VID:
return "VID";
case HEX_REG_IAD:
return "IAD";
case HEX_REG_IEL:
return "IEL";
case HEX_REG_IAHL:
return "IAHL";
case HEX_REG_CFGBASE:
return "CFGBASE";
case HEX_REG_DIAG:
return "DIAG";
case HEX_REG_REV:
return "REV";
case HEX_REG_PCYCLELO:
return "PCYCLELO";
case HEX_REG_PCYCLEHI:
return "PCYCLEHI";
case HEX_REG_ISDBST:
return "ISDBST";
case HEX_REG_ISDBCFG0:
return "ISDBCFG0";
case HEX_REG_ISDBCFG1:
return "ISDBCFG1";
case HEX_REG_BRKPTPC0:
return "BRKPTPC0";
case HEX_REG_BRKPTCFG0:
return "BRKPTCFG0";
case HEX_REG_BRKPTPC1:
return "BRKPTPC1";
case HEX_REG_BRKPTCFG1:
return "BRKPTCFG1";
case HEX_REG_ISDBMBXIN:
return "ISDBMBXIN";
case HEX_REG_ISDBMBXOUT:
return "ISDBMBXOUT";
case HEX_REG_ISDBEN:
return "ISDBEN";
case HEX_REG_ISDBGPR:
return "ISDBGPR";
case HEX_REG_PMUCNT0:
return "PMUCNT0";
case HEX_REG_PMUCNT1:
return "PMUCNT1";
case HEX_REG_PMUCNT2:
return "PMUCNT2";
case HEX_REG_PMUCNT3:
return "PMUCNT3";
case HEX_REG_PMUEVTCFG:
return "PMUEVTCFG";
case HEX_REG_PMUCFG:
return "PMUCFG";
default:
sprintf(tmp, "S%d", opreg);
return tmp;
}
}
char* hex_get_sub_reg(int opreg) {
switch (opreg) {
case HEX_SUB_REG_R0:
return "R0";
case HEX_SUB_REG_R1:
return "R1";
case HEX_SUB_REG_R2:
return "R2";
case HEX_SUB_REG_R3:
return "R3";
case HEX_SUB_REG_R4:
return "R4";
case HEX_SUB_REG_R5:
return "R5";
case HEX_SUB_REG_R6:
return "R6";
case HEX_SUB_REG_R7:
return "R7";
case HEX_SUB_REG_R16:
return "R16";
case HEX_SUB_REG_R17:
return "R17";
case HEX_SUB_REG_R18:
return "R18";
case HEX_SUB_REG_R19:
return "R19";
case HEX_SUB_REG_R20:
return "R20";
case HEX_SUB_REG_R21:
return "R21";
case HEX_SUB_REG_R22:
return "R22";
case HEX_SUB_REG_R23:
return "R23";
default:
return "<err>";
}
}
char* hex_get_sub_regpair(int opreg)
{
switch (opreg) {
case HEX_SUB_REGPAIR_R1_R0:
return "R1:R0";
case HEX_SUB_REGPAIR_R3_R2:
return "R3:R2";
case HEX_SUB_REGPAIR_R5_R4:
return "R5:R4";
case HEX_SUB_REGPAIR_R7_R6:
return "R7:R6";
case HEX_SUB_REGPAIR_R17_R16:
return "R17:R16";
case HEX_SUB_REGPAIR_R19_R18:
return "R19:R18";
case HEX_SUB_REGPAIR_R21_R20:
return "R21:R20";
case HEX_SUB_REGPAIR_R23_R22:
return "R23:R22";
default:
return "<err>";
}
}
inline bool hex_if_duplex(uint32_t insn_word)
{
if ((insn_word & (3 << 14)) == 0) {
return true;
}
return false;
}
// Constant extender value
ut32 constant_extender = 1;
void hex_op_extend(HexOp *op) {
if ((constant_extender != 1) && (op->type == HEX_OP_TYPE_IMM)) {
op->op.imm = ((op->op.imm) & 0x3F) | (constant_extender);
}
constant_extender = 1;
}
void hex_op_extend_off(HexOp *op, int offset) {
return;
if ((constant_extender != 1) && (op->type == HEX_OP_TYPE_IMM)) {
op->op.imm = (op->op.imm) >> offset;
hex_op_extend(op);
}
}
-282
View File
@@ -1,282 +0,0 @@
// Predicates - declare the predicate state
#ifndef HEXAGON_H
#define HEXAGON_H
typedef enum {
HEX_NOPRED, // no conditional execution
HEX_PRED_TRUE, // if (Pd) ...
HEX_PRED_FALSE, // if (!Pd) ...
HEX_PRED_TRUE_NEW, // if (Pd.new) ...
HEX_PRED_FALSE_NEW, // if (!Pd.new) ...
} HexPred;
// Pre/post-fixes, different types
typedef enum {
HEX_PF_RND = 1, // :rnd
HEX_PF_CRND = 1<<1, // :crnd
HEX_PF_RAW = 1<<2, // :raw
HEX_PF_CHOP = 1<<3, // :chop
HEX_PF_SAT = 1<<4, // :sat
HEX_PF_HI = 1<<5, // :hi
HEX_PF_LO = 1<<6, // :lo
HEX_PF_LSH1 = 1<<7, // :<<1
HEX_PF_LSH16 = 1<<8, // :<<16
HEX_PF_RSH1 = 1<<9, // :>>1
HEX_PF_NEG = 1<<10, // :neg
HEX_PF_POS = 1<<11, // :pos
HEX_PF_SCALE = 1<<12, // :scale, for FMA instructions
HEX_PF_DEPRECATED = 1<<15, // :deprecated
} HexPf;
typedef enum {
HEX_OP_TYPE_IMM,
HEX_OP_TYPE_REG,
HEX_OP_TYPE_PREDICATE,
HEX_OP_TYPE_CONTROL,
HEX_OP_TYPE_SYSTEM,
HEX_OP_TYPE_OPT, // Do not really use in the C code
} HexOpType;
// Attributes - .H/.L, const extender
typedef enum {
HEX_OP_CONST_EXT = 1 << 0, // Constant extender marker for Immediate
HEX_OP_REG_HI = 1 << 1, // Rn.H marker
HEX_OP_REG_LO = 1 << 2, // Rn.L marker
HEX_OP_REG_PAIR = 1 << 3, // Is this a register pair?
} HexOpAttr;
typedef struct {
ut8 type;
union {
ut8 reg; // + additional Hi or Lo selector // + additional shift // + additional :brev //
ut32 imm;
ut8 pred; // predicates - P0-P3 registers
ut8 cr; // control register
ut8 sys; // system control register
} op;
ut8 attr;
} HexOp;
typedef struct {
int instruction;
ut32 mask;
HexPred predicate; // predicate set if set
ut16 pf; // additional prefixes (bitmap)
bool duplex; // is part of duplex container?
bool compound; // is part of compound instruction?
bool last; // is last in instruction packet?
int shift; // Optional shift left is it true?
ut8 op_count;
HexOp ops[8];
char mnem[128]; // Instruction mnemonic
} HexInsn;
// Instruction container (currently only 2 instructions)
// Can handle duplexes
typedef struct {
bool duplex;
HexInsn ins[2]; // Or make it pointer + size?
} HexInsnCont;
// Instruction packet (Maximum - 4 instructions)
// Can handle up to 4 instructions or 1 duplex + 2 instructions
// Can have a loop marks
typedef struct {
bool loop0; // :endloop0 marker
bool loop1; // :endloop1 marker
int cont_cnt;
HexInsnCont ins[4]; // Or make it pointer + size?
} HexInsnPkt;
typedef enum {
HEX_INSN_CLASS_CEXT = 0, // Constant extender
HEX_INSN_CLASS_J1 = 1, // Jump
HEX_INSN_CLASS_J2 = 2, // Jump
HEX_INSN_CLASS_LD_ST = 3, // Load/Store
HEX_INSN_CLASS_LD_ST_COND_GP = 4, // Load/Store conditional or GP relative
HEX_INSN_CLASS_J3 = 5, // Jump
HEX_INSN_CLASS_CR = 6, // Control register instructions
HEX_INSN_CLASS_ALU32 = 7, // ALU32
HEX_INSN_CLASS_XTYPE = 8, // XTYPE
HEX_INSN_CLASS_LD = 9, // Just load instructions
HEX_INSN_CLASS_ST = 10, // Just store instructions
HEX_INSN_CLASS_ALU32_1 = 11, // ALU32
HEX_INSN_CLASS_XTYPE_1 = 12, // XTYPE again
HEX_INSN_CLASS_XTYPE_2 = 13, // XTYPE one more time
HEX_INSN_CLASS_XTYPE_3 = 14, // And again, XTYPE
HEX_INSN_CLASS_ALU32_2 = 12, // ALU32 again
} HEX_INSN_CLASS;
typedef enum {
HEX_REG_R0 = 0,
HEX_REG_R1 = 1,
HEX_REG_R2 = 2,
HEX_REG_R3 = 3,
HEX_REG_R4 = 4,
HEX_REG_R5 = 5,
HEX_REG_R6 = 6,
HEX_REG_R7 = 7,
HEX_REG_R8 = 8,
HEX_REG_R9 = 9,
HEX_REG_R10 = 10,
HEX_REG_R11 = 11,
HEX_REG_R12 = 12,
HEX_REG_R13 = 13,
HEX_REG_R14 = 14,
HEX_REG_R15 = 15,
HEX_REG_R16 = 16,
HEX_REG_R17 = 17,
HEX_REG_R18 = 18,
HEX_REG_R19 = 19,
HEX_REG_R20 = 20,
HEX_REG_R21 = 21,
HEX_REG_R22 = 22,
HEX_REG_R23 = 23,
HEX_REG_R24 = 24,
HEX_REG_R25 = 25,
HEX_REG_R26 = 26,
HEX_REG_R27 = 27,
HEX_REG_R28 = 28,
HEX_REG_R29 = 29,
HEX_REG_R30 = 30,
HEX_REG_R31 = 31,
} HEX_REG;
// TODO: Also add regpair values
// Control registers
typedef enum {
// Loop registers
HEX_REG_SA0 = 0, // C0
HEX_REG_LC0 = 1, // C1
HEX_REG_SA1 = 2, // C2
HEX_REG_LC1 = 3, // C3
HEX_REG_P = 4, // C4 - 4 of 8bit registers
// C5 is reserved
// Modifier registers
HEX_REG_M0 = 6, // C6
HEX_REG_M1 = 7, // C7
HEX_REG_USR = 8, // C8 // User Status Register
HEX_REG_PC = 9, // C9 // Program counter
HEX_REG_UGP = 10, // C10 // User General Pointer
HEX_REG_GP = 11, // C11 // Global Pointer
// Circular Start registers
HEX_REG_CS0 = 12, // C12
HEX_REG_CS1 = 13, // C13
// Cycle Count registers
HEX_REG_UPCYCLELO = 14, // C14
HEX_REG_UPCYCLEHI = 15, // C15
HEX_REG_FRAMELIMIT = 16, // C16 // Stack Bounds register
HEX_REG_FRAMEKEY = 17, // C17 // Stack Smash register
// Packet Count registers
HEX_REG_PKTCOUNTLO = 18, // C18
HEX_REG_PKTCOUNTHI = 19, // C19
// C20 - C29 are reserved
// Qtimer registers
HEX_REG_UTIMERLO = 30, // C30
HEX_REG_UTIMERHI = 31, // C31
} HEX_CR_REG;
// Supervisor control registers
typedef enum {
HEX_REG_SGP0 = 0, // S0
HEX_REG_SGP1 = 1, // S1
HEX_REG_STID = 2, // S2
HEX_REG_ELR = 3, // S3
HEX_REG_BADVA0 = 4, // S4
HEX_REG_BADVA1 = 5, // S5
HEX_REG_SSR = 6, // S6
HEX_REG_CCR = 7, // S7
HEX_REG_HTID = 8, // S8
HEX_REG_BADVA = 9, // S9
HEX_REG_IMASK = 10, // S10
// S11 - S15 are reserved
HEX_REG_EVB = 16, // S16
HEX_REG_MODECTL = 17, // S17
HEX_REG_SYSCFG = 18, // S18
// S19 is reserved
HEX_REG_IPEND = 20, // S20
HEX_REG_VID = 21, // S21
HEX_REG_IAD = 22, // S22
// S23 is reserved
HEX_REG_IEL = 24, // S24
// S25 is reserved
HEX_REG_IAHL = 26, // S26
HEX_REG_CFGBASE = 27, // S27
HEX_REG_DIAG = 28, // S28
HEX_REG_REV = 29, // S29
HEX_REG_PCYCLELO = 30, // S30
HEX_REG_PCYCLEHI = 31, // S31
HEX_REG_ISDBST = 32, // S32
HEX_REG_ISDBCFG0 = 33, // S33
HEX_REG_ISDBCFG1 = 34, // S34
// S35 is reserved
HEX_REG_BRKPTPC0 = 36, // S36
HEX_REG_BRKPTCFG0 = 37, // S37
HEX_REG_BRKPTPC1 = 38, // S38
HEX_REG_BRKPTCFG1 = 39, // S39
HEX_REG_ISDBMBXIN = 40, // S40
HEX_REG_ISDBMBXOUT = 41, // S41
HEX_REG_ISDBEN = 42, // S42
HEX_REG_ISDBGPR = 43, // S43
// S44 - S47 are reserved
HEX_REG_PMUCNT0 = 48, // S48
HEX_REG_PMUCNT1 = 49, // S49
HEX_REG_PMUCNT2 = 50, // S50
HEX_REG_PMUCNT3 = 51, // S51
HEX_REG_PMUEVTCFG = 52, // S52
HEX_REG_PMUCFG = 53, // S53
// S54 - S63 are reserved
} HEX_SYSCR_REG;
// Here are the register field values for subinstructions
typedef enum {
HEX_SUB_REG_R0 = 0, // 0b0000
HEX_SUB_REG_R1 = 1, // 0b0001
HEX_SUB_REG_R2 = 2, // 0b0010
HEX_SUB_REG_R3 = 3, // 0b0011
HEX_SUB_REG_R4 = 4, // 0b0100
HEX_SUB_REG_R5 = 5, // 0b0101
HEX_SUB_REG_R6 = 6, // 0b0110
HEX_SUB_REG_R7 = 7, // 0b0111
HEX_SUB_REG_R16 = 8, // 0b1000
HEX_SUB_REG_R17 = 9, // 0b1001
HEX_SUB_REG_R18 = 10, // 0b1010
HEX_SUB_REG_R19 = 11, // 0b1011
HEX_SUB_REG_R20 = 12, // 0b1100
HEX_SUB_REG_R21 = 13, // 0b1101
HEX_SUB_REG_R22 = 14, // 0b1110
HEX_SUB_REG_R23 = 15, // 0b1111
} HEX_SUB_REG;
typedef enum {
HEX_SUB_REGPAIR_R1_R0 = 0, // 0b000
HEX_SUB_REGPAIR_R3_R2 = 1, // 0b001
HEX_SUB_REGPAIR_R5_R4 = 2, // 0b010
HEX_SUB_REGPAIR_R7_R6 = 3, // 0b011
HEX_SUB_REGPAIR_R17_R16 = 4, // 0b100
HEX_SUB_REGPAIR_R19_R18 = 5, // 0b101
HEX_SUB_REGPAIR_R21_R20 = 6, // 0b110
HEX_SUB_REGPAIR_R23_R22 = 7, // 0b111
} HEX_SUB_REGPAIR;
#define BIT_MASK(len) (BIT(len)-1)
#define BF_MASK(start, len) (BIT_MASK(len)<<(start))
#define BF_PREP(x, start, len) (((x)&BIT_MASK(len))<<(start))
#define BF_GET(y, start, len) (((y)>>(start)) & BIT_MASK(len))
#define BF_GETB(y, start, end) (BF_GET((y), (start), (end) - (start) + 1)
char* hex_get_cntl_reg(int opreg);
char* hex_get_sys_reg(int opreg);
char* hex_get_sub_reg(int opreg);
char* hex_get_sub_regpair(int opreg);
bool hex_if_duplex(ut32 insn_word);
void hex_op_extend(HexOp *op);
void hex_op_extend_off(HexOp *op, int offset);
int hexagon_disasm_instruction(ut32 hi_u32, HexInsn *hi, ut32 addr);
#endif
-9
View File
@@ -1,9 +0,0 @@
OBJ_MALBOLGE=anal_malbolge.o
STATIC_OBJ+=${OBJ_MALBOLGE}
TARGET_MALBOLGE=anal_malbolge.${EXT_SO}
ALL_TARGETS+=${TARGET_MALBOLGE}
${TARGET_MALBOLGE}: ${OBJ_MALBOLGE}
${CC} $(call libname,anal_malbolge) ${LDFLAGS} ${CFLAGS} -o anal_malbolge.${EXT_SO} ${OBJ_MALBOLGE}
-8
View File
@@ -1,8 +0,0 @@
crz=crazy operation
end=end
in=inputs a character, as an ascii code
jmp=jump
mov=moves data from src to dst
nop=do nothing
out=prints the value, as an ascii character, to the screen
rotr=rotates the value by one ternary digit
Loaded 100 of 685 files, more files were not shown because too many files have changed in this diff. Show more