mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
Merge remote-tracking branch
'origin/GP-5593_ghidorahrex_PR-7985_niooss-ledger_ebpf-fix-semantic-byte-swap-instructions' into patch (Closes #7985)
This commit is contained in:
commit
179263a592
6 changed files with 84 additions and 26 deletions
|
@ -7,4 +7,5 @@ data/languages/eBPF.ldefs||GHIDRA||||END|
|
||||||
data/languages/eBPF.opinion||GHIDRA||||END|
|
data/languages/eBPF.opinion||GHIDRA||||END|
|
||||||
data/languages/eBPF.pspec||GHIDRA||||END|
|
data/languages/eBPF.pspec||GHIDRA||||END|
|
||||||
data/languages/eBPF.sinc||GHIDRA||||END|
|
data/languages/eBPF.sinc||GHIDRA||||END|
|
||||||
|
data/languages/eBPF_be.slaspec||GHIDRA||||END|
|
||||||
data/languages/eBPF_le.slaspec||GHIDRA||||END|
|
data/languages/eBPF_le.slaspec||GHIDRA||||END|
|
||||||
|
|
|
@ -1,5 +1,17 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<language_definitions>
|
<language_definitions>
|
||||||
|
<language processor="eBPF"
|
||||||
|
endian="big"
|
||||||
|
size="64"
|
||||||
|
variant="default"
|
||||||
|
version="1.0"
|
||||||
|
slafile="eBPF_be.sla"
|
||||||
|
processorspec="eBPF.pspec"
|
||||||
|
id="eBPF:BE:64:default">
|
||||||
|
<description>eBPF processor 64-bit big-endian</description>
|
||||||
|
<compiler name="default" spec="eBPF.cspec" id="default"/>
|
||||||
|
<external_name tool="DWARF.register.mapping.file" name="eBPF.dwarf"/>
|
||||||
|
</language>
|
||||||
<language processor="eBPF"
|
<language processor="eBPF"
|
||||||
endian="little"
|
endian="little"
|
||||||
size="64"
|
size="64"
|
||||||
|
@ -10,6 +22,6 @@
|
||||||
id="eBPF:LE:64:default">
|
id="eBPF:LE:64:default">
|
||||||
<description>eBPF processor 64-bit little-endian</description>
|
<description>eBPF processor 64-bit little-endian</description>
|
||||||
<compiler name="default" spec="eBPF.cspec" id="default"/>
|
<compiler name="default" spec="eBPF.cspec" id="default"/>
|
||||||
<external_name tool="DWARF.register.mapping.file" name="eBPF.dwarf"/>
|
<external_name tool="DWARF.register.mapping.file" name="eBPF.dwarf"/>
|
||||||
</language>
|
</language>
|
||||||
</language_definitions>
|
</language_definitions>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<opinions>
|
<opinions>
|
||||||
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
|
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
|
||||||
|
<constraint primary="247" processor="eBPF" endian="big" size="64" />
|
||||||
<constraint primary="247" processor="eBPF" endian="little" size="64" />
|
<constraint primary="247" processor="eBPF" endian="little" size="64" />
|
||||||
</constraint>
|
</constraint>
|
||||||
</opinions>
|
</opinions>
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
# eBPF Processor Specification for Ghidra
|
# eBPF Processor Specification for Ghidra
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
define endian=$(ENDIAN);
|
||||||
|
|
||||||
#eBPF is a RISC register machine with a total of 11 64-bit registers, a program counter and a 512 byte fixed-size stack.
|
#eBPF is a RISC register machine with a total of 11 64-bit registers, a program counter and a 512 byte fixed-size stack.
|
||||||
#9 registers are general purpose read-write, one is a read-only stack pointer and the program counter is implicit,
|
#9 registers are general purpose read-write, one is a read-only stack pointer and the program counter is implicit,
|
||||||
#i.e. we can only jump to a certain offset from it. The eBPF registers are always 64-bit wide.
|
#i.e. we can only jump to a certain offset from it. The eBPF registers are always 64-bit wide.
|
||||||
|
@ -13,6 +15,7 @@ define space syscall type=ram_space size=4;
|
||||||
define register offset=0 size=8 [ R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 PC ];
|
define register offset=0 size=8 [ R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 PC ];
|
||||||
|
|
||||||
# Instruction encoding: Insop:8, dst_reg:4, src_reg:4, off:16, imm:32 - from lsb to msb
|
# Instruction encoding: Insop:8, dst_reg:4, src_reg:4, off:16, imm:32 - from lsb to msb
|
||||||
|
@if ENDIAN == "little"
|
||||||
define token instr(64)
|
define token instr(64)
|
||||||
imm=(32, 63) signed
|
imm=(32, 63) signed
|
||||||
off=(16, 31) signed
|
off=(16, 31) signed
|
||||||
|
@ -29,6 +32,23 @@ define token instr(64)
|
||||||
define token immtoken(64)
|
define token immtoken(64)
|
||||||
imm2=(32, 63)
|
imm2=(32, 63)
|
||||||
;
|
;
|
||||||
|
@else # ENDIAN == "big"
|
||||||
|
define token instr(64)
|
||||||
|
imm=(0, 31) signed
|
||||||
|
off=(32, 47) signed
|
||||||
|
src=(48, 51)
|
||||||
|
dst=(52, 55)
|
||||||
|
op_insn_class=(56, 58)
|
||||||
|
op_ld_st_size=(59, 60)
|
||||||
|
op_ld_st_mode=(61, 63)
|
||||||
|
op_alu_jmp_source=(59, 59)
|
||||||
|
op_alu_jmp_opcode=(60, 63)
|
||||||
|
;
|
||||||
|
|
||||||
|
define token immtoken(64)
|
||||||
|
imm2=(0, 31)
|
||||||
|
;
|
||||||
|
@endif # ENDIAN = "big"
|
||||||
|
|
||||||
#To operate with registers
|
#To operate with registers
|
||||||
attach variables [ src dst ] [ R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 _ _ _ _ _ ];
|
attach variables [ src dst ] [ R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 _ _ _ _ _ ];
|
||||||
|
@ -104,33 +124,54 @@ DST4: dst is dst { local tmp:4 = dst:4; export tmp; }
|
||||||
|
|
||||||
#Bytewasp instructions
|
#Bytewasp instructions
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@if ENDIAN == "little"
|
||||||
# BPF_ALU | BPF_K | BPF_END
|
# BPF_ALU | BPF_K | BPF_END
|
||||||
:LE16 dst is imm=0x10 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x4 { dst=((dst) >> 8) | ((dst) << 8); }
|
:LE16 dst is imm=0x10 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:2); }
|
||||||
:LE32 dst is imm=0x20 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x4 { dst=((dst) >> 24) | (((dst) & 0x00FF0000) >> 8) | (((dst) & 0x0000FF00) << 8) | ((dst) << 24); }
|
:LE32 dst is imm=0x20 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4); }
|
||||||
|
:LE64 dst is imm=0x40 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x4 {}
|
||||||
|
|
||||||
|
# BPF_ALU | BPF_X | BPF_END
|
||||||
|
:BE16 dst is imm=0x10 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x4 {
|
||||||
|
dst = ((dst & 0xff00) >> 8) | ((dst & 0x00ff) << 8);
|
||||||
|
}
|
||||||
|
:BE32 dst is imm=0x20 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x4 {
|
||||||
|
dst = ((dst & 0xff000000) >> 24) | (((dst) & 0x00ff0000) >> 8) | (((dst) & 0x0000ff00) << 8) | ((dst & 0x000000ff) << 24);
|
||||||
|
}
|
||||||
|
:BE64 dst is imm=0x40 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x4 {
|
||||||
|
dst = ((dst << 56) & 0xff00000000000000) |
|
||||||
|
((dst << 40) & 0x00ff000000000000) |
|
||||||
|
((dst << 24) & 0x0000ff0000000000) |
|
||||||
|
((dst << 8) & 0x000000ff00000000) |
|
||||||
|
((dst >> 8) & 0x00000000ff000000) |
|
||||||
|
((dst >> 24) & 0x0000000000ff0000) |
|
||||||
|
((dst >> 40) & 0x000000000000ff00) |
|
||||||
|
((dst >> 56) & 0x00000000000000ff);
|
||||||
|
}
|
||||||
|
@else # ENDIAN == "big"
|
||||||
|
# BPF_ALU | BPF_K | BPF_END
|
||||||
|
:LE16 dst is imm=0x10 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x4 {
|
||||||
|
dst = ((dst & 0xff00) >> 8) | ((dst & 0x00ff) << 8);
|
||||||
|
}
|
||||||
|
:LE32 dst is imm=0x20 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x4 {
|
||||||
|
dst = ((dst & 0xff000000) >> 24) | (((dst) & 0x00ff0000) >> 8) | (((dst) & 0x0000ff00) << 8) | ((dst & 0x000000ff) << 24);
|
||||||
|
}
|
||||||
:LE64 dst is imm=0x40 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x4 {
|
:LE64 dst is imm=0x40 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x4 {
|
||||||
dst=( (dst << 56) & 0xff00000000000000 ) |
|
dst = ((dst << 56) & 0xff00000000000000) |
|
||||||
( (dst << 40) & 0x00ff000000000000 ) |
|
((dst << 40) & 0x00ff000000000000) |
|
||||||
( (dst << 24) & 0x0000ff0000000000 ) |
|
((dst << 24) & 0x0000ff0000000000) |
|
||||||
( (dst << 8) & 0x000000ff00000000 ) |
|
((dst << 8) & 0x000000ff00000000) |
|
||||||
( (dst >> 8) & 0x00000000ff000000 ) |
|
((dst >> 8) & 0x00000000ff000000) |
|
||||||
( (dst >> 24) & 0x0000000000ff0000 ) |
|
((dst >> 24) & 0x0000000000ff0000) |
|
||||||
( (dst >> 40) & 0x000000000000ff00 ) |
|
((dst >> 40) & 0x000000000000ff00) |
|
||||||
( (dst >> 56) & 0x00000000000000ff );
|
((dst >> 56) & 0x00000000000000ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
# BPF_ALU | BPF_X | BPF_END
|
# BPF_ALU | BPF_X | BPF_END
|
||||||
:BE16 dst is imm=0x10 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x4 { dst=((dst) >> 8) | ((dst) << 8); }
|
:BE16 dst is imm=0x10 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:2); }
|
||||||
:BE32 dst is imm=0x20 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x4 { dst=((dst) >> 24) | (((dst) & 0x00FF0000) >> 8) | (((dst) & 0x0000FF00) << 8) | ((dst) << 24); }
|
:BE32 dst is imm=0x20 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4); }
|
||||||
:BE64 dst is imm=0x40 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x4 {
|
:BE64 dst is imm=0x40 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x4 {}
|
||||||
dst=( (dst << 56) & 0xff00000000000000 ) |
|
@endif # ENDIAN = "big"
|
||||||
( (dst << 40) & 0x00ff000000000000 ) |
|
|
||||||
( (dst << 24) & 0x0000ff0000000000 ) |
|
|
||||||
( (dst << 8) & 0x000000ff00000000 ) |
|
|
||||||
( (dst >> 8) & 0x00000000ff000000 ) |
|
|
||||||
( (dst >> 24) & 0x0000000000ff0000 ) |
|
|
||||||
( (dst >> 40) & 0x000000000000ff00 ) |
|
|
||||||
( (dst >> 56) & 0x00000000000000ff );
|
|
||||||
}
|
|
||||||
|
|
||||||
#Memory instructions - Load and Store
|
#Memory instructions - Load and Store
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
3
Ghidra/Processors/eBPF/data/languages/eBPF_be.slaspec
Normal file
3
Ghidra/Processors/eBPF/data/languages/eBPF_be.slaspec
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@define ENDIAN "big"
|
||||||
|
|
||||||
|
@include "eBPF.sinc"
|
|
@ -1,3 +1,3 @@
|
||||||
define endian=little;
|
@define ENDIAN "little"
|
||||||
|
|
||||||
@include "eBPF.sinc"
|
@include "eBPF.sinc"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue