Compare commits

...
504 Commits
Author SHA1 Message Date
n0p a29ce917c1 mn103: r2r test databases in the extras tree
test/db/extras/asm/mn103 (55 disassembly vectors) and test/db/extras/mn103
(disassembly, analysis, pseudo syntax, cpu levels and ESIL emulation),
run by the CI like the microblaze and ppcdisasm databases; the radare2
test target is no longer needed.
2026-11-08 15:31:12 +01:00
n0p 8c738204dd mn103: build and test the plugin in CI
Add mn103 to LOCAL_BUILDS (installed through the r2pm package) and to
TESTS (the r2r database test/db/extras/asm/mn103 of radare2). The
Makefile honours R2PM_PLUGDIR as the r2pm package expects.
2026-11-08 15:31:12 +01:00
n0p 031b077f2c mn103: tests, sweep tool and docs
Unit checks of the decoder, analysis, ESIL and the length rule of every
table row; r2 integration tests (disassembly, pseudo syntax, cpu levels,
aoj metadata, function analysis, emulation of multiply/divide, flags,
call/ret and movm frames, memory bit operations, loops); the mn103-dis
linear sweep tool; README, doc/mn103.md and CHANGELOG.
2026-11-08 15:31:12 +01:00
n0p 2a44edead6 mn103: MN10300/AM33 architecture plugin from the binutils opcode table
The GNU binutils MN10300 opcode table (opcodes/m10300-opc.c, 1129 rows)
as generated C arrays, a C port of the length rule, first-match lookup
and operand extraction of opcodes/m10300-dis.c, and the RArchPlugin:
analysis types for every row, control flow (branches, setlb/lXX loops,
jumps and calls, returns), loads/stores with size and addressing mode,
stack deltas for add/sub sp, movm and the call/ret register-list frames,
a register profile with the PSW flags and the AM33/FPU registers, and
ESIL for the integer core. asm.cpu selects the machine level
(mn10300 < am30 < am33 < am33-2); the udf placeholder rows are looked up
after the named rows of the same encoding (mulq, mulqu, swap, ...).
A pseudo-syntax parse plugin covers the common forms.
2026-11-08 15:31:12 +01:00
pancake ee031a7021 vc4: upstream cgen tables, assembler, ESIL emulation and analysis
- Update the cgen generated sources to puppeh/binutils-vc4 (branch vc4),
  which decodes the vector unit and fixes sized ld/st, scaled immediates
  and the signed 12 bit offsets
- Decode 80 bit vector insns (16 byte buffer, 10 byte max op size)
- Decode what the tables miss or get wrong: tbb/tbh, 48 bit b/bl pc+o32,
  the missing 48 bit alu ops, and the shift of 32 bit addscale immediates
- Treat the 16 bit sp offset of lea/add sp as signed, print float6
  immediates as values so they assemble back
- Add an assembler on top of the cgen one, pc relative operands, relaxed
  wider forms, 48 bit fallbacks, and a check that rejects encodings cgen
  silently truncates
- Replace the analysis with a text driven one that emits ESIL for all
  scalar insns: flags in sr, conditions, compare and branch, ldm/stm,
  table branches, floats and conversions; vector insns are typed only
- Rewrite the pseudo plugin for the upstream syntax
- Drop libvc4 from the builds, the plugin never used it
2026-11-04 20:19:45 +01:00
pancake 0a0327aa45 vc4: pseudo compare-and-branch forms and meson include path fix
- Translate addcmpb<cond> and 3 operand b<cond> into compare and goto
- Render the never-taken f condition as false and fix 'x -N' spacing
- Resolve ../../include with realpath since p/vc4 is usually a symlink
- Document the separate arch.vc4 and asm.vc4 XPS plugins
2026-11-04 18:41:02 +01:00
pancake 9870775224 Add r2plugin xps interface and pseudo for vc4 2026-11-04 18:31:28 +01:00
pancake d5e7a28186 Ignore vc4 plugin build artifacts and editor caches 2026-11-04 11:33:25 +01:00
pancake c9571534b9 Add standalone Makefile to build the vc4 asm/anal plugin
Allows building arch_vc4 from libr/asm/arch/vc4 directly instead of
going through the whole r2 build. Mirrors libr/asm/p/vc4.mk but
resolves the sources locally, links libr/libvc4 objects and the
libr/asm/p/arch_vc4.c glue, and adds an install target.
2026-11-04 11:33:09 +01:00
pancake 5fff0016a3 Support bits:// packed and be16 unpacked roms for r2tama 2026-11-03 18:30:00 +01:00
pancake f2199032a7 Add Tamagotchi P1/P2 ESIL emulator 2026-11-03 18:10:09 +01:00
n0p 5d28dc6de4 md32: tests and docs for the scq16 table update and the public test vectors
test/test_scq16.py (267 checks) and test/test_md32.c cover the new forms, the open marker, the broadcast ports, the confidence levels and ctz(0). test/scq16_vectors.json carries 195 public bytes-only vectors with the expected result in the big-endian regime of the harness and in the little-endian regime of the core data memory; test/test_scq16_vectors.py runs both and the Makefile adds it to make test. doc/scq16.md, README and CHANGELOG describe the hypothesis file, the confidence levels and the open question on ctz(0).
2026-11-03 10:17:01 +01:00
n0p 645f4154ff md32: scq16 table update (229 forms), the open-reading marker, the broadcast ports and the confidence levels
jr rn (6f ec) reads a 5-bit register field (r0-r31); btst rd, rd, #pos (67 f8-fb) has a 5-bit position; ctz is its own form without the hypothetical flag and sqr? belongs to the op41 placeholder; and rd, rs, #0x1|#0x3|#0xf (2 bytes), add rd, rs, #-1 (2 bytes) and the 4-byte sb are high, the 4-byte btst rd, rs, #pos is medium (settled by execution results).

The exporter marks an open reading (a family placeholder or a provisional name) with SCQ16_FL_OPEN and gives an open alternative without a template the uniform ESIL marker REF,ALT,open; export --hyp applies the declared plugin hypotheses of isa/scq16_hyp.json, which is empty: the packing ESIL of op41.fld rd, rs, rt, #pos is carried by the ISA source, still flagged hypothetical.

The scalar ports v0-v31 are the broadcast ports of the vector register file: a write by vbcast / vbcast.i reaches the 64 lanes of vr_k; the custom op open has no effect; aoj reports open, reading, hypothetical and confidence per unit. ctz of a zero operand gives -1 under the table ESIL; whether the hardware returns 32 is an open question. asm: the pseudo rule of op41.fld.
2026-11-03 10:17:01 +01:00
n0p 899e3344ff md32: document the three encodings the plugin serves and its scope
The README introduction states what MS15E30, uSIP and SCQ16 are and how they relate: two MD32 encodings and one distinct byte-granular encoding that shares the MD32 scalar programming model, which is why it is a cpu mode of this plugin; the remaining DSP cores of the same modem use an unrelated SIMD ISA and are out of scope. doc/scq16.md carries the same note.
2026-11-03 08:31:29 +01:00
n0p 6493987c72 md32: tests and docs for the scq16 table update and the vector unit model
test/test_scq16.py: bytes-only checks of ctz (established) next to the
provisional sqr?, sra? rd, rd, #pos, vrd? rd, vb1[x], op41.fld with three
registers, the provisional and? masks, lw.post of 2 bytes with a 4-bit
destination, the signed post-increment of the 6e page, vector ops with
non-zero fields, a vector head and B slots with the new forms; analysis
(ctz named, sqr? / sra? / vrd? provisional, op41.fld with rt, the lw.post
destination r11); the ESIL of ctz / sqr? / sra? / vrd?, the .post
templates writing rd last (rd == rb), the signed post-increments and the
vector unit model (vset.a / vmem.set, v.mem.ld with a count and with the
whole register, v.mem.ld + v.mem.st through the VU, v.move.mv back and
forth, F2 >= 4 without effect, a bundle with a vector load, unmodelled
vector ops stepped over).  test/test_md32.c: ctz, lw.post r11, sra?,
v.mem.ld with its fields.  doc/scq16.md: the new forms, the .post
convention, the VU model and its limits, the register profile with vr*,
the calling convention (r16-r31 callee-saved, r0-r15 caller-saved, lr
saved by the functions that call); README "SCQ16 mode": the VU model,
the provisional sqr? / sra?, the calling convention; CHANGELOG entry.
2026-11-03 08:31:29 +01:00
n0p ba096f3546 md32: scq16 table update (402 bit alternatives), the .post convention and the vector unit model
isa/scq16_isa.json is re-exported by the `export` command of
tools/gen_scq16_tables.py: 228 forms / 402 bit alternatives.  ctz rd, rs
(41 f3 0x22) is an established operation with the ESIL rd = 31 - clz(rs
& -rs); new provisional readings: sqr? rd, rs (41 f3 0x23, rd = rs * rs),
sra? rd, rd, #pos (67 fc-fd), vrd? rd, vb1[x] (1a xy, a 32-bit read of
the VU scalar bank with rd = w[3:0] + 1), and? #0xf000? (67 98-9b and the
2-byte 00/01 with k = 6) and and? #0xc000? (67 b4-b7); op41.fld rd, rs,
rt, #pos reads its third field as a register; lw.post rd, [rb] += 4 (21)
has a 4-bit destination (r1-r16); the 3-bit post-increment of the 6e
.post family (sh.post, lw.post, lhu.post?, lbu.post) is signed (x = 4..7
is -4..-1 units); sra rd, rd, #imm (09) is established; the load
templates with a post-increment write rd last, so with rd == rb the
loaded value wins (a declared convention: the public MD32 documents rd
written first).

scq16_vu.inc.c (new, included by scq16_arch.inc.c): the vector unit
model of the ESIL.  The register profile gains the vector register file
vr0-vr31 (128 bytes each, exposed as the four 256-bit quarters
vrK_0..vrK_3; lane 16q is the low 16 bits of quarter q); vp0-vp7 (written
by vmem.set and the hypothetical vcfg4c? #0xc) and va0-va7 (written by
vset.a) are the existing scalar ports.  The custom ESIL op vop models the
three established vector operations and nothing else: v.mem.ld copies n
halves from DM[p] into vr[F1 >> 2] and v.mem.st copies n halves from vr0
to DM[p], with p = vp[2 * F2 + F3[4]] when F2 < 4 and n = va[A] when
1..64 (otherwise the whole register), post-incrementing the pointer by
the bytes accessed; v.move.mv copies vr[F3] into vr[F1].  A memory op
with F2 >= 4, the pair mode B = 2 of v.move.mv and every other op9 pop
their operands and have no effect.  The data memory is read and written
through the ESIL memory callbacks; the vector registers are kept in the
register arena.

asm_md32.c: pseudo rule of sqr (rd = (rs * rs)).  Makefile: the new
include file among the dependencies of the arch plugin.
2026-11-03 08:31:29 +01:00
n0p bfab794507 md32: tests and docs for the scq16 table update
test/test_scq16.py: bytes-only checks of the page 42 (cmov.ge, cmov.eq
with a register, the provisional cmov.*?, the remaining sel? codes), the
67 page (mv, bset/btst rd, rd, #pos, and #0x3fff), lbu.post with 5-bit
registers and the 23 page with a signed post-increment, the 6-byte and
#imm16, ctz?/clb?, vcfg4c? #0xc, ld46?, the established vector names
(v.move.mv, v.mem.ld, v.mem.st) next to the provisional ones, addsp 14 8x,
halt, sys41, lbu? off(sp), the 4-byte beq of 5c 40-6f, j.d1 decided by its
target (also in a B slot), the ESIL of the new forms, negative frame
offsets, halt/sys41 without effect and ret.d2 / jr.d2 across two aes
steps (a packet in the first slot).  test/test_md32.c: cmov.ge, mv 67 c8,
j.d1 by target, lbu.post of the 23 page, v.mem.ld.  doc/scq16.md: the
j.d1 length by target, the vector names (established / provisional), the
page 42, 46, 4c, 41 f3, 22/23, 67, 6e and 74 families, the ESIL
conventions (.d2 across two aes steps, 32-bit addresses, no-effect units,
the memory order inside a packet), the hypothetical alternatives of the
table, the limits (rd == rb post-increment, the vector unit), the
data-space bases; README "SCQ16 mode" updates; CHANGELOG entry;
tools/scq16_flags.r2 (DM, I/O window and DM2 bases as flags).
2026-11-02 16:26:48 +01:00
n0p 619f60a7df md32: scq16 table update (228 forms), decoder rules and generator features
isa/scq16_isa.json is re-exported by the `export` command of
tools/gen_scq16_tables.py: 228 forms / 400 bit alternatives.  The ESIL
templates, the delayed transfers (SETJT/SETD) and the hypothetical flag
come from the form-description module itself (its HYP table), so the
exporter applies no overlay of its own.  The vector names carry the ? of
a provisional name in the table string and none when the operation is
established (v.move.mv, v.mem.ld, v.mem.st: vector.firm_op9).  New or
renamed forms: cmov.ge rd, rs, #imm, ra; cmov.eq rd, rs, rx, ra (register
form); the provisional cmov.leu? / cmov.ltu? / cmov.lt? / cmov.le?; mv rd,
rs (67 c8); bset / btst rd, rd, #pos (3 bytes); lbu.post rd, [rb] += inc
with 5-bit registers (6e q2) and the 23 page as lbu.post rd, [rb] += simm3
(-4..-1); and rd, rs, #0x3fff (67 a4-a7); the 6-byte and rd, rs, #imm16
(74 sub 1); the provisional ctz? / clb? (41 f3); vcfg4c? #0xc with the
hypothetical p_k <- rs; ld46? as a hypothetical byte load with a
post-increment; lbu? rd, off(sp) (ex lb?); addsp sp, #imm (14 8x-fx); fxts
without the ?; halt and sys41 with the empty ESIL; the length leaves make
5c 40-6f a 4-byte beq rA, rB.

