|
15 | 15 | #include "ebpf_serialize.h" |
16 | 16 | #include "ebpf_shared_framework.h" |
17 | 17 | #include "ebpf_tracelog.h" |
| 18 | +// Undefine Windows min/max macros for ELFIO |
| 19 | +#undef max |
| 20 | +#undef min |
| 21 | +#include "elfio_wrapper.hpp" |
18 | 22 | #include "hash.h" |
19 | 23 | #pragma warning(push) |
20 | 24 | #pragma warning(disable : 4200) // Zero-sized array in struct/union |
@@ -564,7 +568,7 @@ _ebpf_map_lookup_element_batch_helper( |
564 | 568 |
|
565 | 569 | while (count_returned < input_count) { |
566 | 570 | // Fetch the next batch of entries. |
567 | | - size_t entries_to_fetch = min(input_count - count_returned, max_entries_per_batch); |
| 571 | + size_t entries_to_fetch = std::min(input_count - count_returned, max_entries_per_batch); |
568 | 572 |
|
569 | 573 | ebpf_protocol_buffer_t request_buffer( |
570 | 574 | EBPF_OFFSET_OF(_ebpf_operation_map_get_next_key_value_batch_request, previous_key) + |
@@ -772,7 +776,7 @@ _update_map_element_batch( |
772 | 776 | try { |
773 | 777 | for (size_t key_index = 0; key_index < input_count;) { |
774 | 778 | // Compute the number of entries to update in this batch. |
775 | | - size_t entries_to_update = min(input_count - key_index, max_entries_per_batch); |
| 779 | + size_t entries_to_update = std::min(input_count - key_index, max_entries_per_batch); |
776 | 780 |
|
777 | 781 | request_buffer.resize( |
778 | 782 | EBPF_OFFSET_OF(ebpf_operation_map_update_element_batch_request_t, data) + |
@@ -1102,7 +1106,7 @@ ebpf_map_delete_element_batch(fd_t map_fd, _In_ const void* keys, _Inout_ uint32 |
1102 | 1106 | try { |
1103 | 1107 | for (size_t key_index = 0; key_index < input_count;) { |
1104 | 1108 | // Compute the number of entries to update in this batch. |
1105 | | - size_t entries_to_delete = min(input_count - key_index, max_entries_per_batch); |
| 1109 | + size_t entries_to_delete = std::min(input_count - key_index, max_entries_per_batch); |
1106 | 1110 |
|
1107 | 1111 | request_buffer.resize( |
1108 | 1112 | EBPF_OFFSET_OF(ebpf_operation_map_delete_element_batch_request_t, keys) + key_size * entries_to_delete); |
@@ -5252,6 +5256,134 @@ ebpf_map_set_wait_handle(fd_t map_fd, uint64_t index, ebpf_handle_t handle) NO_E |
5252 | 5256 | } |
5253 | 5257 | CATCH_NO_MEMORY_EBPF_RESULT |
5254 | 5258 |
|
| 5259 | +// Context structure for section data extraction |
| 5260 | +typedef struct _ebpf_section_data_context |
| 5261 | +{ |
| 5262 | + const char* section_name; |
| 5263 | + bool section_found; |
| 5264 | + size_t section_size; |
| 5265 | + const uint8_t* section_data; |
| 5266 | +} ebpf_section_data_context_t; |
| 5267 | + |
| 5268 | +// Callback function for PE section iteration |
| 5269 | +static int |
| 5270 | +_ebpf_pe_find_section( |
| 5271 | + _Inout_ void* context, |
| 5272 | + _In_ const VA& va, |
| 5273 | + _In_ const std::string& section_name, |
| 5274 | + _In_ const image_section_header& section_header, |
| 5275 | + _In_ const bounded_buffer* buffer) NO_EXCEPT_TRY |
| 5276 | +{ |
| 5277 | + UNREFERENCED_PARAMETER(va); |
| 5278 | + UNREFERENCED_PARAMETER(section_header); |
| 5279 | + |
| 5280 | + ebpf_section_data_context_t* ctx = static_cast<ebpf_section_data_context_t*>(context); |
| 5281 | + |
| 5282 | + if (section_name == ctx->section_name && buffer != nullptr) { |
| 5283 | + ctx->section_found = true; |
| 5284 | + ctx->section_size = buffer->bufLen; |
| 5285 | + ctx->section_data = buffer->buf; |
| 5286 | + return 1; // Stop iteration |
| 5287 | + } |
| 5288 | + return 0; // Continue iteration |
| 5289 | +} |
| 5290 | +CATCH_NO_MEMORY_INT(1) |
| 5291 | + |
| 5292 | +_Must_inspect_result_ ebpf_result_t |
| 5293 | +ebpf_api_get_data_section( |
| 5294 | + _In_z_ const char* file_path, |
| 5295 | + _In_z_ const char* section_name, |
| 5296 | + _Out_writes_bytes_opt_(*data_size) uint8_t* data, |
| 5297 | + _Inout_ size_t* data_size) NO_EXCEPT_TRY |
| 5298 | +{ |
| 5299 | + EBPF_LOG_ENTRY(); |
| 5300 | + |
| 5301 | + if (file_path == nullptr || section_name == nullptr || data_size == nullptr) { |
| 5302 | + EBPF_RETURN_RESULT(EBPF_INVALID_ARGUMENT); |
| 5303 | + } |
| 5304 | + |
| 5305 | + // Determine file type by extension |
| 5306 | + std::string path(file_path); |
| 5307 | + bool is_pe_file = false; |
| 5308 | + if (path.size() > 4) { |
| 5309 | + std::string extension = path.substr(path.size() - 4); |
| 5310 | + std::transform(extension.begin(), extension.end(), extension.begin(), [](char c) { |
| 5311 | + return static_cast<char>(::tolower(static_cast<unsigned char>(c))); |
| 5312 | + }); |
| 5313 | + is_pe_file = (extension == ".dll" || extension == ".sys" || extension == ".exe"); |
| 5314 | + } |
| 5315 | + |
| 5316 | + ebpf_result_t result = EBPF_SUCCESS; |
| 5317 | + |
| 5318 | + if (is_pe_file) { |
| 5319 | + // Parse PE file using pe-parse library |
| 5320 | + std::scoped_lock pe_parse_lock(_pe_parse_mutex); |
| 5321 | + parsed_pe* pe = ParsePEFromFile(file_path); |
| 5322 | + if (pe == nullptr) { |
| 5323 | + EBPF_RETURN_RESULT(EBPF_INVALID_OBJECT); |
| 5324 | + } |
| 5325 | + |
| 5326 | + // Set up context for section search |
| 5327 | + ebpf_section_data_context_t section_context = { |
| 5328 | + .section_name = section_name, .section_found = false, .section_size = 0, .section_data = nullptr}; |
| 5329 | + |
| 5330 | + IterSec(pe, _ebpf_pe_find_section, §ion_context); |
| 5331 | + |
| 5332 | + if (!section_context.section_found) { |
| 5333 | + DestructParsedPE(pe); |
| 5334 | + EBPF_RETURN_RESULT(EBPF_OBJECT_NOT_FOUND); |
| 5335 | + } |
| 5336 | + |
| 5337 | + // Check buffer size |
| 5338 | + if (data == nullptr) { |
| 5339 | + // Just return the size |
| 5340 | + *data_size = section_context.section_size; |
| 5341 | + } else if (*data_size < section_context.section_size) { |
| 5342 | + // Buffer too small |
| 5343 | + *data_size = section_context.section_size; |
| 5344 | + DestructParsedPE(pe); |
| 5345 | + EBPF_RETURN_RESULT(EBPF_INSUFFICIENT_BUFFER); |
| 5346 | + } else { |
| 5347 | + // Copy data to buffer |
| 5348 | + memcpy(data, section_context.section_data, section_context.section_size); |
| 5349 | + *data_size = section_context.section_size; |
| 5350 | + } |
| 5351 | + |
| 5352 | + DestructParsedPE(pe); |
| 5353 | + } else { |
| 5354 | + // Parse ELF file using ELFIO library |
| 5355 | + ELFIO::elfio reader; |
| 5356 | + if (!reader.load(file_path)) { |
| 5357 | + EBPF_RETURN_RESULT(EBPF_INVALID_OBJECT); |
| 5358 | + } |
| 5359 | + |
| 5360 | + // Find the section by name |
| 5361 | + ELFIO::section* section = reader.sections[section_name]; |
| 5362 | + if (section == nullptr || section->get_data() == nullptr) { |
| 5363 | + EBPF_RETURN_RESULT(EBPF_OBJECT_NOT_FOUND); |
| 5364 | + } |
| 5365 | + |
| 5366 | + size_t section_size = section->get_size(); |
| 5367 | + |
| 5368 | + // Check buffer size |
| 5369 | + if (data == nullptr) { |
| 5370 | + // Just return the size |
| 5371 | + *data_size = section_size; |
| 5372 | + } else if (*data_size < section_size) { |
| 5373 | + // Buffer too small |
| 5374 | + *data_size = section_size; |
| 5375 | + EBPF_RETURN_RESULT(EBPF_INSUFFICIENT_BUFFER); |
| 5376 | + } else { |
| 5377 | + // Copy data to buffer |
| 5378 | + memcpy(data, section->get_data(), section_size); |
| 5379 | + *data_size = section_size; |
| 5380 | + } |
| 5381 | + } |
| 5382 | + |
| 5383 | + EBPF_RETURN_RESULT(result); |
| 5384 | +} |
| 5385 | +CATCH_NO_MEMORY_EBPF_RESULT |
| 5386 | + |
5255 | 5387 | static _Must_inspect_result_ ebpf_result_t |
5256 | 5388 | _ebpf_link_mark_as_legacy_mode(ebpf_handle_t link_handle) NO_EXCEPT_TRY |
5257 | 5389 | { |
|
0 commit comments