Skip to content

Instantly share code, notes, and snippets.

@wjsl
Created January 18, 2018 23:45
Show Gist options
  • Save wjsl/212d032c088b9c2df948efde7a924169 to your computer and use it in GitHub Desktop.
Save wjsl/212d032c088b9c2df948efde7a924169 to your computer and use it in GitHub Desktop.
A demo program that exercises libyara's exception macro in a multi-threaded program
#include <pthread.h>
#include <yara.h>
#include <stdio.h>
int callback_function(int, void*, void*);
void *YaraWorker(void *);
void *Segfaulter();
void *Safebet();
typedef struct yargs_struct {
YR_RULES *rules;
uint8_t *buffer;
int (*ptrFunc)(int, void*, void*);
} yargs;
int main(int argc, char **argv) {
int ret = yr_initialize();
YR_COMPILER* compiler = malloc(sizeof(YR_COMPILER));
int compiler_create = yr_compiler_create(&compiler);
char* yara_rule_str = "import \"pe\"\n"
"rule HelloWorld : silent\n"
"{\n"
"meta:\n"
"my_identifier_1 = \"Some string data\"\n"
"my_identifier_2 = 24\n"
"my_identifier_3 = true\n"
"strings:\n"
"$a = \"Hello world\"\n"
"condition: $a\n"
"}";
ret = yr_compiler_add_string(compiler, yara_rule_str, NULL);
int (*ptrFunc)(int, void*, void*);
ptrFunc = callback_function;
YR_RULES* rules = malloc(sizeof(YR_RULES));
ret = yr_compiler_get_rules(compiler,&rules);
uint8_t* buffer = "Hello world";
yargs *thread_args = malloc(sizeof(yargs));
thread_args->rules = rules;
thread_args->buffer = buffer;
thread_args->ptrFunc = ptrFunc;
pthread_t threads[100];
int rc;
long t;
long max = 65;
for(t=0; t<max; t++) {
// we'll get some threads running in the background, but throw a wrench in their plans
if (t == 63) {
pthread_create(&threads[t], NULL, &Segfaulter, NULL);
//pthread_create(&threads[t], NULL, &Safebet, NULL);
} else {
rc = pthread_create(&threads[t], NULL, &YaraWorker, (void *)thread_args);
}
}
for(t=0; t<max; t++) {
pthread_join(threads[t], NULL);
}
yr_finalize();
return pthread_exit(NULL);
}
int callback_function(
int message,
void* message_data,
void* user_data) {
switch (message) {
case CALLBACK_MSG_RULE_MATCHING:
printf("Match!\n");
break;
case CALLBACK_MSG_RULE_NOT_MATCHING:
printf("No Match!\n");
break;
case CALLBACK_MSG_SCAN_FINISHED:
printf("Scan done!\n");
break;
case CALLBACK_MSG_IMPORT_MODULE:
printf("Import!\n");
break;
case CALLBACK_MSG_MODULE_IMPORTED:
printf("Imported!\n");
break;
}
return 0;
}
void *YaraWorker(void *args) {
yargs *myargs = args;
int ret = yr_rules_scan_mem(myargs->rules, myargs->buffer, 12, 0, myargs->ptrFunc, NULL, 10000);
printf("scan returned %d\n", ret);
yr_finalize_thread();
pthread_exit(NULL);
}
void *Segfaulter() {
uint8_t *empty_array = NULL;
empty_array[0] = 4;
printf("deadcode\n");
pthread_exit(NULL);
}
void *Safebet() {
printf("We're safe!\n");
pthread_exit(NULL);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment