Merged PR 4236890: Add option to dump loaded programs
Add option to dump loaded programs
This commit is contained in:
Родитель
ff4aaa51e7
Коммит
39bdb252da
|
@ -81,6 +81,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "setup_build", "scripts\setu
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "port_quota", "src\tools\port_quota\port_quota.vcxproj", "{DDADF35D-C02C-40BB-9F95-5BF8BFDB51CE}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "port_leak", "src\tools\port_leak\port_leak.vcxproj", "{DB2AF239-5251-43F1-BABF-11E707DC5523}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM = Debug|ARM
|
||||
|
@ -545,6 +547,34 @@ Global
|
|||
{DDADF35D-C02C-40BB-9F95-5BF8BFDB51CE}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{DDADF35D-C02C-40BB-9F95-5BF8BFDB51CE}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
|
||||
{DDADF35D-C02C-40BB-9F95-5BF8BFDB51CE}.RelWithDebInfo|x86.Build.0 = Release|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.Debug|ARM.ActiveCfg = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.Debug|ARM64.ActiveCfg = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.Debug|x64.Build.0 = Debug|x64
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.Debug|x86.Build.0 = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.MinSizeRel|ARM.ActiveCfg = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.MinSizeRel|ARM.Build.0 = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.MinSizeRel|ARM64.ActiveCfg = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.MinSizeRel|ARM64.Build.0 = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.MinSizeRel|x64.ActiveCfg = Debug|x64
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.MinSizeRel|x64.Build.0 = Debug|x64
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.MinSizeRel|x86.ActiveCfg = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.MinSizeRel|x86.Build.0 = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.Release|ARM.ActiveCfg = Release|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.Release|ARM64.ActiveCfg = Release|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.Release|x64.ActiveCfg = Release|x64
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.Release|x64.Build.0 = Release|x64
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.Release|x86.ActiveCfg = Release|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.Release|x86.Build.0 = Release|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.RelWithDebInfo|ARM.ActiveCfg = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.RelWithDebInfo|ARM.Build.0 = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.RelWithDebInfo|ARM64.ActiveCfg = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.RelWithDebInfo|ARM64.Build.0 = Debug|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523}.RelWithDebInfo|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -566,6 +596,7 @@ Global
|
|||
{43B63487-B277-4912-BDA8-C805347B4BA8} = {492C9B22-9237-4996-9E33-CA14D3533616}
|
||||
{231EE32B-EBA4-4FE5-A55B-DB18F539D403} = {B09749EC-3D14-414B-BA9B-CD20E218DC84}
|
||||
{DDADF35D-C02C-40BB-9F95-5BF8BFDB51CE} = {B09749EC-3D14-414B-BA9B-CD20E218DC84}
|
||||
{DB2AF239-5251-43F1-BABF-11E707DC5523} = {B09749EC-3D14-414B-BA9B-CD20E218DC84}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3D5F862D-74C6-4357-9F95-0B152E33B7B8}
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
;
|
||||
; Copyright (c) Microsoft Corporation
|
||||
; SPDX-License-Identifier: MIT
|
||||
;
|
||||
|
||||
LIBRARY
|
||||
EXPORTS
|
||||
ebpf_api_initiate
|
||||
ebpf_api_terminate
|
||||
ebpf_api_load_program
|
||||
ebpf_api_free_error_message
|
||||
ebpf_api_free_string
|
||||
ebpf_api_unload_program
|
||||
ebpf_api_attach_program
|
||||
ebpf_api_detach_program
|
||||
ebpf_api_map_lookup_element
|
||||
ebpf_api_map_update_element
|
||||
ebpf_api_map_delete_element
|
||||
ebpf_api_map_next_key
|
||||
ebpf_api_get_next_map_key
|
||||
ebpf_api_delete_map
|
||||
ebpf_api_elf_enumerate_sections
|
||||
ebpf_api_elf_disassemble_section
|
||||
|
@ -18,4 +23,7 @@ EXPORTS
|
|||
ebpf_api_elf_free
|
||||
ebpf_api_pin_map
|
||||
ebpf_api_unpin_map
|
||||
ebpf_api_get_next_map
|
||||
ebpf_api_lookup_map
|
||||
ebpf_api_get_next_program
|
||||
ebpf_api_program_query_information
|
||||
|
|
|
@ -119,17 +119,27 @@ extern "C"
|
|||
* @retval ERROR_NO_MORE_ITEMS previous_key was the last key.
|
||||
*/
|
||||
uint32_t
|
||||
ebpf_api_map_next_key(ebpf_handle_t handle, uint32_t key_size, const uint8_t* previous_key, uint8_t* next_key);
|
||||
ebpf_api_get_next_map_key(ebpf_handle_t handle, uint32_t key_size, const uint8_t* previous_key, uint8_t* next_key);
|
||||
|
||||
/**
|
||||
* @brief Enumerate through eBPF maps.
|
||||
* @brief Get the next eBPF map.
|
||||
* @param[in] previous_handle Handle to previous eBPF map or
|
||||
* ebpf_handle_invalid to start enumeration.
|
||||
* @param[out] next_handle The next eBPF map or ebpf_handle_invalid if this
|
||||
* is the last map.
|
||||
*/
|
||||
uint32_t
|
||||
ebpf_api_map_enumerate(ebpf_handle_t previous_handle, ebpf_handle_t* next_handle);
|
||||
ebpf_api_get_next_map(ebpf_handle_t previous_handle, ebpf_handle_t* next_handle);
|
||||
|
||||
/**
|
||||
* @brief Get the next eBPF program.
|
||||
* @param[in] previous_handle Handle to previous eBPF program or
|
||||
* ebpf_handle_invalid to start enumeration.
|
||||
* @param[out] next_handle The next eBPF program or ebpf_handle_invalid if this
|
||||
* is the last map.
|
||||
*/
|
||||
uint32_t
|
||||
ebpf_api_get_next_program(ebpf_handle_t previous_handle, ebpf_handle_t* next_handle);
|
||||
|
||||
/**
|
||||
* @brief Query properties of an eBPF map.
|
||||
|
@ -149,6 +159,14 @@ extern "C"
|
|||
uint32_t* value_size,
|
||||
uint32_t* max_entries);
|
||||
|
||||
/**
|
||||
* @brief Query information about an eBPF program.
|
||||
* @param[in] handle Handle to an eBPF program.
|
||||
*/
|
||||
uint32_t
|
||||
ebpf_api_program_query_information(
|
||||
ebpf_handle_t handle, ebpf_execution_type_t* program_type, const char** file_name, const char** section_name);
|
||||
|
||||
/**
|
||||
* @brief Close a handle to an eBPF map.
|
||||
* @param[in] handle Handle to eBPF map.
|
||||
|
@ -225,10 +243,10 @@ extern "C"
|
|||
|
||||
/**
|
||||
* @brief Free memory for a string returned from eBPF API.
|
||||
* @param[in] error_message Memory to free.
|
||||
* @param[in] string Memory to free.
|
||||
*/
|
||||
void
|
||||
ebpf_api_free_error_message(const char* error_message);
|
||||
ebpf_api_free_string(const char* string);
|
||||
|
||||
/**
|
||||
* @brief Associate a name with a map handle.
|
||||
|
|
|
@ -18,78 +18,6 @@ extern "C"
|
|||
void
|
||||
ebpf_core_terminate();
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_attach_code(_In_ const struct _ebpf_operation_attach_detach_request* request);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_detach_code(_In_ const struct _ebpf_operation_attach_detach_request* request);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_unload_code(_In_ const struct _ebpf_operation_unload_code_request* request);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_load_code(
|
||||
_In_ const struct _ebpf_operation_load_code_request* inputRequest,
|
||||
_Inout_ struct _ebpf_operation_load_code_reply* loadReply,
|
||||
uint16_t reply_length);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_resolve_helper(
|
||||
_In_ const struct _ebpf_operation_resolve_helper_request* request,
|
||||
_Inout_ struct _ebpf_operation_resolve_helper_reply* reply,
|
||||
uint16_t reply_length);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_resolve_map(
|
||||
_In_ const struct _ebpf_operation_resolve_map_request* request,
|
||||
_Inout_ struct _ebpf_operation_resolve_map_reply* reply,
|
||||
uint16_t reply_length);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_create_map(
|
||||
_In_ const struct _ebpf_operation_create_map_request* request,
|
||||
_Inout_ struct _ebpf_operation_create_map_reply* reply,
|
||||
uint16_t reply_length);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_map_lookup_element(
|
||||
_In_ const struct _ebpf_operation_map_lookup_element_request* request,
|
||||
_Inout_ struct _ebpf_operation_map_lookup_element_reply* reply,
|
||||
uint16_t reply_length);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_map_update_element(_In_ const struct _ebpf_operation_map_update_element_request* request);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_map_delete_element(_In_ const struct _ebpf_operation_map_delete_element_request* request);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_map_get_next_key(
|
||||
_In_ const struct _ebpf_operation_map_next_key_request* request,
|
||||
_Inout_ struct _ebpf_operation_map_next_key_reply* reply,
|
||||
uint16_t reply_length);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_enumerate_maps(
|
||||
_In_ const struct _ebpf_operation_enumerate_maps_request* request,
|
||||
_Inout_ struct _ebpf_operation_enumerate_maps_reply* reply,
|
||||
uint16_t reply_length);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_query_map_definition(
|
||||
_In_ const struct _ebpf_operation_query_map_definition_request* request,
|
||||
_Inout_ struct _ebpf_operation_query_map_definition_reply* reply,
|
||||
uint16_t reply_length);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_update_map_pinning(_In_ const struct _ebpf_operation_update_map_pinning_request* request);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_lookup_map_pinning(
|
||||
_In_ const struct _ebpf_operation_lookup_map_pinning_request* request,
|
||||
_Inout_ struct _ebpf_operation_lookup_map_pinning_reply* reply,
|
||||
uint16_t reply_length);
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_invoke_hook(_In_ ebpf_program_type_t hook_point, _Inout_ void* context, _Inout_ uint32_t* result);
|
||||
|
||||
|
|
|
@ -18,9 +18,11 @@ typedef enum _ebpf_operation_id
|
|||
EBPF_OPERATION_MAP_LOOKUP_ELEMENT,
|
||||
EBPF_OPERATION_MAP_UPDATE_ELEMENT,
|
||||
EBPF_OPERATION_MAP_DELETE_ELEMENT,
|
||||
EBPF_OPERATION_MAP_NEXT_KEY,
|
||||
EBPF_OPERATION_ENUMERATE_MAPS,
|
||||
EBPF_OPERATION_MAP_GET_NEXT_KEY,
|
||||
EBPF_OPERATION_GET_NEXT_MAP,
|
||||
EBPF_OPERATION_GET_NEXT_PROGRAM,
|
||||
EBPF_OPERATION_QUERY_MAP_DEFINITION,
|
||||
EBPF_OPERATION_QUERY_PROGRAM_INFORMATION,
|
||||
EBPF_OPERATION_UPDATE_MAP_PINNING,
|
||||
EBPF_OPERATION_LOOKUP_MAP_PINNING,
|
||||
} ebpf_operation_id_t;
|
||||
|
@ -77,7 +79,10 @@ typedef struct _ebpf_operation_load_code_request
|
|||
{
|
||||
struct _ebpf_operation_header header;
|
||||
ebpf_code_type_t code_type;
|
||||
uint8_t code[1];
|
||||
uint16_t file_name_offset;
|
||||
uint16_t section_name_offset;
|
||||
uint16_t code_offset;
|
||||
uint8_t data[1];
|
||||
} ebpf_operation_load_code_request_t;
|
||||
|
||||
typedef struct _ebpf_operation_unload_code_request
|
||||
|
@ -138,17 +143,29 @@ typedef struct _ebpf_operation_map_delete_element_request
|
|||
uint8_t key[1];
|
||||
} ebpf_operation_map_delete_element_request_t;
|
||||
|
||||
typedef struct _ebpf_operation_enumerate_maps_request
|
||||
typedef struct _ebpf_operation_get_next_map_request
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint64_t previous_handle;
|
||||
} ebpf_operation_enumerate_maps_request;
|
||||
} ebpf_operation_get_next_map_request;
|
||||
|
||||
typedef struct _ebpf_operation_enumerate_maps_reply
|
||||
typedef struct _ebpf_operation_get_next_map_reply
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint64_t next_handle;
|
||||
} ebpf_operation_enumerate_maps_reply_t;
|
||||
} ebpf_operation_get_next_map_reply_t;
|
||||
|
||||
typedef struct _ebpf_operation_get_next_program_request
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint64_t previous_handle;
|
||||
} ebpf_operation_get_next_program_request;
|
||||
|
||||
typedef struct _ebpf_operation_get_next_program_reply
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint64_t next_handle;
|
||||
} ebpf_operation_get_next_program_reply_t;
|
||||
|
||||
typedef struct _ebpf_operation_query_map_definition_request
|
||||
{
|
||||
|
@ -162,19 +179,34 @@ typedef struct _ebpf_operation_query_map_definition_reply
|
|||
struct _ebpf_map_definition map_definition;
|
||||
} ebpf_operation_query_map_definition_reply;
|
||||
|
||||
typedef struct _ebpf_operation_map_next_key_request
|
||||
typedef struct _ebpf_operation_query_program_information_request
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint64_t handle;
|
||||
} ebpf_operation_query_program_information_request;
|
||||
|
||||
typedef struct _ebpf_operation_query_program_information_reply
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
ebpf_code_type_t code_type;
|
||||
uint16_t file_name_offset;
|
||||
uint16_t section_name_offset;
|
||||
uint8_t data[1];
|
||||
} ebpf_operation_query_program_information_reply;
|
||||
|
||||
typedef struct _ebpf_operation_map_get_next_key_request
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint64_t handle;
|
||||
uint8_t previous_key[1];
|
||||
} ebpf_operation_map_next_key_request_t;
|
||||
} ebpf_operation_map_get_next_key_request_t;
|
||||
|
||||
typedef struct _ebpf_operation_map_next_key_reply
|
||||
typedef struct _ebpf_operation_map_get_next_key_reply
|
||||
{
|
||||
struct _ebpf_operation_header header;
|
||||
uint64_t handle;
|
||||
uint8_t next_key[1];
|
||||
} ebpf_operation_map_next_key_reply_t;
|
||||
} ebpf_operation_map_get_next_key_reply_t;
|
||||
|
||||
typedef struct _ebpf_operation_update_map_pinning_request
|
||||
{
|
||||
|
|
|
@ -42,6 +42,7 @@ invoke_ioctl(ebpf_handle_t handle, request_t& request, reply_t& reply = _empty_r
|
|||
void* request_ptr;
|
||||
uint32_t reply_size;
|
||||
void* reply_ptr;
|
||||
bool variable_reply_size = false;
|
||||
|
||||
if constexpr (std::is_same<request_t, nullptr_t>::value) {
|
||||
request_size = 0;
|
||||
|
@ -60,6 +61,7 @@ invoke_ioctl(ebpf_handle_t handle, request_t& request, reply_t& reply = _empty_r
|
|||
} else if constexpr (std::is_same<reply_t, std::vector<uint8_t>>::value) {
|
||||
reply_size = static_cast<uint32_t>(reply.size());
|
||||
reply_ptr = reply.data();
|
||||
variable_reply_size = true;
|
||||
} else if constexpr (std::is_same<reply_t, empty_reply>::value) {
|
||||
reply_size = 0;
|
||||
reply_ptr = nullptr;
|
||||
|
@ -82,7 +84,7 @@ invoke_ioctl(ebpf_handle_t handle, request_t& request, reply_t& reply = _empty_r
|
|||
return GetLastError();
|
||||
}
|
||||
|
||||
if (actual_reply_size != reply_size) {
|
||||
if (actual_reply_size != reply_size && !variable_reply_size) {
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -251,8 +253,6 @@ ebpf_api_load_program(
|
|||
{
|
||||
std::vector<uint8_t> byte_code(MAX_CODE_SIZE);
|
||||
size_t byte_code_size = byte_code.size();
|
||||
std::vector<uint8_t> machine_code(MAX_CODE_SIZE);
|
||||
size_t machine_code_size = machine_code.size();
|
||||
std::vector<uint8_t> request_buffer;
|
||||
_ebpf_operation_load_code_reply reply;
|
||||
struct ubpf_vm* vm = nullptr;
|
||||
|
@ -300,7 +300,15 @@ ebpf_api_load_program(
|
|||
return result;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> file_name_bytes(strlen(file_name));
|
||||
std::vector<uint8_t> section_name_bytes(strlen(section_name));
|
||||
std::copy(file_name, file_name + file_name_bytes.size(), file_name_bytes.begin());
|
||||
std::copy(section_name, section_name + section_name_bytes.size(), section_name_bytes.begin());
|
||||
|
||||
if (execution_type == EBPF_EXECUTION_JIT) {
|
||||
std::vector<uint8_t> machine_code(MAX_CODE_SIZE);
|
||||
size_t machine_code_size = machine_code.size();
|
||||
|
||||
// JIT code.
|
||||
vm = ubpf_create();
|
||||
if (vm == nullptr) {
|
||||
|
@ -320,28 +328,25 @@ ebpf_api_load_program(
|
|||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
machine_code.resize(machine_code_size);
|
||||
|
||||
request_buffer.resize(machine_code.size() + offsetof(ebpf_operation_load_code_request_t, code));
|
||||
auto request = reinterpret_cast<ebpf_operation_load_code_request_t*>(request_buffer.data());
|
||||
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_LOAD_CODE;
|
||||
request->header.length = static_cast<uint16_t>(request_buffer.size());
|
||||
request->code_type = EBPF_CODE_NATIVE;
|
||||
std::copy(
|
||||
machine_code.begin(),
|
||||
machine_code.end(),
|
||||
request_buffer.begin() + offsetof(ebpf_operation_load_code_request_t, code));
|
||||
} else {
|
||||
request_buffer.resize(byte_code.size() + offsetof(ebpf_operation_load_code_request_t, code));
|
||||
auto request = reinterpret_cast<ebpf_operation_load_code_request_t*>(request_buffer.data());
|
||||
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_LOAD_CODE;
|
||||
request->header.length = static_cast<uint16_t>(request_buffer.size());
|
||||
request->code_type = EBPF_CODE_EBPF;
|
||||
std::copy(
|
||||
byte_code.begin(),
|
||||
byte_code.end(),
|
||||
request_buffer.begin() + offsetof(ebpf_operation_load_code_request_t, code));
|
||||
byte_code = machine_code;
|
||||
}
|
||||
|
||||
request_buffer.resize(
|
||||
offsetof(ebpf_operation_load_code_request_t, data) + file_name_bytes.size() + section_name_bytes.size() +
|
||||
byte_code.size());
|
||||
auto request = reinterpret_cast<ebpf_operation_load_code_request_t*>(request_buffer.data());
|
||||
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_LOAD_CODE;
|
||||
request->header.length = static_cast<uint16_t>(request_buffer.size());
|
||||
request->code_type = execution_type == EBPF_EXECUTION_JIT ? EBPF_CODE_NATIVE : EBPF_CODE_EBPF;
|
||||
request->file_name_offset = offsetof(ebpf_operation_load_code_request_t, data);
|
||||
request->section_name_offset = request->file_name_offset + static_cast<uint16_t>(file_name_bytes.size());
|
||||
request->code_offset = request->section_name_offset + static_cast<uint16_t>(section_name_bytes.size());
|
||||
std::copy(file_name_bytes.begin(), file_name_bytes.end(), request_buffer.begin() + request->file_name_offset);
|
||||
std::copy(
|
||||
section_name_bytes.begin(), section_name_bytes.end(), request_buffer.begin() + request->section_name_offset);
|
||||
|
||||
std::copy(byte_code.begin(), byte_code.end(), request_buffer.begin() + request->code_offset);
|
||||
|
||||
result = invoke_ioctl(device_handle, request_buffer, reply);
|
||||
|
||||
if (result != ERROR_SUCCESS) {
|
||||
|
@ -361,7 +366,7 @@ ebpf_api_load_program(
|
|||
}
|
||||
|
||||
void
|
||||
ebpf_api_free_error_message(const char* error_message)
|
||||
ebpf_api_free_string(const char* error_message)
|
||||
{
|
||||
return free(const_cast<char*>(error_message));
|
||||
}
|
||||
|
@ -508,25 +513,25 @@ ebpf_api_map_delete_element(ebpf_handle_t handle, uint32_t key_size, const uint8
|
|||
}
|
||||
|
||||
uint32_t
|
||||
ebpf_api_map_next_key(ebpf_handle_t handle, uint32_t key_size, const uint8_t* previous_key, uint8_t* next_key)
|
||||
ebpf_api_get_next_map_key(ebpf_handle_t handle, uint32_t key_size, const uint8_t* previous_key, uint8_t* next_key)
|
||||
{
|
||||
std::vector<uint8_t> request_buffer(offsetof(ebpf_operation_map_next_key_request_t, previous_key) + key_size);
|
||||
std::vector<uint8_t> reply_buffer(offsetof(ebpf_operation_map_next_key_reply_t, next_key) + key_size);
|
||||
auto request = reinterpret_cast<ebpf_operation_map_next_key_request_t*>(request_buffer.data());
|
||||
auto reply = reinterpret_cast<ebpf_operation_map_next_key_reply_t*>(reply_buffer.data());
|
||||
std::vector<uint8_t> request_buffer(offsetof(ebpf_operation_map_get_next_key_request_t, previous_key) + key_size);
|
||||
std::vector<uint8_t> reply_buffer(offsetof(ebpf_operation_map_get_next_key_reply_t, next_key) + key_size);
|
||||
auto request = reinterpret_cast<ebpf_operation_map_get_next_key_request_t*>(request_buffer.data());
|
||||
auto reply = reinterpret_cast<ebpf_operation_map_get_next_key_reply_t*>(reply_buffer.data());
|
||||
|
||||
request->header.length = static_cast<uint16_t>(request_buffer.size());
|
||||
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_MAP_NEXT_KEY;
|
||||
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_MAP_GET_NEXT_KEY;
|
||||
request->handle = reinterpret_cast<uint64_t>(handle);
|
||||
if (previous_key) {
|
||||
std::copy(previous_key, previous_key + key_size, request->previous_key);
|
||||
} else {
|
||||
request->header.length = offsetof(ebpf_operation_map_next_key_request_t, previous_key);
|
||||
request->header.length = offsetof(ebpf_operation_map_get_next_key_request_t, previous_key);
|
||||
}
|
||||
|
||||
auto retval = invoke_ioctl(device_handle, request_buffer, reply_buffer);
|
||||
|
||||
if (reply->header.id != ebpf_operation_id_t::EBPF_OPERATION_MAP_NEXT_KEY) {
|
||||
if (reply->header.id != ebpf_operation_id_t::EBPF_OPERATION_MAP_GET_NEXT_KEY) {
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -537,14 +542,29 @@ ebpf_api_map_next_key(ebpf_handle_t handle, uint32_t key_size, const uint8_t* pr
|
|||
}
|
||||
|
||||
uint32_t
|
||||
ebpf_api_map_enumerate(ebpf_handle_t previous_handle, ebpf_handle_t* next_handle)
|
||||
ebpf_api_get_next_map(ebpf_handle_t previous_handle, ebpf_handle_t* next_handle)
|
||||
{
|
||||
_ebpf_operation_enumerate_maps_request request{
|
||||
_ebpf_operation_get_next_map_request request{
|
||||
sizeof(request), ebpf_operation_id_t::EBPF_OPERATION_GET_NEXT_MAP, reinterpret_cast<uint64_t>(previous_handle)};
|
||||
|
||||
_ebpf_operation_get_next_map_reply reply;
|
||||
|
||||
uint32_t retval = invoke_ioctl(device_handle, request, reply);
|
||||
if (retval == ERROR_SUCCESS) {
|
||||
*next_handle = reinterpret_cast<ebpf_handle_t>(reply.next_handle);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ebpf_api_get_next_program(ebpf_handle_t previous_handle, ebpf_handle_t* next_handle)
|
||||
{
|
||||
_ebpf_operation_get_next_program_request request{
|
||||
sizeof(request),
|
||||
ebpf_operation_id_t::EBPF_OPERATION_ENUMERATE_MAPS,
|
||||
ebpf_operation_id_t::EBPF_OPERATION_GET_NEXT_PROGRAM,
|
||||
reinterpret_cast<uint64_t>(previous_handle)};
|
||||
|
||||
_ebpf_operation_enumerate_maps_reply reply;
|
||||
_ebpf_operation_get_next_program_reply reply;
|
||||
|
||||
uint32_t retval = invoke_ioctl(device_handle, request, reply);
|
||||
if (retval == ERROR_SUCCESS) {
|
||||
|
@ -578,6 +598,47 @@ ebpf_api_map_query_definition(
|
|||
return retval;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ebpf_api_program_query_information(
|
||||
ebpf_handle_t handle, ebpf_execution_type_t* program_type, const char** file_name, const char** section_name)
|
||||
{
|
||||
std::vector<uint8_t> reply_buffer(1024);
|
||||
_ebpf_operation_query_program_information_request request{
|
||||
sizeof(request),
|
||||
ebpf_operation_id_t::EBPF_OPERATION_QUERY_PROGRAM_INFORMATION,
|
||||
reinterpret_cast<uint64_t>(handle)};
|
||||
|
||||
auto reply = reinterpret_cast<_ebpf_operation_query_program_information_reply*>(reply_buffer.data());
|
||||
|
||||
uint32_t retval = invoke_ioctl(device_handle, request, reply_buffer);
|
||||
if (retval != ERROR_SUCCESS) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
size_t file_name_length = reply->section_name_offset - reply->file_name_offset;
|
||||
size_t section_name_length = reply->header.length - reply->section_name_offset;
|
||||
char* local_file_name = reinterpret_cast<char*>(calloc(file_name_length + 1, sizeof(char)));
|
||||
char* local_section_name = reinterpret_cast<char*>(calloc(section_name_length + 1, sizeof(char)));
|
||||
|
||||
if (!local_file_name || !local_section_name) {
|
||||
free(local_file_name);
|
||||
free(local_section_name);
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
memcpy(local_file_name, reply_buffer.data() + reply->file_name_offset, file_name_length);
|
||||
memcpy(local_section_name, reply_buffer.data() + reply->section_name_offset, section_name_length);
|
||||
|
||||
local_file_name[file_name_length] = '\0';
|
||||
local_section_name[section_name_length] = '\0';
|
||||
|
||||
*program_type = reply->code_type == EBPF_CODE_NATIVE ? EBPF_EXECUTION_JIT : EBPF_EXECUTION_INTERPRET;
|
||||
*file_name = local_file_name;
|
||||
*section_name = local_section_name;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_api_delete_map(ebpf_handle_t handle)
|
||||
{
|
||||
|
|
|
@ -27,6 +27,11 @@ typedef struct _ebpf_core_code_entry
|
|||
// pointer to code buffer
|
||||
ebpf_code_type_t code_type;
|
||||
|
||||
uint8_t* file_name;
|
||||
size_t file_name_length;
|
||||
uint8_t* section_name;
|
||||
size_t section_name_length;
|
||||
|
||||
// determinant is code_type
|
||||
union
|
||||
{
|
||||
|
@ -302,7 +307,7 @@ ebpf_core_terminate()
|
|||
ebpf_lock_unlock(&_ebpf_core_pinning_table_lock, &state);
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_attach_code(_In_ const struct _ebpf_operation_attach_detach_request* request)
|
||||
{
|
||||
ebpf_error_code_t retval = EBPF_ERROR_NOT_FOUND;
|
||||
|
@ -331,7 +336,7 @@ Done:
|
|||
return retval;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_detach_code(_In_ const struct _ebpf_operation_attach_detach_request* request)
|
||||
{
|
||||
ebpf_error_code_t retval = EBPF_ERROR_NOT_FOUND;
|
||||
|
@ -351,30 +356,49 @@ Done:
|
|||
return retval;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_unload_code(_In_ const struct _ebpf_operation_unload_code_request* request)
|
||||
{
|
||||
return _ebpf_core_delete_code_entry(request->handle);
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_load_code(
|
||||
_In_ const ebpf_operation_load_code_request_t* request,
|
||||
_Inout_ struct _ebpf_operation_load_code_reply* reply,
|
||||
uint16_t reply_length)
|
||||
{
|
||||
ebpf_error_code_t retval;
|
||||
size_t code_size = request->header.length - RTL_OFFSET_OF(ebpf_operation_load_code_request_t, code);
|
||||
size_t blob_size = request->header.length - RTL_OFFSET_OF(ebpf_operation_load_code_request_t, data);
|
||||
size_t allocation_size = 0;
|
||||
ebpf_core_code_entry_t* code = NULL;
|
||||
ebpf_core_code_entry_t* code_entry = NULL;
|
||||
ebpf_memory_type_t memory_type;
|
||||
uint8_t* file_name = NULL;
|
||||
size_t file_name_length = 0;
|
||||
uint8_t* section_name = NULL;
|
||||
size_t section_name_length = 0;
|
||||
uint8_t* code = NULL;
|
||||
size_t code_length = 0;
|
||||
|
||||
UNREFERENCED_PARAMETER(reply_length);
|
||||
|
||||
retval = ebpf_safe_size_t_add(code_size, sizeof(ebpf_core_code_entry_t), &allocation_size);
|
||||
retval = ebpf_safe_size_t_add(blob_size, sizeof(ebpf_core_code_entry_t), &allocation_size);
|
||||
if (retval != EBPF_ERROR_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
if (request->file_name_offset > request->header.length) {
|
||||
return EBPF_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (request->section_name_offset > request->header.length) {
|
||||
return EBPF_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (request->code_offset > request->header.length) {
|
||||
return EBPF_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (request->code_type == EBPF_CODE_NATIVE) {
|
||||
if (_ebpf_core_code_integrity_state == EBPF_CODE_INTEGRITY_HYPER_VISOR_KERNEL_MODE) {
|
||||
retval = EBPF_ERROR_BLOCKED_BY_POLICY;
|
||||
|
@ -385,24 +409,35 @@ ebpf_core_protocol_load_code(
|
|||
memory_type = EBPF_MEMORY_NO_EXECUTE;
|
||||
}
|
||||
|
||||
code = ebpf_allocate(allocation_size, memory_type);
|
||||
if (!code) {
|
||||
code_entry = ebpf_allocate(allocation_size, memory_type);
|
||||
if (!code_entry) {
|
||||
retval = EBPF_ERROR_OUT_OF_RESOURCES;
|
||||
goto Done;
|
||||
}
|
||||
code->code_or_vm.code = (uint8_t*)(code + 1);
|
||||
|
||||
file_name = (uint8_t*)request + request->file_name_offset;
|
||||
section_name = (uint8_t*)request + request->section_name_offset;
|
||||
code = (uint8_t*)request + request->code_offset;
|
||||
file_name_length = section_name - file_name;
|
||||
section_name_length = code - section_name;
|
||||
code_length = request->header.length - request->code_offset;
|
||||
|
||||
code_entry->file_name = (uint8_t*)(code_entry + 1);
|
||||
code_entry->file_name_length = file_name_length;
|
||||
memcpy(code_entry->file_name, file_name, code_entry->file_name_length);
|
||||
code_entry->section_name = code_entry->file_name + file_name_length;
|
||||
code_entry->section_name_length = section_name_length;
|
||||
memcpy(code_entry->section_name, section_name, code_entry->section_name_length);
|
||||
|
||||
if (request->code_type == EBPF_CODE_NATIVE) {
|
||||
code->code_type = EBPF_CODE_NATIVE;
|
||||
memcpy(
|
||||
code->code_or_vm.code,
|
||||
request->code,
|
||||
request->header.length - RTL_OFFSET_OF(ebpf_operation_load_code_request_t, code));
|
||||
code_entry->code_type = EBPF_CODE_NATIVE;
|
||||
code_entry->code_or_vm.code = code_entry->section_name + section_name_length;
|
||||
memcpy(code_entry->code_or_vm.code, code, code_length);
|
||||
} else {
|
||||
char* error_message = NULL;
|
||||
code->code_type = EBPF_CODE_EBPF;
|
||||
code->code_or_vm.vm = ubpf_create();
|
||||
if (!code->code_or_vm.vm) {
|
||||
code_entry->code_type = EBPF_CODE_EBPF;
|
||||
code_entry->code_or_vm.vm = ubpf_create();
|
||||
if (!code_entry->code_or_vm.vm) {
|
||||
retval = EBPF_ERROR_OUT_OF_RESOURCES;
|
||||
goto Done;
|
||||
}
|
||||
|
@ -410,30 +445,30 @@ ebpf_core_protocol_load_code(
|
|||
// BUG - ubpf implements bounds checking to detect interpreted code accesing
|
||||
// memory out of bounds. Currently this is flagging valid access checks and
|
||||
// failing.
|
||||
toggle_bounds_check(code->code_or_vm.vm, false);
|
||||
toggle_bounds_check(code_entry->code_or_vm.vm, false);
|
||||
|
||||
ubpf_register_helper_resolver(code->code_or_vm.vm, code, ebpf_core_interpreter_helper_resolver);
|
||||
if (ubpf_load(code->code_or_vm.vm, &request->code[0], (uint32_t)code_size, &error_message) != 0) {
|
||||
ubpf_register_helper_resolver(code_entry->code_or_vm.vm, code_entry, ebpf_core_interpreter_helper_resolver);
|
||||
if (ubpf_load(code_entry->code_or_vm.vm, code, (uint32_t)code_length, &error_message) != 0) {
|
||||
ebpf_free(error_message);
|
||||
retval = EBPF_ERROR_INVALID_PARAMETER;
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
reply->handle = _ebpf_core_insert_code_entry(code);
|
||||
reply->handle = _ebpf_core_insert_code_entry(code_entry);
|
||||
|
||||
retval = reply->handle != UINT64_MAX ? EBPF_ERROR_SUCCESS : EBPF_ERROR_OUT_OF_RESOURCES;
|
||||
|
||||
Done:
|
||||
if (retval != EBPF_ERROR_SUCCESS) {
|
||||
if (code && code->code_type == EBPF_CODE_EBPF) {
|
||||
ubpf_destroy(code->code_or_vm.vm);
|
||||
if (code_entry && code_entry->code_type == EBPF_CODE_EBPF) {
|
||||
ubpf_destroy(code_entry->code_or_vm.vm);
|
||||
}
|
||||
ebpf_free(code);
|
||||
ebpf_free(code_entry);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_resolve_helper(
|
||||
_In_ const struct _ebpf_operation_resolve_helper_request* request,
|
||||
_Inout_ struct _ebpf_operation_resolve_helper_reply* reply,
|
||||
|
@ -449,7 +484,7 @@ ebpf_core_protocol_resolve_helper(
|
|||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_resolve_map(
|
||||
_In_ const struct _ebpf_operation_resolve_map_request* request,
|
||||
_Inout_ struct _ebpf_operation_resolve_map_reply* reply,
|
||||
|
@ -492,7 +527,7 @@ ebpf_core_invoke_hook(_In_ ebpf_program_type_t hook_point, _Inout_ void* context
|
|||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_create_map(
|
||||
_In_ const struct _ebpf_operation_create_map_request* request,
|
||||
_Inout_ struct _ebpf_operation_create_map_reply* reply,
|
||||
|
@ -535,7 +570,7 @@ Done:
|
|||
return retval;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_map_lookup_element(
|
||||
_In_ const ebpf_operation_map_lookup_element_request_t* request,
|
||||
_Inout_ ebpf_operation_map_lookup_element_reply_t* reply,
|
||||
|
@ -579,7 +614,7 @@ Done:
|
|||
return retval;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_map_update_element(_In_ const epf_operation_map_update_element_request_t* request)
|
||||
{
|
||||
ebpf_error_code_t retval;
|
||||
|
@ -607,7 +642,7 @@ Done:
|
|||
return retval;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_map_delete_element(_In_ const ebpf_operation_map_delete_element_request_t* request)
|
||||
{
|
||||
ebpf_error_code_t retval;
|
||||
|
@ -634,10 +669,10 @@ Done:
|
|||
return retval;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_map_get_next_key(
|
||||
_In_ const ebpf_operation_map_next_key_request_t* request,
|
||||
_Inout_ ebpf_operation_map_next_key_reply_t* reply,
|
||||
_In_ const ebpf_operation_map_get_next_key_request_t* request,
|
||||
_Inout_ ebpf_operation_map_get_next_key_reply_t* reply,
|
||||
uint16_t reply_length)
|
||||
{
|
||||
ebpf_error_code_t retval;
|
||||
|
@ -659,11 +694,11 @@ ebpf_core_protocol_map_get_next_key(
|
|||
}
|
||||
|
||||
// If request length shows zero key, treat as restart.
|
||||
if (request->header.length == RTL_OFFSET_OF(ebpf_operation_map_next_key_request_t, previous_key)) {
|
||||
if (request->header.length == RTL_OFFSET_OF(ebpf_operation_map_get_next_key_request_t, previous_key)) {
|
||||
previous_key = NULL;
|
||||
} else if (
|
||||
request->header.length <
|
||||
(RTL_OFFSET_OF(ebpf_operation_map_next_key_request_t, previous_key) + map->ebpf_map_definition.key_size)) {
|
||||
(RTL_OFFSET_OF(ebpf_operation_map_get_next_key_request_t, previous_key) + map->ebpf_map_definition.key_size)) {
|
||||
retval = EBPF_ERROR_INVALID_PARAMETER;
|
||||
goto Done;
|
||||
} else {
|
||||
|
@ -672,7 +707,7 @@ ebpf_core_protocol_map_get_next_key(
|
|||
|
||||
next_key = reply->next_key;
|
||||
if (reply_length <
|
||||
(RTL_OFFSET_OF(ebpf_operation_map_next_key_reply_t, next_key) + map->ebpf_map_definition.key_size)) {
|
||||
(RTL_OFFSET_OF(ebpf_operation_map_get_next_key_reply_t, next_key) + map->ebpf_map_definition.key_size)) {
|
||||
retval = EBPF_ERROR_INVALID_PARAMETER;
|
||||
goto Done;
|
||||
}
|
||||
|
@ -683,10 +718,10 @@ Done:
|
|||
return retval;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
ebpf_core_protocol_enumerate_maps(
|
||||
_In_ const struct _ebpf_operation_enumerate_maps_request* request,
|
||||
_Inout_ struct _ebpf_operation_enumerate_maps_reply* reply,
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_get_next_map(
|
||||
_In_ const struct _ebpf_operation_get_next_map_request* request,
|
||||
_Inout_ struct _ebpf_operation_get_next_map_reply* reply,
|
||||
uint16_t reply_length)
|
||||
{
|
||||
uint64_t next_handle = request->previous_handle;
|
||||
|
@ -717,7 +752,41 @@ ebpf_core_protocol_enumerate_maps(
|
|||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_get_next_program(
|
||||
_In_ const struct _ebpf_operation_get_next_program_request* request,
|
||||
_Inout_ struct _ebpf_operation_get_next_program_reply* reply,
|
||||
uint16_t reply_length)
|
||||
{
|
||||
uint64_t next_handle = request->previous_handle;
|
||||
UNREFERENCED_PARAMETER(reply_length);
|
||||
|
||||
// Start search from begining
|
||||
if (next_handle == UINT64_MAX) {
|
||||
next_handle = 1;
|
||||
} else {
|
||||
next_handle++;
|
||||
}
|
||||
|
||||
ebpf_lock_state_t state;
|
||||
ebpf_lock_lock(&_ebpf_core_code_entry_table_lock, &state);
|
||||
for (; next_handle < RTL_COUNT_OF(_ebpf_core_code_entry_table); next_handle++) {
|
||||
if (_ebpf_core_code_entry_table[next_handle] != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ebpf_lock_unlock(&_ebpf_core_code_entry_table_lock, &state);
|
||||
|
||||
// No more handles, return end
|
||||
if (next_handle == RTL_COUNT_OF(_ebpf_core_code_entry_table)) {
|
||||
next_handle = UINT64_MAX;
|
||||
}
|
||||
|
||||
reply->next_handle = next_handle;
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_query_map_definition(
|
||||
_In_ const struct _ebpf_operation_query_map_definition_request* request,
|
||||
_Inout_ struct _ebpf_operation_query_map_definition_reply* reply,
|
||||
|
@ -736,7 +805,40 @@ ebpf_core_protocol_query_map_definition(
|
|||
return retval;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_query_program_information(
|
||||
_In_ const struct _ebpf_operation_query_program_information_request* request,
|
||||
_Inout_ struct _ebpf_operation_query_program_information_reply* reply,
|
||||
uint16_t reply_length)
|
||||
{
|
||||
ebpf_core_code_entry_t* code = NULL;
|
||||
size_t required_reply_length;
|
||||
|
||||
code = _ebpf_core_find_code_entry(request->handle);
|
||||
if (!code) {
|
||||
return EBPF_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
required_reply_length = RTL_OFFSET_OF(struct _ebpf_operation_query_program_information_reply, data) +
|
||||
code->file_name_length + code->section_name_length;
|
||||
|
||||
if (reply_length < required_reply_length) {
|
||||
return EBPF_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
reply->file_name_offset = RTL_OFFSET_OF(struct _ebpf_operation_query_program_information_reply, data);
|
||||
reply->section_name_offset = reply->file_name_offset + (uint16_t)code->file_name_length;
|
||||
|
||||
memcpy(reply->data, code->file_name, code->file_name_length);
|
||||
memcpy(reply->data + code->file_name_length, code->section_name, code->section_name_length);
|
||||
reply->code_type = code->code_type;
|
||||
|
||||
reply->header.length = (uint16_t)required_reply_length;
|
||||
|
||||
return EBPF_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_update_map_pinning(_In_ const struct _ebpf_operation_update_map_pinning_request* request)
|
||||
{
|
||||
ebpf_error_code_t retval;
|
||||
|
@ -777,7 +879,7 @@ Done:
|
|||
return retval;
|
||||
}
|
||||
|
||||
ebpf_error_code_t
|
||||
static ebpf_error_code_t
|
||||
ebpf_core_protocol_lookup_map_pinning(
|
||||
_In_ const struct _ebpf_operation_lookup_map_pinning_request* request,
|
||||
_Inout_ struct _ebpf_operation_lookup_map_pinning_reply* reply,
|
||||
|
@ -805,21 +907,21 @@ Done:
|
|||
return retval;
|
||||
}
|
||||
|
||||
void*
|
||||
static void*
|
||||
_ebpf_core_map_lookup_element(ebpf_core_map_t* map, const uint8_t* key)
|
||||
{
|
||||
size_t type = map->ebpf_map_definition.type;
|
||||
return ebpf_map_function_tables[type].lookup_entry(map, key);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
_ebpf_core_map_update_element(ebpf_core_map_t* map, const uint8_t* key, const uint8_t* value)
|
||||
{
|
||||
size_t type = map->ebpf_map_definition.type;
|
||||
ebpf_map_function_tables[type].update_entry(map, key, value);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
_ebpf_core_map_delete_element(ebpf_core_map_t* map, const uint8_t* key)
|
||||
{
|
||||
size_t type = map->ebpf_map_definition.type;
|
||||
|
@ -859,14 +961,20 @@ ebpf_protocol_handler_t EbpfProtocolHandlers[EBPF_OPERATION_LOOKUP_MAP_PINNING +
|
|||
{ebpf_core_protocol_map_update_element, sizeof(struct _ebpf_operation_map_update_element_request), 0},
|
||||
{ebpf_core_protocol_map_delete_element, sizeof(struct _ebpf_operation_map_delete_element_request), 0},
|
||||
{(ebpf_error_code_t(__cdecl*)(const void*))ebpf_core_protocol_map_get_next_key,
|
||||
RTL_OFFSET_OF(ebpf_operation_map_next_key_request_t, previous_key),
|
||||
sizeof(ebpf_operation_map_next_key_reply_t)},
|
||||
{(ebpf_error_code_t(__cdecl*)(const void*))ebpf_core_protocol_enumerate_maps,
|
||||
sizeof(struct _ebpf_operation_enumerate_maps_request),
|
||||
sizeof(struct _ebpf_operation_enumerate_maps_reply)},
|
||||
RTL_OFFSET_OF(ebpf_operation_map_get_next_key_request_t, previous_key),
|
||||
sizeof(ebpf_operation_map_get_next_key_reply_t)},
|
||||
{(ebpf_error_code_t(__cdecl*)(const void*))ebpf_core_protocol_get_next_map,
|
||||
sizeof(struct _ebpf_operation_get_next_map_request),
|
||||
sizeof(struct _ebpf_operation_get_next_map_reply)},
|
||||
{(ebpf_error_code_t(__cdecl*)(const void*))ebpf_core_protocol_get_next_program,
|
||||
sizeof(struct _ebpf_operation_get_next_program_request),
|
||||
sizeof(struct _ebpf_operation_get_next_program_reply)},
|
||||
{(ebpf_error_code_t(__cdecl*)(const void*))ebpf_core_protocol_query_map_definition,
|
||||
sizeof(struct _ebpf_operation_query_map_definition_request),
|
||||
sizeof(struct _ebpf_operation_query_map_definition_reply)},
|
||||
{(ebpf_error_code_t(__cdecl*)(const void*))ebpf_core_protocol_query_program_information,
|
||||
sizeof(struct _ebpf_operation_query_program_information_request),
|
||||
sizeof(struct _ebpf_operation_query_program_information_reply)},
|
||||
{ebpf_core_protocol_update_map_pinning, sizeof(struct _ebpf_operation_update_map_pinning_request), 0},
|
||||
{(ebpf_error_code_t(__cdecl*)(const void*))ebpf_core_protocol_lookup_map_pinning,
|
||||
sizeof(struct _ebpf_operation_lookup_map_pinning_request),
|
||||
|
|
|
@ -155,7 +155,7 @@ TEST_CASE("droppacket-jit", "[droppacket_jit]")
|
|||
bool ec_initialized = false;
|
||||
bool api_initialized = false;
|
||||
_unwind_helper on_exit([&] {
|
||||
ebpf_api_free_error_message(error_message);
|
||||
ebpf_api_free_string(error_message);
|
||||
if (api_initialized)
|
||||
ebpf_api_terminate();
|
||||
if (ec_initialized)
|
||||
|
@ -230,7 +230,7 @@ TEST_CASE("droppacket-interpret", "[droppacket_interpret]")
|
|||
ebpf_handle_t map_handle;
|
||||
uint32_t count_of_map_handle = 1;
|
||||
_unwind_helper on_exit([&] {
|
||||
ebpf_api_free_error_message(error_message);
|
||||
ebpf_api_free_string(error_message);
|
||||
if (api_initialized)
|
||||
ebpf_api_terminate();
|
||||
if (ec_initialized)
|
||||
|
@ -300,7 +300,7 @@ TEST_CASE("enum section", "[enum sections]")
|
|||
bool ec_initialized = false;
|
||||
bool api_initialized = false;
|
||||
_unwind_helper on_exit([&] {
|
||||
ebpf_api_free_error_message(error_message);
|
||||
ebpf_api_free_string(error_message);
|
||||
ebpf_api_elf_free(section_data);
|
||||
if (api_initialized)
|
||||
ebpf_api_terminate();
|
||||
|
@ -347,8 +347,8 @@ TEST_CASE("verify section", "[verify section]")
|
|||
bool ec_initialized = false;
|
||||
bool api_initialized = false;
|
||||
_unwind_helper on_exit([&] {
|
||||
ebpf_api_free_error_message(error_message);
|
||||
ebpf_api_free_error_message(report);
|
||||
ebpf_api_free_string(error_message);
|
||||
ebpf_api_free_string(report);
|
||||
if (api_initialized)
|
||||
ebpf_api_terminate();
|
||||
if (ec_initialized)
|
||||
|
@ -430,7 +430,7 @@ TEST_CASE("bindmonitor-interpret", "[bindmonitor_interpret]")
|
|||
uint64_t fake_pid = 12345;
|
||||
|
||||
_unwind_helper on_exit([&] {
|
||||
ebpf_api_free_error_message(error_message);
|
||||
ebpf_api_free_string(error_message);
|
||||
if (api_initialized)
|
||||
ebpf_api_terminate();
|
||||
if (ec_initialized)
|
||||
|
@ -502,11 +502,11 @@ TEST_CASE("bindmonitor-interpret", "[bindmonitor_interpret]")
|
|||
&test_handle) == ERROR_NOT_FOUND);
|
||||
|
||||
ebpf_handle_t handle_iterator = INVALID_HANDLE_VALUE;
|
||||
REQUIRE(ebpf_api_map_enumerate(handle_iterator, &handle_iterator) == ERROR_SUCCESS);
|
||||
REQUIRE(ebpf_api_get_next_map(handle_iterator, &handle_iterator) == ERROR_SUCCESS);
|
||||
REQUIRE(handle_iterator == map_handles[0]);
|
||||
REQUIRE(ebpf_api_map_enumerate(handle_iterator, &handle_iterator) == ERROR_SUCCESS);
|
||||
REQUIRE(ebpf_api_get_next_map(handle_iterator, &handle_iterator) == ERROR_SUCCESS);
|
||||
REQUIRE(handle_iterator == map_handles[1]);
|
||||
REQUIRE(ebpf_api_map_enumerate(handle_iterator, &handle_iterator) == ERROR_SUCCESS);
|
||||
REQUIRE(ebpf_api_get_next_map(handle_iterator, &handle_iterator) == ERROR_SUCCESS);
|
||||
REQUIRE(handle_iterator == INVALID_HANDLE_VALUE);
|
||||
|
||||
REQUIRE(ebpf_api_attach_program(program_handle, EBPF_PROGRAM_TYPE_BIND) == ERROR_SUCCESS);
|
||||
|
@ -544,16 +544,93 @@ TEST_CASE("bindmonitor-interpret", "[bindmonitor_interpret]")
|
|||
|
||||
uint64_t pid;
|
||||
REQUIRE(
|
||||
ebpf_api_map_next_key(map_handles[0], sizeof(uint64_t), NULL, reinterpret_cast<uint8_t*>(&pid)) ==
|
||||
ebpf_api_get_next_map_key(map_handles[0], sizeof(uint64_t), NULL, reinterpret_cast<uint8_t*>(&pid)) ==
|
||||
ERROR_SUCCESS);
|
||||
REQUIRE(pid != 0);
|
||||
REQUIRE(
|
||||
ebpf_api_map_next_key(
|
||||
ebpf_api_get_next_map_key(
|
||||
map_handles[0], sizeof(uint64_t), reinterpret_cast<uint8_t*>(&pid), reinterpret_cast<uint8_t*>(&pid)) ==
|
||||
ERROR_SUCCESS);
|
||||
REQUIRE(pid != 0);
|
||||
REQUIRE(
|
||||
ebpf_api_map_next_key(
|
||||
ebpf_api_get_next_map_key(
|
||||
map_handles[0], sizeof(uint64_t), reinterpret_cast<uint8_t*>(&pid), reinterpret_cast<uint8_t*>(&pid)) ==
|
||||
ERROR_NO_MORE_ITEMS);
|
||||
}
|
||||
|
||||
TEST_CASE("enumerate_and_query_programs", "[enumerate_and_query_programs]")
|
||||
{
|
||||
device_io_control_handler = GlueDeviceIoControl;
|
||||
create_file_handler = GlueCreateFileW;
|
||||
close_handle_handler = GlueCloseHandle;
|
||||
|
||||
ebpf_handle_t program_handle;
|
||||
ebpf_handle_t map_handles[3];
|
||||
uint32_t count_of_map_handle = 1;
|
||||
const char* error_message = NULL;
|
||||
bool ec_initialized = false;
|
||||
bool api_initialized = false;
|
||||
const char* file_name = nullptr;
|
||||
const char* section_name = nullptr;
|
||||
|
||||
_unwind_helper on_exit([&] {
|
||||
ebpf_api_free_string(error_message);
|
||||
if (api_initialized)
|
||||
ebpf_api_terminate();
|
||||
if (ec_initialized)
|
||||
ebpf_core_terminate();
|
||||
ebpf_api_free_string(file_name);
|
||||
ebpf_api_free_string(section_name);
|
||||
});
|
||||
|
||||
REQUIRE(ebpf_core_initialize() == EBPF_ERROR_SUCCESS);
|
||||
ec_initialized = true;
|
||||
|
||||
REQUIRE(ebpf_api_initiate() == ERROR_SUCCESS);
|
||||
api_initialized = true;
|
||||
|
||||
REQUIRE(
|
||||
ebpf_api_load_program(
|
||||
SAMPLE_PATH "droppacket.o",
|
||||
"xdp",
|
||||
EBPF_EXECUTION_JIT,
|
||||
&program_handle,
|
||||
&count_of_map_handle,
|
||||
map_handles,
|
||||
&error_message) == ERROR_SUCCESS);
|
||||
|
||||
REQUIRE(
|
||||
ebpf_api_load_program(
|
||||
SAMPLE_PATH "droppacket.o",
|
||||
"xdp",
|
||||
EBPF_EXECUTION_INTERPRET,
|
||||
&program_handle,
|
||||
&count_of_map_handle,
|
||||
map_handles,
|
||||
&error_message) == ERROR_SUCCESS);
|
||||
|
||||
ebpf_execution_type_t type;
|
||||
program_handle = INVALID_HANDLE_VALUE;
|
||||
REQUIRE(ebpf_api_get_next_program(program_handle, &program_handle) == ERROR_SUCCESS);
|
||||
REQUIRE(ebpf_api_program_query_information(program_handle, &type, &file_name, §ion_name) == ERROR_SUCCESS);
|
||||
REQUIRE(type == EBPF_EXECUTION_JIT);
|
||||
REQUIRE(strcmp(file_name, SAMPLE_PATH "droppacket.o") == 0);
|
||||
REQUIRE(strcmp(section_name, "xdp") == 0);
|
||||
REQUIRE(program_handle != INVALID_HANDLE_VALUE);
|
||||
ebpf_api_free_string(file_name);
|
||||
ebpf_api_free_string(section_name);
|
||||
file_name = nullptr;
|
||||
section_name = nullptr;
|
||||
REQUIRE(ebpf_api_get_next_program(program_handle, &program_handle) == ERROR_SUCCESS);
|
||||
REQUIRE(program_handle != INVALID_HANDLE_VALUE);
|
||||
REQUIRE(ebpf_api_program_query_information(program_handle, &type, &file_name, §ion_name) == ERROR_SUCCESS);
|
||||
REQUIRE(type == EBPF_EXECUTION_INTERPRET);
|
||||
REQUIRE(strcmp(file_name, SAMPLE_PATH "droppacket.o") == 0);
|
||||
REQUIRE(strcmp(section_name, "xdp") == 0);
|
||||
ebpf_api_free_string(file_name);
|
||||
ebpf_api_free_string(section_name);
|
||||
file_name = nullptr;
|
||||
section_name = nullptr;
|
||||
REQUIRE(ebpf_api_get_next_program(program_handle, &program_handle) == ERROR_SUCCESS);
|
||||
REQUIRE(program_handle == INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
<AdditionalIncludeDirectories>$(SolutionDir)src\ebpf\include;$(SolutionDir)external\ubpf\vm;$(SolutionDir)external\ubpf\vm\inc;$(SolutionDir)external\ebpf-verifier\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
// clang -O2 -Wall -c droppacket.c -o dropjit.o
|
||||
//
|
||||
// For bpf code: clang -target bpf -O2 -Wall -c repro.c -o repro.o
|
||||
// this passes the checker
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned long long uint64_t;
|
||||
#else
|
||||
typedef unsigned long uint64_t;
|
||||
#endif
|
||||
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
typedef struct _bind_md
|
||||
{
|
||||
char* app_id_start;
|
||||
char* app_id_end;
|
||||
uint64_t process_id;
|
||||
uint8_t socket_address[16];
|
||||
uint8_t socket_address_length;
|
||||
uint8_t operation;
|
||||
uint8_t protocol;
|
||||
} bind_md_t;
|
||||
|
||||
typedef enum _bind_operation
|
||||
{
|
||||
BIND_OPERATION_BIND, // Entry to bind
|
||||
BIND_OPERATION_POST_BIND, // After port allocation
|
||||
BIND_OPERATION_UNBIND, // Release port
|
||||
} bind_operation_t;
|
||||
|
||||
typedef enum _bind_action
|
||||
{
|
||||
BIND_PERMIT,
|
||||
BIND_DENY,
|
||||
BIND_REDIRECT,
|
||||
} bind_action_t;
|
||||
|
||||
typedef struct _bpf_map_def
|
||||
{
|
||||
uint32_t size;
|
||||
uint32_t type;
|
||||
uint32_t key_size;
|
||||
uint32_t value_size;
|
||||
uint32_t max_entries;
|
||||
} bpf_map_def_t;
|
||||
|
||||
typedef enum _ebpf_map_type
|
||||
{
|
||||
EBPF_MAP_TYPE_UNSPECIFIED = 0,
|
||||
EBPF_MAP_TYPE_HASH = 1,
|
||||
EBPF_MAP_TYPE_ARRAY = 2,
|
||||
} ebpf_map_type_t;
|
||||
|
||||
typedef void* (*ebpf_map_lookup_elem_t)(bpf_map_def_t* map, void* key);
|
||||
#define ebpf_map_lookup_elem ((ebpf_map_lookup_elem_t)1)
|
||||
|
||||
typedef void (*ebpf_map_update_element_t)(bpf_map_def_t* map, void* key, void* data, uint64_t flags);
|
||||
#define ebpf_map_update_element ((ebpf_map_update_element_t)2)
|
||||
|
||||
typedef void (*ebpf_map_delete_elem_t)(bpf_map_def_t* map, void* key);
|
||||
#define ebpf_map_delete_elem ((ebpf_map_delete_elem_t)3)
|
||||
|
||||
#pragma clang section data = "maps"
|
||||
bpf_map_def_t test_map = {
|
||||
.size = sizeof(bpf_map_def_t),
|
||||
.type = EBPF_MAP_TYPE_HASH,
|
||||
.key_size = sizeof(uint64_t),
|
||||
.value_size = sizeof(uint64_t),
|
||||
.max_entries = 1};
|
||||
|
||||
#pragma clang section text = "bind"
|
||||
int
|
||||
BindMonitor(bind_md_t* ctx)
|
||||
{
|
||||
uint64_t key = ctx->process_id;
|
||||
|
||||
uint64_t* value = ebpf_map_lookup_elem(&test_map, &key);
|
||||
|
||||
*value = 1;
|
||||
|
||||
return BIND_PERMIT;
|
||||
}
|
|
@ -73,11 +73,11 @@ handle_ebpf_show_disassembly(
|
|||
const char* error_message = nullptr;
|
||||
if (ebpf_api_elf_disassemble_section(filename.c_str(), section.c_str(), &disassembly, &error_message) != 0) {
|
||||
std::cerr << error_message << std::endl;
|
||||
ebpf_api_free_error_message(error_message);
|
||||
ebpf_api_free_string(error_message);
|
||||
return ERROR_SUPPRESS_OUTPUT;
|
||||
} else {
|
||||
std::cout << disassembly << std::endl;
|
||||
ebpf_api_free_error_message(disassembly);
|
||||
ebpf_api_free_string(disassembly);
|
||||
return NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ handle_ebpf_show_sections(
|
|||
if (ebpf_api_elf_enumerate_sections(
|
||||
filename.c_str(), section.c_str(), level == VL_VERBOSE, §ion_data, &error_message) != 0) {
|
||||
std::cerr << error_message << std::endl;
|
||||
ebpf_api_free_error_message(error_message);
|
||||
ebpf_api_free_string(error_message);
|
||||
ebpf_api_elf_free(section_data);
|
||||
return ERROR_SUPPRESS_OUTPUT;
|
||||
}
|
||||
|
@ -240,8 +240,8 @@ handle_ebpf_show_verification(
|
|||
if (report) {
|
||||
std::cerr << "\nVerification report:\n" << report << std::endl;
|
||||
}
|
||||
ebpf_api_free_error_message(error_message);
|
||||
ebpf_api_free_error_message(report);
|
||||
ebpf_api_free_string(error_message);
|
||||
ebpf_api_free_string(report);
|
||||
return ERROR_SUPPRESS_OUTPUT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "ebpf_api.h"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
static ebpf_handle_t _program_handle = INVALID_HANDLE_VALUE;
|
||||
static ebpf_handle_t _map_handles[10];
|
||||
|
@ -139,7 +140,7 @@ handle_ebpf_add_program(
|
|||
} else {
|
||||
std::cerr << "error " << status << ": could not load program" << std::endl;
|
||||
}
|
||||
ebpf_api_free_error_message(error_message);
|
||||
ebpf_api_free_string(error_message);
|
||||
return ERROR_SUPPRESS_OUTPUT;
|
||||
}
|
||||
|
||||
|
@ -335,6 +336,42 @@ handle_ebpf_show_programs(
|
|||
level = VL_VERBOSE;
|
||||
}
|
||||
|
||||
// TODO: enumerate programs using specified constraints
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
// BUG: We need to implement the other columns and implement filtering.
|
||||
|
||||
std::cout << "\n";
|
||||
std::cout << " File Name Section Requested Execution Type\n";
|
||||
std::cout << "==================== =============== ========================\n";
|
||||
|
||||
ebpf_handle_t program_handle = INVALID_HANDLE_VALUE;
|
||||
for (;;) {
|
||||
const char* program_file_name;
|
||||
const char* program_section_name;
|
||||
const char* program_type_name;
|
||||
ebpf_execution_type_t program_execution_type;
|
||||
status = ebpf_api_get_next_program(program_handle, &program_handle);
|
||||
|
||||
if (status != ERROR_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (program_handle == INVALID_HANDLE_VALUE) {
|
||||
break;
|
||||
}
|
||||
|
||||
status = ebpf_api_program_query_information(
|
||||
program_handle, &program_execution_type, &program_file_name, &program_section_name);
|
||||
|
||||
if (status != ERROR_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
program_type_name = program_execution_type == EBPF_EXECUTION_JIT ? "JIT" : "INTERPRET";
|
||||
std::cout << std::setw(20) << std::right << program_file_name << " " << std::setw(15) << std::right
|
||||
<< program_section_name << " " << std::setw(24) << std::right << program_type_name << "\n";
|
||||
|
||||
ebpf_api_free_string(program_file_name);
|
||||
ebpf_api_free_string(program_section_name);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <WinSock2.h>
|
||||
#include <iostream>
|
||||
#include <Windows.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
WSADATA wsa_data;
|
||||
WSAStartup(2, &wsa_data);
|
||||
|
||||
for (;;) {
|
||||
Sleep(10);
|
||||
|
||||
auto s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (s == INVALID_SOCKET) {
|
||||
continue;
|
||||
}
|
||||
sockaddr_in addr;
|
||||
addr.sin_addr.S_un.S_addr = 0;
|
||||
addr.sin_port = 0;
|
||||
addr.sin_family = AF_INET;
|
||||
bind(s, (sockaddr*)&addr, sizeof(addr));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{db2af239-5251-43f1-babf-11e707dc5523}</ProjectGuid>
|
||||
<RootNamespace>portleak</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="port_leak.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="port_leak.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -30,7 +30,7 @@ load(int argc, char** argv)
|
|||
if (result != ERROR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to load port quota eBPF program\n");
|
||||
fprintf(stderr, "%s", error_message);
|
||||
ebpf_api_free_error_message(error_message);
|
||||
ebpf_api_free_string(error_message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -43,13 +43,13 @@ load(int argc, char** argv)
|
|||
result = ebpf_api_pin_map(maps[0], process_map, sizeof(process_map));
|
||||
if (result != ERROR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to pin eBPF program: %d\n", result);
|
||||
ebpf_api_free_error_message(error_message);
|
||||
ebpf_api_free_string(error_message);
|
||||
return 1;
|
||||
}
|
||||
result = ebpf_api_pin_map(maps[1], limits_map, sizeof(limits_map));
|
||||
if (result != ERROR_SUCCESS) {
|
||||
fprintf(stderr, "Failed to pin eBPF program: %d\n", result);
|
||||
ebpf_api_free_error_message(error_message);
|
||||
ebpf_api_free_string(error_message);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -77,7 +77,7 @@ stats(int argc, char** argv)
|
|||
}
|
||||
|
||||
printf("Pid\tCount\tAppId\n");
|
||||
result = ebpf_api_map_next_key(map, sizeof(uint64_t), nullptr, reinterpret_cast<uint8_t*>(&pid));
|
||||
result = ebpf_api_get_next_map_key(map, sizeof(uint64_t), nullptr, reinterpret_cast<uint8_t*>(&pid));
|
||||
while (result == ERROR_SUCCESS) {
|
||||
memset(&process_entry, 0, sizeof(process_entry));
|
||||
result = ebpf_api_map_lookup_element(
|
||||
|
@ -91,7 +91,7 @@ stats(int argc, char** argv)
|
|||
return 1;
|
||||
}
|
||||
printf("%lld\t%d\t%S\n", pid, process_entry.count, reinterpret_cast<wchar_t*>(process_entry.name));
|
||||
result = ebpf_api_map_next_key(
|
||||
result = ebpf_api_get_next_map_key(
|
||||
map, sizeof(uint64_t), reinterpret_cast<uint8_t*>(&pid), reinterpret_cast<uint8_t*>(&pid));
|
||||
};
|
||||
return 0;
|
||||
|
|
|
@ -117,6 +117,7 @@
|
|||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)src\ebpf\include</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
|
Загрузка…
Ссылка в новой задаче