scq16_decode.c: a first byte 56 with the top two bits of the second byte
clear is the 4-byte j.d1 when its 22-bit target (from the packet start in
a B slot) is a plausible code address, else a formless 2-byte unit
(without a function table the plugin cannot decide by membership).  Every
ESIL memory access cuts its address to 32 bits: the ESIL machine computes
in 64 bits and aes does not mask addresses, so a negative frame offset
over sp wrapped above 4 GB.  The ? of a vector name now comes with the
table string (scq16_vname_firm).  scq16_arch.inc.c: a unit whose ESIL is
the empty string (nop, halt, ieon/ieoff, loopend, vwait?, sys41) no
longer blocks the ESIL of its packet; the override hook counts as the
unit ESIL; opex named / provisional of a vector op follow the table name.

asm_md32.c: pseudo rules of cmov.ge / cmov.leu / cmov.le (the ? of a
provisional name is stripped before the lookup), sys41, ctz / clb.
2026-11-02 16:26:48 +01:00
n0p f4f11b90c3 md32: tests and docs for the uSIP table update 2026-11-02 06:43:08 +01:00
n0p f58de93399 md32: uSIP table update (760 forms), decoder rules and generator features 2026-11-02 06:43:08 +01:00
n0p 58a5ac18e6 md32: English output text for the scq16 loop, jump and trap forms 2026-11-01 20:21:45 +01:00
n0p 9b0adabca8 md32: tests and docs for the scq16 mode
test/test_scq16.py exercises cpu=scq16 inside r2 with loose bytes only
(disassembly of units, packets, vector operations and bundles; analysis;
ESIL; the pseudo parser) and runs from make test; test/test_md32.c gets
three decode checks.  README section "SCQ16 mode", doc/scq16.md and the
CHANGELOG entry.
2026-11-01 20:21:45 +01:00
n0p 219b1f7c07 md32: scq16 cpu mode (table, decoder, arch and asm)
Add cpu=scq16, the SCQ16 variant of the MD32 family with a byte-granular
packet encoding, as a third cpu of the plugin.

isa/scq16_isa.json is the ISA table (218 forms, 389 bit alternatives, the
length-rule leaves of stand-alone units and packet heads, the vector op9
classes and provisional names, the register names) and
tools/gen_scq16_tables.py generates scq16_opcodes.h from it (the VU scalar
ports as ESIL registers, vector operations as the custom op vop, delayed
transfers as SETJT/SETD, the no-effect system forms and the hypothetical
readings flagged).

scq16_decode.c implements the length and packet rule by first-byte leaves
(stand-alone units, packet heads read shifted by one bit with the borrowed
bit of the B slot, masked orphans, 4-byte vector operations, vector heads,
8-byte bundles), the form match over the transformed unit, the operand
text and the ESIL expansion with the parallel-packet register remap and
the VU scalar-port registers.

scq16_arch.inc.c carries the analysis of the SCQ16 decode (types,
jump/fail with the delay slots counted in instructions, do as a loop
reference, loads/stores, stack ops, opex with the unit/packet/bundle
structure), the ESIL (the scalar forms; a packet as A then B with the
registers B reads and A writes copied to temporaries first; delayed
transfers through SETJT/SETD; the VU ports as registers; vector operations
as the custom op vop, a no-op) and the register profile (sp/lr as
csr14/csr15, a0, the loop registers, the VU ports).  arch_md32.c
dispatches decode, info and regs on cpu=scq16 and registers vop through
esilcb; asm_md32.c gets the SCQ16 pseudo-syntax (packets as
parallel { a; b; }, memory, stack, bit-field and transfer rules).
2026-11-01 20:21:45 +01:00
n0p a1b8861f9d md32: tests and docs for the uSIP table update
Plugin vectors for the loop count, the F' = 0 / h = 1 / m = 1 loops
(validated and unverified), the 4- and 3-unit bz.s (validated and unknown),
beq9sp, the bgt rA, #-1 cell, the W6 h = 1 cells and the loop guard, op2z?,
the h = 1 shifts, the 16-bit lea, the splits (R-slot4n, R-op4imm in 2 and
more units, S0-slot, S3), op72?, saturate?, sat40 H H T T, R-waw with the
P2W prefix, R-b111pre, R-b111ctl, R-bsnext, the omitted weak cell of
R-brHHTT, sub r14, st.w [sp], st.abs hi F' = 0, addq / cell E by value,
mtcsr of the accumulator CSRs, R-1eX0F0, R-movi6d; the lea, loop#, mtcsr,
movi #-32768 / #-32767, ld.h / ld.hu of R-1eX0 / R-ldF0 / R-hhttF0 / R-F0d,
op2z? and two R-waw vectors updated to the new readings; pseudo vectors for
the new rules; README, doc/usip.md (the loop cells, the post-layout splits
and the fusion, the explicit candidates, score rules and layout
constraints, the cells added with the table, the unverified fallback and
the order of the packet-level passes) and CHANGELOG.
2026-11-01 18:45:09 +01:00
n0p 85f40b5d6c md32: uSIP table update (726 forms), decoder rules and generator features
Regenerate isa/usip_isa.json and usip_opcodes.h (52 forms added, 13 retired,
14 modified): the loop #N count is the collected head field (bits 13:5, no
+1), loop #N with the F' = 0 tail exactly at +2, with h = 1 (N >= 128) and
with m = 1 (N >= 256, printed loop #N?), bz.s in 4- and 3-unit packets, the
split entries of the slot family stslot / stslot? / ldslot? (F-slot0,
S0-slot, the S3 cells ldslot/stslot #48-63), the fusion entry
op72? rA, #k, asr#b, op2z? rA, lsl/asr r8-r15, #B, the W6 cells
ld.h/st.h rB, [r8+rrr] and [rA]+ with h = 1, sub r14, #f12/2 with any F/F'
(spfix_sub_sp retired), st.w [sp], #imm14, st.abs with the hi F' = 0,
add rB, rB, #imm27 / st.h? [rB], #sat selected by the immediate value (also
the cell-E triples), add? rB, r15, #rot12 and ld.h? / ld.hu? rB, [r15+off]
with the F' = 0 tail, saturate? rd, rs1, movi #simm6 in the delay slot of a
validated branch, mtcsr #0x30-0x3e, ld.h / ld.hu / lea / movi #-32768 /
#-32767 / ld.hu [rA+rB] without the ?; the constraints of beq_imm8_d (the
op 9 beq.d with base sp and the adjacent tail is not a branch) and of the
seven op a *_s0f1 / *_imm8_F0 entries (the bgt rA, #-1 head class takes
only the adjacent S = 1 tail); the ABI passes eight arguments in r0-r7.

The generator emits the flags FUSE, SPLIT / SPLITBARE (with a USIP_FORM_*
index for every split and fusion entry), the constraint op instr_index,
any with up to four alternatives that may be a context condition or an
instruction position and six new context conditions; the loopn operand
type is the collected field.

