mirror of
https://github.com/radareorg/radare2-extras.git
synced 2026-11-08 17:43:28 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e45ff06e70 | ||
|
|
6f726e0f68 | ||
|
|
c4d27a8e94 | ||
|
|
fb7ed81025 | ||
|
|
a9b4f2be6f | ||
|
|
dd59385722 | ||
|
|
440147b930 | ||
|
|
7d2cdb43dc | ||
|
|
70907f1ee4 | ||
|
|
d7fc41424b | ||
|
|
1d54839979 | ||
|
|
5561fe99c3 | ||
|
|
e74a93c4ad | ||
|
|
374fa1646f | ||
|
|
8069025044 | ||
|
|
d818dba15e | ||
|
|
010a1e39b1 | ||
|
|
3167bed57f | ||
|
|
b6acfeef45 | ||
|
|
3fd5cd76cb | ||
|
|
86f8c56be8 | ||
|
|
a015f9fe7e | ||
|
|
792d43b3ba | ||
|
|
8d1c02121a | ||
|
|
dc5887818e | ||
|
|
ac22c81ada | ||
|
|
859c307cb5 | ||
|
|
249e782a2e | ||
|
|
097a5f56e4 | ||
|
|
d65bb20b65 | ||
|
|
e9993f8fdf | ||
|
|
db29d60aa9 | ||
|
|
e9a74be52c | ||
|
|
72a43824b1 | ||
|
|
8a5936eb64 | ||
|
|
e4a73ccf07 | ||
|
|
fc564166bd | ||
|
|
7cc5d343af | ||
|
|
854e6f38ed | ||
|
|
8da191d171 | ||
|
|
2749dedb1e | ||
|
|
327898bac1 | ||
|
|
046efbdae8 | ||
|
|
cc4a103ff3 | ||
|
|
b9723c5629 | ||
|
|
ae90621fe0 | ||
|
|
2e53b36308 | ||
|
|
26838fc56f | ||
|
|
986b99a6fe | ||
|
|
4c9a552d06 | ||
|
|
ef5771f7ce | ||
|
|
8ba3432f5c | ||
|
|
271369f8ee | ||
|
|
145e685c60 | ||
|
|
730433360e | ||
|
|
f1f617f791 | ||
|
|
c3d8e433bd | ||
|
|
934c08364f | ||
|
|
6e8b2ed5db | ||
|
|
2434f97937 | ||
|
|
3319911179 | ||
|
|
5eb18b3e3b | ||
|
|
91eeb7b154 | ||
|
|
b01f0180ea | ||
|
|
16e27dc9e9 | ||
|
|
5f6f945498 |
No files matched your search
@@ -0,0 +1,56 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
pull_request:
|
||||
|
||||
|
||||
jobs:
|
||||
|
||||
build-extras:
|
||||
name: Build radare2 extras and r2pipe
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TESTS: 'armthumb atombios baleful bcl ba2 blackfin blessr2 keystone-lib keystone lang-duktape mc6809 microblaze msil pcap ppcdisasm psosvm swf unicorn-lib unicorn vc4 x86udis x86bea x86tab x86olly x86zyan z80-nc'
|
||||
R2PIPE_TESTS: 'r2pipe-go r2pipe-js r2pipe-py'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
repository: zamaudio/radare2
|
||||
ref: r2pm-gitmaster
|
||||
path: ./radare2
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get --assume-yes install wget unzip python3-wheel python3-setuptools build-essential python3-pip && sudo pip3 install meson ninja
|
||||
- name: Install radare2
|
||||
run: |
|
||||
export PATH=$PATH:/usr/local/bin
|
||||
meson --prefix=/usr --buildtype=release build && ninja -C build && sudo ninja -C build install
|
||||
working-directory: radare2
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
path: ./radare2-extras
|
||||
- name: Init r2pm
|
||||
run: r2pm init
|
||||
- name: Compile and install plugins
|
||||
run: |
|
||||
set -e
|
||||
export R2PM_GITDIR=./
|
||||
export R2PM_GITMASTER=`cd radare2-extras; git describe --always --all`
|
||||
for p in $TESTS ; do
|
||||
echo $p
|
||||
r2pm -i $p
|
||||
done
|
||||
set +e
|
||||
- name: Compile and install r2pipe
|
||||
run: |
|
||||
set -e
|
||||
export R2PM_GITDIR=./
|
||||
export R2PM_GITMASTER=`cd radare2-extras; git describe --always --all`
|
||||
for p in $R2PIPE_TESTS ; do
|
||||
echo $p
|
||||
r2pm -i $p
|
||||
done
|
||||
set +e
|
||||
|
||||
@@ -18,3 +18,8 @@
|
||||
*.un~
|
||||
/Makefile
|
||||
/options.mk
|
||||
|
||||
# misc
|
||||
tags
|
||||
|
||||
node_modules
|
||||
+11
-11
@@ -32,24 +32,25 @@ addons:
|
||||
env:
|
||||
- TESTS="r2pm -i armthumb"
|
||||
- TESTS="r2pm -i baleful"
|
||||
# - TESTS="r2pm -i bcl" [BR] https://travis-ci.org/radareorg/radare2-extras/builds/157522362
|
||||
- TESTS="r2pm -i bcl"
|
||||
- TESTS="r2pm -i ba2"
|
||||
- TESTS="r2pm -i blackfin"
|
||||
- TESTS="r2pm -i blessr2"
|
||||
# - TESTS="r2pm -i bpf" [BR] https://travis-ci.org/radareorg/radare2-extras/builds/157522362
|
||||
# - TESTS="r2pm -i dlang" [BR] https://travis-ci.org/radareorg/radare2-extras/builds/157522362
|
||||
- TESTS="r2pm -i dirtycow"
|
||||
# ONLY FOR LINUX - 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="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/radareorg/radare2-extras/builds/157522362
|
||||
- TESTS="r2pm -i mc6809"
|
||||
- TESTS="r2pm -i microblaze && cd radare2-regressions && make microblaze"
|
||||
- TESTS="r2pm -i microblaze && cd radare2/test && make microblaze && cd ../.."
|
||||
- TESTS="r2pm -i msil"
|
||||
- TESTS="r2pm -i nios"
|
||||
- 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/radareorg/radare2-extras/builds/387043680
|
||||
# - TESTS="r2pm -i r2pipe-cs" [BR] https://travis-ci.org/radareorg/radare2-extras/builds/157522362
|
||||
# - TESTS="r2pm -i r2pipe-go" [BR] https://travis-ci.org/radareorg/radare2-extras/builds/387043680
|
||||
@@ -60,8 +61,8 @@ env:
|
||||
- TESTS="r2pm -i radare2"
|
||||
# - TESTS="r2pm -i r2snow" https://travis-ci.org/radareorg/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 retdec"
|
||||
- TESTS="r2pm -i swf && make -C radare2/test swf"
|
||||
# - 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"
|
||||
@@ -79,9 +80,9 @@ env:
|
||||
- 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 x86olly && cd radare2/test && make olly-extras && cd ../.."
|
||||
- TESTS="r2pm -i z80-nc"
|
||||
- TESTS="r2pm -i yara && r2pm -i yara-r2"
|
||||
- TESTS="r2pm -i yara && r2pm -i yara-r2 && cd radare2/test && make yara && cd ../.."
|
||||
- TESTS="r2pm -i x86zyan"
|
||||
language:
|
||||
- rust
|
||||
@@ -95,7 +96,6 @@ 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 10
|
||||
- git clone https://github.com/radareorg/radare2-regressions
|
||||
- git clone https://github.com/radareorg/radare2 && cd radare2
|
||||
- export CC=gcc-7
|
||||
- ./configure --prefix=${WORKING_DIR}/install > /dev/null
|
||||
|
||||
+1
-1
@@ -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) {
|
||||
static int bcl_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
|
||||
int i;
|
||||
char cache[256] = {0};
|
||||
ut64 dst = 0LL;
|
||||
|
||||
+6
-3
@@ -9,21 +9,23 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
const char *bases = "ACGT";
|
||||
if (a->pc == 0) {
|
||||
ut32 *clusters = (ut32*)buf;
|
||||
snprintf (op->buf_asm, sizeof (op->buf_asm), "clusters %d\n", *clusters);
|
||||
r_strbuf_setf (&op->buf_asm, "clusters %d", *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;
|
||||
snprintf (op->buf_asm, sizeof (op->buf_asm), "%c ; %d", base, qual);
|
||||
r_strbuf_setf (&op->buf_asm, "%c ; %d", base, qual);
|
||||
op->size = 1;
|
||||
return 1;
|
||||
}
|
||||
strcpy (op->buf_asm, ".");
|
||||
r_strbuf_setf (&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;
|
||||
@@ -76,6 +78,7 @@ static int assemble(RAsm *a, RAsmOp *op, const char *buf) {
|
||||
out[op->size] = (quality<<2) | base;
|
||||
op->size ++;
|
||||
}
|
||||
#endif
|
||||
return op->size;
|
||||
}
|
||||
|
||||
|
||||
+65
-90
@@ -5,8 +5,11 @@
|
||||
#include <r_lib.h>
|
||||
#include <r_bin.h>
|
||||
|
||||
static int check_bytes(const ut8 *buf, ut64 length) {
|
||||
if (buf && length >= 4) {
|
||||
static bool __check_buffer(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)) {
|
||||
ut32 cls = r_mem_get_num (buf, 4);
|
||||
ut32 cls2 = r_mem_get_num (buf + 4, 4);
|
||||
if (cls + 4 == length && !cls2) {
|
||||
@@ -16,64 +19,49 @@ static int check_bytes(const ut8 *buf, ut64 length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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 bool load_buffer(RBinFile *bf, void **bin_obj, RBuffer *buf, ut64 loadaddr, Sdb *sdb) {
|
||||
return __check_buffer (buf);
|
||||
}
|
||||
|
||||
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) {
|
||||
static ut64 baddr(RBinFile *bf) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
static RBinAddr* binsym(RBinFile *arch, int type) {
|
||||
static RBinAddr* binsym(RBinFile *bf, 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->length; i++) {
|
||||
if (buf->buf[i] != 0) {
|
||||
for (i = 4; i < buf_size; i++) {
|
||||
if (r_buf_read_at (buf, i, &b, 1) != 1) {
|
||||
break;
|
||||
}
|
||||
if (b != 0) {
|
||||
if (n == 0) {
|
||||
return i;
|
||||
}
|
||||
n--;
|
||||
for (++i; i<buf->length; i++) {
|
||||
if (!buf->buf[i])
|
||||
for (++i; i < buf_size && b; i++) {
|
||||
if (r_buf_read_at (buf, i, &b, 1) != 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static RList* entries(RBinFile *arch) {
|
||||
static RList* entries(RBinFile *bf) {
|
||||
RList* ret = r_list_newf (free);
|
||||
RBinAddr *ptr = NULL;
|
||||
if (ret) {
|
||||
if ((ptr = R_NEW0 (RBinAddr))) {
|
||||
ut64 entry = findEntry (arch->buf, 2);
|
||||
if (!entry) entry = findEntry (arch->buf, 1);
|
||||
if (!entry) entry = findEntry (arch->buf, 0);
|
||||
ut64 entry = findEntry (bf->buf, 2);
|
||||
if (!entry) entry = findEntry (bf->buf, 1);
|
||||
if (!entry) entry = findEntry (bf->buf, 0);
|
||||
if (!entry) entry = 4;
|
||||
ptr->paddr = entry;
|
||||
ptr->vaddr = entry;
|
||||
@@ -86,79 +74,74 @@ static RList* entries(RBinFile *arch) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RList* sections(RBinFile *arch) {
|
||||
static RList* sections(RBinFile *bf) {
|
||||
RList *ret = NULL;
|
||||
RBinSection *ptr = NULL;
|
||||
ut64 textsize, datasize, symssize, spszsize, pcszsize;
|
||||
ut64 entry0 = findEntry (arch->buf, 0);
|
||||
ut64 entry1 = findEntry (arch->buf, 1);
|
||||
ut64 entry2 = findEntry (arch->buf, 2);
|
||||
ut64 entry0 = findEntry (bf->buf, 0);
|
||||
ut64 entry1 = findEntry (bf->buf, 1);
|
||||
ut64 entry2 = findEntry (bf->buf, 2);
|
||||
|
||||
if (!(ret = r_list_newf (free))) {
|
||||
return NULL;
|
||||
}
|
||||
// add text segment
|
||||
textsize = r_mem_get_num (arch->buf->buf + 4, 4);
|
||||
ut8 str[4] = {0};
|
||||
r_buf_read_at (bf->buf, 4, str, 4);
|
||||
textsize = r_mem_get_num (str, 4);
|
||||
if (!(ptr = R_NEW0 (RBinSection))) {
|
||||
return ret;
|
||||
}
|
||||
if (!entry1) {
|
||||
entry1 = arch->buf->length;
|
||||
entry1 = r_buf_size (bf->buf);
|
||||
}
|
||||
strncpy (ptr->name, "init", R_BIN_SIZEOF_STRINGS);
|
||||
ptr->size = entry1-entry0;
|
||||
ptr->vsize = entry1-entry0;
|
||||
ptr->name = strdup ("init");
|
||||
ptr->size = entry1 - entry0;
|
||||
ptr->vsize = entry1 - entry0;
|
||||
ptr->paddr = entry0 + 4;
|
||||
ptr->vaddr = entry0;
|
||||
ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; // r-x
|
||||
ptr->add = true;
|
||||
ptr->perm = R_PERM_RX;
|
||||
r_list_append (ret, ptr);
|
||||
|
||||
if (entry1) {
|
||||
if (entry2) {
|
||||
if (!(ptr = R_NEW0 (RBinSection)))
|
||||
if (!(ptr = R_NEW0 (RBinSection))) {
|
||||
return ret;
|
||||
strncpy (ptr->name, "fini", R_BIN_SIZEOF_STRINGS);
|
||||
ptr->size = entry2-entry1;
|
||||
ptr->vsize = entry2-entry1;
|
||||
}
|
||||
ptr->name = strdup ("fini");
|
||||
ptr->size = entry2 - entry1;
|
||||
ptr->vsize = entry2 - entry1;
|
||||
ptr->paddr = entry1 + 4;
|
||||
ptr->vaddr = entry1;
|
||||
ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; // r-x
|
||||
ptr->perm = R_PERM_RX;
|
||||
ptr->add = true;
|
||||
r_list_append (ret, ptr);
|
||||
} else {
|
||||
entry2 = entry1;
|
||||
}
|
||||
}
|
||||
if (entry2) {
|
||||
if (!(ptr = R_NEW0 (RBinSection)))
|
||||
if (!(ptr = R_NEW0 (RBinSection))) {
|
||||
return ret;
|
||||
strncpy (ptr->name, "text", R_BIN_SIZEOF_STRINGS);
|
||||
ptr->size = arch->buf->length - entry2;
|
||||
ptr->vsize = arch->buf->length - entry2;
|
||||
}
|
||||
ptr->name = strdup ("text");
|
||||
ut64 filesize = r_buf_size (bf->buf);
|
||||
ptr->size = filesize - entry2;
|
||||
ptr->vsize = filesize - entry2;
|
||||
ptr->paddr = entry2 + 4;
|
||||
ptr->vaddr = entry2;
|
||||
ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; // r-x
|
||||
ptr->perm = R_PERM_RX;
|
||||
ptr->add = true;
|
||||
r_list_append (ret, ptr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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) {
|
||||
static RBinInfo* info(RBinFile *bf) {
|
||||
RBinInfo *ret = R_NEW0 (RBinInfo);
|
||||
if (ret) {
|
||||
ret->file = strdup (arch->file);
|
||||
ret->file = strdup (bf->file);
|
||||
ret->bclass = strdup ("dna");
|
||||
ret->rclass = strdup ("bcl");
|
||||
ret->os = strdup ("Illumina DNA Sequences");
|
||||
@@ -174,18 +157,17 @@ static RBinInfo* info(RBinFile *arch) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ut64 size(RBinFile *arch) {
|
||||
ut64 text, data, syms, spsz;
|
||||
int big_endian;
|
||||
if (!arch->o->info) {
|
||||
arch->o->info = info (arch);
|
||||
static ut64 size(RBinFile *bf) {
|
||||
if (!bf->o->info) {
|
||||
bf->o->info = info (bf);
|
||||
}
|
||||
big_endian = arch->o->info->big_endian;
|
||||
ut8 str[32] = {0};
|
||||
r_buf_read_at (bf->buf, 0, str, 32);
|
||||
// TODO: reuse section list
|
||||
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);
|
||||
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);
|
||||
return text + data + syms + spsz + (6 * 4);
|
||||
}
|
||||
|
||||
@@ -193,25 +175,18 @@ RBinPlugin r_bin_plugin_bcl = {
|
||||
.name = "bcl",
|
||||
.desc = "Base Call DNA Illumina",
|
||||
.license = "BSD",
|
||||
.get_sdb = &get_sdb,
|
||||
.load = &load,
|
||||
.load_bytes = &load_bytes,
|
||||
.load_buffer = &load_buffer,
|
||||
.check_buffer = &__check_buffer,
|
||||
.size = &size,
|
||||
.destroy = &destroy,
|
||||
.check = &check,
|
||||
.check_bytes = &check_bytes,
|
||||
.baddr = &baddr,
|
||||
.binsym = &binsym,
|
||||
.entries = &entries,
|
||||
.sections = §ions,
|
||||
.symbols = &symbols,
|
||||
.imports = &imports,
|
||||
.info = &info,
|
||||
.libs = &libs,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_BIN,
|
||||
.data = &r_bin_plugin_bcl,
|
||||
.version = R2_VERSION
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# This script was automatically generated by ACR v1.7.2
|
||||
# This script was automatically generated by ACR v1.8.1
|
||||
# @author: pancake <nopcode.org>
|
||||
# @url: http://www.nopcode.org
|
||||
# @repo: git clone https://github.com/radare/acr
|
||||
@@ -105,12 +105,12 @@ done
|
||||
: ${INSTALL_PROGRAM_STRIP:=${INSTALL} -m 755 -s}
|
||||
: ${INSTALL_MAN:=${INSTALL} -m 444}
|
||||
: ${INSTALL_LIB:=${INSTALL} -m 755 -c}
|
||||
PKGNAME='radare2-extras' ; VERSION='4.0.0' ; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
|
||||
PKGNAME='radare2-extras' ; VERSION='4.4.0' ; VERSION_MAJOR=4; VERSION_MINOR=4; VERSION_PATCH=0; VERSION_NUMBER=40400; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
|
||||
}
|
||||
|
||||
show_usage() {
|
||||
cat <<EOF2
|
||||
'configure' configures radare2-extras-4.0.0 to adapt to many kinds of systems.
|
||||
'configure' configures radare2-extras-4.4.0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: ./configure [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -180,7 +180,7 @@ take_environ() {
|
||||
}
|
||||
|
||||
show_version() {
|
||||
echo "radare2-extras-4.0.0 configuration script done with acr v1.7.2.
|
||||
echo "radare2-extras-4.4.0 configuration script done with acr v1.8.1.
|
||||
The 'Free Software Foundation' message is only for autodetection.
|
||||
Originally written by pancake <nopcode.org>."
|
||||
exit 0
|
||||
@@ -204,7 +204,7 @@ case $flag in
|
||||
show_version ; ;;
|
||||
-r|--r|--report)
|
||||
echo "PKGNAME: radare2-extras"
|
||||
echo "VERSION: 4.0.0"
|
||||
echo "VERSION: 4.4.0"
|
||||
echo "LANGS: c"
|
||||
echo "OPTIONAL: libewf libyara"
|
||||
echo "PKG-CONFIG: r_core libewf unicorn yara"
|
||||
@@ -273,7 +273,7 @@ parse_options "$1"
|
||||
shift
|
||||
done
|
||||
|
||||
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"
|
||||
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 VERSION VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_NUMBER PKGNAME VPATH 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
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
PKGNAME radare2-extras
|
||||
VERSION 4.0.0
|
||||
VERSION 4.4.0
|
||||
CONTACT pancake ; [email protected]
|
||||
|
||||
REPORT PREFIX ;
|
||||
|
||||
Vendored
+4
-4
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# This script was automatically generated by ACR v1.7.2
|
||||
# This script was automatically generated by ACR v1.8.1
|
||||
# @author: pancake <nopcode.org>
|
||||
# @url: http://www.nopcode.org
|
||||
# @repo: git clone https://github.com/radare/acr
|
||||
@@ -103,7 +103,7 @@ done
|
||||
: ${INSTALL_PROGRAM_STRIP:=${INSTALL} -m 755 -s}
|
||||
: ${INSTALL_MAN:=${INSTALL} -m 444}
|
||||
: ${INSTALL_LIB:=${INSTALL} -m 755 -c}
|
||||
PKGNAME='radare2-keystone' ; VERSION='0.1' ; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
|
||||
PKGNAME='radare2-keystone' ; VERSION='0.1' ; VERSION_MAJOR=0; VERSION_MINOR=1; VERSION_PATCH=0; VERSION_NUMBER=00100; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
|
||||
}
|
||||
|
||||
show_usage() {
|
||||
@@ -177,7 +177,7 @@ take_environ() {
|
||||
}
|
||||
|
||||
show_version() {
|
||||
echo "radare2-keystone-0.1 configuration script done with acr v1.7.2.
|
||||
echo "radare2-keystone-0.1 configuration script done with acr v1.8.1.
|
||||
The 'Free Software Foundation' message is only for autodetection.
|
||||
Originally written by pancake <nopcode.org>."
|
||||
exit 0
|
||||
@@ -267,7 +267,7 @@ parse_options "$1"
|
||||
shift
|
||||
done
|
||||
|
||||
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"
|
||||
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 VERSION VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_NUMBER PKGNAME VPATH 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
|
||||
|
||||
|
||||
@@ -9,6 +9,10 @@ atombios:
|
||||
$(MAKE) -C anal atombios
|
||||
$(MAKE) -C bin atombios
|
||||
|
||||
ba2:
|
||||
$(MAKE) -C asm ba2
|
||||
$(MAKE) -C anal ba2
|
||||
|
||||
blackfin:
|
||||
$(MAKE) -C asm blackfin
|
||||
|
||||
@@ -37,6 +41,7 @@ evm:
|
||||
|
||||
nios:
|
||||
$(MAKE) -C asm nios
|
||||
$(MAKE) -C anal nios
|
||||
|
||||
clean:
|
||||
$(MAKE) -C asm clean
|
||||
@@ -47,6 +52,10 @@ 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)
|
||||
@@ -76,5 +85,6 @@ evm-install:
|
||||
|
||||
nios-install:
|
||||
cp -f asm/p/asm_nios.$(LIBEXT) $(R2PM_PLUGDIR)
|
||||
cp -f anal/p/anal_nios.$(LIBEXT) $(R2PM_PLUGDIR)
|
||||
|
||||
include ../options.mk
|
||||
@@ -1,3 +1,6 @@
|
||||
ba2:
|
||||
cd p ; $(MAKE) anal_ba2.$(LIBEXT)
|
||||
|
||||
bea:
|
||||
cd p ; $(MAKE) anal_x86_bea.$(LIBEXT)
|
||||
|
||||
@@ -13,9 +16,14 @@ atombios:
|
||||
evm:
|
||||
cd p ; $(MAKE) anal_evm.$(LIBEXT)
|
||||
|
||||
nios:
|
||||
cd p ; $(MAKE) anal_nios.$(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
|
||||
@@ -1,5 +1,6 @@
|
||||
ARCHS=
|
||||
|
||||
ARCHS+=ba2.mk
|
||||
ARCHS+=x86_bea.mk
|
||||
#ARCHS+=x86_im.mk
|
||||
ARCHS+=x86_simple.mk
|
||||
@@ -7,5 +8,6 @@ ARCHS+=x86_udis.mk
|
||||
ARCHS+=m68k_net.mk
|
||||
ARCHS+=evm.mk
|
||||
ARCHS+=atombios.mk
|
||||
ARCHS+=nios.mk
|
||||
|
||||
include ../../plugs.mk
|
||||
+16
-69
@@ -8,8 +8,6 @@
|
||||
|
||||
#include "../../asm/arch/atombios/atombios.h"
|
||||
|
||||
#define R_IPI static
|
||||
|
||||
typedef struct {
|
||||
_RAnalOpType optype;
|
||||
const char *reg;
|
||||
@@ -155,66 +153,17 @@ atombios_ops_t atombios_ops[256] = {
|
||||
[0xff] = { R_ANAL_OP_TYPE_ILL, NULL }, // not implemented (reserved)
|
||||
};
|
||||
|
||||
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) {
|
||||
static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len, RAnalOpMask unused) {
|
||||
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;
|
||||
@@ -418,9 +367,8 @@ static int atombios_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int le
|
||||
|
||||
// op ds (imm data table)
|
||||
case 0x7a:
|
||||
{
|
||||
|
||||
} break;
|
||||
op->size = 3;// + r_read_at_le16(b, 1);
|
||||
break;
|
||||
|
||||
// op imm8
|
||||
case 0x50:
|
||||
@@ -463,7 +411,7 @@ 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 - 6 + r_read_at_le16(b, 1);
|
||||
op->jump = cursect->paddr + r_read_at_le16(b, 1);
|
||||
op->eob = true;
|
||||
esilprintf (op, "0x%08x,pc,=", op->jump);
|
||||
} break;
|
||||
@@ -475,7 +423,7 @@ 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 - 6 + r_read_at_le16(b, 1);
|
||||
op->jump = cursect->paddr + r_read_at_le16(b, 1);
|
||||
op->fail = addr + op->size;
|
||||
op->eob = true;
|
||||
esilprintf (op, "$z,?{,0x%08x,pc,=,}", op->jump);
|
||||
@@ -488,7 +436,7 @@ 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 - 6 + r_read_at_le16(b, 1);
|
||||
op->jump = cursect->paddr + r_read_at_le16(b, 1);
|
||||
op->fail = addr + op->size;
|
||||
op->eob = true;
|
||||
esilprintf (op, "$of,$sf,!=,?{,0x%08x,pc,=,}", op->jump);
|
||||
@@ -501,7 +449,7 @@ 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 - 6 + r_read_at_le16(b, 1);
|
||||
op->jump = cursect->paddr + r_read_at_le16(b, 1);
|
||||
op->fail = addr + op->size;
|
||||
op->eob = true;
|
||||
esilprintf (op, "$z,!,$of,$sf,==,&,?{,0x%08x,pc,=,}", op->jump);
|
||||
@@ -514,7 +462,7 @@ 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 - 6 + r_read_at_le16(b, 1);
|
||||
op->jump = cursect->paddr + r_read_at_le16(b, 1);
|
||||
op->fail = addr + op->size;
|
||||
op->eob = true;
|
||||
esilprintf (op, "$z,$of,$sf,!=,|,?{,0x%08x,pc,=,}", op->jump);
|
||||
@@ -527,7 +475,7 @@ 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 - 6 + r_read_at_le16(b, 1);
|
||||
op->jump = cursect->paddr + r_read_at_le16(b, 1);
|
||||
op->fail = addr + op->size;
|
||||
op->eob = true;
|
||||
esilprintf (op, "$of,$sf,==,?{,0x%08x,pc,=,}", op->jump);
|
||||
@@ -540,7 +488,7 @@ 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 - 6 + r_read_at_le16(b, 1);
|
||||
op->jump = cursect->paddr + r_read_at_le16(b, 1);
|
||||
op->fail = addr + op->size;
|
||||
op->eob = true;
|
||||
esilprintf (op, "$z,!,?{,0x%08x,pc,=,}", op->jump);
|
||||
@@ -892,7 +840,7 @@ static int archinfo(RAnal *anal, int query) {
|
||||
}
|
||||
}
|
||||
|
||||
static int set_reg_profile(RAnal *anal) {
|
||||
static bool set_reg_profile(RAnal *anal) {
|
||||
const char *p =
|
||||
"=PC pc\n"
|
||||
"=SP sp\n"
|
||||
@@ -1114,7 +1062,6 @@ RAnalPlugin r_anal_plugin_atombios = {
|
||||
.arch = "atombios",
|
||||
.bits = 32 | 64,
|
||||
.op = &atombios_op,
|
||||
.analyze_fns = atombios_analyze_fns,
|
||||
.archinfo = archinfo,
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/* 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
|
||||
|
||||
@@ -0,0 +1,799 @@
|
||||
/* 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++) {
|
||||
const char *key = sdb_fmt("%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];
|
||||
const char *key = sdb_fmt("%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
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
OBJ_BA2=anal_ba2.o
|
||||
CFLAGS+=-I../asm/arch/ba2
|
||||
|
||||
STATIC_OBJ+=${OBJ_BA2}
|
||||
TARGET_BA2=anal_ba2.${LIBEXT}
|
||||
|
||||
ALL_TARGETS+=${TARGET_BA2}
|
||||
|
||||
${TARGET_BA2}: ${OBJ_BA2}
|
||||
${CC} $(call libname,anal_ba2) ${LDFLAGS} ${CFLAGS} -o ${TARGET_BA2} ${OBJ_BA2}
|
||||
@@ -0,0 +1,14 @@
|
||||
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}
|
||||
|
||||
+7
-11
@@ -3,6 +3,12 @@ R2PM_PLUGDIR ?=$(HOME)/.config/radare2/plugins
|
||||
atombios:
|
||||
cd p ; $(MAKE) asm_atombios.$(LIBEXT)
|
||||
|
||||
spc700:
|
||||
cd p ; $(MAKE) asm_spc700.$(LIBEXT)
|
||||
|
||||
ba2:
|
||||
cd p ; $(MAKE) asm_ba2.$(LIBEXT)
|
||||
|
||||
blackfin:
|
||||
cd p ; $(MAKE) asm_blackfin.$(LIBEXT)
|
||||
|
||||
@@ -24,9 +30,6 @@ tab:
|
||||
swf:
|
||||
cd p ; $(MAKE) asm_swf.$(LIBEXT)
|
||||
|
||||
pyc:
|
||||
cd p ; $(MAKE) asm_pyc.$(LIBEXT)
|
||||
|
||||
olly:
|
||||
cd p ; $(MAKE) asm_x86_olly.$(LIBEXT)
|
||||
|
||||
@@ -50,13 +53,6 @@ zyan-uninstall:
|
||||
$(RM) $(R2PM_PLUGDIR)/asm_x86_zyan.$(LIBEXT)
|
||||
|
||||
clean:
|
||||
rm -f p/asm_x86_bea.$(LIBEXT)
|
||||
rm -f p/asm_x86_tab.$(LIBEXT)
|
||||
rm -f p/asm_x86_olly.$(LIBEXT)
|
||||
rm -f p/asm_m68k.$(LIBEXT)
|
||||
rm -f p/asm_x86_zyan.$(LIBEXT)
|
||||
rm -f p/asm_atombios.{$(LIBEXT),o}
|
||||
rm -f arch/atombios/atombios.o
|
||||
rm -f p/asm_nios.$(LIBEXT)
|
||||
rm -f p/*.$(LIBEXT) p/*.o
|
||||
|
||||
include ../../options.mk
|
||||
@@ -592,12 +592,16 @@ int atombios_inst_len(const ut8 *buf) {
|
||||
return size;
|
||||
}
|
||||
|
||||
int atombios_disassemble(const ut8 *inbuf, char *outbuf) {
|
||||
int atombios_disassemble(const ut8 *inbuf, int len, char *outbuf) {
|
||||
const ut8 *d = inbuf;
|
||||
ut8 size = 0;
|
||||
|
||||
if (optable[*d].process) {
|
||||
size = optable[*d].process (d, outbuf);
|
||||
if (size > len) {
|
||||
sprintf (outbuf, "<truncated>");
|
||||
size = 1;
|
||||
}
|
||||
} else {
|
||||
sprintf (outbuf, "<unknown opcode> %02x", *d);
|
||||
size = 1;
|
||||
|
||||
@@ -68,7 +68,7 @@ typedef struct {
|
||||
|
||||
|
||||
int atombios_inst_len(const ut8 *buf);
|
||||
int atombios_disassemble(const ut8 *inbuf, char *outbuf);
|
||||
int atombios_disassemble(const ut8 *inbuf, int len, char *outbuf);
|
||||
const char *get_index (int type, int val);
|
||||
|
||||
extern const char *align_source_esil[];
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -36,8 +36,12 @@
|
||||
#define EXIT exit
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <regex.h>
|
||||
|
||||
typedef long TIword;
|
||||
|
||||
|
||||
#define HOST_LONG_WORD_SIZE (sizeof (long) * 8)
|
||||
#define XFIELD(w,p,s) (((w) & ((1 << (s)) - 1) << (p)) >> (p))
|
||||
#define SIGNEXTEND(v, n) ((v << (HOST_LONG_WORD_SIZE - (n))) >> (HOST_LONG_WORD_SIZE - (n)))
|
||||
@@ -130,7 +134,9 @@ fmtconst (const_forms_t cf, TIword x, bfd_vma pc, disassemble_info *outf)
|
||||
bfd_vma ea = (((constant_formats[cf].pcrel ? SIGNEXTEND (x, constant_formats[cf].nbits)
|
||||
: x) + constant_formats[cf].offset) << constant_formats[cf].scale);
|
||||
if (constant_formats[cf].pcrel)
|
||||
ea += pc;
|
||||
{
|
||||
ea += pc;
|
||||
}
|
||||
|
||||
/* truncate to 32-bits for proper symbol lookup/matching */
|
||||
ea = (bu32)ea;
|
||||
@@ -551,7 +557,7 @@ static void
|
||||
aligndir (int r0, disassemble_info *outf)
|
||||
{
|
||||
if (r0 == 1)
|
||||
OUTS (outf, " (e)");
|
||||
OUTS (outf, " (r)");
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1298,24 +1304,24 @@ decode_BRCC_0 (TIword iw0, bfd_vma pc, disassemble_info *outf)
|
||||
|
||||
if (T == 1 && B == 1)
|
||||
{
|
||||
OUTS (outf, "if cc jump 0x");
|
||||
OUTS (outf, "if cc jump ");
|
||||
OUTS (outf, pcrel10 (offset));
|
||||
OUTS (outf, " (bp)");
|
||||
}
|
||||
else if (T == 0 && B == 1)
|
||||
{
|
||||
OUTS (outf, "if !cc jump 0x");
|
||||
OUTS (outf, "if !cc jump ");
|
||||
OUTS (outf, pcrel10 (offset));
|
||||
OUTS (outf, " (bp)");
|
||||
}
|
||||
else if (T == 1)
|
||||
{
|
||||
OUTS (outf, "if cc jump 0x");
|
||||
OUTS (outf, "if cc jump ");
|
||||
OUTS (outf, pcrel10 (offset));
|
||||
}
|
||||
else if (T == 0)
|
||||
{
|
||||
OUTS (outf, "if !cc jump 0x");
|
||||
OUTS (outf, "if !cc jump ");
|
||||
OUTS (outf, pcrel10 (offset));
|
||||
}
|
||||
else
|
||||
@@ -1336,8 +1342,9 @@ decode_UJUMP_0 (TIword iw0, bfd_vma pc, disassemble_info *outf)
|
||||
if (parallel)
|
||||
return 0;
|
||||
|
||||
OUTS (outf, "jump.s 0x");
|
||||
OUTS (outf, "jump.s ");
|
||||
OUTS (outf, pcrel12 (offset));
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -1594,9 +1601,10 @@ decode_LOGI2op_0 (TIword iw0, disassemble_info *outf)
|
||||
OUTS (outf, dregs (dst));
|
||||
OUTS (outf, ", ");
|
||||
OUTS (outf, uimm5 (src));
|
||||
OUTS (outf, ");\t\t/* bit");
|
||||
OUTS (outf, imm7d (src));
|
||||
OUTS (outf, " */");
|
||||
OUTS (outf, ");");
|
||||
// OUTS (outf, "\t\t/* bit");
|
||||
// OUTS (outf, imm7d (src));
|
||||
// OUTS (outf, " */");
|
||||
comment = 1;
|
||||
}
|
||||
else if (opc == 1)
|
||||
@@ -1605,9 +1613,10 @@ decode_LOGI2op_0 (TIword iw0, disassemble_info *outf)
|
||||
OUTS (outf, dregs (dst));
|
||||
OUTS (outf, ", ");
|
||||
OUTS (outf, uimm5 (src));
|
||||
OUTS (outf, ");\t\t/* bit");
|
||||
OUTS (outf, imm7d (src));
|
||||
OUTS (outf, " */");
|
||||
OUTS (outf, ");");
|
||||
// OUTS (outf, "\t\t/* bit");
|
||||
// OUTS (outf, imm7d (src));
|
||||
// OUTS (outf, " */");
|
||||
comment = 1;
|
||||
}
|
||||
else if (opc == 2)
|
||||
@@ -1616,9 +1625,10 @@ decode_LOGI2op_0 (TIword iw0, disassemble_info *outf)
|
||||
OUTS (outf, dregs (dst));
|
||||
OUTS (outf, ", ");
|
||||
OUTS (outf, uimm5 (src));
|
||||
OUTS (outf, ");\t\t/* bit");
|
||||
OUTS (outf, imm7d (src));
|
||||
OUTS (outf, " */");
|
||||
OUTS (outf, ");");
|
||||
// OUTS (outf, "\t\t/* bit");
|
||||
// OUTS (outf, imm7d (src));
|
||||
// OUTS (outf, " */");
|
||||
comment = 1;
|
||||
}
|
||||
else if (opc == 3)
|
||||
@@ -1627,9 +1637,10 @@ decode_LOGI2op_0 (TIword iw0, disassemble_info *outf)
|
||||
OUTS (outf, dregs (dst));
|
||||
OUTS (outf, ", ");
|
||||
OUTS (outf, uimm5 (src));
|
||||
OUTS (outf, ");\t\t/* bit");
|
||||
OUTS (outf, imm7d (src));
|
||||
OUTS (outf, " */");
|
||||
OUTS (outf, ");");
|
||||
// OUTS (outf, "\t\t/* bit");
|
||||
// OUTS (outf, imm7d (src));
|
||||
// OUTS (outf, " */");
|
||||
comment = 1;
|
||||
}
|
||||
else if (opc == 4)
|
||||
@@ -1638,9 +1649,10 @@ decode_LOGI2op_0 (TIword iw0, disassemble_info *outf)
|
||||
OUTS (outf, dregs (dst));
|
||||
OUTS (outf, ", ");
|
||||
OUTS (outf, uimm5 (src));
|
||||
OUTS (outf, ");\t\t/* bit");
|
||||
OUTS (outf, imm7d (src));
|
||||
OUTS (outf, " */");
|
||||
OUTS (outf, ");");
|
||||
// OUTS (outf, "\t\t/* bit");
|
||||
// OUTS (outf, imm7d (src));
|
||||
// OUTS (outf, " */");
|
||||
comment = 1;
|
||||
}
|
||||
else if (opc == 5)
|
||||
@@ -1791,13 +1803,14 @@ decode_COMPI2opD_0 (TIword iw0, disassemble_info *outf)
|
||||
OUTS (outf, dregs (dst));
|
||||
OUTS (outf, " = ");
|
||||
OUTS (outf, imm7 (src));
|
||||
OUTS (outf, " (X);\t\t/*\t\t");
|
||||
OUTS (outf, dregs (dst));
|
||||
OUTS (outf, "=");
|
||||
OUTS (outf, uimm32 (*pval));
|
||||
OUTS (outf, "(");
|
||||
OUTS (outf, imm32 (*pval));
|
||||
OUTS (outf, ") */");
|
||||
OUTS (outf, " (X);");
|
||||
// OUTS (outf, "\t\t/*\t\t");
|
||||
// OUTS (outf, dregs (dst));
|
||||
// OUTS (outf, "=");
|
||||
// OUTS (outf, uimm32 (*pval));
|
||||
// OUTS (outf, "(");
|
||||
// OUTS (outf, imm32 (*pval));
|
||||
// OUTS (outf, ") */");
|
||||
comment = 1;
|
||||
}
|
||||
else if (op == 1)
|
||||
@@ -1805,9 +1818,10 @@ decode_COMPI2opD_0 (TIword iw0, disassemble_info *outf)
|
||||
OUTS (outf, dregs (dst));
|
||||
OUTS (outf, " += ");
|
||||
OUTS (outf, imm7 (src));
|
||||
OUTS (outf, ";\t\t/* (");
|
||||
OUTS (outf, imm7d (src));
|
||||
OUTS (outf, ") */");
|
||||
OUTS (outf, ";");
|
||||
// OUTS (outf, "\t\t/* (");
|
||||
// OUTS (outf, imm7d (src));
|
||||
// OUTS (outf, ") */");
|
||||
comment = 1;
|
||||
}
|
||||
else
|
||||
@@ -1846,13 +1860,14 @@ decode_COMPI2opP_0 (TIword iw0, disassemble_info *outf)
|
||||
OUTS (outf, pregs (dst));
|
||||
OUTS (outf, " = ");
|
||||
OUTS (outf, imm7 (src));
|
||||
OUTS (outf, " (x);\t\t/*\t\t");
|
||||
OUTS (outf, pregs (dst));
|
||||
OUTS (outf, "=");
|
||||
OUTS (outf, uimm32 (*pval));
|
||||
OUTS (outf, "(");
|
||||
OUTS (outf, imm32 (*pval));
|
||||
OUTS (outf, ") */");
|
||||
OUTS (outf, " (x);");
|
||||
// OUTS (outf, "\t\t/*\t\t");
|
||||
// OUTS (outf, pregs (dst));
|
||||
// OUTS (outf, "=");
|
||||
// OUTS (outf, uimm32 (*pval));
|
||||
// OUTS (outf, "(");
|
||||
// OUTS (outf, imm32 (*pval));
|
||||
// OUTS (outf, ") */");
|
||||
comment = 1;
|
||||
}
|
||||
else if (op == 1)
|
||||
@@ -1860,9 +1875,10 @@ decode_COMPI2opP_0 (TIword iw0, disassemble_info *outf)
|
||||
OUTS (outf, pregs (dst));
|
||||
OUTS (outf, " += ");
|
||||
OUTS (outf, imm7 (src));
|
||||
OUTS (outf, ";\t\t/* (");
|
||||
OUTS (outf, imm7d (src));
|
||||
OUTS (outf, ") */");
|
||||
OUTS (outf, ";");
|
||||
// OUTS (outf, "\t\t/* (");
|
||||
// OUTS (outf, imm7d (src));
|
||||
// OUTS (outf, ") */");
|
||||
comment = 1;
|
||||
}
|
||||
else
|
||||
@@ -2603,9 +2619,9 @@ decode_LoopSetup_0 (TIword iw0, TIword iw1, bfd_vma pc, disassemble_info *outf)
|
||||
if (rop == 0)
|
||||
{
|
||||
OUTS (outf, "lsetup");
|
||||
OUTS (outf, "(0x");
|
||||
OUTS (outf, "(");
|
||||
OUTS (outf, pcrel4 (soffset));
|
||||
OUTS (outf, ", 0x");
|
||||
OUTS (outf, ", ");
|
||||
OUTS (outf, lppcrel10 (eoffset));
|
||||
OUTS (outf, ") ");
|
||||
OUTS (outf, counters (c));
|
||||
@@ -2613,9 +2629,9 @@ decode_LoopSetup_0 (TIword iw0, TIword iw1, bfd_vma pc, disassemble_info *outf)
|
||||
else if (rop == 1)
|
||||
{
|
||||
OUTS (outf, "lsetup");
|
||||
OUTS (outf, "(0x");
|
||||
OUTS (outf, "(");
|
||||
OUTS (outf, pcrel4 (soffset));
|
||||
OUTS (outf, ", 0x");
|
||||
OUTS (outf, ", ");
|
||||
OUTS (outf, lppcrel10 (eoffset));
|
||||
OUTS (outf, ") ");
|
||||
OUTS (outf, counters (c));
|
||||
@@ -2625,9 +2641,9 @@ decode_LoopSetup_0 (TIword iw0, TIword iw1, bfd_vma pc, disassemble_info *outf)
|
||||
else if (rop == 3)
|
||||
{
|
||||
OUTS (outf, "lsetup");
|
||||
OUTS (outf, "(0x");
|
||||
OUTS (outf, "(");
|
||||
OUTS (outf, pcrel4 (soffset));
|
||||
OUTS (outf, ", 0x");
|
||||
OUTS (outf, ", ");
|
||||
OUTS (outf, lppcrel10 (eoffset));
|
||||
OUTS (outf, ") ");
|
||||
OUTS (outf, counters (c));
|
||||
@@ -2744,39 +2760,39 @@ decode_LDIMMhalf_0 (TIword iw0, TIword iw1, disassemble_info *outf)
|
||||
/* And we print out the 32-bit value if it is a pointer. */
|
||||
if (S == 0 && Z == 0)
|
||||
{
|
||||
OUTS (outf, ";\t\t/* (");
|
||||
OUTS (outf, imm16d (hword));
|
||||
OUTS (outf, ")\t");
|
||||
// OUTS (outf, ";\t\t/* (");
|
||||
// OUTS (outf, imm16d (hword));
|
||||
// OUTS (outf, ")\t");
|
||||
|
||||
/* If it is an MMR, don't print the symbol. */
|
||||
if (*pval < 0xFFC00000 && grp == 1)
|
||||
{
|
||||
OUTS (outf, regs (reg, grp));
|
||||
OUTS (outf, "=0x");
|
||||
OUTS (outf, huimm32e (*pval));
|
||||
}
|
||||
else
|
||||
{
|
||||
OUTS (outf, regs (reg, grp));
|
||||
OUTS (outf, "=0x");
|
||||
OUTS (outf, huimm32e (*pval));
|
||||
OUTS (outf, "(");
|
||||
OUTS (outf, imm32 (*pval));
|
||||
OUTS (outf, ")");
|
||||
}
|
||||
// /* If it is an MMR, don't print the symbol. */
|
||||
// if (*pval < 0xFFC00000 && grp == 1)
|
||||
// {
|
||||
// OUTS (outf, regs (reg, grp));
|
||||
// OUTS (outf, "=0x");
|
||||
// OUTS (outf, huimm32e (*pval));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// OUTS (outf, regs (reg, grp));
|
||||
// OUTS (outf, "=0x");
|
||||
// OUTS (outf, huimm32e (*pval));
|
||||
// OUTS (outf, "(");
|
||||
// OUTS (outf, imm32 (*pval));
|
||||
// OUTS (outf, ")");
|
||||
// }
|
||||
|
||||
OUTS (outf, " */");
|
||||
// OUTS (outf, " */");
|
||||
comment = 1;
|
||||
}
|
||||
if (S == 1 || Z == 1)
|
||||
{
|
||||
OUTS (outf, ";\t\t/*\t\t");
|
||||
OUTS (outf, regs (reg, grp));
|
||||
OUTS (outf, "=0x");
|
||||
OUTS (outf, huimm32e (*pval));
|
||||
OUTS (outf, "(");
|
||||
OUTS (outf, imm32 (*pval));
|
||||
OUTS (outf, ") */");
|
||||
// OUTS (outf, ";\t\t/*\t\t");
|
||||
// OUTS (outf, regs (reg, grp));
|
||||
// OUTS (outf, "=0x");
|
||||
// OUTS (outf, huimm32e (*pval));
|
||||
// OUTS (outf, "(");
|
||||
// OUTS (outf, imm32 (*pval));
|
||||
// OUTS (outf, ") */");
|
||||
comment = 1;
|
||||
}
|
||||
return 4;
|
||||
@@ -2798,9 +2814,9 @@ decode_CALLa_0 (TIword iw0, TIword iw1, bfd_vma pc, disassemble_info *outf)
|
||||
return 0;
|
||||
|
||||
if (S == 1)
|
||||
OUTS (outf, "call 0x");
|
||||
OUTS (outf, "call ");
|
||||
else if (S == 0)
|
||||
OUTS (outf, "jump.l 0x");
|
||||
OUTS (outf, "jump.l ");
|
||||
else
|
||||
return 0;
|
||||
|
||||
@@ -2937,9 +2953,10 @@ decode_linkage_0 (TIword iw0, TIword iw1, disassemble_info *outf)
|
||||
{
|
||||
OUTS (outf, "link ");
|
||||
OUTS (outf, uimm16s4 (framesize));
|
||||
OUTS (outf, ";\t\t/* (");
|
||||
OUTS (outf, uimm16s4d (framesize));
|
||||
OUTS (outf, ") */");
|
||||
OUTS (outf, ";");
|
||||
// OUTS (outf, "\t\t/* (");
|
||||
// OUTS (outf, uimm16s4d (framesize));
|
||||
// OUTS (outf, ") */");
|
||||
comment = 1;
|
||||
}
|
||||
else if (R == 1)
|
||||
@@ -3557,7 +3574,7 @@ decode_dsp32alu_0 (TIword iw0, TIword iw1, disassemble_info *outf)
|
||||
OUTS (outf, dregs (src1 + 1));
|
||||
OUTS (outf, ":");
|
||||
OUTS (outf, imm5d (src1));
|
||||
OUTS (outf, ") (lO");
|
||||
OUTS (outf, ") (lo");
|
||||
if (s == 1)
|
||||
OUTS (outf, ", r)");
|
||||
else
|
||||
@@ -4654,11 +4671,7 @@ _print_insn_bfin (bfd_vma pc, disassemble_info *outf)
|
||||
int status;
|
||||
int rv = 0;
|
||||
|
||||
status = (*outf->read_memory_func) (pc & ~0x1, buf, 2, outf);
|
||||
/* FIXME */
|
||||
(void) status;
|
||||
status = (*outf->read_memory_func) ((pc + 2) & ~0x1, buf + 2, 2, outf);
|
||||
/* FIXME */
|
||||
status = (*outf->read_memory_func) ((pc) & ~0x1, buf, 4, outf);
|
||||
(void) status;
|
||||
|
||||
iw0 = bfd_getl16 (buf);
|
||||
@@ -4811,3 +4824,5 @@ print_insn_bfin (bfd_vma pc, disassemble_info *outf)
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ const EvmOpDef opcodes[256] = {
|
||||
[EVM_OP_XOR] = { "xor", 1 },
|
||||
[EVM_OP_NOT] = { "not", 1 },
|
||||
[EVM_OP_BYTE] = { "byte", 1 },
|
||||
[EVM_OP_SHL] = { "shl", 1 },
|
||||
[EVM_OP_SHR] = { "shr", 1 },
|
||||
[EVM_OP_SAR] = { "sar", 1 },
|
||||
[EVM_OP_SHA3] = { "sha3", 1 },
|
||||
[EVM_OP_ADDRESS] = { "address", 1 },
|
||||
[EVM_OP_BALANCE] = { "balance", 1 },
|
||||
@@ -46,12 +49,15 @@ const EvmOpDef opcodes[256] = {
|
||||
[EVM_OP_EXTCODECOPY] = { "extcodecopy", 1 },
|
||||
[EVM_OP_RETURNDATASIZE] = { "returndatasize", 1},
|
||||
[EVM_OP_RETURNDATACOPY] = { "returndatacopy", 1},
|
||||
[EVM_OP_EXTCODEHASH] = { "extcodehash", 1},
|
||||
[EVM_OP_BLOCKHASH] = { "blockhash", 1 },
|
||||
[EVM_OP_COINBASE] = { "coinbase", 1 },
|
||||
[EVM_OP_TIMESTAMP] = { "timestamp", 1 },
|
||||
[EVM_OP_NUMBER] = { "number", 1 },
|
||||
[EVM_OP_DIFFICULTY] = { "difficulty", 1 },
|
||||
[EVM_OP_GASLIMIT] = { "gaslimit", 1 },
|
||||
[EVM_OP_CHAINID] = { "chainid", 1 },
|
||||
[EVM_OP_SELFBALANCE] = { "selfbalance", 1 },
|
||||
[EVM_OP_POP] = { "pop", 1 },
|
||||
[EVM_OP_MLOAD] = { "mload", 1 },
|
||||
[EVM_OP_MSTORE] = { "mstore", 1 },
|
||||
@@ -70,8 +76,10 @@ const EvmOpDef opcodes[256] = {
|
||||
[EVM_OP_CALLCODE] = { "callcode", 1 },
|
||||
[EVM_OP_RETURN] = { "return", 1 },
|
||||
[EVM_OP_DELEGATECALL] = { "delegatecall", 1 },
|
||||
[EVM_OP_CREATE2] = { "create2", 1 },
|
||||
[EVM_OP_STATICCALL] = { "staticcall", 1 },
|
||||
[EVM_OP_REVERT] = { "revert", 1 },
|
||||
[EVM_OP_INVALID] = { "invalid", 1 },
|
||||
[EVM_OP_SELFDESTRUCT] = { "selfdestruct", 1 },
|
||||
};
|
||||
|
||||
@@ -214,7 +222,7 @@ int evm_dis(EvmOp *op, const unsigned char *buf, int buf_len) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
settxtf (op, "invalid");
|
||||
settxtf (op, "unassigned");
|
||||
op->len = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
+11
-4
@@ -28,6 +28,9 @@ typedef enum {
|
||||
EVM_OP_XOR,
|
||||
EVM_OP_NOT,
|
||||
EVM_OP_BYTE,
|
||||
EVM_OP_SHL,
|
||||
EVM_OP_SHR,
|
||||
EVM_OP_SAR,
|
||||
EVM_OP_SHA3 = 0x20,
|
||||
|
||||
EVM_OP_ADDRESS = 0x30,
|
||||
@@ -45,13 +48,15 @@ typedef enum {
|
||||
EVM_OP_EXTCODECOPY,
|
||||
EVM_OP_RETURNDATASIZE,
|
||||
EVM_OP_RETURNDATACOPY,
|
||||
|
||||
EVM_OP_BLOCKHASH = 0x40,
|
||||
EVM_OP_EXTCODEHASH,
|
||||
EVM_OP_BLOCKHASH,
|
||||
EVM_OP_COINBASE,
|
||||
EVM_OP_TIMESTAMP,
|
||||
EVM_OP_NUMBER,
|
||||
EVM_OP_DIFFICULTY,
|
||||
EVM_OP_GASLIMIT,
|
||||
EVM_OP_CHAINID,
|
||||
EVM_OP_SELFBALANCE,
|
||||
|
||||
EVM_OP_POP = 0x50,
|
||||
EVM_OP_MLOAD,
|
||||
@@ -142,9 +147,11 @@ typedef enum {
|
||||
EVM_OP_CALLCODE,
|
||||
EVM_OP_RETURN,
|
||||
EVM_OP_DELEGATECALL,
|
||||
EVM_OP_CREATE2,
|
||||
EVM_OP_STATICCALL = 0xfa,
|
||||
EVM_OP_REVERT = 0xfd,
|
||||
EVM_OP_SELFDESTRUCT = 0xff
|
||||
EVM_OP_REVERT,
|
||||
EVM_OP_INVALID,
|
||||
EVM_OP_SELFDESTRUCT
|
||||
} EvmOpcodes;
|
||||
|
||||
typedef struct EvmOp {
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
/* Instruction printing code for the Hexagon.
|
||||
Copyright 1994, 1995, 1997, 1998, 2000, 2001, 2002
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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-1335 USA
|
||||
*/
|
||||
|
||||
#include "ansidecl.h"
|
||||
#include "libiberty.h"
|
||||
#include "disas-asm.h"
|
||||
#include "opcode/hexagon.h"
|
||||
#include "mybfd.h"
|
||||
//#include "elf/hexagon.h"
|
||||
#include <string.h>
|
||||
#include "opintl.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "safe-ctype.h"
|
||||
|
||||
static int
|
||||
hexagon_dis_inst(
|
||||
bfd_vma address,
|
||||
hexagon_insn insn,
|
||||
char *instrBuffer,
|
||||
disassemble_info * info
|
||||
)
|
||||
{
|
||||
const hexagon_opcode *opcode;
|
||||
int len;
|
||||
char *errmsg = NULL;
|
||||
|
||||
len = HEXAGON_INSN_LEN;
|
||||
|
||||
opcode = hexagon_lookup_insn(insn);
|
||||
if (opcode) {
|
||||
|
||||
if (!hexagon_dis_opcode(instrBuffer, insn, address, opcode, &errmsg)) {
|
||||
/* Some kind of error! */
|
||||
if (errmsg) {
|
||||
(*info->fprintf_func) (info->stream, "%s", errmsg);
|
||||
strcpy(instrBuffer, "");
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// Instruction not found
|
||||
strcpy(instrBuffer, "<unknown>");
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
/* Decode an instruction returning the size of the instruction
|
||||
in bytes or zero if unrecognized. */
|
||||
static int
|
||||
hexagon_decode_inst(
|
||||
bfd_vma address, /* Address of this instruction. */
|
||||
disassemble_info * info
|
||||
)
|
||||
{
|
||||
int status;
|
||||
hexagon_insn insn;
|
||||
bfd_byte buffer[4];
|
||||
void *stream = info->stream; /* output stream */
|
||||
fprintf_ftype func = info->fprintf_func;
|
||||
char instrBuffer[100];
|
||||
int bytes;
|
||||
char *str;
|
||||
|
||||
#if 0
|
||||
/* Decide if we have a 16-bit instruction */
|
||||
// Nope comment you are drunk.
|
||||
status = (*info->read_memory_func)(address, buffer, 2, info);
|
||||
if (status != 0) {
|
||||
(*info->memory_error_func)(status, address, info);
|
||||
return -1;
|
||||
}
|
||||
if (info->endian == BFD_ENDIAN_LITTLE) {
|
||||
insn = bfd_getl16 (buffer);
|
||||
}
|
||||
else {
|
||||
insn = bfd_getb16 (buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
status = (*info->read_memory_func)(address, buffer, 4, info);
|
||||
if (status != 0) {
|
||||
(*info->memory_error_func)(status, address, info);
|
||||
return -1;
|
||||
}
|
||||
if (info->endian == BFD_ENDIAN_LITTLE) {
|
||||
insn = bfd_getl32(buffer);
|
||||
}
|
||||
else {
|
||||
insn = bfd_getb32(buffer);
|
||||
}
|
||||
|
||||
/* disassemble */
|
||||
bytes = hexagon_dis_inst(address, insn, instrBuffer, info);
|
||||
|
||||
/* display the disassembly instruction */
|
||||
if (bytes == 2) {
|
||||
(*func) (stream, " %04x ", insn);
|
||||
}
|
||||
else {
|
||||
(*func) (stream, "%08x ", insn);
|
||||
}
|
||||
(*func) (stream, " ");
|
||||
|
||||
/* Print the instruction buffer
|
||||
Watch out for placeholders where we want
|
||||
to print out the symbolic name for an address */
|
||||
str = instrBuffer;
|
||||
while (*str) {
|
||||
char ch = *str++;
|
||||
if (ch == '@') {
|
||||
bfd_vma addr = 0;
|
||||
while (ISDIGIT(*str)) {
|
||||
ch = *str++;
|
||||
addr = 10*addr + (ch - '0');
|
||||
}
|
||||
(*info->print_address_func)(addr, info);
|
||||
}
|
||||
else {
|
||||
(*func)(stream, "%c", ch);
|
||||
}
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* Return the print_insn function to use. */
|
||||
disassembler_ftype
|
||||
hexagon_get_disassembler_from_mach(
|
||||
unsigned long machine,
|
||||
unsigned long big_p
|
||||
)
|
||||
{
|
||||
hexagon_opcode_init_tables(hexagon_get_opcode_mach(machine, big_p));
|
||||
return hexagon_decode_inst;
|
||||
}
|
||||
|
||||
disassembler_ftype
|
||||
hexagon_get_disassembler(
|
||||
bfd *abfd
|
||||
)
|
||||
{
|
||||
unsigned long machine = 0; // XXX bfd_get_mach(abfd);
|
||||
unsigned long big_p = bfd_big_endian(abfd);
|
||||
return (hexagon_get_disassembler_from_mach(machine, big_p));
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,522 @@
|
||||
|
||||
|
||||
/* Opcode table for the Hexagon.
|
||||
Copyright 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler, GDB, the GNU debugger, and
|
||||
the GNU Binutils.
|
||||
|
||||
GAS/GDB 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 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GAS/GDB 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 GAS or GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
||||
*/
|
||||
|
||||
#ifndef OPCODES_HEXAGON_H
|
||||
#define OPCODES_HEXAGON_H 1
|
||||
|
||||
/* List of the various cpu types.
|
||||
The tables currently use bit masks to say whether the instruction or
|
||||
whatever is supported by a particular cpu. This lets us have one entry
|
||||
apply to several cpus.
|
||||
|
||||
The `base' cpu must be 0. The cpu type is treated independently of
|
||||
endianness. The complete `mach' number includes endianness.
|
||||
These values are internal to opcodes/bfd/binutils/gas. */
|
||||
#define HEXAGON_MACH 0
|
||||
#define HEXAGON_MACH_V2 2
|
||||
#define HEXAGON_MACH_V3 3
|
||||
#define HEXAGON_MACH_V4 4
|
||||
#define HEXAGON_MACH_V5 5
|
||||
/* Additional cpu values can be inserted here and HEXAGON_MACH_BIG moved down. */
|
||||
#define HEXAGON_MACH_BIG 16
|
||||
|
||||
/* Mask of number of bits necessary to record cpu type. */
|
||||
#define HEXAGON_MACH_CPU_MASK (HEXAGON_MACH_BIG - 1)
|
||||
/* Mask of number of bits necessary to record cpu type + endianness. */
|
||||
#define HEXAGON_MACH_MASK ((HEXAGON_MACH_BIG << 1) - 1)
|
||||
|
||||
/* Qualifier for several table entries. */
|
||||
#define HEXAGON_IS_V2 (1 << 31)
|
||||
#define HEXAGON_IS_V3 (1 << 30)
|
||||
#define HEXAGON_IS_V4 (1 << 29)
|
||||
#define HEXAGON_IS_V5 (1 << 28)
|
||||
#define HEXAGON_V2_AND_V3 (HEXAGON_IS_V3 | HEXAGON_IS_V2)
|
||||
#define HEXAGON_V2_AND_UP (HEXAGON_IS_V5 | HEXAGON_IS_V4 | HEXAGON_IS_V3 | HEXAGON_IS_V2)
|
||||
#define HEXAGON_V3_AND_UP (HEXAGON_IS_V5 | HEXAGON_IS_V4 | HEXAGON_IS_V3)
|
||||
#define HEXAGON_V4_AND_UP (HEXAGON_IS_V5 | HEXAGON_IS_V4)
|
||||
|
||||
/* This is the instruction size in bytes. */
|
||||
#define HEXAGON_INSN_LEN (4)
|
||||
|
||||
/** Maximum number of insns in a packet.
|
||||
*/
|
||||
#define MAX_PACKET_INSNS 4
|
||||
|
||||
/* This is the mnemonic length for mapped insns. */
|
||||
#define HEXAGON_MAPPED_LEN (256)
|
||||
|
||||
/* Determine if a number can be represented in 16 bits (unsigned) */
|
||||
#define HEXAGON_IS16BITS(num) 0 /* not yet implemented */
|
||||
|
||||
/* Determine if a number is a 16-bit instruction */
|
||||
#define HEXAGON_IS16INSN(num) 0 /* not yet implemented */
|
||||
|
||||
/* Extract the low 16 bits */
|
||||
#define HEXAGON_LO16(num) ((num) & ~(-1UL << 16))
|
||||
|
||||
/* Extract the high 16 bits */
|
||||
#define HEXAGON_HI16(num) (HEXAGON_LO16 ((num) >> 16))
|
||||
|
||||
/* Extract the extender bits. */
|
||||
#define HEXAGON_KXER_MASK(num) ((num) & (-1 << 6))
|
||||
|
||||
/* Extract the extended bits. */
|
||||
#define HEXAGON_KXED_MASK(num) ((num) & ~(-1 << 6))
|
||||
|
||||
/* Registers. */
|
||||
#define HEXAGON_NUM_GENERAL_PURPOSE_REGS 32
|
||||
#define HEXAGON_NUM_CONTROL_REGS 32
|
||||
#define HEXAGON_NUM_SYS_CTRL_REGS 64
|
||||
#define HEXAGON_NUM_PREDICATE_REGS 4
|
||||
#define HEXAGON_NUM_GUEST_REGS 32
|
||||
|
||||
/* Specify the register sub-ranges. */
|
||||
#define HEXAGON_SUBREGS (16)
|
||||
#define HEXAGON_SUBREGS_LO (0)
|
||||
#define HEXAGON_SUBREGS_HI (16)
|
||||
#define HEXAGON_SUBREGS_TO(r, p) (((r) < HEXAGON_SUBREGS_HI \
|
||||
? (r) \
|
||||
: (r) - HEXAGON_SUBREGS / 2) \
|
||||
/ ((p)? 2: 1))
|
||||
#define HEXAGON_SUBREGS_FROM(r, p) ((r) * ((p)? 2: 1) < HEXAGON_SUBREGS / 2 \
|
||||
? (r) * ((p)? 2: 1) \
|
||||
: (r) * ((p)? 2: 1) - HEXAGON_SUBREGS / 2 + HEXAGON_SUBREGS_HI)
|
||||
|
||||
/** Slots used by some insns.
|
||||
*/
|
||||
#define HEXAGON_SLOTS_DUPLEX (0x3) /** < Paired isns. */
|
||||
#define HEXAGON_SLOTS_STORES (0x2) /** < In-order dual-stores. */
|
||||
#define HEXAGON_SLOTS_1 (0x2) /** < Slot #1. */
|
||||
#define HEXAGON_SLOTS_MEM1 (0x1) /** < Preference for single memory access. */
|
||||
|
||||
/** Insn type opcode ranges.
|
||||
*/
|
||||
#define HEXAGON_INSN_TYPE_A7 (0x70000000) /** A-type. */
|
||||
#define HEXAGON_INSN_TYPE_X8 (0x80000000) /** X-type. */
|
||||
#define HEXAGON_INSN_TYPE_A11 (0xb0000000) /** A-type. */
|
||||
#define HEXAGON_INSN_TYPE_X12 (0xc0000000) /** X-type. */
|
||||
#define HEXAGON_INSN_TYPE_X13 (0xd0000000) /** X-type. */
|
||||
#define HEXAGON_INSN_TYPE_X14 (0xe0000000) /** X-type. */
|
||||
#define HEXAGON_INSN_TYPE_A15 (0xf0000000) /** A-type. */
|
||||
#define HEXAGON_INSN_TYPE_MASK(i) ((i) & 0xf0000000) /** Insn type mask. */
|
||||
#define HEXAGON_INSN_TYPE_A(i) ((HEXAGON_INSN_TYPE_MASK (i) == HEXAGON_INSN_TYPE_A7) \
|
||||
|| (HEXAGON_INSN_TYPE_MASK (i) == HEXAGON_INSN_TYPE_A11) \
|
||||
|| (HEXAGON_INSN_TYPE_MASK (i) == HEXAGON_INSN_TYPE_A15))
|
||||
#define HEXAGON_INSN_TYPE_X(i) ((HEXAGON_INSN_TYPE_MASK (i) == HEXAGON_INSN_TYPE_X8) \
|
||||
|| (HEXAGON_INSN_TYPE_MASK (i) == HEXAGON_INSN_TYPE_X12) \
|
||||
|| (HEXAGON_INSN_TYPE_MASK (i) == HEXAGON_INSN_TYPE_X13) \
|
||||
|| (HEXAGON_INSN_TYPE_MASK (i) == HEXAGON_INSN_TYPE_X14))
|
||||
|
||||
/* Type to denote an Hexagon instruction (at least a 32 bit unsigned int). */
|
||||
typedef unsigned int hexagon_insn;
|
||||
|
||||
typedef struct _hexagon_opcode
|
||||
{
|
||||
char *syntax; /* syntax of insn */
|
||||
char *enc; /* string representing the encoding */
|
||||
int flags; /* various flag bits */
|
||||
|
||||
/* Values for `flags'. */
|
||||
|
||||
/* Return CPU number, given flag bits. */
|
||||
#define HEXAGON_CODE_CPU(b) ((b) & HEXAGON_MACH_CPU_MASK)
|
||||
/* Return MACH number, given flag bits. */
|
||||
#define HEXAGON_CODE_MACH(b) ((b) & HEXAGON_MACH_MASK)
|
||||
|
||||
/* First opcode flag bit available after machine mask
|
||||
(with room for machine/cpu). */
|
||||
#define HEXAGON_CODE_FLAG(f) ((f) << 8)
|
||||
|
||||
#define HEXAGON_CODE_IS_PREFIX (HEXAGON_CODE_FLAG (0x0001))
|
||||
#define HEXAGON_CODE_IS_DUPLEX (HEXAGON_CODE_FLAG (0x0002))
|
||||
#define HEXAGON_CODE_IS_COMPND (HEXAGON_CODE_FLAG (0x0004))
|
||||
#define HEXAGON_CODE_IS_BRANCH (HEXAGON_CODE_FLAG (0x0008))
|
||||
#define HEXAGON_CODE_IS_MEMORY (HEXAGON_CODE_FLAG (0x0010))
|
||||
#define HEXAGON_CODE_IS_LOAD (HEXAGON_CODE_FLAG (0x0020))
|
||||
#define HEXAGON_CODE_IS_STORE (HEXAGON_CODE_FLAG (0x0040))
|
||||
|
||||
/* These values are used to optimize assembly and disassembly. Each insn
|
||||
is on a list of related insns (same first letter for assembly, same
|
||||
insn code for disassembly). */
|
||||
|
||||
struct _hexagon_opcode *next_asm; /* Next instr to try during assembly. */
|
||||
struct _hexagon_opcode *next_dis; /* Next instr to try during disassembly. */
|
||||
|
||||
/* Macros to create the hash values for the lists. */
|
||||
#define HEXAGON_HASH_OPCODE(string) \
|
||||
hexagon_hash_opcode (string)
|
||||
#define HEXAGON_HASH_ICODE(insn) \
|
||||
hexagon_hash_icode (insn)
|
||||
|
||||
/* Macros to access `next_asm', `next_dis' so users needn't care about the
|
||||
underlying mechanism. */
|
||||
#define HEXAGON_CODE_NEXT_ASM(op) ((op)? (op)->next_asm: (op))
|
||||
#define HEXAGON_CODE_NEXT_DIS(op) ((op)? (op)->next_dis: (op))
|
||||
|
||||
unsigned int slots; /* Slots onto which the instruction can go */
|
||||
|
||||
unsigned int implicit; /* specifies implicit register writes */
|
||||
|
||||
/* Values for implicit register definitions */
|
||||
#define IMPLICIT_LR 0x0001
|
||||
#define IMPLICIT_SP 0x0002
|
||||
#define IMPLICIT_FP 0x0004
|
||||
#define IMPLICIT_PC 0x0008
|
||||
#define IMPLICIT_LC0 0x0010
|
||||
#define IMPLICIT_SA0 0x0020
|
||||
#define IMPLICIT_LC1 0x0040
|
||||
#define IMPLICIT_SA1 0x0080
|
||||
#define IMPLICIT_SR_OVF 0x0100
|
||||
#define IMPLICIT_P3 0x0200
|
||||
/* V3 */
|
||||
#define IMPLICIT_P0 0x0400
|
||||
/* V4 */
|
||||
#define IMPLICIT_P1 0x0800
|
||||
|
||||
unsigned int attributes;
|
||||
|
||||
/* Values for 'attributes' */
|
||||
#define A_IT_NOP 0x00000001
|
||||
#define A_RESTRICT_NOSRMOVE 0x00000002
|
||||
#define A_RESTRICT_LOOP_LA 0x00000004
|
||||
#define A_NOTE_LA_RESTRICT A_RESTRICT_LOOP_LA
|
||||
#define A_RESTRICT_COF_MAX1 0x00000008
|
||||
#define A_RESTRICT_NOPACKET 0x00000010
|
||||
#define A_NOTE_NOPACKET A_RESTRICT_NOPACKET
|
||||
#define A_RESTRICT_NOSLOT1 0x00000020
|
||||
#define A_NOTE_NOSLOT1 A_RESTRICT_NOSLOT1
|
||||
#define A_RESTRICT_NOCOF 0x00000040
|
||||
#define A_COF 0x00000080
|
||||
#define A_RESTRICT_BRANCHADDER_MAX1 0x00000100
|
||||
#define A_NOTE_BRANCHADDER_MAX1 A_RESTRICT_BRANCHADDER_MAX1
|
||||
#define A_BRANCHADDER 0x00000200
|
||||
#define A_RESTRICT_SINGLE_MEM_FIRST 0x00000400
|
||||
#define CONDITIONAL_EXEC 0x00000800
|
||||
#define A_CONDEXEC CONDITIONAL_EXEC
|
||||
#define A_NOTE_CONDITIONAL CONDITIONAL_EXEC
|
||||
#define CONDITION_SENSE_INVERTED 0x00001000
|
||||
#define CONDITION_DOTNEW 0x00002000
|
||||
#define A_DOTNEW CONDITION_DOTNEW
|
||||
#define A_RESTRICT_PREFERSLOT0 0x00004000
|
||||
#define A_RESTRICT_LATEPRED 0x00008000
|
||||
#define A_NOTE_LATEPRED A_RESTRICT_LATEPRED
|
||||
/* V3 */
|
||||
#define A_RESTRICT_PACKET_AXOK 0x00010000
|
||||
#define A_NOTE_AXOK A_RESTRICT_PACKET_AXOK
|
||||
#define A_RESTRICT_PACKET_SOMEREGS_OK 0x00020000
|
||||
#define A_RELAX_COF_1ST 0x00040000
|
||||
#define A_RELAX_COF_2ND 0x00080000
|
||||
/* V4 */
|
||||
#define PACKED 0x00100000
|
||||
#define A_IT_EXTENDER 0x00200000
|
||||
#define EXTENDABLE_LOWER_CASE_IMMEDIATE 0x00400000
|
||||
#define EXTENDABLE_UPPER_CASE_IMMEDIATE 0x00800000
|
||||
#define A_RESTRICT_SLOT0ONLY 0x01000000
|
||||
#define A_STORE 0x02000000
|
||||
#define A_STOREIMMED 0x04000000
|
||||
#define A_RESTRICT_NOSLOT1_STORE 0x08000000
|
||||
#define MUST_EXTEND 0x10000000
|
||||
#define A_MUST_EXTEND MUST_EXTEND
|
||||
#define A_IT_HWLOOP 0x20000000
|
||||
#define A_RESTRICT_NOLOOPSETUP 0x40000000
|
||||
/* V5 */
|
||||
/* Yet unused */
|
||||
#define A_GUEST 0x00000000
|
||||
#define A_NOTE_GUEST 0x00000000
|
||||
#define A_EXTENDABLE 0x00000000
|
||||
#define A_EXT_LOWER_IMMED 0x00000000
|
||||
#define A_EXT_UPPER_IMMED 0x00000000
|
||||
#define A_ARCHV2 0x00000000
|
||||
#define A_ARCHV3 0x00000000
|
||||
#define A_CRSLOT23 0x00000000
|
||||
#define A_NOTE_CRSLOT23 0x00000000
|
||||
#define A_MEMSIZE_1B 0x00000000
|
||||
#define A_MEMSIZE_2B 0x00000000
|
||||
#define A_MEMSIZE_4B 0x00000000
|
||||
#define A_MEMSIZE_8B 0x00000000
|
||||
#define A_MEMLIKE 0x00000000
|
||||
#define A_IMPLICIT_WRITES_SP 0x00000000
|
||||
#define A_IMPLICIT_READS_SP 0x00000000
|
||||
#define A_IMPLICIT_READS_LR 0x00000000
|
||||
#define A_IMPLICIT_WRITES_LR 0x00000000
|
||||
#define A_IMPLICIT_WRITES_FP 0x00000000
|
||||
#define A_IMPLICIT_READS_FP 0x00000000
|
||||
#define A_IMPLICIT_READS_PC 0x00000000
|
||||
#define A_IMPLICIT_WRITES_PC 0x00000000
|
||||
#define A_IMPLICIT_READS_GP 0x00000000
|
||||
#define A_IMPLICIT_READS_CS 0x00000000
|
||||
#define A_IMPLICIT_READS_P0 0x00000000
|
||||
#define A_IMPLICIT_WRITES_P0 0x00000000
|
||||
#define A_IMPLICIT_READS_P1 0x00000000
|
||||
#define A_IMPLICIT_WRITES_P1 0x00000000
|
||||
#define A_IMPLICIT_WRITES_P3 0x00000000
|
||||
#define A_IMPLICIT_WRITES_SRBIT 0x00000000
|
||||
#define A_IMPLICIT_WRITES_LC0 0x00000000
|
||||
#define A_IMPLICIT_WRITES_LC1 0x00000000
|
||||
#define A_IMPLICIT_WRITES_SA0 0x00000000
|
||||
#define A_IMPLICIT_WRITES_SA1 0x00000000
|
||||
#define A_JUMP 0x00000000
|
||||
#define A_CJUMP 0x00000000
|
||||
#define A_NEWCMPJUMP 0x00000000
|
||||
#define A_DIRECT 0x00000000
|
||||
#define A_INDIRECT 0x00000000
|
||||
#define A_CALL 0x00000000
|
||||
#define A_ROPS_2 0x00000000
|
||||
#define A_ROPS_3 0x00000000
|
||||
#define A_MEMOP 0x00000000
|
||||
#define A_LOAD 0x00000000
|
||||
#define A_NVSTORE 0x00000000
|
||||
#define A_DOTOLD 0x00000000
|
||||
#define A_COMMUTES 0x00000000
|
||||
#define A_PRIV 0x00000000
|
||||
#define A_NOTE_PRIV 0x00000000
|
||||
#define A_SATURATE 0x00000000
|
||||
#define A_USATURATE 0x00000000
|
||||
#define A_NOTE_SR_OVF_WHEN_SATURATING 0x00000000
|
||||
#define A_BIDIRSHIFTL 0x00000000
|
||||
#define A_BIDIRSHIFTR 0x00000000
|
||||
#define A_NOTE_OOBVSHIFT 0X00000000
|
||||
#define A_ICOP 0x00000000
|
||||
#define A_INTRINSIC_RETURNS_UNSIGNED 0x00000000
|
||||
#define A_CIRCADDR 0x00000000
|
||||
#define A_BREVADDR 0x00000000
|
||||
#define A_IT_MPY 0x00000000
|
||||
#define A_IT_MPY_32 0x00000000
|
||||
#define A_NOTE_SPECIALGROUPING 0x00000000
|
||||
#define A_NOTE_PACKET_PC 0x00000000
|
||||
#define A_NOTE_PACKET_NPC 0x00000000
|
||||
#define A_NOTE_RELATIVE_ADDRESS 0x00000000
|
||||
#define A_EXCEPTION_SWI 0x00000000
|
||||
#define A_NOTE_NEWVAL_SLOT0 0x00000000
|
||||
#define A_DOTNEWVALUE 0x00000000
|
||||
#define A_FPOP 0x00000000
|
||||
#define A_FPDOUBLE 0x00000000
|
||||
#define A_FPSINGLE 0x00000000
|
||||
#define A_RET_TYPE 0x00000000
|
||||
#define A_PRED_BIT_4 0x00000000
|
||||
#define A_NOTE_COMPAT_ACCURACY 0x00000000
|
||||
#define A_MPY 0x00000000
|
||||
#define A_CACHEOP 0x00000000
|
||||
#define A_RESTRICT_SLOT1_AOK 0x00000000
|
||||
#define A_NOTE_SLOT1_AOK A_RESTRICT_SLOT1_AOK
|
||||
#define A_NOTE_DEALLOCRET 0x00000000
|
||||
#define A_HINTJR 0x00000000
|
||||
#define A_PRED_BIT_7 0x00000000
|
||||
#define A_PRED_BIT_12 0x00000000
|
||||
#define A_PRED_BIT_13 0x00000000
|
||||
#define A_NOTE_NVSLOT0 0x00000000
|
||||
#define A_NOTE_DEPRECATED 0x00000000
|
||||
#define A_HWLOOP0_SETUP 0x00000000
|
||||
#define A_HWLOOP1_SETUP 0x00000000
|
||||
#define A_DOTNEW_LOAD 0x00000000
|
||||
|
||||
/* If this opcode is mapped, then the function that performs the mapping */
|
||||
void *map;
|
||||
} hexagon_opcode;
|
||||
|
||||
typedef size_t hexagon_hash;
|
||||
|
||||
typedef struct _hexagon_operand
|
||||
{
|
||||
/* Format that will appear in the hexagon_opcode syntax */
|
||||
char *fmt;
|
||||
|
||||
/* The number of bits in the operand (may be unused for a modifier). */
|
||||
unsigned char bits;
|
||||
|
||||
/* The letter that identifies this operand in the hexagon_opcode enc string */
|
||||
char enc_letter;
|
||||
|
||||
/* For immediate arguments, the value should be shifted right by this amount */
|
||||
unsigned int shift_count;
|
||||
|
||||
/* The relocation type and that of the extension and itself after extended. */
|
||||
bfd_reloc_code_real_type reloc_type, reloc_kxer, reloc_kxed;
|
||||
|
||||
/* Various flag bits. */
|
||||
int flags;
|
||||
|
||||
/* Values for `flags'. */
|
||||
#define HEXAGON_OPERAND_IS_IMMEDIATE 0x00000001
|
||||
#define HEXAGON_OPERAND_PC_RELATIVE 0x00000002
|
||||
#define HEXAGON_OPERAND_IS_SIGNED 0x00000004
|
||||
#define HEXAGON_OPERAND_IS_PAIR 0x00000008
|
||||
#define HEXAGON_OPERAND_IS_SUBSET 0x00000010
|
||||
#define HEXAGON_OPERAND_IS_MODIFIER 0x00000020
|
||||
#define HEXAGON_OPERAND_IS_PREDICATE 0x00000040
|
||||
#define HEXAGON_OPERAND_IS_CONTROL 0x00000080
|
||||
#define HEXAGON_OPERAND_IS_SYSTEM 0x00000100
|
||||
#define HEXAGON_OPERAND_IS_LO16 0x00000200
|
||||
#define HEXAGON_OPERAND_IS_HI16 0x00000400
|
||||
#define HEXAGON_OPERAND_IS_READ 0x00000800
|
||||
#define HEXAGON_OPERAND_IS_WRITE 0x00001000
|
||||
#define HEXAGON_OPERAND_IS_MODIFIED 0x00002000
|
||||
#define HEXAGON_OPERAND_IS_NEGATIVE 0x00004000
|
||||
#define HEXAGON_OPERAND_IS_CONSTANT 0x00008000
|
||||
#define HEXAGON_OPERAND_IS_NEW 0x00010000
|
||||
#define HEXAGON_OPERAND_IS_GUEST 0x00020000
|
||||
#define HEXAGON_OPERAND_IS_REGISTER 0x00040000
|
||||
#define HEXAGON_OPERAND_IS_RNEW 0x00080000
|
||||
|
||||
#define HEXAGON_OPERAND_IS_RELAX 0x10000000
|
||||
#define HEXAGON_OPERAND_IS_KXER 0x20000000
|
||||
#define HEXAGON_OPERAND_IS_KXED 0x40000000
|
||||
#define HEXAGON_OPERAND_IS_INVALID 0x80000000
|
||||
|
||||
/* Format string and alternate format string for disassembly. */
|
||||
char *dis_fmt, *alt_fmt;
|
||||
|
||||
/* Function used to change the original insn into another semantically equivalent. */
|
||||
char *(*parse) (const struct _hexagon_operand *, hexagon_insn *,
|
||||
const hexagon_opcode *, char *, long *, int *, char **);
|
||||
} hexagon_operand;
|
||||
|
||||
typedef struct hexagon_operand_arg
|
||||
{
|
||||
const hexagon_operand *operand;
|
||||
long value;
|
||||
char string [HEXAGON_MAPPED_LEN];
|
||||
} hexagon_operand_arg;
|
||||
|
||||
typedef void (*hexagon_mapping) (char *, size_t, const hexagon_operand_arg []);
|
||||
|
||||
typedef struct hexagon_reg
|
||||
{
|
||||
const char *name;
|
||||
int reg_num;
|
||||
int flags;
|
||||
|
||||
/* Values for flags. */
|
||||
#define HEXAGON_REG_IS_READONLY (1 << 0)
|
||||
#define HEXAGON_REG_IS_WRITEONLY (1 << 1)
|
||||
#define HEXAGON_REG_IS_READWRITE (1 << 2)
|
||||
} hexagon_reg;
|
||||
|
||||
typedef struct hexagon_reg_score
|
||||
{
|
||||
char used, letter;
|
||||
#define HEXAGON_PRED_LEN (3)
|
||||
#define HEXAGON_PRED_MSK (~(-1 << HEXAGON_PRED_LEN))
|
||||
#define HEXAGON_PRED_YES (0x01)
|
||||
#define HEXAGON_PRED_NOT (0x02)
|
||||
#define HEXAGON_PRED_NEW (0x04)
|
||||
#define HEXAGON_PRED_GET(P, I) (((P) >> ((I) * HEXAGON_PRED_LEN)) & HEXAGON_PRED_MSK)
|
||||
#define HEXAGON_PRED_SET(P, I, N) \
|
||||
((HEXAGON_PRED_GET (P, I) | ((N) & HEXAGON_PRED_MSK)) << ((I) * HEXAGON_PRED_LEN))
|
||||
long pred: (HEXAGON_NUM_PREDICATE_REGS * HEXAGON_PRED_LEN);
|
||||
size_t ndx;
|
||||
} hexagon_reg_score;
|
||||
|
||||
/* Bits that say what version of cpu we have. These should be passed to
|
||||
hexagon_init_opcode_tables. At present, all there is is the cpu type. */
|
||||
|
||||
/* CPU number, given value passed to `hexagon_init_opcode_tables'. */
|
||||
#define HEXAGON_HAVE_CPU(bits) ((bits) & HEXAGON_MACH_CPU_MASK)
|
||||
/* MACH number, given value passed to `hexagon_init_opcode_tables'. */
|
||||
#define HEXAGON_HAVE_MACH(bits) ((bits) & HEXAGON_MACH_MASK)
|
||||
|
||||
extern const hexagon_operand hexagon_operands [];
|
||||
extern const size_t hexagon_operand_count;
|
||||
extern hexagon_opcode *hexagon_opcodes;
|
||||
extern size_t hexagon_opcodes_count;
|
||||
extern int hexagon_verify_hw;
|
||||
extern hexagon_insn hexagon_nop, hexagon_kext;
|
||||
|
||||
/** Packet delimeters.
|
||||
*/
|
||||
#define PACKET_BEGIN '{' /** < Beginning of packet. */
|
||||
#define PACKET_END '}' /** < End of packet. */
|
||||
#define PACKET_END_INNER ":endloop0" /** < End of inner loop. */
|
||||
#define PACKET_END_OUTER ":endloop1" /** < End of outer loop. */
|
||||
#define PACKET_PAIR ';' /** < Sub-insn separator. */
|
||||
|
||||
/** Bits 15:14 in the instruction mark boundaries.
|
||||
*/
|
||||
#define HEXAGON_END_PACKET_POS (14)
|
||||
#define HEXAGON_END_PACKET_MASK (3 << HEXAGON_END_PACKET_POS)
|
||||
#define HEXAGON_END_PACKET (3 << HEXAGON_END_PACKET_POS) /** < End of packet. */
|
||||
#define HEXAGON_END_LOOP (2 << HEXAGON_END_PACKET_POS) /** < End of loop. */
|
||||
#define HEXAGON_END_NOT (1 << HEXAGON_END_PACKET_POS) /** < Neither. */
|
||||
#define HEXAGON_END_PAIR (0 << HEXAGON_END_PACKET_POS) /** < Compound insn. */
|
||||
|
||||
/** Get, set and reset packet bits in insn.
|
||||
*/
|
||||
#define HEXAGON_END_PACKET_GET(insn) \
|
||||
((insn) & HEXAGON_END_PACKET_MASK) /** < Get */
|
||||
#define HEXAGON_END_PACKET_SET(insn, bits) \
|
||||
(((insn) & ~HEXAGON_END_PACKET_MASK) | (bits)) /** < Set */
|
||||
#define HEXAGON_END_PACKET_RESET(insn) \
|
||||
(HEXAGON_END_PACKET_SET ((insn), \
|
||||
HEXAGON_END_PACKET_GET (insn) == HEXAGON_END_PAIR \
|
||||
? HEXAGON_END_PAIR: HEXAGON_END_NOT)) /** < Reset */
|
||||
|
||||
/** Test for arch version.
|
||||
*/
|
||||
#define hexagon_if_arch_v1() (FALSE) /** < V1 (Obsolete) */
|
||||
#define hexagon_if_arch_v2() (hexagon_if_arch (HEXAGON_MACH_V2)) /** < V2 */
|
||||
#define hexagon_if_arch_v3() (hexagon_if_arch (HEXAGON_MACH_V3)) /** < V3 */
|
||||
#define hexagon_if_arch_v4() (hexagon_if_arch (HEXAGON_MACH_V4)) /** < V4 */
|
||||
#define hexagon_if_arch_v5() (hexagon_if_arch (HEXAGON_MACH_V5)) /** < V5 */
|
||||
|
||||
extern int hexagon_arch (void);
|
||||
extern int hexagon_if_arch (int);
|
||||
extern int hexagon_if_arch_kext (void);
|
||||
extern int hexagon_if_arch_pairs (void);
|
||||
extern int hexagon_if_arch_autoand (void);
|
||||
extern int hexagon_get_opcode_mach (int, int);
|
||||
extern hexagon_hash hexagon_hash_opcode (const char *);
|
||||
extern hexagon_hash hexagon_hash_icode (hexagon_insn);
|
||||
extern hexagon_insn hexagon_encode_opcode (const char *);
|
||||
extern hexagon_insn hexagon_encode_mask (char *);
|
||||
/* `hexagon_opcode_init_tables' must be called before `hexagon_xxx_supported'. */
|
||||
extern void hexagon_opcode_init_tables (int);
|
||||
extern const hexagon_opcode *hexagon_opcode_next_asm (const hexagon_opcode *);
|
||||
extern const hexagon_opcode *hexagon_opcode_lookup_asm (const char *);
|
||||
extern const hexagon_opcode *hexagon_opcode_lookup_dis (hexagon_insn);
|
||||
extern const hexagon_opcode *hexagon_lookup_insn (hexagon_insn);
|
||||
extern int hexagon_opcode_supported (const hexagon_opcode *);
|
||||
extern int hexagon_encode_operand
|
||||
(const hexagon_operand *, hexagon_insn *, const hexagon_opcode *,
|
||||
long, long *, int, int, char **);
|
||||
extern const hexagon_operand *hexagon_lookup_operand (const char *);
|
||||
extern const hexagon_operand *hexagon_lookup_reloc
|
||||
(bfd_reloc_code_real_type, int, const hexagon_opcode *);
|
||||
extern int hexagon_extract_operand
|
||||
(const hexagon_operand *, hexagon_insn, bfd_vma, char *, int *, char **);
|
||||
extern int hexagon_extract_predicate_operand
|
||||
(const hexagon_operand *, hexagon_insn, char *, int *, char **);
|
||||
extern int hexagon_extract_modifier_operand
|
||||
(const hexagon_operand *, hexagon_insn, char *, int *, char **);
|
||||
extern char *hexagon_dis_operand
|
||||
(const hexagon_operand *, hexagon_insn, bfd_vma, bfd_vma, char *, char *, char **);
|
||||
extern int hexagon_dis_opcode
|
||||
(char *, hexagon_insn, bfd_vma, const hexagon_opcode *, char **);
|
||||
extern const hexagon_operand *hexagon_operand_find_lo16 (const hexagon_operand *);
|
||||
extern const hexagon_operand *hexagon_operand_find_hi16 (const hexagon_operand *);
|
||||
extern const hexagon_operand *hexagon_operand_find
|
||||
(const hexagon_operand *, const char *);
|
||||
|
||||
/* We don't put the packet header in the opcode table */
|
||||
extern const hexagon_opcode hexagon_packet_header_opcode;
|
||||
|
||||
#endif /* OPCODES_HEXAGON_H */
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,255 @@
|
||||
/* <ctype.h> replacement macros.
|
||||
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2004,
|
||||
2005 Free Software Foundation, Inc.
|
||||
Contributed by Zack Weinberg <[email protected]>.
|
||||
|
||||
This file is part of the libiberty library.
|
||||
Libiberty is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
Libiberty 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with libiberty; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/*
|
||||
|
||||
@defvr Extension HOST_CHARSET
|
||||
This macro indicates the basic character set and encoding used by the
|
||||
host: more precisely, the encoding used for character constants in
|
||||
preprocessor @samp{#if} statements (the C "execution character set").
|
||||
It is defined by @file{safe-ctype.h}, and will be an integer constant
|
||||
with one of the following values:
|
||||
|
||||
@ftable @code
|
||||
@item HOST_CHARSET_UNKNOWN
|
||||
The host character set is unknown - that is, not one of the next two
|
||||
possibilities.
|
||||
|
||||
@item HOST_CHARSET_ASCII
|
||||
The host character set is ASCII.
|
||||
|
||||
@item HOST_CHARSET_EBCDIC
|
||||
The host character set is some variant of EBCDIC. (Only one of the
|
||||
nineteen EBCDIC varying characters is tested; exercise caution.)
|
||||
@end ftable
|
||||
@end defvr
|
||||
|
||||
@deffn Extension ISALPHA (@var{c})
|
||||
@deffnx Extension ISALNUM (@var{c})
|
||||
@deffnx Extension ISBLANK (@var{c})
|
||||
@deffnx Extension ISCNTRL (@var{c})
|
||||
@deffnx Extension ISDIGIT (@var{c})
|
||||
@deffnx Extension ISGRAPH (@var{c})
|
||||
@deffnx Extension ISLOWER (@var{c})
|
||||
@deffnx Extension ISPRINT (@var{c})
|
||||
@deffnx Extension ISPUNCT (@var{c})
|
||||
@deffnx Extension ISSPACE (@var{c})
|
||||
@deffnx Extension ISUPPER (@var{c})
|
||||
@deffnx Extension ISXDIGIT (@var{c})
|
||||
|
||||
These twelve macros are defined by @file{safe-ctype.h}. Each has the
|
||||
same meaning as the corresponding macro (with name in lowercase)
|
||||
defined by the standard header @file{ctype.h}. For example,
|
||||
@code{ISALPHA} returns true for alphabetic characters and false for
|
||||
others. However, there are two differences between these macros and
|
||||
those provided by @file{ctype.h}:
|
||||
|
||||
@itemize @bullet
|
||||
@item These macros are guaranteed to have well-defined behavior for all
|
||||
values representable by @code{signed char} and @code{unsigned char}, and
|
||||
for @code{EOF}.
|
||||
|
||||
@item These macros ignore the current locale; they are true for these
|
||||
fixed sets of characters:
|
||||
@multitable {@code{XDIGIT}} {yada yada yada yada yada yada yada yada}
|
||||
@item @code{ALPHA} @tab @kbd{A-Za-z}
|
||||
@item @code{ALNUM} @tab @kbd{A-Za-z0-9}
|
||||
@item @code{BLANK} @tab @kbd{space tab}
|
||||
@item @code{CNTRL} @tab @code{!PRINT}
|
||||
@item @code{DIGIT} @tab @kbd{0-9}
|
||||
@item @code{GRAPH} @tab @code{ALNUM || PUNCT}
|
||||
@item @code{LOWER} @tab @kbd{a-z}
|
||||
@item @code{PRINT} @tab @code{GRAPH ||} @kbd{space}
|
||||
@item @code{PUNCT} @tab @kbd{`~!@@#$%^&*()_-=+[@{]@}\|;:'",<.>/?}
|
||||
@item @code{SPACE} @tab @kbd{space tab \n \r \f \v}
|
||||
@item @code{UPPER} @tab @kbd{A-Z}
|
||||
@item @code{XDIGIT} @tab @kbd{0-9A-Fa-f}
|
||||
@end multitable
|
||||
|
||||
Note that, if the host character set is ASCII or a superset thereof,
|
||||
all these macros will return false for all values of @code{char} outside
|
||||
the range of 7-bit ASCII. In particular, both ISPRINT and ISCNTRL return
|
||||
false for characters with numeric values from 128 to 255.
|
||||
@end itemize
|
||||
@end deffn
|
||||
|
||||
@deffn Extension ISIDNUM (@var{c})
|
||||
@deffnx Extension ISIDST (@var{c})
|
||||
@deffnx Extension IS_VSPACE (@var{c})
|
||||
@deffnx Extension IS_NVSPACE (@var{c})
|
||||
@deffnx Extension IS_SPACE_OR_NUL (@var{c})
|
||||
@deffnx Extension IS_ISOBASIC (@var{c})
|
||||
These six macros are defined by @file{safe-ctype.h} and provide
|
||||
additional character classes which are useful when doing lexical
|
||||
analysis of C or similar languages. They are true for the following
|
||||
sets of characters:
|
||||
|
||||
@multitable {@code{SPACE_OR_NUL}} {yada yada yada yada yada yada yada yada}
|
||||
@item @code{IDNUM} @tab @kbd{A-Za-z0-9_}
|
||||
@item @code{IDST} @tab @kbd{A-Za-z_}
|
||||
@item @code{VSPACE} @tab @kbd{\r \n}
|
||||
@item @code{NVSPACE} @tab @kbd{space tab \f \v \0}
|
||||
@item @code{SPACE_OR_NUL} @tab @code{VSPACE || NVSPACE}
|
||||
@item @code{ISOBASIC} @tab @code{VSPACE || NVSPACE || PRINT}
|
||||
@end multitable
|
||||
@end deffn
|
||||
|
||||
*/
|
||||
|
||||
#include "ansidecl.h"
|
||||
#include <safe-ctype.h>
|
||||
#include <stdio.h> /* for EOF */
|
||||
|
||||
#if EOF != -1
|
||||
#error "<safe-ctype.h> requires EOF == -1"
|
||||
#endif
|
||||
|
||||
/* Shorthand */
|
||||
#define bl _sch_isblank
|
||||
#define cn _sch_iscntrl
|
||||
#define di _sch_isdigit
|
||||
#define is _sch_isidst
|
||||
#define lo _sch_islower
|
||||
#define nv _sch_isnvsp
|
||||
#define pn _sch_ispunct
|
||||
#define pr _sch_isprint
|
||||
#define sp _sch_isspace
|
||||
#define up _sch_isupper
|
||||
#define vs _sch_isvsp
|
||||
#define xd _sch_isxdigit
|
||||
|
||||
/* Masks. */
|
||||
#define L (const unsigned short) (lo|is |pr) /* lower case letter */
|
||||
#define XL (const unsigned short) (lo|is|xd|pr) /* lowercase hex digit */
|
||||
#define U (const unsigned short) (up|is |pr) /* upper case letter */
|
||||
#define XU (const unsigned short) (up|is|xd|pr) /* uppercase hex digit */
|
||||
#define D (const unsigned short) (di |xd|pr) /* decimal digit */
|
||||
#define P (const unsigned short) (pn |pr) /* punctuation */
|
||||
#define _ (const unsigned short) (pn|is |pr) /* underscore */
|
||||
|
||||
#define C (const unsigned short) ( cn) /* control character */
|
||||
#define Z (const unsigned short) (nv |cn) /* NUL */
|
||||
#define M (const unsigned short) (nv|sp |cn) /* cursor movement: \f \v */
|
||||
#define V (const unsigned short) (vs|sp |cn) /* vertical space: \r \n */
|
||||
#define T (const unsigned short) (nv|sp|bl|cn) /* tab */
|
||||
#define S (const unsigned short) (nv|sp|bl|pr) /* space */
|
||||
|
||||
/* Are we ASCII? */
|
||||
#if HOST_CHARSET == HOST_CHARSET_ASCII
|
||||
|
||||
const unsigned short _sch_istable[256] =
|
||||
{
|
||||
Z, C, C, C, C, C, C, C, /* NUL SOH STX ETX EOT ENQ ACK BEL */
|
||||
C, T, V, M, M, V, C, C, /* BS HT LF VT FF CR SO SI */
|
||||
C, C, C, C, C, C, C, C, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
|
||||
C, C, C, C, C, C, C, C, /* CAN EM SUB ESC FS GS RS US */
|
||||
S, P, P, P, P, P, P, P, /* SP ! " # $ % & ' */
|
||||
P, P, P, P, P, P, P, P, /* ( ) * + , - . / */
|
||||
D, D, D, D, D, D, D, D, /* 0 1 2 3 4 5 6 7 */
|
||||
D, D, P, P, P, P, P, P, /* 8 9 : ; < = > ? */
|
||||
P, XU, XU, XU, XU, XU, XU, U, /* @ A B C D E F G */
|
||||
U, U, U, U, U, U, U, U, /* H I J K L M N O */
|
||||
U, U, U, U, U, U, U, U, /* P Q R S T U V W */
|
||||
U, U, U, P, P, P, P, _, /* X Y Z [ \ ] ^ _ */
|
||||
P, XL, XL, XL, XL, XL, XL, L, /* ` a b c d e f g */
|
||||
L, L, L, L, L, L, L, L, /* h i j k l m n o */
|
||||
L, L, L, L, L, L, L, L, /* p q r s t u v w */
|
||||
L, L, L, P, P, P, P, C, /* x y z { | } ~ DEL */
|
||||
|
||||
/* high half of unsigned char is locale-specific, so all tests are
|
||||
false in "C" locale */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
const unsigned char _sch_tolower[256] =
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64,
|
||||
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
|
||||
91, 92, 93, 94, 95, 96,
|
||||
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
|
||||
123,124,125,126,127,
|
||||
|
||||
128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
|
||||
144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
|
||||
160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175,
|
||||
176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191,
|
||||
|
||||
192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
|
||||
208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
|
||||
224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
|
||||
240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255,
|
||||
};
|
||||
|
||||
const unsigned char _sch_toupper[256] =
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64,
|
||||
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
|
||||
91, 92, 93, 94, 95, 96,
|
||||
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
|
||||
123,124,125,126,127,
|
||||
|
||||
128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
|
||||
144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
|
||||
160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175,
|
||||
176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191,
|
||||
|
||||
192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
|
||||
208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
|
||||
224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
|
||||
240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255,
|
||||
};
|
||||
|
||||
#else
|
||||
# if HOST_CHARSET == HOST_CHARSET_EBCDIC
|
||||
#error "FIXME: write tables for EBCDIC"
|
||||
# else
|
||||
#error "Unrecognized host character set"
|
||||
# endif
|
||||
#endif
|
||||
@@ -643,7 +643,7 @@
|
||||
#define DF_P1_LAZYLOAD 0x00000001
|
||||
#define DF_P1_GROUPPERM 0x00000002
|
||||
|
||||
/* Flag value in in the DT_FLAGS_1 .dynamic entry. */
|
||||
/* Flag value in the DT_FLAGS_1 .dynamic entry. */
|
||||
#define DF_1_NOW 0x00000001
|
||||
#define DF_1_GLOBAL 0x00000002
|
||||
#define DF_1_GROUP 0x00000004
|
||||
|
||||
@@ -37,6 +37,7 @@ static void add_insn_to_hash_chain (CGEN_INSN_LIST *,
|
||||
CGEN_INSN_LIST **,
|
||||
unsigned int);
|
||||
|
||||
#if 0
|
||||
bfd_uint64_t
|
||||
bfd_get_bits (const void *p, int bits, bfd_boolean big_p)
|
||||
{
|
||||
@@ -59,6 +60,7 @@ bfd_get_bits (const void *p, int bits, bfd_boolean big_p)
|
||||
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
bfd_put_bits (bfd_uint64_t data, void *p, int bits, bfd_boolean big_p)
|
||||
|
||||
@@ -1054,10 +1054,12 @@ nios_cgen_assemble_insn (CGEN_CPU_DESC cd,
|
||||
|
||||
str = start;
|
||||
|
||||
#if 0
|
||||
/* Skip this insn if str doesn't look right lexically. */
|
||||
if (CGEN_INSN_RX (insn) != NULL &&
|
||||
regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
/* Allow parse/insert handlers to obtain length of insn. */
|
||||
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
|
||||
|
||||
@@ -1612,9 +1612,10 @@ nios_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian)
|
||||
void
|
||||
nios_cgen_cpu_close (CGEN_CPU_DESC cd)
|
||||
{
|
||||
unsigned int i;
|
||||
const CGEN_INSN *insns;
|
||||
|
||||
#if 0
|
||||
const CGEN_INSN *insns;
|
||||
unsigned int i;
|
||||
if (cd->macro_insn_table.init_entries)
|
||||
{
|
||||
insns = cd->macro_insn_table.init_entries;
|
||||
@@ -1630,6 +1631,7 @@ nios_cgen_cpu_close (CGEN_CPU_DESC cd)
|
||||
if (CGEN_INSN_RX (insns))
|
||||
regfree (CGEN_INSN_RX (insns));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cd->macro_insn_table.init_entries)
|
||||
free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
|
||||
|
||||
@@ -746,7 +746,6 @@ print_insn_nios (bfd_vma pc, disassemble_info *info)
|
||||
if (! cd)
|
||||
{
|
||||
const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
|
||||
//const bfd_arch_info_type *arch_type = &bfd_nios_arch;
|
||||
const char *mach_name;
|
||||
|
||||
if (!arch_type)
|
||||
|
||||
@@ -1349,15 +1349,13 @@ static const CGEN_OPCODE nios_cgen_macro_insn_opcode_table[] =
|
||||
Targets are free to override CGEN_{ASM,DIS}_HASH_P in the .opc file. */
|
||||
|
||||
static int
|
||||
asm_hash_insn_p (insn)
|
||||
const CGEN_INSN *insn;
|
||||
asm_hash_insn_p (const CGEN_INSN *insn)
|
||||
{
|
||||
return CGEN_ASM_HASH_P (insn);
|
||||
}
|
||||
|
||||
static int
|
||||
dis_hash_insn_p (insn)
|
||||
const CGEN_INSN *insn;
|
||||
dis_hash_insn_p (const CGEN_INSN *insn)
|
||||
{
|
||||
/* If building the hash table and the NO-DIS attribute is present,
|
||||
ignore. */
|
||||
@@ -1389,8 +1387,7 @@ dis_hash_insn_p (insn)
|
||||
Targets are free to override CGEN_{ASM,DIS}_HASH in the .opc file. */
|
||||
|
||||
static unsigned int
|
||||
asm_hash_insn (mnem)
|
||||
const char * mnem;
|
||||
asm_hash_insn (const char *mnem)
|
||||
{
|
||||
return CGEN_ASM_HASH (mnem);
|
||||
}
|
||||
@@ -1399,9 +1396,7 @@ asm_hash_insn (mnem)
|
||||
VALUE is the first base_insn_bitsize bits as an int in host order. */
|
||||
|
||||
static unsigned int
|
||||
dis_hash_insn (buf, value)
|
||||
const char * buf;
|
||||
CGEN_INSN_INT value;
|
||||
dis_hash_insn (const char *buf, CGEN_INSN_INT value)
|
||||
{
|
||||
return CGEN_DIS_HASH (buf, value);
|
||||
}
|
||||
@@ -1409,9 +1404,7 @@ dis_hash_insn (buf, value)
|
||||
/* Set the recorded length of the insn in the CGEN_FIELDS struct. */
|
||||
|
||||
static void
|
||||
set_fields_bitsize (fields, size)
|
||||
CGEN_FIELDS *fields;
|
||||
int size;
|
||||
set_fields_bitsize (CGEN_FIELDS *fields, int size)
|
||||
{
|
||||
CGEN_FIELDS_BITSIZE (fields) = size;
|
||||
}
|
||||
@@ -1420,8 +1413,7 @@ set_fields_bitsize (fields, size)
|
||||
This plugs the opcode entries and macro instructions into the cpu table. */
|
||||
|
||||
void
|
||||
nios_cgen_init_opcode_table (cd)
|
||||
CGEN_CPU_DESC cd;
|
||||
nios_cgen_init_opcode_table (CGEN_CPU_DESC cd)
|
||||
{
|
||||
int i;
|
||||
int num_macros = (sizeof (nios_cgen_macro_insn_table) /
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
#define STOP_CODE 0
|
||||
#define POP_TOP 1
|
||||
#define ROT_TWO 2
|
||||
#define ROT_THREE 3
|
||||
#define DUP_TOP 4
|
||||
#define ROT_FOUR 5
|
||||
#define NOP 9
|
||||
|
||||
#define UNARY_POSITIVE 10
|
||||
#define UNARY_NEGATIVE 11
|
||||
#define UNARY_NOT 12
|
||||
#define UNARY_CONVERT 13
|
||||
|
||||
#define UNARY_INVERT 15
|
||||
|
||||
#define BINARY_POWER 19
|
||||
|
||||
#define BINARY_MULTIPLY 20
|
||||
#define BINARY_DIVIDE 21
|
||||
#define BINARY_MODULO 22
|
||||
#define BINARY_ADD 23
|
||||
#define BINARY_SUBTRACT 24
|
||||
#define BINARY_SUBSCR 25
|
||||
#define BINARY_FLOOR_DIVIDE 26
|
||||
#define BINARY_TRUE_DIVIDE 27
|
||||
#define INPLACE_FLOOR_DIVIDE 28
|
||||
#define INPLACE_TRUE_DIVIDE 29
|
||||
|
||||
#define SLICE 30
|
||||
/* Also uses 31-33 */
|
||||
#define SLICE_1 31
|
||||
#define SLICE_2 32
|
||||
#define SLICE_3 33
|
||||
|
||||
#define STORE_SLICE 40
|
||||
/* Also uses 41-43 */
|
||||
#define STORE_SLICE_1 41
|
||||
#define STORE_SLICE_2 42
|
||||
#define STORE_SLICE_3 43
|
||||
|
||||
#define DELETE_SLICE 50
|
||||
/* Also uses 51-53 */
|
||||
#define DELETE_SLICE_1 51
|
||||
#define DELETE_SLICE_2 52
|
||||
#define DELETE_SLICE_3 53
|
||||
|
||||
#define STORE_MAP 54
|
||||
#define INPLACE_ADD 55
|
||||
#define INPLACE_SUBTRACT 56
|
||||
#define INPLACE_MULTIPLY 57
|
||||
#define INPLACE_DIVIDE 58
|
||||
#define INPLACE_MODULO 59
|
||||
#define STORE_SUBSCR 60
|
||||
#define DELETE_SUBSCR 61
|
||||
|
||||
#define BINARY_LSHIFT 62
|
||||
#define BINARY_RSHIFT 63
|
||||
#define BINARY_AND 64
|
||||
#define BINARY_XOR 65
|
||||
#define BINARY_OR 66
|
||||
#define INPLACE_POWER 67
|
||||
#define GET_ITER 68
|
||||
|
||||
#define PRINT_EXPR 70
|
||||
#define PRINT_ITEM 71
|
||||
#define PRINT_NEWLINE 72
|
||||
#define PRINT_ITEM_TO 73
|
||||
#define PRINT_NEWLINE_TO 74
|
||||
#define INPLACE_LSHIFT 75
|
||||
#define INPLACE_RSHIFT 76
|
||||
#define INPLACE_AND 77
|
||||
#define INPLACE_XOR 78
|
||||
#define INPLACE_OR 79
|
||||
#define BREAK_LOOP 80
|
||||
#define WITH_CLEANUP 81
|
||||
#define LOAD_LOCALS 82
|
||||
#define RETURN_VALUE 83
|
||||
#define IMPORT_STAR 84
|
||||
#define EXEC_STMT 85
|
||||
#define YIELD_VALUE 86
|
||||
#define POP_BLOCK 87
|
||||
#define END_FINALLY 88
|
||||
#define BUILD_CLASS 89
|
||||
|
||||
#define HAVE_ARGUMENT 90 /* Opcodes from here have an argument: */
|
||||
|
||||
#define STORE_NAME 90 /* Index in name list */
|
||||
#define DELETE_NAME 91 /* "" */
|
||||
#define UNPACK_SEQUENCE 92 /* Number of sequence items */
|
||||
#define FOR_ITER 93
|
||||
#define LIST_APPEND 94
|
||||
|
||||
#define STORE_ATTR 95 /* Index in name list */
|
||||
#define DELETE_ATTR 96 /* "" */
|
||||
#define STORE_GLOBAL 97 /* "" */
|
||||
#define DELETE_GLOBAL 98 /* "" */
|
||||
#define DUP_TOPX 99 /* number of items to duplicate */
|
||||
#define LOAD_CONST 100 /* Index in const list */
|
||||
#define LOAD_NAME 101 /* Index in name list */
|
||||
#define BUILD_TUPLE 102 /* Number of tuple items */
|
||||
#define BUILD_LIST 103 /* Number of list items */
|
||||
#define BUILD_SET 104 /* Number of set items */
|
||||
#define BUILD_MAP 105 /* Always zero for now */
|
||||
#define LOAD_ATTR 106 /* Index in name list */
|
||||
#define COMPARE_OP 107 /* Comparison operator */
|
||||
#define IMPORT_NAME 108 /* Index in name list */
|
||||
#define IMPORT_FROM 109 /* Index in name list */
|
||||
#define JUMP_FORWARD 110 /* Number of bytes to skip */
|
||||
|
||||
#define JUMP_IF_FALSE_OR_POP 111 /* Target byte offset from beginning
|
||||
of code */
|
||||
#define JUMP_IF_TRUE_OR_POP 112 /* "" */
|
||||
#define JUMP_ABSOLUTE 113 /* "" */
|
||||
#define POP_JUMP_IF_FALSE 114 /* "" */
|
||||
#define POP_JUMP_IF_TRUE 115 /* "" */
|
||||
|
||||
#define LOAD_GLOBAL 116 /* Index in name list */
|
||||
|
||||
#define CONTINUE_LOOP 119 /* Start of loop (absolute) */
|
||||
#define SETUP_LOOP 120 /* Target address (relative) */
|
||||
#define SETUP_EXCEPT 121 /* "" */
|
||||
#define SETUP_FINALLY 122 /* "" */
|
||||
|
||||
#define LOAD_FAST 124 /* Local variable number */
|
||||
#define STORE_FAST 125 /* Local variable number */
|
||||
#define DELETE_FAST 126 /* Local variable number */
|
||||
|
||||
#define RAISE_VARARGS 130 /* Number of raise arguments (1, 2 or 3) */
|
||||
/* CALL_FUNCTION_XXX opcodes defined below depend on this definition */
|
||||
#define CALL_FUNCTION 131 /* #args + (#kwargs<<8) */
|
||||
#define MAKE_FUNCTION 132 /* #defaults */
|
||||
#define BUILD_SLICE 133 /* Number of items */
|
||||
|
||||
#define MAKE_CLOSURE 134 /* #free vars */
|
||||
#define LOAD_CLOSURE 135 /* Load free variable from closure */
|
||||
#define LOAD_DEREF 136 /* Load and dereference from closure cell */
|
||||
#define STORE_DEREF 137 /* Store into cell */
|
||||
|
||||
/* The next 3 opcodes must be contiguous and satisfy
|
||||
(CALL_FUNCTION_VAR - CALL_FUNCTION) & 3 == 1 */
|
||||
#define CALL_FUNCTION_VAR 140 /* #args + (#kwargs<<8) */
|
||||
#define CALL_FUNCTION_KW 141 /* #args + (#kwargs<<8) */
|
||||
#define CALL_FUNCTION_VAR_KW 142 /* #args + (#kwargs<<8) */
|
||||
|
||||
#define SETUP_WITH 143
|
||||
|
||||
/* Support for opargs more than 16 bits long */
|
||||
#define EXTENDED_ARG 145
|
||||
|
||||
#define SET_ADD 146
|
||||
#define MAP_ADD 147
|
||||
|
||||
char *op_name[0xff + 1];
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
#include <r_types.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_util.h>
|
||||
#include <r_asm.h>
|
||||
|
||||
#include "opcode.h"
|
||||
|
||||
typedef enum {
|
||||
TYPE_ASCII = 'a',
|
||||
TYPE_ASCII_INTERNED = 'A',
|
||||
TYPE_BINARY_COMPLEX = 'y',
|
||||
TYPE_BINARY_FLOAT = 'g',
|
||||
TYPE_CODE_v0 = 'C',
|
||||
TYPE_CODE_v1 = 'c',
|
||||
TYPE_COMPLEX = 'x',
|
||||
TYPE_DICT = '{',
|
||||
TYPE_ELLIPSIS = '.',
|
||||
TYPE_FALSE = 'F',
|
||||
TYPE_FLOAT = 'f',
|
||||
TYPE_FROZENSET = '>',
|
||||
TYPE_INT64 = 'I',
|
||||
TYPE_INTERNED = 't',
|
||||
TYPE_INT = 'i',
|
||||
TYPE_LIST = '[',
|
||||
TYPE_LONG = 'l',
|
||||
TYPE_NONE = 'N',
|
||||
TYPE_NULL = '0',
|
||||
TYPE_REF = 'r',
|
||||
TYPE_SET = '<',
|
||||
TYPE_SHORT_ASCII_INTERNED = 'Z',
|
||||
TYPE_SHORT_ASCII = 'z',
|
||||
TYPE_SMALL_TUPLE = ')',
|
||||
TYPE_STOPITER = 'S',
|
||||
TYPE_STRINGREF = 'R',
|
||||
TYPE_STRING = 's',
|
||||
TYPE_TRUE = 'T',
|
||||
TYPE_TUPLE = '(',
|
||||
TYPE_UNICODE = 'u',
|
||||
TYPE_UNKNOWN = '?',
|
||||
} pyc_marshal_type;
|
||||
|
||||
typedef enum {
|
||||
FLAG_REF = '\x80',
|
||||
} pyc_marshal_flag;
|
||||
|
||||
typedef struct {
|
||||
pyc_marshal_type type;
|
||||
void *data;
|
||||
} pyc_object;
|
||||
|
||||
typedef struct {
|
||||
ut32 argcount;
|
||||
ut32 kwonlyargcount;
|
||||
ut32 nlocals;
|
||||
ut32 stacksize;
|
||||
ut32 flags;
|
||||
pyc_object *code;
|
||||
pyc_object *consts;
|
||||
pyc_object *names;
|
||||
pyc_object *varnames;
|
||||
pyc_object *freevars;
|
||||
pyc_object *cellvars;
|
||||
pyc_object *filename;
|
||||
pyc_object *name;
|
||||
ut32 firstlineno;
|
||||
pyc_object *lnotab;
|
||||
st64 start_offset;
|
||||
st64 end_offset;
|
||||
} pyc_code_object;
|
||||
|
||||
char *parse_arg (ut8 op, ut32 oparg, RList *names, RList *consts, RList *varnames, RList *interned_table);
|
||||
int r_pyc_disasm (RAsmOp *op, const ut8 *buf, RList *cobjs, RList *interned_table, ut64 pc);
|
||||
char *generic_array_obj_to_string (RList *l);
|
||||
void dump_cobj (pyc_code_object *c);
|
||||
void init_opname_table ();
|
||||
void dump (RList *l);
|
||||
@@ -1,307 +0,0 @@
|
||||
#include "pyc_dis.h"
|
||||
|
||||
void init_opname_table () {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 0xff+1; i++)
|
||||
op_name[i] = NULL;
|
||||
|
||||
op_name[STOP_CODE] = "STOP_CODE";
|
||||
op_name[POP_TOP] = "POP_TOP";
|
||||
op_name[ROT_TWO] = "ROT_TWO";
|
||||
op_name[ROT_THREE] = "ROT_THREE";
|
||||
op_name[DUP_TOP] = "DUP_TOP";
|
||||
op_name[ROT_FOUR] = "ROT_FOUR";
|
||||
op_name[NOP] = "NOP";
|
||||
op_name[UNARY_POSITIVE] = "UNARY_POSITIVE";
|
||||
op_name[UNARY_NEGATIVE] = "UNARY_NEGATIVE";
|
||||
op_name[UNARY_NOT] = "UNARY_NOT";
|
||||
op_name[UNARY_CONVERT] = "UNARY_CONVERT";
|
||||
op_name[UNARY_INVERT] = "UNARY_INVERT";
|
||||
op_name[BINARY_POWER] = "BINARY_POWER";
|
||||
op_name[BINARY_MULTIPLY] = "BINARY_MULTIPLY";
|
||||
op_name[BINARY_DIVIDE] = "BINARY_DIVIDE";
|
||||
op_name[BINARY_MODULO] = "BINARY_MODULO";
|
||||
op_name[BINARY_ADD] = "BINARY_ADD";
|
||||
op_name[BINARY_SUBTRACT] = "BINARY_SUBTRACT";
|
||||
op_name[BINARY_SUBSCR] = "BINARY_SUBSCR";
|
||||
op_name[BINARY_FLOOR_DIVIDE] = "BINARY_FLOOR_DIVIDE";
|
||||
op_name[BINARY_TRUE_DIVIDE] = "BINARY_TRUE_DIVIDE";
|
||||
op_name[INPLACE_FLOOR_DIVIDE] = "INPLACE_FLOOR_DIVIDE";
|
||||
op_name[INPLACE_TRUE_DIVIDE] = "INPLACE_TRUE_DIVIDE";
|
||||
op_name[SLICE] = "SLICE";
|
||||
op_name[SLICE_1] = "SLICE_1";
|
||||
op_name[SLICE_2] = "SLICE_2";
|
||||
op_name[SLICE_3] = "SLICE_3";
|
||||
op_name[STORE_SLICE] = "STORE_SLICE";
|
||||
op_name[STORE_SLICE_1] = "STORE_SLICE_1";
|
||||
op_name[STORE_SLICE_2] = "STORE_SLICE_2";
|
||||
op_name[STORE_SLICE_3] = "STORE_SLICE_3";
|
||||
op_name[DELETE_SLICE] = "DELETE_SLICE";
|
||||
op_name[DELETE_SLICE_1] = "DELETE_SLICE_1";
|
||||
op_name[DELETE_SLICE_2] = "DELETE_SLICE_2";
|
||||
op_name[DELETE_SLICE_3] = "DELETE_SLICE_3";
|
||||
op_name[STORE_MAP] = "STORE_MAP";
|
||||
op_name[INPLACE_ADD] = "INPLACE_ADD";
|
||||
op_name[INPLACE_SUBTRACT] = "INPLACE_SUBTRACT";
|
||||
op_name[INPLACE_MULTIPLY] = "INPLACE_MULTIPLY";
|
||||
op_name[INPLACE_DIVIDE] = "INPLACE_DIVIDE";
|
||||
op_name[INPLACE_MODULO] = "INPLACE_MODULO";
|
||||
op_name[STORE_SUBSCR] = "STORE_SUBSCR";
|
||||
op_name[DELETE_SUBSCR] = "DELETE_SUBSCR";
|
||||
op_name[BINARY_LSHIFT] = "BINARY_LSHIFT";
|
||||
op_name[BINARY_RSHIFT] = "BINARY_RSHIFT";
|
||||
op_name[BINARY_AND] = "BINARY_AND";
|
||||
op_name[BINARY_XOR] = "BINARY_XOR";
|
||||
op_name[BINARY_OR] = "BINARY_OR";
|
||||
op_name[INPLACE_POWER] = "INPLACE_POWER";
|
||||
op_name[GET_ITER] = "GET_ITER";
|
||||
op_name[PRINT_EXPR] = "PRINT_EXPR";
|
||||
op_name[PRINT_ITEM] = "PRINT_ITEM";
|
||||
op_name[PRINT_NEWLINE] = "PRINT_NEWLINE";
|
||||
op_name[PRINT_ITEM_TO] = "PRINT_ITEM_TO";
|
||||
op_name[PRINT_NEWLINE_TO] = "PRINT_NEWLINE_TO";
|
||||
op_name[INPLACE_LSHIFT] = "INPLACE_LSHIFT";
|
||||
op_name[INPLACE_RSHIFT] = "INPLACE_RSHIFT";
|
||||
op_name[INPLACE_AND] = "INPLACE_AND";
|
||||
op_name[INPLACE_XOR] = "INPLACE_XOR";
|
||||
op_name[INPLACE_OR] = "INPLACE_OR";
|
||||
op_name[BREAK_LOOP] = "BREAK_LOOP";
|
||||
op_name[WITH_CLEANUP] = "WITH_CLEANUP";
|
||||
op_name[LOAD_LOCALS] = "LOAD_LOCALS";
|
||||
op_name[RETURN_VALUE] = "RETURN_VALUE";
|
||||
op_name[IMPORT_STAR] = "IMPORT_STAR";
|
||||
op_name[EXEC_STMT] = "EXEC_STMT";
|
||||
op_name[YIELD_VALUE] = "YIELD_VALUE";
|
||||
op_name[POP_BLOCK] = "POP_BLOCK";
|
||||
op_name[END_FINALLY] = "END_FINALLY";
|
||||
op_name[BUILD_CLASS] = "BUILD_CLASS";
|
||||
op_name[HAVE_ARGUMENT] = "HAVE_ARGUMENT";
|
||||
op_name[STORE_NAME] = "STORE_NAME";
|
||||
op_name[DELETE_NAME] = "DELETE_NAME";
|
||||
op_name[UNPACK_SEQUENCE] = "UNPACK_SEQUENCE";
|
||||
op_name[FOR_ITER] = "FOR_ITER";
|
||||
op_name[LIST_APPEND] = "LIST_APPEND";
|
||||
op_name[STORE_ATTR] = "STORE_ATTR";
|
||||
op_name[DELETE_ATTR] = "DELETE_ATTR";
|
||||
op_name[STORE_GLOBAL] = "STORE_GLOBAL";
|
||||
op_name[DELETE_GLOBAL] = "DELETE_GLOBAL";
|
||||
op_name[DUP_TOPX] = "DUP_TOPX";
|
||||
op_name[LOAD_CONST] = "LOAD_CONST";
|
||||
op_name[LOAD_NAME] = "LOAD_NAME";
|
||||
op_name[BUILD_TUPLE] = "BUILD_TUPLE";
|
||||
op_name[BUILD_LIST] = "BUILD_LIST";
|
||||
op_name[BUILD_SET] = "BUILD_SET";
|
||||
op_name[BUILD_MAP] = "BUILD_MAP";
|
||||
op_name[LOAD_ATTR] = "LOAD_ATTR";
|
||||
op_name[COMPARE_OP] = "COMPARE_OP";
|
||||
op_name[IMPORT_NAME] = "IMPORT_NAME";
|
||||
op_name[IMPORT_FROM] = "IMPORT_FROM";
|
||||
op_name[JUMP_FORWARD] = "JUMP_FORWARD";
|
||||
op_name[JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP";
|
||||
op_name[JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP";
|
||||
op_name[JUMP_ABSOLUTE] = "JUMP_ABSOLUTE";
|
||||
op_name[POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE";
|
||||
op_name[POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE";
|
||||
op_name[LOAD_GLOBAL] = "LOAD_GLOBAL";
|
||||
op_name[CONTINUE_LOOP] = "CONTINUE_LOOP";
|
||||
op_name[SETUP_LOOP] = "SETUP_LOOP";
|
||||
op_name[SETUP_EXCEPT] = "SETUP_EXCEPT";
|
||||
op_name[SETUP_FINALLY] = "SETUP_FINALLY";
|
||||
op_name[LOAD_FAST] = "LOAD_FAST";
|
||||
op_name[STORE_FAST] = "STORE_FAST";
|
||||
op_name[DELETE_FAST] = "DELETE_FAST";
|
||||
op_name[RAISE_VARARGS] = "RAISE_VARARGS";
|
||||
op_name[CALL_FUNCTION] = "CALL_FUNCTION";
|
||||
op_name[MAKE_FUNCTION] = "MAKE_FUNCTION";
|
||||
op_name[BUILD_SLICE] = "BUILD_SLICE";
|
||||
op_name[MAKE_CLOSURE] = "MAKE_CLOSURE";
|
||||
op_name[LOAD_CLOSURE] = "LOAD_CLOSURE";
|
||||
op_name[LOAD_DEREF] = "LOAD_DEREF";
|
||||
op_name[STORE_DEREF] = "STORE_DEREF";
|
||||
op_name[CALL_FUNCTION_VAR] = "CALL_FUNCTION_VAR";
|
||||
op_name[CALL_FUNCTION_KW] = "CALL_FUNCTION_KW";
|
||||
op_name[CALL_FUNCTION_VAR_KW] = "CALL_FUNCTION_VAR_KW";
|
||||
op_name[SETUP_WITH] = "SETUP_WITH";
|
||||
op_name[EXTENDED_ARG] = "EXTENDED_ARG";
|
||||
op_name[SET_ADD] = "SET_ADD";
|
||||
op_name[MAP_ADD] = "MAP_ADD";
|
||||
}
|
||||
|
||||
int r_pyc_disasm (RAsmOp *opstruct, const ut8 *code, RList *cobjs, RList *interned_table, ut64 pc) {
|
||||
pyc_code_object *cobj = NULL, *t = NULL;
|
||||
ut32 extended_arg = 0, i = 0, oparg;
|
||||
st64 start_offset, end_offset;
|
||||
RListIter *iter = NULL;
|
||||
|
||||
char *name = NULL;
|
||||
char *arg = NULL;
|
||||
RList *varnames;
|
||||
RList *consts;
|
||||
RList *names;
|
||||
ut8 op;
|
||||
|
||||
r_list_foreach (cobjs, iter, t) {
|
||||
start_offset = t->start_offset;
|
||||
end_offset = t->end_offset;
|
||||
if (pc > start_offset && pc < end_offset) {
|
||||
cobj = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cobj != NULL) {
|
||||
/* TODO: adding line number and offset */
|
||||
varnames = cobj->varnames->data;
|
||||
consts = cobj->consts->data;
|
||||
names = cobj->names->data;
|
||||
|
||||
op = code[i];
|
||||
i += 1;
|
||||
name = op_name[op];
|
||||
r_strbuf_set (&opstruct->buf_asm, name);
|
||||
if (name == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (op >= HAVE_ARGUMENT) {
|
||||
oparg = code[i] + code[i+1]*256 + extended_arg;
|
||||
extended_arg = 0;
|
||||
i += 2;
|
||||
if (op == EXTENDED_ARG)
|
||||
extended_arg = oparg*65536;
|
||||
arg = parse_arg (op, oparg, names, consts, varnames, interned_table);
|
||||
if (arg != NULL) {
|
||||
r_strbuf_appendf (&opstruct->buf_asm, "%20s", arg);
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *parse_arg (ut8 op, ut32 oparg, RList *names, RList *consts, RList *varnames, RList *interned_table) {
|
||||
pyc_object *t = NULL;
|
||||
char *arg = NULL;
|
||||
|
||||
switch (op) {
|
||||
case DUP_TOPX:
|
||||
case UNPACK_SEQUENCE:
|
||||
case BUILD_TUPLE:
|
||||
case BUILD_LIST: //checked
|
||||
case BUILD_SET:
|
||||
case JUMP_FORWARD:
|
||||
case CONTINUE_LOOP:
|
||||
case SETUP_LOOP:
|
||||
case BUILD_SLICE:
|
||||
case CALL_FUNCTION:
|
||||
case POP_JUMP_IF_FALSE:
|
||||
case POP_JUMP_IF_TRUE:
|
||||
case JUMP_ABSOLUTE:
|
||||
case JUMP_IF_TRUE_OR_POP:
|
||||
case JUMP_IF_FALSE_OR_POP:
|
||||
case LOAD_CLOSURE:
|
||||
case LOAD_DEREF:
|
||||
case CALL_FUNCTION_KW:
|
||||
arg = r_str_newf ("%u", oparg);
|
||||
break;
|
||||
case LOAD_FAST:
|
||||
case STORE_FAST:
|
||||
case DELETE_FAST:
|
||||
t = (pyc_object*)r_list_get_n (varnames, oparg);
|
||||
if (t == NULL)
|
||||
return NULL;
|
||||
arg = t->data;
|
||||
break;
|
||||
case LOAD_CONST:
|
||||
t = (pyc_object*)r_list_get_n (consts, oparg);
|
||||
if (t == NULL)
|
||||
return NULL;
|
||||
switch (t->type) {
|
||||
case TYPE_CODE_v1:
|
||||
arg = strdup("CodeObject");
|
||||
break;
|
||||
case TYPE_TUPLE:
|
||||
arg = generic_array_obj_to_string (t->data);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
case TYPE_INTERNED:
|
||||
case TYPE_STRINGREF:
|
||||
arg = r_str_newf ("'%s'", t->data);
|
||||
break;
|
||||
default:
|
||||
arg = t->data;
|
||||
}
|
||||
break;
|
||||
case STORE_NAME:
|
||||
case STORE_ATTR:
|
||||
case LOAD_NAME:
|
||||
case LOAD_ATTR:
|
||||
case IMPORT_NAME:
|
||||
case IMPORT_FROM:
|
||||
case LOAD_GLOBAL:
|
||||
t = (pyc_object*)r_list_get_n (names, oparg);
|
||||
if (t == NULL)
|
||||
return NULL;
|
||||
arg = t->data;
|
||||
break;
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
/* for debugging purpose */
|
||||
void dump (RList *l) {
|
||||
RListIter *it;
|
||||
pyc_object *e = NULL;
|
||||
|
||||
r_list_foreach (l, it, e) {
|
||||
if (e->type == TYPE_TUPLE) {
|
||||
eprintf ("[TYPE_TUPLE] %s\n", generic_array_obj_to_string(e->data));
|
||||
return;
|
||||
}
|
||||
eprintf("[DATA] %s\n", (char *)e->data);
|
||||
}
|
||||
}
|
||||
|
||||
char *generic_array_obj_to_string (RList *l) {
|
||||
RListIter *iter = NULL;
|
||||
pyc_object *e = NULL;
|
||||
ut32 size = 256, used = 0;
|
||||
char *r = NULL, *buf = NULL;
|
||||
|
||||
buf = (char*)calloc (1024, 0);
|
||||
r_list_foreach (l, iter, e) {
|
||||
while ( !(strlen (e->data) < size) ) {
|
||||
size *= 2;
|
||||
buf = realloc (buf, used + size);
|
||||
if (!buf) {
|
||||
eprintf ("generic_array_obj_to_string cannot request more memory");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
strcat (buf, e->data);
|
||||
strcat (buf, ",");
|
||||
size -= strlen (e->data) + 1;
|
||||
used += strlen (e->data) + 1;
|
||||
}
|
||||
/* remove last , */
|
||||
buf[ strlen(buf)-1 ] = '\0';
|
||||
r = r_str_newf ("(%s)", buf);
|
||||
free(buf);
|
||||
return r;
|
||||
}
|
||||
|
||||
void dump_cobj (pyc_code_object *c) {
|
||||
eprintf("[DUMP]\n");
|
||||
eprintf("name: %s\n", (char *)c->name->data);
|
||||
eprintf("const_start\n");
|
||||
dump(c->consts->data);
|
||||
eprintf("consts_end\n");
|
||||
|
||||
eprintf("names_start\n");
|
||||
dump(c->names->data);
|
||||
eprintf("names_end\n");
|
||||
|
||||
eprintf("varnames_start\n");
|
||||
dump(c->varnames->data);
|
||||
eprintf("varnames_end\n");
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
#include <r_types.h>
|
||||
|
||||
#define SPC_OP 0
|
||||
#define SPC_ARG8_1 1
|
||||
#define SPC_ARG8_2 2
|
||||
#define SPC_ARG16 3
|
||||
|
||||
typedef struct spc_700_op_t {
|
||||
char *name;
|
||||
ut8 type;
|
||||
} Spc700Op;
|
||||
|
||||
static const Spc700Op spc_op_table[] = {
|
||||
{"nop", SPC_OP},
|
||||
{"call [0xffde]", SPC_OP},
|
||||
{"set1 0x%02x.0", SPC_ARG8_1},
|
||||
{"bbs 0x%02x.0,0x%02x", SPC_ARG8_2},
|
||||
{"or A,0x%02x", SPC_ARG8_1},
|
||||
{"or A,!0x%04x", SPC_ARG16},
|
||||
{"or A,(X)", SPC_OP},
|
||||
{"or A,[0x%02x+X]", SPC_ARG8_1},
|
||||
{"or A,#0x%02x", SPC_ARG8_1},
|
||||
{"or 0x%02x,0x%02x", SPC_ARG8_2},
|
||||
{"or1 C,0x%02x.0x%02x", SPC_ARG8_2},
|
||||
{"asl 0x%02x", SPC_ARG8_1},
|
||||
{"asl !0x%04x", SPC_ARG16},
|
||||
{"push psw", SPC_OP},
|
||||
{"tset1 !0x%04x", SPC_ARG16},
|
||||
{"brk", SPC_OP},
|
||||
{"bpl 0x%02x", SPC_ARG8_1},
|
||||
{"call [0xffdc]", SPC_OP},
|
||||
{"clr1 0x%02x,0", SPC_ARG8_1},
|
||||
{"bbc 0x%02x.0,0x%02x", SPC_ARG8_2},
|
||||
{"or A,0x%02x+X", SPC_ARG8_1},
|
||||
{"or A,!0x%04x+X", SPC_ARG8_1},
|
||||
{"or A,!0x%04x+Y", SPC_ARG16},
|
||||
{"or A,[0x%02x]+Y", SPC_ARG8_1},
|
||||
{"or 0x%02x,#0x%02x", SPC_ARG8_2},
|
||||
{"or (X),(Y)", SPC_OP},
|
||||
{"decw 0x%02x", SPC_ARG8_1},
|
||||
{"asl 0x%02x+X", SPC_ARG8_1},
|
||||
{"asl A", SPC_OP},
|
||||
{"dec X", SPC_OP},
|
||||
{"cmp X,!0x%04x", SPC_ARG16},
|
||||
{"jmp [!0x%04x+X]", SPC_ARG16},
|
||||
{"clrp", SPC_OP},
|
||||
{"call [0xffda]", SPC_OP},
|
||||
{"set1 0x%02x.1", SPC_ARG8_1},
|
||||
{"bbs 0x%02x.1,0x%02x", SPC_ARG8_2},
|
||||
{"and A,0x%02x", SPC_ARG8_1},
|
||||
{"and A,!0x%04x", SPC_ARG16},
|
||||
{"and A,(X)", SPC_OP},
|
||||
{"and A,[0x%02x+X]", SPC_ARG8_1},
|
||||
{"and A,#0x%02x", SPC_ARG8_1},
|
||||
{"and 0x%02x,0x%02x", SPC_ARG8_2},
|
||||
{"or1 C,/0x%02x.0x%02x", SPC_ARG8_2},
|
||||
{"rol 0x%02x", SPC_ARG8_1},
|
||||
{"rol !0x%04x", SPC_ARG16},
|
||||
{"push A", SPC_OP},
|
||||
{"cbne 0x%02x,0x%02x", SPC_ARG8_2},
|
||||
{"bra 0x%02x", SPC_ARG8_1},
|
||||
{"bmi 0x%02x", SPC_ARG8_1},
|
||||
{"call [0xffd8]", SPC_OP},
|
||||
{"clr1 0x%02x.1", SPC_ARG8_1},
|
||||
{"bbc 0x%02x.1,0x%02x", SPC_ARG8_2},
|
||||
{"and A,0x%02x+X", SPC_ARG8_1},
|
||||
{"and A,!0x%04x+X", SPC_ARG16},
|
||||
{"and A,!0x%04x+Y", SPC_ARG16},
|
||||
{"and A,[0x%02x]+Y", SPC_ARG8_1},
|
||||
{"and 0x%02x,#0x%02x", SPC_ARG8_2},
|
||||
{"and (X),(Y)", SPC_OP},
|
||||
{"incw 0x%02x", SPC_ARG8_1},
|
||||
{"rol 0x%02x+X", SPC_ARG8_1},
|
||||
{"rol A", SPC_OP},
|
||||
{"inc X", SPC_OP},
|
||||
{"cmp X,0x%02x", SPC_ARG8_1},
|
||||
{"call !0x%04x", SPC_ARG16},
|
||||
{"call [0xffd6]", SPC_OP},
|
||||
{"set1 0x%02x.2", SPC_ARG8_1},
|
||||
{"bbs 0x%02x.2,0x%02x", SPC_ARG8_2},
|
||||
{"setp", SPC_OP},
|
||||
{"eor A,0x%02x", SPC_ARG8_1},
|
||||
{"eor A,!0x%04x", SPC_ARG16},
|
||||
{"eor A,(X)", SPC_OP},
|
||||
{"eor A,[0x%02x+X]", SPC_ARG8_1},
|
||||
{"eor A,#0x%02x", SPC_ARG8_1},
|
||||
{"eor 0x%02x,0x%02x", SPC_ARG8_2},
|
||||
{"and1 C,0x%02x.0x%02x", SPC_ARG8_2},
|
||||
{"lsr 0x%02x", SPC_ARG8_1},
|
||||
{"lsr !0x%04x", SPC_ARG16},
|
||||
{"push X", SPC_OP},
|
||||
{"tclr1 !0x%04x", SPC_ARG16},
|
||||
{"pcall 0x%02x", SPC_ARG8_1},
|
||||
{"bvc 0x%02x", SPC_ARG8_1},
|
||||
{"call [0xffd4]", SPC_OP},
|
||||
{"clr1 0x%02x.2", SPC_ARG8_1},
|
||||
{"bbc 0x%02x.2,0x%02x", SPC_ARG8_2},
|
||||
{"eor A,0x%02x+X", SPC_ARG8_1},
|
||||
{"eor A,!0x%04x+X", SPC_ARG16},
|
||||
{"eor A,!0x%04x+Y", SPC_ARG16},
|
||||
{"eor A,[0x%02x]+Y", SPC_ARG8_1},
|
||||
{"eor 0x%02x,#0x%02x", SPC_ARG8_2},
|
||||
{"eor (X),(Y)", SPC_OP},
|
||||
{"cmpw YA,0x%02x", SPC_ARG8_1},
|
||||
{"lsr 0x%02x+X", SPC_ARG8_1},
|
||||
{"lsr A", SPC_OP},
|
||||
{"mov X,A", SPC_OP},
|
||||
{"cmp Y,!0x%04x", SPC_ARG16},
|
||||
{"jmp !0x%04x", SPC_ARG16},
|
||||
{"clrc", SPC_OP},
|
||||
{"call [0xffd2]", SPC_OP},
|
||||
{"set1 0x%02x.3", SPC_ARG8_1},
|
||||
{"bbs 0x%02x.3,0x%02x", SPC_ARG8_2},
|
||||
{"cmp A,0x%02x", SPC_ARG8_1},
|
||||
{"cmp A,!0x%04x", SPC_ARG16},
|
||||
{"cmp A,(X)", SPC_OP},
|
||||
{"cmp A,[0x%02x+X]", SPC_ARG8_1},
|
||||
{"cmp A,#0x%02x", SPC_ARG8_1},
|
||||
{"cmp 0x%02x,0x%02x", SPC_ARG8_2},
|
||||
{"and1 C,/0x%02x.0x%02x", SPC_ARG8_2},
|
||||
{"ror 0x%02x", SPC_ARG8_1},
|
||||
{"ror !0x%04x", SPC_ARG16},
|
||||
{"push Y", SPC_OP},
|
||||
{"dbnz 0x%02x,0x%02x", SPC_ARG8_2},
|
||||
{"ret", SPC_OP},
|
||||
{"bvs 0x%02x", SPC_ARG8_1},
|
||||
{"call [0xffd0]", SPC_OP},
|
||||
{"clr1 0x%02x.3", SPC_ARG8_1},
|
||||
{"bbc 0x%02x.3,0x%02x", SPC_ARG8_2},
|
||||
{"cmp A,0x%02x+X", SPC_ARG8_1},
|
||||
{"cmp A,!0x%04x+X", SPC_ARG16},
|
||||
{"cmp A,!0x%04x+Y", SPC_ARG16},
|
||||
{"cmp A,[0x%02x]+Y", SPC_ARG8_1},
|
||||
{"cmp 0x%02x,#0x%02x", SPC_ARG8_2},
|
||||
{"cmp (X),(Y)", SPC_OP},
|
||||
{"addw YA,0x%02x", SPC_ARG8_1},
|
||||
{"ror 0x%02x+X", SPC_ARG8_1},
|
||||
{"ror A", SPC_OP},
|
||||
{"mov A,X", SPC_OP},
|
||||
{"cmp Y,0x%02x", SPC_ARG8_1},
|
||||
{"ret1", SPC_OP},
|
||||
{"setc", SPC_OP},
|
||||
{"call [0xffce]", SPC_OP},
|
||||
{"set1 0x%02x.4", SPC_ARG8_1},
|
||||
{"bbs 0x%02x.4,0x%02x", SPC_ARG8_2},
|
||||
{"adc A,0x%02x", SPC_ARG8_1},
|
||||
{"adc A,!0x%04x", SPC_ARG16},
|
||||
{"adc A,(X)", SPC_OP},
|
||||
{"adc A,[0x%02x+X]", SPC_ARG8_1},
|
||||
{"adc A,#0x%02x", SPC_ARG8_1},
|
||||
{"adc 0x%02x,0x%02x", SPC_ARG8_2},
|
||||
{"eor1 C,0x%02x.0x%02x", SPC_ARG8_2},
|
||||
{"dec 0x%02x", SPC_ARG8_1},
|
||||
{"dec !0x%04x", SPC_ARG16},
|
||||
{"mov Y,#0x%02x", SPC_ARG8_1},
|
||||
{"pop psw", SPC_OP},
|
||||
{"mov 0x%02x,#0x%02x", SPC_ARG8_2},
|
||||
{"bcc 0x%02x", SPC_ARG8_1},
|
||||
{"call [0xffcc]", SPC_OP},
|
||||
{"clr1 0x%02x.4", SPC_ARG8_1},
|
||||
{"bbc 0x%02x.4,0x%02x", SPC_ARG8_2},
|
||||
{"adc A,0x%02x+X", SPC_ARG8_1},
|
||||
{"adc A,!0x%04x+X", SPC_ARG16},
|
||||
{"adc A,!0x%04x+Y", SPC_ARG16},
|
||||
{"adc A,[0x%02x]+Y", SPC_ARG8_1},
|
||||
{"adc 0x%02x,#0x%02x", SPC_ARG8_2},
|
||||
{"adc (X),(Y)", SPC_OP},
|
||||
{"subw YA,0x%02x", SPC_ARG8_1},
|
||||
{"dec 0x%02x+X", SPC_ARG8_1},
|
||||
{"dec A", SPC_OP},
|
||||
{"mov X,SP", SPC_OP},
|
||||
{"div YA,X", SPC_OP},
|
||||
{"xcn A", SPC_OP},
|
||||
{"ei", SPC_OP},
|
||||
{"call [0xffca]", SPC_OP},
|
||||
{"set1 0x%02x.5", SPC_ARG8_1},
|
||||
{"bbs 0x%02x.5,0x%02x", SPC_ARG8_2},
|
||||
{"sbc A,0x%02x", SPC_ARG8_1},
|
||||
{"sbc A,!0x%04x", SPC_ARG16},
|
||||
{"sbc A,(X)", SPC_OP},
|
||||
{"sbc A,[0x%02x+X]", SPC_ARG8_1},
|
||||
{"sbc A,#0x%02x", SPC_ARG8_1},
|
||||
{"sbc 0x%02x,0x%02x", SPC_ARG8_2},
|
||||
{"mov1 C,0x%02x.0x%02x", SPC_ARG8_2},
|
||||
{"inc 0x%02x", SPC_ARG8_1},
|
||||
{"inc !0x%04x", SPC_ARG16},
|
||||
{"cmp Y,#0x%02x", SPC_ARG8_1},
|
||||
{"pop A", SPC_OP},
|
||||
{"mov (X)+,A", SPC_OP},
|
||||
{"bcs 0x%02x", SPC_ARG8_1},
|
||||
{"call [0xffc8]", SPC_OP},
|
||||
{"clr1 0x%02x.5", SPC_ARG8_1},
|
||||
{"bbc 0x%02x.5,0x%02x", SPC_ARG8_2},
|
||||
{"sbc A,0x%02x+X", SPC_ARG8_1},
|
||||
{"sbc A,!0x%04x+X", SPC_ARG16},
|
||||
{"sbc A,!0x%04x+Y", SPC_ARG16},
|
||||
{"sbc A,[0x%02x]+Y", SPC_ARG8_1},
|
||||
{"sbc 0x%02x,#0x%02x", SPC_ARG8_2},
|
||||
{"sbc (X),(Y)", SPC_OP},
|
||||
{"movw YA,0x%02x", SPC_ARG8_1},
|
||||
{"inc 0x%02x+X", SPC_ARG8_1},
|
||||
{"inc A", SPC_OP},
|
||||
{"mov SP,X", SPC_OP},
|
||||
{"das", SPC_OP},
|
||||
{"mov A,(X)+", SPC_OP},
|
||||
{"di", SPC_OP},
|
||||
{"call [0xffc6]", SPC_OP},
|
||||
{"set1 0x%02x.6", SPC_ARG8_1},
|
||||
{"bbs 0x%02x.6,0x%02x", SPC_ARG8_2},
|
||||
{"mov 0x%02x,A", SPC_ARG8_1},
|
||||
{"mov !0x%04x,A", SPC_ARG16},
|
||||
{"mov (X),A", SPC_OP},
|
||||
{"mov [0x%02x+X],A", SPC_ARG8_1},
|
||||
{"cmp X,#0x%02x", SPC_ARG8_1},
|
||||
{"mov !0x%04x,X", SPC_ARG16},
|
||||
{"and1 0x%02x.0x%02x,C", SPC_ARG8_2},
|
||||
{"mov 0x%02x,Y", SPC_ARG8_1},
|
||||
{"mov !0x%04x,Y", SPC_ARG16},
|
||||
{"mov X,#0x%02x", SPC_ARG8_1},
|
||||
{"pop X", SPC_OP},
|
||||
{"mul YA", SPC_OP},
|
||||
{"bne 0x%02x", SPC_ARG8_1},
|
||||
{"call [0xffc4]", SPC_OP},
|
||||
{"clr1 0x%02x.6", SPC_ARG8_1},
|
||||
{"bbc 0x%02x.6,0x%02x", SPC_ARG8_2},
|
||||
{"mov 0x%02x+X,A", SPC_ARG8_1},
|
||||
{"mov !0x%04x+X,A", SPC_ARG16},
|
||||
{"mov !0x%04x+Y,A", SPC_ARG16},
|
||||
{"mov [0x%02x]+Y,A", SPC_ARG8_1},
|
||||
{"mov 0x%02x,X", SPC_ARG8_1},
|
||||
{"mov 0x%02x+Y,X", SPC_ARG8_1},
|
||||
{"movw 0x%02x,YA", SPC_ARG8_1},
|
||||
{"mov 0x%02x+X,Y", SPC_ARG8_1},
|
||||
{"dec Y", SPC_OP},
|
||||
{"mov A,Y", SPC_OP},
|
||||
{"cbne 0x%02x+X,0x%02x", SPC_ARG8_2},
|
||||
{"daa", SPC_OP},
|
||||
{"clrv", SPC_OP},
|
||||
{"call [0xffc2]", SPC_OP},
|
||||
{"set1 0x%02x.7", SPC_ARG8_1},
|
||||
{"bbs 0x%02x.7,0x%02x", SPC_ARG8_2},
|
||||
{"mov A,0x%02x", SPC_ARG8_1},
|
||||
{"mov A,!0x%04x", SPC_ARG16},
|
||||
{"mov A,(X)", SPC_OP},
|
||||
{"mov A,[0x%02x+X]", SPC_ARG8_1},
|
||||
{"mov A,#0x%02x", SPC_ARG8_1},
|
||||
{"mov X,!0x%04x", SPC_ARG16},
|
||||
{"not1 0x%02x.0x%02x", SPC_ARG8_2},
|
||||
{"mov Y,0x%02x", SPC_ARG8_1},
|
||||
{"mov Y,!0x%04x", SPC_ARG16},
|
||||
{"notc", SPC_OP},
|
||||
{"pop Y", SPC_OP},
|
||||
{"sleep", SPC_OP},
|
||||
{"beq 0x%02x", SPC_ARG8_1},
|
||||
{"call [0xffc0]", SPC_OP},
|
||||
{"clr1 0x%02x.7", SPC_ARG8_1},
|
||||
{"bbc 0x%02x.7,0x%02x", SPC_ARG8_2},
|
||||
{"mov A,0x%02x+X", SPC_ARG8_1},
|
||||
{"mov A,!0x%04x+X", SPC_ARG16},
|
||||
{"mov A,!0x%04x+Y", SPC_ARG16},
|
||||
{"mov A,[0x%02x]+Y", SPC_ARG8_1},
|
||||
{"mov X,0x%02x", SPC_ARG8_1},
|
||||
{"mov X,0x%02x+Y", SPC_ARG8_1},
|
||||
{"mov 0x%02x,0x%02x", SPC_ARG8_2},
|
||||
{"mov Y,0x%02x+X", SPC_ARG8_1},
|
||||
{"inc Y", SPC_OP},
|
||||
{"mov Y,A", SPC_OP},
|
||||
{"dbnz Y,0x%02x", SPC_ARG8_1},
|
||||
{"stop", SPC_OP}
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
/* radare - LGPL - Copyright 2014 - [email protected] */
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_asm.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "spc700_opcode_table.h"
|
||||
|
||||
static int spc700OpLength(int spcoptype){
|
||||
switch(spcoptype) {
|
||||
case SPC_OP:
|
||||
return 1;
|
||||
case SPC_ARG8_1:
|
||||
return 2;
|
||||
case SPC_ARG8_2:
|
||||
case SPC_ARG16:
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spc700Disass(RAsmOp *op, const ut8 *buf, int len) {
|
||||
int foo = spc700OpLength (spc_op_table[buf[0]].type);
|
||||
if (len < foo) {
|
||||
return 0;
|
||||
}
|
||||
const char *buf_asm = "invalid";
|
||||
switch (spc_op_table[buf[0]].type) {
|
||||
case SPC_OP:
|
||||
buf_asm = spc_op_table[buf[0]].name;
|
||||
break;
|
||||
case SPC_ARG8_1:
|
||||
buf_asm = sdb_fmt (spc_op_table[buf[0]].name, buf[1]);
|
||||
break;
|
||||
case SPC_ARG8_2:
|
||||
buf_asm = sdb_fmt (spc_op_table[buf[0]].name, buf[1], buf[2]);
|
||||
break;
|
||||
case SPC_ARG16:
|
||||
buf_asm = sdb_fmt (spc_op_table[buf[0]].name, buf[1]+0x100*buf[2]);
|
||||
break;
|
||||
}
|
||||
r_asm_op_set_asm (op, buf_asm);
|
||||
return foo;
|
||||
}
|
||||
@@ -89,7 +89,7 @@ int r_asm_swf_disass(RBinObject *obj, char* buf_asm, const ut8* buf, int len, ut
|
||||
case 0: { /* String */
|
||||
char* str = (char*) (buf+i);
|
||||
i += strlen (str);
|
||||
sprintf (name, "str: \"%s\"", str);
|
||||
snprintf (name,strsize, "str: \"%s\"", str);
|
||||
break;
|
||||
}
|
||||
case 1: { /* Floating point */
|
||||
@@ -162,7 +162,7 @@ int r_asm_swf_disass(RBinObject *obj, char* buf_asm, const ut8* buf, int len, ut
|
||||
}
|
||||
case SWFACTION_GETURL: {
|
||||
char* url = (char*) buf+1;
|
||||
sprintf (buf_asm, "%s %s", op.name, url);
|
||||
snprintf (buf_asm, 1024,"%s %s", op.name, url);
|
||||
dlen = strlen (url) + 2;
|
||||
break;
|
||||
}
|
||||
@@ -203,7 +203,7 @@ int r_asm_swf_disass(RBinObject *obj, char* buf_asm, const ut8* buf, int len, ut
|
||||
}
|
||||
case SWFACTION_SETTARGET: {
|
||||
char* target = (char*) buf+1;
|
||||
sprintf (buf_asm, "%s %s", op.name, target);
|
||||
sprintf (buf_asm, 1024,"%s %s", op.name, target);
|
||||
dlen = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,8 @@
|
||||
ARCHS=
|
||||
|
||||
ARCHS+=x86_udis.mk
|
||||
ARCHS+=spc700.mk
|
||||
ARCHS+=ba2.mk
|
||||
ARCHS+=x86_olly.mk
|
||||
ARCHS+=x86_tab.mk
|
||||
ARCHS+=armthumb.mk
|
||||
@@ -15,7 +17,6 @@ ARCHS+=swf.mk
|
||||
ARCHS+=vc4.mk
|
||||
ARCHS+=mc6809.mk
|
||||
ARCHS+=z80_nc.mk
|
||||
ARCHS+=pyc.mk
|
||||
ARCHS+=x86_zyan.mk
|
||||
ARCHS+=evm.mk
|
||||
ARCHS+=atombios.mk
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
#include "../arch/atombios/atombios.h"
|
||||
|
||||
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
op->size = atombios_disassemble (buf, r_asm_op_get_asm (op));
|
||||
char res[1024];
|
||||
res[0] = 0;
|
||||
op->size = atombios_disassemble (buf, len, res);
|
||||
r_strbuf_set (&op->buf_asm, res);
|
||||
return op->size;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <r_types.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_util.h>
|
||||
#include <r_asm.h>
|
||||
|
||||
#include "../../asm/arch/ba2/ba2_disas.c"
|
||||
|
||||
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
struct op_cmd cmd = {
|
||||
.instr = "",
|
||||
.operands = ""
|
||||
};
|
||||
int ret = ba2_decode_opcode (a->pc, buf, len, &cmd, NULL, NULL);
|
||||
if((len < ret) || (!ret && len<6)){
|
||||
r_strbuf_set (&op->buf_asm, "truncated");
|
||||
op->size = 0;
|
||||
return 0;
|
||||
}
|
||||
if (ret > 0) {
|
||||
snprintf (op->buf_asm.buf, sizeof(op->buf_asm.buf), "%s %s", cmd.instr, cmd.operands);
|
||||
}else{
|
||||
r_strbuf_set (&op->buf_asm, "invalid");
|
||||
return -1;
|
||||
}
|
||||
return op->size = ret;
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_ba2 = {
|
||||
.name = "ba2",
|
||||
.license = "LGPL3",
|
||||
.desc = "Beyond Architecture 2 disassembly plugin",
|
||||
.arch = "ba2",
|
||||
.bits = 32,
|
||||
.endian = R_SYS_ENDIAN_LITTLE,
|
||||
.disassemble = &disassemble
|
||||
};
|
||||
|
||||
#ifndef R2_PLUGIN_INCORE
|
||||
R_API RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_ba2,
|
||||
.version = R2_VERSION
|
||||
};
|
||||
#endif
|
||||
|
||||
+40
-12
@@ -9,32 +9,39 @@
|
||||
#include <r_asm.h>
|
||||
|
||||
#include "blackfin/bfin-dis.c"
|
||||
#include "blackfin/bfin-asm.c"
|
||||
|
||||
static unsigned long Offset = 0;
|
||||
static RStrBuf *buf_global = NULL;
|
||||
static unsigned char bytes[4];
|
||||
static unsigned char bytes[8]; // Allow for parallel combination of instructions: 4 bytes + 2 bytes + 2 bytes
|
||||
|
||||
static int bfin_buffer_read_memory (bfd_vma memaddr, bfd_byte *myaddr, ut32 length, struct disassemble_info *info) {
|
||||
memcpy (myaddr, bytes, length);
|
||||
static int bfin_buffer_read_memory (bfd_vma memaddr, bfd_byte *myaddr, ut32 length, struct disassemble_info *info)
|
||||
{
|
||||
memcpy (myaddr, bytes+memaddr-Offset, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int symbol_at_address(bfd_vma addr, struct disassemble_info * info) {
|
||||
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) {
|
||||
static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_info *info)
|
||||
{
|
||||
//--
|
||||
}
|
||||
|
||||
static void print_address(bfd_vma address, struct disassemble_info *info) {
|
||||
|
||||
static void print_address(bfd_vma address, struct disassemble_info *info)
|
||||
{
|
||||
if (buf_global == NULL)
|
||||
return;
|
||||
r_strbuf_appendf (buf_global, "0x%08"PFMT64x"", (ut64)address);
|
||||
}
|
||||
|
||||
|
||||
static int buf_fprintf(void *stream, const char *format, ...) {
|
||||
static int buf_fprintf(void *stream, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
if (buf_global == NULL)
|
||||
return 0;
|
||||
@@ -44,15 +51,17 @@ static int buf_fprintf(void *stream, const char *format, ...) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len)
|
||||
{
|
||||
struct disassemble_info disasm_obj;
|
||||
r_strbuf_set (&op->buf_asm, "");
|
||||
op->size = 4;
|
||||
if (len<4)
|
||||
if (len<2)
|
||||
return -1;
|
||||
buf_global = &op->buf_asm;
|
||||
Offset = a->pc;
|
||||
memcpy (bytes, buf, 4); // TODO handle thumb
|
||||
if (len<8) memcpy (bytes, buf, len);
|
||||
else memcpy (bytes, buf, 8);
|
||||
|
||||
/* prepare disassembler */
|
||||
memset (&disasm_obj, '\0', sizeof (struct disassemble_info));
|
||||
@@ -74,15 +83,34 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
return op->size;
|
||||
}
|
||||
|
||||
static int assemble(RAsm *a, RAsmOp *op, const char *buf)
|
||||
{
|
||||
ut8 hexbuf[8];
|
||||
int oplen;
|
||||
|
||||
r_asm_op_init(op);
|
||||
|
||||
oplen=bfin_assemble(buf, (uint32_t)(a->pc), hexbuf);
|
||||
|
||||
r_asm_op_set_hexbuf(op, hexbuf, oplen);
|
||||
|
||||
return op->buf.len;
|
||||
}
|
||||
|
||||
static bool init(void *user)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_blackfin = {
|
||||
.name = "blackfin",
|
||||
.arch = "blackfin",
|
||||
.bits = 32,
|
||||
.desc = "Blackfin Analog Devices",
|
||||
.init = NULL,
|
||||
.init = &init,
|
||||
.fini = NULL,
|
||||
.disassemble = &disassemble,
|
||||
.assemble = NULL
|
||||
.assemble = &assemble
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/* 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
|
||||
@@ -30,12 +30,13 @@ static int disassemble(RAsm *a, RAsmOp *aop, const ut8 *buf, int len) {
|
||||
// invalid instruction
|
||||
return aop->size = 2;
|
||||
}
|
||||
ilen = (buf2-(const ut8*)bof);
|
||||
if (*operands)
|
||||
ilen = buf2 - (const ut8*)bof;
|
||||
if (*operands) {
|
||||
buf_asm = sdb_fmt ("%s %s", opcode, operands);
|
||||
else
|
||||
} else {
|
||||
buf_asm = sdb_fmt ("%s", opcode);
|
||||
r_str_rmch (buf_asm, '#');
|
||||
}
|
||||
r_str_replace_ch (buf_asm, '#', 0, 1);
|
||||
r_asm_op_set_asm (aop, buf_asm);
|
||||
aop->size = ilen;
|
||||
return aop->size;
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
#include <r_types.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_util.h>
|
||||
#include <r_asm.h>
|
||||
|
||||
#include "pyc_dis.h"
|
||||
|
||||
static int disassemble (RAsm *a, RAsmOp *opstruct, const ut8 *buf, int len) {
|
||||
RList *interned_table = NULL;
|
||||
RList *shared = NULL;
|
||||
RList *cobjs = NULL;
|
||||
|
||||
RBin *bin = a->binb.bin;
|
||||
ut64 pc = a->pc;
|
||||
|
||||
RBinPlugin *plugin = bin && bin->cur && bin->cur->o ?
|
||||
bin->cur->o->plugin : NULL;
|
||||
|
||||
if (plugin) {
|
||||
if (!strcmp (plugin->name, "pyc")) {
|
||||
shared = bin->cur->o->bin_obj;
|
||||
}
|
||||
}
|
||||
cobjs = r_list_get_n (shared, 0);
|
||||
interned_table = r_list_get_n (shared, 1);
|
||||
int r = r_pyc_disasm (opstruct, buf, cobjs, interned_table, pc);
|
||||
opstruct->size = r;
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool init (void *user) {
|
||||
init_opname_table ();
|
||||
return true;
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_pyc = {
|
||||
.name = "pyc",
|
||||
.arch = "pyc",
|
||||
.license = "LGPL3",
|
||||
.bits = 32,
|
||||
.desc = "PYC disassemble plugin",
|
||||
.disassemble = &disassemble,
|
||||
.init = &init,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_pyc,
|
||||
.version = R2_VERSION
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
/* radare - LGPL - Copyright 2012-2020 - pancake, condret */
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include <r_asm.h>
|
||||
#include <sdb.h>
|
||||
#include <r_lib.h>
|
||||
#include "../arch/spc700/spc700dis.c"
|
||||
|
||||
static int disassemble(RAsm *a, RAsmOp *r_op, const ut8 *buf, int len) {
|
||||
int dlen = spc700Disass (r_op, buf, len);
|
||||
if (dlen < 0) {
|
||||
dlen = 0;
|
||||
}
|
||||
r_op->size = dlen;
|
||||
return dlen;
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_spc700 = {
|
||||
.name = "spc700",
|
||||
.desc = "spc700, snes' sound-chip",
|
||||
.arch = "spc700",
|
||||
.license = "LGPL3",
|
||||
.bits = 16,
|
||||
.endian = R_SYS_ENDIAN_NONE, // is this LE?
|
||||
.disassemble = &disassemble,
|
||||
};
|
||||
|
||||
#ifndef R2_PLUGIN_INCORE
|
||||
R_API RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_spc700,
|
||||
.version = R2_VERSION
|
||||
};
|
||||
#endif
|
||||
@@ -13,7 +13,10 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
|
||||
obj = bin->cur->o;
|
||||
|
||||
int dlen = r_asm_swf_disass (obj, op->buf_asm, buf, len, a->pc);
|
||||
char res[1024];
|
||||
res[0] = 0;
|
||||
int dlen = r_asm_swf_disass (obj, res, buf, len, a->pc);
|
||||
r_strbuf_set (&op->buf_asm, res);
|
||||
op->size = dlen;
|
||||
return dlen;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,10 @@ static int disassemble(RAsm *a, RAsmOp *aop, const ut8 *buf, int len) {
|
||||
ZydisStatus st = ZydisDecoderDecodeInstruction (&decr, buf, len, a->pc, &info);
|
||||
if (ZYDIS_SUCCESS (st)) {
|
||||
ZydisFormatterInitInstructionFormatter (&fmtr, ZYDIS_FORMATTER_STYLE_INTEL);
|
||||
ZydisFormatterFormatInstruction (&fmtr, &info, aop->buf_asm, R_ASM_BUFSIZE);
|
||||
char str[128];
|
||||
str[0] = 0;
|
||||
ZydisFormatterFormatInstruction (&fmtr, &info, str, sizeof (str));
|
||||
r_strbuf_set (&aop->buf_asm, str);
|
||||
}
|
||||
|
||||
return aop->size = info.length;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2012-2013 - pancake */
|
||||
/* radare - LGPL - Copyright 2012-2020 - pancake */
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
@@ -7,7 +7,9 @@
|
||||
#include "../arch/z80_nc/disasm.c"
|
||||
|
||||
static int do_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
int dlen = z80dis (0, buf, op->buf_asm, len);
|
||||
char str[128];
|
||||
int dlen = z80dis (0, buf, str, len);
|
||||
r_strbuf_set (&op->buf_asm, str);
|
||||
if (dlen<0) dlen = 0;
|
||||
op->size = dlen;
|
||||
return op->size;
|
||||
@@ -24,7 +26,7 @@ RAsmPlugin r_asm_plugin_z80 = {
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_z80,
|
||||
.version = R2_VERSION
|
||||
|
||||
@@ -6,4 +6,4 @@ STATIC_OBJ+=${OBJ_ATOMBIOS}
|
||||
|
||||
ALL_TARGETS+=${TARGET_ATOMBIOS}
|
||||
${TARGET_ATOMBIOS}: ${OBJ_ATOMBIOS}
|
||||
${CC} -g $(call libname,asm_atombios) ${LDFLAGS} ${CFLAGS} -o ${TARGET_ATOMBIOS} ${OBJ_ATOMBIOS}
|
||||
${CC} -g $(call libname,asm_atombios) ${LDFLAGS} ${CFLAGS} -o ${TARGET_ATOMBIOS} ${OBJ_ATOMBIOS} -lr_util
|
||||
@@ -0,0 +1,10 @@
|
||||
OBJ_BA2=asm_ba2.o
|
||||
CFLAGS+=-I./arch/ba2/
|
||||
|
||||
STATIC_OBJ+=${OBJ_BA2}
|
||||
TARGET_BA2=asm_ba2.${LIBEXT}
|
||||
|
||||
ALL_TARGETS+=${TARGET_BA2}
|
||||
|
||||
${TARGET_BA2}: ${OBJ_BA2}
|
||||
${CC} ${CFLAGS} -o ${TARGET_BA2} ${OBJ_BA2}
|
||||
@@ -0,0 +1,14 @@
|
||||
OBJ_HEXAGON_GNU=asm_hexagon_gnu.o
|
||||
OBJ_HEXAGON_GNU+=../arch/hexagon/gnu/hexagon-dis.o
|
||||
OBJ_HEXAGON_GNU+=../arch/hexagon/gnu/hexagon-opc.o
|
||||
OBJ_HEXAGON_GNU+=../arch/hexagon/gnu/safe-ctype.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_HEXAGON_GNU}
|
||||
|
||||
TARGET_HEXAGON_GNU=asm_hexagon_gnu.${EXT_SO}
|
||||
ifeq ($(WITHPIC),1)
|
||||
ALL_TARGETS+=${TARGET_HEXAGON_GNU}
|
||||
|
||||
${TARGET_HEXAGON_GNU}: ${OBJ_HEXAGON_GNU}
|
||||
${CC} $(call libname,asm_hexagon_gnu) ${LDFLAGS} ${CFLAGS} -o ${TARGET_HEXAGON_GNU} ${OBJ_HEXAGON_GNU}
|
||||
endif
|
||||
@@ -1,12 +0,0 @@
|
||||
OBJ_PYC=asm_pyc.o
|
||||
OBJ_PYC+=../arch/pyc/pyc_disasm.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_PYC}
|
||||
TARGET_PYC=asm_pyc.$(LIBEXT)
|
||||
|
||||
ALL_TARGETS+=${TARGET_PYC}
|
||||
CFLAGS+=-I../arch/pyc
|
||||
|
||||
${TARGET_PYC}: ${OBJ_PYC}
|
||||
${CC} ${CFLAGS} $(LDFLAGS) -o ${TARGET_PYC} ${OBJ_PYC} -lr_util
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
OBJ_SPC700=asm_spc700.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_SPC700}
|
||||
TARGET_SPC700=asm_spc700.${LIBEXT}
|
||||
|
||||
ALL_TARGETS+=${TARGET_SPC700}
|
||||
|
||||
${TARGET_SPC700}: ${OBJ_SPC700}
|
||||
${CC} $(call libname,asm_spc700) ${CFLAGS} -o ${TARGET_SPC700} ${OBJ_SPC700} -lr_asm -lr_util
|
||||
@@ -14,4 +14,4 @@ ALL_TARGETS+=${TARGET_X86_ZYAN}
|
||||
CFLAGS+=-I../arch/x86/zyan/include
|
||||
|
||||
${TARGET_X86_ZYAN}: ${OBJ_X86_ZYAN}
|
||||
${CC} ${CFLAGS} -o ${TARGET_X86_ZYAN} ${OBJ_X86_ZYAN}
|
||||
${CC} ${LDFLAGS} ${CFLAGS} -o ${TARGET_X86_ZYAN} ${OBJ_X86_ZYAN}
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
bea:
|
||||
cd p ; $(MAKE) bin_dlang.$(LIBEXT)
|
||||
|
||||
pyc:
|
||||
cd p ; $(MAKE) bin_pyc.$(LIBEXT)
|
||||
spc700:
|
||||
cd p ; $(MAKE) bin_spc700.$(LIBEXT)
|
||||
|
||||
swf:
|
||||
cd p ; $(MAKE) bin_swf.$(LIBEXT)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef _ATOMBIOS_H_
|
||||
#define _ATOMBIOS_H_
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
|
||||
// The atombios object for RBinFile
|
||||
typedef struct atombios_obj_s {
|
||||
//atombios_hdr_t *header;
|
||||
RBuffer *b;
|
||||
} atombios_obj_t;
|
||||
|
||||
#endif
|
||||
+407
-90
@@ -1,151 +1,468 @@
|
||||
#include <r_bin.h>
|
||||
|
||||
#include "pcap.h"
|
||||
|
||||
void read_pcap_file_hdr(pcap_file_hdr_t *hdr, const ut8 *buf, int swap_endian) {
|
||||
memcpy (hdr, buf, sizeof (pcap_file_hdr_t));
|
||||
if (swap_endian) {
|
||||
hdr->magic = r_swap_ut32 (hdr->magic);
|
||||
hdr->version_major = r_swap_ut16 (hdr->version_major);
|
||||
hdr->version_minor = r_swap_ut16 (hdr->version_minor);
|
||||
hdr->this_zone = r_swap_st32 (hdr->this_zone);
|
||||
hdr->ts_accuracy = r_swap_ut32 (hdr->ts_accuracy);
|
||||
hdr->max_pkt_len = r_swap_ut32 (hdr->max_pkt_len);
|
||||
hdr->network = r_swap_ut32 (hdr->network);
|
||||
void pcap_obj_free (pcap_obj_t *obj) {
|
||||
if (obj) {
|
||||
free (obj->header);
|
||||
r_list_free (obj->recs);
|
||||
r_buf_fini (obj->b);
|
||||
free (obj);
|
||||
}
|
||||
}
|
||||
|
||||
void read_pcap_pktrec_hdr(pcap_pktrec_hdr_t *hdr, const ut8 *buf, int swap_endian) {
|
||||
memcpy (hdr, buf, sizeof (pcap_pktrec_hdr_t));
|
||||
if (swap_endian) {
|
||||
hdr->ts_sec = r_swap_ut32 (hdr->ts_sec);
|
||||
hdr->ts_usec = r_swap_ut32 (hdr->ts_usec);
|
||||
hdr->cap_len = r_swap_ut32 (hdr->cap_len);
|
||||
hdr->orig_len = r_swap_ut32 (hdr->orig_len);
|
||||
static bool pcap_obj_init_hdr(pcap_obj_t *obj) {
|
||||
pcap_hdr_t *hdr = R_NEW0 (pcap_hdr_t);
|
||||
if (!hdr) {
|
||||
return false;
|
||||
}
|
||||
hdr->magic = r_buf_read_ble32_at (obj->b, 0, obj->bigendian);
|
||||
hdr->version_major = r_buf_read_ble16_at (obj->b, 4, obj->bigendian);
|
||||
hdr->version_minor = r_buf_read_ble16_at (obj->b, 6, obj->bigendian);
|
||||
hdr->this_zone = r_buf_read_ble32_at (obj->b, 8, obj->bigendian);
|
||||
hdr->ts_accuracy = r_buf_read_ble32_at (obj->b, 12, obj->bigendian);
|
||||
hdr->max_pkt_len = r_buf_read_ble32_at (obj->b, 16, obj->bigendian);
|
||||
hdr->network = r_buf_read_ble32_at (obj->b, 20, obj->bigendian);
|
||||
obj->header = hdr;
|
||||
return true;
|
||||
}
|
||||
|
||||
void pcaprec_free(pcaprec_t *rec) {
|
||||
if (rec) {
|
||||
free (rec->hdr);
|
||||
free (rec->link.ether_hdr);
|
||||
free (rec->net.ipv4_hdr);
|
||||
free (rec->transport.tcp_hdr);
|
||||
free (rec->data);
|
||||
free (rec);
|
||||
}
|
||||
}
|
||||
|
||||
void read_pcap_pktrec_ether(pcap_pktrec_ether_t *hdr, const ut8 *buf, int swap_endian) {
|
||||
memcpy (hdr, buf, sizeof (pcap_pktrec_ether_t));
|
||||
if (swap_endian) {
|
||||
hdr->type = r_swap_ut16 (hdr->type);
|
||||
static void parse_tcp (pcaprec_t *rec, ut8 *buf, ut32 size, bool bigendian) {
|
||||
pcaprec_tcp_t *tcp = R_NEW0 (pcaprec_tcp_t);
|
||||
if (!tcp) {
|
||||
return;
|
||||
}
|
||||
tcp->src_port = r_read_at_be16 (buf, 0);
|
||||
tcp->dst_port = r_read_at_be16 (buf, 2);
|
||||
tcp->seq_num = r_read_at_be32 (buf, 4);
|
||||
tcp->ack_num = r_read_at_be32 (buf, 8);
|
||||
tcp->hdr_len = r_read_at_be8 (buf, 12);
|
||||
tcp->flags = r_read_at_be16 (buf, 13);
|
||||
tcp->win_sz = r_read_at_be16 (buf, 15);
|
||||
tcp->chksum = r_read_at_be16 (buf, 17);
|
||||
tcp->urgnt_ptr = r_read_at_be16 (buf, 19);
|
||||
rec->transport.tcp_hdr = tcp;
|
||||
|
||||
// data offset at (((tcp->hdr_len >> 4) & 0x0F) * 4)
|
||||
ut32 dataoff = ((tcp->hdr_len & 0xF0) >> 2);
|
||||
rec->datasz = size - dataoff;
|
||||
rec->data = malloc (rec->datasz);
|
||||
if (!rec->data) {
|
||||
free (tcp);
|
||||
return;
|
||||
}
|
||||
memcpy (rec->data, buf + dataoff, rec->datasz);
|
||||
}
|
||||
|
||||
static void parse_ipv4 (pcaprec_t *rec, ut8 *buf, bool bigendian) {
|
||||
pcaprec_ipv4_t *ipv4 = R_NEW0 (pcaprec_ipv4_t);
|
||||
if (!ipv4) {
|
||||
return;
|
||||
}
|
||||
ipv4->ver_len = r_read_at_be8 (buf, 0);
|
||||
ipv4->diff_serv = r_read_at_be8 (buf, 1);
|
||||
ipv4->tot_len = r_read_at_be16 (buf, 2);
|
||||
ipv4->id = r_read_at_be16 (buf, 4);
|
||||
ipv4->flag_frag = r_read_at_be16 (buf, 6);
|
||||
ipv4->ttl = r_read_at_be8 (buf, 8);
|
||||
ipv4->protocol = r_read_at_be8 (buf, 9);
|
||||
ipv4->chksum = r_read_at_be16 (buf, 10);
|
||||
ipv4->src = r_read_at_be32 (buf, 12);
|
||||
ipv4->dst = r_read_at_be32 (buf, 16);
|
||||
|
||||
switch (ipv4->protocol) {
|
||||
case TRANSPORT_TCP:
|
||||
{
|
||||
ut32 tcpoff = ((ipv4->ver_len & 0x0F) * 4);
|
||||
parse_tcp (rec, buf + tcpoff, ipv4->tot_len - tcpoff, bigendian);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rec->net.ipv4_hdr = ipv4;
|
||||
}
|
||||
|
||||
static void parse_ipv6 (pcaprec_t *rec, ut8 *buf, bool bigendian) {
|
||||
pcaprec_ipv6_t *ipv6 = R_NEW0 (pcaprec_ipv6_t);
|
||||
if (!ipv6) {
|
||||
return;
|
||||
}
|
||||
memcpy (ipv6, buf, sizeof (pcaprec_ipv6_t));
|
||||
ipv6->vc_flow = r_read_at_be32 (buf, 0);
|
||||
ipv6->plen = r_read_at_be16 (buf, 4);
|
||||
switch (ipv6->nxt) {
|
||||
case TRANSPORT_TCP:
|
||||
parse_tcp (rec, buf + sizeof (pcaprec_ipv6_t), ipv6->plen, bigendian);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rec->net.ipv6_hdr = ipv6;
|
||||
}
|
||||
|
||||
static void parse_ether (pcaprec_t *rec, ut8 *buf, bool bigendian) {
|
||||
pcaprec_ether_t *ether = R_NEW0 (pcaprec_ether_t);
|
||||
if (!ether) {
|
||||
return;
|
||||
}
|
||||
// dst 6 bytes
|
||||
// src 6 bytes
|
||||
memcpy (ether, buf, 12);
|
||||
ether->type = r_read_at_be16 (buf, 12);
|
||||
switch (ether->type) {
|
||||
case NET_IPV4:
|
||||
parse_ipv4 (rec, buf + sizeof (pcaprec_ether_t), bigendian);
|
||||
break;
|
||||
case NET_IPV6:
|
||||
parse_ipv6 (rec, buf + sizeof (pcaprec_ether_t), bigendian);
|
||||
break;
|
||||
}
|
||||
rec->link.ether_hdr = ether;
|
||||
}
|
||||
|
||||
static bool pcap_obj_init_recs (pcap_obj_t *obj) {
|
||||
ut64 off = sizeof (pcap_hdr_t);
|
||||
ut64 size = r_buf_size (obj->b);
|
||||
if (size == 0 || size == UT64_MAX) {
|
||||
return false;
|
||||
}
|
||||
RList *recs = r_list_newf ((RListFree)pcaprec_free);
|
||||
if (!recs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (off < size) {
|
||||
pcaprec_hdr_t *rec_hdr = R_NEW0 (pcaprec_hdr_t);
|
||||
if (!rec_hdr) {
|
||||
goto error;
|
||||
}
|
||||
rec_hdr->ts_sec = r_buf_read_ble32_at (obj->b, off, obj->bigendian);
|
||||
rec_hdr->ts_usec = r_buf_read_ble32_at (obj->b, off + 4, obj->bigendian);
|
||||
rec_hdr->incl_len = r_buf_read_ble32_at (obj->b, off + 8, obj->bigendian);
|
||||
rec_hdr->orig_len = r_buf_read_ble32_at (obj->b, off + 12, obj->bigendian);
|
||||
if (off + sizeof (rec_hdr) + rec_hdr->incl_len > size) {
|
||||
free (rec_hdr);
|
||||
goto error;
|
||||
}
|
||||
off += 16;
|
||||
|
||||
pcaprec_t *rec = R_NEW0 (pcaprec_t);
|
||||
if (!rec) {
|
||||
free (rec_hdr);
|
||||
goto error;
|
||||
}
|
||||
rec->paddr = off;
|
||||
rec->hdr = rec_hdr;
|
||||
ut8 *pktbuf = malloc (rec_hdr->incl_len);
|
||||
if (!pktbuf) {
|
||||
free (rec_hdr);
|
||||
goto error;
|
||||
}
|
||||
if (r_buf_read_at (obj->b, off, pktbuf, rec_hdr->incl_len) < 0) {
|
||||
free (rec->data);
|
||||
free (rec_hdr);
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch (obj->header->network) {
|
||||
case LINK_ETHERNET:
|
||||
parse_ether (rec, pktbuf, obj->bigendian);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
free (pktbuf);
|
||||
r_list_append (recs, rec);
|
||||
off += rec_hdr->incl_len;
|
||||
}
|
||||
obj->recs = recs;
|
||||
return true;
|
||||
error:
|
||||
r_list_free (recs);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool pcap_obj_init (pcap_obj_t *obj) {
|
||||
switch (r_buf_read_be32_at (obj->b, 0)) {
|
||||
case PCAP_MAGIC_LE:
|
||||
obj->bigendian = false;
|
||||
obj->is_nsec = false;
|
||||
break;
|
||||
case PCAP_MAGIC_BE:
|
||||
obj->bigendian = true;
|
||||
obj->is_nsec = false;
|
||||
break;
|
||||
case PCAP_NSEC_MAGIC_LE:
|
||||
obj->bigendian = false;
|
||||
obj->is_nsec = true;
|
||||
break;
|
||||
case PCAP_NSEC_MAGIC_BE:
|
||||
obj->bigendian = true;
|
||||
obj->is_nsec = true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pcap_obj_init_hdr (obj)) {
|
||||
return false;
|
||||
}
|
||||
if (!pcap_obj_init_recs (obj)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pcap_obj_t *pcap_obj_new_buf(RBuffer *buf) {
|
||||
r_return_val_if_fail (buf, NULL);
|
||||
|
||||
pcap_obj_t *obj = R_NEW0 (pcap_obj_t);
|
||||
if (!obj) {
|
||||
return NULL;
|
||||
}
|
||||
obj->b = r_buf_ref (buf);
|
||||
|
||||
if (!pcap_obj_init (obj)) {
|
||||
pcap_obj_free (obj);
|
||||
return NULL;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void pcaprec_tcp_sym_add(RList *list, pcaprec_t* rec, ut64 paddr, ut32 size) {
|
||||
RBinSymbol *ptr = R_NEW0 (RBinSymbol);
|
||||
if (!ptr) {
|
||||
return;
|
||||
}
|
||||
pcaprec_tcp_t *tcp = rec->transport.tcp_hdr;
|
||||
ut32 datasz = size - ((tcp->hdr_len & 0xF0) >> 2);
|
||||
ptr->name = r_str_newf ("0x%"PFMT64x": Transmission Control Protocol, Src Port: %d, Dst"
|
||||
" port: %d, Len: %d", paddr, tcp->src_port, tcp->dst_port, datasz);
|
||||
ptr->paddr = ptr->vaddr = paddr;
|
||||
r_list_append (list, ptr);
|
||||
}
|
||||
|
||||
static void pcaprec_ipv4_sym_add(RList *list, pcaprec_t* rec, ut64 paddr) {
|
||||
RBinSymbol *ptr = R_NEW0 (RBinSymbol);
|
||||
if (!ptr) {
|
||||
return;
|
||||
}
|
||||
pcaprec_ipv4_t *ipv4 = rec->net.ipv4_hdr;
|
||||
ptr->name = r_str_newf ("0x%"PFMT64x": IPV%d, Src: %d.%d.%d.%d, Dst: %d.%d.%d.%d",
|
||||
paddr, (ipv4->ver_len >> 4) & 0x0F,
|
||||
(ipv4->src >> 24) & 0xFF, (ipv4->src >> 16) & 0xFF,
|
||||
(ipv4->src >> 8) & 0xFF, ipv4->src & 0xFF,
|
||||
(ipv4->dst >> 24) & 0xFF, (ipv4->dst >> 16) & 0xFF,
|
||||
(ipv4->dst >> 8) & 0xFF, ipv4->dst & 0xFF);
|
||||
ptr->paddr = ptr->vaddr = paddr;
|
||||
r_list_append (list, ptr);
|
||||
|
||||
switch (ipv4->protocol) {
|
||||
case TRANSPORT_TCP:
|
||||
{
|
||||
ut32 tcpoff = ((ipv4->ver_len & 0x0F) * 4);
|
||||
pcaprec_tcp_sym_add (list, rec, paddr + tcpoff, ipv4->tot_len - tcpoff);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void read_pcap_pktrec_ipv4(pcap_pktrec_ipv4_t *hdr, const ut8 *buf, int swap_endian) {
|
||||
memcpy (hdr, buf, sizeof (pcap_pktrec_ipv4_t));
|
||||
hdr->tot_len = r_read_be16 (&hdr->tot_len);
|
||||
hdr->src = r_read_be32 (&hdr->src);
|
||||
hdr->dst = r_read_be32 (&hdr->dst);
|
||||
hdr->id = r_read_be16 (&hdr->id);
|
||||
hdr->flag_frag = r_read_be16 (&hdr->flag_frag);
|
||||
hdr->chksum = r_read_be16 (&hdr->chksum);
|
||||
}
|
||||
static void pcaprec_ipv6_sym_add(RList *list, pcaprec_t* rec, ut64 paddr) {
|
||||
RBinSymbol *ptr = R_NEW0 (RBinSymbol);
|
||||
if (!ptr) {
|
||||
return;
|
||||
}
|
||||
pcaprec_ipv6_t *ipv6 = rec->net.ipv6_hdr;
|
||||
const char *src = ipv6_addr_string (ipv6->src);
|
||||
const char *dst = ipv6_addr_string (ipv6->dst);
|
||||
ptr->name = r_str_newf ("0x%"PFMT64x": IPV6, Src: %s, Dst: %s", paddr, src, dst);
|
||||
ptr->paddr = ptr->vaddr = paddr;
|
||||
r_list_append (list, ptr);
|
||||
free ((char *)src);
|
||||
free ((char *)dst);
|
||||
|
||||
void read_pcap_pktrec_ipv6(pcap_pktrec_ipv6_t *hdr, const ut8 *buf, int swap_endian) {
|
||||
memcpy (hdr, buf, sizeof (pcap_pktrec_ipv6_t));
|
||||
if (swap_endian) {
|
||||
hdr->plen = r_swap_ut16 (hdr->plen);
|
||||
switch (ipv6->nxt) {
|
||||
case TRANSPORT_TCP:
|
||||
pcaprec_tcp_sym_add (list, rec, paddr + sizeof (pcaprec_ipv6_t), ipv6->plen);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void read_pcap_pktrec_tcp(pcap_pktrec_tcp_t *hdr, const ut8 *buf, int swap_endian) {
|
||||
memcpy (hdr, buf, sizeof (pcap_pktrec_tcp_t));
|
||||
hdr->src_port = r_read_be16 (&hdr->src_port);
|
||||
hdr->dst_port = r_read_be16 (&hdr->dst_port);
|
||||
hdr->seq_num = r_read_be32 (&hdr->seq_num);
|
||||
hdr->ack_num = r_read_be32 (&hdr->ack_num);
|
||||
hdr->flags = r_read_be16 (&hdr->flags);
|
||||
hdr->win_sz = r_read_be16 (&hdr->win_sz);
|
||||
hdr->chksum = r_read_be16 (&hdr->chksum);
|
||||
hdr->urgnt_ptr = r_read_be16 (&hdr->urgnt_ptr);
|
||||
void pcaprec_ether_sym_add(RList *list, pcaprec_t *rec, ut64 paddr) {
|
||||
RBinSymbol *ptr = R_NEW0 (RBinSymbol);
|
||||
if (!ptr) {
|
||||
return;
|
||||
}
|
||||
pcaprec_ether_t *ether = rec->link.ether_hdr;
|
||||
ptr->name = r_str_newf ("0x%"PFMT64x": Ethernet, Src: %02"PFMT32x ":%02"PFMT32x ":%02"PFMT32x
|
||||
":%02"PFMT32x ":%02"PFMT32x ":%02"PFMT32x ", Dst: %02"PFMT32x
|
||||
":%02"PFMT32x ":%02"PFMT32x ":%02"PFMT32x ":%02"PFMT32x ":%02"PFMT32x,
|
||||
paddr, ether->src[0], ether->src[1], ether->src[2], ether->src[3], ether->src[4], ether->src[5],
|
||||
ether->dst[0], ether->dst[1], ether->dst[2], ether->dst[3], ether->dst[4], ether->dst[5]);
|
||||
ptr->paddr = ptr->vaddr = paddr;
|
||||
r_list_append (list, ptr);
|
||||
|
||||
switch (ether->type) {
|
||||
case NET_IPV4:
|
||||
pcaprec_ipv4_sym_add (list, rec, paddr + sizeof (pcaprec_ether_t));
|
||||
break;
|
||||
case NET_IPV6:
|
||||
pcaprec_ipv6_sym_add (list, rec, paddr + sizeof (pcaprec_ether_t));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char* pcap_net_type(ut32 net) {
|
||||
switch (net) {
|
||||
case NOLINK:
|
||||
const char* pcap_network_string(ut32 network) {
|
||||
switch (network) {
|
||||
case LINK_NOLINK:
|
||||
return "No link-layer encapsulation";
|
||||
case ETHERNET:
|
||||
case LINK_ETHERNET:
|
||||
return "Ethernet";
|
||||
case ETHERNET_3MB:
|
||||
case LINK_ETHERNET_3MB:
|
||||
return "3Mb Ethernet";
|
||||
case AX_25:
|
||||
case LINK_AX_25:
|
||||
return "AX.25";
|
||||
case PRONET:
|
||||
case LINK_PRONET:
|
||||
return "ProNET";
|
||||
case CHAOS:
|
||||
case LINK_CHAOS:
|
||||
return "CHAOS";
|
||||
case TOKEN_RING:
|
||||
case LINK_TOKEN_RING:
|
||||
return "Token Ring";
|
||||
case ARCNET:
|
||||
case LINK_ARCNET:
|
||||
return "ARCNET";
|
||||
case SLIP:
|
||||
case LINK_SLIP:
|
||||
return "SLIP";
|
||||
case PPP:
|
||||
case LINK_PPP:
|
||||
return "PPP";
|
||||
case FDDI:
|
||||
case LINK_FDDI:
|
||||
return "FDDI";
|
||||
case RFC_1483_ATM_1:
|
||||
case RFC_1483_ATM_2:
|
||||
case LINK_RFC_1483_ATM_1:
|
||||
case LINK_RFC_1483_ATM_2:
|
||||
return "RFC 1483 ATM";
|
||||
case RAW_IP_1:
|
||||
case RAW_IP_2:
|
||||
case LINK_RAW_IP_1:
|
||||
case LINK_RAW_IP_2:
|
||||
return "raw IP";
|
||||
case BSDOS_SLIP_1:
|
||||
case BSDOS_SLIP_2:
|
||||
case LINK_BSDOS_SLIP_1:
|
||||
case LINK_BSDOS_SLIP_2:
|
||||
return "BSD/OS SLIP";
|
||||
case BSDOS_PPP_1:
|
||||
case BSDOS_PPP_2:
|
||||
case LINK_BSDOS_PPP_1:
|
||||
case LINK_BSDOS_PPP_2:
|
||||
return "BSD/OS PPP";
|
||||
case LINUX_ATM_CLASSICAL_IP:
|
||||
case LINK_LINUX_ATM_CLASSICAL_IP:
|
||||
return "Linux ATM Classical IP";
|
||||
case PPP_CISCO_HDLC:
|
||||
case LINK_PPP_CISCO_HDLC:
|
||||
return "PPP or Cisco HDLC";
|
||||
case PPP_OVER_ETHERNET:
|
||||
case LINK_PPP_OVER_ETHERNET:
|
||||
return "PPP-over-Ethernet";
|
||||
case SYMANTEC_FIREWALL:
|
||||
case LINK_SYMANTEC_FIREWALL:
|
||||
return "Symantec Enterprise Firewall";
|
||||
case BSDOS_CISCO_HDLC:
|
||||
case LINK_BSDOS_CISCO_HDLC:
|
||||
return "BSD/OS Cisco HDLC";
|
||||
case _802_11:
|
||||
case LINK_802_11:
|
||||
return "802.11";
|
||||
case LINUX_CLASSICAL_IP_ATM:
|
||||
case LINK_LINUX_CLASSICAL_IP_ATM:
|
||||
return "Linux Classical IP over ATM";
|
||||
case FRAME_RELAY:
|
||||
case LINK_FRAME_RELAY:
|
||||
return "Frame Relay";
|
||||
case OPENBSD_LOOPBACK:
|
||||
case LINK_OPENBSD_LOOPBACK:
|
||||
return "OpenBSD loopback";
|
||||
case OPENBSD_IPSEC_ENC:
|
||||
case LINK_OPENBSD_IPSEC_ENC:
|
||||
return "OpenBSD IPsec encrypted";
|
||||
case CISCO_HDLC:
|
||||
case LINK_CISCO_HDLC:
|
||||
return "Cisco HDLC";
|
||||
case LINUX_COOKED:
|
||||
case LINK_LINUX_COOKED:
|
||||
return "Linux \"cooked\"";
|
||||
case LOCALTALK:
|
||||
case LINK_LOCALTALK:
|
||||
return "LocalTalk";
|
||||
case OPENBSD_PFLOG:
|
||||
case LINK_OPENBSD_PFLOG:
|
||||
return "OpenBSD PFLOG";
|
||||
case _802_11_PRISM:
|
||||
case LINK_802_11_PRISM:
|
||||
return "802.11 with Prism header";
|
||||
case RFC_2625_IP_FIBRE_CHANNEL:
|
||||
case LINK_RFC_2625_IP_FIBRE_CHANNEL:
|
||||
return "RFC 2625 over Fibre Channel";
|
||||
case SUNATM:
|
||||
case LINK_SUNATM:
|
||||
return "SunATM";
|
||||
case _802_11_RADIOTAP:
|
||||
case LINK_802_11_RADIOTAP:
|
||||
return "802.11 with radiotap header";
|
||||
case LINUX_ARCNET:
|
||||
case LINK_LINUX_ARCNET:
|
||||
return "Linux ARCNET";
|
||||
case APPLE_IP_IEEE_1394:
|
||||
case LINK_APPLE_IP_IEEE_1394:
|
||||
return "Apple IP over IEEE 1394";
|
||||
case MTP2:
|
||||
case LINK_MTP2:
|
||||
return "MTP2";
|
||||
case MTP3:
|
||||
case LINK_MTP3:
|
||||
return "MTP3";
|
||||
case DOCSIS:
|
||||
case LINK_DOCSIS:
|
||||
return "DOCSIS";
|
||||
case IRDA:
|
||||
case LINK_IRDA:
|
||||
return "IrDA";
|
||||
case _802_11_AVS_HDR:
|
||||
case LINK_802_11_AVS_HDR:
|
||||
return "802.11 with AVS header";
|
||||
default:
|
||||
return "Unkown";
|
||||
}
|
||||
}
|
||||
|
||||
const char *ipv6_addr_string(ut8 *addr) {
|
||||
size_t i;
|
||||
size_t start = -1;
|
||||
size_t tmp = -1;
|
||||
size_t len = 0, maxlen = 0;
|
||||
|
||||
ut16 words[8] = { 0 };
|
||||
for (i = 0; i < 8; i++) {
|
||||
words[i] = r_read_at_be16 (addr, i * 2);
|
||||
}
|
||||
|
||||
// find the longest sequence of zero field
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (words[i] == 0) {
|
||||
if (tmp == -1) {
|
||||
tmp = i;
|
||||
len = 1;
|
||||
} else {
|
||||
len++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len > maxlen) {
|
||||
maxlen = len;
|
||||
start = tmp;
|
||||
}
|
||||
tmp = -1;
|
||||
}
|
||||
|
||||
if (maxlen > 1) {
|
||||
RStrBuf *addr = r_strbuf_new (NULL);
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i == start) {
|
||||
r_strbuf_append (addr, "::");
|
||||
i += maxlen - 1;
|
||||
} else {
|
||||
r_strbuf_appendf (addr, "%x", words[i]);
|
||||
}
|
||||
}
|
||||
return r_strbuf_drain (addr);
|
||||
}
|
||||
return r_str_newf ("%x:%x:%x:%x:%x:%x:%x:%x",
|
||||
words[0], words[1], words[2], words[3],
|
||||
words[4], words[5], words[6], words[7]);
|
||||
}
|
||||
+114
-86
@@ -1,113 +1,110 @@
|
||||
#include <r_util.h>
|
||||
|
||||
#ifndef _PCAP_H_
|
||||
#define _PCAP_H_
|
||||
|
||||
// Definitions
|
||||
#define PCAP_MAGIC 0xa1b2c3d4 // Magic number for pcap files
|
||||
#define PCAP_NSEC_MAGIC 0xa1b23c4d // Modified pcap with nsec resolution
|
||||
#define LIBPCAP_MAGIC 0xa1b2cd34 // "libpcap" with Alexey Kuznetsoc's patches
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
|
||||
// The network field in the pcap file header
|
||||
typedef enum pcap_net {
|
||||
NOLINK = 0,
|
||||
ETHERNET = 1,
|
||||
ETHERNET_3MB = 2,
|
||||
AX_25 = 3,
|
||||
PRONET = 4,
|
||||
CHAOS = 5,
|
||||
TOKEN_RING = 6,
|
||||
ARCNET = 7,
|
||||
SLIP = 8,
|
||||
PPP = 9,
|
||||
FDDI = 10,
|
||||
RFC_1483_ATM_1 = 11,
|
||||
RAW_IP_1 = 12,
|
||||
BSDOS_SLIP_1 = 13,
|
||||
BSDOS_PPP_1 = 14,
|
||||
LINUX_ATM_CLASSICAL_IP = 19,
|
||||
PPP_CISCO_HDLC = 50,
|
||||
PPP_OVER_ETHERNET = 51,
|
||||
SYMANTEC_FIREWALL = 99,
|
||||
RFC_1483_ATM_2 = 100,
|
||||
RAW_IP_2 = 101,
|
||||
BSDOS_SLIP_2 = 102,
|
||||
BSDOS_PPP_2 = 103,
|
||||
BSDOS_CISCO_HDLC = 104,
|
||||
_802_11 = 105,
|
||||
LINUX_CLASSICAL_IP_ATM = 106,
|
||||
FRAME_RELAY = 107,
|
||||
OPENBSD_LOOPBACK = 108,
|
||||
OPENBSD_IPSEC_ENC = 109,
|
||||
CISCO_HDLC = 112,
|
||||
LINUX_COOKED = 113,
|
||||
LOCALTALK = 114,
|
||||
OPENBSD_PFLOG = 117,
|
||||
_802_11_PRISM = 119,
|
||||
RFC_2625_IP_FIBRE_CHANNEL = 122,
|
||||
SUNATM = 123,
|
||||
_802_11_RADIOTAP = 127,
|
||||
LINUX_ARCNET = 129,
|
||||
APPLE_IP_IEEE_1394 = 138,
|
||||
MTP2 = 140,
|
||||
MTP3 = 141,
|
||||
DOCSIS = 143,
|
||||
IRDA = 144,
|
||||
_802_11_AVS_HDR = 163,
|
||||
} pcap_net_t;
|
||||
// Magic number
|
||||
#define PCAP_MAGIC_LE 0xd4c3b2a1 // Magic number for pcap files
|
||||
#define PCAP_MAGIC_BE 0xa1b2c3d4 // Magic number for pcap files
|
||||
#define PCAP_NSEC_MAGIC_LE 0x4d3cb2a1 // Modified pcap with nsec resolution
|
||||
#define PCAP_NSEC_MAGIC_BE 0xa1b23c4d // Modified pcap with nsec resolution
|
||||
#define LIBPCAP_MAGIC 0xa1b2cd34// "libpcap" with Alexey Kuznetsoc's patches
|
||||
|
||||
// pcap file header
|
||||
typedef struct pcap_file_hdr {
|
||||
#define LINK_NOLINK 0
|
||||
#define LINK_ETHERNET 1
|
||||
#define LINK_ETHERNET_3MB 2
|
||||
#define LINK_AX_25 3
|
||||
#define LINK_PRONET 4
|
||||
#define LINK_CHAOS 5
|
||||
#define LINK_TOKEN_RING 6
|
||||
#define LINK_ARCNET 7
|
||||
#define LINK_SLIP 8
|
||||
#define LINK_PPP 9
|
||||
#define LINK_FDDI 10
|
||||
#define LINK_RFC_1483_ATM_1 11
|
||||
#define LINK_RAW_IP_1 12
|
||||
#define LINK_BSDOS_SLIP_1 13
|
||||
#define LINK_BSDOS_PPP_1 14
|
||||
#define LINK_LINUX_ATM_CLASSICAL_IP 19
|
||||
#define LINK_PPP_CISCO_HDLC 50
|
||||
#define LINK_PPP_OVER_ETHERNET 51
|
||||
#define LINK_SYMANTEC_FIREWALL 99
|
||||
#define LINK_RFC_1483_ATM_2 100
|
||||
#define LINK_RAW_IP_2 101
|
||||
#define LINK_BSDOS_SLIP_2 102
|
||||
#define LINK_BSDOS_PPP_2 103
|
||||
#define LINK_BSDOS_CISCO_HDLC 104
|
||||
#define LINK_802_11 105
|
||||
#define LINK_LINUX_CLASSICAL_IP_ATM 106
|
||||
#define LINK_FRAME_RELAY 107
|
||||
#define LINK_OPENBSD_LOOPBACK 108
|
||||
#define LINK_OPENBSD_IPSEC_ENC 109
|
||||
#define LINK_CISCO_HDLC 112
|
||||
#define LINK_LINUX_COOKED 113
|
||||
#define LINK_LOCALTALK 114
|
||||
#define LINK_OPENBSD_PFLOG 117
|
||||
#define LINK_802_11_PRISM 119
|
||||
#define LINK_RFC_2625_IP_FIBRE_CHANNEL 122
|
||||
#define LINK_SUNATM 123
|
||||
#define LINK_802_11_RADIOTAP 127
|
||||
#define LINK_LINUX_ARCNET 129
|
||||
#define LINK_APPLE_IP_IEEE_1394 138
|
||||
#define LINK_MTP2 140
|
||||
#define LINK_MTP3 141
|
||||
#define LINK_DOCSIS 143
|
||||
#define LINK_IRDA 144
|
||||
#define LINK_802_11_AVS_HDR 163
|
||||
|
||||
#define NET_IPV4 0x0800
|
||||
#define NET_IPV6 0x86dd
|
||||
|
||||
#define TRANSPORT_TCP 6
|
||||
|
||||
// Global Header
|
||||
typedef struct pcap_hdr_s {
|
||||
ut32 magic; // magic number
|
||||
ut16 version_major;
|
||||
ut16 version_minor;
|
||||
int this_zone; // GMT to local correction
|
||||
st32 this_zone; // GMT to local correction
|
||||
ut32 ts_accuracy; // Accuracy of timestamps
|
||||
ut32 max_pkt_len; // Max length of captured packets in bytes
|
||||
pcap_net_t network; // Data link type
|
||||
} pcap_file_hdr_t;
|
||||
|
||||
// Packet record header, always 16 bytes
|
||||
typedef struct pcak_pktrec_hdr {
|
||||
ut32 ts_sec; // Timestamp in seconds
|
||||
ut32 ts_usec; // Timestamp in usec (nanosec for PCAP_NSEC_MAGIC)
|
||||
ut32 cap_len; // Length of packet captured
|
||||
ut32 orig_len; // Original length of packet
|
||||
} pcap_pktrec_hdr_t;
|
||||
ut32 network; // Data link type
|
||||
} pcap_hdr_t;
|
||||
|
||||
// Ethernet header, always 14 bytes
|
||||
typedef struct pcap_pktrec_ether {
|
||||
ut8 dst[6]; // Destination MAC address
|
||||
ut8 src[6]; // Source MAC address
|
||||
ut16 type; // 0x0080 = IPV4, 0xdd86 = IPV6 etc
|
||||
} pcap_pktrec_ether_t;
|
||||
typedef struct pcaprec_ether {
|
||||
ut8 dst[6]; // Destination MAC address
|
||||
ut8 src[6]; // Source MAC address
|
||||
ut16 type;
|
||||
} pcaprec_ether_t;
|
||||
|
||||
// IPV4 header, atleast 20 bytes
|
||||
typedef struct pcap_pktrec_ipv4 {
|
||||
typedef struct pcaprec_ipv4 {
|
||||
ut8 ver_len; // Upper nibble = version, lower = header len in 4-byte words
|
||||
ut8 diff_serv; // Differentiated services field
|
||||
ut16 tot_len; // Total length of IPV4 packet
|
||||
ut16 id;
|
||||
ut16 flag_frag; // Upper 3 bits = flags, lower 13 = fragment offset
|
||||
ut8 ttl;
|
||||
ut8 protocol; // 6 = TCP
|
||||
ut8 protocol;
|
||||
ut16 chksum;
|
||||
ut32 src; // Source IP
|
||||
ut32 dst; // Destination IP
|
||||
} pcap_pktrec_ipv4_t;
|
||||
} pcaprec_ipv4_t;
|
||||
|
||||
// IPV6 header
|
||||
typedef struct pcap_pktrec_ipv6 {
|
||||
typedef struct pcaprec_ipv6 {
|
||||
ut32 vc_flow; // version, class, flow
|
||||
ut16 plen; // payload length
|
||||
ut8 nxt; // next header
|
||||
ut8 hlim; // hop limit
|
||||
ut8 src[16]; // source address
|
||||
ut8 dest[16]; // destination address
|
||||
} pcap_pktrec_ipv6_t;
|
||||
ut8 dst[16]; // destination address
|
||||
} pcaprec_ipv6_t;
|
||||
|
||||
// TCP header, 20 - 60 bytes
|
||||
typedef struct pcap_pktrec_tcp {
|
||||
typedef struct pcaprec_tcp {
|
||||
ut16 src_port; // Port on source
|
||||
ut16 dst_port; // Port on destination
|
||||
ut32 seq_num; // Sequence number
|
||||
@@ -118,16 +115,47 @@ typedef struct pcap_pktrec_tcp {
|
||||
ut16 chksum;
|
||||
ut16 urgnt_ptr; // Urgent
|
||||
// Variable length options. Use hdr_len
|
||||
} pcap_pktrec_tcp_t;
|
||||
} pcaprec_tcp_t;
|
||||
|
||||
// Record (Packet) Header
|
||||
typedef struct pcaprec_hdr_s {
|
||||
ut32 ts_sec; // Timestamp in seconds
|
||||
ut32 ts_usec; // Timestamp in usec (nanosec for PCAP_NSEC_MAGIC)
|
||||
ut32 incl_len; // Length of packet captured
|
||||
ut32 orig_len; // Original length of packet
|
||||
} pcaprec_hdr_t;
|
||||
|
||||
void read_pcap_file_hdr(pcap_file_hdr_t *hdr, const ut8 *buf, int swap_endian);
|
||||
void read_pcap_pktrec_hdr(pcap_pktrec_hdr_t *hdr, const ut8 *buf, int swap_endian);
|
||||
void read_pcap_pktrec_ether(pcap_pktrec_ether_t *hdr, const ut8 *buf, int swap_endian);
|
||||
void read_pcap_pktrec_ipv4(pcap_pktrec_ipv4_t *hdr, const ut8 *buf, int swap_endian);
|
||||
void read_pcap_pktrec_ipv6(pcap_pktrec_ipv6_t *hdr, const ut8 *buf, int swap_endian);
|
||||
void read_pcap_pktrec_tcp(pcap_pktrec_tcp_t *hdr, const ut8 *buf, int swap_endian);
|
||||
typedef struct pcaprec_s {
|
||||
ut64 paddr;
|
||||
pcaprec_hdr_t *hdr;
|
||||
union {
|
||||
pcaprec_ether_t *ether_hdr;
|
||||
} link;
|
||||
union {
|
||||
pcaprec_ipv4_t *ipv4_hdr;
|
||||
pcaprec_ipv6_t *ipv6_hdr;
|
||||
} net;
|
||||
union {
|
||||
pcaprec_tcp_t *tcp_hdr;
|
||||
} transport;
|
||||
ut32 datasz;
|
||||
ut8 *data;
|
||||
} pcaprec_t;
|
||||
|
||||
const char* pcap_net_type (ut32 net);
|
||||
// The pcap object for RBinFile
|
||||
typedef struct pcap_obj_s {
|
||||
pcap_hdr_t *header; // File header
|
||||
RList/*<pcaprec_t>*/ *recs;
|
||||
bool is_nsec; // nsec timestamp resolution?
|
||||
bool bigendian;
|
||||
RBuffer *b;
|
||||
} pcap_obj_t;
|
||||
|
||||
pcap_obj_t *pcap_obj_new_buf(RBuffer *buf);
|
||||
void pcap_obj_free (pcap_obj_t *obj);
|
||||
void pcaprec_free(pcaprec_t *rec);
|
||||
void pcaprec_ether_sym_add(RList *list, pcaprec_t *rec, ut64 paddr);
|
||||
const char* pcap_network_string(ut32 network);
|
||||
const char *ipv6_addr_string (ut8 *addr);
|
||||
|
||||
#endif // _PCAP_H_
|
||||
@@ -1,988 +0,0 @@
|
||||
/* radare - LGPL3 - Copyright 2016 - Matthieu (c0riolis) Tardy - l0stb1t*/
|
||||
|
||||
#include <r_io.h>
|
||||
#include <r_bin.h>
|
||||
#include <gmp.h>
|
||||
#include "marshal.h"
|
||||
|
||||
#define SIZE32_MAX 0x7FFFFFFF
|
||||
|
||||
/* not need in python 2
|
||||
static RList *refs = NULL;
|
||||
*/
|
||||
|
||||
/* interned_table is used to handle TYPE_INTERNED object */
|
||||
extern RList *interned_table;
|
||||
|
||||
static pyc_object *get_object (RBuffer *buffer);
|
||||
/* not need in python2
|
||||
static pyc_object *copy_object (pyc_object *object);
|
||||
*/
|
||||
static void free_object (pyc_object *object);
|
||||
|
||||
static ut8 get_ut8 (RBuffer *buffer, bool *error) {
|
||||
ut8 ret = 0;
|
||||
int size = r_buf_read (buffer, &ret, sizeof (ret));
|
||||
if (size < sizeof (ret))
|
||||
*error = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ut16 get_ut16 (RBuffer *buffer, bool *error) {
|
||||
ut16 ret = 0;
|
||||
|
||||
int size = r_buf_read (buffer, (ut8*)&ret, sizeof(ret));
|
||||
if (size != sizeof (ret))
|
||||
*error = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ut32 get_ut32 (RBuffer *buffer, bool *error) {
|
||||
ut32 ret = 0;
|
||||
int size = r_buf_read (buffer, (ut8*)&ret, sizeof (ret));
|
||||
if (size != sizeof (ret))
|
||||
*error = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static st32 get_st32 (RBuffer *buffer, bool *error) {
|
||||
st32 ret = 0;
|
||||
int size = r_buf_read (buffer, (ut8*)&ret, sizeof (ret));
|
||||
if (size < sizeof (ret))
|
||||
*error = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static st64 get_st64 (RBuffer *buffer, bool *error) {
|
||||
st64 ret = 0;
|
||||
int size = r_buf_read (buffer, (ut8 *)&ret, sizeof (ret));
|
||||
if ( size < sizeof (ret) )
|
||||
*error = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static double get_float64 (RBuffer *buffer, bool *error) {
|
||||
double ret = 0;
|
||||
int size = r_buf_read (buffer, (ut8*)&ret, sizeof(ret));
|
||||
if ( size < sizeof (ret) )
|
||||
*error = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ut8 *get_bytes (RBuffer *buffer, ut32 size) {
|
||||
ut8 *ret = R_NEWS0 (ut8, size + 1);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
if (r_buf_read (buffer, ret, size) < size) {
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_none_object (void) {
|
||||
pyc_object *ret;
|
||||
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_NONE;
|
||||
ret->data = strdup ("None");
|
||||
if (!ret->data)
|
||||
R_FREE (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_false_object (void) {
|
||||
pyc_object *ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_FALSE;
|
||||
ret->data = strdup ("False");
|
||||
if (!ret->data)
|
||||
R_FREE (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_true_object (void) {
|
||||
pyc_object *ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_TRUE;
|
||||
ret->data = strdup ("True");
|
||||
if (!ret->data)
|
||||
R_FREE (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_int_object (RBuffer *buffer) {
|
||||
bool error = false;
|
||||
pyc_object *ret = NULL;
|
||||
|
||||
st32 i = get_st32 (buffer, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_INT;
|
||||
ret->data = r_str_newf ("%d", i);
|
||||
if (!ret->data)
|
||||
R_FREE (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_int64_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
|
||||
st64 i = get_st64 (buffer, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_INT64;
|
||||
ret->data = r_str_newf ("%lld", i);
|
||||
if (!ret->data)
|
||||
R_FREE (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* long is used when the number is > MAX_INT64 */
|
||||
static pyc_object *get_long_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
bool neg = false;
|
||||
ut16 base = 32768;
|
||||
mpz_t pow, N, s;
|
||||
ut32 i;
|
||||
|
||||
st32 ndigits = get_st32 (buffer, &error);
|
||||
if (ndigits < -SIZE32_MAX || ndigits > SIZE32_MAX) {
|
||||
eprintf("bad marshal data (long size out of range)");
|
||||
return NULL;
|
||||
}
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_LONG;
|
||||
if (ndigits < 0) {
|
||||
ndigits = -ndigits;
|
||||
neg = true;
|
||||
}
|
||||
mpz_init (pow);
|
||||
mpz_init (N);
|
||||
mpz_init (s);
|
||||
mpz_set_ui (pow, 1);
|
||||
/* N += digits[i]*(pow); pow *= base */
|
||||
for (i = 0; i < ndigits; i++) {
|
||||
mpz_mul_ui(s, pow, get_ut16(buffer, &error));
|
||||
mpz_add(N, N, s);
|
||||
mpz_mul_ui(pow, pow, base);
|
||||
mpz_set_ui(s, 0);
|
||||
}
|
||||
/*negative number */
|
||||
if (neg)
|
||||
mpz_neg(N, N);
|
||||
char *buf = malloc (mpz_sizeinbase(N, 10) + 2);
|
||||
mpz_get_str (buf, 10, N);
|
||||
ret->data = buf;
|
||||
ret->type = TYPE_LONG;
|
||||
mpz_clear (pow);
|
||||
mpz_clear (N);
|
||||
mpz_clear (s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_stringref_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
ut32 n = 0;
|
||||
|
||||
n = get_st32 (buffer, &error);
|
||||
if (n >= r_list_length(interned_table)) {
|
||||
eprintf("bad marshal data (string ref out of range)");
|
||||
return NULL;
|
||||
}
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_STRINGREF;
|
||||
ret->data = r_list_get_n (interned_table, n);
|
||||
if (!ret->data)
|
||||
R_FREE (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_float_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
ut32 size = 0;
|
||||
ut8 n = 0;
|
||||
|
||||
n = get_ut8 (buffer, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ut8 *s = malloc (n);
|
||||
if (!s)
|
||||
return NULL;
|
||||
/* object contain string representation of the number */
|
||||
size = r_buf_read (buffer, s, n);
|
||||
if (size != n) {
|
||||
R_FREE (s);
|
||||
R_FREE (ret);
|
||||
return NULL;
|
||||
}
|
||||
s[n] = '\0';
|
||||
ret->type = TYPE_FLOAT;
|
||||
ret->data = s;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_binary_float_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
double f;
|
||||
|
||||
f = get_float64 (buffer, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_FLOAT;
|
||||
ret->data = r_str_newf ("%.15g", f);
|
||||
if (!ret->data) {
|
||||
R_FREE (ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_complex_object (RBuffer *buffer) {
|
||||
eprintf("not implemented");
|
||||
return NULL;
|
||||
/*
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
ut8 *buf = NULL;
|
||||
ut32 size = 0;
|
||||
ut8 n;
|
||||
|
||||
n = get_ut8 (buffer, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
buf = (ut8 *)malloc (256);
|
||||
size = r_buf_read (buffer, buf, n);
|
||||
if (size != n)
|
||||
eprintf("EOF read where object expected");
|
||||
return NULL;
|
||||
buf[n] = '\0';
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret) {
|
||||
free (buf);
|
||||
return NULL;
|
||||
}
|
||||
ret->type = TYPE_COMPLEX;
|
||||
return ret;
|
||||
*/
|
||||
}
|
||||
|
||||
static pyc_object *get_binary_complex_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
double a, b;
|
||||
|
||||
//a + bj
|
||||
a = get_float64 (buffer, &error);
|
||||
b = get_float64 (buffer, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_BINARY_COMPLEX;
|
||||
ret->data = r_str_newf ("%.15g+%.15gj", a, b);
|
||||
if (!ret->data) {
|
||||
R_FREE (ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_string_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
ut32 n = 0;
|
||||
|
||||
n = get_ut32 (buffer, &error);
|
||||
if (n < 0 || n > SIZE32_MAX) {
|
||||
eprintf("bad marshal data (string size out of range)");
|
||||
return NULL;
|
||||
}
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_STRING;
|
||||
ret->data = get_bytes (buffer, n);
|
||||
if (!ret->data) {
|
||||
R_FREE (ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_unicode_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
ut32 n = 0;
|
||||
|
||||
n = get_ut32 (buffer, &error);
|
||||
if (n < 0 || n > SIZE32_MAX) {
|
||||
eprintf("bad marshal data (unicode size out of range)");
|
||||
return NULL;
|
||||
}
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = R_NEW0 (pyc_object);
|
||||
ret->type = TYPE_UNICODE;
|
||||
ret->data = get_bytes (buffer, n);
|
||||
if (!ret->data) {
|
||||
R_FREE (ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_interned_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
ut32 n = 0;
|
||||
|
||||
n = get_ut32 (buffer, &error);
|
||||
if (n < 0 || n > SIZE32_MAX) {
|
||||
eprintf("bad marshal data (string size out of range)");
|
||||
return NULL;
|
||||
}
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_INTERNED;
|
||||
ret->data = get_bytes (buffer, n);
|
||||
/* add data pointer to interned table */
|
||||
r_list_append (interned_table, ret->data);
|
||||
if (!ret->data)
|
||||
R_FREE (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_array_object_generic (RBuffer *buffer, ut32 size) {
|
||||
pyc_object *tmp = NULL;
|
||||
pyc_object *ret = NULL;
|
||||
ut32 i = 0;
|
||||
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->data = r_list_new ();
|
||||
if (!ret->data) {
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < size; i++) {
|
||||
tmp = get_object (buffer);
|
||||
if (!tmp) {
|
||||
r_list_free (ret->data);
|
||||
R_FREE (ret);
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
if (!r_list_append (ret->data, tmp)) {
|
||||
free (tmp);
|
||||
r_list_free (ret->data);
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* small TYPE_SMALL_TUPLE doesn't exist in python2 */
|
||||
/* */
|
||||
pyc_object *get_small_tuple_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
ut8 n = 0;
|
||||
|
||||
n = get_ut8 (buffer, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = get_array_object_generic (buffer, n);
|
||||
if (ret) {
|
||||
ret->type = TYPE_SMALL_TUPLE;
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pyc_object *get_tuple_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
ut32 n = 0;
|
||||
|
||||
n = get_ut32 (buffer, &error);
|
||||
if (n > SIZE32_MAX) {
|
||||
eprintf("bad marshal data (tuple size out of range)");
|
||||
return NULL;
|
||||
}
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = get_array_object_generic (buffer, n);
|
||||
if (ret) {
|
||||
ret->type = TYPE_TUPLE;
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pyc_object *get_list_object (RBuffer *buffer) {
|
||||
pyc_object* ret = NULL;
|
||||
bool error = false;
|
||||
ut32 n = 0;
|
||||
|
||||
n = get_ut32 (buffer, &error);
|
||||
if (n > SIZE32_MAX) {
|
||||
eprintf("bad marshal data (list size out of range)");
|
||||
return NULL;
|
||||
}
|
||||
if (error)
|
||||
return NULL;
|
||||
ret = get_array_object_generic (buffer, n);
|
||||
ret->type = TYPE_LIST;
|
||||
return ret;
|
||||
}
|
||||
|
||||
pyc_object *get_dict_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL,
|
||||
*key = NULL,
|
||||
*val = NULL;
|
||||
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->data = r_list_new ();
|
||||
if (!ret->data) {
|
||||
R_FREE (ret);
|
||||
return NULL;
|
||||
}
|
||||
for(;;) {
|
||||
key = get_object (buffer);
|
||||
if (key == NULL)
|
||||
break;
|
||||
if (!r_list_append (ret->data, key)) {
|
||||
r_list_free (ret->data);
|
||||
R_FREE (ret);
|
||||
R_FREE (key);
|
||||
return NULL;
|
||||
}
|
||||
val = get_object (buffer);
|
||||
if (!r_list_append (ret->data, val))
|
||||
return NULL;
|
||||
if (val == NULL)
|
||||
break;
|
||||
}
|
||||
ret->type = TYPE_DICT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
pyc_object *get_set_object (RBuffer *buffer) {
|
||||
pyc_object *ret = NULL;
|
||||
bool error = false;
|
||||
ut32 n = 0;
|
||||
|
||||
n = get_ut32 (buffer, &error);
|
||||
if (n > SIZE32_MAX) {
|
||||
eprintf("bad marshal data (set size out of range)");
|
||||
return NULL;
|
||||
}
|
||||
if (error) {
|
||||
return NULL;
|
||||
}
|
||||
ret = get_array_object_generic (buffer, n);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_SET;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* not exists in python2
|
||||
static pyc_object *get_ascii_object_generic (RBuffer *buffer, ut32 size, bool interned) {
|
||||
pyc_object *ret = NULL;
|
||||
|
||||
ret = R_NEW0 (pyc_object);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->type = TYPE_ASCII;
|
||||
ret->data = get_bytes (buffer, size);
|
||||
if (!ret->data)
|
||||
R_FREE (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_ascii_object (RBuffer *buffer) {
|
||||
bool error = false;
|
||||
ut32 n = 0;
|
||||
|
||||
n = get_ut32 (buffer, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
return get_ascii_object_generic (buffer, n, true);
|
||||
}
|
||||
|
||||
static pyc_object *get_ascii_interned_object (RBuffer *buffer) {
|
||||
bool error = false;
|
||||
ut32 n;
|
||||
|
||||
n = get_ut32 (buffer, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
return get_ascii_object_generic (buffer, n, true);
|
||||
}
|
||||
|
||||
static pyc_object *get_short_ascii_object(RBuffer *buffer) {
|
||||
bool error = false;
|
||||
ut8 n;
|
||||
|
||||
n = get_ut8 (buffer, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
return get_ascii_object_generic (buffer, n, false);
|
||||
}
|
||||
|
||||
static pyc_object *get_short_ascii_interned_object(RBuffer *buffer) {
|
||||
bool error = false;
|
||||
ut8 n;
|
||||
|
||||
n = get_ut8 (buffer, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
return get_ascii_object_generic (buffer, n, true);
|
||||
}
|
||||
|
||||
static pyc_object *get_ref_object(RBuffer *buffer) {
|
||||
bool error = false;
|
||||
pyc_object *ret;
|
||||
pyc_object *obj;
|
||||
ut32 index;
|
||||
|
||||
index = get_ut32 (buffer, &error);
|
||||
if (error)
|
||||
return NULL;
|
||||
if (index >= r_list_length (refs))
|
||||
return NULL;
|
||||
obj = r_list_get_n (refs, index);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
ret = copy_object (obj);
|
||||
if (!ret)
|
||||
free (obj);
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
|
||||
void free_object(pyc_object *object) {
|
||||
if (!object)
|
||||
return;
|
||||
switch (object->type) {
|
||||
case TYPE_SMALL_TUPLE:
|
||||
case TYPE_TUPLE:
|
||||
r_list_free (object->data);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
case TYPE_TRUE:
|
||||
case TYPE_FALSE:
|
||||
case TYPE_INT:
|
||||
case TYPE_NONE:
|
||||
case TYPE_NULL:
|
||||
case TYPE_ASCII_INTERNED:
|
||||
case TYPE_SHORT_ASCII:
|
||||
case TYPE_ASCII:
|
||||
case TYPE_SHORT_ASCII_INTERNED:
|
||||
free (object->data);
|
||||
break;
|
||||
case TYPE_CODE_v1:
|
||||
{
|
||||
pyc_code_object *cobj = object->data;
|
||||
free_object (cobj->code);
|
||||
free_object (cobj->consts);
|
||||
free_object (cobj->names);
|
||||
free_object (cobj->varnames);
|
||||
free_object (cobj->freevars);
|
||||
free_object (cobj->cellvars);
|
||||
free_object (cobj->filename);
|
||||
free_object (cobj->name);
|
||||
free_object (cobj->lnotab);
|
||||
free (object->data);
|
||||
}
|
||||
break;
|
||||
case TYPE_REF:
|
||||
free_object (object->data);
|
||||
break;
|
||||
case TYPE_SET:
|
||||
case TYPE_FROZENSET:
|
||||
case TYPE_ELLIPSIS:
|
||||
case TYPE_STOPITER:
|
||||
case TYPE_BINARY_COMPLEX:
|
||||
case TYPE_BINARY_FLOAT:
|
||||
case TYPE_CODE_v0:
|
||||
case TYPE_COMPLEX:
|
||||
case TYPE_STRINGREF:
|
||||
case TYPE_DICT:
|
||||
case TYPE_FLOAT:
|
||||
case TYPE_INT64:
|
||||
case TYPE_INTERNED:
|
||||
case TYPE_LIST:
|
||||
case TYPE_LONG:
|
||||
case TYPE_UNICODE:
|
||||
case TYPE_UNKNOWN:
|
||||
eprintf ("Free not implemented for type %x\n", object->type);
|
||||
return;
|
||||
default:
|
||||
eprintf ("Undefined type in free_object (%x)\n", object->type);
|
||||
return;
|
||||
}
|
||||
free (object);
|
||||
}
|
||||
|
||||
/* not need in python2
|
||||
pyc_object *copy_object (pyc_object *object) {
|
||||
pyc_object *copy = R_NEW0 (pyc_object);
|
||||
if (!copy || !object) {
|
||||
free (copy);
|
||||
return NULL;
|
||||
}
|
||||
copy->type = object->type;
|
||||
switch (object->type) {
|
||||
case TYPE_NULL:
|
||||
break;
|
||||
case TYPE_TUPLE:
|
||||
case TYPE_SMALL_TUPLE:
|
||||
copy->data = r_list_clone (object->data);
|
||||
break;
|
||||
case TYPE_INT:
|
||||
case TYPE_NONE:
|
||||
case TYPE_TRUE:
|
||||
case TYPE_FALSE:
|
||||
case TYPE_STRING:
|
||||
case TYPE_ASCII:
|
||||
case TYPE_SHORT_ASCII:
|
||||
case TYPE_ASCII_INTERNED:
|
||||
case TYPE_SHORT_ASCII_INTERNED:
|
||||
copy->data = strdup (object->data);
|
||||
break;
|
||||
case TYPE_CODE_v1:
|
||||
{
|
||||
pyc_code_object *src = object->data;
|
||||
pyc_code_object *dst = R_NEW0 (pyc_code_object);
|
||||
if (!dst)
|
||||
break;
|
||||
memcpy (dst, src, sizeof (*dst));
|
||||
dst->code = copy_object (src->code);
|
||||
dst->consts = copy_object (src->consts);
|
||||
dst->names = copy_object (src->names);
|
||||
dst->varnames = copy_object (src->varnames);
|
||||
dst->freevars = copy_object (src->freevars);
|
||||
dst->cellvars = copy_object (src->cellvars);
|
||||
dst->filename = copy_object (src->filename);
|
||||
dst->name = copy_object (src->name);
|
||||
dst->lnotab = copy_object (src->lnotab);
|
||||
copy->data = dst;
|
||||
}
|
||||
break;
|
||||
case TYPE_REF:
|
||||
copy->data = copy_object (object->data);
|
||||
break;
|
||||
case TYPE_ELLIPSIS:
|
||||
case TYPE_STOPITER:
|
||||
case TYPE_BINARY_COMPLEX:
|
||||
case TYPE_BINARY_FLOAT:
|
||||
case TYPE_CODE_v0:
|
||||
case TYPE_COMPLEX:
|
||||
case TYPE_STRINGREF:
|
||||
case TYPE_DICT:
|
||||
case TYPE_FLOAT:
|
||||
case TYPE_FROZENSET:
|
||||
case TYPE_INT64:
|
||||
case TYPE_INTERNED:
|
||||
case TYPE_LIST:
|
||||
case TYPE_LONG:
|
||||
case TYPE_SET:
|
||||
case TYPE_UNICODE:
|
||||
case TYPE_UNKNOWN:
|
||||
eprintf ("Copy not implemented for type %x\n", object->type);
|
||||
return NULL;
|
||||
default:
|
||||
eprintf ("Undefined type in copy_object (%x)\n", object->type);
|
||||
return NULL;
|
||||
}
|
||||
if (!copy->data)
|
||||
R_FREE (copy);
|
||||
return copy;
|
||||
}
|
||||
*/
|
||||
|
||||
static pyc_object *get_code_object (RBuffer *buffer) {
|
||||
bool error = false;
|
||||
|
||||
pyc_object *ret = R_NEW0 (pyc_object);
|
||||
pyc_code_object *cobj = R_NEW0 (pyc_code_object);
|
||||
if (!ret || !cobj) {
|
||||
free (ret);
|
||||
free (cobj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->type = TYPE_CODE_v1;
|
||||
ret->data = cobj;
|
||||
|
||||
cobj->argcount = get_ut32 (buffer, &error);
|
||||
//cobj->kwonlyargcount = get_ut32 (buffer, &error);
|
||||
cobj->nlocals = get_ut32 (buffer, &error);
|
||||
cobj->stacksize = get_ut32 (buffer, &error);
|
||||
cobj->flags = get_ut32 (buffer, &error);
|
||||
|
||||
//to help disassemble the code
|
||||
cobj->start_offset = buffer->cur + 4;
|
||||
cobj->code = get_object (buffer);
|
||||
cobj->end_offset = buffer->cur;
|
||||
|
||||
cobj->consts = get_object (buffer);
|
||||
cobj->names = get_object (buffer);
|
||||
cobj->varnames = get_object (buffer);
|
||||
cobj->freevars = get_object (buffer);
|
||||
cobj->cellvars = get_object (buffer);
|
||||
cobj->filename = get_object (buffer);
|
||||
cobj->name = get_object (buffer);
|
||||
cobj->firstlineno = get_ut32 (buffer, &error);
|
||||
cobj->lnotab = get_object (buffer);
|
||||
if (error) {
|
||||
free_object (cobj->code);
|
||||
free_object (cobj->consts);
|
||||
free_object (cobj->names);
|
||||
free_object (cobj->varnames);
|
||||
free_object (cobj->freevars);
|
||||
free_object (cobj->cellvars);
|
||||
free_object (cobj->filename);
|
||||
free_object (cobj->name);
|
||||
free_object (cobj->lnotab);
|
||||
free (cobj);
|
||||
R_FREE (ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pyc_object *get_object (RBuffer *buffer) {
|
||||
bool error = false;
|
||||
pyc_object *ret = NULL;
|
||||
ut8 code = get_ut8 (buffer, &error);
|
||||
/* not need in python2
|
||||
ut8 flag = code & FLAG_REF;
|
||||
RListIter *ref_idx;
|
||||
*/
|
||||
ut8 type = code & ~FLAG_REF;
|
||||
|
||||
if (error)
|
||||
return NULL;
|
||||
|
||||
/* not need in python2
|
||||
if (flag) {
|
||||
ret = get_none_object ();
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ref_idx = r_list_append (refs, ret);
|
||||
if (!ref_idx) {
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
switch (type) {
|
||||
case TYPE_NULL:
|
||||
return NULL;
|
||||
case TYPE_TRUE:
|
||||
return get_true_object ();
|
||||
case TYPE_FALSE:
|
||||
return get_false_object ();
|
||||
case TYPE_NONE:
|
||||
return get_none_object ();
|
||||
/* not exists in python 2
|
||||
case TYPE_REF:
|
||||
return get_ref_object (buffer);
|
||||
|
||||
case TYPE_SMALL_TUPLE:
|
||||
ret = get_small_tuple_object (buffer);
|
||||
break;
|
||||
*/
|
||||
case TYPE_TUPLE:
|
||||
ret = get_tuple_object (buffer);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
ret = get_string_object (buffer);
|
||||
break;
|
||||
case TYPE_CODE_v1:
|
||||
ret = get_code_object (buffer);
|
||||
break;
|
||||
case TYPE_INT:
|
||||
ret = get_int_object (buffer);
|
||||
break;
|
||||
/* not exists in python2
|
||||
case TYPE_ASCII_INTERNED:
|
||||
ret = get_ascii_interned_object (buffer);
|
||||
break;
|
||||
case TYPE_SHORT_ASCII:
|
||||
ret = get_short_ascii_object (buffer);
|
||||
break;
|
||||
case TYPE_ASCII:
|
||||
ret = get_ascii_object (buffer);
|
||||
break;
|
||||
case TYPE_SHORT_ASCII_INTERNED:
|
||||
ret = get_short_ascii_interned_object (buffer);
|
||||
break;
|
||||
*/
|
||||
case TYPE_INT64:
|
||||
ret = get_int64_object(buffer);
|
||||
break;
|
||||
case TYPE_INTERNED:
|
||||
ret = get_interned_object(buffer);
|
||||
break;
|
||||
case TYPE_STRINGREF:
|
||||
ret = get_stringref_object(buffer);
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
ret = get_float_object(buffer);
|
||||
break;
|
||||
case TYPE_BINARY_FLOAT:
|
||||
ret = get_binary_float_object(buffer);
|
||||
break;
|
||||
case TYPE_COMPLEX:
|
||||
ret = get_complex_object(buffer);
|
||||
break;
|
||||
case TYPE_BINARY_COMPLEX:
|
||||
ret = get_binary_complex_object(buffer);
|
||||
break;
|
||||
case TYPE_LIST:
|
||||
ret = get_list_object(buffer);
|
||||
break;
|
||||
case TYPE_LONG:
|
||||
ret = get_long_object(buffer);
|
||||
break;
|
||||
case TYPE_UNICODE:
|
||||
ret = get_unicode_object(buffer);
|
||||
break;
|
||||
case TYPE_DICT:
|
||||
ret = get_dict_object(buffer);
|
||||
break;
|
||||
case TYPE_FROZENSET:
|
||||
case TYPE_SET:
|
||||
ret = get_set_object(buffer);
|
||||
break;
|
||||
case TYPE_STOPITER:
|
||||
ret = R_NEW0(pyc_object);
|
||||
break;
|
||||
case TYPE_ELLIPSIS:
|
||||
ret = R_NEW0(pyc_object);
|
||||
break;
|
||||
case TYPE_CODE_v0:
|
||||
case TYPE_UNKNOWN:
|
||||
eprintf ("Get not implemented for type 0x%x\n", type);
|
||||
return NULL;
|
||||
default:
|
||||
eprintf ("Undefined type in get_object (0x%x)\n", type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* for debugging purpose
|
||||
if (ret == NULL) {
|
||||
eprintf("***%d***\n", type);
|
||||
}
|
||||
*/
|
||||
|
||||
/* not need in python2
|
||||
if (flag) {
|
||||
free_object (ref_idx->data);
|
||||
ref_idx->data = copy_object (ret);
|
||||
}
|
||||
*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool extract_sections (pyc_object *obj, RList *sections, RList *cobjs, char *prefix) {
|
||||
pyc_code_object *cobj = NULL;
|
||||
RBinSection *section = NULL;
|
||||
RListIter *i = NULL;
|
||||
|
||||
//each code object is a section
|
||||
if (!obj || (obj->type != TYPE_CODE_v1))
|
||||
return false;
|
||||
cobj = obj->data;
|
||||
if (!cobj || !cobj->name)
|
||||
return false;
|
||||
if (cobj->name->type != TYPE_ASCII && cobj->name->type != TYPE_STRING && cobj->name->type != TYPE_INTERNED)
|
||||
return false;
|
||||
if (!cobj->name->data)
|
||||
return false;
|
||||
//add the cobj to objs list
|
||||
if (!r_list_append (cobjs, cobj))
|
||||
goto fail;
|
||||
section = R_NEW0 (RBinSection);
|
||||
prefix = r_str_newf ("%s%s%s", prefix ? prefix : "",
|
||||
prefix ? "." : "", cobj->name->data);
|
||||
if (!prefix || !section)
|
||||
goto fail;
|
||||
if (!strncpy ((char*)§ion->name, prefix, R_BIN_SIZEOF_STRINGS))
|
||||
goto fail;
|
||||
section->paddr = cobj->start_offset+1;
|
||||
section->vaddr = cobj->start_offset+1;
|
||||
section->size = cobj->end_offset - cobj->start_offset- 1;
|
||||
section->vsize = cobj->end_offset - cobj->start_offset - 1;
|
||||
if (!r_list_append (sections, section))
|
||||
goto fail;
|
||||
if (cobj->consts->type != TYPE_TUPLE)
|
||||
return false;
|
||||
r_list_foreach (((RList*)(cobj->consts->data)), i, obj)
|
||||
extract_sections (obj, sections, cobjs, prefix);
|
||||
free (prefix);
|
||||
return true;
|
||||
fail:
|
||||
|
||||
free (section);
|
||||
free (prefix);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool get_sections_from_code_objects(RBuffer *buffer, RList *sections, RList *cobjs) {
|
||||
bool ret;
|
||||
/* not need in python2
|
||||
refs = r_list_new ();
|
||||
refs->free = (RListFree)free_object;
|
||||
*/
|
||||
ret = extract_sections (get_object (buffer), sections, cobjs, NULL);
|
||||
/* not need in python2
|
||||
r_list_free (refs);
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/* radare - LGPL3 - Copyright 2016 - Matthieu (c0riolis) Tardy */
|
||||
|
||||
#ifndef MARSHAL_H
|
||||
#define MARSHAL_H
|
||||
|
||||
#include <r_util.h>
|
||||
#include <r_types.h>
|
||||
|
||||
typedef enum {
|
||||
TYPE_ASCII = 'a',
|
||||
TYPE_ASCII_INTERNED = 'A',
|
||||
TYPE_BINARY_COMPLEX = 'y',
|
||||
TYPE_BINARY_FLOAT = 'g',
|
||||
TYPE_CODE_v0 = 'C',
|
||||
TYPE_CODE_v1 = 'c',
|
||||
TYPE_COMPLEX = 'x',
|
||||
TYPE_DICT = '{',
|
||||
TYPE_ELLIPSIS = '.',
|
||||
TYPE_FALSE = 'F',
|
||||
TYPE_FLOAT = 'f',
|
||||
TYPE_FROZENSET = '>',
|
||||
TYPE_INT64 = 'I',
|
||||
TYPE_INTERNED = 't',
|
||||
TYPE_INT = 'i',
|
||||
TYPE_LIST = '[',
|
||||
TYPE_LONG = 'l',
|
||||
TYPE_NONE = 'N',
|
||||
TYPE_NULL = '0',
|
||||
TYPE_REF = 'r',
|
||||
TYPE_SET = '<',
|
||||
TYPE_SHORT_ASCII_INTERNED = 'Z',
|
||||
TYPE_SHORT_ASCII = 'z',
|
||||
TYPE_SMALL_TUPLE = ')',
|
||||
TYPE_STOPITER = 'S',
|
||||
TYPE_STRINGREF = 'R',
|
||||
TYPE_STRING = 's',
|
||||
TYPE_TRUE = 'T',
|
||||
TYPE_TUPLE = '(',
|
||||
TYPE_UNICODE = 'u',
|
||||
TYPE_UNKNOWN = '?',
|
||||
} pyc_marshal_type;
|
||||
|
||||
typedef enum {
|
||||
FLAG_REF = '\x80',
|
||||
} pyc_marshal_flag;
|
||||
|
||||
typedef struct {
|
||||
pyc_marshal_type type;
|
||||
void *data;
|
||||
} pyc_object;
|
||||
|
||||
typedef struct {
|
||||
ut32 argcount;
|
||||
ut32 kwonlyargcount;
|
||||
ut32 nlocals;
|
||||
ut32 stacksize;
|
||||
ut32 flags;
|
||||
pyc_object *code;
|
||||
pyc_object *consts;
|
||||
pyc_object *names;
|
||||
pyc_object *varnames;
|
||||
pyc_object *freevars;
|
||||
pyc_object *cellvars;
|
||||
pyc_object *filename;
|
||||
pyc_object *name;
|
||||
ut32 firstlineno;
|
||||
pyc_object *lnotab;
|
||||
st64 start_offset;
|
||||
st64 end_offset;
|
||||
} pyc_code_object;
|
||||
|
||||
bool get_sections_from_code_objects(RBuffer *buffer, RList *sections, RList *objs);
|
||||
|
||||
#endif
|
||||
@@ -1,150 +0,0 @@
|
||||
/* radare - LGPL3 - Copyright 2016 - Matthieu (c0riolis) Tardy */
|
||||
|
||||
#include "pyc.h"
|
||||
#include "marshal.h"
|
||||
|
||||
bool pyc_get_sections(RList *sections, RList *cobjs, RBuffer *buf, ut32 magic) {
|
||||
return get_sections_from_code_objects (buf, sections, cobjs);
|
||||
}
|
||||
|
||||
ut64 pyc_get_entrypoint(ut32 magic) {
|
||||
switch (magic) {
|
||||
case MAGIC_0_9_4_BETA:
|
||||
case MAGIC_0_9_9_v0:
|
||||
case MAGIC_0_9_9_v1:
|
||||
case MAGIC_0_9_9_v2:
|
||||
case MAGIC_1_0_1:
|
||||
case MAGIC_1_1:
|
||||
case MAGIC_1_2:
|
||||
case MAGIC_1_3_B1:
|
||||
case MAGIC_1_4_B1_v0:
|
||||
case MAGIC_1_4_B1_v1:
|
||||
case MAGIC_1_4:
|
||||
case MAGIC_1_5_A1:
|
||||
case MAGIC_1_6_A2:
|
||||
case MAGIC_2_0_B1_v0:
|
||||
case MAGIC_2_0_B1_v1_U:
|
||||
case MAGIC_2_0_B1_v2:
|
||||
case MAGIC_2_0_B1_v2_U:
|
||||
case MAGIC_2_0_B1_v3:
|
||||
case MAGIC_2_0_B1_v3_U:
|
||||
case MAGIC_2_0_B1_v4:
|
||||
case MAGIC_2_0_B1_v4_U:
|
||||
case MAGIC_2_0_B1_v5_U:
|
||||
case MAGIC_2_0_B1_v6_U:
|
||||
case MAGIC_2_1_A1:
|
||||
case MAGIC_2_1_A1_U:
|
||||
case MAGIC_2_1_A2:
|
||||
case MAGIC_2_1_A2_U:
|
||||
case MAGIC_2_2_A0:
|
||||
case MAGIC_2_2_A0_U:
|
||||
case MAGIC_2_2_A1:
|
||||
case MAGIC_2_2_A1_U:
|
||||
case MAGIC_2_3_A0_v0:
|
||||
case MAGIC_2_3_A0_v0_U:
|
||||
case MAGIC_2_3_A0_v1:
|
||||
case MAGIC_2_3_A0_v1_U:
|
||||
case MAGIC_2_3_A0_v2:
|
||||
case MAGIC_2_3_A0_v2_U:
|
||||
case MAGIC_2_4_A0_v0:
|
||||
case MAGIC_2_4_A0_v0_U:
|
||||
case MAGIC_2_4_A0_v1:
|
||||
case MAGIC_2_4_A0_v1_U:
|
||||
case MAGIC_2_4_A2:
|
||||
case MAGIC_2_4_A2_U:
|
||||
case MAGIC_2_4_A3:
|
||||
case MAGIC_2_4_A3_U:
|
||||
case MAGIC_2_5_A0_v0:
|
||||
case MAGIC_2_5_A0_v0_U:
|
||||
case MAGIC_2_5_A0_v1:
|
||||
case MAGIC_2_5_A0_v1_U:
|
||||
case MAGIC_2_5_A0_v2:
|
||||
case MAGIC_2_5_A0_v2_U:
|
||||
case MAGIC_2_5_A0_v3_U:
|
||||
case MAGIC_2_5_B2_v0:
|
||||
case MAGIC_2_5_B2_v0_U:
|
||||
case MAGIC_2_5_B2_v1:
|
||||
case MAGIC_2_5_B2_v1_U:
|
||||
case MAGIC_2_5_C3:
|
||||
case MAGIC_2_5_C3_U:
|
||||
case MAGIC_2_6_A0_v0:
|
||||
case MAGIC_2_6_A0_v0_U:
|
||||
case MAGIC_2_6_A0_v1:
|
||||
case MAGIC_2_6_A0_v1_U:
|
||||
case MAGIC_2_6_A0_v2:
|
||||
case MAGIC_2_6_A0_v2_U:
|
||||
case MAGIC_2_6_A1_PLUS_v0:
|
||||
case MAGIC_2_6_A1_PLUS_v0_U:
|
||||
case MAGIC_2_6_A1_PLUS_v1:
|
||||
case MAGIC_2_6_A1_PLUS_v1_U:
|
||||
case MAGIC_2_7_A0_v0:
|
||||
case MAGIC_2_7_A0_v0_U:
|
||||
case MAGIC_2_7_A0_v1:
|
||||
case MAGIC_2_7_A0_v1_U:
|
||||
case MAGIC_2_7_A0_v2:
|
||||
case MAGIC_2_7_A0_v2_U:
|
||||
case MAGIC_2_7_A2_PLUS_v0:
|
||||
case MAGIC_2_7_A2_PLUS_v0_U:
|
||||
case MAGIC_2_7_A2_PLUS_v1:
|
||||
case MAGIC_2_7_A2_PLUS_v1_U:
|
||||
case MAGIC_3_0X_v0:
|
||||
case MAGIC_3_0X_v0_U:
|
||||
case MAGIC_3_0X_v1:
|
||||
case MAGIC_3_0X_v1_U:
|
||||
case MAGIC_3_0X_v2:
|
||||
case MAGIC_3_0X_v2_U:
|
||||
case MAGIC_3_0X_v3:
|
||||
case MAGIC_3_0X_v3_U:
|
||||
case MAGIC_3_0X_v4:
|
||||
case MAGIC_3_0X_v4_U:
|
||||
case MAGIC_3_0X_v5:
|
||||
case MAGIC_3_0X_v5_U:
|
||||
case MAGIC_3_0X_v6:
|
||||
case MAGIC_3_0X_v6_U:
|
||||
case MAGIC_3_0_A1_v0:
|
||||
case MAGIC_3_0_A1_v0_U:
|
||||
case MAGIC_3_0_A1_v1:
|
||||
case MAGIC_3_0_A1_v1_U:
|
||||
case MAGIC_3_0_A1_PLUS:
|
||||
case MAGIC_3_0_A1_PLUS_U:
|
||||
case MAGIC_3_0_A2:
|
||||
case MAGIC_3_0_A2_U:
|
||||
case MAGIC_3_0_A2_PLUS:
|
||||
case MAGIC_3_0_A2_PLUS_U:
|
||||
case MAGIC_3_0_A3_PLUS:
|
||||
case MAGIC_3_0_A3_PLUS_U:
|
||||
case MAGIC_3_0_A5_PLUS:
|
||||
case MAGIC_3_0_A5_PLUS_U:
|
||||
case MAGIC_3_1_A0_v0:
|
||||
case MAGIC_3_1_A0_v0_U:
|
||||
case MAGIC_3_1_A0_v1:
|
||||
case MAGIC_3_1_A0_v1_U:
|
||||
case MAGIC_3_2_A0:
|
||||
case MAGIC_3_2_A0_U:
|
||||
case MAGIC_3_2_A1_PLUS_U:
|
||||
case MAGIC_3_2_A2_PLUS_U:
|
||||
case MAGIC_3_3_A0_U:
|
||||
case MAGIC_3_3_0_A0_v0_U:
|
||||
return 0x8;
|
||||
case MAGIC_3_3_0_A0_v1_U:
|
||||
case MAGIC_3_3_0_A1_PLUS_U:
|
||||
case MAGIC_3_3_0_A3_PLUS_U:
|
||||
case MAGIC_3_4_0_A0_v0_U:
|
||||
case MAGIC_3_4_0_A0_v1_U:
|
||||
case MAGIC_3_4_0_A0_v2_U:
|
||||
case MAGIC_3_4_0_A0_v3_U:
|
||||
case MAGIC_3_4_0_A0_v4_U:
|
||||
case MAGIC_3_4_0_A3_PLUS_v0_U:
|
||||
case MAGIC_3_4_0_A3_PLUS_v1_U:
|
||||
case MAGIC_3_4_0_RC1_PLUS_U:
|
||||
case MAGIC_3_5_0_A0_U:
|
||||
case MAGIC_3_5_0_A4_PLUS_U:
|
||||
case MAGIC_3_5_0_B1_PLUS_U:
|
||||
case MAGIC_3_5_0_B2_PLUS_U:
|
||||
case MAGIC_3_6_0_A0_v0_U:
|
||||
case MAGIC_3_6_0_A0_v1_U:
|
||||
return 0xc;
|
||||
default:
|
||||
return 0x0;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
/* radare - LGPL3 - Copyright 2016 - Matthieu (c0riolis) Tardy */
|
||||
|
||||
#ifndef PYC_H
|
||||
#define PYC_H
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_bin.h>
|
||||
#include "pyc_magic.h"
|
||||
|
||||
bool pyc_get_sections(RList *sections, RList* mem, RBuffer *buf, ut32 magic);
|
||||
ut64 pyc_get_entrypoint(ut32 magic);
|
||||
|
||||
#endif
|
||||
@@ -1,156 +0,0 @@
|
||||
/* radare - LGPL3 - Copyright 2016 - Matthieu (c0riolis) Tardy */
|
||||
|
||||
#include "pyc_magic.h"
|
||||
|
||||
static struct pyc_version versions[] = {
|
||||
{MAGIC_0_9_4_BETA, "0.9.4 beta", "77b80a91d357c1d95d8e7cd4cbbe799e5deb777e", false},
|
||||
{MAGIC_0_9_9_v0, "0.9.9", "1cabc2b6c9701aea29bb506b593946e67bf7593a", false},
|
||||
{MAGIC_0_9_9_v1, "0.9.9", "f820e6917f07e5012bdd103ef97389318d5a10f8", false},
|
||||
{MAGIC_0_9_9_v2, "0.9.9", "9fed5726a36d7ce1355c30592838d93321d580ee", false},
|
||||
{MAGIC_1_0_1, "1.0.1", "1808ca5d8883097c72c6a8a89143041c20ea13c1", false},
|
||||
{MAGIC_1_1, "1.1", "d1e6c9a64a563841f60177ac907739f953f15630", false},
|
||||
{MAGIC_1_2, "1.2", "fb3daf9b2456dc1a3d99f56f78c5e6270eeaf1e8", false},
|
||||
{MAGIC_1_3_B1, "1.3b1", "0261bf5b3819b03d83f254562947244634604026", false},
|
||||
{MAGIC_1_4_B1_v0, "1.4b1", "d1ae0ea9a585f912d7aa3d004ff817d0dea112f8", false},
|
||||
{MAGIC_1_4_B1_v1, "1.4b1", "22e29b1747e139d9598eaa5126c59313af39949d", false},
|
||||
{MAGIC_1_4, "1.4", "b82d847b3dcbccd63de075e3879a9369dfb34e0d", false},
|
||||
{MAGIC_1_5_A1, "1.5a1", "104a646fc7a67f27df25d4e941b20035e5876f9f", false},
|
||||
{MAGIC_1_6_A2, "1.6a2", "84cd52b560e571eba371d7136abcc9c42c27b002", false},
|
||||
{MAGIC_2_0_B1_v0, "2.0b1", "f79434ee41fa86019216240ba32be660bcfc5419", false},
|
||||
{MAGIC_2_0_B1_v1, "2.0b1", "4388249506d190a76a4dbbbc70294ef6ba0656d5", false},
|
||||
{MAGIC_2_0_B1_v1_U, "2.0b1", "4388249506d190a76a4dbbbc70294ef6ba0656d5", true,},
|
||||
{MAGIC_2_0_B1_v2, "2.0b1", "4eaa463c031a1bdb5e7791c370d04108e0682dd4", false},
|
||||
{MAGIC_2_0_B1_v2_U, "2.0b1", "4eaa463c031a1bdb5e7791c370d04108e0682dd4", true },
|
||||
{MAGIC_2_0_B1_v3, "2.0b1", "18385172fac0b7099bd2d2264df614ed4466f083", false},
|
||||
{MAGIC_2_0_B1_v3_U, "2.0b1", "18385172fac0b7099bd2d2264df614ed4466f083", true },
|
||||
{MAGIC_2_0_B1_v4, "2.0b1", "f657dc8ff25e93b877305bbcfc45e360191bb326", false},
|
||||
{MAGIC_2_0_B1_v4_U, "2.0b1", "f657dc8ff25e93b877305bbcfc45e360191bb326", true },
|
||||
{MAGIC_2_0_B1_v5, "2.0b1", "1b9fd0cbd914947cc421ba7e45aa093d7ba9af00", false},
|
||||
{MAGIC_2_0_B1_v5_U, "2.0b1", "1b9fd0cbd914947cc421ba7e45aa093d7ba9af00", true },
|
||||
{MAGIC_2_0_B1_v6, "2.0b1", "1f1a156ed5af8f7a50ce05fc85f85423a24f2aa4", false},
|
||||
{MAGIC_2_0_B1_v6_U, "2.0b1", "1f1a156ed5af8f7a50ce05fc85f85423a24f2aa4", true },
|
||||
{MAGIC_2_1_A1, "2.1a1", "fd8c7203251ff37dbb397f7d423ae41f16a03c68", false},
|
||||
{MAGIC_2_1_A1_U, "2.1a1", "fd8c7203251ff37dbb397f7d423ae41f16a03c68", true },
|
||||
{MAGIC_2_1_A2, "2.1a2", "0076e8d28f9eba9eff4508696dc33730af2b4001", false},
|
||||
{MAGIC_2_1_A2_U, "2.1a2", "0076e8d28f9eba9eff4508696dc33730af2b4001", true },
|
||||
{MAGIC_2_2_A0, "2.2a0", "32e7d0898eab85de8134f932680a85c6e7abcec0", false},
|
||||
{MAGIC_2_2_A0_U, "2.2a0", "32e7d0898eab85de8134f932680a85c6e7abcec0", true },
|
||||
{MAGIC_2_2_A1, "2.2a1", "09df3254b49d7c9306585302fe815ab0bdb53439", false},
|
||||
{MAGIC_2_2_A1_U, "2.2a1", "09df3254b49d7c9306585302fe815ab0bdb53439", true },
|
||||
{MAGIC_2_3_A0_v0, "2.3a0", "abedb2418f6231adf24205092a59996f1f1e4c02", false},
|
||||
{MAGIC_2_3_A0_v0_U, "2.3a0", "abedb2418f6231adf24205092a59996f1f1e4c02", true },
|
||||
{MAGIC_2_3_A0_v1, "2.3a0", "d6ae544acd24a1f72ce00534fed464fde91ee504", false},
|
||||
{MAGIC_2_3_A0_v1_U, "2.3a0", "d6ae544acd24a1f72ce00534fed464fde91ee504", true },
|
||||
{MAGIC_2_3_A0_v2, "2.3a0", "cf5928fab108de9fbe02632d07176c717c2b3aa7", false},
|
||||
{MAGIC_2_3_A0_v2_U, "2.3a0", "cf5928fab108de9fbe02632d07176c717c2b3aa7", true },
|
||||
{MAGIC_2_3_A0_v3, "2.3a0", "5fe4d93df429134ef8695c12e59ff962ff8b73d2", false},
|
||||
{MAGIC_2_3_A0_v3_U, "2.3a0", "5fe4d93df429134ef8695c12e59ff962ff8b73d2", true },
|
||||
{MAGIC_2_4_A0_v0, "2.4a0", "adb42a71169604d3609ac2fbdb64cf8cd1c7250b", false},
|
||||
{MAGIC_2_4_A0_v0_U, "2.4a0", "adb42a71169604d3609ac2fbdb64cf8cd1c7250b", true },
|
||||
{MAGIC_2_4_A0_v1, "2.4a0", "3df36e2e5ddc1149af8eb52e20bc225d806236d4", false},
|
||||
{MAGIC_2_4_A0_v1_U, "2.4a0", "3df36e2e5ddc1149af8eb52e20bc225d806236d4", true },
|
||||
{MAGIC_2_4_A2, "2.4a2", "1f9b9c226b43ed20cb61e6d21aea6cb966e8bcd3", false},
|
||||
{MAGIC_2_4_A2_U, "2.4a2", "1f9b9c226b43ed20cb61e6d21aea6cb966e8bcd3", true },
|
||||
{MAGIC_2_4_A3, "2.4a3", "2b49b4a85d9eb4a4cfa9f29c21d649c383945671", false},
|
||||
{MAGIC_2_4_A3_U, "2.4a3", "2b49b4a85d9eb4a4cfa9f29c21d649c383945671", true },
|
||||
{MAGIC_2_5_A0_v0, "2.5a0", "44e3f21f052590ddfabc12909af5188a4cd89d8c", false},
|
||||
{MAGIC_2_5_A0_v0_U, "2.5a0", "44e3f21f052590ddfabc12909af5188a4cd89d8c", true },
|
||||
{MAGIC_2_5_A0_v1, "2.5a0", "eb15cdd4a2f1001792074ca0789026989452ff82", false},
|
||||
{MAGIC_2_5_A0_v1_U, "2.5a0", "eb15cdd4a2f1001792074ca0789026989452ff82", true },
|
||||
{MAGIC_2_5_A0_v2, "2.5a0", "b6d2f6fd3e116b9b9fe95bc982ac763c359ff103", false},
|
||||
{MAGIC_2_5_A0_v2_U, "2.5a0", "b6d2f6fd3e116b9b9fe95bc982ac763c359ff103", true },
|
||||
{MAGIC_2_5_A0_v3, "2.5a0", "5c36c222e7ca5310e5cc8b8db283bd669d1e24d4", false},
|
||||
{MAGIC_2_5_A0_v3_U, "2.5a0", "5c36c222e7ca5310e5cc8b8db283bd669d1e24d4", true },
|
||||
{MAGIC_2_5_B2_v0, "2.5b2", "2c3ec720aa7beb0da4002b847cc5ed7dc782566c", false},
|
||||
{MAGIC_2_5_B2_v0_U, "2.5b2", "2c3ec720aa7beb0da4002b847cc5ed7dc782566c", true },
|
||||
{MAGIC_2_5_B2_v1, "2.5b2", "b745b3fd66a649a5fa540bdf47971c26af0a959e", false},
|
||||
{MAGIC_2_5_B2_v1_U, "2.5b2", "b745b3fd66a649a5fa540bdf47971c26af0a959e", true },
|
||||
{MAGIC_2_5_C3, "2.5c3", "b90a8b0395bd43fd193842451d0c49573b4d7166", false},
|
||||
{MAGIC_2_5_C3_U, "2.5c3", "b90a8b0395bd43fd193842451d0c49573b4d7166", true },
|
||||
{MAGIC_2_6_A0_v0, "2.6a0", "8dcb882ec3e1aac7d336a40aa64ec66561fc3dec", false},
|
||||
{MAGIC_2_6_A0_v0_U, "2.6a0", "8dcb882ec3e1aac7d336a40aa64ec66561fc3dec", true },
|
||||
{MAGIC_2_6_A0_v1, "2.6a0", "3985d7e2067db75f170e0891994b0fd70963e40b", false},
|
||||
{MAGIC_2_6_A0_v1_U, "2.6a0", "3985d7e2067db75f170e0891994b0fd70963e40b", true },
|
||||
{MAGIC_2_6_A0_v2, "2.6a0", "07aa19170a673da6b3e8c4c66bfd868b2f90c0e4", false},
|
||||
{MAGIC_2_6_A0_v2_U, "2.6a0", "07aa19170a673da6b3e8c4c66bfd868b2f90c0e4", true },
|
||||
{MAGIC_2_6_A1_PLUS_v0, "2.6a1+", "343597c7d682b3552580352deddd0cdb36978a04", false},
|
||||
{MAGIC_2_6_A1_PLUS_v0_U, "2.6a1+", "343597c7d682b3552580352deddd0cdb36978a04", true },
|
||||
{MAGIC_2_6_A1_PLUS_v1, "2.6a1+", "eac41f90296c69c6d07d29f1feb453a4c0e400d1", false},
|
||||
{MAGIC_2_6_A1_PLUS_v1_U, "2.6a1+", "eac41f90296c69c6d07d29f1feb453a4c0e400d1", true },
|
||||
{MAGIC_2_6_A1_PLUS_v2, "2.6a1+", "a0ea3a0efc710934ad66e3907211230ff227d6a1", false},
|
||||
{MAGIC_2_6_A1_PLUS_v2_U, "2.6a1+", "a0ea3a0efc710934ad66e3907211230ff227d6a1", true },
|
||||
{MAGIC_2_7_A0_v0, "2.7a0", "94e79d78dff0dfb5c53f49842c7df65ad5b79e66", false},
|
||||
{MAGIC_2_7_A0_v0_U, "2.7a0", "94e79d78dff0dfb5c53f49842c7df65ad5b79e66", true },
|
||||
{MAGIC_2_7_A0_v1, "2.7a0", "ef8fe90886968b1eb468cb91ebae103f773fa17f", false},
|
||||
{MAGIC_2_7_A0_v1_U, "2.7a0", "ef8fe90886968b1eb468cb91ebae103f773fa17f", true },
|
||||
{MAGIC_2_7_A0_v2, "2.7a0", "145376df3ad728f7052fdd8b6eba600a8317fece", false},
|
||||
{MAGIC_2_7_A0_v2_U, "2.7a0", "145376df3ad728f7052fdd8b6eba600a8317fece", true },
|
||||
{MAGIC_2_7_A2_PLUS_v0, "2.7a2+", "c2fdf25329ff30cf8d68c0c0e7cf479d7b203745", false},
|
||||
{MAGIC_2_7_A2_PLUS_v0_U, "2.7a2+", "c2fdf25329ff30cf8d68c0c0e7cf479d7b203745", true },
|
||||
{MAGIC_2_7_A2_PLUS_v1, "2.7a2+", "edfed0e32cedf3b84c6e999052486a750a3f5bee", false},
|
||||
{MAGIC_2_7_A2_PLUS_v1_U, "2.7a2+", "edfed0e32cedf3b84c6e999052486a750a3f5bee", true },
|
||||
{MAGIC_3_0X_v0, "3.0x", "49c6eb688906b1dddabf578f08129e6729d6151f", false},
|
||||
{MAGIC_3_0X_v0_U, "3.0x", "49c6eb688906b1dddabf578f08129e6729d6151f", true },
|
||||
{MAGIC_3_0X_v1, "3.0x", "f87a3e61853d72b1d133992f991e397b31aac8e8", false},
|
||||
{MAGIC_3_0X_v1_U, "3.0x", "f87a3e61853d72b1d133992f991e397b31aac8e8", true },
|
||||
{MAGIC_3_0X_v2, "3.0x", "d0b83c4630c0924df661063543f3c5478c8c35ac", false},
|
||||
{MAGIC_3_0X_v2_U, "3.0x", "d0b83c4630c0924df661063543f3c5478c8c35ac", true },
|
||||
{MAGIC_3_0X_v3, "3.0x", "1cce0526d9b0a53f4ff95713dde153dc70dae2dc", false},
|
||||
{MAGIC_3_0X_v3_U, "3.0x", "1cce0526d9b0a53f4ff95713dde153dc70dae2dc", true },
|
||||
{MAGIC_3_0X_v4, "3.0x", "7a35d3d1ac5a301ef3dc52f9140844f0422011a5", false},
|
||||
{MAGIC_3_0X_v4_U, "3.0x", "7a35d3d1ac5a301ef3dc52f9140844f0422011a5", true },
|
||||
{MAGIC_3_0X_v5, "3.0x", "793e0323d4d65bfc89b40d78162cd771c575a18e", false},
|
||||
{MAGIC_3_0X_v5_U, "3.0x", "793e0323d4d65bfc89b40d78162cd771c575a18e", true },
|
||||
{MAGIC_3_0X_v6, "3.0x", "19f7ff443718f7a9da1aea9edbf00a135f860883", false},
|
||||
{MAGIC_3_0X_v6_U, "3.0x", "19f7ff443718f7a9da1aea9edbf00a135f860883", true },
|
||||
{MAGIC_3_0_A1_v0, "3.0a1", "a89d469e1ff77716914ce1a4244fa529a71ce68a", false},
|
||||
{MAGIC_3_0_A1_v0_U, "3.0a1", "a89d469e1ff77716914ce1a4244fa529a71ce68a", true },
|
||||
{MAGIC_3_0_A1_v1, "3.0a1", "19319e70fc3edbb45b2d007161c1b3a1de094181", false},
|
||||
{MAGIC_3_0_A1_v1_U, "3.0a1", "19319e70fc3edbb45b2d007161c1b3a1de094181", true },
|
||||
{MAGIC_3_0_A1_PLUS, "3.0a1+", "0d462d789b18ec6a59ebe2116688d5b6985c215d", false},
|
||||
{MAGIC_3_0_A1_PLUS_U, "3.0a1+", "0d462d789b18ec6a59ebe2116688d5b6985c215d", true },
|
||||
{MAGIC_3_0_A2, "3.0a2", "4dc01402d78afe2c9b4a4bd8004eb08e2647335d", false},
|
||||
{MAGIC_3_0_A2_U, "3.0a2", "4dc01402d78afe2c9b4a4bd8004eb08e2647335d", true },
|
||||
{MAGIC_3_0_A2_PLUS, "3.0a2+", "73e1bf179a01ad7824ff5aa2b29ce068a457cd67", false},
|
||||
{MAGIC_3_0_A2_PLUS_U, "3.0a2+", "73e1bf179a01ad7824ff5aa2b29ce068a457cd67", true },
|
||||
{MAGIC_3_0_A3_PLUS, "3.0a3+", "832c820e9d144cb76c8778ad6fcffe232b1f5c46", false},
|
||||
{MAGIC_3_0_A3_PLUS_U, "3.0a3+", "832c820e9d144cb76c8778ad6fcffe232b1f5c46", true },
|
||||
{MAGIC_3_0_A5_PLUS, "3.0a5+", "212a1fee6bf93f8b74f81dd3567bf964e627ea20", false},
|
||||
{MAGIC_3_0_A5_PLUS_U, "3.0a5+", "212a1fee6bf93f8b74f81dd3567bf964e627ea20", true },
|
||||
{MAGIC_3_1_A0_v0, "3.1a0", "2ee4653927f72f9bb3ff14b3083d4a203d684dfc", false},
|
||||
{MAGIC_3_1_A0_v0_U, "3.1a0", "2ee4653927f72f9bb3ff14b3083d4a203d684dfc", true },
|
||||
{MAGIC_3_1_A0_v1, "3.1a0", "643d8d4fc8ebcc69155d3416357aadca9c053388", false},
|
||||
{MAGIC_3_1_A0_v1_U, "3.1a0", "643d8d4fc8ebcc69155d3416357aadca9c053388", true },
|
||||
{MAGIC_3_2_A0, "3.2a0", "3aaf2e065db05401803705ed4bfa3fd2f9030df8", false},
|
||||
{MAGIC_3_2_A0_U, "3.2a0", "3aaf2e065db05401803705ed4bfa3fd2f9030df8", true },
|
||||
{MAGIC_3_2_A1_PLUS_U, "3.2a1+", "72523121127327c022096d30e7b28a4a5a89495d", true },
|
||||
{MAGIC_3_2_A2_PLUS_U, "3.2a2+", "252895d491570d5a27452809b582717be409b24d", true },
|
||||
{MAGIC_3_3_A0_U, "3.3a0", "9a6d9ac6fb2e1bb15bbb4e8c2a6c939d07088477", true },
|
||||
{MAGIC_3_3_0_A0_v0_U, "3.3.0a0", "e1dbc72bd97f36c1aed7e3ba2a58278f4da807be", true },
|
||||
{MAGIC_3_3_0_A0_v1_U, "3.3.0a0", "87331661042b89022f6f49506ae9c1ae459a95be", true },
|
||||
{MAGIC_3_3_0_A1_PLUS_U, "3.3.0a1+", "c0a6569fdad624cc89cdd24b68331dc2a9b64827", true },
|
||||
{MAGIC_3_3_0_A3_PLUS_U, "3.3.0a3+", "96ab78ef82a775da11a538fc47aebe70d9c34f04", true },
|
||||
{MAGIC_3_4_0_A0_v0_U, "3.4.0a0", "d296cf1600a8c2c7098737944b5ee793b67a6883", true },
|
||||
{MAGIC_3_4_0_A0_v1_U, "3.4.0a0", "2528e4aea33801b40ec902a77b5451ebc925a331", true },
|
||||
{MAGIC_3_4_0_A0_v2_U, "3.4.0a0", "cf65c7a75f558e6cd68903f4c2800f6b9574a35f", true },
|
||||
{MAGIC_3_4_0_A0_v3_U, "3.4.0a0", "3d858f1eef546e6adb2c073be9384065cfc2537e", true },
|
||||
{MAGIC_3_4_0_A0_v4_U, "3.4.0a0", "6db3741e59be2b6427032a0f51d8a06625d64c28", true },
|
||||
{MAGIC_3_4_0_A3_PLUS_v0_U, "3.4.0a3+", "35b384ed594b4618a7ea345dad7d2149eabcf3e7", true },
|
||||
{MAGIC_3_4_0_A3_PLUS_v1_U, "3.4.0a3+", "bb2affc1e317a85c4edfe450c119bdec851a08ee", true },
|
||||
{MAGIC_3_4_0_RC1_PLUS_U, "3.4.0rc1+", "e301a515f8f4c5cdde3b9726ec298bd4de1af963", true },
|
||||
{MAGIC_3_5_0_A0_U, "3.5.0a0", "c553d8f72d659b3bc14fe326662ba53ca97bf38a", true },
|
||||
{MAGIC_3_5_0_A4_PLUS_U, "3.5.0a4+", "a65f685ba8c011bf117cadf26c13ab7a0cbb122c", true },
|
||||
{MAGIC_3_5_0_B1_PLUS_U, "3.5.0b1+", "6f05f83c7010764aff53793fbff162c42018f57e", true },
|
||||
{MAGIC_3_5_0_B2_PLUS_U, "3.5.0b2+", "7a0a1a4ac63942f4ea3c7804e323adf668d40a21", true },
|
||||
{MAGIC_3_6_0_A0_v0_U, "3.6.0a0", "1ddeb2e175df5009571b3632a709c6b74995cb29", true },
|
||||
{MAGIC_3_6_0_A0_v1_U, "3.6.0a0", "775b74e0e103f816382a0fc009b6ac51ea956750", true },
|
||||
};
|
||||
|
||||
struct pyc_version get_pyc_version(ut32 magic) {
|
||||
struct pyc_version fail = {-1, 0, 0, false};
|
||||
ut32 i;
|
||||
for (i = 0; i < sizeof (versions) / sizeof (*versions); ++i)
|
||||
if (versions[i].magic == magic)
|
||||
return versions[i];
|
||||
return fail;
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
/* radare - LGPL3 - Copyright 2016 - Matthieu (c0riolis) Tardy */
|
||||
|
||||
#ifndef PYC_MAGIC_H
|
||||
#define PYC_MAGIC_H
|
||||
|
||||
#include <r_types.h>
|
||||
|
||||
#define MAGIC_0_9_4_BETA 0x00949494
|
||||
#define MAGIC_0_9_9_v0 0x0099be2a
|
||||
#define MAGIC_0_9_9_v1 0x0099be3a
|
||||
#define MAGIC_0_9_9_v2 0x00999901
|
||||
#define MAGIC_1_0_1 0x00999902
|
||||
#define MAGIC_1_1 0x00999903
|
||||
#define MAGIC_1_2 0x0a0d4127
|
||||
#define MAGIC_1_3_B1 0x0a0d2e89
|
||||
#define MAGIC_1_4_B1_v0 0x0a0d0767
|
||||
#define MAGIC_1_4_B1_v1 0x0a0d1704
|
||||
#define MAGIC_1_4 0x0a0d4e95
|
||||
#define MAGIC_1_5_A1 0x0a0d4e99
|
||||
#define MAGIC_1_6_A2 0x0a0dc4fc
|
||||
#define MAGIC_2_0_B1_v0 0x0a0dc61b
|
||||
#define MAGIC_2_0_B1_v1 0x0a0dc4fc
|
||||
#define MAGIC_2_0_B1_v1_U 0x0a0dc4fd
|
||||
#define MAGIC_2_0_B1_v2 0x0a0dc67b
|
||||
#define MAGIC_2_0_B1_v2_U 0x0a0dc67c
|
||||
#define MAGIC_2_0_B1_v3 0x0a0dc67f
|
||||
#define MAGIC_2_0_B1_v3_U 0x0a0dc680
|
||||
#define MAGIC_2_0_B1_v4 0x0a0dc685
|
||||
#define MAGIC_2_0_B1_v4_U 0x0a0dc686
|
||||
#define MAGIC_2_0_B1_v5 0x0a0dc686
|
||||
#define MAGIC_2_0_B1_v5_U 0x0a0dc687
|
||||
#define MAGIC_2_0_B1_v6 0x0a0dc687
|
||||
#define MAGIC_2_0_B1_v6_U 0x0a0dc688
|
||||
#define MAGIC_2_1_A1 0x0a0deadc
|
||||
#define MAGIC_2_1_A1_U 0x0a0deadd
|
||||
#define MAGIC_2_1_A2 0x0a0deb2a
|
||||
#define MAGIC_2_1_A2_U 0x0a0deb2b
|
||||
#define MAGIC_2_2_A0 0x0a0dec04
|
||||
#define MAGIC_2_2_A0_U 0x0a0dec05
|
||||
#define MAGIC_2_2_A1 0x0a0ded2d
|
||||
#define MAGIC_2_2_A1_U 0x0a0ded2e
|
||||
#define MAGIC_2_3_A0_v0 0x0a0df231
|
||||
#define MAGIC_2_3_A0_v0_U 0x0a0df232
|
||||
#define MAGIC_2_3_A0_v1 0x0a0df23b
|
||||
#define MAGIC_2_3_A0_v1_U 0x0a0df23c
|
||||
#define MAGIC_2_3_A0_v2 0x0a0df245
|
||||
#define MAGIC_2_3_A0_v2_U 0x0a0df246
|
||||
#define MAGIC_2_3_A0_v3 0x0a0df23b
|
||||
#define MAGIC_2_3_A0_v3_U 0x0a0df23c
|
||||
#define MAGIC_2_4_A0_v0 0x0a0df24f
|
||||
#define MAGIC_2_4_A0_v0_U 0x0a0df250
|
||||
#define MAGIC_2_4_A0_v1 0x0a0df259
|
||||
#define MAGIC_2_4_A0_v1_U 0x0a0df25a
|
||||
#define MAGIC_2_4_A2 0x0a0df263
|
||||
#define MAGIC_2_4_A2_U 0x0a0df264
|
||||
#define MAGIC_2_4_A3 0x0a0df26d
|
||||
#define MAGIC_2_4_A3_U 0x0a0df26e
|
||||
#define MAGIC_2_5_A0_v0 0x0a0df277
|
||||
#define MAGIC_2_5_A0_v0_U 0x0a0df278
|
||||
#define MAGIC_2_5_A0_v1 0x0a0df281
|
||||
#define MAGIC_2_5_A0_v1_U 0x0a0df282
|
||||
#define MAGIC_2_5_A0_v2 0x0a0df28b
|
||||
#define MAGIC_2_5_A0_v2_U 0x0a0df28c
|
||||
#define MAGIC_2_5_A0_v3 0x0a0df28c
|
||||
#define MAGIC_2_5_A0_v3_U 0x0a0df28d
|
||||
#define MAGIC_2_5_B2_v0 0x0a0df295
|
||||
#define MAGIC_2_5_B2_v0_U 0x0a0df296
|
||||
#define MAGIC_2_5_B2_v1 0x0a0df29f
|
||||
#define MAGIC_2_5_B2_v1_U 0x0a0df2a0
|
||||
#define MAGIC_2_5_C3 0x0a0df2a9
|
||||
#define MAGIC_2_5_C3_U 0x0a0df2aa
|
||||
#define MAGIC_2_6_A0_v0 0x0a0df2b3
|
||||
#define MAGIC_2_6_A0_v0_U 0x0a0df2b4
|
||||
#define MAGIC_2_6_A0_v1 0x0a0df2bd
|
||||
#define MAGIC_2_6_A0_v1_U 0x0a0df2be
|
||||
#define MAGIC_2_6_A0_v2 0x0a0df2c7
|
||||
#define MAGIC_2_6_A0_v2_U 0x0a0df2c8
|
||||
#define MAGIC_2_6_A1_PLUS_v0 0x0a0df2d1
|
||||
#define MAGIC_2_6_A1_PLUS_v0_U 0x0a0df2d2
|
||||
#define MAGIC_2_6_A1_PLUS_v1 0x0a0df2d3
|
||||
#define MAGIC_2_6_A1_PLUS_v1_U 0x0a0df2d4
|
||||
#define MAGIC_2_6_A1_PLUS_v2 0x0a0df2d1
|
||||
#define MAGIC_2_6_A1_PLUS_v2_U 0x0a0df2d2
|
||||
#define MAGIC_2_7_A0_v0 0x0a0df2db
|
||||
#define MAGIC_2_7_A0_v0_U 0x0a0df2dc
|
||||
#define MAGIC_2_7_A0_v1 0x0a0df2e5
|
||||
#define MAGIC_2_7_A0_v1_U 0x0a0df2e6
|
||||
#define MAGIC_2_7_A0_v2 0x0a0df2ef
|
||||
#define MAGIC_2_7_A0_v2_U 0x0a0df2f0
|
||||
#define MAGIC_2_7_A2_PLUS_v0 0x0a0df2f9
|
||||
#define MAGIC_2_7_A2_PLUS_v0_U 0x0a0df2fa
|
||||
#define MAGIC_2_7_A2_PLUS_v1 0x0a0df303
|
||||
#define MAGIC_2_7_A2_PLUS_v1_U 0x0a0df304
|
||||
#define MAGIC_3_0X_v0 0x0a0d0bb8
|
||||
#define MAGIC_3_0X_v0_U 0x0a0d0bb9
|
||||
#define MAGIC_3_0X_v1 0x0a0d0bc2
|
||||
#define MAGIC_3_0X_v1_U 0x0a0d0bc3
|
||||
#define MAGIC_3_0X_v2 0x0a0d0bcc
|
||||
#define MAGIC_3_0X_v2_U 0x0a0d0bcd
|
||||
#define MAGIC_3_0X_v3 0x0a0d0bd6
|
||||
#define MAGIC_3_0X_v3_U 0x0a0d0bd7
|
||||
#define MAGIC_3_0X_v4 0x0a0d0be0
|
||||
#define MAGIC_3_0X_v4_U 0x0a0d0be1
|
||||
#define MAGIC_3_0X_v5 0x0a0d0bea
|
||||
#define MAGIC_3_0X_v5_U 0x0a0d0beb
|
||||
#define MAGIC_3_0X_v6 0x0a0d0bf4
|
||||
#define MAGIC_3_0X_v6_U 0x0a0d0bf5
|
||||
#define MAGIC_3_0_A1_v0 0x0a0d0bfe
|
||||
#define MAGIC_3_0_A1_v0_U 0x0a0d0bff
|
||||
#define MAGIC_3_0_A1_v1 0x0a0d0c08
|
||||
#define MAGIC_3_0_A1_v1_U 0x0a0d0c09
|
||||
#define MAGIC_3_0_A1_PLUS 0x0a0d0c12
|
||||
#define MAGIC_3_0_A1_PLUS_U 0x0a0d0c13
|
||||
#define MAGIC_3_0_A2 0x0a0d0c1c
|
||||
#define MAGIC_3_0_A2_U 0x0a0d0c1d
|
||||
#define MAGIC_3_0_A2_PLUS 0x0a0d0c1e
|
||||
#define MAGIC_3_0_A2_PLUS_U 0x0a0d0c1f
|
||||
#define MAGIC_3_0_A3_PLUS 0x0a0d0c26
|
||||
#define MAGIC_3_0_A3_PLUS_U 0x0a0d0c27
|
||||
#define MAGIC_3_0_A5_PLUS 0x0a0d0c3a
|
||||
#define MAGIC_3_0_A5_PLUS_U 0x0a0d0c3b
|
||||
#define MAGIC_3_1_A0_v0 0x0a0d0c44
|
||||
#define MAGIC_3_1_A0_v0_U 0x0a0d0c45
|
||||
#define MAGIC_3_1_A0_v1 0x0a0d0c4e
|
||||
#define MAGIC_3_1_A0_v1_U 0x0a0d0c4f
|
||||
#define MAGIC_3_2_A0 0x0a0d0c58
|
||||
#define MAGIC_3_2_A0_U 0x0a0d0c59
|
||||
#define MAGIC_3_2_A1_PLUS_U 0x0a0d0c62
|
||||
#define MAGIC_3_2_A2_PLUS_U 0x0a0d0c6c
|
||||
#define MAGIC_3_3_A0_U 0x0a0d0c76
|
||||
#define MAGIC_3_3_0_A0_v0_U 0x0a0d0c80
|
||||
#define MAGIC_3_3_0_A0_v1_U 0x0a0d0c8a
|
||||
#define MAGIC_3_3_0_A1_PLUS_U 0x0a0d0c94
|
||||
#define MAGIC_3_3_0_A3_PLUS_U 0x0a0d0c9e
|
||||
#define MAGIC_3_4_0_A0_v0_U 0x0a0d0ca8
|
||||
#define MAGIC_3_4_0_A0_v1_U 0x0a0d0cb2
|
||||
#define MAGIC_3_4_0_A0_v2_U 0x0a0d0cbc
|
||||
#define MAGIC_3_4_0_A0_v3_U 0x0a0d0cc6
|
||||
#define MAGIC_3_4_0_A0_v4_U 0x0a0d0cd0
|
||||
#define MAGIC_3_4_0_A3_PLUS_v0_U 0x0a0d0cda
|
||||
#define MAGIC_3_4_0_A3_PLUS_v1_U 0x0a0d0ce4
|
||||
#define MAGIC_3_4_0_RC1_PLUS_U 0x0a0d0cee
|
||||
#define MAGIC_3_5_0_A0_U 0x0a0d0cf8
|
||||
#define MAGIC_3_5_0_A4_PLUS_U 0x0a0d0d02
|
||||
#define MAGIC_3_5_0_B1_PLUS_U 0x0a0d0d0c
|
||||
#define MAGIC_3_5_0_B2_PLUS_U 0x0a0d0d16
|
||||
#define MAGIC_3_6_0_A0_v0_U 0x0a0d0d20
|
||||
#define MAGIC_3_6_0_A0_v1_U 0x0a0d0d21
|
||||
|
||||
struct pyc_version {
|
||||
ut32 magic;
|
||||
char *version;
|
||||
char *revision;
|
||||
bool unicode;
|
||||
};
|
||||
|
||||
struct pyc_version get_pyc_version(ut32 magic);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,85 @@
|
||||
/* radare - LGPL - 2015 - maijin */
|
||||
|
||||
#ifndef _SPC_H
|
||||
#define _SPC_H
|
||||
|
||||
#define SPC_MAGIC "SNES-SPC700 Sound File Data"
|
||||
#define SPC_HDR_SIZE sizeof (spc_hdr)
|
||||
|
||||
#define RAM_START_ADDRESS 0x100
|
||||
#define RAM_SIZE 0x10000
|
||||
|
||||
#define DSP_REG_START_ADDRESS 0x10100
|
||||
#define DSP_REG_SIZE 0x80
|
||||
|
||||
#define EXTRA_RAM_START_ADDRESS 0x101C0
|
||||
#define EXTRA_RAM_SIZE 0x40
|
||||
|
||||
#define EXTENDED_ID666_START_ADDRESS 0x10200
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN,
|
||||
ZSNES,
|
||||
SNES9X,
|
||||
} emulator_used;
|
||||
|
||||
R_PACKED(
|
||||
typedef struct { //SNES9x
|
||||
char song_title [32];
|
||||
char game_title [32];
|
||||
char name_of_dumper [16];
|
||||
char comments [32];
|
||||
ut8 date[11];
|
||||
ut8 num_sec_bef_fade_out[3];
|
||||
ut8 len_fade_out[5];
|
||||
char artist_song [32];
|
||||
bool default_channel_disabled;
|
||||
emulator_used emulator_used[1];
|
||||
ut8 reserved[1];
|
||||
}) id666_tag_text;
|
||||
|
||||
R_PACKED (
|
||||
typedef struct { //ZSNES
|
||||
char song_title [32];
|
||||
char game_title [32];
|
||||
char name_of_dumper [16];
|
||||
char comments [32];
|
||||
ut8 date[4];
|
||||
ut8 unused[8];
|
||||
ut8 num_sec_bef_fade_out[3];
|
||||
ut8 len_fade_out[4];
|
||||
char artist_song [32];
|
||||
bool default_channel_disabled;
|
||||
ut8 reserved[1];
|
||||
}) id666_tag_binary;
|
||||
|
||||
R_PACKED (
|
||||
typedef struct {
|
||||
char signature [33];
|
||||
ut8 signature2 [2];
|
||||
ut8 has_id666;
|
||||
ut8 version;
|
||||
}) spc_hdr;
|
||||
|
||||
R_PACKED (
|
||||
typedef struct {
|
||||
ut8 pcl;
|
||||
ut8 pch;
|
||||
ut8 a;
|
||||
ut8 x;
|
||||
ut8 y;
|
||||
ut8 psw;
|
||||
ut8 sp;
|
||||
ut8 reserved_1;
|
||||
ut8 reserved_2;
|
||||
}) spc_reg;
|
||||
|
||||
R_PACKED (
|
||||
typedef struct {
|
||||
ut8 ram [0x10000];
|
||||
ut8 dsp [128];
|
||||
ut8 unused [0x40];
|
||||
ut8 ipl_rom [0x40];
|
||||
}) spc_data;
|
||||
|
||||
#endif // _SPC_H
|
||||
+13
-14
@@ -74,13 +74,13 @@ int r_bin_swf_get_sections(RList *list, RBinFile *arch) {
|
||||
if (!(head_sect = R_NEW0 (RBinSection))) {
|
||||
return false;
|
||||
}
|
||||
strcpy (head_sect->name, "Header");
|
||||
head_sect->name = strdup ("Header");
|
||||
head_sect->paddr = 0;
|
||||
head_sect->vaddr = 0;
|
||||
ut8 start = 0x8; // signature + version + size
|
||||
head_sect->size = start;
|
||||
head_sect->vsize = start;
|
||||
head_sect->srwx = R_BIN_SCN_READABLE;
|
||||
head_sect->perm = R_PERM_R;
|
||||
r_list_append (list, head_sect);
|
||||
|
||||
/* ZlibData section */
|
||||
@@ -89,12 +89,12 @@ int r_bin_swf_get_sections(RList *list, RBinFile *arch) {
|
||||
if (!(data = R_NEW0 (RBinSection)))
|
||||
return false;
|
||||
|
||||
snprintf(data->name, R_BIN_SIZEOF_STRINGS, "ZlibData");
|
||||
data->name = strdup ("ZlibData");
|
||||
data->paddr = start;
|
||||
data->vaddr = start;
|
||||
data->size = r_buf_size(arch->buf) - start;
|
||||
data->vsize = r_buf_size(arch->buf) - start;
|
||||
data->srwx = R_BIN_SCN_READABLE;
|
||||
data->perm = R_PERM_R;
|
||||
|
||||
r_list_append (list, data);
|
||||
} else if (header.signature[0] == ISWF_MAGIC_0_2) {
|
||||
@@ -107,13 +107,13 @@ int r_bin_swf_get_sections(RList *list, RBinFile *arch) {
|
||||
if (!(head_sect = R_NEW0 (RBinSection))) {
|
||||
return false;
|
||||
}
|
||||
strcpy (head_sect->name, "Header");
|
||||
head_sect->name = strdup ("Header");
|
||||
head_sect->paddr = 0;
|
||||
head_sect->vaddr = 0;
|
||||
ut8 start = 0x8; // signature + version + size
|
||||
head_sect->size = start;
|
||||
head_sect->vsize = start;
|
||||
head_sect->srwx = R_BIN_SCN_READABLE;
|
||||
head_sect->perm = R_PERM_R;
|
||||
r_list_append (list, head_sect);
|
||||
|
||||
/* LzmaData section */
|
||||
@@ -121,12 +121,12 @@ int r_bin_swf_get_sections(RList *list, RBinFile *arch) {
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
snprintf(data->name, R_BIN_SIZEOF_STRINGS, "LzmaData");
|
||||
data->name = strdup ("LzmaData");
|
||||
data->paddr = start;
|
||||
data->vaddr = start;
|
||||
data->size = r_buf_size(arch->buf) - start;
|
||||
data->vsize = r_buf_size(arch->buf) - start;
|
||||
data->srwx = R_BIN_SCN_READABLE;
|
||||
data->perm = R_PERM_R;
|
||||
|
||||
r_list_append (list, data);
|
||||
} else {
|
||||
@@ -135,13 +135,13 @@ int r_bin_swf_get_sections(RList *list, RBinFile *arch) {
|
||||
if (!(head_sect = R_NEW0 (RBinSection))) {
|
||||
return false;
|
||||
}
|
||||
strcpy(head_sect->name, "Header");
|
||||
head_sect->name = strdup ("Header");
|
||||
head_sect->paddr = 0;
|
||||
head_sect->vaddr = 0;
|
||||
ut32 start = header.rect_size + SWF_HDR_MIN_SIZE; // rect + min_size
|
||||
head_sect->size = start;
|
||||
head_sect->vsize = start;
|
||||
head_sect->srwx = R_BIN_SCN_READABLE;
|
||||
head_sect->perm = R_PERM_R;
|
||||
r_list_append (list, head_sect);
|
||||
|
||||
/* Other sections */
|
||||
@@ -173,7 +173,7 @@ int r_bin_swf_get_sections(RList *list, RBinFile *arch) {
|
||||
return false;
|
||||
}
|
||||
swf_tag_t tag = r_asm_swf_gettag (tagCode);
|
||||
strcpy (new->name, tag.name);
|
||||
new->name = strdup (tag.name);
|
||||
new->paddr = start;
|
||||
new->vaddr = start;
|
||||
|
||||
@@ -183,11 +183,11 @@ int r_bin_swf_get_sections(RList *list, RBinFile *arch) {
|
||||
switch (tagCode) {
|
||||
case TAG_DOACTION:
|
||||
case TAG_DOINITACTION:
|
||||
new->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE;
|
||||
new->perm = R_PERM_RX;
|
||||
new->has_strings = true;
|
||||
break;
|
||||
default:
|
||||
new->srwx = R_BIN_SCN_READABLE;
|
||||
new->perm = R_PERM_R;
|
||||
break;
|
||||
}
|
||||
r_list_append (list, new);
|
||||
@@ -196,7 +196,6 @@ int r_bin_swf_get_sections(RList *list, RBinFile *arch) {
|
||||
r_buf_read_at (arch->buf, end, (ut8*)&tagCodeAndLength, 2);
|
||||
section++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+1
-1
@@ -2,8 +2,8 @@ ARCHS=
|
||||
|
||||
ARCHS+=dlang.mk
|
||||
ARCHS+=swf.mk
|
||||
ARCHS+=pyc.mk
|
||||
ARCHS+=pcap.mk
|
||||
ARCHS+=spc700.mk
|
||||
ARCHS+=atombios.mk
|
||||
# doesnt build yet
|
||||
#ARCHS+=m68k.mk
|
||||
|
||||
+59
-56
@@ -6,6 +6,7 @@
|
||||
#include <r_bin.h>
|
||||
#include <r_endian.h>
|
||||
#include "../../asm/arch/atombios/atombios.h"
|
||||
#include "atombios.h"
|
||||
|
||||
static ut16 header;
|
||||
static ut16 mastercmdoffset;
|
||||
@@ -15,58 +16,55 @@ static ut32 cmdtablesize[N_TABLES_CMD];
|
||||
static ut32 datatableoffs[N_TABLES_DATA];
|
||||
static ut32 datatablesize[N_TABLES_DATA];
|
||||
|
||||
static bool check_bytes(const ut8 *buf, ut64 length) {
|
||||
if (!buf || length < 0x70)
|
||||
static bool check_buffer(RBuffer *b) {
|
||||
if (!b || r_buf_size (b) < 0x70)
|
||||
return false;
|
||||
|
||||
header = r_read_at_le16(buf, HEADER_OFFSET);
|
||||
if (memcmp (buf + header + 4, ATOM_MAGIC, 4))
|
||||
ut8 magic[4] = {0};
|
||||
header = r_buf_read_le16_at (b, HEADER_OFFSET);
|
||||
r_buf_read_at (b, header + 4, magic, 4);
|
||||
if (memcmp (magic, ATOM_MAGIC, 4))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
|
||||
ut8 i;
|
||||
if (!check_bytes(buf, sz))
|
||||
static bool load_buffer(RBinFile *bf, void **bin_obj, RBuffer *b, ut64 loadaddr, Sdb *sdb){
|
||||
if (!check_buffer(b))
|
||||
return false;
|
||||
|
||||
mastercmdoffset = r_read_at_le16(buf, header + 30) + 4;
|
||||
masterdataoffset = r_read_at_le16(buf, header + 32) + 4;
|
||||
ut8 i;
|
||||
atombios_obj_t *obj = R_NEW0 (atombios_obj_t);
|
||||
if (!obj) {
|
||||
return false;
|
||||
} else {
|
||||
obj->b = r_buf_ref (b);
|
||||
*bin_obj = obj;
|
||||
}
|
||||
|
||||
mastercmdoffset = r_buf_read_le16_at (b, header + 30) + 4;
|
||||
masterdataoffset = r_buf_read_le16_at (b, header + 32) + 4;
|
||||
|
||||
for (i = 0; i < N_TABLES_CMD; i++) {
|
||||
cmdtableoffs[i] = r_read_at_le16 (buf, mastercmdoffset + i * sizeof (ut16));
|
||||
cmdtableoffs[i] = r_buf_read_le16_at (b, mastercmdoffset + i * sizeof (ut16));
|
||||
if (!cmdtableoffs[i]) {
|
||||
cmdtablesize[i] = 0;
|
||||
} else {
|
||||
cmdtablesize[i] = r_read_at_le16 (buf, cmdtableoffs[i]) - 6;
|
||||
cmdtableoffs[i] += 6;
|
||||
cmdtablesize[i] = r_buf_read_le16_at (b, cmdtableoffs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < N_TABLES_DATA; i++) {
|
||||
datatableoffs[i] = r_read_at_le16 (buf, masterdataoffset + i * sizeof (ut16));
|
||||
datatableoffs[i] = r_buf_read_le16_at (b, masterdataoffset + i * sizeof (ut16));
|
||||
if (!datatableoffs[i]) {
|
||||
datatablesize[i] = 0;
|
||||
} else {
|
||||
datatablesize[i] = r_read_at_le16 (buf, datatableoffs[i]) - 4;
|
||||
datatableoffs[i] += 4;
|
||||
datatablesize[i] = r_buf_read_le16_at (b, datatableoffs[i]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool load(RBinFile *bf) {
|
||||
const ut8 *bytes = bf ? r_buf_buffer (bf->buf) : NULL;
|
||||
ut64 sz = bf ? r_buf_size (bf->buf): 0;
|
||||
|
||||
if (!bf || !bf->o) {
|
||||
return false;
|
||||
}
|
||||
return load_bytes (bf, &bf->o->bin_obj, bytes, sz, bf->o->loadaddr, bf->sdb);
|
||||
}
|
||||
|
||||
static RBinInfo* info(RBinFile *arch) {
|
||||
RBinInfo *ret = R_NEW0 (RBinInfo);
|
||||
if (!ret) {
|
||||
@@ -81,67 +79,73 @@ static RBinInfo* info(RBinFile *arch) {
|
||||
ret->arch = strdup ("atombios");
|
||||
ret->bits = 32;
|
||||
ret->has_va = false;
|
||||
ret->dbg_info = 0;
|
||||
ret->dbg_info = 1;
|
||||
ret->has_nx = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void addsym(RList *ret, const char *name, ut64 addr, ut32 size) {
|
||||
RBinSymbol *ptr = R_NEW0 (RBinSymbol);
|
||||
if (!ptr) return;
|
||||
ptr->name = strdup (name? name: "");
|
||||
ptr->paddr = ptr->vaddr = addr;
|
||||
ptr->size = size;
|
||||
ptr->ordinal = 0;
|
||||
r_list_append (ret, ptr);
|
||||
RBinSymbol *ptr = R_NEW0 (RBinSymbol);
|
||||
if (!ptr) return;
|
||||
ptr->name = strdup (name? name: "dummy");
|
||||
ptr->paddr = ptr->vaddr = addr;
|
||||
ptr->size = size;
|
||||
ptr->ordinal = 0;
|
||||
r_list_append (ret, ptr);
|
||||
}
|
||||
|
||||
static RList* symbols(RBinFile *bf) {
|
||||
ut8 i;
|
||||
RList *ret = NULL;
|
||||
if (!(ret = r_list_newf (free))) {
|
||||
if (!(ret = r_list_newf (free)))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Data table symbols */
|
||||
for (i = 0; i < N_TABLES_DATA; i++) {
|
||||
if (datatableoffs[i])
|
||||
addsym (ret, index_data_table[i], datatableoffs[i], datatablesize[i]);
|
||||
if (datatablesize[i])
|
||||
addsym (ret, index_data_table[i], datatableoffs[i] + 4, datatablesize[i] - 4);
|
||||
}
|
||||
|
||||
/* Command table symbols */
|
||||
for (i = 0; i < N_TABLES_CMD; i++) {
|
||||
if (cmdtablesize[i])
|
||||
addsym (ret, index_command_table[i], cmdtableoffs[i] + 6, cmdtablesize[i] - 6);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RList* sections(RBinFile *arch) {
|
||||
static RList* sections(RBinFile *bf) {
|
||||
ut8 i;
|
||||
ut16 sz = 0;
|
||||
RList *ret = NULL;
|
||||
RBinSection *sect;
|
||||
//RBuffer *b = bf->o->bin_obj;
|
||||
|
||||
if (!(ret = r_list_new()))
|
||||
if (!(ret = r_list_newf (free)))
|
||||
return NULL;
|
||||
|
||||
/* Command table sections */
|
||||
for (i = 0; i < N_TABLES_CMD; i++) {
|
||||
sz = cmdtablesize[i];
|
||||
if (!(sect = R_NEW0 (RBinSection))) {
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
if (cmdtableoffs[i]) {
|
||||
strcpy (sect->name, index_command_table[i]);
|
||||
sect->name = strdup (index_command_table[i]);
|
||||
sect->paddr = cmdtableoffs[i];
|
||||
sect->vaddr = cmdtableoffs[i];
|
||||
sect->size = sz;
|
||||
sect->vsize = sz;
|
||||
sect->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE;
|
||||
//TODO sect->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE;
|
||||
r_list_append (ret, sect);
|
||||
} else {
|
||||
strcpy (sect->name, "dummy");
|
||||
sect->name = strdup ("dummy");
|
||||
sect->paddr = 0;
|
||||
sect->vaddr = 0;
|
||||
sect->size = 0;
|
||||
sect->vsize = 0;
|
||||
sect->srwx = 0;
|
||||
r_list_append (ret, sect);
|
||||
}
|
||||
}
|
||||
@@ -150,23 +154,22 @@ static RList* sections(RBinFile *arch) {
|
||||
for (i = 0; i < N_TABLES_DATA; i++) {
|
||||
sz = datatablesize[i];
|
||||
if (!(sect = R_NEW0 (RBinSection))) {
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
if (datatableoffs[i]) {
|
||||
strcpy (sect->name, index_data_table[i]);
|
||||
sect->name = strdup (index_data_table[i]);
|
||||
sect->paddr = datatableoffs[i];
|
||||
sect->vaddr = datatableoffs[i];
|
||||
sect->size = sz;
|
||||
sect->vsize = sz;
|
||||
sect->srwx = R_BIN_SCN_READABLE;
|
||||
//TODO sect->srwx = R_BIN_SCN_READABLE;
|
||||
r_list_append (ret, sect);
|
||||
} else {
|
||||
strcpy (sect->name, "dummy");
|
||||
sect->name = strdup ("dummy");
|
||||
sect->paddr = 0;
|
||||
sect->vaddr = 0;
|
||||
sect->size = 0;
|
||||
sect->vsize = 0;
|
||||
sect->srwx = 0;
|
||||
r_list_append (ret, sect);
|
||||
}
|
||||
}
|
||||
@@ -182,8 +185,8 @@ static RList* entries(RBinFile *arch) {
|
||||
if (!(ptr = R_NEW0 (RBinAddr)))
|
||||
return ret;
|
||||
|
||||
ptr->paddr = cmdtableoffs[0];
|
||||
ptr->vaddr = cmdtableoffs[0];
|
||||
ptr->paddr = cmdtableoffs[0] + 6;
|
||||
ptr->vaddr = cmdtableoffs[0] + 6;
|
||||
r_list_append(ret, ptr);
|
||||
|
||||
return ret;
|
||||
@@ -191,11 +194,10 @@ static RList* entries(RBinFile *arch) {
|
||||
|
||||
RBinPlugin r_bin_plugin_atombios = {
|
||||
.name = "atombios",
|
||||
.desc = "AtomBIOS",
|
||||
.desc = "AtomBIOS binary format parser",
|
||||
.license = "LGPL3",
|
||||
.load = &load,
|
||||
.load_bytes = &load_bytes,
|
||||
.check_bytes = &check_bytes,
|
||||
.load_buffer = &load_buffer,
|
||||
.check_buffer = &check_buffer,
|
||||
.entries = &entries,
|
||||
.sections = §ions,
|
||||
.symbols = &symbols,
|
||||
@@ -206,6 +208,7 @@ RBinPlugin r_bin_plugin_atombios = {
|
||||
RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_BIN,
|
||||
.data = &r_bin_plugin_atombios,
|
||||
.version = R2_VERSION
|
||||
.version = R2_VERSION,
|
||||
.pkgname = "atombios",
|
||||
};
|
||||
#endif
|
||||
+79
-382
@@ -1,442 +1,139 @@
|
||||
#include <r_bin.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_types.h>
|
||||
|
||||
#include "pcap.h"
|
||||
|
||||
#define OPP_ENDIAN 1
|
||||
#define SAME_ENDIAN 0
|
||||
|
||||
// The pcap object for RBinFile
|
||||
typedef struct pcap_obj {
|
||||
struct pcap_file_hdr header; // File header
|
||||
bool is_nsec; // nsec timestamp resolution?
|
||||
int endian; // Relative endianness (same or different from host)
|
||||
} pcap_obj_t;
|
||||
|
||||
|
||||
// Functions
|
||||
|
||||
static RBinInfo *info(RBinFile *arch) {
|
||||
if (!arch || !arch->o || !arch->o->bin_obj) {
|
||||
return NULL;
|
||||
}
|
||||
static RBinInfo *info(RBinFile *bf) {
|
||||
r_return_val_if_fail (bf && bf->o && bf->o->bin_obj, NULL);
|
||||
RBinInfo *ret = R_NEW0 (RBinInfo);
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
pcap_file_hdr_t *header = &((pcap_obj_t *) arch->o->bin_obj)->header;
|
||||
ret->file = strdup (arch->file);
|
||||
pcap_obj_t *obj = bf->o->bin_obj;
|
||||
pcap_hdr_t *header = obj->header;
|
||||
ret->file = strdup (bf->file);
|
||||
ret->type = r_str_newf ("tcpdump capture file - version %d.%d (%s, "
|
||||
"capture length %"PFMT32u ")", header->version_major,
|
||||
header->version_minor, pcap_net_type (header->network),
|
||||
header->max_pkt_len);
|
||||
"capture length %"PFMT32u ")",
|
||||
header->version_major, header->version_minor,
|
||||
pcap_network_string (header->network), header->max_pkt_len);
|
||||
ret->rclass = strdup ("pcap");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool check_bytes(const ut8 *buf, ut64 length) {
|
||||
if (!buf || length < sizeof (pcap_file_hdr_t) || length == UT64_MAX) {
|
||||
return false;
|
||||
}
|
||||
pcap_file_hdr_t *header = (pcap_file_hdr_t *) buf;
|
||||
switch (header->magic) {
|
||||
case PCAP_MAGIC:
|
||||
case PCAP_NSEC_MAGIC:
|
||||
static bool check_buffer(RBuffer *b) {
|
||||
r_return_val_if_fail (b, false);
|
||||
|
||||
switch (r_buf_read_be32_at (b, 0)) {
|
||||
case PCAP_MAGIC_LE:
|
||||
case PCAP_MAGIC_BE:
|
||||
case PCAP_NSEC_MAGIC_LE:
|
||||
case PCAP_NSEC_MAGIC_BE:
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
switch (r_swap_ut32 (header->magic)) {
|
||||
case PCAP_MAGIC:
|
||||
case PCAP_NSEC_MAGIC:
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool load_buffer(RBinFile *bf, void **bin_obj, RBuffer *buf, ut64 loadaddr, Sdb *sdb) {
|
||||
r_return_val_if_fail (bf && bin_obj && buf, false);
|
||||
|
||||
pcap_obj_t *obj = pcap_obj_new_buf (buf);
|
||||
if (obj) {
|
||||
*bin_obj = obj;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void *load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb) {
|
||||
if (!buf || !sz || sz < sizeof (pcap_file_hdr_t) || sz == UT64_MAX) {
|
||||
static RList *symbols(RBinFile *bf) {
|
||||
r_return_val_if_fail (bf && bf->o && bf->o->bin_obj, NULL);
|
||||
|
||||
RBinSymbol *ptr;
|
||||
pcap_obj_t *obj = bf->o->bin_obj;
|
||||
ut64 size = r_buf_size (obj->b);
|
||||
if (size == 0 || size == UT64_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
struct pcap_obj *obj = NULL;
|
||||
if (!(obj = R_NEW0 (pcap_obj_t))) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy (&obj->header, buf, sizeof (pcap_file_hdr_t));
|
||||
|
||||
obj->endian = SAME_ENDIAN;
|
||||
switch (obj->header.magic) {
|
||||
case PCAP_MAGIC:
|
||||
obj->is_nsec = false;
|
||||
break;
|
||||
case PCAP_NSEC_MAGIC:
|
||||
obj->is_nsec = true;
|
||||
break;
|
||||
default:
|
||||
switch (r_swap_ut32 (obj->header.magic)) {
|
||||
case PCAP_MAGIC:
|
||||
obj->is_nsec = false;
|
||||
break;
|
||||
case PCAP_NSEC_MAGIC:
|
||||
obj->is_nsec = true;
|
||||
break;
|
||||
default:
|
||||
free (obj);
|
||||
return NULL;
|
||||
}
|
||||
obj->endian = OPP_ENDIAN;
|
||||
}
|
||||
// Reload file header
|
||||
read_pcap_file_hdr (&obj->header, buf, obj->endian);
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void _read_tcp_sym(RList *list, const ut8 *buf, ut64 off, ut64 sz, ut64 tcplen, int endian) {
|
||||
RBinSymbol *ptr = NULL;
|
||||
if (off + sizeof (pcap_pktrec_tcp_t) > sz) {
|
||||
return;
|
||||
}
|
||||
if (!(ptr = R_NEW0 (RBinSymbol))) {
|
||||
return;
|
||||
}
|
||||
pcap_pktrec_tcp_t tcp;
|
||||
read_pcap_pktrec_tcp (&tcp, &buf[off], endian);
|
||||
ut64 tcp_data_len = tcplen - (((tcp.hdr_len >> 4) & 0x0F) * 4);
|
||||
ptr->name = r_str_newf ("0x%x: Transmission Control Protocol, Src Port: %d, Dst"
|
||||
" port: %d, Len: %d", off, tcp.src_port, tcp.dst_port,
|
||||
tcp_data_len);
|
||||
ptr->paddr = ptr->vaddr = off;
|
||||
r_list_append (list, ptr);
|
||||
}
|
||||
|
||||
static void _read_ipv4_sym(RList *list, const ut8 *buf, ut64 off, ut64 sz, int endian) {
|
||||
RBinSymbol *ptr = NULL;
|
||||
if (!(ptr = R_NEW0 (RBinSymbol))) {
|
||||
return;
|
||||
}
|
||||
pcap_pktrec_ipv4_t ipv4;
|
||||
read_pcap_pktrec_ipv4 (&ipv4, &buf[off], endian);
|
||||
ptr->name = r_str_newf ("0x%"PFMT64x": IPV%d, Src: %d.%d.%d.%d, Dst: %d.%d.%d.%d",
|
||||
off, (ipv4.ver_len >> 4) & 0x0F, (ipv4.src >> 24) & 0xFF,
|
||||
(ipv4.src >> 16) & 0xFF, (ipv4.src >> 8) & 0xFF,
|
||||
ipv4.src && 0xFF, (ipv4.dst >> 24) & 0xFF,
|
||||
(ipv4.dst >> 16) & 0xFF, (ipv4.dst >> 8) & 0xFF,
|
||||
ipv4.dst && 0xFF);
|
||||
ptr->paddr = ptr->vaddr = off;
|
||||
r_list_append (list, ptr);
|
||||
if (off + ipv4.tot_len > sz) {
|
||||
return;
|
||||
}
|
||||
off += (ipv4.ver_len & 0x0F) * 4;
|
||||
|
||||
// For now, if not TCP, continue. TODO others
|
||||
switch (ipv4.protocol) {
|
||||
case 6:
|
||||
_read_tcp_sym (list, buf, off, sz, (ipv4.tot_len - ((ipv4.ver_len & 0x0F) * 4)), endian);
|
||||
}
|
||||
}
|
||||
|
||||
static void _write_ipv6_addr(const ut8 *addr, char *buf, int len) {
|
||||
struct { int start, len; } best, cur;
|
||||
ut16 words[8] = { 0 };
|
||||
int i;
|
||||
char *ptr = buf;
|
||||
best.start = cur.start = -1;
|
||||
best.len = cur.len = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
words[i] = (addr[i * 2] << 4) | addr[i * 2 + 1];
|
||||
if (words[i] == 0) {
|
||||
if (cur.start == -1) {
|
||||
cur.start = i;
|
||||
cur.len = 1;
|
||||
} else {
|
||||
cur.len++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (cur.start != -1) {
|
||||
if (best.start == -1 || cur.len > best.len) {
|
||||
best.start = cur.start;
|
||||
best.len = cur.len;
|
||||
}
|
||||
cur.start = -1;
|
||||
}
|
||||
}
|
||||
if (best.start == -1 || cur.len > best.len) {
|
||||
best.start = cur.start;
|
||||
best.len = cur.len;
|
||||
}
|
||||
if (best.len < 2) {
|
||||
best.start = -1;
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i == best.start) {
|
||||
*ptr++ = ':';
|
||||
continue;
|
||||
}
|
||||
if (best.start != -1 && i > best.start && i < best.start + best.len) {
|
||||
continue;
|
||||
}
|
||||
if (i != 0) {
|
||||
*ptr++ = ':';
|
||||
}
|
||||
ptr += snprintf (ptr, len - (ptr - buf), "%x", words[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void _read_ipv6_sym(RList *list, const ut8 *buf, ut64 off, ut64 sz, int endian) {
|
||||
RBinSymbol *ptr = NULL;
|
||||
if (!(ptr = R_NEW0 (RBinSymbol))) {
|
||||
return;
|
||||
}
|
||||
char write_buf[256] = { 0 };
|
||||
pcap_pktrec_ipv6_t ipv6;
|
||||
int len;
|
||||
read_pcap_pktrec_ipv6 (&ipv6, &buf[off], endian);
|
||||
snprintf (write_buf, sizeof (write_buf) - 1, "0x%"PFMT64x": IPV6, Src: ", off);
|
||||
len = strlen (write_buf);
|
||||
_write_ipv6_addr (ipv6.src, write_buf + len, sizeof (write_buf) - len);
|
||||
len += strlen (write_buf + len);
|
||||
strcpy (write_buf + len, ", Dst: ");
|
||||
len += strlen (write_buf + len);
|
||||
_write_ipv6_addr (ipv6.dest, write_buf + len, sizeof (write_buf) - len);
|
||||
|
||||
if (!(ptr->name = strdup (write_buf))) {
|
||||
free (ptr);
|
||||
return;
|
||||
}
|
||||
ptr->paddr = ptr->vaddr = off;
|
||||
r_list_append (list, ptr);
|
||||
if (off + ipv6.plen + sizeof (pcap_pktrec_ipv6_t) > sz) {
|
||||
return;
|
||||
}
|
||||
off += sizeof (pcap_pktrec_ipv6_t);
|
||||
|
||||
// For now, if not TCP, continue. TODO others
|
||||
switch (ipv6.nxt) {
|
||||
case 6:
|
||||
_read_tcp_sym (list, buf, off, sz, ipv6.plen, endian);
|
||||
}
|
||||
}
|
||||
|
||||
static void _read_ether_sym(RList *list, const ut8 *buf, ut64 off, ut64 sz, int endian) {
|
||||
RBinSymbol *ptr = NULL;
|
||||
if (!(ptr = R_NEW0 (RBinSymbol))) {
|
||||
return;
|
||||
}
|
||||
pcap_pktrec_ether_t ether;
|
||||
read_pcap_pktrec_ether (ðer, &buf[off], endian);
|
||||
ptr->name = r_str_newf ("0x%x: Ethernet, Src: %02"PFMT32x ":%02"PFMT32x ":%02"PFMT32x
|
||||
":%02"PFMT32x ":%02"PFMT32x ":%02"PFMT32x ", Dst: %02"PFMT32x
|
||||
":%02"PFMT32x ":%02"PFMT32x ":%02"PFMT32x ":%02"PFMT32x
|
||||
":%02"PFMT32x, off, ether.src[0], ether.src[1],
|
||||
ether.src[2], ether.src[3], ether.src[4], ether.src[5],
|
||||
ether.dst[0], ether.dst[1], ether.dst[2], ether.dst[3],
|
||||
ether.dst[4], ether.dst[5]);
|
||||
ptr->paddr = ptr->vaddr = off;
|
||||
r_list_append (list, ptr);
|
||||
off += sizeof (pcap_pktrec_ether_t);
|
||||
|
||||
// For now, if not IPV4, continue. TODO IPV6
|
||||
switch (ether.type) {
|
||||
case 0x08:
|
||||
_read_ipv4_sym (list, buf, off, sz, endian);
|
||||
break;
|
||||
case 0xdd86:
|
||||
_read_ipv6_sym (list, buf, off, sz, endian);
|
||||
}
|
||||
}
|
||||
|
||||
static RList *symbols(RBinFile *arch) {
|
||||
RBinSymbol *ptr = NULL;
|
||||
RList *ret = NULL;
|
||||
pcap_obj_t *obj = NULL;
|
||||
const ut8 *buf = NULL;
|
||||
ut64 sz = 0;
|
||||
ut64 off;
|
||||
ut64 pkt_num = 0;
|
||||
if (!arch || !arch->o || !arch->o->bin_obj || !arch->buf || !arch->buf->buf) {
|
||||
return NULL;
|
||||
}
|
||||
obj = arch->o->bin_obj;
|
||||
buf = r_buf_buffer (arch->buf);
|
||||
sz = r_buf_size (arch->buf);
|
||||
if (sz == 0 || sz == UT64_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
if (!(ret = r_list_new ())) {
|
||||
RList *ret = r_list_newf (free);
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// File header
|
||||
if (!(ptr = R_NEW0 (RBinSymbol))) {
|
||||
return ret;
|
||||
ptr = R_NEW0 (RBinSymbol);
|
||||
if (!ptr) {
|
||||
r_list_free (ret);
|
||||
return NULL;
|
||||
}
|
||||
ptr->name = r_str_newf ("tcpdump capture file - version %d.%d (%s, "
|
||||
"capture length %"PFMT32u ")", obj->header.version_major,
|
||||
obj->header.version_minor, pcap_net_type (obj->header.network),
|
||||
obj->header.max_pkt_len);
|
||||
"capture length %"PFMT32u ")", obj->header->version_major,
|
||||
obj->header->version_minor, pcap_network_string (obj->header->network),
|
||||
obj->header->max_pkt_len);
|
||||
ptr->paddr = ptr->vaddr = 0;
|
||||
r_list_append (ret, ptr);
|
||||
|
||||
// Go through each packet
|
||||
off = sizeof (pcap_file_hdr_t);
|
||||
while (off <= sz - sizeof (pcap_pktrec_hdr_t)) {
|
||||
pkt_num++;
|
||||
|
||||
// Frame header
|
||||
if (!(ptr = R_NEW0 (RBinSymbol))) {
|
||||
break;
|
||||
// Go through each record packet
|
||||
RListIter *iter;
|
||||
pcaprec_t *rec;
|
||||
switch (obj->header->network) {
|
||||
case LINK_ETHERNET:
|
||||
r_list_foreach (obj->recs, iter, rec) {
|
||||
pcaprec_ether_sym_add (ret, rec, rec->paddr + sizeof (pcaprec_hdr_t));
|
||||
}
|
||||
pcap_pktrec_hdr_t pkthdr;
|
||||
read_pcap_pktrec_hdr (&pkthdr, &buf[off], obj->endian);
|
||||
ptr->name = r_str_newf ("0x%x: Frame %d, %d bytes on wire, %d bytes captured",
|
||||
off, pkt_num, pkthdr.orig_len, pkthdr.cap_len);
|
||||
ptr->paddr = ptr->vaddr = off;
|
||||
r_list_append (ret, ptr);
|
||||
|
||||
// Check if rest of file is present. If not, break
|
||||
if (off + sizeof (pcap_pktrec_hdr_t) + pkthdr.cap_len > sz) {
|
||||
break;
|
||||
}
|
||||
|
||||
// For now, if not ethernet, continue. TODO others
|
||||
switch (obj->header.network) {
|
||||
case ETHERNET:
|
||||
_read_ether_sym (ret, buf, off + sizeof (pcap_pktrec_hdr_t), sz, obj->endian);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
off += sizeof (pcap_pktrec_hdr_t) + pkthdr.cap_len;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RList *strings(RBinFile *arch) {
|
||||
RBinString *ptr = NULL;
|
||||
RList *ret = NULL;
|
||||
pcap_obj_t *obj = NULL;
|
||||
const ut8 *buf = NULL;
|
||||
char *tmp = NULL;
|
||||
ut64 sz = 0;
|
||||
ut64 off;
|
||||
if (!arch || !arch->o || !arch->o->bin_obj || !arch->buf || !arch->buf->buf) {
|
||||
static RList *strings(RBinFile *bf) {
|
||||
r_return_val_if_fail (bf && bf->o && bf->o->bin_obj, NULL);
|
||||
|
||||
RBinString *ptr;
|
||||
pcap_obj_t *obj = bf->o->bin_obj;
|
||||
RList *ret = r_list_newf (free);
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
obj = arch->o->bin_obj;
|
||||
buf = r_buf_buffer (arch->buf);
|
||||
sz = r_buf_size (arch->buf);
|
||||
if (sz == 0 || sz == UT64_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
if (!(ret = r_list_new ())) {
|
||||
return NULL;
|
||||
}
|
||||
if (!(tmp = malloc (obj->header.max_pkt_len + 1))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Go through each packet
|
||||
off = sizeof (pcap_file_hdr_t);
|
||||
while (off <= sz - sizeof (pcap_pktrec_hdr_t)) {
|
||||
ut64 tmp_off = off;
|
||||
// Frame header
|
||||
pcap_pktrec_hdr_t pkthdr;
|
||||
read_pcap_pktrec_hdr (&pkthdr, &buf[tmp_off], obj->endian);
|
||||
if (tmp_off + sizeof (pcap_pktrec_hdr_t) + pkthdr.cap_len > sz) {
|
||||
break;
|
||||
RListIter *iter;
|
||||
pcaprec_t *rec;
|
||||
r_list_foreach (obj->recs, iter, rec) {
|
||||
if (rec->data && *rec->data != 0) {
|
||||
ptr = R_NEW0 (RBinString);
|
||||
if (!ptr) {
|
||||
r_list_free (ret);
|
||||
return NULL;
|
||||
}
|
||||
ptr->string = strdup ((char *)rec->data);
|
||||
ptr->paddr = ptr->vaddr = //XXX;
|
||||
ptr->length = strlen (ptr->string);
|
||||
ptr->size = ptr->length + 1;
|
||||
ptr->type = R_STRING_TYPE_DETECT;
|
||||
r_list_append (ret, ptr);
|
||||
}
|
||||
off += sizeof (pcap_pktrec_hdr_t) + pkthdr.cap_len;
|
||||
|
||||
// Ethernet data. For now, if not ethernet, continue. TODO others
|
||||
if (obj->header.network != ETHERNET) {
|
||||
continue;
|
||||
}
|
||||
tmp_off += sizeof (pcap_pktrec_hdr_t);
|
||||
pcap_pktrec_ether_t ether;
|
||||
read_pcap_pktrec_ether (ðer, &buf[tmp_off], obj->endian);
|
||||
|
||||
// IPV4 data. For now, if not IPV4, continue. TODO IPV6
|
||||
if (ether.type != 0x08) {
|
||||
continue;
|
||||
}
|
||||
tmp_off += sizeof (pcap_pktrec_ether_t);
|
||||
pcap_pktrec_ipv4_t ipv4;
|
||||
read_pcap_pktrec_ipv4 (&ipv4, &buf[tmp_off], obj->endian);
|
||||
if (tmp_off + ipv4.tot_len > sz) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TCP header data. For now, if not TCP, continue. TODO others}
|
||||
if (ipv4.protocol != 6) {
|
||||
continue;
|
||||
}
|
||||
tmp_off += (ipv4.ver_len & 0x0F) * 4;
|
||||
if (tmp_off + sizeof (pcap_pktrec_tcp_t) > sz) {
|
||||
continue;
|
||||
}
|
||||
pcap_pktrec_tcp_t tcp;
|
||||
read_pcap_pktrec_tcp (&tcp, &buf[tmp_off], obj->endian);
|
||||
ut64 tcp_data_len = (ipv4.tot_len - ((ipv4.ver_len & 0x0F) * 4)) -
|
||||
(((tcp.hdr_len >> 4) & 0x0F) * 4);
|
||||
if (tcp_data_len <= 1) {
|
||||
continue;
|
||||
}
|
||||
tmp_off += ((tcp.hdr_len >> 4) & 0x0F) * 4;
|
||||
if (tcp_data_len > obj->header.max_pkt_len || tmp_off + tcp_data_len > sz) {
|
||||
continue;
|
||||
}
|
||||
size_t str_len;
|
||||
|
||||
memset (tmp, 0, obj->header.max_pkt_len);
|
||||
strncpy (tmp, (const char *) &buf[tmp_off], tcp_data_len);
|
||||
tmp[tcp_data_len] = '\0';
|
||||
if (!(str_len = strlen (tmp))) {
|
||||
continue;
|
||||
}
|
||||
if (!(ptr = R_NEW0 (RBinString))) {
|
||||
break;
|
||||
}
|
||||
ptr->string = strdup (tmp);
|
||||
ptr->paddr = ptr->vaddr = tmp_off;
|
||||
ptr->length = str_len;
|
||||
ptr->size = ptr->length + 1;
|
||||
ptr->type = R_STRING_TYPE_DETECT;
|
||||
r_list_append (ret, ptr);
|
||||
|
||||
}
|
||||
free (tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool load(RBinFile *arch) {
|
||||
if (!arch || !arch->o) {
|
||||
return false;
|
||||
}
|
||||
const ut8 *bytes = r_buf_buffer (arch->buf);
|
||||
ut64 size = r_buf_size (arch->buf);
|
||||
if (!bytes || size == 0 || size == UT64_MAX) {
|
||||
return false;
|
||||
}
|
||||
arch->o->bin_obj = load_bytes (arch, bytes, size, arch->o->loadaddr, arch->sdb);
|
||||
return arch->o->bin_obj != NULL;
|
||||
}
|
||||
|
||||
RBinPlugin r_bin_plugin_pcap = {
|
||||
.name = "pcap",
|
||||
.desc = "libpcap .pcap format r2 plugin",
|
||||
.license = "LGPL3",
|
||||
.info = info,
|
||||
.load = load,
|
||||
.strings = strings,
|
||||
.symbols = symbols,
|
||||
.load_bytes = load_bytes,
|
||||
.check_bytes = check_bytes,
|
||||
.load_buffer= load_buffer,
|
||||
.check_buffer = check_buffer,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_BIN,
|
||||
.data = &r_bin_plugin_pcap,
|
||||
.version = R2_VERSION,
|
||||
.pkgname = "pcap"
|
||||
};
|
||||
#endif
|
||||
@@ -1,100 +0,0 @@
|
||||
/* radare - LGPL3 - Copyright 2016-2017 - Matthieu (c0riolis) Tardy */
|
||||
|
||||
#include <r_bin.h>
|
||||
#include "pyc_magic.h"
|
||||
#include "pyc.h"
|
||||
|
||||
// XXX: to not use globals
|
||||
|
||||
static struct pyc_version version;
|
||||
/* used from marshall.c */
|
||||
RList *interned_table = NULL;
|
||||
|
||||
static bool check_bytes(const ut8 *buf, ut64 length) {
|
||||
if (!buf || length < 8) {
|
||||
// magic + timestamp
|
||||
return false;
|
||||
}
|
||||
version = get_pyc_version (*(ut32*)buf);
|
||||
return version.magic != -1;
|
||||
}
|
||||
|
||||
static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb) {
|
||||
return check_bytes (buf, sz);
|
||||
}
|
||||
|
||||
static RBinInfo *info(RBinFile *arch) {
|
||||
RBinInfo *ret = R_NEW0 (RBinInfo);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->file = strdup (arch->file);
|
||||
ret->type = r_str_newf ("Python %s%s byte-compiled file", version.version,
|
||||
version.unicode ? " Unicode" : "");
|
||||
ret->bclass = strdup ("Python byte-compiled file");
|
||||
ret->rclass = strdup ("pyc");
|
||||
ret->machine = r_str_newf ("Python %s VM (rev %s)", version.version,
|
||||
version.revision);
|
||||
ret->os = strdup ("any");
|
||||
ret->bits = 32;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RList *sections(RBinFile *arch) {
|
||||
RList *shared = r_list_new ();
|
||||
if (!shared) {
|
||||
return NULL;
|
||||
}
|
||||
RList *cobjs = r_list_new ();
|
||||
if (!cobjs) {
|
||||
return NULL;
|
||||
}
|
||||
interned_table = r_list_new ();
|
||||
if (!interned_table) {
|
||||
return NULL;
|
||||
}
|
||||
r_list_append (shared, cobjs);
|
||||
r_list_append (shared, interned_table);
|
||||
arch->o->bin_obj = shared;
|
||||
RList *sections = r_list_new ();
|
||||
if (!sections) {
|
||||
return NULL;
|
||||
}
|
||||
pyc_get_sections (sections, cobjs, arch->buf, version.magic);
|
||||
return sections;
|
||||
}
|
||||
|
||||
static RList *entries(RBinFile *arch) {
|
||||
RList *entries = r_list_new ();
|
||||
if (!entries) {
|
||||
return NULL;
|
||||
}
|
||||
RBinAddr *addr = R_NEW0 (RBinAddr);
|
||||
if (!addr) {
|
||||
return NULL;
|
||||
}
|
||||
ut64 entrypoint = pyc_get_entrypoint (version.magic);
|
||||
addr->paddr = entrypoint;
|
||||
addr->vaddr = entrypoint;
|
||||
r_buf_seek (arch->buf, entrypoint, R_IO_SEEK_CUR);
|
||||
r_list_append (entries, addr);
|
||||
return entries;
|
||||
}
|
||||
|
||||
RBinPlugin r_bin_plugin_pyc = {
|
||||
.name = "pyc",
|
||||
.desc = "Python byte-compiled file plugin",
|
||||
.license = "LGPL3",
|
||||
.info = &info,
|
||||
.load_bytes = &load_bytes,
|
||||
.check_bytes = &check_bytes,
|
||||
.entries = &entries,
|
||||
.sections = §ions,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_BIN,
|
||||
.data = &r_bin_plugin_pyc,
|
||||
.version = R2_VERSION,
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,99 @@
|
||||
/* radare - LGPL - 2015-2020 - maijin, pancake */
|
||||
|
||||
#include <r_bin.h>
|
||||
#include <r_lib.h>
|
||||
#include "../format/spc700/spc_specs.h"
|
||||
|
||||
static bool check_buffer(RBuffer *b) {
|
||||
ut8 buf[27];
|
||||
if (r_buf_read_at (b, 0, buf, sizeof (buf)) == 27) {
|
||||
return !memcmp (buf, SPC_MAGIC, 27);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool load_buffer(RBinFile *bf, void **bin_obj, RBuffer *b, ut64 loadaddr, Sdb *sdb){
|
||||
return check_buffer (b);
|
||||
}
|
||||
|
||||
static RBinInfo* info(RBinFile *bf) {
|
||||
RBinInfo *ret = NULL;
|
||||
spc_hdr spchdr;
|
||||
memset (&spchdr, 0, SPC_HDR_SIZE);
|
||||
int reat = r_buf_read_at (bf->buf, 0, (ut8*)&spchdr, SPC_HDR_SIZE);
|
||||
if (reat != SPC_HDR_SIZE) {
|
||||
eprintf ("Truncated Header\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!(ret = R_NEW0 (RBinInfo))) {
|
||||
return NULL;
|
||||
}
|
||||
ret->file = strdup (bf->file);
|
||||
ret->type = strdup ("Sound File Data");
|
||||
ret->machine = strdup ("SPC700");
|
||||
ret->os = strdup ("spc700");
|
||||
ret->arch = strdup ("spc700");
|
||||
ret->bits = 16;
|
||||
ret->has_va = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RList* sections(RBinFile *bf) {
|
||||
RList *ret = NULL;
|
||||
RBinSection *ptr = NULL;
|
||||
spc_hdr spchdr;
|
||||
memset (&spchdr, 0, SPC_HDR_SIZE);
|
||||
int reat = r_buf_read_at (bf->buf, 0, (ut8*)&spchdr, SPC_HDR_SIZE);
|
||||
if (reat != SPC_HDR_SIZE) {
|
||||
eprintf ("Truncated Header\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!(ret = r_list_new ())) {
|
||||
return NULL;
|
||||
}
|
||||
if (!(ptr = R_NEW0 (RBinSection))) {
|
||||
r_list_free (ret);
|
||||
return NULL;
|
||||
}
|
||||
ptr->name = strdup ("RAM");
|
||||
ptr->paddr = RAM_START_ADDRESS;
|
||||
ptr->size = RAM_SIZE;
|
||||
ptr->vaddr = 0x0;
|
||||
ptr->vsize = RAM_SIZE;
|
||||
ptr->perm = R_PERM_R;
|
||||
ptr->add = true;
|
||||
r_list_append (ret, ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RList* entries(RBinFile *bf) {
|
||||
RList *ret = r_list_newf (free);
|
||||
if (ret) {
|
||||
RBinAddr *ptr = R_NEW0 (RBinAddr);
|
||||
if (ptr) {
|
||||
ptr->paddr = RAM_START_ADDRESS;
|
||||
ptr->vaddr = 0;
|
||||
r_list_append (ret, ptr);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
RBinPlugin r_bin_plugin_spc700 = {
|
||||
.name = "spc700",
|
||||
.desc = "SNES-SPC700 Sound File Data",
|
||||
.license = "LGPL3",
|
||||
.load_buffer = &load_buffer,
|
||||
.check_buffer = &check_buffer,
|
||||
.entries = &entries,
|
||||
.sections = §ions,
|
||||
.info = &info,
|
||||
};
|
||||
|
||||
#ifndef R2_PLUGIN_INCORE
|
||||
R_API RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_BIN,
|
||||
.data = &r_bin_plugin_spc700,
|
||||
.version = R2_VERSION
|
||||
};
|
||||
#endif
|
||||
+25
-14
@@ -1,4 +1,4 @@
|
||||
/* radare - LGPL3 - 2016 - xarkes */
|
||||
/* radare - LGPL3 - 2016-2020 - xarkes */
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
@@ -7,14 +7,15 @@
|
||||
#include "../format/swf/swf_specs.h"
|
||||
#include "../format/swf/swf.h"
|
||||
|
||||
static int check(RBinFile *arch);
|
||||
static int check_bytes(const ut8 *buf, ut64 length);
|
||||
static bool check_buffer(RBuffer *b);
|
||||
|
||||
static char compression;
|
||||
static char flashVersion;
|
||||
|
||||
static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
|
||||
if (check_bytes (buf, sz)) {
|
||||
static bool load_buffer(RBinFile *bf, void **bin_obj, RBuffer *b, ut64 loadaddr, Sdb *sdb){
|
||||
if (check_buffer (b)) {
|
||||
ut8 buf[4];
|
||||
r_buf_read_at (b, 0, buf, 4);
|
||||
compression = buf[0];
|
||||
flashVersion = buf[3];
|
||||
return true;
|
||||
@@ -22,12 +23,21 @@ static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut
|
||||
return false;
|
||||
}
|
||||
|
||||
static int check_bytes(const ut8 *buf, ut64 length) {
|
||||
if (!buf || length < 4) return false;
|
||||
|
||||
if ((*buf == ISWF_MAGIC_0_0 || *buf == ISWF_MAGIC_0_1 ||
|
||||
*buf == ISWF_MAGIC_0_2) && (!memcmp (buf+1, ISWF_MAGIC, 2)))
|
||||
return true;
|
||||
static bool check_buffer(RBuffer *b) {
|
||||
ut8 buf[4];
|
||||
if (r_buf_size (b) < 4) {
|
||||
return false;
|
||||
}
|
||||
r_buf_read_at (b, 0, buf, 4);
|
||||
switch (buf[0]) {
|
||||
case ISWF_MAGIC_0_0:
|
||||
case ISWF_MAGIC_0_1:
|
||||
case ISWF_MAGIC_0_2:
|
||||
if (!memcmp (buf + 1, ISWF_MAGIC, 2)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -92,8 +102,8 @@ RBinPlugin r_bin_plugin_swf = {
|
||||
.name = "swf",
|
||||
.desc = "SWF",
|
||||
.license = "LGPL3",
|
||||
.load_bytes = &load_bytes,
|
||||
.check_bytes = &check_bytes,
|
||||
.load_buffer = &load_buffer,
|
||||
.check_buffer = &check_buffer,
|
||||
.entries = &entries,
|
||||
.sections = §ions,
|
||||
.info = &info,
|
||||
@@ -103,6 +113,7 @@ RBinPlugin r_bin_plugin_swf = {
|
||||
RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_BIN,
|
||||
.data = &r_bin_plugin_swf,
|
||||
.version = R2_VERSION
|
||||
.version = R2_VERSION,
|
||||
.pkgname = "swf"
|
||||
};
|
||||
#endif
|
||||
@@ -1,14 +0,0 @@
|
||||
OBJ_PYC=bin_pyc.o
|
||||
OBJ_PYC+=../format/pyc/marshal.o
|
||||
OBJ_PYC+=../format/pyc/pyc_magic.o
|
||||
OBJ_PYC+=../format/pyc/pyc.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_PYC}
|
||||
TARGET_PYC=bin_pyc.${LIBEXT}
|
||||
CFLAGS+=-I../format/pyc/
|
||||
|
||||
ALL_TARGETS+=${TARGET_PYC}
|
||||
|
||||
${TARGET_PYC}: ${OBJ_PYC}
|
||||
${CC} ${CFLAGS} -o ${TARGET_PYC} ${OBJ_PYC} $(R2_CFLAGS) $(R2_LDFLAGS) -lr_util -lgmp
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
OBJ_SPC700=bin_spc700.o
|
||||
STATIC_OBJ+=${OBJ_SPC700}
|
||||
TARGET_SPC700=bin_spc700.${LIBEXT}
|
||||
|
||||
# include $(SHLR)/zip/deps.mk
|
||||
|
||||
ALL_TARGETS+=${TARGET_SPC700}
|
||||
|
||||
${TARGET_SPC700}: ${OBJ_SPC700}
|
||||
${CC} $(call libname,bin_spc700) -shared ${CFLAGS} \
|
||||
-o ${TARGET_SPC700} ${OBJ_SPC700} ${LDFLAGS} ${LINK}
|
||||
@@ -204,12 +204,11 @@ static RList *r_debug_unicorn_pids(RDebug *dbg, int pid) {
|
||||
static RList *r_debug_unicorn_map_get(RDebug *dbg) {
|
||||
RDebugMap *m;
|
||||
RList *list;
|
||||
SdbListIter *iter;
|
||||
RIOMap *map;
|
||||
int i = 0;
|
||||
list = r_list_new ();
|
||||
//list->free = r_debug_map_free;
|
||||
ls_foreach (dbg->iob.io->maps, iter, map) {
|
||||
r_vector_foreach (&dbg->iob.io->maps.v, map) {
|
||||
m = r_debug_map_new (map->name,
|
||||
map->itv.addr,
|
||||
map->itv.addr + map->itv.size,
|
||||
@@ -237,7 +236,7 @@ static RDebugInfo* r_debug_unicorn_info(RDebug *dbg, const char *arg) {
|
||||
return rdi;
|
||||
}
|
||||
|
||||
static RDebugMap * r_debug_unicorn_map_alloc(RDebug *dbg, ut64 addr, int size) {
|
||||
static RDebugMap * r_debug_unicorn_map_alloc(RDebug *dbg, ut64 addr, int size, bool thp) {
|
||||
RDebugMap *map;
|
||||
uc_err err = uc_mem_map (uh, addr, size, UC_PROT_WRITE | UC_PROT_READ);
|
||||
if (err) {
|
||||
@@ -263,7 +262,7 @@ static int r_debug_unicorn_map_dealloc(RDebug *dbg, ut64 addr, int size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int r_debug_unicorn_detach(int pid) {
|
||||
static int r_debug_unicorn_detach(RDebug *dbg, int pid) {
|
||||
if (uh) {
|
||||
/* unicorn lib doesnt checks for null. it just crashes -_-U */
|
||||
uc_close (uh);
|
||||
@@ -275,7 +274,7 @@ static int r_debug_unicorn_detach(int pid) {
|
||||
static bool r_debug_unicorn_kill(RDebug *dbg, int pid, int tid, int sig) {
|
||||
// TODO: implement thread support signaling here
|
||||
message ("TODO: r_debug_unicorn_kill\n");
|
||||
(void)r_debug_unicorn_detach(pid);
|
||||
(void)r_debug_unicorn_detach(dbg, pid);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -390,7 +389,10 @@ static void _insn_out(uc_engine *handle, uint32_t port, int size, uint32_t value
|
||||
static bool _mem_invalid(uc_engine *handle, uc_mem_type type,
|
||||
uint64_t address, int size, int64_t value, void *user_data) {
|
||||
const char *typestr = "";
|
||||
switch(type) {
|
||||
switch (type) {
|
||||
case UC_MEM_READ_AFTER:
|
||||
typestr = "read-after";
|
||||
break;
|
||||
case UC_MEM_READ:
|
||||
typestr = "read";
|
||||
break;
|
||||
@@ -485,7 +487,7 @@ static int r_debug_unicorn_attach(RDebug *dbg, int pid) {
|
||||
return ret;
|
||||
#endif
|
||||
//if (!uh) {
|
||||
r_debug_unicorn_detach (pid);
|
||||
r_debug_unicorn_detach (dbg, pid);
|
||||
r_debug_unicorn_init (dbg);
|
||||
//}
|
||||
return 'U' + 'N' + 'I' + 'C' + 'O' + 'R' + 'N';
|
||||
@@ -508,7 +510,6 @@ static int r_debug_unicorn_wait(RDebug *dbg, int pid) {
|
||||
}
|
||||
|
||||
static int r_debug_unicorn_init(RDebug *dbg) {
|
||||
SdbListIter *iter;
|
||||
int code_is_mapped;
|
||||
RIOMap *map;
|
||||
int bits = (dbg->bits & R_SYS_BITS_64) ? 64: 32;
|
||||
@@ -532,7 +533,7 @@ static int r_debug_unicorn_init(RDebug *dbg) {
|
||||
return false;
|
||||
}
|
||||
ut64 lastvaddr = 0LL;
|
||||
int n_sect = ls_length (dbg->iob.io->maps);
|
||||
size_t n_sect = dbg->iob.io->maps.v.len;
|
||||
if (n_sect == 0) {
|
||||
message (logo);
|
||||
message ("[UNICORN] dpa # reatach to initialize the unicorn\n");
|
||||
@@ -540,7 +541,7 @@ static int r_debug_unicorn_init(RDebug *dbg) {
|
||||
}
|
||||
code_is_mapped = 0;
|
||||
|
||||
ls_foreach (dbg->iob.io->maps, iter, map) {
|
||||
r_vector_foreach (&dbg->iob.io->maps.v, map) {
|
||||
int perms = 0;
|
||||
if (map->perm & R_PERM_R) perms |= UC_PROT_READ;
|
||||
if (map->perm & R_PERM_W) perms |= UC_PROT_WRITE;
|
||||
|
||||
@@ -164,6 +164,13 @@ static char *get_field_imm15 (long instr)
|
||||
return (tmpstr);
|
||||
}
|
||||
|
||||
static char *get_field_imm5 (long instr)
|
||||
{
|
||||
char *tmpstr;
|
||||
tmpstr = r_str_newf ("%u", (short)((instr & IMM5_MASK) >> IMM_LOW));
|
||||
return (tmpstr);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_field_special (long instr, struct op_code_struct * op)
|
||||
{
|
||||
@@ -244,7 +251,6 @@ static void analyse_arithmetic_inst_imm(struct mb_anal_ctx *ctx, unsigned long i
|
||||
struct op_code_struct *mb_op) {
|
||||
RAnalOp *op = ctx->op;
|
||||
char *ra = get_field_r1 (insn);
|
||||
char *rb = get_field_r2 (insn);
|
||||
char *rd = get_field_rd (insn);
|
||||
char *imm = get_imm (ctx, insn);
|
||||
|
||||
@@ -254,40 +260,38 @@ static void analyse_arithmetic_inst_imm(struct mb_anal_ctx *ctx, unsigned long i
|
||||
switch (mb_op->instr) {
|
||||
case addi:
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,+,%s,=", ra, rd);
|
||||
r_strbuf_appendf (&op->esil, ",31,$c,c,=");
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case rsubi:
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,-,%s,=", ra, rd);
|
||||
r_strbuf_appendf (&op->esil, "%s,_imm,-,%s,=", ra, rd);
|
||||
r_strbuf_appendf (&op->esil, ",1,$b,!,c,=");
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
case addic:
|
||||
/* should use carry */
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,+,%s,=", ra, rd);
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,+,c,+,%s,=", ra, rd);
|
||||
r_strbuf_appendf (&op->esil, ",31,$c,c,=");
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case rsubic:
|
||||
/* should use carry */
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,-,%s,=", ra, rd);
|
||||
r_strbuf_appendf (&op->esil, "%s,_imm,-,c,+,%s,=", ra, rd);
|
||||
r_strbuf_appendf (&op->esil, ",1,$b,!,c,=");
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
case addik:
|
||||
/* should keep carry */
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,+,%s,=", ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case rsubik:
|
||||
/* should keep carry */
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,-,%s,=", ra, rd);
|
||||
r_strbuf_appendf (&op->esil, "%s,_imm,-,%s,=", ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
case addikc:
|
||||
/* should use and keep carry */
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,+,%s,=", ra, rd);
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,+,c,+,%s,=", ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case rsubikc:
|
||||
/* should use and keep carry */
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,-,%s,=", ra, rd);
|
||||
r_strbuf_appendf (&op->esil, "%s,_imm,-,c,+,%s,=", ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
}
|
||||
@@ -306,27 +310,29 @@ static void analyse_arithmetic_inst(struct mb_anal_ctx *ctx, unsigned long insn,
|
||||
switch (mb_op->instr) {
|
||||
case add:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,+,%s,=", ra, rb, rd);
|
||||
r_strbuf_appendf (&op->esil, ",31,$c,c,=");
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case rsub:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,-,%s,=", ra, rb, rd);
|
||||
r_strbuf_appendf (&op->esil, ",1,$b,!,c,=");
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
case addc:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,c,+,+,%s,=", ra, rb, rd);
|
||||
r_strbuf_appendf (&op->esil, "32,%s,>>,c,+=", rd);
|
||||
r_strbuf_appendf (&op->esil, ",31,$c,c,=");
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case rsubc:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,-,c,+,%s,=", ra, rb, rd);
|
||||
r_strbuf_appendf (&op->esil, ",1,$b,!,c,=");
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
case addk:
|
||||
/* should keep carry */
|
||||
r_strbuf_setf (&op->esil, "%s,%s,+,%s,=", ra, rb, rd);
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case rsubk:
|
||||
/* should keep carry */
|
||||
r_strbuf_setf (&op->esil, "%s,%s,-,%s,=", ra, rb, rd);
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
@@ -341,10 +347,11 @@ static void analyse_arithmetic_inst(struct mb_anal_ctx *ctx, unsigned long insn,
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
break;
|
||||
case addkc:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,c,+,+,%s,=", ra, rb, rd);
|
||||
r_strbuf_setf (&op->esil, "%s,%s,+,c,+,%s,=", ra, rb, rd);
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
break;
|
||||
case rsubkc:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,-,c,+,%s,=", ra, rb, rd);
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
break;
|
||||
case swapb:
|
||||
@@ -359,13 +366,48 @@ static void analyse_arithmetic_inst(struct mb_anal_ctx *ctx, unsigned long insn,
|
||||
r_strbuf_appendf (&op->esil, ",0,_imm,=");
|
||||
}
|
||||
|
||||
static void analyse_logical_inst_imm(struct mb_anal_ctx *ctx, unsigned long insn,
|
||||
struct op_code_struct *mb_op) {
|
||||
RAnalOp *op = ctx->op;
|
||||
char *ra = get_field_r1 (insn);
|
||||
char *rd = get_field_rd (insn);
|
||||
char *imm = get_imm (ctx, insn);
|
||||
|
||||
r_strbuf_setf (&op->esil, "1,_immf,==,$z,?{,%s,%u,&,_imm,|,_imm,=,},", imm, UT16_MAX);
|
||||
r_strbuf_appendf (&op->esil, "0,_immf,==,$z,?{,%s,_imm,=,},", imm);
|
||||
|
||||
switch (mb_op->instr) {
|
||||
case ori:
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,|,%s,=", ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_OR;
|
||||
break;
|
||||
case andi:
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,&,%s,=", ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_AND;
|
||||
break;
|
||||
case xori:
|
||||
r_strbuf_appendf (&op->esil, "_imm,%s,^,%s,=", ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_XOR;
|
||||
break;
|
||||
case andni:
|
||||
r_strbuf_appendf (&op->esil, "_imm,!,%s,&,%s,=", ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_NOT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Reset _immf to zero even if not used.
|
||||
r_strbuf_appendf (&op->esil, ",0,_immf,=");
|
||||
r_strbuf_appendf (&op->esil, ",0,_imm,=");
|
||||
}
|
||||
|
||||
static void analyse_logical_inst(struct mb_anal_ctx *ctx, unsigned long insn,
|
||||
struct op_code_struct *mb_op) {
|
||||
RAnalOp *op = ctx->op;
|
||||
char *ra = get_field_r1 (insn);
|
||||
char *rb = get_field_r2 (insn);
|
||||
char *rd = get_field_rd (insn);
|
||||
char *imm = get_imm (ctx, insn);
|
||||
|
||||
switch (mb_op->instr) {
|
||||
case or:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,|,%s,=", ra, rb, rd);
|
||||
@@ -393,32 +435,27 @@ static void analyse_logical_inst(struct mb_anal_ctx *ctx, unsigned long insn,
|
||||
case pcmpne:
|
||||
break;
|
||||
case sra:
|
||||
r_strbuf_setf (&op->esil, "1,%s,>>>,%s,=", ra, rd);
|
||||
r_strbuf_setf (&op->esil, "%s,1,&,c,=,", ra);
|
||||
r_strbuf_appendf (&op->esil, "1,%s,>>>>,%s,=", ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_SAR;
|
||||
break;
|
||||
case src:
|
||||
r_strbuf_setf (&op->esil, "1,%s,>>,%s,=,", ra, rd);
|
||||
r_strbuf_appendf (&op->esil, "31,c,<<,%s,|=", rd);
|
||||
op->type = R_ANAL_OP_TYPE_SHR;
|
||||
break;
|
||||
case srl:
|
||||
r_strbuf_setf (&op->esil, "%s,1,&,c,=,", ra);
|
||||
r_strbuf_appendf (&op->esil, "1,%s,>>,%s,=", ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_SHR;
|
||||
break;
|
||||
case sext8:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,=,7,%s,>>,?{,0xffffff00,%s,|=,}", ra, rd, ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_CAST;
|
||||
break;
|
||||
case sext16:
|
||||
break;
|
||||
case ori:
|
||||
r_strbuf_setf (&op->esil, "%s,_imm,|,%s,|,%s,=", ra, imm, rd);
|
||||
op->type = R_ANAL_OP_TYPE_OR;
|
||||
break;
|
||||
case andi:
|
||||
r_strbuf_setf (&op->esil, "%s,_imm,|,%s,&,%s,=", ra, imm, rd);
|
||||
op->type = R_ANAL_OP_TYPE_AND;
|
||||
break;
|
||||
case xori:
|
||||
r_strbuf_setf (&op->esil, "%s,_imm,|,%s,^,%s,=", ra, imm, rd);
|
||||
op->type = R_ANAL_OP_TYPE_XOR;
|
||||
break;
|
||||
case andni:
|
||||
r_strbuf_setf (&op->esil, "%s,!,%s,&,%s,=", ra, imm, rd);
|
||||
op->type = R_ANAL_OP_TYPE_NOT;
|
||||
r_strbuf_setf (&op->esil, "%s,%s,=,15,%s,>>,?{,0xffff0000,%s,|=,}", ra, rd, ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_CAST;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -537,12 +574,12 @@ static void analyse_branch_inst_imm(struct mb_anal_ctx *ctx, unsigned long insn,
|
||||
op->jump = jump_addr;
|
||||
break;
|
||||
case brai:
|
||||
r_strbuf_setf (&op->esil, "_imm,pc,=");
|
||||
r_strbuf_appendf (&op->esil, "_imm,pc,=");
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = jump_addr;
|
||||
break;
|
||||
case braid:
|
||||
r_strbuf_appendf (&op->esil, "_imm,|,pc,=");
|
||||
r_strbuf_appendf (&op->esil, "_imm,pc,=");
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
op->delay = 1;
|
||||
op->jump = jump_addr;
|
||||
@@ -559,13 +596,13 @@ static void analyse_branch_inst_imm(struct mb_anal_ctx *ctx, unsigned long insn,
|
||||
op->jump = jump_addr;
|
||||
break;
|
||||
case beqi:
|
||||
r_strbuf_appendf (&op->esil, "0,%s,==,?{,_imm,$$,+,pc,=,}", ra);
|
||||
r_strbuf_appendf (&op->esil, "0,%s,==,$z,?{,_imm,$$,+,pc,=,}", ra);
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = jump_addr;
|
||||
op->fail = op->addr + op->size;
|
||||
break;
|
||||
case beqid:
|
||||
r_strbuf_appendf (&op->esil, "0,%s,==,?{,_imm,$$,+,pc,=,}", ra);
|
||||
r_strbuf_appendf (&op->esil, "0,%s,==,$z,?{,_imm,$$,+,pc,=,}", ra);
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->delay = 1;
|
||||
op->jump = jump_addr;
|
||||
@@ -784,6 +821,7 @@ static void analyse_return_inst(struct mb_anal_ctx *ctx, unsigned long insn,
|
||||
}
|
||||
// Reset _immf to zero even if not used.
|
||||
r_strbuf_appendf (&op->esil, ",0,_immf,=");
|
||||
r_strbuf_appendf (&op->esil, ",0,_imm,=");
|
||||
}
|
||||
|
||||
static void analyse_special_inst(struct mb_anal_ctx *ctx, unsigned long insn, struct op_code_struct *mb_op) {
|
||||
@@ -858,12 +896,43 @@ static void analyse_anyware_inst(struct mb_anal_ctx *ctx, unsigned long insn, st
|
||||
r_strbuf_appendf (&op->esil, ",0,_imm,=");
|
||||
}
|
||||
|
||||
static void analyse_memory_load_inst_imm(struct mb_anal_ctx *ctx, unsigned long insn, struct op_code_struct *mb_op) {
|
||||
RAnalOp *op = ctx->op;
|
||||
char *ra = get_field_r1 (insn);
|
||||
char *rd = get_field_rd (insn);
|
||||
char *imm = get_imm (ctx, insn);
|
||||
|
||||
r_strbuf_setf (&op->esil, "1,_immf,==,$z,?{,%s,%u,&,_imm,|,_imm,=,},", imm, UT16_MAX);
|
||||
r_strbuf_appendf (&op->esil, "0,_immf,==,$z,?{,%s,_imm,=,},", imm);
|
||||
|
||||
switch (mb_op->instr) {
|
||||
case lbui:
|
||||
r_strbuf_appendf (&op->esil, "%s,_imm,+,[1],%s,=", ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
break;
|
||||
case lhui:
|
||||
r_strbuf_appendf (&op->esil, "%s,_imm,+,[4],%s,=", ra, rd);
|
||||
r_strbuf_appendf (&op->esil, ",16,%s,>>=",rd);
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
break;
|
||||
case lwi:
|
||||
r_strbuf_appendf (&op->esil, "%s,_imm,+,[4],%s,=", ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Reset _immf to zero even if not used.
|
||||
r_strbuf_appendf (&op->esil, ",0,_immf,=");
|
||||
r_strbuf_appendf (&op->esil, ",0,_imm,=");
|
||||
}
|
||||
|
||||
static void analyse_memory_load_inst(struct mb_anal_ctx *ctx, unsigned long insn, struct op_code_struct *mb_op) {
|
||||
RAnalOp *op = ctx->op;
|
||||
char *ra = get_field_r1 (insn);
|
||||
char *rb = get_field_r2 (insn);
|
||||
char *rd = get_field_rd (insn);
|
||||
char *imm = get_imm (ctx, insn);
|
||||
|
||||
switch (mb_op->instr) {
|
||||
case lbu:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,[],+,%s,=", ra, rb, rd);
|
||||
@@ -893,18 +962,37 @@ static void analyse_memory_load_inst(struct mb_anal_ctx *ctx, unsigned long insn
|
||||
r_strbuf_setf (&op->esil, "%s,%s,[],+,%s,=", ra, rb, rd);
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
break;
|
||||
case lbui:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,_imm,|,+,[1],%s,=", ra, imm, rd);
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
default:
|
||||
break;
|
||||
case lhui:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,_imm,|,+,[4],%s,=", ra, imm, rd);
|
||||
r_strbuf_appendf (&op->esil, ",16,%s,>>=",rd);
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
}
|
||||
// Reset _immf to zero even if not used.
|
||||
r_strbuf_appendf (&op->esil, ",0,_immf,=");
|
||||
r_strbuf_appendf (&op->esil, ",0,_imm,=");
|
||||
}
|
||||
|
||||
static void analyse_memory_store_inst_imm(struct mb_anal_ctx *ctx, unsigned long insn, struct op_code_struct *mb_op) {
|
||||
RAnalOp *op = ctx->op;
|
||||
char *ra = get_field_r1 (insn);
|
||||
char *rd = get_field_rd (insn);
|
||||
char *imm = get_imm (ctx, insn);
|
||||
|
||||
r_strbuf_setf (&op->esil, "1,_immf,==,$z,?{,%s,%u,&,_imm,|,_imm,=,},", imm, UT16_MAX);
|
||||
r_strbuf_appendf (&op->esil, "0,_immf,==,$z,?{,%s,_imm,=,},", imm);
|
||||
|
||||
switch (mb_op->instr) {
|
||||
case sbi:
|
||||
/* Only store least significant byte */
|
||||
r_strbuf_appendf (&op->esil, "%s,%s,_imm,+,=[1]", rd, ra);
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
break;
|
||||
case lwi:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,_imm,|,+,[4],%s,=", ra, imm, rd);
|
||||
op->type = R_ANAL_OP_TYPE_LOAD;
|
||||
case shi:
|
||||
/* Only store least significant halword */
|
||||
r_strbuf_appendf (&op->esil, "%s,%s,_imm,+,=[2]", rd, ra);
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
break;
|
||||
case swi:
|
||||
r_strbuf_appendf (&op->esil, "%s,%s,_imm,+,=[]", rd, ra);
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -919,7 +1007,7 @@ static void analyse_memory_store_inst(struct mb_anal_ctx *ctx, unsigned long ins
|
||||
char *ra = get_field_r1 (insn);
|
||||
char *rb = get_field_r2 (insn);
|
||||
char *rd = get_field_rd (insn);
|
||||
char *imm = get_imm (ctx, insn);
|
||||
|
||||
switch (mb_op->instr) {
|
||||
case sb:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,%s,+,=[1]", rd, ra, rb);
|
||||
@@ -951,20 +1039,6 @@ static void analyse_memory_store_inst(struct mb_anal_ctx *ctx, unsigned long ins
|
||||
r_strbuf_setf (&op->esil, "%s,%s,+,%s,=[]", rd, ra, rb);
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
break;
|
||||
case sbi:
|
||||
/* Only store least significant byte */
|
||||
r_strbuf_setf (&op->esil, ",%s,%s,%s,_imm,|,+,=[1]", rd, ra, imm);
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
break;
|
||||
case shi:
|
||||
/* Only store least significant halword */
|
||||
r_strbuf_setf (&op->esil, ",%s,%s,%s,_imm,|,+,=[2]", rd, ra, imm);
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
break;
|
||||
case swi:
|
||||
r_strbuf_setf (&op->esil, "%s,%s,%s,_imm,|,+,=[]", rd, ra, imm);
|
||||
op->type = R_ANAL_OP_TYPE_STORE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -975,23 +1049,34 @@ static void analyse_memory_store_inst(struct mb_anal_ctx *ctx, unsigned long ins
|
||||
|
||||
static void analyse_barrel_shift_inst(struct mb_anal_ctx *ctx, unsigned long insn, struct op_code_struct *mb_op) {
|
||||
RAnalOp *op = ctx->op;
|
||||
char *ra = get_field_r1 (insn);
|
||||
char *rb = get_field_r2 (insn);
|
||||
char *rd = get_field_rd (insn);
|
||||
char *imm5 = get_field_imm5 (insn);
|
||||
|
||||
switch (mb_op->instr) {
|
||||
case bsll:
|
||||
r_strbuf_setf (&op->esil, ",%s,%s,<<,%s,=", rb, ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_SHL;
|
||||
break;
|
||||
case bsra:
|
||||
r_strbuf_setf (&op->esil, ",%s,%s,>>>>,%s,=", rb, ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_SAR;
|
||||
break;
|
||||
case bsrl:
|
||||
r_strbuf_setf (&op->esil, ",%s,%s,>>,%s,=", rb, ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_SHR;
|
||||
break;
|
||||
case bslli:
|
||||
r_strbuf_setf (&op->esil, ",%s,%s,<<,%s,=", imm5, ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_SHL;
|
||||
break;
|
||||
case bsrai:
|
||||
r_strbuf_setf (&op->esil, ",%s,%s,>>>>,%s,=", imm5, ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_SAR;
|
||||
break;
|
||||
case bsrli:
|
||||
r_strbuf_setf (&op->esil, ",%s,%s,>>,%s,=", imm5, ra, rd);
|
||||
op->type = R_ANAL_OP_TYPE_SHR;
|
||||
break;
|
||||
default:
|
||||
@@ -999,10 +1084,11 @@ static void analyse_barrel_shift_inst(struct mb_anal_ctx *ctx, unsigned long ins
|
||||
}
|
||||
// Reset _immf to zero even if not used.
|
||||
r_strbuf_appendf (&op->esil, ",0,_immf,=");
|
||||
r_strbuf_appendf (&op->esil, ",0,_imm,=");
|
||||
}
|
||||
|
||||
|
||||
static int microblaze_op(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
|
||||
static int microblaze_op(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
|
||||
int oplen = 4;
|
||||
static struct mb_anal_ctx ctx;
|
||||
static bool first_time = true;
|
||||
@@ -1055,6 +1141,9 @@ static int microblaze_op(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int l
|
||||
op->type = R_ANAL_OP_TYPE_ILL;
|
||||
return oplen;
|
||||
}
|
||||
if (mask & R_ANAL_OP_MASK_DISASM) {
|
||||
op->mnemonic = strdup (mb_op->name);
|
||||
}
|
||||
|
||||
r_strbuf_setf (&op->esil, "");
|
||||
handle_immediate_inst (&ctx, insn, mb_op);
|
||||
@@ -1072,6 +1161,9 @@ static int microblaze_op(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int l
|
||||
case logical_inst:
|
||||
analyse_logical_inst (&ctx, insn, mb_op);
|
||||
break;
|
||||
case logical_inst_imm:
|
||||
analyse_logical_inst_imm (&ctx, insn, mb_op);
|
||||
break;
|
||||
case mult_inst:
|
||||
analyse_mult_inst (&ctx, insn, mb_op);
|
||||
break;
|
||||
@@ -1093,9 +1185,15 @@ static int microblaze_op(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int l
|
||||
case memory_load_inst:
|
||||
analyse_memory_load_inst (&ctx, insn, mb_op);
|
||||
break;
|
||||
case memory_load_inst_imm:
|
||||
analyse_memory_load_inst_imm (&ctx, insn, mb_op);
|
||||
break;
|
||||
case memory_store_inst:
|
||||
analyse_memory_store_inst (&ctx, insn, mb_op);
|
||||
break;
|
||||
case memory_store_inst_imm:
|
||||
analyse_memory_store_inst_imm (&ctx, insn, mb_op);
|
||||
break;
|
||||
case barrel_shift_inst:
|
||||
analyse_barrel_shift_inst (&ctx, insn, mb_op);
|
||||
break;
|
||||
@@ -1125,7 +1223,7 @@ static int microblaze_set_reg_profile(RAnal* anal) {
|
||||
"=A6 r10\n"
|
||||
"=R0 r3\n"
|
||||
"=R1 r4\n"
|
||||
"gpr r0 .32 0 0\n"
|
||||
"gpr r0 .32 ? 0\n"
|
||||
"gpr r1 .32 4 0\n"
|
||||
"gpr r2 .32 8 0\n"
|
||||
"gpr r3 .32 12 0\n"
|
||||
@@ -1159,7 +1257,7 @@ static int microblaze_set_reg_profile(RAnal* anal) {
|
||||
"gpr r31 .32 124 0\n"
|
||||
"gpr pc .32 128 0\n"
|
||||
"gpr msr .32 132 0\n" /* machine status register */
|
||||
"gpr c .1 132.29 0\n" /* arithmetic carry */
|
||||
"gpr c .1 132.2 0\n" /* arithmetic carry */
|
||||
"gpr ear .32 136 0\n" /* exception address register */
|
||||
"gpr esr .32 140 0\n" /* exception status register */
|
||||
"gpr btr .32 144 0\n" /* branch target register */
|
||||
|
||||
@@ -199,10 +199,10 @@ static struct op_code_struct
|
||||
{"bgtd", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9E800000, OPCODE_MASK_H14, bgtd, branch_inst },
|
||||
{"bge", INST_TYPE_R1_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9CA00000, OPCODE_MASK_H14, bge, branch_inst },
|
||||
{"bged", INST_TYPE_R1_R2, INST_PC_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x9EA00000, OPCODE_MASK_H14, bged, branch_inst },
|
||||
{"ori", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA0000000, OPCODE_MASK_H, ori, logical_inst },
|
||||
{"andi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA4000000, OPCODE_MASK_H, andi, logical_inst },
|
||||
{"xori", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA8000000, OPCODE_MASK_H, xori, logical_inst },
|
||||
{"andni", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xAC000000, OPCODE_MASK_H, andni, logical_inst },
|
||||
{"ori", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA0000000, OPCODE_MASK_H, ori, logical_inst_imm },
|
||||
{"andi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA4000000, OPCODE_MASK_H, andi, logical_inst_imm },
|
||||
{"xori", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xA8000000, OPCODE_MASK_H, xori, logical_inst_imm },
|
||||
{"andni", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xAC000000, OPCODE_MASK_H, andni, logical_inst_imm },
|
||||
{"imm", INST_TYPE_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB0000000, OPCODE_MASK_H12, imm, immediate_inst },
|
||||
{"rtsd", INST_TYPE_R1_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6000000, OPCODE_MASK_H1, rtsd, return_inst },
|
||||
{"rtid", INST_TYPE_R1_IMM, INST_NO_OFFSET, DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xB6200000, OPCODE_MASK_H1, rtid, return_inst },
|
||||
@@ -241,12 +241,12 @@ static struct op_code_struct
|
||||
{"sw", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000000, OPCODE_MASK_H4, sw, memory_store_inst },
|
||||
{"swr", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000200, OPCODE_MASK_H4, swr, memory_store_inst },
|
||||
{"swx", INST_TYPE_RD_R1_R2, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xD8000400, OPCODE_MASK_H4, swx, memory_store_inst },
|
||||
{"lbui", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE0000000, OPCODE_MASK_H, lbui, memory_load_inst },
|
||||
{"lhui", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE4000000, OPCODE_MASK_H, lhui, memory_load_inst },
|
||||
{"lwi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE8000000, OPCODE_MASK_H, lwi, memory_load_inst },
|
||||
{"sbi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF0000000, OPCODE_MASK_H, sbi, memory_store_inst },
|
||||
{"shi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF4000000, OPCODE_MASK_H, shi, memory_store_inst },
|
||||
{"swi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF8000000, OPCODE_MASK_H, swi, memory_store_inst },
|
||||
{"lbui", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE0000000, OPCODE_MASK_H, lbui, memory_load_inst_imm },
|
||||
{"lhui", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE4000000, OPCODE_MASK_H, lhui, memory_load_inst_imm },
|
||||
{"lwi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xE8000000, OPCODE_MASK_H, lwi, memory_load_inst_imm },
|
||||
{"sbi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF0000000, OPCODE_MASK_H, sbi, memory_store_inst_imm },
|
||||
{"shi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF4000000, OPCODE_MASK_H, shi, memory_store_inst_imm },
|
||||
{"swi", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0xF8000000, OPCODE_MASK_H, swi, memory_store_inst_imm },
|
||||
{"nop", INST_TYPE_NONE, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x80000000, OPCODE_MASK_H1234, invalid_inst, logical_inst }, /* translates to or r0, r0, r0. */
|
||||
{"la", INST_TYPE_RD_R1_IMM, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x30000000, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* la translates to addik. */
|
||||
{"tuqula",INST_TYPE_RD, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x3000002A, OPCODE_MASK_H, invalid_inst, arithmetic_inst }, /* tuqula rd translates to addik rd, r0, 42. */
|
||||
|
||||
@@ -61,9 +61,10 @@ enum microblaze_instr
|
||||
|
||||
enum microblaze_instr_type
|
||||
{
|
||||
arithmetic_inst, arithmetic_inst_imm, logical_inst, mult_inst, div_inst, branch_inst,
|
||||
branch_inst_imm, return_inst, immediate_inst, special_inst, memory_load_inst,
|
||||
memory_store_inst, barrel_shift_inst, anyware_inst
|
||||
arithmetic_inst, arithmetic_inst_imm, logical_inst, logical_inst_imm,
|
||||
mult_inst, div_inst, branch_inst, branch_inst_imm, return_inst,
|
||||
immediate_inst, special_inst, memory_load_inst, memory_load_inst_imm,
|
||||
memory_store_inst, memory_store_inst_imm, barrel_shift_inst, anyware_inst
|
||||
};
|
||||
|
||||
#define INST_WORD_SIZE 4
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.3 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
Executable
+457
@@ -0,0 +1,457 @@
|
||||
#!/usr/bin/python3.8
|
||||
from __future__ import print_function
|
||||
import r2lang
|
||||
import r2pipe
|
||||
from graph import Graph # pip3 install graph-theory
|
||||
from tempfile import NamedTemporaryFile
|
||||
from random import choice
|
||||
from string import ascii_uppercase
|
||||
from json import dumps
|
||||
from sys import argv
|
||||
from os import system
|
||||
import traceback
|
||||
|
||||
__author__ = "s0i37"
|
||||
__version__ = 0.10
|
||||
|
||||
r2 = r2pipe.open()
|
||||
MAX_DEEP = int( argv[1] ) if len(argv) > 1 else 100
|
||||
|
||||
|
||||
def aG():
|
||||
'''Recursive graphs:
|
||||
aGx[format] references to current function (Xrefs to graph)
|
||||
aGc[format] calls of current function (Xrefs from graph)
|
||||
aGC[format] calls of all functions (Global calls graph)
|
||||
|
||||
Output formats:
|
||||
<blank> simple text
|
||||
v interactive ascii art
|
||||
d graphviz dot
|
||||
w webGL 3D graph
|
||||
'''
|
||||
print(aG.__doc__)
|
||||
|
||||
def just_print(graph):
|
||||
from colorama import Fore
|
||||
|
||||
def get_node_color(sub):
|
||||
if sub.find('imp.') != -1:
|
||||
return Fore.LIGHTYELLOW_EX
|
||||
elif sub.find('sym.') != -1:
|
||||
return Fore.LIGHTGREEN_EX
|
||||
elif sub.find('sub.') != -1:
|
||||
return Fore.LIGHTMAGENTA_EX
|
||||
else:
|
||||
return Fore.LIGHTWHITE_EX
|
||||
|
||||
def walk(node, deep):
|
||||
print("%s%s" % (" "*deep, get_node_color(node) + node + Fore.RESET))
|
||||
for sub_node in nodes[node]:
|
||||
walk(sub_node, deep+1)
|
||||
|
||||
nodes = graph.to_dict()
|
||||
for node in graph.roots:
|
||||
walk(node, 0)
|
||||
|
||||
def v(graph):
|
||||
'''Interactive ascii art'''
|
||||
def walk(node):
|
||||
for sub_node in nodes[node]:
|
||||
r2.cmd("agn {sub}".format(sub=sub_node))
|
||||
r2.cmd("age {sub1} {sub2}".format(sub1=node, sub2=sub_node))
|
||||
walk(sub_node)
|
||||
r2.cmd("ag-")
|
||||
nodes = graph.to_dict()
|
||||
for node in graph.roots:
|
||||
r2.cmd("agn {sub}".format(sub=node))
|
||||
walk(node)
|
||||
r2.cmd("aggv")
|
||||
|
||||
def d(graph):
|
||||
'''Graphviz dot'''
|
||||
import pydot
|
||||
|
||||
def get_node_color(sub):
|
||||
if sub.find('imp.') != -1:
|
||||
return 'yellow','black'
|
||||
elif sub.find('sym.') != -1:
|
||||
return 'green','black'
|
||||
elif sub.find('sub.') != -1:
|
||||
return 'purple','white'
|
||||
else:
|
||||
return 'black','white'
|
||||
|
||||
known_nodes = set()
|
||||
known_edges = set()
|
||||
def walk(node):
|
||||
for sub_node in nodes[node]:
|
||||
if not graph.node(sub_node) in known_nodes:
|
||||
dot.add_node(pydot.Node(sub_node, style="filled", fillcolor=get_node_color(sub_node)[0], fontcolor=get_node_color(sub_node)[1]))
|
||||
known_nodes.add(graph.node(sub_node))
|
||||
if not (node, sub_node) in known_edges:
|
||||
dot.add_edge(pydot.Edge(node, sub_node))
|
||||
known_edges.add((node, sub_node))
|
||||
walk(sub_node)
|
||||
|
||||
nodes = graph.to_dict()
|
||||
dot = pydot.Dot(graph_type='digraph')
|
||||
for node in graph.roots:
|
||||
if not graph.node(node) in known_nodes:
|
||||
dot.add_node(pydot.Node(node, style="filled", fillcolor=get_node_color(node)[0], fontcolor=get_node_color(node)[1]))
|
||||
known_nodes.add(graph.node(node))
|
||||
walk(node)
|
||||
|
||||
tmpfile = NamedTemporaryFile(suffix='.dot', delete=False)
|
||||
dot.write_dot(tmpfile.name)
|
||||
system('xdot %s &' % tmpfile.name)
|
||||
|
||||
def w(graph):
|
||||
'''WebGL 3D graph (regards https://github.com/vasturiano/3d-force-graph)'''
|
||||
WWW='''
|
||||
<head>
|
||||
<style> body { margin: 0; } </style>
|
||||
<script src="https://unpkg.com/three"></script>
|
||||
<script src="https://unpkg.com/three-spritetext"></script>
|
||||
<script src="https://unpkg.com/3d-force-graph"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="3d-graph"></div>
|
||||
<script>
|
||||
var xrefs = __xrefs__
|
||||
const elem = document.getElementById('3d-graph');
|
||||
const nodes = {}
|
||||
xrefs.nodes.forEach(node => {
|
||||
nodes[node.id] = node
|
||||
})
|
||||
xrefs.links.forEach(link => {
|
||||
const a = nodes[link.source];
|
||||
const b = nodes[link.target];
|
||||
!a.neighbors && (a.neighbors = []);
|
||||
!b.neighbors && (b.neighbors = []);
|
||||
a.neighbors.push(b);
|
||||
b.neighbors.push(a);
|
||||
|
||||
!a.links && (a.links = []);
|
||||
!b.links && (b.links = []);
|
||||
a.links.push(link);
|
||||
b.links.push(link);
|
||||
});
|
||||
|
||||
const highlightNodes = new Set();
|
||||
const highlightLinks = new Set();
|
||||
let hoverNode = null;
|
||||
|
||||
const Graph = ForceGraph3D()(elem)
|
||||
.graphData(xrefs)
|
||||
.nodeAutoColorBy('color')
|
||||
.nodeLabel(node => `${node.name}`)
|
||||
.onNodeHover(node => elem.style.cursor = node ? 'pointer' : null)
|
||||
.onNodeClick(node => alert(`function ${node.id}`))
|
||||
.nodeThreeObject(node => {
|
||||
const obj = new THREE.Mesh(
|
||||
new THREE.SphereGeometry(10),
|
||||
new THREE.MeshBasicMaterial({ depthWrite: false, transparent: true, opacity: 0 })
|
||||
);
|
||||
const sprite = new SpriteText(node.name);
|
||||
sprite.color = node.color;
|
||||
sprite.textHeight = 8;
|
||||
obj.add(sprite);
|
||||
return obj;
|
||||
})
|
||||
.onNodeDragEnd(node => {
|
||||
node.fx = node.x;
|
||||
node.fy = node.y;
|
||||
node.fz = node.z;
|
||||
})
|
||||
.nodeColor(node => highlightNodes.has(node) ? node === hoverNode ? 'rgb(255,0,0,1)' : 'rgba(255,160,0,0.8)' : 'rgba(0,255,255,0.6)')
|
||||
.linkWidth(link => highlightLinks.has(link) ? 4 : 1)
|
||||
.linkDirectionalParticles(link => highlightLinks.has(link) ? 4 : 0)
|
||||
.linkDirectionalParticleWidth(4)
|
||||
.onNodeHover(node => {
|
||||
if ((!node && !highlightNodes.size) || (node && hoverNode === node)) return;
|
||||
highlightNodes.clear();
|
||||
highlightLinks.clear();
|
||||
if (node) {
|
||||
highlightNodes.add(node);
|
||||
node.neighbors.forEach(neighbor => highlightNodes.add(neighbor));
|
||||
node.links.forEach(link => highlightLinks.add(link));
|
||||
}
|
||||
hoverNode = node || null;
|
||||
updateHighlight();
|
||||
})
|
||||
.onLinkHover(link => {
|
||||
highlightNodes.clear();
|
||||
highlightLinks.clear();
|
||||
if (link) {
|
||||
highlightLinks.add(link);
|
||||
highlightNodes.add(link.source);
|
||||
highlightNodes.add(link.target);
|
||||
}
|
||||
updateHighlight();
|
||||
});
|
||||
Graph.d3Force('charge').strength(-120);
|
||||
|
||||
function updateHighlight() {
|
||||
Graph
|
||||
.nodeColor(Graph.nodeColor())
|
||||
.linkWidth(Graph.linkWidth())
|
||||
.linkDirectionalParticles(Graph.linkDirectionalParticles());
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
'''
|
||||
def get_color(name):
|
||||
if name == graph.origin:
|
||||
return 'red'
|
||||
elif name.find('imp.') != -1:
|
||||
return 'yellow'
|
||||
elif name.find('sym.') != -1:
|
||||
return 'green'
|
||||
elif name.find('sub.') != -1:
|
||||
return 'purple'
|
||||
else:
|
||||
return 'white'
|
||||
|
||||
xrefs = {'nodes': [], 'links': []}
|
||||
|
||||
known_nodes = set()
|
||||
known_edges = set()
|
||||
def walk(node):
|
||||
for sub_node in nodes[node]:
|
||||
if not graph.node(sub_node) in known_nodes:
|
||||
xrefs['nodes'].append(
|
||||
{
|
||||
"id": graph.node(sub_node),
|
||||
"name": sub_node,
|
||||
"description": sub_node,
|
||||
"color": get_color(sub_node)
|
||||
}
|
||||
)
|
||||
known_nodes.add(graph.node(sub_node))
|
||||
if not (graph.node(node), graph.node(sub_node)) in known_edges:
|
||||
xrefs['links'].append(
|
||||
{
|
||||
"source": graph.node(node),
|
||||
"target": graph.node(sub_node),
|
||||
"color": get_color(sub_node)
|
||||
}
|
||||
)
|
||||
known_edges.add((graph.node(node), graph.node(sub_node)))
|
||||
walk(sub_node)
|
||||
|
||||
nodes = graph.to_dict()
|
||||
for node in graph.roots:
|
||||
if not graph.node(node) in known_nodes:
|
||||
xrefs['nodes'].append(
|
||||
{
|
||||
"id": graph.node(node),
|
||||
"name": node,
|
||||
"description": node,
|
||||
"color": get_color(node)
|
||||
}
|
||||
)
|
||||
known_nodes.add(graph.node(node))
|
||||
walk(node)
|
||||
|
||||
tmpfile = NamedTemporaryFile(suffix='.html', delete=False)
|
||||
with open(tmpfile.name, 'w') as o:
|
||||
o.write( WWW.replace('__xrefs__', dumps(xrefs)) )
|
||||
system('xdg-open %s &' % tmpfile.name)
|
||||
|
||||
|
||||
def aGx(command):
|
||||
'''xrefs to'''
|
||||
graph = Graph()
|
||||
graph.roots = set()
|
||||
known_subs = set()
|
||||
def fcns_walk(fcn, calls):
|
||||
xref = None
|
||||
for xref in r2.cmdj( 'axtj {fcn}'.format(fcn=fcn) ):
|
||||
if xref["type"].lower() == "call":
|
||||
sub_fcn = xref.get("fcn_name")
|
||||
sub_fcn_addr = xref.get("fcn_addr")
|
||||
if not sub_fcn:
|
||||
sub_fcn = r2.cmdj("fdj @ {addr}".format(addr=xref.get("from")))["name"] or hex(addr)
|
||||
|
||||
if sub_fcn in calls: # anti loop
|
||||
continue
|
||||
|
||||
if not sub_fcn in graph:
|
||||
graph.add_node(sub_fcn, sub_fcn_addr)
|
||||
|
||||
graph.add_edge(sub_fcn, fcn)
|
||||
|
||||
if sub_fcn in known_subs or len(calls) >= MAX_DEEP:
|
||||
graph.roots.add(sub_fcn)
|
||||
continue
|
||||
|
||||
known_subs.add(sub_fcn)
|
||||
fcns_walk(sub_fcn, calls+[sub_fcn])
|
||||
|
||||
if not xref:
|
||||
graph.roots.add(fcn)
|
||||
|
||||
current_fcn = r2.cmd("afn").split('\n')[0] or r2.cmdj("fdj")["name"] or r2.cmd("s")
|
||||
current_addr = int(r2.cmd("s").split('\n')[0], 16)
|
||||
graph.origin = current_fcn
|
||||
known_subs.add(current_fcn)
|
||||
graph.add_node(current_fcn, current_addr)
|
||||
try:
|
||||
fcns_walk(current_fcn, [current_fcn])
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
|
||||
|
||||
if command == "aGx":
|
||||
just_print(graph)
|
||||
elif command == "aGxv":
|
||||
v(graph)
|
||||
elif command == "aGxd":
|
||||
d(graph)
|
||||
elif command == "aGxw":
|
||||
w(graph)
|
||||
|
||||
def aGc(command):
|
||||
'''xrefs from'''
|
||||
graph = Graph()
|
||||
graph.roots = set()
|
||||
known_subs = set()
|
||||
def fcns_walk(fcn, deep, calls):
|
||||
subs = set()
|
||||
for xref in r2.cmdj("afxj @ {fcn}".format(fcn=fcn)):
|
||||
if xref["type"] == "call":
|
||||
sub_fcn_addr = xref["to"]
|
||||
sub_fcn = r2.cmd("afn @ {addr}".format(addr=sub_fcn_addr)).split('\n')[0] or r2.cmdj("fdj @ {addr}".format(addr=sub_fcn_addr))["name"] or hex(sub_fcn_addr)
|
||||
|
||||
if sub_fcn in calls: # anti loop
|
||||
continue
|
||||
|
||||
if not sub_fcn in subs:
|
||||
subs.add(sub_fcn)
|
||||
graph.add_node(sub_fcn, sub_fcn_addr)
|
||||
graph.add_edge(fcn, sub_fcn)
|
||||
if sub_fcn in known_subs or deep >= MAX_DEEP:
|
||||
continue
|
||||
known_subs.add(sub_fcn)
|
||||
fcns_walk(sub_fcn, deep+1, calls+[sub_fcn])
|
||||
|
||||
current_fcn = r2.cmd("afn").split('\n')[0] or r2.cmdj("fdj")["name"] or r2.cmd("s")
|
||||
current_addr = int(r2.cmd("s").split('\n')[0], 16)
|
||||
graph.origin = current_fcn
|
||||
graph.add_node(current_fcn, current_addr)
|
||||
graph.roots.add(current_fcn)
|
||||
try:
|
||||
fcns_walk(current_fcn, 1, [current_fcn])
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
|
||||
|
||||
if command == "aGc":
|
||||
just_print(graph)
|
||||
elif command == "aGcv":
|
||||
v(graph)
|
||||
elif command == "aGcd":
|
||||
d(graph)
|
||||
elif command == "aGcw":
|
||||
w(graph)
|
||||
|
||||
def aGC(command):
|
||||
'''global calls graph'''
|
||||
graph = Graph()
|
||||
graph.roots = set()
|
||||
def unknown():
|
||||
return "unknown_" + "".join(map(lambda i:choice(ascii_uppercase), range(5)))
|
||||
|
||||
current_fcn = r2.cmd("afn").split('\n')[0] or r2.cmdj("fdj")["name"] or r2.cmd("s")
|
||||
graph.origin = current_fcn
|
||||
|
||||
nodes_from = set()
|
||||
nodes_to = set()
|
||||
for xref in r2.cmdj('axj'):
|
||||
if xref['type'] == 'CALL' and xref['addr'] != 0:
|
||||
fcn_addr_from = r2.cmd('afo @%d' % xref['from'])
|
||||
fcn_from = r2.cmd('afn @%d' % xref['from']).split('\n')[0] or unknown()
|
||||
fcn_addr_to = r2.cmd('afo @%d' % xref['addr'])
|
||||
fcn_to = r2.cmd('afn @%d' % xref['addr']).split('\n')[0] or unknown()
|
||||
if fcn_addr_from and fcn_addr_to:
|
||||
if not fcn_from in graph:
|
||||
graph.add_node(fcn_from, fcn_addr_from)
|
||||
|
||||
if not fcn_to in graph:
|
||||
graph.add_node(fcn_to, fcn_addr_to)
|
||||
|
||||
graph.add_edge(fcn_from, fcn_to)
|
||||
nodes_from.add(fcn_from)
|
||||
nodes_to.add(fcn_to)
|
||||
|
||||
graph.roots = nodes_from - nodes_to
|
||||
|
||||
graph_without_loops = Graph()
|
||||
graph_without_loops.roots = graph.roots
|
||||
graph_without_loops.origin = graph.origin
|
||||
known_nodes = set()
|
||||
def check_loops(node, calls):
|
||||
graph_without_loops.add_node(node, graph.node(node))
|
||||
for sub_node in nodes[node]:
|
||||
|
||||
if sub_node in calls: # anti loop
|
||||
continue
|
||||
|
||||
graph_without_loops.add_node(sub_node, graph.node(sub_node))
|
||||
graph_without_loops.add_edge(node, sub_node)
|
||||
|
||||
if sub_node in known_nodes or len(calls) >= MAX_DEEP:
|
||||
continue
|
||||
known_nodes.add(sub_node)
|
||||
check_loops(sub_node, calls+[sub_node])
|
||||
|
||||
nodes = graph.to_dict()
|
||||
for node in graph.roots:
|
||||
check_loops(node, [node])
|
||||
|
||||
if command == "aGC":
|
||||
just_print(graph_without_loops)
|
||||
elif command == "aGCv":
|
||||
v(graph_without_loops)
|
||||
elif command == "aGCd":
|
||||
d(graph_without_loops)
|
||||
elif command == "aGCw":
|
||||
w(graph_without_loops)
|
||||
|
||||
def r2xrefs(_):
|
||||
"""Build the plugin"""
|
||||
|
||||
def process(command):
|
||||
try:
|
||||
if not command in ("aG",
|
||||
"aGx", "aGxv", "aGxd", "aGxw",
|
||||
"aGc", "aGcv", "aGcd", "aGcw",
|
||||
"aGC", "aGCv", "aGCd", "aGCw"):
|
||||
return 0
|
||||
|
||||
# Parse arguments
|
||||
if command == "aG":
|
||||
aG()
|
||||
elif command.startswith("aGx"):
|
||||
aGx(command)
|
||||
elif command.startswith("aGc"):
|
||||
aGc(command)
|
||||
elif command.startswith("aGC"):
|
||||
aGC(command)
|
||||
except Exception as e:
|
||||
print(traceback.format_exc())
|
||||
|
||||
return 1
|
||||
|
||||
return {"name": "r2xrefs",
|
||||
"author": "s0i37",
|
||||
"version": 0.10,
|
||||
"licence": "GPLv3",
|
||||
"desc": "radare2 cross reference visualization",
|
||||
"call": process}
|
||||
|
||||
|
||||
# Register the plugin
|
||||
if not r2lang.plugin("core", r2xrefs):
|
||||
print("An error occurred while registering r2xrefs plugin !")
|
||||
@@ -0,0 +1,41 @@
|
||||
r2graph
|
||||
=======
|
||||
|
||||
Recursive graphs.
|
||||
|
||||
aG
|
||||
|
||||
```
|
||||
Recursive graphs:
|
||||
aGx[format] references to current function (Xrefs to graph)
|
||||
aGc[format] calls of current function (Xrefs from graph)
|
||||
aGC[format] calls of all functions (Global calls graph)
|
||||
|
||||
Output formats:
|
||||
<blank> simple text
|
||||
v interactive ascii art
|
||||
d graphviz dot
|
||||
w webGL 3D graph
|
||||
```
|
||||
|
||||
### Xrefs to graph:
|
||||
|
||||
aGx - just printing
|
||||
|
||||

|
||||
|
||||
aGxv - interactive ascii graph
|
||||
|
||||

|
||||
|
||||
### Xrefs from graph:
|
||||
|
||||
aGcd - graphviz dot graph
|
||||
|
||||

|
||||
|
||||
### Global calls graph:
|
||||
|
||||
aGCw - webGL 3D graph
|
||||
|
||||

|
||||
Generated
+6
-14
@@ -5,9 +5,9 @@
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"acorn": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.0.tgz",
|
||||
"integrity": "sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw=="
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
|
||||
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA=="
|
||||
},
|
||||
"acorn-jsx": {
|
||||
"version": "5.0.1",
|
||||
@@ -615,14 +615,6 @@
|
||||
"acorn": "^6.0.2",
|
||||
"acorn-jsx": "^5.0.0",
|
||||
"eslint-visitor-keys": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz",
|
||||
"integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"esprima": {
|
||||
@@ -1016,9 +1008,9 @@
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
||||
"version": "4.17.19",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
||||
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
|
||||
"dev": true
|
||||
},
|
||||
"loose-envify": {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
BINDIR=$(shell r2pm -H R2PM_BINDIR)
|
||||
|
||||
all: cmsis-svd
|
||||
|
||||
cmsis-svd:
|
||||
git clone https://github.com/posborne/cmsis-svd
|
||||
|
||||
install:
|
||||
cp -f r2svd.py $(BINDIR)/r2svd
|
||||
chmod +x $(BINDIR)/r2svd
|
||||
|
||||
uninstall:
|
||||
rm -f $(BINDIR)/r2svd.py
|
||||
@@ -0,0 +1,44 @@
|
||||
SVD loader for r2
|
||||
=================
|
||||
|
||||
https://github.com/radareorg/radare2/issues/15484
|
||||
|
||||
https://raw.githubusercontent.com/posborne/cmsis-svd/master/data/Atmel/AT91SAM9CN11.svd
|
||||
|
||||
Installation:
|
||||
-------------
|
||||
```
|
||||
$ r2pm -i r2svd
|
||||
```
|
||||
|
||||
or just `make install` in this directory
|
||||
|
||||
Usage:
|
||||
------
|
||||
|
||||
```
|
||||
$ r2 -m 0x400000 firmware.fw
|
||||
> !r2svd
|
||||
|
||||
TexasInstruments
|
||||
Nordic
|
||||
NXP
|
||||
Cypress
|
||||
Fujitsu
|
||||
Toshiba
|
||||
Spansion
|
||||
ARM_SAMPLE
|
||||
Nuvoton
|
||||
Freescale
|
||||
Holtek
|
||||
SiliconLabs
|
||||
SiFive-Community
|
||||
STMicro
|
||||
Atmel
|
||||
|
||||
> !r2svd Holtek
|
||||
ht32f125x.svd
|
||||
ht32f175x.svd
|
||||
ht32f275x.svd
|
||||
> .!r2svd Holtek ht32f125x.svd
|
||||
```
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
# use cmsis-svd python api to load the SVD peripheral and memory layout into r2
|
||||
# --pancake @ 2020
|
||||
|
||||
import json
|
||||
import sys
|
||||
import math
|
||||
import pkg_resources
|
||||
from cmsis_svd.parser import SVDParser
|
||||
|
||||
argc = len(sys.argv)
|
||||
if argc != 3:
|
||||
try:
|
||||
if argc == 1:
|
||||
vendors = pkg_resources.resource_listdir("cmsis_svd", "data")
|
||||
print('\n'.join(vendors))
|
||||
elif argc == 2:
|
||||
svds = pkg_resources.resource_listdir("cmsis_svd", "data/%s"%(sys.argv[1]))
|
||||
print('\n'.join(svds))
|
||||
else:
|
||||
raise Exception('')
|
||||
except:
|
||||
print('Usage: .!r2svd [mcu] [svd]')
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
mcu = sys.argv[1] # Freescale
|
||||
svd = sys.argv[2] # MK20D7.svd
|
||||
|
||||
parser = SVDParser.for_packaged_svd(mcu, svd)
|
||||
svd_dict = parser.get_device().to_dict()
|
||||
for p in svd_dict['peripherals']:
|
||||
addr = p['base_address']
|
||||
size = p['address_block']['size'] / 8
|
||||
print("CC %s @ 0x%x"%(p['description'], addr))
|
||||
print("f %s %d 0x%x"%(p['name'], size, addr))
|
||||
s = ""
|
||||
for r in p['registers']:
|
||||
offs = int(r['address_offset'])
|
||||
at = int(addr) + math.floor(offs / 8)
|
||||
bt = (offs % 8)
|
||||
s += " " + r['name']
|
||||
if at != addr:
|
||||
print("f %s.%s %d 0x%x"%(p['name'], r['name'], size, at))
|
||||
# print(" 0x%x %d %s"%(at, bt, r['name']))
|
||||
print("CC (%s) @ 0x%x"%(s, addr))
|
||||
|
||||
# print(json.dumps(svd_dict, sort_keys=True, indent=4, separators=(',', ': ')))
|
||||
@@ -0,0 +1,17 @@
|
||||
r2taint
|
||||
=======
|
||||
|
||||
Static taint analysis.
|
||||
|
||||
Usage:
|
||||
|
||||
$taint -reg rax -mem 0xADDR -mem var_name -deep N -v
|
||||
|
||||
### Demo1
|
||||
|
||||
[](https://asciinema.org/a/332707)
|
||||
|
||||
### Demo2
|
||||
|
||||
[](https://asciinema.org/a/332708)
|
||||
|
||||
Executable
+351
@@ -0,0 +1,351 @@
|
||||
#!/usr/bin/python2
|
||||
import r2pipe
|
||||
import argparse
|
||||
|
||||
__author__ = "s0i37"
|
||||
__version__ = 0.10
|
||||
|
||||
parser = argparse.ArgumentParser( description='static taint analysis' )
|
||||
parser.add_argument("-reg", action="append", default=[], help='taint register')
|
||||
parser.add_argument("-mem", action="append", default=[], help='taint memory')
|
||||
parser.add_argument("-deep", type=int, default=1, help='max analysis deep')
|
||||
parser.add_argument("-v", action="store_true", help='verbose')
|
||||
parser.add_argument("--version", action="store_true", help='show version')
|
||||
args = parser.parse_args()
|
||||
r2 = r2pipe.open()
|
||||
|
||||
|
||||
def get_sub_registers(register):
|
||||
register = register.lower()
|
||||
for sub_registers in [
|
||||
['rax', 'eax', 'ax', 'ah', 'al'],
|
||||
['rdx', 'edx', 'dx', 'dh', 'dl'],
|
||||
['rcx', 'ecx', 'cx', 'ch', 'cl'],
|
||||
['rbx', 'ebx', 'bx', 'bh', 'bl'],
|
||||
['rbp', 'esp', 'sp'],
|
||||
['rsp', 'ebp', 'bp'],
|
||||
['rdi', 'edi', 'di'],
|
||||
['rsi', 'esi', 'si'],
|
||||
['r8', 'r8d', 'r8w', 'r8b'],
|
||||
['r9', 'r9d', 'r9w', 'r9b'],
|
||||
['r10', 'r10d', 'r10w', 'r10b'],
|
||||
['r11', 'r11d', 'r11w', 'r11b'],
|
||||
['r12', 'r12d', 'r12w', 'r12b'],
|
||||
['r13', 'r13d', 'r13w', 'r13b'],
|
||||
['r14', 'r14d', 'r14w', 'r14b'],
|
||||
['r15', 'r15d', 'r15w', 'r15b'],
|
||||
]:
|
||||
if register in sub_registers:
|
||||
index = sub_registers.index(register)
|
||||
if index < 3:
|
||||
return sub_registers[index:] # AX has [AH,AL]
|
||||
else:
|
||||
return [sub_registers[index]] # AH hasn't AL
|
||||
return [register]
|
||||
|
||||
def taint_blacklist(instr):
|
||||
if instr["mnemonic"] in ("xor",):
|
||||
if instr["opex"]["operands"][0]["type"] == "reg" and instr["opex"]["operands"][1]["type"] == "reg":
|
||||
if instr["opex"]["operands"][0]["value"] == instr["opex"]["operands"][1]["value"]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
regs_taint = set()
|
||||
mems_taint = set()
|
||||
tainted = []
|
||||
def taint(rip, instr, access):
|
||||
global regs_taint, mems_taint, tainted
|
||||
((regs_r, regs_w), (mems_r, mems_w)) = access
|
||||
is_propagation = False
|
||||
|
||||
for reg_r in regs_r:
|
||||
if reg_r in regs_taint:
|
||||
is_propagation = True
|
||||
for mem_r in mems_r:
|
||||
if mem_r in mems_taint:
|
||||
is_propagation = True
|
||||
|
||||
if taint_blacklist(instr):
|
||||
is_propagation = False
|
||||
|
||||
if is_propagation:
|
||||
out = "[taint] {addr}: {instr}".format(addr=hex(rip), instr=instr["disasm"])
|
||||
if not out in tainted:
|
||||
tainted.append(out)
|
||||
if args.v:
|
||||
print out
|
||||
r2.cmd("ecHi yellow @{addr}".format(addr=rip))
|
||||
for reg_w in regs_w:
|
||||
if instr["mnemonic"] in ('push','pop'):
|
||||
if reg_w in ('rsp','esp','sp'):
|
||||
continue
|
||||
for reg in get_sub_registers(reg_w):
|
||||
regs_taint.add(reg)
|
||||
for mem_w in mems_w:
|
||||
mems_taint.add(mem_w)
|
||||
else:
|
||||
for reg_w in regs_w:
|
||||
for reg in get_sub_registers(reg_w):
|
||||
if reg in regs_taint:
|
||||
regs_taint.remove(reg)
|
||||
for mem_w in mems_w:
|
||||
if mem_w in mems_taint:
|
||||
mems_taint.remove(mem_w)
|
||||
|
||||
return is_propagation
|
||||
|
||||
def init_taint(args):
|
||||
global regs_taint, mems_taint
|
||||
regs_taint = set()
|
||||
mems_taint = set()
|
||||
ret = False
|
||||
for reg in args.reg:
|
||||
regs_taint.add(reg)
|
||||
ret = True
|
||||
for mem in args.mem:
|
||||
try:
|
||||
addr = int(mem, 16)
|
||||
mems_taint.add(addr)
|
||||
ret = True
|
||||
except:
|
||||
pass
|
||||
|
||||
flag = get_flag_by_name(mem)
|
||||
if not flag:
|
||||
flag = get_flag_by_name("fcnvar." + mem)
|
||||
if flag:
|
||||
for i in xrange(flag["size"]):
|
||||
mems_taint.add(flag["offset"]+i)
|
||||
ret = True
|
||||
return ret
|
||||
|
||||
|
||||
EIP = {16: "ip", 32: "eip", 64: "rip"}.get( r2.cmdj("ej")["asm.bits"] )
|
||||
class Emu:
|
||||
def __init__(self):
|
||||
self.clean()
|
||||
self.init()
|
||||
self.rip = r2.cmdj("arj")[EIP]
|
||||
self.__idx = 0
|
||||
|
||||
def __del__(self):
|
||||
self.clean()
|
||||
|
||||
def init(self):
|
||||
r2.cmd("aei")
|
||||
r2.cmd("aeip")
|
||||
r2.cmd("aeim")
|
||||
r2.cmd("aets+")
|
||||
r2.cmd(".afv*")
|
||||
r2.cmd("e io.cache=1")
|
||||
|
||||
def clean(self):
|
||||
r2.cmd("aei-;ar0")
|
||||
r2.cmd("dte-*")
|
||||
|
||||
def goto(self, addr):
|
||||
r2.cmd("aepc %d" % addr)
|
||||
self.rip = addr
|
||||
|
||||
def get_access(self):
|
||||
regs_r = set(); regs_w = set()
|
||||
mems_r = set(); mems_w = set()
|
||||
esil_trace_log = r2.cmd("dte").split('\n')
|
||||
esil_trace_log = filter(lambda l:l!='', esil_trace_log)
|
||||
self.__idx = int(esil_trace_log[-1][4:])
|
||||
for esil_event in esil_trace_log:
|
||||
if esil_event.startswith("%d." % self.__idx):
|
||||
if esil_event.find("mem.read.data") != -1:
|
||||
addr = int( esil_event.split("=")[0].split(".")[-1], 16)
|
||||
size = len( esil_event.split("=")[1] )/2
|
||||
for i in xrange(size):
|
||||
mems_r.add(addr+i)
|
||||
elif esil_event.find("mem.write.data") != -1:
|
||||
addr = int( esil_event.split("=")[0].split(".")[-1], 16)
|
||||
size = len( esil_event.split("=")[1] )/2
|
||||
for i in xrange(size):
|
||||
mems_w.add(addr+i)
|
||||
elif esil_event.find("reg.read=") != -1:
|
||||
for reg in esil_event.split("=")[1].split(','):
|
||||
regs_r.add(reg)
|
||||
elif esil_event.find("reg.write=") != -1:
|
||||
for reg in esil_event.split("=")[1].split(','):
|
||||
regs_w.add(reg)
|
||||
return ((regs_r, regs_w), (mems_r, mems_w))
|
||||
|
||||
def get_regs(self):
|
||||
return r2.cmdj("arj")
|
||||
|
||||
def step(self):
|
||||
r2.cmd("aes")
|
||||
self.rip = r2.cmdj("arj")[EIP]
|
||||
|
||||
def get_rip():
|
||||
return int(r2.cmd("s"), 16)
|
||||
|
||||
def set_rip(addr):
|
||||
r2.cmd("s {addr}".format(addr=addr))
|
||||
|
||||
def get_flag_by_addr(addr):
|
||||
return r2.cmdj("fdj @{addr}".format(addr=addr))
|
||||
|
||||
def get_flag_by_name(flag_name):
|
||||
for flag in r2.cmdj("fj"):
|
||||
if flag["name"].lower() == flag_name.lower() != -1:
|
||||
return flag
|
||||
|
||||
def next_instruction_addr(addr):
|
||||
return r2.cmdj("pdj 2@{addr}".format(addr=addr))[1]["offset"]
|
||||
|
||||
def get_n_instruction_addr(addr, num):
|
||||
return r2.cmdj("pdj {num}@{addr}".format(addr=addr, num=num))[-1]["offset"]
|
||||
|
||||
def get_instruction_size(addr):
|
||||
return r2.cmdj("aoj @{addr}".format(addr=addr))[0]["size"]
|
||||
|
||||
def disas(addr):
|
||||
return r2.cmdj("aoj @{addr}".format(addr=addr))[0]
|
||||
|
||||
def xrefs_from(addr):
|
||||
return r2.cmdj("axfj @{addr}".format(addr=addr))
|
||||
|
||||
def is_function(addr):
|
||||
return r2.cmdj("afdj @{addr}".format(addr=addr)) != {}
|
||||
|
||||
def get_function_range(addr):
|
||||
_range = set()
|
||||
for instr in r2.cmdj("pdrj @{addr}".format(addr=addr)) or {}:
|
||||
_range.add(instr["offset"])
|
||||
return _range
|
||||
|
||||
def get_function_jumps(addr):
|
||||
jumps = {}
|
||||
for xref in r2.cmdj("afxj @{addr}".format(addr=addr)):
|
||||
if xref["type"] == "code":
|
||||
if not xref["from"] in jumps:
|
||||
jumps[xref["from"]] = []
|
||||
jumps[xref["from"]].append(xref["to"]) # true case
|
||||
jumps[xref["from"]].append(xref["from"] + get_instruction_size(xref["from"])) # false case
|
||||
return jumps
|
||||
|
||||
def get_function_end_addrs(addr):
|
||||
ends = []
|
||||
for bb in r2.cmdj("afbj @{addr}".format(addr=addr)):
|
||||
if not "jump" in bb:
|
||||
ends.append( get_n_instruction_addr(bb["addr"], bb["ninstr"]) )
|
||||
return ends
|
||||
|
||||
functions = []
|
||||
def get_current_function(addr):
|
||||
global functions
|
||||
for function in functions:
|
||||
if addr in function.range:
|
||||
return function
|
||||
|
||||
function = Function(addr)
|
||||
if function.range:
|
||||
functions.append(function)
|
||||
return function
|
||||
|
||||
class Function:
|
||||
def __init__(self, addr):
|
||||
self.range = get_function_range(addr)
|
||||
self.jumps = get_function_jumps(addr)
|
||||
self.ends = get_function_end_addrs(addr)
|
||||
|
||||
|
||||
def main(args):
|
||||
origin = get_rip()
|
||||
path_constraint = None
|
||||
while True:
|
||||
emu = Emu()
|
||||
init_taint(args)
|
||||
deep = 0
|
||||
calle = 0
|
||||
branches = set()
|
||||
last_branch = None
|
||||
while deep >= 0:
|
||||
if deep > args.deep:
|
||||
break
|
||||
|
||||
#r2.cmd("ecHi blue @%d" % emu.rip)
|
||||
|
||||
function = get_current_function(emu.rip)
|
||||
if not function: # out of function
|
||||
break
|
||||
|
||||
instr = disas(emu.rip)
|
||||
if args.v:
|
||||
print "[*][%d] 0x%x: %s" % (deep, emu.rip, instr["disasm"])
|
||||
|
||||
if emu.rip in branches: # anti-loop
|
||||
break
|
||||
|
||||
if emu.rip in function.jumps:
|
||||
branches.add(emu.rip)
|
||||
if emu.rip == path_constraint:
|
||||
function.jumps[emu.rip].pop(0)
|
||||
jump = function.jumps[emu.rip][0]
|
||||
|
||||
if not function.jumps[emu.rip]:
|
||||
function.jumps[emu.rip].append(jump)
|
||||
|
||||
if len(function.jumps[emu.rip]) > 1:
|
||||
last_branch = emu.rip
|
||||
|
||||
if not emu.rip in function.ends:
|
||||
emu.step()
|
||||
#print "goto 0x%x (%d)" % (jump,jump)
|
||||
emu.goto(jump)
|
||||
else:
|
||||
#print "force return to 0x%x" % calle
|
||||
emu.goto(calle)
|
||||
continue
|
||||
|
||||
if instr["mnemonic"] == "call":
|
||||
func_addr = int( xrefs_from(emu.rip)[0]["to"] )
|
||||
if get_flag_by_addr(func_addr).get("name","").find(".imp.") != -1 or is_function(func_addr) == False:
|
||||
emu.goto( next_instruction_addr(emu.rip) )
|
||||
continue
|
||||
if instr["disasm"].find("sym.__x86.get_pc_thunk.ax") == -1:
|
||||
deep += 1
|
||||
calle = next_instruction_addr(emu.rip)
|
||||
elif instr["mnemonic"] == "ret" or emu.rip in function.ends:
|
||||
deep -= 1
|
||||
|
||||
rip = emu.rip
|
||||
emu.step()
|
||||
taint(rip, instr, emu.get_access())
|
||||
|
||||
del(emu)
|
||||
set_rip(origin)
|
||||
path_constraint = last_branch
|
||||
if not path_constraint:
|
||||
break
|
||||
if args.v:
|
||||
print "path_constraint: 0x%x" % (path_constraint or 0)
|
||||
#if raw_input():
|
||||
# break
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if args.version:
|
||||
print __version__
|
||||
exit()
|
||||
if args.reg == [] and args.mem == []:
|
||||
parser.print_help()
|
||||
exit()
|
||||
|
||||
try:
|
||||
main(args)
|
||||
except KeyboardInterrupt:
|
||||
print "[!] interrupted"
|
||||
except:
|
||||
print "[!] something went wrong"
|
||||
|
||||
if tainted:
|
||||
for t in tainted:
|
||||
print t
|
||||
else:
|
||||
print "[-] no taint"
|
||||
Loaded 100 of 112 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user