From b0716c7a2910ab8f2c290535522b1867cfddcb6f Mon Sep 17 00:00:00 2001 From: Heurs Date: Tue, 17 May 2022 14:48:05 +0200 Subject: [PATCH] New processor for BPF bytecode delete and rename after review --- Ghidra/Processors/BPF/Module.manifest | 1 + .../Processors/BPF/data/languages/BPF.cspec | 44 +++++ .../Processors/BPF/data/languages/BPF.ldefs | 15 ++ .../Processors/BPF/data/languages/BPF.pspec | 8 + Ghidra/Processors/BPF/data/languages/BPF.sinc | 184 ++++++++++++++++++ .../BPF/data/languages/BPF_le.slaspec | 3 + 6 files changed, 255 insertions(+) create mode 100644 Ghidra/Processors/BPF/Module.manifest create mode 100644 Ghidra/Processors/BPF/data/languages/BPF.cspec create mode 100644 Ghidra/Processors/BPF/data/languages/BPF.ldefs create mode 100644 Ghidra/Processors/BPF/data/languages/BPF.pspec create mode 100644 Ghidra/Processors/BPF/data/languages/BPF.sinc create mode 100644 Ghidra/Processors/BPF/data/languages/BPF_le.slaspec diff --git a/Ghidra/Processors/BPF/Module.manifest b/Ghidra/Processors/BPF/Module.manifest new file mode 100644 index 0000000000..8d1c8b69c3 --- /dev/null +++ b/Ghidra/Processors/BPF/Module.manifest @@ -0,0 +1 @@ + diff --git a/Ghidra/Processors/BPF/data/languages/BPF.cspec b/Ghidra/Processors/BPF/data/languages/BPF.cspec new file mode 100644 index 0000000000..80c72d9cf4 --- /dev/null +++ b/Ghidra/Processors/BPF/data/languages/BPF.cspec @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ghidra/Processors/BPF/data/languages/BPF.ldefs b/Ghidra/Processors/BPF/data/languages/BPF.ldefs new file mode 100644 index 0000000000..d2c8dcf4f3 --- /dev/null +++ b/Ghidra/Processors/BPF/data/languages/BPF.ldefs @@ -0,0 +1,15 @@ + + + + BPF processor 32-bit little-endian + + + + diff --git a/Ghidra/Processors/BPF/data/languages/BPF.pspec b/Ghidra/Processors/BPF/data/languages/BPF.pspec new file mode 100644 index 0000000000..387831da41 --- /dev/null +++ b/Ghidra/Processors/BPF/data/languages/BPF.pspec @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Ghidra/Processors/BPF/data/languages/BPF.sinc b/Ghidra/Processors/BPF/data/languages/BPF.sinc new file mode 100644 index 0000000000..c843c9f151 --- /dev/null +++ b/Ghidra/Processors/BPF/data/languages/BPF.sinc @@ -0,0 +1,184 @@ +############################################################################### +# BPF Processor Specification for Ghidra +############################################################################### + +define space ram type=ram_space size=4 default; +define space packet type=ram_space size=4; +define space mem type=ram_space size=4; +define space register type=register_space size=4; + +define register offset=0 size=4 [ A X RS R PC ]; +define register offset=0 size=2 [ AH _ XH _ RSH _ RH _ PCH _ ]; +define register offset=0 size=1 [ AB _ _ _ XB _ _ _ RSB _ _ _ RB _ _ _ PCB _ _ _ ]; + +# Instruction encoding: Insop:8, dst_reg:4, src_reg:4, off:16, imm:32 - from lsb to msb +define token instr(64) + imm=(32, 63) + jf=(24, 31) signed + jt=(16, 23) signed + op_src_K_X=(3, 3) + op_alu_jmp_opcode=(4, 7) + op_alu_jmp_source=(3, 3) + op_alu_mode=(4, 7) + op_ld_st_mode=(5, 7) + op_ld_st_size=(3, 4) + op_insn_class=(0, 2) +; + +:LD imm is imm & op_ld_st_mode=0x0 & op_ld_st_size=0x0 & op_insn_class=0x0 { A=imm; } +:LDH imm is imm & op_ld_st_mode=0x0 & op_ld_st_size=0x1 & op_insn_class=0x0 { AH=imm:2; A = A & 0xffff; } +:LDB imm is imm & op_ld_st_mode=0x0 & op_ld_st_size=0x2 & op_insn_class=0x0 { AB=imm:1; A = A & 0xff;} + +:LDX imm is imm & op_ld_st_mode=0x0 & op_ld_st_size=0x0 & op_insn_class=0x1 { X=imm; } +:LDXH imm is imm & op_ld_st_mode=0x0 & op_ld_st_size=0x1 & op_insn_class=0x1 { XH=imm:2; X = X & 0xffff; } +:LDXB imm is imm & op_ld_st_mode=0x0 & op_ld_st_size=0x2 & op_insn_class=0x1 { XB=imm:1; X = X & 0xff;} + +:LD imm is imm & op_ld_st_mode=0x1 & op_ld_st_size=0x0 & op_insn_class=0x0 { A=*[packet]:4 imm:4; } +:LDH imm is imm & op_ld_st_mode=0x1 & op_ld_st_size=0x1 & op_insn_class=0x0 { A=*[packet]:2 imm:4; A = A & 0xffff; } +:LDB imm is imm & op_ld_st_mode=0x1 & op_ld_st_size=0x2 & op_insn_class=0x0 { A=*[packet]:1 imm:4; A = A & 0xff;} + +:LDX imm is imm & op_ld_st_mode=0x1 & op_ld_st_size=0x0 & op_insn_class=0x1 { X=*[packet]:4 imm:4; } +:LDXH imm is imm & op_ld_st_mode=0x1 & op_ld_st_size=0x1 & op_insn_class=0x1 { X=*[packet]:2 imm:4; X = X & 0xffff; } +:LDXB imm is imm & op_ld_st_mode=0x1 & op_ld_st_size=0x2 & op_insn_class=0x1 { X=*[packet]:1 imm:4; X = X & 0xff;} + +:ST imm is imm & op_insn_class=0x2 { *[mem]:4 imm:4=A:4; } +:STX imm is imm & op_insn_class=0x3 { *[mem]:4 imm:4=X:4; } + +:LDI imm is imm & op_ld_st_mode=0x2 & op_ld_st_size=0x0 & op_insn_class=0x0 { A=*[packet]:4 (imm:4 + X); } +:LDIH imm is imm & op_ld_st_mode=0x2 & op_ld_st_size=0x1 & op_insn_class=0x0 { A=*[packet]:2 (imm:4 + X); A = A & 0xffff; } +:LDIB imm is imm & op_ld_st_mode=0x2 & op_ld_st_size=0x2 & op_insn_class=0x0 { A=*[packet]:1 (imm:4 + X); A = A & 0xff; } + +:LD imm is imm & op_ld_st_mode=0x3 & op_ld_st_size=0x0 & op_insn_class=0x0 { A=*[mem]:4 imm:4; } +:LDH imm is imm & op_ld_st_mode=0x3 & op_ld_st_size=0x1 & op_insn_class=0x0 { A=*[mem]:2 imm:4; A = A & 0xffff; } +:LDB imm is imm & op_ld_st_mode=0x3 & op_ld_st_size=0x2 & op_insn_class=0x0 { A=*[mem]:1 imm:4; A = A & 0xff; } + +:LDX imm is imm & op_ld_st_mode=0x3 & op_ld_st_size=0x0 & op_insn_class=0x1 { X=*[mem]:4 imm:4; } +:LDXH imm is imm & op_ld_st_mode=0x3 & op_ld_st_size=0x1 & op_insn_class=0x1 { X=*[mem]:2 imm:4; X = X & 0xffff; } +:LDXB imm is imm & op_ld_st_mode=0x3 & op_ld_st_size=0x2 & op_insn_class=0x1 { X=*[mem]:1 imm:4; X = X & 0xff; } + +# ALU +:ADD imm is imm & op_alu_mode=0x0 & op_insn_class=0x4 & op_src_K_X = 0x0 { A= A + imm; } +:ADD X is X & op_alu_mode=0x0 & op_insn_class=0x4 & op_src_K_X = 0x1 { A= A + X; } +:SUB imm is imm & op_alu_mode=0x1 & op_insn_class=0x4 & op_src_K_X = 0x0 { A= A - imm; } +:SUB X is X & op_alu_mode=0x1 & op_insn_class=0x4 & op_src_K_X = 0x1 { A= A - X; } +:MUL imm is imm & op_alu_mode=0x2 & op_insn_class=0x4 & op_src_K_X = 0x0 { A= A * imm; } +:MUL X is X & op_alu_mode=0x2 & op_insn_class=0x4 & op_src_K_X = 0x1 { A= A * X; } +:DIV imm is imm & op_alu_mode=0x3 & op_insn_class=0x4 & op_src_K_X = 0x0 { A= A / imm; } +:DIV X is X & op_alu_mode=0x3 & op_insn_class=0x4 & op_src_K_X = 0x1 { A= A / X; } +:OR imm is imm & op_alu_mode=0x4 & op_insn_class=0x4 & op_src_K_X = 0x0 { A= A | imm; } +:OR X is X & op_alu_mode=0x4 & op_insn_class=0x4 & op_src_K_X = 0x1 { A= A | X; } +:AND imm is imm & op_alu_mode=0x5 & op_insn_class=0x4 & op_src_K_X = 0x0 { A= A & imm; } +:AND X is X & op_alu_mode=0x5 & op_insn_class=0x4 & op_src_K_X = 0x1 { A= A & X; } +:LSH imm is imm & op_alu_mode=0x6 & op_insn_class=0x4 & op_src_K_X = 0x0 { A= A << imm; } +:LSH X is X & op_alu_mode=0x6 & op_insn_class=0x4 & op_src_K_X = 0x1 { A= A << X; } +:RSH imm is imm & op_alu_mode=0x7 & op_insn_class=0x4 & op_src_K_X = 0x0 { A= A >> imm; } +:RSH X is X & op_alu_mode=0x7 & op_insn_class=0x4 & op_src_K_X = 0x1 { A= A >> X; } +:NEG is op_alu_mode=0x8 & op_insn_class=0x4 & op_src_K_X = 0x0 { A= -A; } +:MOD imm is imm & op_alu_mode=0x9 & op_insn_class=0x4 & op_src_K_X = 0x0 { A= A % imm; } +:MOD X is X & op_alu_mode=0x9 & op_insn_class=0x4 & op_src_K_X = 0x1 { A= A % X; } +:XOR imm is imm & op_alu_mode=0xa & op_insn_class=0x4 & op_src_K_X = 0x0 { A= A ^ imm; } +:XOR X is X & op_alu_mode=0xa & op_insn_class=0x4 & op_src_K_X = 0x1 { A= A ^ X; } + +:TAX is op_insn_class=0x7 & op_src_K_X = 0x0 { A= X; } +:TXA is op_insn_class=0x7 & op_src_K_X = 0x1 { X= A; } + + +:LD_MSH imm is imm & op_ld_st_mode=0x5 & op_ld_st_size=0x0 & op_insn_class=0x0 { + local t_val = *[packet]:4 imm:4; + t_val = t_val&0xf; + t_val = t_val << 2; + A = t_val; +} + +:LDH_MSH imm is imm & op_ld_st_mode=0x5 & op_ld_st_size=0x1 & op_insn_class=0x0 { + local t_val = *[packet]:2 imm:4; + t_val = t_val&0xf; + t_val = t_val << 2; + AH = t_val; +} + +:LDB_MSH imm is imm & op_ld_st_mode=0x5 & op_ld_st_size=0x2 & op_insn_class=0x0 { + local t_val = *[packet]:1 imm:4; + t_val = t_val&0xf; + t_val = t_val << 2; + AB = t_val; +} + +:LDX_MSH imm is imm & op_ld_st_mode=0x5 & op_ld_st_size=0x0 & op_insn_class=0x1 { + local t_val = *[packet]:4 imm:4; + t_val = t_val&0xf; + t_val = t_val << 2; + X = t_val; +} + +:LDXH_MSH imm is imm & op_ld_st_mode=0x5 & op_ld_st_size=0x1 & op_insn_class=0x1 { + local t_val = *[packet]:2 imm:4; + t_val = t_val&0xf; + t_val = t_val << 2; + XH = t_val; + X = X & 0xffff; +} + +:LDXB_MSH imm is imm & op_ld_st_mode=0x5 & op_ld_st_size=0x2 & op_insn_class=0x1 { + local t_val = *[packet]:1 imm:4; + t_val = t_val&0xf; + t_val = t_val << 2; + XB = t_val; + X = X & 0xff; +} + +#Branch instructions +############################################################################### + +joff: reloc is imm [ reloc = inst_next + imm * 8; ] { export *:8 reloc; } +jtoff: reloc is jt [ reloc = inst_next + jt * 8; ] { export *:8 reloc; } +jfoff: reloc is jf [ reloc = inst_next + jf * 8; ] { export *:8 reloc; } + +:JA joff is joff & op_alu_jmp_opcode=0x0 & op_alu_jmp_source=0 & op_insn_class=0x5 { + goto joff; +} + +:JEQ jtoff, jfoff, imm is imm & jtoff & jfoff & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=0 & op_insn_class=0x5 { + if (A==imm) goto jtoff; + goto jfoff; +} + +:JEQ jtoff, jfoff, X is X & jtoff & jfoff & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=1 & op_insn_class=0x5 { + if (A==X) goto jtoff; + goto jfoff; +} + +:JGT jtoff, jfoff, imm is imm & jtoff & jfoff & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=0 & op_insn_class=0x5 { + if (A > imm) goto jtoff; + goto jfoff; +} + +:JGT jtoff, jfoff, X is X & jtoff & jfoff & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=1 & op_insn_class=0x5 { + if (A > X) goto jtoff; + goto jfoff; +} + +:JGE jtoff, jfoff, imm is imm & jtoff & jfoff & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=0 & op_insn_class=0x5 { + if (A >= imm) goto jtoff; + goto jfoff; +} + +:JGE jtoff, jfoff, X is X & jtoff & jfoff & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=1 & op_insn_class=0x5 { + if (A >= X) goto jtoff; + goto jfoff; +} + +:JSET jtoff, jfoff, imm is imm & jtoff & jfoff & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=0 & op_insn_class=0x5 { + if ((A&imm) != 0) goto jtoff; + goto jfoff; +} + +:JSET jtoff, jfoff, X is X & jtoff & jfoff & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=1 & op_insn_class=0x5 { + if ((A&X) != 0) goto jtoff; + goto jfoff; +} + +:RETW imm is imm & op_ld_st_size=0 & op_insn_class=0x6 { + R = imm; + return [*:8 RS]; +} diff --git a/Ghidra/Processors/BPF/data/languages/BPF_le.slaspec b/Ghidra/Processors/BPF/data/languages/BPF_le.slaspec new file mode 100644 index 0000000000..479e11ea67 --- /dev/null +++ b/Ghidra/Processors/BPF/data/languages/BPF_le.slaspec @@ -0,0 +1,3 @@ +define endian=little; + +@include "BPF.sinc" \ No newline at end of file