Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions lib/src/compiler/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use itertools::Itertools;
use rustc_hash::FxHashSet;

use yara_x_parser::ast::{Ident, WithSpan};
use yara_x_parser::Span;

use crate::compiler::errors::{CompileError, UnknownPattern};
use crate::compiler::ir::{PatternIdx, IR};
Expand Down Expand Up @@ -118,7 +119,8 @@ impl<'src> CompileContext<'_, 'src> {
// If the current symbol table is `None` it means that the
// identifier is not a field or method of some structure.
return if symbol_table.is_none() {
Err(UnknownIdentifier::build(
// Build the error for the unknown identifier.
let mut err = UnknownIdentifier::build(
self.report_builder,
ident.name.to_string(),
self.report_builder.span_to_code_loc(ident.span()),
Expand All @@ -133,7 +135,16 @@ impl<'src> CompileContext<'_, 'src> {
} else {
None
},
))
);
// If the identifier is a known module, add a fix that inserts
// the import statement at the beginning of the file.
if BUILTIN_MODULES.contains_key(ident.name) {
err.report_mut().patch(
self.report_builder.span_to_code_loc(Span(0..0)),
format!("import \"{}\"\n", ident.name),
);
}
Err(err)
} else {
Err(UnknownField::build(
self.report_builder,
Expand Down
5 changes: 5 additions & 0 deletions lib/src/compiler/tests/testdata/errors/154.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// test_proto2-module required
rule test {
condition:
test_proto2.int32_zero == 0
}
11 changes: 11 additions & 0 deletions lib/src/compiler/tests/testdata/errors/154.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E009]: unknown identifier `test_proto2`
--> line:4:5
|
4 | test_proto2.int32_zero == 0
| ^^^^^^^^^^^ this identifier has not been declared
|
= note: there is a module named `test_proto2`, but the `import "test_proto2"` statement is missing
help: consider the following change
|
1 + import "test_proto2"
|
59 changes: 35 additions & 24 deletions lib/src/modules/macho/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ const CPU_TYPE_SPARC: u32 = 0x0000000e;
const CPU_TYPE_POWERPC: u32 = 0x00000012;
const CPU_TYPE_POWERPC64: u32 = 0x01000012;

/// Mach-O Import Fixup Formats
const DYLD_CHAINED_IMPORT: u32 = 1;
const DYLD_CHAINED_IMPORT_ADDEND: u32 = 2;
const DYLD_CHAINED_IMPORT_ADDEND64: u32 = 3;

/// Represents a Mach-O file. It can represent both a multi-architecture
/// binary (a.k.a. FAT binary) or a single-architecture binary.
pub struct MachO<'a> {
Expand Down Expand Up @@ -1335,7 +1340,7 @@ impl<'a> MachOFile<'a> {
imports_offset,
symbols_offset,
imports_count,
_imports_format: imports_format,
imports_format,
_symbols_format: symbols_format,
}
},
Expand All @@ -1350,29 +1355,35 @@ impl<'a> MachOFile<'a> {
let (_, header) = self.chained_fixup_header().parse(data)?;

if let Some(import_data) = data.get(header.imports_offset as usize..) {
let mut remainder = import_data;
let mut chained_import_value: u32;

for _ in 0..header.imports_count {
(remainder, chained_import_value) =
u32(self.endianness)(remainder)?;

let _lib_ordinal = chained_import_value & 0xff;
let _import_kind = (chained_import_value >> 8) & 0x1;
let name_offset = chained_import_value >> 9;

if let Some(name_buffer) = data.get(
header.symbols_offset.saturating_add(name_offset)
as usize..,
) {
let (_remainder, import_str) = map(
(take_till(|b| b == b'\x00'), tag("\x00")),
|(s, _)| s,
)
.parse(name_buffer)?;
let entry_size = match header.imports_format {
DYLD_CHAINED_IMPORT => 4,
DYLD_CHAINED_IMPORT_ADDEND => 8,
DYLD_CHAINED_IMPORT_ADDEND64 => 16,
_ => 4, // fallback
};

if let Ok(import) = import_str.to_str() {
self.imports.push(import.to_string());
let imports_size = (header.imports_count as usize) * entry_size;
if let Some(raw_imports_blob) = import_data.get(..imports_size) {
for chunk in raw_imports_blob.chunks_exact(entry_size) {
let (_, chained_import_value) =
u32(self.endianness)(chunk)?;

let _lib_ordinal = chained_import_value & 0xff;
let _import_kind = (chained_import_value >> 8) & 0x1;
let name_offset = (chained_import_value >> 9) & 0x7FFFFF;

if let Some(name_buffer) = data.get(
header.symbols_offset.saturating_add(name_offset)
as usize..,
) {
let (_remainder, import_str) = map(
(take_till(|b| b == b'\x00'), tag("\x00")),
|(s, _)| s,
)
.parse(name_buffer)?;
if let Ok(import) = import_str.to_str() {
self.imports.push(import.to_string());
}
}
}
}
Expand Down Expand Up @@ -1800,7 +1811,7 @@ struct ChainedFixupsHeader {
imports_offset: u32,
symbols_offset: u32,
imports_count: u32,
_imports_format: u32,
imports_format: u32,
_symbols_format: u32,
}

Expand Down
Binary file not shown.
Loading
Loading