DanielCohen197/Conex

GitHub: DanielCohen197/Conex

一个 C++ 单头文件库,通过自定义 lambda 条件实现语义化的二进制数据模式匹配与搜索。

Stars: 2 | Forks: 0

# Conex 一个基于条件的二进制模式匹配 C++ 单头文件库。 Conex 允许你使用类似正则表达式的模式语法搜索二进制数据,其中每个分组由一个条件定义——即一个检查原始字节并返回 true 或 false 的 lambda。 ``` auto result = conex::search_first(blob, "(c0:4)(c1:8)", [](std::span s) { /* signature check */ }, [](std::span s) { /* address check */ } ); ``` ## 环境要求 - C++17 或更高版本 - 除标准库外无其他依赖 ## 安装说明 将 `conex.hpp` 复制到你的项目中并包含它。 ``` #include "conex.hpp" ``` ## 模式语法 模式是一系列分组: ``` (cN:W)Q ``` | 部分 | 含义 | |------|---------| | `N` | 要使用的 lambda 索引(从 0 开始,与你的可变参数对应) | | `:W` | 每次匹配消耗的字节宽度(默认值:1) | | `Q` | 量词:`*` 零次或多次,`+` 一次或多次,`?` 零次或一次,无 = 恰好一次 | ### 示例 | 模式 | 含义 | |---------|---------| | `(c0:4)` | 恰好 4 个满足 lambda 0 的字节 | | `(c0:4)(c1:8)` | 4 个满足 c0 的字节,紧接着 8 个满足 c1 的字节 | | `(c0:4)*` | 零个或多个满足 c0 的 4 字节序列 | | `(c0:4)+(c1:2)` | 一个或多个 4 字节序列,然后恰好 2 个字节 | | `(c0:8)(c0:8)(c1:4)*(c2:2)(c3:8)` | 两个 8 字节地址,任意数量的 4 字节记录,两个字节,八个字节 | ## API ### `conex::search_first` 扫描数据块并返回第一个匹配项。 ``` conex::MatchResult conex::search_first( std::span blob, std::string_view pattern, Conds&&... conditions ); ``` ### `conex::search_all` 返回所有不重叠的匹配项。 ``` std::vector conex::search_all( std::span blob, std::string_view pattern, Conds&&... conditions ); ``` ### `conex::match` 尝试在给定 span 的起始位置进行匹配。要在特定偏移量处匹配,请传递 `blob.subspan(offset)`。 ``` conex::MatchResult conex::match( std::span blob, std::string_view pattern, Conds&&... conditions ); ``` ## 匹配结果 ``` struct MatchResult { bool matched; size_t start; // byte offset where match begins size_t end; // byte offset after match ends std::vector> captures; // captures[group][repetition] }; struct Capture { size_t offset; // byte offset in original blob std::span bytes; // the matched bytes }; ``` `captures[i]` 包含由分组 `i` 匹配到的每次重复。对于非重复分组,它将始终只有一个条目(如果匹配成功)。 ## 示例 通过签名和页对齐的地址成员在二进制数据块中查找结构体: ``` #include "conex.hpp" bool is_page_aligned_address(std::span bytes) { uint64_t addr; std::memcpy(&addr, bytes.data(), 8); return (addr & 0xFFF) == 0; // page-aligned } auto result = conex::search_first( std::span(blob), "(c0:4)(c1:8)", // c0: match the struct signature [](std::span s) { uint32_t sig; std::memcpy(&sig, s.data(), 4); return sig == 0xDEADBEEF; }, // c1: match page aligned address condition [](std::span s) { return is_page_aligned_address(s); } ); if (result) { auto* s = reinterpret_cast(blob.data() + result.start); } ``` 在特定偏移量处匹配: ``` auto result = conex::match(std::span(blob).subspan(offset, 4), "(c0:4)", my_lambda); ``` 遍历重复分组中捕获的记录: ``` auto result = conex::search_first(blob, "(c0:8)(c1:4)*(c2:2)", c0, c1, c2); for (auto& capture : result.captures[1]) { // group 1 = (c1:4)* uint32_t val; std::memcpy(&val, capture.bytes.data(), 4); printf("record at offset %zu: 0x%08X\n", capture.offset, val); } ``` 更多示例,请查看示例文件。
标签:C++, C++17, DAST, DNS 反向解析, Header-Only, HTTP头分析, IP 地址批量处理, URL发现, 二进制数据, 云安全监控, 云资产清单, 内存扫描, 单头文件库, 字节流解析, 安全工具开发, 安全检测, 恶意软件分析, 数据擦除, 数据结构, 无第三方依赖, 条件匹配, 模式匹配, 正则表达式风格, 特征码搜索, 签名匹配, 网络信息收集, 自动化资产收集, 逆向工程, 静态分析