The decoder keeps the score in twentieths (al1 = 0.3), adds the explicit
candidates loopcand / R-brHHTT / R-b111pre / R-b111ctl with the b111_layout
context extended to them, the bz.s rules of 4- and 3-unit packets (the rest
re-parsed as the delay slot, the 3-unit one with the target beyond the
packet and no write of rA), the S3 renames and the split pass of the slot
family with the split-tail reading and the nowaw guardian, the fusion after
the renames, R-movi6d, the R-w6h1 loop guard evaluated with the packet being
parsed, the R-loopA adjacency (.word at any distance but +2), rf0dmidwaw,
the score rules R-waw / al1 / R-bsnext / P2W-P2H prefix / sat40 H H T T /
rf0dpen and the instruction position of the renames. The loop entries with
the F' = 0 tail at +2 and the h = 1 heads with the S = 1 tail (and the
adjacent F = 0 tail) are accepted unverified; the m = 1 (loop #N?) and the
other h = 1 entries are not.

The arch plugin reports the stores of an immediate ([rB] / [sp], #imm) with
the value in val and [sp] as a stack access; the new mnemonics keep their
kinds (op2z? / op72? / saturate? are unknown operations). Pseudo syntax for
the stores of an immediate (also to [sp]), the absolute st.abs / ld.abs and
the ? of a count (loop#? #256?).
2026-11-01 18:45:09 +01:00
n0p a8d4a6a520 md32: tests and docs for the uSIP table update
Plugin vectors for the F = S = 0 and R-br0 cells (validated by the session,
rejected with fall-through, unknown backward, unverified forward), ret.s.d,
movi #-1 with F = 0, the op 2 shifts, the open b.s rejected and unverified,
bz.s P5, the m = 1 slots, loop.b1? and the ?ss=N loops, movi? #-32767, the
asr16 clamp, the bit-field pair and the BF_SEL cells, ld.bu/st.b with the
byte displacement, ld.b/st.h with F != S at +2 and the undo at +1, the
ld.h?/ld.hu? of R-hhttF0 / R-F0d, the sp adjustment pair, the ld.w?/st.w?
word classes, .stimm16? and mtcsr? with a named tail; the loop, open b.s,
mtcsr, movhi and save vectors updated; pseudo vectors; README, doc/usip.md
and CHANGELOG (the target validation filter, the address views, the F = 0
branch cells, the split and context groups, the new tie-breaks and what the
plugin can see of the guards).
2026-11-01 18:45:09 +01:00
n0p e108f90f79 md32: uSIP table update (687 forms), decoder rules and generator features
Regenerate isa/usip_isa.json and usip_opcodes.h (56 forms added, 3 retired,
71 modified): the b<cond>.d cells with head F = 0 (bne.d, ble.d, bgeu.d,
bge.d, bne.u8.d, beq.u8.d, bleu.d, read only in the (B class, tail distance)
cells of usip_br0_cells; the five weak cells of usip_br0_cells_weak are never
taken), bgt.d of the F = S = 0 cell back in the table, ret.s.d, loop.b1? and
the ?ss=N loops, bz.s with bit 3 = 0, the ld/st type 111 ld.bu / st.b with
the byte displacement (st.b? retired), ld.b / st.h with F != S of op 1
exactly at +2, ld.h? / ld.hu? with the F' = 0 tail as the second head of
H H T T and by the deferred tail of a head with base sp, the bit-field pair
in H H T T and the BF_SEL cells renamed from .bf?, the 16-bit op 2 shifts
lsl/lsl?/asr/asr? (addi4 retired), ldslot/stslot with m = 1, .stimm16?,
ld.w?/st.w? for the f12 = 1 / 3 mod 4 word classes, add r14 / sub r14,
movi? #-32767, movi rA, #-1 with F = 0, mtcsr? of the accumulator CSRs with
a named 16-bit tail; the known target as a validation filter on the
F = S = 0 cells, bne.d #-1, the loops with the F' = 1 tail, the open b.s and
the near b, with fall-through on failure (USIP_F_GUARDFT); the operand
conventions of six families revised. Thirty-one entries are post-layout
renames.

The generator emits the operand type offb, the flags GUARDFT / B111 / F0CTX
(flags is ut32), the constraint ops br0_cells / br0_cells_live, bf_valid,
the guards tail_named16 and target_packet_start_any_or_function_start, the
any sub-operations packet_len, guard, range and br0_cells, the large value
sets (usip_value_sets), the new context conditions and the tables
usip_br0_cells, usip_br0_cells_weak and usip_c48sym_table; form names are
sanitised into C identifiers.

The decoder implements the fall-through guards, the fifth guard kind with
the optional packet_start_any callback, the R-br0 cells by B class and tail
distance, the b111 group in the 2-unit packet and in H H T T (which now
takes tt = 11 tails), the context conditions b111_layout, hhtt_second_head,
f0d_triple, bfpair, bf_dst_not_written and rest_named_no_q, the f0ctx pass
on the .word pairs and the re-read of the R-F0d middle unit, R-op1fs, the
bz_s_P5 context rule, the m = 1 R7 slots, P2H, R-lr16, R-align48 and
R-c48sym in the score, the b.s guard admitting a function start and the
loop F' = 0 rule by field; immediates glued to a letter or '=' print in
decimal. The forms whose guard is a validation filter keep their reading
unverified when the target is unknown (conditional branches only forward);
a definite "not a packet start" rejects them.

The arch plugin initialises UsipGuardCtx by field, separates "not a packet
start" from "unknown" for backward targets with the lowest packet start
decoded in the session, reports offb as a disp operand in opex and sets the
stack deltas of addsp and the add r14, r14, #imm / sub r14, #imm pairs.
Pseudo syntax for the 2-operand lsl / asr.
2026-11-01 18:45:09 +01:00
n0p 5b9a32f8c4 md32: tests and docs for the uSIP table update
Plugin vectors for the 14-bit word displacement, nop.ctl, the bit-field
family, mtacc?, movi? #-32768, sgt #-1, the register bset/bext, the S0F1
branches (unverified, validated by the session, not validated), the r15-based
loads, .ldF0?, the F' = 0 ld.h?, the 48-bit value table, .3eX0?, the
lsl/sext16/zext16 renames, cop with addi, .hi, movhi with the tt = 10 tail
and .op4t0; the op8 slot split vector updated; pseudo vectors; README,
doc/usip.md and CHANGELOG (the post-layout renames, the K-tie cascade and
what the plugin can see of it, the extended target-guard fallback).
2026-11-01 18:45:09 +01:00
n0p 71ab77c46b md32: uSIP table update (634 forms), decoder rules and generator features
Regenerate isa/usip_isa.json and usip_opcodes.h (52 forms added, 12
retired, 103 modified): the 14-bit word displacement of the two-unit
ld.w/st.w, nop.ctl, the bit-field family fxtu/fxts/fup, movi? #-32768, the
register bset/bext, mtacc?, sgt #-1 with F = S = 1, addi #32 next to cop,
the 16-bit lsl/sext16/zext16 variants, the r15-based loads, .ldF0? and the
F' = 0 ld.h?/ld.hu?, .3eX0?, the b<cond>.d cells with the [0][1][tt] tail at
+2, movhi with the tt = 10 tail, the 48-bit constants admitted by value, the
double-class split; the .hi/.hilo pair entries and every not_hi1010
constraint are gone. Twenty entries are post-layout renames.

The generator emits the rename_from lists, the constraint ops tail_adjacent,
ieee_short and the 48-bit value table membership, the tail_adjacent
sub-operation of any, the context conditions cop_rA_in_packet and
not_c48_lo_follows, USIP_MAXVALS 12 and the tables usip_never_tail,
usip_never_head_with_tail and usip_c48_table; the rename entries are exempt
from the 16-bit position-class checks.

The decoder implements W14, the never-tail and never-head-with-tail units
from the tables, H1 (the forced hi(1010) decode is gone; .hi/.lo only after
a 48-bit-family head in the packet), the 48-bit value table in the partial
admission, P2W (no alignment penalty for the 2 mod 4 word offsets in the
H H T T layout), callin through a new guard callback, the post-layout
renames and the K-tie cascade: dedup and nowaw on the tied readings of the
packet, du2 over the neighbouring packets the caller supplies (packet_at /
branch_target callbacks, first-pass readings with USIP_GUARD_NO_CASCADE).
UsipPacket reports how a tie was decided; a failed guard of the op C
compare-and-branch cell prints the pair as .dsp. The unverified fallback
accepts the S0F1 cells whose unverified readings are right in nearly every
case and loop rX with the F' = 0 tail when the head has F = 1 and the S = 1
tail sits at +2.

The arch plugin answers the cascade callbacks with the packets decoded
earlier in the session, the first-pass readings of the packets inside the
bytes at hand and the branch targets seen so far, reports the tie-break in
opex, sets ireg for the r15-based loads and types fxtu/fxts as cast and fup
as or. Pseudo syntax for fxtu/fxts/fup, mtacc, the 2-operand addi,
sext16/zext16 and asr16; nop.ctl reads nop.
2026-11-01 18:45:09 +01:00
n0p b6da363492 md32: tests and docs for the uSIP table update
Plugin vectors for loop# (validated at +1 and +2, unverified), b<cond>.l
(validated, unverified, not taken, 64-bit), the signed 64-bit pairs, the
negative offsets, seq/sle/sgt, movhi, the 16-bit first-slot st.h, the
deferred st.h and its undo by a validated b.s, H H T T, the op8 split, the
0e10 trio, cop with F = S = 0, xor, movi rA!, bset rd!, osl and the
cmulr16/cmuli16 names; the jr, ld.d, movhi and bank-bit vectors updated;
pseudo vectors; README, doc/usip.md and CHANGELOG.
2026-11-01 18:45:09 +01:00
n0p 4932f31af9 md32: cmulr16/cmuli16 names follow the little-endian data memory
The names of 0xDA00 (cmulr16, a*c - b*d) and 0xDC00 (cmuli16, a*d + b*c)
follow the little-endian layout of the data memory: the high half of a 32-bit
complex word is at +2 and holds the real part. The earlier assignment assumed
a big-endian data memory.
2026-11-01 18:45:09 +01:00
n0p cdd0753019 md32: new uSIP mnemonics and conditions in the arch and asm plugins
Conditions bequ/bneu of the 48-bit forms, types for sle (cmp) and osl (shl),
val = N for loop #N, the signed offsets as disp operands in opex; pseudo
syntax for loop#, sle, bequ/bneu, the 2-operand xor, mfacc, the bset family
and osl; the ? marker is stripped repeatedly and ld.d/ld.w are not
sign-extended.
2026-11-01 18:45:09 +01:00
n0p 8b98f544d7 md32: uSIP table update (594 forms) and prior-free packet layout
The uSIP table grows to 594 forms (137 added, 18 retired, 76 modified): the
48/64-bit b<cond>.l prefix forms with the complete condition table, loop #N,
the op 6 set-on-compare family, movhi by its 20-bit value, the 48-bit
constants by one formula, the signed ld.d/st.d, the closed negative
half-word and word offsets, the deferred st.h tail, the position cells and
the slot split.

The generator gains the operand types offh/offw/loopn and the redefined
movhi, the flags ADJDEF/PREFIX/RENAME/HHTT, 8 ranges per field, 64-bit
entries, the constraints gt/odd/packet_len_ge/head_index/head_pos_ge/ctx and
the b.s guard, any with up to three alternatives, the bcc48 condition table
and save w=4.

The decoder matches the prefix forms before the layout, ranks the readings
with the prior-free total order (s0, I, Fv, -A, K) instead of the enumeration
order and the group count, and implements the grammar rules (5e0d never a
tail, the deferred st.h tail with its undo and the validated-b.s guard, the
.d SP-negative rejection, the 3-unit and H H T T candidates with the forced
decode of hi(1010) heads, the 0e10 trio, the loop #N adjacency, the op8
split), the new penalties, the deferred constraints with fall-through, the
late guard evaluation, three tails for the 64-bit forms and the unverified
fallback for the prefix forms and loop #N.
2026-11-01 18:45:09 +01:00
n0p 4ad1a62408 md32: docs for the uSIP table update
README uSIP mode: the F' = 0 control tails, the target guards and what the
plugin can check, the new mnemonics and analysis types.  doc/usip.md: the
packet-model rules R0/R7, the table additions (movhi, base/offset, scale, the
new constraints, kinds io/jr), confidence census, ABI without a classic CSR
bank, and a section on the target-guard knowledge and the fallbacks.
CHANGELOG entry.
2026-11-01 18:45:09 +01:00
n0p 39458c3b5b md32: tests for the uSIP table update
test_plugin.py: vectors for ior/iow, nop32, the 32-bit ret of the sys shape,
jr?, addsp, ld.d?, the first-slot ldslot/lea? forms, movhi? and the guarded
3-unit control packets (loop with the tail at +2 and the end at the next
packet, beqz.d validated by a forward packet start and read as data when the
target is not one, call with the F' = 0 tail read unverified); the mov32 and
ld.b vectors show the bank bit on the register it applies to (r15!).
test_parse.c: the new pseudo rules.
2026-11-01 18:45:09 +01:00
n0p b07fcf44b1 md32: new uSIP mnemonics in the arch and asm plugins
arch_md32.c: operation types for the forms of the updated table: io for
ior/iow (ireg = the port register), rjmp for jr? rB (register jump with the
delay slot of a return), ret for rti, trap for trap?, nop for nop32, add for
addsp, lea for lea?, cmp for sne/scmp?, cast for extu, refptr 8 for the
ld.d?/st.d? pairs; the mnemonic test ignores the trailing ? of the medium
forms; extended CSR names in opex.

asm_md32.c: pseudo syntax for ior/iow, mfcsr/mtcsr, addsp (sp += / sp -=),
ldslot/stslot, jr, nop32, sne, scmp, movhi, extu, cop, rti, ieon/ieoff, idle,
isync, lpexit, trap and the 64-bit loads/stores; the trailing ? marker of
lea?/jr?/call? is ignored.
2026-11-01 18:45:09 +01:00
n0p 58536ef4e9 md32: uSIP table update (475 forms), generator features and decoder rules
isa/usip_isa.json goes from 386 to 475 forms (110 added, 24 retired, 140
modified): port I/O ior/iow instead of mfcr/mtcr, mtcsr and mfcsr with F' = 0,
the sys shape split by its tail field (cop, rti, lpexit?, isync?, ieon, ieoff,
trap?, sys?, ret, ret?, jr?, call rB), nop32, cmov r15, add rB, rA, #rot12 for
the whole op 0 cell, sne, scmp?, movhi?, extu, movi #-1, addsp, lea?, the
stack-slot closers (ldslot/stslot, .slot?, lsl #1/#2, movi #simm6, .bit4?,
.ext8?), ld.d?/st.d? (64-bit pairs), st.b?, ld.hu for type 110, unsigned
12-bit ld/st offsets, ld.bu in the class-E cells, per-operand bank bits
(rB! by x, rA! by m, rs1! by ss), save w=2 = four words; the 48-bit call with
the far tail is retired (those packets are call/b with the F' = 0 tail at +2).

tools/gen_usip_tables.py: the movhi operand type, base as a constant added to
register/immediate fields, scale on immediates, the ge and any constraints,
membership masks for the large CSR sets, the target guards as constraint
records, flag USIP_F_ADJ2, kinds io/jr, the sys name table, extended CSR names
and kind names.  The header stays byte-identical on regeneration.

usip_decode.c: packet guards, adjacency rule and tie-breaks.  F' = 0 control
tails exactly at +2 (otherwise data), target guards evaluated after the mask
match (32-bit forms: a failure is .word, no fall-through; the 16-bit call.s
falls through), packet_len constraints with the real packet length so that
the stand-alone closers never count as named 16-bit ops, closers matched with
bit 15, rules R0 (the final closer may be its own group) and R7 (first-slot
ldslot/stslot/lea? when the rest of the packet is named), the 1dX6 + named
tail and validated-guard tie-breaks; the enumeration order is unchanged.

The decoder asks the caller about branch targets through UsipGuardCtx.  The
arch plugin answers packet starts from the stream: the packets decoded so far
in the session and a scan of the bytes radare2 hands it (64 bytes of
lookahead).  Function starts are not available to an arch plugin, so the
decoder applies a documented fallback: the call / b / compare-and-branch with
immediate forms whose F' = 0 tail sits at +2 and beqz.d are read unverified
(trailing ?, confidence medium, opex.target_guard = unverified); loop, far b,
bnez.d, the register compare-and-branch and the open-packet call.s are
treated as a failed guard.
2026-11-01 18:45:09 +01:00
n0p 3dfb0180d0 md32: changelog note for the emulator test expectation in usip mode 2026-11-01 18:45:09 +01:00
n0p 73831a1ee2 md32: emulator test expects the delayed-return stop in usip mode
With the packet decoder, 5ef9 is ret.d and the rest of the packet is its
delay slot, so md32-run stops with unsupported_delay_slot_execution and
zero completed steps, exactly as for the MS15E30 delayed branch.  README:
make test passes against radare2 6.2.5 on Linux as well.
2026-11-01 18:45:09 +01:00
n0p 68e9f6dfe3 md32: six group-5 16-bit forms missing from the MS15E30 table
rem16, ctz16 and the four complex half-word products (cmulcr16, cmuli16,
cmulr16, cmulci16) occupy 0xCA80-0xCABF, 0xCB00-0xCBFF and 0xD800-0xDFFF,
which the public table leaves undecoded.  Names and operand order follow
the neighbouring group-5 forms; the semantics are inferred from usage
(rem16 as a non-negative modulo, the cmul* variants as the cross-sum and
straight-difference terms) and are marked as such in the source.
2026-10-30 19:53:17 +01:00
n0p 2c54fda563 md32: document the uSIP mode
README: the uSIP mode section (packet model, what one pd line is,
mnemonics and operands, analysis, limitations) replaces the partial
support notes; build note for radare2 6.2.2.  CHANGELOG entry.
doc/usip.md: table format, constraint and context-rule semantics,
confidence levels, ABI, known limitations of the table-driven reading.
2026-10-30 16:28:21 +01:00
n0p a0ccecf534 md32: uSIP packet vectors in the plugin test
Exercise the usip mode on real packets: conditional branch with its tail,
b.s with a 48-bit delay-slot op, call with the S S O O layout (.unit
tails, delay = 3), interleaved 48-bit call.abs, hardware loop reference,
ret.d, the two-unit bz.s context rule, a truncated packet at the end of
the buffer, save/restore/ret and basic blocks that keep the delay slot.
2026-10-30 16:28:21 +01:00
n0p e94cc3060d md32: uSIP pseudo syntax
Pseudo rules for the uSIP mnemonics: # immediates, [base+off], [base]+
and [sp+off] memory operands, compare-and-branch, ld/st as dmemN[...],
movi/mov32, ALU, cmov, loop, save/restore.  test_parse.c updated.
2026-10-30 16:28:21 +01:00
n0p ac1af9c612 md32: wire the uSIP packet decoder into the arch plugin
In usip mode the plugin decodes whole packets (cached per session, 64
entries) and emits one op per run of adjacent units of the same
instruction; displaced tails become .unit ops that name their head.
Types, conditions, jump/fail/delay, loads/stores, immediates, save and
restore, sys and loop references come from the table; opex reports the
form, its confidence, the slot, the unit addresses and the packet
summary.  MAXOP_SIZE is 16 in this mode and regs() exposes the ABI.
The previous five hard-coded uSIP patterns are replaced by the table.
MS15E30 decoding is unchanged.
2026-10-30 16:28:21 +01:00
n0p 94bccea25c md32: table-driven VLIW packet decoder for uSIP
usip_decode.c reads the 16-bit big-endian units of a packet (closed by
bit 15), enumerates the group splits and head/tail assignments the table
allows (heads first, tails round-robin), scores them (unknown units,
instructions, groups, documented tie-break penalties), applies the
adjacency and context rules and returns one instruction per head with
the addresses of its units.  Control flow is restricted to slot 0 and
the rest of an open packet is its delay slot.
2026-10-30 16:28:21 +01:00
n0p 3f8dada173 md32: add the uSIP instruction table and its header generator
isa/usip_isa.json describes the uSIP (MD32 family, VLIW packet variant)
instruction set: 386 forms with masks, operand fields, constraints,
packet rules and a confidence level, plus the packet model (unit scan,
head/tail layout, tie-breaks, context rules) and the register/CSR model.
tools/gen_usip_tables.py generates usip_opcodes.h from it: every field
referenced by a format string or a constraint, constraints as structured
UsipCons records, 16-bit flags and the indices of the context-only forms.
2026-10-30 16:28:21 +01:00
pancake a21d29689b Add support for md32 architecture 2026-10-30 10:31:15 +01:00
pancake 099cb94abf Initial import of the gamegear emulator 2026-10-29 13:35:02 +01:00
pancake de674fbeb0 Add gameboy emulation documentation 2026-10-29 13:30:02 +01:00
pancake f81d48eaca Add gameboy usleep delays 2026-10-29 13:16:44 +01:00
pancake 610dd48707 Fix standalone r2gb test loading and ignore build outputs 2026-10-27 00:35:12 +01:00
pancake c6663b87e9 Initial import of the r2gb plugin 2026-10-27 00:30:24 +01:00
pancake f7dca9d52b Add asynchronous PCM streaming through auq 2026-10-27 00:28:32 +01:00
pancake f2a4b1dfa0 Fix the arpeggio demo 2026-10-26 23:37:46 +01:00
pancake b5b1101110 Fix the doom song 2026-10-26 23:30:34 +01:00
pancake 445c6a5a57 Fix build of r2au 2026-10-26 23:08:44 +01:00
Ricardo J. Rodríguez 5ab2c6aa7d msl: follow spec 1.1.1 register names and thread states
Thread Context (0x0011) changed in Memory Slice spec 1.1.0/1.1.1:
register names are now normative (Table 19g) and the block gained
Suspended/Partial flags, thread states 0x05-0x07 and a per-thread Arch
byte at +0x13.

debug.msl: map the ARM64 aliases fp/lr (and cpsr) that 1.1.0 producers
could write to x29/x30/pstate when seeding (consumer rule 29), using the
thread's Arch byte with the file header as fallback. `dpt` derives the
status letter from ThreadState (r/S/s/z) instead of only the Current flag.

core.msl (`dgm`): never write the fp/lr aliases on ARM64, tag the frame
pointer, status and link registers via r2's BP/SR/LR aliases, and set
Suspended alongside Current since the registers come from a halted
debuggee.
2026-10-26 18:38:36 +01:00
dependabot[bot] 1e989215d9 Bump libc from 0.2.190 to 0.2.191 in /x86iced
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.190 to 0.2.191.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.191/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.190...0.2.191)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.191
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-26 13:48:46 +01:00
dependabot[bot] a2692a2380 Bump libc from 0.2.172 to 0.2.190 in /x86iced
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.172 to 0.2.190.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.190/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.172...0.2.190)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.190
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-13 08:46:15 +02:00
pancake 614d94959e r2ida: import IDB C types into radare2 scripts 2026-09-27 07:36:17 +02:00
pancake 7a0269097b Fix PowerPC disassembler plugin 2026-09-27 07:14:34 +02:00
pancake c8f032c01d Fix MicroBlaze plugin build 2026-09-27 07:05:38 +02:00
pancake 188d102f6b Initial chrome devtools interface for radare2 2026-08-31 19:22:37 +02:00
Abhi 3275d32127 Build CI plugins from checkout 2026-07-29 15:13:39 +01:00
Abhi f4218097d2 Use radare2 GitHub Action in CI 2026-07-29 15:13:39 +01:00
Abhi 96dbf53b1c Fix x86iced for r2 6.1 ABI 2026-07-29 15:13:39 +01:00
pancake e3111fcba3 Remove the r2jadx attic 2026-06-27 18:51:29 +02:00
dependabot[bot] 5b0ea473f9 Bump libc from 0.2.154 to 0.2.172 in /x86iced
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.154 to 0.2.172.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.172/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.154...0.2.172)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.172
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-06-27 18:39:34 +02:00
f28a2ec94c Add plugins for memory slice (msl)
* msl: add Memory Slice (.msl) plugins (io/bin/debug/core)

Loadable radare2 plugins for the Memory Slice process-dump format:

- io_msl    open a slice as a process address space (msl://); verifies
            the SHA-256 block chain and End-of-Capture FileHash on open,
            warning on a truncated or tampered slice
- bin_msl   parse a slice as a CORE object (arch/bits/os, entry, maps)
- debug_msl emulated ESIL debug backend, incl. reverse exec (dsb/aesb)
- core_msl  producer: "dgm"/"dgma" write a slice from a live debug session

Build/install with the local Makefile (pkg-config r_core) or via r2pm.
test/genmsl.py emits a valid synthetic slice for exercising the read path.

* msl: select and list captured threads in the debug backend

A slice can capture several threads (one Thread Context block each); the debug
backend only seeded the Current thread. Expose every captured thread:

- .threads callback: `dpt` / `dptj` lists each captured thread with its PC.
- .select callback: `dpt=<tid>` re-seeds the register file from that thread
  and seeks to its captured PC, so any thread can be emulated.

msl_seed_regs now takes a target tid (>=0 exact, <0 Current with first-thread
fallback) and reports the chosen tid, which msl_ensure stores in dbg->tid.

Also fixes a double-unref of the mmap buffer (msl_seed_regs used to unref a
buffer owned by its caller), and accounts for r_debug_select swapping the
register arena after .select returns (seed both arenas so the new thread's
registers survive the swap). test/genmsl.py gains --mt to emit a second,
non-Current thread for exercising listing and selection.

* msl: resolve module symbols and PE exports in bin.msl

The bin plugin presented a slice as maps only. Parse ModuleEntry (0x0002)
blocks and expose them as libraries (`il`) and symbols (`is`): one symbol per
module base plus, for PE images whose headers are captured, one FUNC symbol per
exported function at its address. A VA->file-offset translator over the
captured-run maps reads the module image (DOS/PE headers, export directory).
radare2 then names call targets -- `sym.kernel32.dll_CreateFileW` -- instead of
bare addresses.

test/genmsl.py gains --pe (a minimal in-memory PE export table) and a
memory_region() helper. ELF .dynsym resolution is left to the Python tools.

* msl: note thread listing/selection in the plugin table

The debug.msl row documented reverse execution but not the `dpt` / `dpt=<tid>`
thread listing and selection; mention it for consistency with the body.

---------

Co-authored-by: Ricardo J. Rodríguez <ricardo@thanatos>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-27 09:51:49 +02:00
pancake 80925aeba6 r2jadx: Use r2.log instead of console.log 2026-05-11 15:44:41 +02:00
pancake 45f9bc841c r2jadx: Use better r2js and improve xrefs caching and more 2026-05-11 12:09:41 +02:00
pancake 69f93467a1 r2jadx: refactor into separate files 2026-05-11 07:53:17 +02:00
pancake 67b24be239 r2jadx: add -s to search words 2026-05-11 07:43:26 +02:00
pancake cd9cc5c190 r2jadx: add pd:j alias 2026-05-11 07:26:42 +02:00
pancake 568a7fd146 r2jadx: config -e with optable color and addresses 2026-05-11 07:22:21 +02:00
pancake d276feb5e8 Fix help message for r2jadx 2026-05-11 06:11:22 +02:00
pancake c3b9864f1d Rewrite r2jadx to typescript 2026-05-10 09:57:56 +02:00
Nerijus Bendžiūnas 7a6e3737c8 fix(r2k): allow Linux module to compile using clang
__FORCE_ORDER is a GCC-specific input constraint not supported
by clang. Use a "memory" clobber on clang instead.

Signed-off-by: Nerijus Bendžiūnas <[email protected]>
2026-02-28 17:46:22 +01:00
pancake 430b6fa559 Minor fix for the rar cpu code 2026-01-09 07:29:22 +01:00
pancake 1cf58513ad Fix r2doom build 2025-10-03 23:15:11 +02:00
Takumi Matsuura da8623bdbe Change to prioritize using uv 2025-10-03 13:58:38 +02:00
pancake 43057468c6 Add r2604 badge 2025-09-30 14:07:19 +02:00
pancake 7ed4cb393f Assume keys in afen can have spaces 2025-09-30 14:05:07 +02:00
pancake 031b7c20c0 Implement 'afen*' command to dump the database 2025-09-30 14:01:32 +02:00
pancake 9edd5e922b Release 6.0.0 2025-09-22 18:38:39 +02:00
satk0 dea1f62f8f Remove global var in afen 2025-09-22 15:54:03 +02:00
pancake e9306ef9fe Fix x86iced build for r2-6.0 2025-09-16 17:10:17 +02:00
pancake 941e0e8f81 Fix the VC4 build 2025-09-16 16:41:11 +02:00
satk0 fdcf847944 Make afen work 2025-09-16 15:41:57 +02:00
pancake e9035eda1c Rewrite all the asm plugins into arch ones 2025-09-04 12:08:37 +02:00
pancake f2d4e0d371 Fix vc4 build 2025-09-04 11:17:25 +02:00
pancake f06bef6f21 Do not build afen 2025-09-04 01:06:35 +02:00
pancake aac87e940d Fix build of the bin.gguf plugin 2025-09-02 19:38:24 +02:00
Abhi 6c0afb35c2 r2angr: fix latest cmake issues on termux (#386)
* fix latest cmake issues on termux

Affected packages: unicorn, pypcode

* pin angr version

angr since `9.2.155` moved to rust toolchain, which can't be compiled in termux due to bug in rustc not us.

* Update angr

just in case user installed r2 from package manager

* small fixes

* fix: illegal number

```shell
r2angr: 8: [: Illegal number:
```
2025-08-30 01:39:59 +02:00
pancake 1b276095d4 Add a chiptune song created with r2ai 2025-08-27 18:33:22 +02:00
pancake e90d99b9f4 Add more openai-generated versions of the "doom song" 2025-08-27 18:06:47 +02:00
pancake e0bb03cdd1 Fix r2au for the r2-6.x 2025-08-27 17:38:01 +02:00
pancake 6c9df38c66 FIx vc4 and blackfin 2025-03-13 19:27:49 +01:00
pancake 38e79b50b1 Fix build with latest r2 from git 2025-03-12 16:28:10 +01:00
pancake b03125fc99 Move rlcc from libr/egg/rlcc and shlr/mpc 2025-02-06 23:02:37 +01:00
pancake 36f9503eda Fix gguf plugin name 2025-02-06 19:18:10 +01:00
pancake 3a25b7f345 Fix hexagon install 2024-12-11 15:31:52 +01:00
pancake b91c295be3 Remove awful function and warning from squashfs 2024-12-04 16:47:19 +01:00
pancake 9e4c70872e Fix build of fs-squashfs 2024-12-04 11:50:32 +01:00
pancake 94f8d2dc94 Update build instructions for the r2k plugin 2024-12-02 15:37:00 +01:00
pancake 89624cc37c r2k: Fix write on protected regions, lock RCU when acessing tasks fixing races 2024-12-02 15:32:27 +01:00
NighterMan 42aed83113 Fix r2k-linux build on latest Linux kernels 6.4.x 2024-12-01 23:52:32 +01:00
pancake 4d944cce9a Release 5.9.6 2024-11-05 18:30:09 +01:00
pancake 49a91651d2 Fix invalid pfb string in r2svd when the bitstruct have 0 fields 2024-10-31 08:50:51 +01:00
Roman Valls Guimera 3596e7f1a5 Repoint cmsis-svd repo to upstream cmsis-svd org 2024-10-22 06:52:53 +02:00
Abhi 54ff412976 Fix setup on termux (#367)
* Fix installation on termux
* remove binutils & build-essential
  * They should already be present if the user has installed R2.
* remove un-necessary install
2024-10-21 17:49:49 +02:00
dependabot[bot] 3d2fa7985b Bump serde_json from 1.0.124 to 1.0.132 in /x86iced
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.124 to 1.0.132.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.124...1.0.132)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-10-21 17:49:10 +02:00
pancake 3064bbcb7f Fix license names 2024-10-21 17:48:39 +02:00
pancake 97d8b87bf5 Fix license name for blackfin 2024-10-21 17:48:35 +02:00
pancake 26450ea9b9 Fix the CI 2024-09-30 20:10:22 +02:00
pancake 14d385082c Inverse r2 version check for r2svd 2024-09-30 13:10:12 +02:00
pancake 3a92956545 os.path.join is UB. thank you py3 2024-09-30 12:41:05 +02:00
pancake 5ef0b34d57 Install r2svd with symlink 2024-09-30 12:30:36 +02:00
pancake 57f3c159e0 Setuptools is dead, not just deprecated. workarounding with more hacks 2024-09-30 12:26:21 +02:00
pancake 991ee0f685 Setuptools was deprecated, so we need it now 2024-09-30 12:19:41 +02:00
pancake 4e72a04103 Join paths properly 2024-09-30 12:16:14 +02:00
pancake 9a61bb6f7d Use our cmsis-svd fork 2024-09-30 12:15:39 +02:00
pancake 9c22aa709d Parse register fields and support ascii art stuff for r2svd 2024-09-29 19:23:14 +02:00
Roman Valls Guimera ccefb4237d Fix setuptools deprecations and switch to version-1.0 of cmsis_svd 2024-09-29 12:11:59 +02:00
Roman Valls Guimera ef93ab4c91 Deprecate setuptools:
% r2svd --help
/Users/rvalls/.local/share/radare2/prefix/bin/r2svd:9: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  import pkg_resources
2024-09-29 12:11:59 +02:00
sha0coder 496b46918b r2ida first version 2024-09-27 22:05:03 +02:00
Nitan Alexandru Marcel 82b3a8e97d Use TMPDIR env or fallback to /tmp for temporary log file (#360) 2024-09-05 16:27:41 +02:00
pancake 0350bec1e7 One venv for angr and arg for structurer 2024-08-31 16:18:57 +02:00
pancake 6e06bcd365 Force the latest capstone to fix angr on arm64 boxes 2024-08-31 16:11:48 +02:00
pancake b170500a27 Honor R2_BADDR in r2angr if set 2024-08-29 20:54:47 +02:00
pancake ece2da866a Show r2poke version 2024-08-29 20:53:41 +02:00
pancake fecf53943b Enable the alien tokens for gnupoke4 2024-08-29 20:53:36 +02:00
pancake dda5cb2d70 Improved output and hints for r2angr 2024-08-29 18:31:16 +02:00
pancake ebe772353a oops 2024-08-29 18:22:22 +02:00
pancake d6f4f63aca Add r2angr wrapper script for decompiling 2024-08-29 17:55:45 +02:00
pancake 343dce1014 atombios not ported, but at least dont break the build 2024-08-26 10:55:50 +02:00
dependabot[bot] 3bb3fbf753 Bump serde from 1.0.201 to 1.0.208 in /x86iced
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.201 to 1.0.208.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.201...v1.0.208)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-08-19 10:53:02 +02:00
dependabot[bot] 42131f6bd6 Bump serde_json from 1.0.117 to 1.0.124 in /x86iced
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.117 to 1.0.124.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.117...v1.0.124)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2024-08-19 09:25:47 +02:00
satk0 663b25a8fc Make afen function specific (#351) 2024-08-01 22:43:01 +02:00
pancake b0f48b0194 Support GNU Poke4 for r2poke 2024-07-11 17:08:10 +02:00
satk0 6e4ece2732 Fix rparse to rcore binding for afen (#346) 2024-06-25 18:07:32 +02:00
Sylvain Pelissier 628a9d20d0 Update ci.yml with afen plugin
Add r2afen build in CI.
2024-05-22 08:16:50 +02:00
pancake 315256b0ef Release 5.9.0 2024-05-21 17:18:27 +02:00
satk0 eef6f4a39f Fix to make afen installable 2024-05-20 17:38:01 +02:00
satk0 306cc36d80 Add possibility to build afen plugin 2024-05-20 07:36:08 +02:00
satk0 39f897acfe Mention pancake help in README 2024-05-20 07:36:08 +02:00
satk0 33c681dadf Add an example usage 2024-05-20 07:36:08 +02:00
satk0 fd6d8979ea Add afen plugin 2024-05-20 07:36:08 +02:00
Sylvain Pelissier 167e5c48b2 Update ci.yml with VC4 test
Brings back the VC4 test in CI.
2024-05-13 08:17:46 +02:00
Sylvain Pelissier 82d0276127 Update ci.yml with x86iced plugin
Add x86iced pulgin in CI.
2024-05-12 07:40:36 +02:00
GRAUX Pierre d9273fc53e Enable CI for vc4 plugin 2024-05-11 23:49:37 +02:00
GRAUX Pierre 26d8b75ffe Remove compilation warnings for vc4 plugin 2024-05-11 21:12:56 +02:00
GRAUX Pierre fc38eb7862 Add instruction analysis information for vc4 plugin 2024-05-11 21:12:56 +02:00
GRAUX Pierre da11f75c73 Translate the vc4 plugin from asm to arch 2024-05-11 21:12:56 +02:00
pancake 7be547f648 Some minor improvements for r2jadx 2024-05-10 20:37:25 +02:00
Richard Patel 31fba0eafd x86iced: add register access info 2024-05-09 08:37:58 +02:00
Richard Patel 77269480b3 x86iced: support mnemonic 2024-05-09 08:37:58 +02:00
pancake 8903ddf7ef r2sarif is now in a separate repository 2024-05-09 01:59:40 +02:00
Richard Patel a88eecf962 x86iced: fix crash 2024-05-08 14:54:20 +02:00
Richard Patel f912df64a2 x86iced: add metadata
- Enable Dependabot so we get automatic PRs for iced-x86 updates
- Add Cargo metadata (disable publish, MIT license, description)
2024-05-08 14:54:20 +02:00
pancake 6dd7921729 Rename r2iced to x86iced 2024-05-07 17:42:37 +02:00
pancake ae05525a78 Add makefile for r2iced. Rename to x86-iced 2024-05-07 17:02:03 +02:00
Richard Patel 78f4e70ca7 r2iced: support AT&T, masm syntax 2024-05-07 15:59:51 +02:00
Richard Patel ec94bfcd50 Add r2iced 2024-05-04 14:24:13 +02:00
Sylvain Pelissier 6de9a49e88 Update ci.yml
Bring back blackfin build in CI
2024-05-01 14:30:39 +02:00
GRAUX Pierre a36564eaa9 Fix blackfin plugin compilation 2024-04-29 18:05:22 +02:00
pancake ccc7d46e92 Initial work to support revng decompiler for r2, for now just a docker image 2024-03-29 17:36:39 +01:00
pancake 6c21ca2a7d Implement sarif -i to import findings 2024-03-10 20:20:56 +01:00
pancake adf9e7aca8 Make rules supported by sarif generic from external file instead of hardcoded 2024-03-10 20:08:16 +01:00
pancake d1f90741b0 Initial working version of Sarif and add a couple of finding types more 2024-03-01 16:59:06 +01:00
pancake bb15dc4562 Add Makefile, readme and some more code for the Sarif plugin 2024-02-29 12:43:03 +01:00
pancake 90567f4c80 Add sample sarif script for r2 2024-02-19 19:41:16 +01:00
silur e8d1cb20b2 remove libr/asm/arch/evm 2024-02-09 23:26:29 +01:00
pancake 98e6d29133 leftover? 2024-02-07 09:42:51 +01:00
pancake e5ef780da8 Rewrite the r2jadx plugin into r2js
* nodejs code was broken because syspipe was no longer compatible with latest node
* This is very experimental
2023-12-05 20:28:35 +01:00
pancake 6f8c8f0836 Initial import of the GGUF bin plugin 2023-11-21 11:26:25 +01:00
Sylvain Pelissier c28cf25f7a Fix CI badge 2023-10-30 21:48:26 +01:00
Sylvain Pelissier 6a7a636ebe Update ci.yml with asahi plugin
Add asahi build in CI
2023-10-23 13:38:20 +02:00
pancake e3b6897bda apt update 2023-10-19 21:39:01 +02:00
pancake 209c82d674 Bump ubuntu and checkout version 2023-10-19 21:37:46 +02:00
pancake e68f98a223 Fix build of the asahi plugin 2023-10-19 21:30:18 +02:00
pancake 84aa166231 r2ai has been permanently moved into its own repository 2023-10-16 14:37:20 +02:00
pancake a005f0402b Add support for tinyllama queries 2023-10-16 14:30:18 +02:00
pancake 1a1e68a882 Remove unused code_interpreter.py 2023-10-16 01:35:46 +02:00
pancake 68a8e3d4e5 Add conversational example and refactoring the templater logic in r2ai 2023-10-10 00:18:02 +02:00
pancake 7d6afc0855 Support multiple AIs instances 2023-10-09 21:31:13 +02:00
pancake a0fd4013b0 Always decolor the command queries and improve <<SYS>> prompt 2023-10-09 20:43:44 +02:00
pancake dd78a53a1a Fix r2ai from shell 2023-10-09 18:58:19 +02:00
pancake 5a13ac3032 More cleanup and tweaks for r2ai 2023-10-09 12:37:33 +02:00
pancake d3fe9b7223 Use r2lang.cmd if needed 2023-10-09 12:14:22 +02:00
pancake 90b782e683 Add uninstall target 2023-10-09 12:06:33 +02:00
pancake 36feb1733c Add make user-install 2023-10-09 12:06:01 +02:00
pancake 0fd38b8121 Add live mode option to fully integrate r2ai with r2js 2023-10-09 11:53:07 +02:00
pancake 229188050e Remove r2ai/cli 2023-10-09 10:54:32 +02:00
pancake 31a841c561 Use rlang if available, so we can register a core plugin for r2ai 2023-10-09 10:48:33 +02:00
Sylvain Pelissier 5469876cfa Remove r2yara from ci.yml
Now in it's own package
2023-10-06 22:19:51 +00:00
pancake 8c90086fc2 Remove r2yara because it's now living in its own repo
* https://github.com/radareorg/r2yara
2023-10-06 16:45:29 +02:00
Sylvain Pelissier 82734d3371 Uptade CI 2023-10-03 10:09:44 +00:00
pancake edeadec44c Add 'model' command and bring back the hugging face download 2023-10-03 00:44:47 +02:00
pancake d5a88f6b41 Fix yara 'scan S' regression and add short command 'yr' 2023-10-02 12:29:33 +02:00
pancake 4f67e1af9a Add yara version command in r2yara 2023-10-02 12:08:26 +02:00
Sylvain Pelissier e1ace49642 Update core_yara.c
Fix options parsing.
2023-10-02 09:35:24 +00:00
pancake 046db11e95 Fix segfault in yara scan 2023-10-02 11:22:46 +02:00
pancake e1edea1405 Prepend cwd in model path 2023-09-29 02:30:52 +02:00
pancake a5a042cecc Fix crash and improve chat model query construction 2023-09-28 11:25:05 +02:00
pancake d91308a818 Support uncensored models, more tokens and custom query templates 2023-09-28 10:37:12 +02:00
pancake bb205b2607 Add torrent file for the models 2023-09-27 17:28:33 +02:00
pancake 3636cc53ff Fix r2poke build 2023-09-26 23:16:38 +02:00
pancake b652ff1305 Add r2ai.pdf 2023-09-26 16:42:02 +02:00
pancake e50cfcc008 Fix r2yara null deref and help message 2023-09-26 11:39:34 +02:00
pancake 7044515214 Fix build of the keystone plugins 2023-09-26 11:25:44 +02:00
pancake 1c83c693ba Update gitignore 2023-09-26 11:22:40 +02:00
pancake d3f44531c7 path fixes for r2yara 2023-09-26 11:21:00 +02:00
pancake 9a2cd79b6c Move yara/yara into r2yara 2023-09-26 11:17:37 +02:00
pancake 44ae4f46c5 Update r2yara core plugin to fix build and fix other UB bugs 2023-09-26 11:01:00 +02:00
pancake 296ff27e42 py3 just in case 2023-09-25 20:33:24 +02:00
pancake 400d67c472 Download the cherrypop model 2023-09-25 20:24:42 +02:00
pancake 01ef784858 r2pm init is deprecated 2023-09-22 17:56:49 +02:00
pancake 8a2c686105 More fixes for r2ai to handle ^C and solve installation issues 2023-09-22 13:28:32 +02:00
pancake d12ef02a13 Add env, improve prompt, clear screen, better prompting, etc 2023-09-22 12:45:27 +02:00
pancake 3fcb7ecf9b Fix prompt glitches in r2ai 2023-09-21 02:50:14 +02:00
pancake e7c8f4e7e5 Initial implementation of the local r2ai based on open-interpreter
* Improved shell with, $role :slurp !r2 !!r2pipe commands
* See readme for default model download
2023-09-21 02:08:28 +02:00
robman2444 848a1b2eeb added -fPIC to hexagon makefile. Kindof a kludge, but it works 2023-09-16 00:01:56 +02:00
pancake 1947df56fd Missing file 2023-09-15 16:27:33 +02:00
pancake c12d4badff Fix crash 2023-09-12 22:28:55 +02:00
pancake fd3871893a Reword the anal and asm hexagon plugins into an arch one 2023-09-12 22:08:55 +02:00
pancake 0a7590f748 Add hugging face test script 2023-08-18 16:04:02 +02:00
pancake 9ae0981f5a Improve optimized decompilation with bard 2023-08-01 12:56:54 +02:00
pancake bdb04b54fa Minor help improvement for bard 2023-07-19 18:42:34 +02:00
pancake 1318082a67 Make the bard script a plugin 2023-07-19 18:30:03 +02:00
pancake e72b5010c8 Add bard setup instructions 2023-07-18 13:50:54 +02:00
pancake 9b5b0013f9 Add hello world for r2ai with Google Bard 2023-07-18 13:49:05 +02:00
pancake c4b7f76081 Fix unicorn build with latest r2 2023-07-11 16:31:18 +02:00
pancake 71eb56d619 Add r2doom ai-image logo 2023-06-19 11:04:27 +02:00
pancake d3911fa5a5 Add support for delimited alien tokens in r2poke 2023-05-18 16:55:53 +02:00
pancake 5cf30b4af2 Fix enemy's health 2023-05-18 15:17:54 +02:00
pancake 0b983e477e Add beep support to r2doom 2023-05-18 11:23:33 +02:00
pancake 822a45ab18 Go realtime in r2doom 2023-05-17 12:12:17 +02:00
pancake cd4e396bcd Rename sysz to s390x and add evm to keystone 2023-05-15 12:32:28 +02:00
pancake 22f196cecc Implement strife, locked doors, ascii perspective, better damage, flash weapon when shooting 2023-05-15 10:48:59 +02:00
pancake f8dea3b7e2 Fix x86.ks 2023-05-14 22:08:38 +02:00
pancake 3a7484b467 Fix build of the keystone plugins 2023-05-14 22:07:30 +02:00
pancake 4901c49c4e Fix r2au assembler, visual piano, phone and other demos 2023-05-14 21:44:42 +02:00
pancake 90765cc641 Minor improvements for the r2au plugin 2023-05-13 21:29:03 +02:00
pancake f665a9eb11 Update r2au plugin for r2-5.8.x 2023-05-13 21:08:37 +02:00
pancake e0a8b8b3e3 Fix shooting and damage computations 2023-05-13 20:13:25 +02:00
pancake 3584dee33b Handle arrow and wasd keys in r2doom 2023-05-13 20:04:05 +02:00
pancake 0c113bdea8 Faster clear primitives to fix the blinking hud in r2doom 2023-05-13 19:50:10 +02:00
pancake 23fc638c27 Fix collisions precission bug in r2doom 2023-05-13 19:35:25 +02:00
pancake 7d67e6343d Fix infinite loop on large screens running r2doom 2023-05-12 12:36:07 +02:00
pancake ad95329c1e facepalm 2023-05-09 11:49:08 +02:00
pancake d10a5257cd glibc fix 2023-05-09 11:41:58 +02:00
pancake 9896414afb Fix linux build 2023-05-09 11:37:26 +02:00
pancake a599c6c2d6 Add screenshot and fix the readme 2023-05-09 11:25:19 +02:00
pancake ba754bed7b Fix linux build of r2doom 2023-05-09 11:08:13 +02:00
pancake a745e3cd65 Initial import of the r2doom 2023-05-09 10:56:05 +02:00
pancake 4235786fab Fix #322 - filter newlines in comments 2023-03-10 12:46:06 +01:00
pancake 6fc39af6e2 Support call commands in r2svd if available 2023-03-10 12:42:41 +01:00
pancake 6a0781ab3f Add initial json.pk for r2poke from mnabipoor <3 2023-02-28 00:30:13 +01:00
pancake c31f8fb226 Fix reg profile for blackfin 2023-02-27 00:22:41 +01:00
pancake 831b8579ee Upgrade the blackfin disassembler from latest -plus code 2023-02-27 00:03:31 +01:00
pancake 6bd03e5642 Improve the blackfin analysis details 2023-02-26 23:38:28 +01:00
pancake 77c8e95061 Translate the blackfin plugin from asm to arch 2023-02-26 19:33:48 +01:00
pancake 730aff1b19 Use rpath for home's poke 2023-02-16 20:28:46 +01:00
pancake eba95758d2 Support alien tokens thanks to the cuki lexic
* WIP: Use $r2cmd::.... to run commands or resolve flags
2023-02-16 17:21:43 +01:00
pancake 9836aa3b73 r2poke: Add eprint and use it from the runtime exception handler 2023-02-16 17:04:44 +01:00
pancake ab97757ada Implement eprintf() for the r2poke 2023-02-16 16:58:19 +01:00
dependabot[bot] ad856dee2d Bump minimist and mkdirp in /r2jadx
Bumps [minimist](https://github.com/substack/minimist) and [mkdirp](https://github.com/isaacs/node-mkdirp). These dependencies needed to be updated together.

Updates `minimist` from 1.2.0 to 1.2.6
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/commits)

Updates `mkdirp` from 0.5.1 to 0.5.6
- [Release notes](https://github.com/isaacs/node-mkdirp/releases)
- [Changelog](https://github.com/isaacs/node-mkdirp/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-mkdirp/compare/0.5.1...v0.5.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
- dependency-name: mkdirp
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-02-16 16:28:28 +01:00
pancake 07c8150329 Initial the exception handler and open the R2 io device 2023-02-16 16:27:52 +01:00
pancake 913874da41 Add runtime exception handler for r2poke 2023-02-16 15:48:03 +01:00
pancake 75a4f63391 Improve the poke plugin 2023-02-16 00:46:35 +01:00
pancake d834af469c Link to the system wide poke 2023-02-09 22:38:06 +01:00
pancake 7e0235ea45 Add the fosdem 2023 slides 2023-02-08 11:01:01 +01:00
pancake e49a1bb2e3 Build fixes 2023-01-19 16:50:40 +01:00
pancake c563cdd8f8 More standard makefile stuff 2023-01-19 11:47:35 +01:00
pancake bb4a2bdb6d Show help on poke 2023-01-19 11:37:59 +01:00
pancake 97070385b4 Initial import of the r2poke plugin 2023-01-19 03:58:54 +01:00
pancake 18d26928e6 Fix m32c build for r2-5.8 2023-01-17 17:32:05 +01:00
pancake 5baebd4620 Initial publication of the EAST decompiler (Vlang)
* It's just a PoC that aims to combine the vlang compiler internals
* Feel free to play or contribute! I wrote pdq based on this codebase
* Based on ESIL parsing and analysis to create an AST that can be
* printed into C-like syntax.
2022-12-30 12:20:37 +01:00
pancake d034b2769a Release 5.8.0 2022-12-23 11:33:24 +01:00
pancake 0cea6e28e4 Better name for the r2addrline script 2022-12-08 05:11:23 +01:00
pancake 9689796965 Add script to convert addr2line output to r2 CL script 2022-12-08 05:05:27 +01:00
pancake 8fe16da993 Add the daila question 2022-12-06 16:41:02 +01:00
pancake 52439a5845 Improve the readme 2022-12-02 21:05:16 +01:00
pancake e27b7bfe3c Initial import of the r2ai plugin PoC 2022-12-02 21:01:07 +01:00
dependabot[bot] 9962027deb Bump minimatch from 3.0.4 to 3.1.2 in /r2jadx
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-11-30 21:30:28 +01:00
lgtm-com[bot]andLGTM Migrator 79bf9fa5ba Add CodeQL workflow for GitHub code scanning (#319)
Co-authored-by: LGTM Migrator <[email protected]>
2022-11-30 18:34:09 +01:00
pancake b74faa00f2 Add malbolge plugin taken from r2 master 2022-11-13 20:56:03 +01:00
pancake 88a5de0331 fix leak in the world 2022-10-18 22:29:29 +02:00
pancake fe805b5781 fix pwm for negative positions 2022-10-06 19:28:42 +02:00
pancake 33cc031b38 Use RCons.printf in pwm 2022-10-06 00:24:19 +02:00
pancake 39d6a3e9c9 Add pwm plugin to print world map 2022-10-05 22:45:08 +02:00
pancake 5cda6a599e Fix keystone build on latest r2 2022-09-30 12:33:34 +02:00
pancake 245716be19 Use pkg-config for keystone instead of assuming its in libdir 2022-09-30 12:31:35 +02:00
pancake f8137fd314 Expose the +R2PM_USRPLUGIN_DIR for yara 2022-09-29 18:46:22 +02:00
pancake fe4e54b50e expose LIBEXT 2022-09-29 18:45:05 +02:00
pancake 790c02b9ce Support the new xdg apis in the yara plugin 2022-09-29 18:44:07 +02:00
Sylvain Pelissier acbb8a7c0f Remove EVM from CI
The code is moving to core.
2022-09-24 17:28:11 +02:00
Sylvain Pelissier b557dc24a0 Merge pull request #316 from radareorg/evm
Correct EVM opcode max representation length
2022-09-12 17:32:58 +02:00
Sylvain Pelissier c4594ce486 Correct EVM opcode max representation length 2022-09-12 17:22:08 +02:00
Sylvain Pelissier 40a6d34bea Merge pull request #315 from sylvainpelissier/ci
Correct check_buffer for bcl, atombios and pcap.
2022-09-11 23:14:51 +02:00
Sylvain Pelissier 38e369a367 Correct check_buffer for bcl, atombios and pcap. 2022-09-11 22:58:00 +02:00
Sylvain Pelissier af3214df2c Update ci.yml
Bring back yara test
2022-08-22 15:29:59 +02:00
Sylvain Pelissier 88aaebc6ee Update README.md
Change link to plugins documentation.
2022-08-18 09:25:09 +02:00
Sylvain Pelissier 9d82adef43 Temporary disable yara test in CI 2022-08-17 15:15:17 +02:00
Sylvain Pelissier 4779456cd6 Bring back evm, vc4 and yara tests in CI 2022-08-17 15:02:16 +02:00
Sylvain Pelissier 4a795e0b30 Temporary disable r2pipe-go in CI 2022-08-17 14:05:26 +02:00
Sylvain Pelissier bec354d82c Temporary disable swf test in CI 2022-08-17 11:00:59 +02:00
Sylvain Pelissier 0ab8603f0c Update x86 BEA build 2022-08-17 10:39:16 +02:00
Sylvain Pelissier d5add35cd5 Update ci.yml
Add libcurl to CI build process.
2022-08-17 09:57:58 +02:00
Richard Patel 15b05687ae Move BPF to radare2 (#310) 2022-08-01 18:21:21 +02:00
pancake 14f68e9388 import dcpu from r2. as its now a dead arch 2022-06-28 16:39:48 +02:00
Sylvain Pelissier a4f8842bd8 Merge pull request #308 from radareorg/sylvainpelissier-yara
Temporary disable yara in CI
2022-05-09 08:42:48 +02:00
Sylvain Pelissier 55cc028778 Temporary disable yra in CI
Until finding why it does not pass in CI but it pass locally.
2022-05-09 08:30:05 +02:00
Sylvain Pelissier baa29e633a Correct builds 2022-05-08 22:21:29 +02:00
pancake 165b565eb2 More work on the unicorn plugin 2022-05-07 13:05:46 +02:00
pancake 053f774462 Initial mmio support for unicorn 2022-05-07 12:47:08 +02:00
pancake 002b26d5e9 unicorn: Add support for the new command interface 2022-05-07 12:06:21 +02:00
pancake 2dd9a63faa fix null deref in unicorn 2022-05-07 01:04:16 +02:00
pancake 5af97a31d2 Fix arm64 unicorn init 2022-05-07 01:02:59 +02:00
pancake e8099c7b14 codesign when installing debug plugins for latest macOS 2022-05-07 00:47:08 +02:00
pancake 5a78bcb402 codesign unicorn 2022-05-07 00:29:40 +02:00
pancake 8a0da3c5b7 Add support for mips in unicorn 2022-05-07 00:22:21 +02:00
Sylvain Pelissier ed8e9d96d7 Correct EVM and Z80 builds 2022-05-04 09:27:46 +02:00
Sylvain Pelissier a1bc103782 Correct microblaze and x86zyan builds 2022-05-03 16:53:01 +02:00
Sylvain Pelissier c56286efdb Correct blackfin, evm and vc4 builds 2022-05-02 22:24:38 +02:00
Sylvain Pelissier adb999852e Correct bea and ppcdisasm builds 2022-05-02 19:55:58 +02:00
Sylvain Pelissier 3254c72bc6 Merge pull request #307 from radareorg/x86udis
Correct x86udis build
2022-05-02 19:14:38 +02:00
Sylvain Pelissier 575bfec497 Correct x86udis build 2022-05-02 19:03:51 +02:00
Sylvain Pelissier 6a3d97082b Correct keystone build 2022-04-28 22:54:18 +02:00
pancake 5c172dcb55 Release 5.6.8 2022-04-26 11:52:16 +02:00
pancake 64b81544bd Install acr if not installed when autogening 2022-04-26 11:52:06 +02:00
pancake caee604777 Import r2au from https://github.com/radare/radare2-au 2022-04-13 10:46:50 +02:00
pancake 71c938d827 The hexagon (qdsp6) plugin from r2 (moved out from master)
* For maintainance reasons
2022-03-21 23:46:09 +01:00
pancake 5c9126d2d8 Initial import of the rl78 disassembler plugin based on binutils 2022-03-20 18:47:32 +01:00
Sylvain Pelissier df747eba95 Add evm compilation in CI. (#303) 2022-02-12 10:35:23 +01:00
Sylvain Pelissier b50ce706ea Replace sdb_fmt by r_strf (#302) 2022-02-12 10:35:10 +01:00
dependabot[bot] 2eb8d24357 Bump ajv from 6.10.0 to 6.12.6 in /r2jadx (#305) 2022-02-12 10:34:27 +01:00
pancake 3f0adee8a9 Fix evm build warnings 2021-12-13 11:23:00 +01:00
pancake 283554e8fd Sync unicorn with latest r2 io changes 2021-12-13 11:19:45 +01:00
pancake 45d4483161 Fix unicorn build 2021-12-13 11:09:38 +01:00
David Vestal e30d193d28 test extras build for snowman to use QT5 (#300) 2021-12-12 01:42:11 +01:00
Sylvain Pelissier e8c9895354 Add separate CFLAGS to vc4 compilation (#299) 2021-10-24 00:19:48 +02:00
pancake b5b7ddf7c5 Fix m32c build 2021-10-02 11:03:01 +02:00
Sylvain Pelissier 83bcd0ef38 Remove nios from Makefiles (#296) 2021-09-29 22:33:53 +02:00
pancake ea07e3fc43 non-blocking m32c test 2021-09-27 18:13:14 +02:00
pancake e158c1bbdc Initial import of the m32c.gnu plugin ##disasm (#285)
* Delete the nios2 plugin because its already in core
2021-09-27 17:41:43 +02:00
pancake 679046a6c0 lseek -> seek 2021-09-24 16:51:39 +02:00
Sylvain Pelissier 1d9f052001 Remove arm64v35 plugin from extras (#294) 2021-09-09 08:55:42 +02:00
pancake bdb9416300 Fix swf signature 2021-09-09 02:45:17 +02:00
dependabot[bot] 158169099e Bump path-parse from 1.0.6 to 1.0.7 in /r2jadx (#291)
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-11 08:25:36 +02:00
Matthew Di Ferrante a4c71ac354 Fix OP_REVERT and OP_SELFDESTRUCT mapping (#290)
Fix mistaken mapping for REVERT and SELFDESTRUCT from `0xfb` and `0xfd` to `0xfd` and `0xff` respectively.
2021-07-28 08:44:04 +02:00
Sylvain Pelissier 2aee0cb6d8 Add r2svd build in CI. (#289) 2021-07-26 13:04:09 +02:00
pancake 903bbe6c70 unstatic 2021-07-15 17:03:20 +02:00
pancake 5db084ce75 Fix #286 - Fix the bad code in swf disassembler (#287) 2021-07-15 12:31:37 +02:00
Sergi Àlvarez i Capilla b49e51aefb Release 5.3.0 2021-06-01 01:41:35 +02:00
pancake 393d2f573a Fix the priorities to pull the v35 repo 2021-05-25 15:36:33 +02:00
Shadorain 5efc8aac3c sys/sysctl.h no longer supported, won't build. (#282)
* sys/sysctl.h no longer supported by glibc: affects fs-squash

Glibc 2.32 and greater no longer support sys/sysctl.h, fs-squash plugin
doesn't build.
I put an `#ifdef` checking if an older GLIBC is still in use, if not
it will use `linux/sysctl.h` instead.

* remove unsquashfs binary
* Removed support for older glibc
* Processors variable is now const at 1
2021-05-17 00:48:05 +02:00
pancake 4d44a7abea Fix build of z80.nc 2021-05-11 18:00:58 +02:00
pancake 25e895800e Fix build of vc4 and z80 plugins 2021-05-11 17:59:28 +02:00
pancake eea5e126ae Fix ba2 plugin compilation warnings 2021-05-11 12:23:19 +02:00
dependabot[bot] 9e30411db8 Bump hosted-git-info from 2.7.1 to 2.8.9 in /r2jadx (#284)
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.7.1 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.7.1...v2.8.9)

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-10 15:57:12 +02:00
dependabot[bot] 0b1bc17ec4 Bump lodash from 4.17.19 to 4.17.21 in /r2jadx (#283)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.21)

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-10 09:32:06 +02:00
pancake f5763dcae7 Initial import of the r2pongo plugin 2021-05-09 01:22:18 +02:00
Sylvain Pelissier 035c0ff594 Map yara scan results to correct virtual address (#281)
* Map yara scan results to correct virtual address

* Honor io.va configuration during Yara scan

* FIx according to r2 coding guidelines

* Rely on map instead of section for virtual address in Yara scan

* Fix variable error
2021-04-29 23:58:30 +02:00
pancake 32152f2ec2 Fix arm64v35 build 2021-04-27 12:56:17 +02:00
aemmitt-ns b44d25e0e2 Translate arm64 analysis to v35 disassembler (#280)
* convert old arm64 analysis plugin to v35
* add more from previous arm64 analysis, incl float and vec support
* fix sb && s warning from null postfix
* converted the old anop64 to v35
* fix esil for b.cc instrs
* fix cset/csel/cinc
* fix register indexed mem ops, slightly simplify esil generation
2021-04-27 12:25:47 +02:00
pancake e25b59fe2e Release 5.2.0 2021-04-12 01:39:45 +02:00
pancake ac57ab34a7 Update URL 2021-03-29 22:39:31 +02:00
pancake 24072c986e Add README for iref 2021-03-29 22:37:18 +02:00
pancake 5877128009 Add iref utility 2021-03-29 22:33:46 +02:00
pancake 29894cabdc Take the omap3430 registers script into r2svd 2021-03-17 12:39:09 +01:00
Sylvain Pelissier eb27602a8e Add keystone tests in CI (#278) 2021-02-12 16:56:48 +01:00
Sylvain Pelissier 5b020c3796 Add yara build and test in CI. (#277) 2021-02-11 01:45:55 +01:00
Sylvain Pelissier 457a8bf1ea Add test in ci.yml (#275) 2021-02-10 09:28:56 +01:00
Sylvain Pelissier f2b8a6aa40 Bring back tests in CI for plugins (#274) 2021-02-07 21:43:55 +01:00
Sylvain Pelissier 0a09545ce0 Fix baleful plugin build (#273) 2021-02-06 00:16:34 +01:00
Sylvain Pelissier 3b29d305ab Fix Vector35 ARM64 plugin build (#272) 2021-02-04 22:39:37 +01:00
pancake 184a769b90 Release 5.1.0 2021-01-26 18:18:43 +01:00
pancake 5a14def4af Add history logs for the e2r thing 2021-01-18 12:13:31 +01:00
pancake c8cb79e175 Add esil2reil plugin ripping code from r2 2021-01-18 12:12:19 +01:00
pancake e40dd90bb9 Add missing clean targets 2021-01-08 12:32:59 +01:00
pancake ae8872e121 Add ASAHI (Apple-M1's GPU) disassembler plugin 2021-01-08 12:30:06 +01:00
pancake 1943c6793a Build arm64v35 in the CI 2020-12-08 14:20:55 +01:00
pancake d3faa7e8a6 Fix arm64v35 install and implement uninstall 2020-12-08 14:20:11 +01:00
pancake 7c0287d0e7 Add Vector35 ARM64 disassembler and analyzer plugins (#269) 2020-12-08 13:59:38 +01:00
pancakeandpancake ef6b08214f Update autogenerated ACR scripts (#270)
Co-authored-by: pancake <[email protected]>
2020-11-30 18:09:01 +01:00
Damien Zammit 6ec77c12b6 GitHub CI: Point to correct repo, use new flag && fix badge (#268) 2020-10-20 10:59:09 +02:00
pancake 644ee622c5 Add Github CI badge and fix s/lang/rlang pkgname for duktape after being moved to rlang 2020-10-13 14:14:38 +02:00
pancake 34719628b9 Support passing svd file as argument and filter flag names 2020-10-11 10:58:19 +02:00
pancake e45ff06e70 Import spc700 asm + bin plugins from core 2020-10-08 14:18:29 +02:00
Christopher Hewitt 6f726e0f68 Update nios target (#264) ##asm
* nios: Update function syntax, remove comment.
* nios: Initial work on analysis plugin.
* nios: Update Makefile targets.
* nios: Current progress.
* nios: Load nios_ops into hashtable.
* nios: Use new HtPP API.
* nios: Resolve "r_reg_get_value: Bit size 11 not supported", cleanup.
* nios: Remove ambiguity between struct and function.
- nios_op -> insn_op
* nios: Add missing new RAnalOpMask argument to nios_op function.
* nios: Update return type for set_reg_profile.
- int -> bool
* nios: Minor formatting fixes.
- Update plugin date comment
- Remove empty lines after breaks
* nios: Add target to Travis CI build config.
2020-10-01 15:42:05 +02:00
Damien Zammit c4d27a8e94 atombios: Make plugins compile again && GitHub CI (#265) ##asm
* atombios: Make plugins compile again
* anal_atombios: Fix call 0x00 illegal instruction
* bin_atombios: Fix offsets of symbols/sections
* anal_atombios: Fix jump offsets too
* GitHubCI: Add initial yaml
* WIP: Try r2pm fix
* GitHubCI: Add atombios test
2020-10-01 15:41:39 +02:00
darkreaper-skmc fb7ed81025 Blackfin assembly capability added (#266) ##asm 2020-10-01 15:41:04 +02:00
pancake a9b4f2be6f Move r2wars into its own repo 2020-09-08 16:56:05 +02:00
Sylvain Pelissier dd59385722 Set flags for yara hits (#263) 2020-08-03 12:28:22 +08:00
dependabot[bot] 440147b930 Bump lodash from 4.17.15 to 4.17.19 in /r2jadx (#260)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-07-23 13:47:47 +02:00
s0i37 7d2cdb43dc r2graph script (#261) 2020-07-23 13:47:37 +02:00
Jerome-PSandJerome-PS 70907f1ee4 Improve BA2 analyser (#251)
Co-authored-by: Jerome-PS <Jerome-PS>
2020-07-17 11:03:44 +08:00
pancake d7fc41424b Dont test r2frida in here 2020-07-07 13:45:58 +02:00
Emil Bay 1d54839979 Use unassigned as default print since EVM has an invalid instruction 2020-07-07 11:22:44 +02:00
Emil Bay 5561fe99c3 Add latest evm instructions 2020-07-07 11:22:44 +02:00
정재영 e74a93c4ad patch two stack buffer overflow. In disassembling swf function 2020-07-03 11:25:36 +02:00
정재영 374fa1646f patch Heap overflow 2020-07-03 11:25:36 +02:00
abcSup 8069025044 Fix and refactor pcap r_bin plugin 2020-07-03 11:24:40 +02:00
Jerome-PS d818dba15e Adding support for BA2 CPU (#250) ##asm 2020-06-14 23:55:18 +02:00
pancake 010a1e39b1 Fix build of asm.m68k-net 2020-06-11 15:37:04 +02:00
s0i37andsoier 3167bed57f Static taint analysis (#249)
* added static taint analysis script

* Update readme.md

* added help() and version()

* Update readme.md

* cosmetic

Co-authored-by: soier <soier@work>
2020-06-02 12:24:14 -05:00
Sylvain Pelissier b6acfeef45 Update travis to remove pyc (#248)
pyc was removed with #246 .
2020-05-14 15:03:41 +08:00
FXTi 3fd5cd76cb Remove pyc plugins (#246) 2020-05-13 20:12:42 -05:00
Sylvain Pelissier 86f8c56be8 Support yara versions less than 4.0.0 (#247) 2020-05-09 11:33:21 +02:00
pancake a015f9fe7e Add hexagon.gnu plugin (moved from r2 core) 2020-04-24 11:37:30 +02:00
pancake 792d43b3ba Add .pkgname for swf and pcap plugins 2020-04-24 11:36:08 +02:00
FXTi 8d1c02121a Fix pyc anal plugin (#245) 2020-04-18 20:33:57 +02:00
pancake dc5887818e Release 4.4.0 2020-04-14 04:59:48 +02:00
FXTi ac22c81ada Fix (#243) 2020-04-12 10:50:35 +02:00
pancake 859c307cb5 Optimize travis 2020-04-12 02:04:12 +02:00
pancake 249e782a2e Fix crash in swf 2020-04-12 01:00:37 +02:00
pancake 097a5f56e4 Fix build of the unicorn plugin 2020-04-12 00:51:58 +02:00
FXTi d65bb20b65 .pyc anal plugin (#237)
* Add symbols in pyc's bin
2020-04-12 00:40:21 +02:00
dependabot[bot] e9993f8fdf Bump acorn from 6.1.1 to 6.4.1 in /r2jadx (#239)
Bumps [acorn](https://github.com/acornjs/acorn) from 6.1.1 to 6.4.1.
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.1.1...6.4.1)

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-04-05 01:42:38 +02:00
Itay Cohen db29d60aa9 Merge pull request #238 from sylvainpelissier/yara
Update yara  module according to yara API changes
2020-04-04 17:01:29 +03:00
Sylvain Pelissier e9a74be52c Update yara module according to yara API changes 2020-03-22 18:57:07 +01:00
FXTi 72a43824b1 Correct entries function and fixes (#236) 2020-03-18 00:05:54 +01:00
FXTi 8a5936eb64 Improvement of Bin and Asm of pyc plugin (#235) 2020-03-15 09:00:39 +01:00
pancake e4a73ccf07 Release 4.3.0 2020-03-04 01:25:03 +01:00
Sylvain Pelissier fc564166bd Update test folder to radare2/test and add test for yara in Travis (#233) 2020-03-02 21:36:20 +08:00
pancake 7cc5d343af Enable bcl in travis 2020-03-02 12:24:32 +01:00
pancake 854e6f38ed Fix build of BCL plugins (asm, anal, bin) 2020-03-02 12:23:57 +01:00
Sylvain Pelissier 8da191d171 Add print string option to yara 2020-03-01 20:57:48 +01:00
pancake 2749dedb1e The retdec pkg doesnt needs to be tested by us 2020-02-12 00:25:10 +01:00
pancake 327898bac1 Fix build for pcap and swf 2020-02-12 00:22:22 +01:00
pancake 046efbdae8 Fix more plugins 2020-02-11 15:58:45 +01:00
pancake cc4a103ff3 Fix swf build 2020-02-11 15:53:42 +01:00
pancake b9723c5629 Fix nios build 2020-02-11 15:48:36 +01:00
pancake ae90621fe0 Initial implementation of the r2svd tool 2020-02-11 12:23:20 +01:00
Khairulmizam Samsudin 2e53b36308 Code cleanup 2020-02-06 17:55:28 +01:00
Khairulmizam Samsudin 26838fc56f Implement disassembler for Python >=3.6
- Used architecture bits to diffrentiate Python operand size
- Default to Python >=3.6
2020-02-06 17:55:28 +01:00
Khairulmizam Samsudin 986b99a6fe Implement disassembler for Python <3.6 2020-02-06 17:55:28 +01:00
Khairulmizam Samsudin 4c9a552d06 Change line ending to unix 2020-02-06 17:55:28 +01:00
Khairulmizam Samsudin ef5771f7ce Various fix for section detection (#226)
- Correct pointer offset after finding entry point
- Define the right size for Python object type
- Prevent memory corruption problem when naming section
2020-02-04 17:57:38 +01:00
Sylvain Pelissier 8ba3432f5c Microblaze ESIL load and store with immediate 2020-02-03 15:13:39 +01:00
Sylvain Pelissier 271369f8ee Move RAnalOpMask into parameter 2020-02-03 15:13:39 +01:00
Sylvain Pelissier 145e685c60 Logical instructions with immediate 2020-02-03 15:13:39 +01:00
Sylvain Pelissier 730433360e Microblaze ESIL: handle carry flag 2020-02-03 15:13:39 +01:00
Khairulmizam Samsudin f1f617f791 Implement new method to find entrypoint
- Detect entrypoint for ALL cpython version
- Detection does not depend on correct bytecode magic number
2020-02-02 11:13:26 +01:00
Khairulmizam Samsudin c3d8e433bd Refactor pyc_version struct
- Update latest magic from github.com/python/cpython
- Simplify the structure of pyc_version
- remove unicode information from pyc_version struct
2020-02-02 11:13:26 +01:00
Khairulmizam Samsudin 934c08364f Add base address information 2020-01-28 18:07:58 +01:00
Khairulmizam Samsudin 6e8b2ed5db Fix bytecode version detection 2020-01-28 18:07:58 +01:00
Khairulmizam Samsudin 2434f97937 Replace CORELIB with R2_PLUGIN_INCORE 2020-01-28 18:07:58 +01:00
procfs 3319911179 fix overflow bugs in pyc module 2020-01-27 16:58:39 +01:00
Khairulmizam Samsudin 5eb18b3e3b Disable TYPE_LONG due to dependencies to libgmp 2020-01-27 07:45:37 +01:00
Khairulmizam Samsudin 91eeb7b154 Updated using new RBuffer struct 2020-01-27 07:45:37 +01:00
Khairulmizam Samsudin b01f0180ea Updated using new RBinPlugin struct 2020-01-27 07:45:37 +01:00
Khairulmizam Samsudin 16e27dc9e9 Ignore tags 2020-01-27 07:45:37 +01:00
Sylvain Pelissier 5f6f945498 Microblaze ESIL for shift and sign extension (#216) 2019-10-28 16:53:50 +01:00
pancake 7ec6dbcf88 Release 4.0 2019-10-28 16:52:59 +01:00
pancake bc6d3f36da Import r2ida from https://github.com/radare/radare2ida 2019-10-28 11:03:42 +01:00
Sylvain Pelissier 96d68f14ed Microblaze ESIL update (#215)
* Corrected jumps and remove git messages
* Add ESIL for right shift and correct imm value
* Separate branch with immediate instructions
2019-10-16 12:52:27 +02:00
dependabot[bot] a67e7f0adb Bump lodash from 4.17.11 to 4.17.15 in /r2jadx (#213)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.15.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.15)

Signed-off-by: dependabot[bot] <[email protected]>
2019-10-07 18:24:45 +08:00
dependabot[bot] 7125f795b4 Bump eslint-utils from 1.3.1 to 1.4.2 in /r2jadx (#212)
Bumps [eslint-utils](https://github.com/mysticatea/eslint-utils) from 1.3.1 to 1.4.2.
- [Release notes](https://github.com/mysticatea/eslint-utils/releases)
- [Commits](https://github.com/mysticatea/eslint-utils/compare/v1.3.1...v1.4.2)

Signed-off-by: dependabot[bot] <[email protected]>
2019-10-07 18:24:36 +08:00
Sylvain Pelissier 6ad247901d Update test to use NodeJS 10 (#211) 2019-10-07 17:24:36 +08:00
Maijin 7ecb70cd26 Change radare->radareorg links 2019-10-07 10:53:33 +02:00
Sylvain Pelissier f90380fc23 Improvements for Microblaze ESIL of jump an return operations 2019-10-07 15:53:45 +08:00
Anton Kochkov a0d0c360da Fix urls 2019-10-07 15:48:54 +08:00
Anton Kochkov 80e37a663d Fix urls 2019-10-07 15:48:15 +08:00
pancake fb3c96694e Add checkm8 io plugin 2019-09-30 20:01:56 +02:00
Sylvain Pelissier 2ee3d1153b Microblaze add calls and delay branch (#209) 2019-09-24 20:19:46 +02:00
Sylvain Pelissier 972e774df8 Add Travis CI test for Microblaze and update ESIL (#207) 2019-09-18 14:15:21 +02:00
pancake 4325c5c797 Release 3.9.0 2019-09-17 18:50:05 +02:00
Sylvain Pelissier 738ed6451c Improve Microblaze ESIL ##anal (#206) 2019-09-16 09:36:43 +02:00
Sylvain Pelissier d686d94c0e Correct pointer for r_str_newf function (#205) 2019-09-10 13:25:21 +02:00
Sylvain Pelissier 86a32aa11e Handle negative immediate values in instructions (#204) 2019-09-08 19:09:49 +02:00
pancake 0d830052ad Release 3.7.0 2019-08-01 05:10:31 +02:00
pancake cb31b4c934 Fixes and improvements in cmdline handling and such for r2snow 2019-07-24 12:06:33 +02:00
pancake 78336f4977 More fixes for r2snow 2019-07-24 06:45:43 +02:00
pancake 85f79f83b3 Import snowman output as comments into r2 in r2snow 2019-07-24 04:41:53 +02:00
pancake 940dfec369 More fixes and ipmrovements for r2jadx 2019-07-11 06:45:45 +02:00
pancake 807d1999c0 Update r2pipe dependency for r2jadx 2019-07-10 20:15:31 +02:00
pancake b74f1d306b Lots of improvements for r2jadx! 2019-07-10 12:54:43 +02:00
pancake 3134973ee0 Fix indent and add one more try/catch block 2019-07-09 15:42:37 +02:00
pancake 6993b40789 Use --illegal-access=warn 2019-07-09 15:39:04 +02:00
pancake f54381e411 Add missing md380 Makefile 2019-07-09 15:34:21 +02:00
pancake bd89b33d1a Add ^C message 2019-07-09 15:33:55 +02:00
pancake 96a6b07921 Check for jadx version and use r2pipe.isAvailable() after upgrading dependencies 2019-07-09 15:24:39 +02:00
pancake 05f76e5578 Release 3.6.0 2019-06-24 15:49:47 +02:00
pancake 2e8fac708c Initial working version of r2jadx 2019-06-21 10:27:44 +02:00
pancake c7ffc478e5 Initial implementation of r2jadx 2019-06-16 20:15:02 +02:00
meme c276d25c57 Update <mybfd.h> to reflect the static inlining of bfd_get_bits
https://github.com/radare/radare2/blob/master/libr/asm/arch/include/mybfd.h#L584-L585
2019-06-15 16:35:17 +02:00
dissonant-research c45284dab5 Switching from RIOSection to RIOMap in unicorn debug 2019-05-24 09:27:58 +02:00
pancake e9b20fb9eb Release 3.5.0 2019-05-13 11:18:56 +02:00
pancake cabcd22f39 refix 2019-04-26 00:28:49 +02:00
pancake 65b16c4ea2 Fix build for udis 2019-04-26 00:25:37 +02:00
pancake 32caa03626 Fix bin-md380 crash 2019-04-20 11:48:55 +02:00
pancake 710bd658e3 Implement loadbuffer ni md380 2019-04-20 02:17:43 +02:00
pancake a39b5dfac7 Fix build of md380 bin 2019-04-20 02:15:27 +02:00
pancake 207a4677a1 Initial import of the r2emuhash 2019-04-14 13:35:49 +02:00
pancake 9eb4ca72bb Release 3.4.0 2019-04-01 22:16:24 +02:00
Fedor Sakharov 0459dfa816 fixes trimmed last bytes in disassembly (#195)
Fixes #194
2019-03-10 23:20:46 +08:00
pancake d8517a28ec Fix truncated numbers issue 2019-03-08 19:44:30 +01:00
pancake 5a0cc39fac Release 3.3.0 2019-02-19 14:50:08 +01:00
Andrew Barbarello 5883f35f20 yara-r2: replace r_io_read_at with r_io_pread_at
r_io_read_at is deprecated, and the intention is clearly to read all
bytes of the current file to be scanned with yara rules.
2019-02-17 16:25:15 +01:00
Andrew Barbarello 93f603828e yara-r2: remove unused yara2 sigs/refs to yara2 2019-02-17 16:25:15 +01:00
Andrew Barbarello fdcd534137 yara-r2: install to R2PM_USERPLUGIN_DIR
Makefile was using `R2_PLUGDIR`, which is no longer exported in
environment by `r2pm`, see
https://github.com/radare/radare2/issues/12751 .

Instead, we use `R2PM_USRPLUGIN_DIR`. Also update
`r_cmd_yara_load_default_rules` to load yara3 rules from the correct
path
2019-02-17 16:25:15 +01:00
685 changed files with 650079 additions and 24264 deletions

No files matched your search

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