Skip to content
Open
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
5 changes: 5 additions & 0 deletions src/main/java/com/github/subreption/yara/YaraCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ public interface YaraCompiler extends AutoCloseable {
*/
void setCallback(YaraCompilationCallback cbk);

/**
* Instruct the compiler not to allow includes in files
*/
void disableIncludes();

/**
* Add rules content
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ public void setCallback(YaraCompilationCallback cbk) {
library.compilerSetCallback(peer, callBackAddress, 0);
}

/**
* Instructs the compiler to disallow the usage of includes in rules files.
* Compilation will fail if include is present.
* Internally it sets includes handling callback to null.
* https://yara.readthedocs.io/en/stable/capi.html#c.yr_compiler_set_include_callback
*/
@Override
public void disableIncludes() {
library.compilerDisableIncludes(peer, 0);
}

/**
* Release compiler instance
* @throws Exception
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ public void compilerSetCallback(long compiler, long callback, long data) {
yr_compiler_set_callback(compiler, callback, data);
}

private final native void yara_compiler_set_null_include_callback(
@JniArg(cast = "YR_COMPILER*") long compiler,
@JniArg(cast = "void *") long data
);
public void compilerDisableIncludes(long compiler, long data) {
Preconditions.checkState(library != null);
yara_compiler_set_null_include_callback(compiler, data);
}

private final native int yr_compiler_add_string(
@JniArg(cast = "YR_COMPILER *") long compiler,
String rules,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ public void setCallback(YaraCompilationCallback cbk) {
this.callback = cbk;
}

@Override
public void disableIncludes() {
logger.warn("Disabling includes is not supported in external mode");
}

@Override
public void addRulesContent(String content, String namespace) {
Boolean deleteImmediately = false;
Expand Down
8 changes: 8 additions & 0 deletions src/main/native-package/src/yara-wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,14 @@ yara_compiler_add_file(JNIEnv *env, void *compiler, const char *path, const char
return ret;
}

// Disable includes by passing NULL include callback
// https://yara.readthedocs.io/en/stable/capi.html#c.yr_compiler_set_include_callback
static void
yara_compiler_set_null_include_callback(void *compiler, void* user_data) {

yr_compiler_set_include_callback((YR_COMPILER*)compiler, NULL, NULL, user_data);
}

/*
* Module functions
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.io.File;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
Expand All @@ -27,6 +28,7 @@

import org.junit.jupiter.api.AfterEach;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
Expand Down Expand Up @@ -163,6 +165,56 @@ public void onError(ErrorLevel errorLevel, String fileName, long lineNumber, Str
assertTrue(called.get());
}

private static final String YARA_RULE_INCLUDE = "include \"${filePathToInclude}\"\n" +
"rule HiThere\n" +
"{\n" +
" strings:\n" +
" $a = \"Hi there\"\n" +
" condition:\n" +
" $a\n" +
"}\n";

@Test
public void testAddRulesContentFailsOnIncludesDisabled() throws Exception {
Path tempFile = Files.createTempFile("yara-rule-test", ".yara");
try {
Files.write(tempFile, YARA_RULE_HELLO.getBytes(StandardCharsets.UTF_8));

final AtomicBoolean called = new AtomicBoolean();
YaraCompilationCallback callback;

// Don't disable includes - compilation should pass
callback = (errorLevel, fileName, lineNumber, message) -> {
called.set(true);
logger.debug(String.format("Compilation failed in %s at %d: %s", fileName, lineNumber, message));
};
try (YaraCompiler compiler = yara.createCompiler()) {
compiler.setCallback(callback);
compiler.addRulesContent(YARA_RULE_INCLUDE.replace("${filePathToInclude}", tempFile.toAbsolutePath().toString()), null);
} catch (YaraException e) {
fail("Exception not expected: " + e);
}
assertFalse(called.get());

// Disable includes - compilation should fail
callback = (errorLevel, fileName, lineNumber, message) -> {
called.set(true);
assertEquals(1, lineNumber);
assertEquals("includes are disabled", message);
};
try (YaraCompiler compiler = yara.createCompiler()) {
compiler.setCallback(callback);
compiler.disableIncludes();
compiler.addRulesContent(YARA_RULE_INCLUDE.replace("${filePathToInclude}", tempFile.toAbsolutePath().toString()), null);
fail();
} catch (YaraException e) {
}
assertTrue(called.get());
} finally {
Files.deleteIfExists(tempFile);
}
}

@Test
public void testAddRulePackageSucceeds() throws Exception {
YaraCompilationCallback callback = new YaraCompilationCallback() {
Expand Down