Skip to content
This repository was archived by the owner on Jan 27, 2025. It is now read-only.

Commit 2bbdf9f

Browse files
committed
WIP
1 parent d4c55d9 commit 2bbdf9f

8 files changed

+459
-1
lines changed

.clang-format

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
BasedOnStyle: WebKit

.gitignore

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
build
2+
CMakeFiles
3+
CMakeCache.txt
4+
Makefile
5+
cmake_install.cmake
6+
build.ninja
7+
*.o
8+
*.so
9+
*.so.*
10+
*.dylib
11+
*.dll
12+
*.exp
13+
*.ilk
14+
*.lib
15+
*.pdb
16+
*.obj
17+
.qt

CMakeLists.txt

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
2+
3+
project(arch_ebpf)
4+
5+
if((NOT BN_API_PATH) AND (NOT BN_INTERNAL_BUILD))
6+
set(BN_API_PATH $ENV{BN_API_PATH})
7+
if(NOT BN_API_PATH)
8+
message(FATAL_ERROR "Provide path to Binary Ninja API source in BN_API_PATH")
9+
endif()
10+
endif()
11+
if(NOT BN_INTERNAL_BUILD)
12+
add_subdirectory(${BN_API_PATH} ${PROJECT_BINARY_DIR}/api)
13+
endif()
14+
15+
file(GLOB SOURCES
16+
arch_ebpf.cpp
17+
disassembler.cpp
18+
il.cpp
19+
*.h
20+
)
21+
22+
if(DEMO)
23+
add_library(arch_ebpf STATIC ${SOURCES})
24+
else()
25+
add_library(arch_ebpf SHARED ${SOURCES})
26+
endif()
27+
28+
set(CAPSTONE_ARCHITECTURE_DEFAULT OFF CACHE INTERNAL "disable arch by default" FORCE)
29+
set(CAPSTONE_BPF_SUPPORT ON CACHE INTERNAL "enable BPF only" FORCE)
30+
add_subdirectory(${PROJECT_SOURCE_DIR}/capstone)
31+
32+
target_link_libraries(arch_ebpf binaryninjaapi capstone)
33+
34+
set_target_properties(arch_ebpf PROPERTIES
35+
CXX_STANDARD 17
36+
CXX_VISIBILITY_PRESET hidden
37+
CXX_STANDARD_REQUIRED ON
38+
VISIBILITY_INLINES_HIDDEN ON
39+
POSITION_INDEPENDENT_CODE ON)
40+
41+
if(BN_INTERNAL_BUILD)
42+
plugin_rpath(arch_ebpf)
43+
set_target_properties(arch_ebpf PROPERTIES
44+
LIBRARY_OUTPUT_DIRECTORY ${BN_CORE_PLUGIN_DIR}
45+
RUNTIME_OUTPUT_DIRECTORY ${BN_CORE_PLUGIN_DIR})
46+
endif()

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ This BN plugin implements a disassembler and lifter for the eBPF architecture an
1010
git submodule update --init
1111

