Repository: Nalen98/eBPF-for-Ghidra Branch: master Commit: 69f6ea89fecd Files: 20 Total size: 117.8 KB Directory structure: gitextract_aren7096/ ├── .gitignore ├── LICENSE ├── Module.manifest ├── README.md ├── build.gradle ├── data/ │ ├── build.xml │ ├── languages/ │ │ ├── eBPF.cspec │ │ ├── eBPF.dwarf │ │ ├── eBPF.ldefs │ │ ├── eBPF.opinion │ │ ├── eBPF.pspec │ │ ├── eBPF.sinc │ │ └── eBPF.slaspec │ └── sleighArgs.txt ├── extension.properties └── src/ └── main/ └── java/ └── ghidra/ └── app/ ├── plugin/ │ └── core/ │ └── analysis/ │ └── eBPFAnalyzer.java └── util/ └── bin/ └── format/ └── elf/ ├── extend/ │ └── eBPF_ElfExtension.java └── relocation/ ├── ElfeBPFRelocationFixupHandler.java ├── eBPF_ElfRelocationConstants.java └── eBPF_ElfRelocationHandler.java ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .gradle build dist ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2019 Nalen98 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Module.manifest ================================================ ================================================ FILE: README.md ================================================ # eBPF processor for Ghidra The extension implements eBPF architecture support for Ghidra and allows for disassembly and decompilation of eBPF programs. # Warning: eBPF is included in Ghidra since Ghidra 10.3 **Since May 2023, [eBPF-for-Ghidra](https://github.com/Nalen98/eBPF-for-Ghidra) has been included in the official [NationalSecurityAgency/Ghidra](https://github.com/NationalSecurityAgency/ghidra) repository**. You can get the latest updates and fixes for the [eBPF module](https://github.com/NationalSecurityAgency/ghidra/tree/70405b07b0b857d433dfec77ae5c343997f589eb/Ghidra/Processors/eBPF) directly in Ghidra. This repo may be archived in the future. # Examples Example of eBPF program you can get [here](https://github.com/vbpf/ebpf-samples). ![eBPF Extension](./images/eBPF.gif) Example of disassembling and decompiling of eBPF: ![Example of decompiling](./images/Main.png) # Installation - Download Release version of extension and install it in Ghidra `File → Install Extensions...` - Use gradle to build extension: `GHIDRA_INSTALL_DIR=${GHIDRA_HOME} gradle` and use Ghidra to install it: `File → Install Extensions...` - Clone this repository to `\Ghidra\Extensions` directory. # Updates 03.09.2019 — eBPF maps implementation, custom relocation handler was implemented ![](./images/eBPFMaps.png) 19.09.2019 — problem with stack [is resolved](https://github.com/Nalen98/eBPF-for-Ghidra/issues/2#issuecomment-533263382) 20.09.2019 — eBPF call-helpers are implemented as syscalls, added helper's signature through custom eBPFAnalyzer ![](./images/eBPFSyscalls.png) 23.09.2019 — bad bookmarks fixed ![](./images/GoodBookmarks.png) 01.12.2020 — new eBPF-helpers added 23.06.2022 — added support for relative calls (`R_BPF_64_32` relocation type). Thanks [@cnwangjihe](https://github.com/cnwangjihe) for this [idea](https://github.com/Nalen98/eBPF-for-Ghidra/pull/10). `imm` of call instruction where `bpf_call->src_reg == BPF_PSEUDO_CALL` now contains the relative offset to target function. Before: ![image](https://user-images.githubusercontent.com/52778977/175531695-bb059f0c-9f6e-4346-87fa-eaa9c0e6a45a.png) After: ![](./images/RelativeCalls.png) 24.06.2022 — making the [Pull Request](https://github.com/NationalSecurityAgency/ghidra/pull/4378) to official [Ghidra](https://github.com/NationalSecurityAgency/ghidra) repository as the main supplier of the eBPF processor 19.12.2022 — added support for BPF_ATOMIC operations, ALU32 instructions added, BPF_JMP32 instructions added, JSET instruction fixed 03.05.2023 — eBPF processor support added to the Ghidra official repository in the commit [506ca1e](https://github.com/NationalSecurityAgency/ghidra/commit/79102c13c48b56e8173a0754d2804f4fe25adf22) Starting from Ghidra 10.3, the eBPF module is included by default in Ghidra. There's no need to build this project and add it as a Ghidra extension anymore. For users of older versions of Ghidra, the eBPF module can still be accessed through existing [Releases](https://github.com/Nalen98/eBPF-for-Ghidra/releases/tag/v0.2). # Useful links * [Official kernel documentation](https://www.kernel.org/doc/Documentation/networking/filter.txt) * [Official kernel documentation - questions](https://www.kernel.org/doc/html/latest/bpf/bpf_design_QA.html) * [eBPF programs to test in Ghidra](https://github.com/vbpf/ebpf-samples) * [Simple eBPF disassembler in Rust](https://github.com/badboy/ebpf-disasm) * [Rust virtual machine and JIT compiler for eBPF programs](https://github.com/qmonnet/rbpf) * [eBPF helpers (all)](https://github.com/torvalds/linux/blob/v5.17/include/uapi/linux/bpf.h#L2619) * [eBPF overview](https://www.collabora.com/news-and-blog/blog/2019/04/05/an-ebpf-overview-part-1-introduction/) ================================================ FILE: build.gradle ================================================ // Builds a Ghidra Extension for a given Ghidra installation. // // An absolute path to the Ghidra installation directory must be supplied either by setting the // GHIDRA_INSTALL_DIR environment variable or Gradle project property: // // > export GHIDRA_INSTALL_DIR= // > gradle // // or // // > gradle -PGHIDRA_INSTALL_DIR= // // Gradle should be invoked from the directory of the project to build. Please see the // application.gradle.version property in /Ghidra/application.properties // for the correction version of Gradle to use for the Ghidra installation you specify. //----------------------START "DO NOT MODIFY" SECTION------------------------------ def ghidraInstallDir if (System.env.GHIDRA_INSTALL_DIR) { ghidraInstallDir = System.env.GHIDRA_INSTALL_DIR } else if (project.hasProperty("GHIDRA_INSTALL_DIR")) { ghidraInstallDir = project.getProperty("GHIDRA_INSTALL_DIR") } if (ghidraInstallDir) { apply from: new File(ghidraInstallDir).getCanonicalPath() + "/support/buildExtension.gradle" } else { throw new GradleException("GHIDRA_INSTALL_DIR is not defined!") } //----------------------END "DO NOT MODIFY" SECTION------------------------------- ================================================ FILE: data/build.xml ================================================ ================================================ FILE: data/languages/eBPF.cspec ================================================ ================================================ FILE: data/languages/eBPF.dwarf ================================================ ================================================ FILE: data/languages/eBPF.ldefs ================================================ eBPF processor 64-bit little-endian ================================================ FILE: data/languages/eBPF.opinion ================================================ ================================================ FILE: data/languages/eBPF.pspec ================================================ ================================================ FILE: data/languages/eBPF.sinc ================================================ ############################################################################### # eBPF Processor Specification for Ghidra ############################################################################### #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 purpouse 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. define space ram type=ram_space size=8 default; define space register type=register_space size=4; 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 ]; # 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) signed off=(16, 31) signed src=(12, 15) dst=(8, 11) op_alu_jmp_opcode=(4, 7) op_alu_jmp_source=(3, 3) op_ld_st_mode=(5, 7) op_ld_st_size=(3, 4) op_insn_class=(0, 2) ; #We'll need this token to operate with LDDW instruction, which has 64 bit imm value define token immtoken(64) imm2=(32, 63) ; #To operate with registers attach variables [ src dst ] [ R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 _ _ _ _ _ ]; #Arithmetic instructions #BPF_ALU64 ############################################################################### :MOV dst, src is src & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = src; } :MOV dst, imm is imm & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = imm; } :ADD dst, src is src & dst & op_alu_jmp_opcode=0x0 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst + src; } :ADD dst, imm is imm & dst & op_alu_jmp_opcode=0x0 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst + imm; } :SUB dst, src is src & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst - src; } :SUB dst, imm is imm & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst - imm; } :MUL dst, src is src & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst * src; } :MUL dst, imm is imm & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst * imm; } :DIV dst, src is src & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst / src; } :DIV dst, imm is imm & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst / imm; } :OR dst, src is src & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst | src; } :OR dst, imm is imm & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst | imm; } :AND dst, src is src & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst & src; } :AND dst, imm is imm & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst & imm; } :LSH dst, src is src & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst << src; } :LSH dst, imm is imm & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst << imm; } :RSH dst, src is src & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst >> src; } :RSH dst, imm is imm & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst >> imm; } :NEG dst is dst & op_alu_jmp_opcode=0x8 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = -dst; } :MOD dst, src is src & dst & op_alu_jmp_opcode=0x9 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst % src; } :MOD dst, imm is imm & dst & op_alu_jmp_opcode=0x9 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst % imm; } :XOR dst, src is src & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst ^ src; } :XOR dst, imm is imm & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst ^ imm; } :ARSH dst, src is src & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst s>> src; } :ARSH dst, imm is imm & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst s>> imm; } #BPF_ALU ############################################################################### :MOV dst, src is src & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(src:4); } :MOV dst, imm is imm & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = imm; } :ADD dst, src is src & dst & op_alu_jmp_opcode=0x0 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 + src:4); } :ADD dst, imm is imm & dst & op_alu_jmp_opcode=0x0 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 + imm); } :SUB dst, src is src & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 - src:4); } :SUB dst, imm is imm & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 - imm); } :MUL dst, src is src & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 * src:4); } :MUL dst, imm is imm & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 * imm); } :DIV dst, src is src & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 / src:4); } :DIV dst, imm is imm & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 / imm); } :OR dst, src is src & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 | src:4); } :OR dst, imm is imm & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 | imm); } :AND dst, src is src & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 & src:4); } :AND dst, imm is imm & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 & imm); } :LSH dst, src is src & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 << src:4); } :LSH dst, imm is imm & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 << imm); } :RSH dst, src is src & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 >> src:4); } :RSH dst, imm is imm & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 >> imm); } :NEG dst is dst & op_alu_jmp_opcode=0x8 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(-dst:4); } :MOD dst, src is src & dst & op_alu_jmp_opcode=0x9 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 % src:4); } :MOD dst, imm is imm & dst & op_alu_jmp_opcode=0x9 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 % imm); } :XOR dst, src is src & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 ^ src:4); } :XOR dst, imm is imm & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 ^ imm); } :ARSH dst, src is src & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 s>> src:4); } :ARSH dst, imm is imm & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 s>> imm); } #Bytewasp instructions ############################################################################### # 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); } :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); } :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 << 40) & 0x00ff000000000000 ) | ( (dst << 24) & 0x0000ff0000000000 ) | ( (dst << 8) & 0x000000ff00000000 ) | ( (dst >> 8) & 0x00000000ff000000 ) | ( (dst >> 24) & 0x0000000000ff0000 ) | ( (dst >> 40) & 0x000000000000ff00 ) | ( (dst >> 56) & 0x00000000000000ff ); } # 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); } :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); } :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 ); } #Memory instructions - Load and Store ############################################################################### #LDDW is the only 16-byte eBPF instruction which consists of two consecutive 8-byte blocks ('struct bpf_insn') #and interpreted as single instruction which loads 64-bit imm value into dst. Encoding of LDDW: #LSR MSR # opcode src dst offset Low 8-byte imm zero-block High 8-byte imm #bits 8 4 4 16 32 32 32 # So, imm64 consists of concatination of high 8-byte imm and low 8-byte imm. :LDDW dst, concat is imm & dst & op_ld_st_mode=0x0 & op_ld_st_size=0x3 & op_insn_class=0x0; imm2 [ concat= (imm2 << 32) | ((imm) & 0xFFFFFFFF); ] { dst = concat; } #BPF_LD_MAP_FD(DST, MAP_FD) -> second LDDW = pseudo LDDW insn used to refer to process-local map_fd #For each instruction which needs relocation, it inject corresponding file descriptor to imm field. #As a part of protocol, src_reg is set to BPF_PSEUDO_MAP_FD (which defined as 1) to notify kernel this is a map loading instruction. :LDDW dst, imm is imm & src=1 & dst & op_ld_st_mode=0x0 & op_ld_st_size=0x3 & op_insn_class=0x0; imm2 { dst = *:8 imm:8; } :LDABSW dst, imm is imm & dst & op_ld_st_mode=0x1 & op_ld_st_size=0x0 & op_insn_class=0x0 { dst=*:4 imm:8; } :LDABSH dst, imm is imm & dst & op_ld_st_mode=0x1 & op_ld_st_size=0x1 & op_insn_class=0x0 { dst=*:2 imm:8; } :LDABSB dst, imm is imm & dst & op_ld_st_mode=0x1 & op_ld_st_size=0x2 & op_insn_class=0x0 { dst=*:1 imm:8; } :LDABSDW dst, imm is imm & dst & op_ld_st_mode=0x1 & op_ld_st_size=0x3 & op_insn_class=0x0 { dst=*:8 imm:8; } :LDINDW src, dst, imm is imm & src & dst & op_ld_st_mode=0x2 & op_ld_st_size=0x0 & op_insn_class=0x0 { dst=*:4 (src + imm); } :LDINDH src, dst, imm is imm & src & dst & op_ld_st_mode=0x2 & op_ld_st_size=0x1 & op_insn_class=0x0 { dst=*:2 (src + imm); } :LDINDB src, dst, imm is imm & src & dst & op_ld_st_mode=0x2 & op_ld_st_size=0x2 & op_insn_class=0x0 { dst=*:1 (src + imm); } :LDINDDW src, dst, imm is imm & src & dst & op_ld_st_mode=0x2 & op_ld_st_size=0x3 & op_insn_class=0x0 { dst=*:8 (src + imm); } :LDXW dst, [src + off] is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x0 & op_insn_class=0x1 { dst=*:4 (src + off); } :LDXH dst, [src + off] is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x1 & op_insn_class=0x1 { dst=*:2 (src + off); } :LDXB dst, [src + off] is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x2 & op_insn_class=0x1 { dst=*:1 (src + off); } :LDXDW dst, [src + off] is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x3 & op_insn_class=0x1 { dst=*:8 (src + off); } :STW [dst + off], imm is imm & off & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x0 & op_insn_class=0x2 { *:4 (dst + off)=imm:4; } :STH [dst + off], imm is imm & off & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x1 & op_insn_class=0x2 { *:2 (dst + off)=imm:2; } :STB [dst + off], imm is imm & off & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x2 & op_insn_class=0x2 { *:1 (dst + off)=imm:1; } :STDW [dst + off], imm is imm & off & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x3 & op_insn_class=0x2 { *:8 (dst + off)=imm:8; } :STXW [dst + off], src is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x0 & op_insn_class=0x3 { *:4 (dst + off)=src:4; } :STXH [dst + off], src is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x1 & op_insn_class=0x3 { *:2 (dst + off)=src:2; } :STXB [dst + off], src is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x2 & op_insn_class=0x3 { *:1 (dst + off)=src:1; } :STXDW [dst + off], src is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x3 & op_insn_class=0x3 { *:8 (dst + off)=src:8; } # BPF_ATOMIC # BPF_ADD: # BPF_STX | BPF_ATOMIC | BPF_W :STXXADDW [dst + off], src is imm=0x0 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { *:4 (dst + off) = *:4 (dst + off) + src:4; } # BPF_STX | BPF_ATOMIC | BPF_DW :STXXADDDW [dst + off], src is imm=0x0 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { *:8 (dst + off) = *:8 (dst + off) + src; } # BPF_OR: :STXXADDW [dst + off], src is imm=0x40 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { *:4 (dst + off) = *:4 (dst + off) | src:4; } :STXXADDDW [dst + off], src is imm=0x40 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { *:8 (dst + off) = *:8 (dst + off) | src; } # BPF_AND: :STXXADDW [dst + off], src is imm=0x50 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { *:4 (dst + off) = *:4 (dst + off) & src:4; } :STXXADDDW [dst + off], src is imm=0x50 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { *:8 (dst + off) = *:8 (dst + off) & src; } # BPF_XOR: :STXXADDW [dst + off], src is imm=0xa0 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { *:4 (dst + off) = *:4 (dst + off) ^ src:4; } :STXXADDDW [dst + off], src is imm=0xa0 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { *:8 (dst + off) = *:8 (dst + off) ^ src; } # BPF_ADD | BPF_FETCH -> src = atomic_fetch_add(dst + off, src): :STXXADDW [dst + off], src is imm=0x1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { local tmp:4 = *:4 (dst + off); *:4 (dst + off) = *:4 (dst + off) + src:4; src = zext(tmp); } :STXXADDDW [dst + off], src is imm=0x1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { local tmp:8 = *:8 (dst + off); *:8 (dst + off) = *:8 (dst + off) + src; src = tmp; } # BPF_OR | BPF_FETCH -> src = atomic_fetch_or(dst + off, src): :STXXADDW [dst + off], src is imm=0x41 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { local tmp:4 = *:4 (dst + off); *:4 (dst + off) = *:4 (dst + off) | src:4; src = zext(tmp); } :STXXADDDW [dst + off], src is imm=0x41 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { local tmp:8 = *:8 (dst + off); *:8 (dst + off) = *:8 (dst + off) | src; src = tmp; } # BPF_AND | BPF_FETCH -> src = atomic_fetch_and(dst + off, src): :STXXADDW [dst + off], src is imm=0x51 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { local tmp:4 = *:4 (dst + off); *:4 (dst + off) = *:4 (dst + off) & src:4; src = zext(tmp); } :STXXADDDW [dst + off], src is imm=0x51 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { local tmp:8 = *:8 (dst + off); *:8 (dst + off) = *:8 (dst + off) & src; src = tmp; } # BPF_XOR | BPF_FETCH -> src = atomic_fetch_xor(dst + off, src): :STXXADDW [dst + off], src is imm=0xa1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { local tmp:4 = *:4 (dst + off); *:4 (dst + off) = *:4 (dst + off) ^ src:4; src = zext(tmp); } :STXXADDDW [dst + off], src is imm=0xa1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { local tmp:8 = *:8 (dst + off); *:8 (dst + off) = *:8 (dst + off) ^ src; src = tmp; } # BPF_XCHG -> src_reg = atomic_xchg(dst + off, src): :STXXADDW [dst + off], src is imm=0xe1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { local tmp:4 = *:4 (dst + off); *:4 (dst + off) = src:4; src = zext(tmp); } :STXXADDDW [dst + off], src is imm=0xe1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { local tmp:8 = *:8 (dst + off); *:8 (dst + off) = src; src = tmp; } # BPF_CMPXCHG -> R0 = atomic_cmpxchg(dst + off, R0, src): :STXXADDW [dst + off], src is imm=0xf1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { local tmp:4 = *:4 (dst + off); if (R0:4 == tmp) goto ; R0 = zext(tmp); *:4 (dst + off) = src:4; } :STXXADDDW [dst + off], src is imm=0xf1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { local tmp:8 = *:8 (dst + off); if (R0 == tmp) goto ; R0 = tmp; *:8 (dst + off) = src; } #Jump instructions (BPF_JMP, BPF_JMP32) ############################################################################### joff: reloc is off [ reloc = inst_next + off * 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 dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=0 & op_insn_class=0x5 { if (dst == imm) goto joff; } :JEQ dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=1 & op_insn_class=0x5 { if (dst == src) goto joff; } :JEQ dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=0 & op_insn_class=0x6 { if (dst:4 == imm:4) goto joff; } :JEQ dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=1 & op_insn_class=0x6 { if (dst:4 == src:4) goto joff; } :JGT dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=0 & op_insn_class=0x5 { if (dst > imm) goto joff; } :JGT dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=1 & op_insn_class=0x5 { if (dst > src) goto joff; } :JGT dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=0 & op_insn_class=0x6 { if (dst:4 > imm:4) goto joff; } :JGT dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=1 & op_insn_class=0x6 { if (dst:4 > src:4) goto joff; } :JGE dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=0 & op_insn_class=0x5 { if (dst >= imm) goto joff; } :JGE dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=1 & op_insn_class=0x5 { if (dst >= src) goto joff; } :JGE dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=0 & op_insn_class=0x6 { if (dst:4 >= imm:4) goto joff; } :JGE dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=1 & op_insn_class=0x6 { if (dst:4 >= src:4) goto joff; } :JLT dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=0 & op_insn_class=0x5 { if (dst < imm) goto joff; } :JLT dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=1 & op_insn_class=0x5 { if (dst < src) goto joff; } :JLT dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=0 & op_insn_class=0x6 { if (dst:4 < imm:4) goto joff; } :JLT dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=1 & op_insn_class=0x6 { if (dst:4 < src:4) goto joff; } :JLE dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=0 & op_insn_class=0x5 { if (dst <= imm) goto joff; } :JLE dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=1 & op_insn_class=0x5 { if (dst <= src) goto joff; } :JLE dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=0 & op_insn_class=0x6 { if (dst:4 <= imm:4) goto joff; } :JLE dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=1 & op_insn_class=0x6 { if (dst:4 <= src:4) goto joff; } :JNE dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=0 & op_insn_class=0x5 { if (dst != imm) goto joff; } :JNE dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=1 & op_insn_class=0x5 { if (dst != src) goto joff; } :JNE dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=0 & op_insn_class=0x6 { if (dst:4 != imm:4) goto joff; } :JNE dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=1 & op_insn_class=0x6 { if (dst:4 != src:4) goto joff; } :JSET dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=0 & op_insn_class=0x5 { if ((dst & imm) != 0) goto joff; } :JSET dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=1 & op_insn_class=0x5 { if ((dst & src) != 0) goto joff; } :JSET dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=0 & op_insn_class=0x6 { if ((dst:4 & imm:4) != 0) goto joff; } :JSET dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=1 & op_insn_class=0x6 { if ((dst:4 & src:4) != 0) goto joff; } :JSGT dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=0 & op_insn_class=0x5 { if (dst s> imm) goto joff; } :JSGT dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=1 & op_insn_class=0x5 { if (dst s> src) goto joff; } :JSGT dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=0 & op_insn_class=0x6 { if (dst:4 s> imm:4) goto joff; } :JSGT dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=1 & op_insn_class=0x6 { if (dst:4 s> src:4) goto joff; } :JSGE dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=0 & op_insn_class=0x5 { if (dst s>= imm) goto joff; } :JSGE dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=1 & op_insn_class=0x5 { if (dst s>= src) goto joff; } :JSGE dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=0 & op_insn_class=0x6 { if (dst:4 s>= imm:4) goto joff; } :JSGE dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=1 & op_insn_class=0x6 { if (dst:4 s>= src:4) goto joff; } :JSLT dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=0 & op_insn_class=0x5 { if (dst s< imm) goto joff; } :JSLT dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=1 & op_insn_class=0x5 { if (dst s< src) goto joff; } :JSLT dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=0 & op_insn_class=0x6 { if (dst:4 s< imm:4) goto joff; } :JSLT dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=1 & op_insn_class=0x6 { if (dst:4 s< src:4) goto joff; } :JSLE dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x5 { if (dst s<= imm) goto joff; } :JSLE dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x5 { if (dst s<= src) goto joff; } :JSLE dst, imm, joff is imm & joff & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x6 { if (dst:4 s<= imm:4) goto joff; } :JSLE dst, src, joff is joff & src & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x6 { if (dst:4 s<= src:4) goto joff; } SysCall: imm is imm { export *[syscall]:1 imm; } :CALL SysCall is imm & src=0 & op_alu_jmp_opcode=0x8 & op_alu_jmp_source=0 & op_insn_class=0x5 & SysCall { call SysCall; } disp32: reloc is imm [ reloc = inst_next + imm; ] { export *:4 reloc; } :CALL disp32 is imm & src=1 & op_alu_jmp_opcode=0x8 & op_alu_jmp_source=0 & op_insn_class=0x5 & disp32 { call disp32; } :EXIT is op_alu_jmp_opcode=0x9 & op_alu_jmp_source=0 & op_insn_class=0x5 { return [*:8 R10]; } ================================================ FILE: data/languages/eBPF.slaspec ================================================ define endian=little; @include "eBPF.sinc" ================================================ FILE: data/sleighArgs.txt ================================================ # Add sleigh compiler options to this file (one per line) which will # be used when compiling each language within this module. # All options should start with a '-' character. # # IMPORTANT: The -a option should NOT be specified # ================================================ FILE: extension.properties ================================================ name=eBPF description=eBPF Processor for Ghidra author=Nalen98 createdOn= version=@extversion@ ================================================ FILE: src/main/java/ghidra/app/plugin/core/analysis/eBPFAnalyzer.java ================================================ package ghidra.app.plugin.core.analysis; import ghidra.app.cmd.function.SetFunctionNameCmd; import ghidra.app.cmd.function.SetFunctionVarArgsCommand; import ghidra.app.cmd.function.SetReturnDataTypeCmd; import ghidra.app.plugin.core.analysis.ConstantPropagationAnalyzer; import ghidra.app.plugin.core.analysis.ConstantPropagationContextEvaluator; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; import ghidra.program.model.address.*; import ghidra.program.model.data.CharDataType; import ghidra.program.model.data.DataType; import ghidra.program.model.lang.Processor; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.SourceType; import ghidra.program.model.symbol.SymbolIterator; import ghidra.program.model.symbol.SymbolTable; import ghidra.program.util.*; import ghidra.program.model.data.IntegerDataType; import ghidra.program.model.data.PointerDataType; import ghidra.program.model.data.SignedQWordDataType; import ghidra.program.model.data.StructureDataType; import ghidra.program.model.data.UnsignedCharDataType; import ghidra.program.model.data.UnsignedIntegerDataType; import ghidra.program.model.data.UnsignedLongDataType; import ghidra.program.model.data.UnsignedShortDataType; import ghidra.program.model.data.VoidDataType; import ghidra.program.model.listing.BookmarkManager; import ghidra.program.model.listing.CodeUnit; import ghidra.program.model.listing.Function; import ghidra.app.cmd.function.AddMemoryParameterCommand; public class eBPFAnalyzer extends ConstantPropagationAnalyzer { private final static String PROCESSOR_NAME = "eBPF"; public eBPFAnalyzer() { super(PROCESSOR_NAME); } @Override public boolean canAnalyze(Program program) { return program.getLanguage().getProcessor().equals( Processor.findOrPossiblyCreateProcessor(PROCESSOR_NAME)); } @Override public AddressSet flowConstants(final Program program, Address flowStart, AddressSetView flowSet, final SymbolicPropogator symEval, final TaskMonitor monitor) throws CancelledException { // https://github.com/NationalSecurityAgency/ghidra/commit/70405b07b0b857d433dfec77ae5c343997f589eb ContextEvaluator eval = new ConstantPropagationContextEvaluator(monitor, trustWriteMemOption); AddressSet resultSet = symEval.flowConstants(flowStart, flowSet, eval, true, monitor); BookmarkManager bmmanager = program.getBookmarkManager(); bmmanager.removeBookmarks("Error", "Bad Instruction", monitor); SymbolTable table = program.getSymbolTable(); boolean includeDynamicSymbols = true; SymbolIterator symbols = table.getAllSymbols(includeDynamicSymbols); for (ghidra.program.model.symbol.Symbol s: symbols) { if (s.getName().contains("syscall")) { Function func = program.getFunctionManager().getFunctionAt(s.getAddress()); //Definitions for datatypes DataType dstruct = null; DataType dvoid = new VoidDataType(); DataType dint = new IntegerDataType(); DataType dchar = new CharDataType(); DataType duint = new UnsignedIntegerDataType(); DataType dulong = new UnsignedLongDataType(); DataType dushort = new UnsignedShortDataType(); DataType dslong = new SignedQWordDataType(); DataType duchar = new UnsignedCharDataType(); DataType dvp = new PointerDataType(dvoid, 0); DataType dcp = new PointerDataType(dchar, 0); DataType dsp; //DataType for struct-pointer //Command-vars SetFunctionNameCmd cmdName; SetReturnDataTypeCmd cmdRet; AddMemoryParameterCommand cmdArg1; AddMemoryParameterCommand cmdArg2; AddMemoryParameterCommand cmdArg3; AddMemoryParameterCommand cmdArg4; AddMemoryParameterCommand cmdArg5; SetFunctionVarArgsCommand cmdVar = new SetFunctionVarArgsCommand(func, true); String location = s.getName().substring(14); //Getting address of helper int helper_id = Integer.parseInt(location, 16); switch (helper_id) { case(0x0): //void bpf_unspec() cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_unspec", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dvoid, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); program.flushEvents(); break; case (0x1): //void *bpf_map_lookup_elem(struct bpf_map *map, const void *key) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_map_lookup_elem", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dvp, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_map", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "key", dvp, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x2): //int bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_map_update_elem", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_map", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "key", dvp, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "value", dvp, 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); program.flushEvents(); break; case (0x3): //int bpf_map_delete_elem(struct bpf_map *map, const void *key) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_map_delete_elem", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_map", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "key", dvp, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x4): //int bpf_probe_read(void *dst, u32 size, const void *src) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_probe_read", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "dst", dvp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "size", duint, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "src", dvp, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x5): //u64 bpf_ktime_get_ns(void) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_ktime_get_ns", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); program.flushEvents(); break; case (0x6): //int bpf_trace_printk(const char *fmt, u32 fmt_size, ...) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_trace_printk", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "fmt", dcp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "fmt_size", duint, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x7): //u32 bpf_get_prandom_u32(void) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_prandom_u32", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), duint, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); program.flushEvents(); break; case (0x8): //u32 bpf_get_smp_processor_id(void) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_smp_processor_id", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), duint, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); program.flushEvents(); break; case (0x9): //int bpf_skb_store_bytes(struct sk_buff *skb, u32 offset, const void *from, u32 len, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_store_bytes", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdVar.applyTo(program); //If we'll set all arguments for this func (as always), it will give rise nasty errors such "Removing unreachable block at (address)" //int bpf_skb_store_bytes(struct sk_buff *skb, u32 offset, const void *from, u32 len, u64 flags) program.flushEvents(); break; case (0xa): //int bpf_l3_csum_replace(struct sk_buff *skb, u32 offset, u64 from, u64 to, u64 size) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_l3_csum_replace", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "offset", duint, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "from", dulong, 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "to", dulong, 3, SourceType.ANALYSIS); cmdArg5 = new AddMemoryParameterCommand(func, s.getAddress(), "size", dulong, 4, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); cmdArg5.applyTo(program); program.flushEvents(); break; case (0xb): //int bpf_l4_csum_replace(struct sk_buff *skb, u32 offset, u64 from, u64 to, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_l4_csum_replace", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "offset", duint, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "from", dulong, 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "to", dulong, 3, SourceType.ANALYSIS); cmdArg5 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 4, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); cmdArg5.applyTo(program); program.flushEvents(); break; case (0xc): //int bpf_tail_call(void *ctx, struct bpf_map *prog_array_map, u32 index) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_tail_call", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_map", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ctx", dvp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "prog_array_map", dsp, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "index", duint, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0xd): //int bpf_clone_redirect(struct sk_buff *skb, u32 ifindex, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_clone_redirect", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "ifindex", duint, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0xe): //u64 bpf_get_current_pid_tgid(void) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_current_pid_tgid", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); program.flushEvents(); break; case (0xf): //u64 bpf_get_current_uid_gid(void) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_current_uid_gid", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); program.flushEvents(); break; case (0x10): //int bpf_get_current_comm(char *buf, u32 size_of_buf) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_current_comm", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "buf", dcp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "size_of_buf", duint, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x11): //u32 bpf_get_cgroup_classid(struct sk_buff *skb) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_cgroup_classid", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), duint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); program.flushEvents(); break; case (0x12): //int bpf_skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci) //In ghidra Api conditions we must equate__be16 with unsigned short type. cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_vlan_push", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "vlan_proto", dushort, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "vlan_tci", dushort, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x13): //int bpf_skb_vlan_pop(struct sk_buff *skb) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_vlan_pop", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); program.flushEvents(); break; case (0x14): //int bpf_skb_get_tunnel_key(struct sk_buff *skb, struct bpf_tunnel_key *key, u32 size, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_get_tunnel_key", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); DataType dstruct2 = new StructureDataType("struct bpf_tunnel_key", 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "key", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "size", duint, 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); program.flushEvents(); break; case (0x15): //int bpf_skb_set_tunnel_key(struct sk_buff *skb, struct bpf_tunnel_key *key, u32 size, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_set_tunnel_key", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); dstruct2 = new StructureDataType("struct bpf_tunnel_key", 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "key", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "size", duint, 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); program.flushEvents(); break; case (0x16): //u64 bpf_perf_event_read(struct bpf_map *map, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_perf_event_read", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_map", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x17): //int bpf_redirect(u32 ifindex, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_redirect", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ifindex", duint, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x18): //u32 bpf_get_route_realm(struct sk_buff *skb) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_route_realm", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), duint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); program.flushEvents(); break; case (0x19): //int bpf_perf_event_output(struct pt_reg *ctx, struct bpf_map *map, u64 flags, void *data, u64 size) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_perf_event_output", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct pt_reg", 0); dsp = new PointerDataType(dstruct, 0); dstruct2 = new StructureDataType("struct bpf_map", 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ctx", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "map", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "data", dvp, 3, SourceType.ANALYSIS); cmdArg5 = new AddMemoryParameterCommand(func, s.getAddress(), "size", dulong, 4, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); cmdArg5.applyTo(program); program.flushEvents(); break; case (0x1a): //int bpf_skb_load_bytes(const struct sk_buff *skb, u32 offset, void *to, u32 len) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_load_bytes", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); dstruct2 = new StructureDataType("struct bpf_map", 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "offset", duint, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "to", dvp, 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "len", duint, 3, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); program.flushEvents(); break; case (0x1b): //int bpf_get_stackid(struct pt_reg *ctx, struct bpf_map *map, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_stackid", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct pt_reg", 0); dsp = new PointerDataType(dstruct, 0); dstruct2 = new StructureDataType("struct bpf_map", 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ctx", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "map", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x1c): //s64 bpf_csum_diff(__be32 *from, u32 from_size, __be32 *to, u32 to_size, __wsum seed) //In ghidra Api conditions we must equate __be32 and __wsum with u32 (knowing typedef). cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_csum_diff", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dslong, SourceType.ANALYSIS); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "from", new PointerDataType(duint, 0), 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "from_size", duint, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "to", new PointerDataType(duint, 0), 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "to_size", duint, 3, SourceType.ANALYSIS); cmdArg5 = new AddMemoryParameterCommand(func, s.getAddress(), "seed", duint, 4, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); cmdArg5.applyTo(program); program.flushEvents(); break; case (0x1d): //int bpf_skb_get_tunnel_opt(struct sk_buff *skb, u8 *opt, u32 size) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_get_tunnel_opt", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "opt", new PointerDataType(duchar, 0), 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "size", duint, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x1e): //int bpf_skb_set_tunnel_opt(struct sk_buff *skb, u8 *opt, u32 size) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_set_tunnel_opt", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "opt", new PointerDataType(duchar, 0), 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "size", duint, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x1f): //int bpf_skb_change_proto(struct sk_buff *skb, __be16 proto, u64 flags) //__be16 equals u16 for big-endian cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_change_proto", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "proto", dushort, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x20): //int bpf_skb_change_type(struct sk_buff *skb, u32 type) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_change_type", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "type", duint, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x21): //int bpf_skb_under_cgroup(struct sk_buff *skb, struct bpf_map *map, u32 index) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_under_cgroup", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); dstruct2 = new StructureDataType("struct bpf_map", 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "map", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "index", duint, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x22): //u32 bpf_get_hash_recalc(struct sk_buff *skb) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_hash_recalc", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), duint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); program.flushEvents(); break; case (0x23): //u64 bpf_get_current_task(void) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_current_task", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); program.flushEvents(); break; case (0x24): //int bpf_probe_write_user(void *dst, const void *src, u32 len) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_probe_write_user", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "dst", dvp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "src", dvp, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "len", duint, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x25): //int bpf_current_task_under_cgroup(struct bpf_map *map, u32 index) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_current_task_under_cgroup", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_map", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "index", duint, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x26): //int bpf_skb_change_tail(struct sk_buff *skb, u32 len, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_change_tail", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "len", duint, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x27): //int bpf_skb_pull_data(struct sk_buff *skb, u32 len) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_pull_data", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "len", duint, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x28): //s64 bpf_csum_update(struct sk_buff *skb, __wsum csum) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_csum_update", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dslong, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "csum", duint, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x29): //void bpf_set_hash_invalid(struct sk_buff *skb) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_set_hash_invalid", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dvoid, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); program.flushEvents(); break; case (0x2a): //int bpf_get_numa_node_id(void) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_numa_node_id", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); program.flushEvents(); break; case (0x2b): //int bpf_skb_change_head(struct sk_buff *skb, u32 len, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_change_head", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "len", duint, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x2c): //int bpf_xdp_adjust_head(struct xdp_buff *xdp_md, int delta) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_xdp_adjust_head", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct xdp_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "xdp_md", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "delta", dint, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x2d): //int bpf_probe_read_str(void *dst, u32 size, const void *unsafe_ptr) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_probe_read_str", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct xdp_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "dst", dvp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "size", duint, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "unsafe_ptr", dvp, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x2e): //u64 bpf_get_socket_cookie(struct sk_buff *skb) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_socket_cookie", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); program.flushEvents(); break; case (0x2f): //u64 bpf_get_socket_cookie(struct bpf_sock_addr *ctx) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_socket_cookie", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_sock_addr", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ctx", dsp, 0, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); program.flushEvents(); break; case (0x30): //u64 bpf_get_socket_cookie(struct bpf_sock_ops *ctx) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_socket_cookie", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_sock_ops", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ctx", dsp, 0, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); program.flushEvents(); break; case (0x31): //u32 bpf_get_socket_uid(struct sk_buff *skb) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_socket_uid", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), duint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); program.flushEvents(); break; case (0x32): //int bpf_set_hash(struct sk_buff *skb, u32 hash) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_set_hash", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "hash", duint, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x33): //int bpf_setsockopt(void *bpf_socket, int level, int optname, void *optval, int optlen) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_setsockopt", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdVar.applyTo(program); program.flushEvents(); break; case (0x34): //int bpf_skb_adjust_room(struct sk_buff *skb, s32 len_diff, u32 mode, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_adjust_room", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "len_diff", dint, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "mode", duint, 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); program.flushEvents(); break; case (0x35): //int bpf_redirect_map(struct bpf_map *map, u32 key, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_redirect_map", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_map", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "key", duint, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x36): //int bpf_sk_redirect_map(struct sk_buff *skb, struct bpf_map *map, u32 key, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_sk_redirect_map", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_buff", 0); dsp = new PointerDataType(dstruct, 0); dstruct2 = new StructureDataType("struct bpf_map", 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "map", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "key", duint, 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); program.flushEvents(); break; case (0x37): //int bpf_sock_map_update(struct bpf_sock_ops *skops, struct bpf_map *map, void *key, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_sock_map_update", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_sock_ops", 0); dsp = new PointerDataType(dstruct, 0); dstruct2 = new StructureDataType("struct bpf_map", 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skops", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "map", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "key", dvp, 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); program.flushEvents(); break; case (0x38): //int bpf_xdp_adjust_meta(struct xdp_buff *xdp_md, int delta) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_xdp_adjust_meta", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct xdp_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "xdp_md", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "delta", dint, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x39): //int bpf_perf_event_read_value(struct bpf_map *map, u64 flags, struct bpf_perf_event_value *buf, u32 buf_size) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_perf_event_read_value", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_map", 0); dsp = new PointerDataType(dstruct, 0); dstruct2 = new StructureDataType("struct bpf_perf_event_value", 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "buf", new PointerDataType(dstruct2, 0), 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "buf_size", duint, 3, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); program.flushEvents(); break; case (0x3a): //int bpf_perf_prog_read_value(struct bpf_perf_event_data *ctx, struct bpf_perf_event_value *buf, u32 buf_size) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_perf_prog_read_value", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_perf_event_data", 0); dsp = new PointerDataType(dstruct, 0); dstruct2 = new StructureDataType("struct bpf_perf_event_value", 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ctx", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "buf", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "buf_size", duint, 2, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); program.flushEvents(); break; case (0x3b): //int bpf_getsockopt(void *bpf_socket, int level, int optname, void *optval, int optlen) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_getsockopt", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdVar.applyTo(program); program.flushEvents(); break; case (0x3c): //int bpf_override_return(struct pt_regs *regs, u64 rc) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_override_return", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct pt_regs", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "regs", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "rc", dulong, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x3d): //int bpf_sock_ops_cb_flags_set(struct bpf_sock_ops *bpf_sock, int argval) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_sock_ops_cb_flags_set", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct bpf_sock_ops", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "bpf_sock", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "argval", dint, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; case (0x3e): //int bpf_msg_redirect_map(struct sk_msg_buff *msg, struct bpf_map *map, u32 key, u64 flags) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_msg_redirect_map", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_msg_buff", 0); dsp = new PointerDataType(dstruct, 0); dstruct2 = new StructureDataType("struct bpf_map", 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "msg", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "map", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS); cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "key", duint, 2, SourceType.ANALYSIS); cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); cmdArg3.applyTo(program); cmdArg4.applyTo(program); program.flushEvents(); break; case (0x3f): //int bpf_msg_apply_bytes(struct sk_msg_buff *msg, u32 bytes) cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_msg_apply_bytes", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS); dstruct = new StructureDataType("struct sk_msg_buff", 0); dsp = new PointerDataType(dstruct, 0); cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "msg", dsp, 0, SourceType.ANALYSIS); cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "bytes", duint, 1, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); cmdArg1.applyTo(program); cmdArg2.applyTo(program); program.flushEvents(); break; default: //void bpf_undef() cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_undef", SourceType.ANALYSIS); cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dvoid, SourceType.ANALYSIS); cmdName.applyTo(program); cmdRet.applyTo(program); program.flushEvents(); break; } bmmanager.setBookmark(s.getAddress(), "Analysis", "eBPF-helpers", "eBPF-helper Identified"); } } return resultSet; } } ================================================ FILE: src/main/java/ghidra/app/util/bin/format/elf/extend/eBPF_ElfExtension.java ================================================ package ghidra.app.util.bin.format.elf.extend; import ghidra.app.util.bin.format.elf.*; import ghidra.program.model.lang.*; import ghidra.util.exception.*; import ghidra.util.task.TaskMonitor; public class eBPF_ElfExtension extends ElfExtension { @Override public boolean canHandle(ElfHeader elf) { return elf.e_machine() == ElfConstants.EM_BPF && elf.is64Bit(); } @Override public boolean canHandle(ElfLoadHelper elfLoadHelper) { Language language = elfLoadHelper.getProgram().getLanguage(); return canHandle(elfLoadHelper.getElfHeader()) && "eBPF".equals(language.getProcessor().toString()) && language.getLanguageDescription().getSize() == 64; } @Override public String getDataTypeSuffix() { return "eBPF"; } @Override public void processGotPlt(ElfLoadHelper elfLoadHelper, TaskMonitor monitor) throws CancelledException { if (!canHandle(elfLoadHelper)) { return; } super.processGotPlt(elfLoadHelper, monitor); } } ================================================ FILE: src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfeBPFRelocationFixupHandler.java ================================================ package ghidra.app.util.bin.format.elf.relocation; import ghidra.app.plugin.core.reloc.RelocationFixupHandler; import ghidra.app.util.opinion.ElfLoader; import ghidra.program.model.address.Address; import ghidra.program.model.lang.Language; import ghidra.program.model.lang.Processor; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.reloc.Relocation; import ghidra.program.model.util.CodeUnitInsertionException; public class ElfeBPFRelocationFixupHandler extends RelocationFixupHandler { @Override public boolean processRelocation(Program program, Relocation relocation, Address oldImageBase, Address newImageBase) throws MemoryAccessException, CodeUnitInsertionException { return process64BitRelocation(program, relocation, oldImageBase, newImageBase); } @Override public boolean handlesProgram(Program program) { if (!ElfLoader.ELF_NAME.equals(program.getExecutableFormat())) { return false; } Language language = program.getLanguage(); if (language.getLanguageDescription().getSize() != 64) { return false; } Processor processor = language.getProcessor(); return (processor.equals(Processor.findOrPossiblyCreateProcessor("eBPF"))); } } ================================================ FILE: src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationConstants.java ================================================ package ghidra.app.util.bin.format.elf.relocation; public class eBPF_ElfRelocationConstants { /** No operation needed */ public static final int R_BPF_NONE = 0; /** S + A */ public static final int R_BPF_64_64 = 1; /** S + A */ public static final int R_BPF_64_ABS64 = 2; /** S + A */ public static final int R_BPF_64_ABS32 = 3; /** S + A */ public static final int R_BPF_64_NODYLD32 = 4; /** (S + A) / 8 - 1 */ public static final int R_BPF_64_32 = 10; private eBPF_ElfRelocationConstants() { // no construct } } ================================================ FILE: src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationHandler.java ================================================ package ghidra.app.util.bin.format.elf.relocation; import ghidra.app.util.bin.format.elf.*; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.*; import ghidra.program.model.reloc.RelocationResult; import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.symbol.SymbolTable; import ghidra.util.exception.NotFoundException; public class eBPF_ElfRelocationHandler extends ElfRelocationHandler { @Override public boolean canRelocate(ElfHeader elf) { return elf.e_machine() == ElfConstants.EM_BPF; } @Override public RelocationResult relocate(ElfRelocationContext elfRelocationContext, ElfRelocation relocation, Address relocationAddress) throws MemoryAccessException, NotFoundException { ElfHeader elf = elfRelocationContext.getElfHeader(); if (elf.e_machine() != ElfConstants.EM_BPF) { return RelocationResult.FAILURE; } Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); int type = relocation.getType(); if (type == eBPF_ElfRelocationConstants.R_BPF_NONE) { return RelocationResult.SKIPPED; } String section_name = elfRelocationContext.relocationTable.getSectionToBeRelocated().getNameAsString(); if (section_name.toString().contains("debug")) { return RelocationResult.SKIPPED; } SymbolTable table = program.getSymbolTable(); int symbolIndex = relocation.getSymbolIndex(); ElfSymbol symbol = elfRelocationContext.getSymbol(symbolIndex); String symbolName = symbol.getNameAsString(); Address symbolAddr = table.getSymbols(symbolName).next().getAddress(); long new_value = 0; int byteLength = 4; // most relocations affect 4-bytes try { switch (type){ case eBPF_ElfRelocationConstants.R_BPF_64_64: { new_value = symbolAddr.getAddressableWordOffset(); Byte dst = memory.getByte(relocationAddress.add(0x1)); memory.setLong(relocationAddress.add(0x4), new_value); memory.setByte(relocationAddress.add(0x1), (byte)(dst + 0x10)); break; } case eBPF_ElfRelocationConstants.R_BPF_64_32: { // if we have, e.g, non-static function, it will be marked in the relocation table // and indexed in the symbol table and it's easy to calculate the pc-relative offset long instr_next = relocationAddress.add(0x8).getAddressableWordOffset(); if (symbol.isFunction()) { new_value = symbolAddr.getAddressableWordOffset(); int offset = (int)(new_value - instr_next); memory.setInt(relocationAddress.add(0x4), offset); } else if (symbol.isSection()) { if (memory.getInt(relocationAddress) == 0x1085) { ElfSectionHeader sectionHeader = elfRelocationContext.getElfHeader().getSection(symbolName); long section_start = program.getImageBase().getOffset() + sectionHeader.getAddress(); // getting call instruction offset (current imm) int current_imm = memory.getInt(relocationAddress.add(0x4)); // calculate the call target section offset // according to formula in "kernel.org" docs: https://www.kernel.org/doc/html/latest/bpf/llvm_reloc.html int func_sec_offset = (current_imm + 1) * 8; long func_addr = section_start + func_sec_offset; int offset = (int)(func_addr - instr_next); memory.setInt(relocationAddress.add(0x4), offset); } } break; } default: { if (symbolIndex == 0) { markAsWarning(program, relocationAddress, Long.toString(type), "applied relocation with symbol-index of 0", elfRelocationContext.getLog()); } return RelocationResult.UNSUPPORTED; } } } catch (NullPointerException e) { } return new RelocationResult(Status.APPLIED, byteLength); } }