Skip to content

Commit

Permalink
feat: add feature for compiling .proto files with protoc (#188)
Browse files Browse the repository at this point in the history
By default, .proto files are compiled using the pure-Rust compiler implemented by the protobuf-rust, but the protoc feature allows switching to protoc, the official Protobuf compiler.

This required some changes in .proto files, because protoc is stricter than the pure-Rust protobuf compiler.
  • Loading branch information
plusvic authored Sep 4, 2024
1 parent a70e7d8 commit 5b1c348
Show file tree
Hide file tree
Showing 13 changed files with 175 additions and 154 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/code_health.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- uses: dtolnay/[email protected]
with:
components: clippy
- run: cargo clippy --tests --no-deps --all-features -- --deny clippy::all
- run: cargo clippy --tests --no-deps -- --deny clippy::all

rustfmt:
name: Rustfmt
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
- win-msvc
# - win-gnu
- no-default-features
- protoc
include:
- build: msrv
os: ubuntu-latest
Expand Down Expand Up @@ -76,6 +77,13 @@ jobs:
rust_flags: "-Awarnings"
experimental: false

- build: protoc
os: ubuntu-latest
rust: stable
args: "--package yara-x --features=protoc,magic-module"
rust_flags: "-Awarnings"
experimental: false

steps:
- name: Checkout sources
uses: actions/checkout@v4
Expand All @@ -95,6 +103,12 @@ jobs:
sudo apt-get update
sudo apt-get install -y libmagic-dev
- name: Install protoc
if: matrix.build == 'protoc'
run: |
sudo apt-get install -y protobuf-compiler
cargo install protobuf-codegen
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
Expand Down
8 changes: 8 additions & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ exact-atoms = []
# the fast regexp matching mechanism for testing purposes.
fast-regexp = []

# Whether to use protoc for parsing and compiling .proto files. By default,
# .proto files are parsed and compiled by the pure-Rust compiler implemented
# by the `rust-protobuf` crate. With this feature you can change this behavior
# and use protoc, the official Protocol Buffer compiler. You'll need to have
# protoc installed in your system, together with the protoc-gen-rust plugin.
# Follow the instructions in: https://lib.rs/crates/protobuf-codegen3
protoc = []

# Enables debug logs.
logging = ["dep:log"]

Expand Down
12 changes: 8 additions & 4 deletions lib/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,15 @@ fn main() {
let mut proto_compiler = Codegen::new();
let mut proto_parser = Parser::new();

proto_compiler
.pure()
.cargo_out_dir("protos")
.include("src/modules/protos");
if cfg!(feature = "protoc") {
proto_compiler.protoc();
proto_parser.protoc();
} else {
proto_compiler.pure();
proto_parser.pure();
}

proto_compiler.cargo_out_dir("protos").include("src/modules/protos");
proto_parser.include("src/modules/protos");

// All `.proto` files in src/modules/protos must be compiled
Expand Down
2 changes: 1 addition & 1 deletion lib/src/modules/macho/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1835,7 +1835,7 @@ impl From<&MinVersion> for protos::macho::MinVersion {
let mut result = protos::macho::MinVersion::new();

result.set_device(
protobuf::EnumOrUnknown::<protos::macho::DEVICE_TYPE>::from_i32(
protobuf::EnumOrUnknown::<protos::macho::DeviceType>::from_i32(
mv.device as i32,
)
.unwrap(),
Expand Down
4 changes: 2 additions & 2 deletions lib/src/modules/pe/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ fn main(input: &[u8]) -> PE {
#[module_export]
fn is_32bit(ctx: &ScanContext) -> Option<bool> {
let magic = ctx.module_output::<PE>()?.opthdr_magic?;
Some(magic.value() == OptHdrMagic::IMAGE_NT_OPTIONAL_HDR32_MAGIC as i32)
Some(magic.value() == OptionalMagic::IMAGE_NT_OPTIONAL_HDR32_MAGIC as i32)
}

/// Returns true if the file is a 64-bit PE.
#[module_export]
fn is_64bit(ctx: &ScanContext) -> Option<bool> {
let magic = ctx.module_output::<PE>()?.opthdr_magic?;
Some(magic.value() == OptHdrMagic::IMAGE_NT_OPTIONAL_HDR64_MAGIC as i32)
Some(magic.value() == OptionalMagic::IMAGE_NT_OPTIONAL_HDR64_MAGIC as i32)
}

/// Returns true if the file is dynamic link library (DLL)
Expand Down
2 changes: 1 addition & 1 deletion lib/src/modules/pe/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2213,7 +2213,7 @@ impl From<PE<'_>> for protos::pe::PE {
result.set_number_of_symbols(pe.pe_hdr.number_of_symbols);
result.set_size_of_optional_header(pe.pe_hdr.size_of_optional_header.into());

result.opthdr_magic = Some(EnumOrUnknown::<protos::pe::OptHdrMagic>::from_i32(pe
result.opthdr_magic = Some(EnumOrUnknown::<protos::pe::OptionalMagic>::from_i32(pe
.optional_hdr
.magic.into()));

Expand Down
48 changes: 24 additions & 24 deletions lib/src/modules/protos/macho.proto
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ option (yara.module_options) = {
};

message MinVersion {
optional DEVICE_TYPE device = 1;
optional DeviceType device = 1;
optional string version = 2;
optional string sdk = 3;
}
Expand Down Expand Up @@ -113,7 +113,7 @@ message Segment {
optional uint32 maxprot = 8 [(yaml.field).fmt = "x"];
optional uint32 initprot = 9 [(yaml.field).fmt = "x"];
optional uint32 nsects = 10;
optional uint32 flags = 11 [(yaml.field).fmt = "flags:SEGMENT_FLAG"];
optional uint32 flags = 11 [(yaml.field).fmt = "flags:SegmentFlag"];
repeated Section sections = 12;
}

Expand All @@ -133,7 +133,7 @@ message File {
optional uint32 filetype = 4;
optional uint32 ncmds = 5;
optional uint32 sizeofcmds = 6;
optional uint32 flags = 7 [(yaml.field).fmt = "flags:FILE_FLAG"];
optional uint32 flags = 7 [(yaml.field).fmt = "flags:FileFlag"];
optional uint32 reserved = 8;
optional uint64 number_of_segments = 9;
optional bytes dynamic_linker = 10;
Expand Down Expand Up @@ -194,29 +194,29 @@ message Macho {
repeated File file = 30;
}

enum HEADER {
enum Header {
option (yara.enum_options).inline = true;
MH_MAGIC = 0 [(yara.enum_value).i64 = 0xfeedface];
MH_CIGAM = 1 [(yara.enum_value).i64 = 0xcefaedfe];
MH_MAGIC_64 = 2 [(yara.enum_value).i64 = 0xfeedfacf];
MH_CIGAM_64 = 3 [(yara.enum_value).i64 = 0xcffaedfe];
}

enum FAT_HEADER {
enum FatHeader {
option (yara.enum_options).inline = true;
FAT_MAGIC = 0 [(yara.enum_value).i64 = 0xcafebabe];
FAT_CIGAM = 1 [(yara.enum_value).i64 = 0xbebafeca];
FAT_MAGIC_64 = 2 [(yara.enum_value).i64 = 0xcafebabf];
FAT_CIGAM_64 = 3 [(yara.enum_value).i64 = 0xbfbafeca];
}

enum MASK_64BIT {
enum Mask64Bit {
option (yara.enum_options).inline = true;
CPU_ARCH_ABI64 = 0x01000000;
CPU_SUBTYPE_LIB64 = 0 [(yara.enum_value).i64 = 0x80000000];
}

enum CPU_TYPE {
enum CpuType {
option (yara.enum_options).inline = true;
CPU_TYPE_MC680X0 = 0x00000006;
CPU_TYPE_X86 = 0x00000007;
Expand All @@ -231,12 +231,12 @@ enum CPU_TYPE {
CPU_TYPE_POWERPC64 = 0x01000012;
}

enum CPU_I386_TYPE {
enum CpuI386Type {
option (yara.enum_options).inline = true;
CPU_TYPE_I386 = 0x00000007;
}

enum CPU_INTEL_SUBTYPE {
enum CpuIntelSubType {
option (yara.enum_options).inline = true;
CPU_SUBTYPE_INTEL_MODEL_ALL = 0x00000000;
CPU_SUBTYPE_386 = 0x00000003;
Expand All @@ -251,17 +251,17 @@ enum CPU_INTEL_SUBTYPE {
CPU_SUBTYPE_XEON_MP = 0x0000001c;
}

enum CPU_I386_SUBTYPE {
enum CpuI386SubType {
option (yara.enum_options).inline = true;
CPU_SUBTYPE_I386_ALL = 0x00000003;
}

enum CPU_X86_SUBTYPE {
enum CpuX86SubType {
option (yara.enum_options).inline = true;
CPU_SUBTYPE_X86_64_ALL = 0x00000003;
}

enum CPU_INTEL_PENTIUM_SUBTYPE {
enum CpuIntelPentiumSubType {
option (yara.enum_options).inline = true;
CPU_SUBTYPE_PENT = 0x00000005;
CPU_SUBTYPE_PENTPRO = 0x00000016;
Expand All @@ -275,7 +275,7 @@ enum CPU_INTEL_PENTIUM_SUBTYPE {
CPU_SUBTYPE_PENTIUM_4_M = 0x0000001a;
}

enum CPU_ARM_SUBTYPE {
enum CpuArmSubType {
option (yara.enum_options).inline = true;
CPU_SUBTYPE_ARM_ALL = 0x00000000;
CPU_SUBTYPE_ARM_V4T = 0x00000005;
Expand All @@ -291,18 +291,18 @@ enum CPU_ARM_SUBTYPE {
CPU_SUBTYPE_ARM_V7EM = 0x00000010;
}

enum CPU_ARM_64_SUBTYPE {
enum CpuArm64SubType {
option (yara.enum_options).inline = true;
CPU_SUBTYPE_ARM_V5TEJ = 0x00000007;
CPU_SUBTYPE_ARM64_ALL = 0x00000000;
}

enum CPU_SPARC_SUBTYPE {
enum CpuSparcSubType {
option (yara.enum_options).inline = true;
CPU_SUBTYPE_SPARC_ALL = 0x00000000;
}

enum CPU_POWERPC_SUBTYPE {
enum CpuPowerPCSubType {
option (yara.enum_options).inline = true;
CPU_SUBTYPE_POWERPC_ALL = 0x00000000;
CPU_SUBTYPE_POWERPC_601 = 0x00000001;
Expand All @@ -319,13 +319,13 @@ enum CPU_POWERPC_SUBTYPE {
CPU_SUBTYPE_POWERPC_970 = 0x00000064;
}

enum CPU_MC_SUBTYPE {
enum CpuMcSubType {
option (yara.enum_options).inline = true;
CPU_SUBTYPE_MC980000_ALL = 0x00000000;
CPU_SUBTYPE_MC98601 = 0x00000001;
}

enum FILE_TYPE {
enum FileType {
option (yara.enum_options).inline = true;
MH_OBJECT = 0x00000001;
MH_EXECUTE = 0x00000002;
Expand All @@ -340,7 +340,7 @@ enum FILE_TYPE {
MH_KEXT_BUNDLE = 0x0000000b;
}

enum FILE_FLAG {
enum FileFlag {
option (yara.enum_options).inline = true;
MH_NOUNDEFS = 0x00000001;
MH_INCRLINK = 0x00000002;
Expand Down Expand Up @@ -370,21 +370,21 @@ enum FILE_FLAG {
MH_APP_EXTENSION_SAFE = 0x02000000;
}

enum SEGMENT_FLAG {
enum SegmentFlag {
option (yara.enum_options).inline = true;
SG_HIGHVM = 0x00000001;
SG_FVMLIB = 0x00000002;
SG_NORELOC = 0x00000004;
SG_PROTECTED_VERSION_1 = 0x00000008;
}

enum SECTION_FLAG_MASK {
enum SectionFlagMask {
option (yara.enum_options).inline = true;
SECTION_TYPE = 0x000000ff;
SECTION_ATTRIBUTES = 0 [(yara.enum_value).i64 = 0xffffff00];
}

enum SECTION_TYPE {
enum SectionType {
option (yara.enum_options).inline = true;
S_REGULAR = 0x00000000;
S_ZEROFILL = 0x00000001;
Expand All @@ -410,7 +410,7 @@ enum SECTION_TYPE {
S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x00000015;
}

enum SECTION_ATTRIBUTES {
enum SectionAttributes {
option (yara.enum_options).inline = true;
S_ATTR_PURE_INSTRUCTIONS = 0 [(yara.enum_value).i64 = 0x80000000];
S_ATTR_NO_TOC = 0x40000000;
Expand All @@ -424,7 +424,7 @@ enum SECTION_ATTRIBUTES {
S_ATTR_LOC_RELOC = 0x00000100;
}

enum DEVICE_TYPE {
enum DeviceType {
option (yara.enum_options).inline = true;
MACOSX = 0x00000024;
IPHONEOS = 0x00000025;
Expand Down
Loading

0 comments on commit 5b1c348

Please sign in to comment.