1212
mkdir build
13-
cmake . -G Ninja build
13+
cmake -B build . -G Ninja -DBN_API_PATH=/usr/local/opt/binaryninja-api
1414
cmake --build build
1515
```

arch_ebpf.cpp

+217
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
#include <binaryninjaapi.h>
2+
3+
#include "lowlevelilinstruction.h"
4+
using namespace BinaryNinja;
5+
6+
#include <capstone/bpf.h>
7+
8+
enum ElfBpfRelocationType {
9+
R_BPF_NONE = 0,
10+
R_BPF_64_64 = 1,
11+
R_BPF_64_ABS64 = 2,
12+
R_BPF_64_ABS32 = 3,
13+
R_BPF_64_NODYLD32 = 4,
14+
R_BPF_64_RELATIVE = 8,
15+
R_BPF_64_32 = 10,
16+
};
17+
18+
static const char*
19+
GetRelocationString(ElfBpfRelocationType relocType)
20+
{
21+
static std::map<ElfBpfRelocationType, const char*> relocTable = {
22+
{ R_BPF_NONE, "R_BPF_NONE" },
23+
{ R_BPF_64_64, "R_BPF_64_64" },
24+
{ R_BPF_64_ABS64, "R_BPF_64_ABS64" },
25+
{ R_BPF_64_ABS32, "R_BPF_64_ABS32" },
26+
{ R_BPF_64_NODYLD32, "R_BPF_64_NODYLD32" },
27+
{ R_BPF_64_RELATIVE, "R_BPF_64_RELATIVE" },
28+
{ R_BPF_64_32, "R_BPF_64_32" },
29+
};
30+
if (relocTable.count(relocType))
31+
return relocTable.at(relocType);
32+
return "Unknown eBPF relocation";
33+
}
34+
35+
class EBPFArchitecture : public Architecture {
36+
private:
37+
BNEndianness endian;
38+
39+
public:
40+
EBPFArchitecture(const char* name, BNEndianness endian_)
41+
: Architecture(name)
42+
{
43+
endian = endian_;
44+
}
45+
46+
virtual BNEndianness GetEndianness() const override { return endian; }
47+
48+
virtual size_t GetAddressSize() const override { return 4; }
49+
50+
virtual size_t GetDefaultIntegerSize() const override { return 8; }
51+
52+
virtual size_t GetInstructionAlignment() const override { return 8; }
53+
54+
virtual size_t GetMaxInstructionLength() const override { return 16; }
55+
56+
virtual bool GetInstructionInfo(const uint8_t* data,
57+
uint64_t addr,
58+
size_t maxLen,
59+
InstructionInfo& result) override
60+
{
61+
return false;
62+
}
63+
64+
virtual bool GetInstructionText(const uint8_t* data,
65+
uint64_t addr,
66+
size_t& len,
67+
std::vector<InstructionTextToken>& result) override
68+
{
69+
return false;
70+
}
71+
72+
virtual bool GetInstructionLowLevelIL(const uint8_t* data,
73+
uint64_t addr,
74+
size_t& len,
75+
LowLevelILFunction& il) override
76+
{
77+
return false;
78+
}
79+
80+
virtual std::string GetRegisterName(uint32_t regId) override { }
81+
82+
virtual std::vector<uint32_t> GetFullWidthRegisters() override
83+
{
84+
return std::vector<uint32_t> {
85+
86+
};
87+
}
88+
89+
virtual std::vector<uint32_t> GetAllRegisters() override
90+
{
91+
std::vector<uint32_t> result = {};
92+
return result;
93+
}
94+
95+
virtual std::vector<uint32_t> GetGlobalRegisters() override
96+
{
97+
return std::vector<uint32_t> {};
98+
}
99+
100+
virtual BNRegisterInfo GetRegisterInfo(uint32_t regId) override
101+
{
102+
switch (regId) {
103+
}
104+
}
105+
106+
/*************************************************************************/
107+
108+
virtual bool IsNeverBranchPatchAvailable(const uint8_t* data,
109+
uint64_t addr,
110+
size_t len) override
111+
{
112+
}
113+
114+
virtual bool IsAlwaysBranchPatchAvailable(const uint8_t* data,
115+
uint64_t addr,
116+
size_t len) override
117+
{
118+
}
119+
120+
virtual bool IsInvertBranchPatchAvailable(const uint8_t* data,
121+
uint64_t addr,
122+
size_t len) override
123+
{
124+
}
125+
126+
virtual bool IsSkipAndReturnZeroPatchAvailable(const uint8_t* data,
127+
uint64_t addr,
128+
size_t len) override
129+
{
130+
}
131+
132+
virtual bool IsSkipAndReturnValuePatchAvailable(const uint8_t* data,
133+
uint64_t addr,
134+
size_t len) override
135+
{
136+
}
137+
138+
/*************************************************************************/
139+
140+
virtual bool ConvertToNop(uint8_t* data, uint64_t, size_t len) override { }
141+
142+
virtual bool AlwaysBranch(uint8_t* data, uint64_t addr, size_t len) override
143+
{
144+
}
145+
146+
virtual bool InvertBranch(uint8_t* data, uint64_t addr, size_t len) override
147+
{
148+
}
149+
150+
virtual bool SkipAndReturnValue(uint8_t* data,
151+
uint64_t addr,
152+
size_t len,
153+
uint64_t value) override
154+
{
155+
}
156+
};
157+
158+
class EBPFElfRelocationHandler : public RelocationHandler {
159+
public:
160+
virtual bool ApplyRelocation(Ref<BinaryView> view, Ref<Architecture> arch, Ref<Relocation> reloc, uint8_t* dest, size_t len) override
161+
{
162+
auto info = reloc->GetInfo();
163+
switch (info.nativeType) {
164+
case R_BPF_64_64:
165+
break;
166+
case R_BPF_64_ABS64:
167+
break;
168+
case R_BPF_64_ABS32:
169+
break;
170+
case R_BPF_64_NODYLD32:
171+
break;
172+
case R_BPF_64_RELATIVE:
173+
break;
174+
case R_BPF_64_32:
175+
break;
176+
default:
177+
return false;
178+
}
179+
return true;
180+
}
181+
182+
virtual bool GetRelocationInfo(Ref<BinaryView> view, Ref<Architecture> arch, std::vector<BNRelocationInfo>& result) override
183+
{
184+
std::set<uint64_t> relocTypes;
185+
for (auto& reloc : result) {
186+
switch (reloc.nativeType) {
187+
// TODO
188+
}
189+
}
190+
return true;
191+
}
192+
};
193+
194+
extern "C" {
195+
BN_DECLARE_CORE_ABI_VERSION
196+
197+
BINARYNINJAPLUGIN bool CorePluginInit()
198+
{
199+
Architecture* ebpf_be = new EBPFArchitecture("ebpf_be", BigEndian);
200+
Architecture* ebpf_le = new EBPFArchitecture("ebpf_le", LittleEndian);
201+
202+
#define EM_BPF 247
203+
BinaryViewType::RegisterArchitecture(
204+
"ELF",
205+
EM_BPF,
206+
BigEndian,
207+
ebpf_be);
208+
209+
BinaryViewType::RegisterArchitecture(
210+
"ELF",
211+
EM_BPF,
212+
BigEndian,
213+
ebpf_be);
214+
215+
return true;
216+
}
217+
}

0 commit comments

Comments
 (0)