mirror of
https://github.com/stellarbear/YaraSharp
synced 2026-06-08 17:36:09 +00:00
Binary file not shown.
Binary file not shown.
@@ -7,32 +7,40 @@ Nuget package is [available](https://www.nuget.org/packages/YaraSharp)
|
||||
## Usage
|
||||
```C#
|
||||
// All API calls happens here
|
||||
YaraSharp.CYaraSharp YSInstance = new CYaraSharp();
|
||||
YSInstance YSInstance = new YSInstance();
|
||||
|
||||
// Declare external variables (could be null)
|
||||
Dictionary<string, object> Externals = new Dictionary<string, object>()
|
||||
Dictionary<string, object> externals = new Dictionary<string, object>()
|
||||
{
|
||||
{ "filename", string.Empty },
|
||||
{ "filepath", string.Empty },
|
||||
{ "extension", string.Empty }
|
||||
};
|
||||
|
||||
// Errors occured during rule compilation: ignored_file : List<reasons>
|
||||
Dictionary<string, List<string>> Errors = new Dictionary<string, List<string>>();
|
||||
// Get list of YARA rules
|
||||
List<string> ruleFilenames = Directory.GetFiles(@"D:\Test\yara", "*.yar", SearchOption.AllDirectories).ToList();
|
||||
|
||||
// Context is where yara is initialized
|
||||
// From yr_initialize() to yr_finalize()
|
||||
using (YaraSharp.CContext YSContext = new YaraSharp.CContext())
|
||||
using (YSContext context = new YSContext())
|
||||
{
|
||||
// Compiling rules
|
||||
using (YaraSharp.CRules YSRules = YSInstance.CompileFromFiles(RuleFilenames, Externals, out Errors))
|
||||
{
|
||||
// Some file to test yara rules
|
||||
// Here comes long filenames
|
||||
string Filename = "\\?\<some_file>";
|
||||
// Compiling rules
|
||||
using (YSCompiler compiler = instance.CompileFromFiles(ruleFilenames, externals))
|
||||
{
|
||||
// Get compiled rules
|
||||
YSRules rules = compiler.GetRules();
|
||||
|
||||
// Get errors
|
||||
YSReport errors = compiler.GetErrors();
|
||||
// Get warnings
|
||||
YSReport warnings = compiler.GetWarnings();
|
||||
|
||||
|
||||
// Some file to test yara rules
|
||||
string Filename = @"";
|
||||
|
||||
// Get matches
|
||||
List<YaraSharp.CMatches> Matches = YSInstance.ScanFile(Filename, YSRules,
|
||||
List<YSMatches> Matches = instance.ScanFile(Filename, rules,
|
||||
new Dictionary<string, object>()
|
||||
{
|
||||
{ "filename", Alphaleonis.Win32.Filesystem.Path.GetFileName(Filename) },
|
||||
@@ -42,7 +50,7 @@ using (YaraSharp.CContext YSContext = new YaraSharp.CContext())
|
||||
0);
|
||||
|
||||
// Iterate over matches
|
||||
foreach (YaraSharp.CMatches Match in Matches)
|
||||
foreach (YSMatches Match in Matches)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ using namespace System::Security::Permissions;
|
||||
// You can specify all the value or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly:AssemblyVersion("1.2.2")];
|
||||
[assembly:AssemblyFileVersion("1.2.2")];
|
||||
[assembly:AssemblyVersion("1.3.0")];
|
||||
[assembly:AssemblyFileVersion("1.3.0")];
|
||||
|
||||
[assembly:ComVisible(false)];
|
||||
|
||||
|
||||
+105
-75
@@ -1,132 +1,162 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// CCompiler
|
||||
// Compiler
|
||||
namespace YaraSharp
|
||||
{
|
||||
// Constructor
|
||||
CCompiler::CCompiler(Dictionary<String^, Object^>^ ExternalVariables)
|
||||
YSCompiler::YSCompiler(Dictionary<String^, Object^>^ externalVariables)
|
||||
{
|
||||
YR_COMPILER* TestCompiler;
|
||||
ErrorUtility::ThrowOnError(yr_compiler_create(&TestCompiler));
|
||||
Compiler = TestCompiler;
|
||||
YR_COMPILER* testCompiler;
|
||||
YSException::ThrowOnError(yr_compiler_create(&testCompiler));
|
||||
compiler = testCompiler;
|
||||
|
||||
// Set up and initialize the error dictionary for errors and warnings
|
||||
// Which are populated by the callback handler
|
||||
Errors = gcnew Dictionary<int, List<String^>^>();
|
||||
Errors->Add(YARA_ERROR_LEVEL_ERROR, gcnew List<String^>());
|
||||
Errors->Add(YARA_ERROR_LEVEL_WARNING, gcnew List<String^>());
|
||||
errors = gcnew YSReport();
|
||||
warnings = gcnew YSReport();
|
||||
|
||||
SetCompilerExternals(ExternalVariables);
|
||||
SetCompilerExternals(externalVariables);
|
||||
SetCompilerCallback();
|
||||
}
|
||||
// Destructor
|
||||
CCompiler::~CCompiler() { if (Compiler) yr_compiler_destroy(Compiler); }
|
||||
|
||||
YSCompiler::~YSCompiler()
|
||||
{
|
||||
if (compiler)
|
||||
{
|
||||
yr_compiler_destroy(compiler);
|
||||
}
|
||||
|
||||
delete warnings;
|
||||
delete errors;
|
||||
}
|
||||
|
||||
// Rule region
|
||||
int CCompiler::AddFile(String^ FilePath)
|
||||
void YSCompiler::AddFile(String^ filePath)
|
||||
{
|
||||
BindFileToCompiler(this->compiler, filePath);
|
||||
}
|
||||
void YSCompiler::TryAddFile(String^ filePath, Dictionary<String^, Object^>^ externalVariables)
|
||||
{
|
||||
YSCompiler^ testCompiler = gcnew YSCompiler(externalVariables);
|
||||
BindFileToCompiler(testCompiler->compiler, filePath);
|
||||
|
||||
bool isFileCorrect = testCompiler->GetErrors()->IsEmpty();
|
||||
|
||||
// If there are some errors => report to main compiler
|
||||
if (!isFileCorrect)
|
||||
{
|
||||
this->errors->MergeReports(testCompiler->GetErrors());
|
||||
// Warnings are not passed, or else they will be duplicated
|
||||
}
|
||||
// If no errors => pass file to main compiler
|
||||
else
|
||||
{
|
||||
AddFile(filePath);
|
||||
}
|
||||
|
||||
delete testCompiler;
|
||||
}
|
||||
void YSCompiler::AddFiles(List<String^>^ filePathList, Dictionary<String^, Object^>^ externalVariables)
|
||||
{
|
||||
for each (auto filePath in filePathList)
|
||||
TryAddFile(filePath, externalVariables);
|
||||
}
|
||||
|
||||
YSRules^ YSCompiler::GetRules()
|
||||
{
|
||||
YR_RULES* ysRules;
|
||||
|
||||
YSException::ThrowOnError(
|
||||
yr_compiler_get_rules(compiler, &ysRules));
|
||||
|
||||
return gcnew YSRules(ysRules);
|
||||
}
|
||||
YSReport^ YSCompiler::GetErrors()
|
||||
{
|
||||
return this->errors;
|
||||
}
|
||||
YSReport^ YSCompiler::GetWarnings()
|
||||
{
|
||||
return this->warnings;
|
||||
}
|
||||
|
||||
|
||||
void YSCompiler::BindFileToCompiler(YR_COMPILER* compiler, String^ filePath)
|
||||
{
|
||||
FILE* File;
|
||||
Errors->Clear();
|
||||
Errors->Add(YARA_ERROR_LEVEL_ERROR, gcnew List<String^>());
|
||||
Errors->Add(YARA_ERROR_LEVEL_WARNING, gcnew List<String^>());
|
||||
|
||||
auto NativePath = marshal_as<std::string>(FilePath);
|
||||
auto NativePath = marshal_as<std::string>(filePath);
|
||||
|
||||
auto FileOpenError = fopen_s(&File, NativePath.c_str(), "r");
|
||||
|
||||
if (FileOpenError)
|
||||
ErrorUtility::ThrowOnError(String::Format("Error opening file: {0}", FileOpenError));
|
||||
YSException::ThrowOnError(String::Format("Error opening file: {0}", FileOpenError));
|
||||
|
||||
auto errors = yr_compiler_add_file(Compiler, File, nullptr, NativePath.c_str());
|
||||
auto errors = yr_compiler_add_file(compiler, File, nullptr, NativePath.c_str());
|
||||
|
||||
if (File) fclose(File);
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
void CCompiler::AddFiles(List<String^>^ FilePathList)
|
||||
{
|
||||
for each (auto FilePath in FilePathList)
|
||||
AddFile(FilePath);
|
||||
}
|
||||
|
||||
CRules^ CCompiler::GetRules()
|
||||
{
|
||||
YR_RULES* Rules;
|
||||
|
||||
ErrorUtility::ThrowOnError(
|
||||
yr_compiler_get_rules(Compiler, &Rules));
|
||||
|
||||
return gcnew CRules(Rules);
|
||||
}
|
||||
|
||||
List<String^>^ CCompiler::GetErrors(Boolean IncludeWarnings)
|
||||
{
|
||||
if (IncludeWarnings)
|
||||
if (File)
|
||||
{
|
||||
List<String^>^ errorsAndWarnings = gcnew List<String^>(this->Errors[YARA_ERROR_LEVEL_ERROR]);
|
||||
errorsAndWarnings->AddRange(this->Errors[YARA_ERROR_LEVEL_WARNING]);
|
||||
return errorsAndWarnings;
|
||||
fclose(File);
|
||||
}
|
||||
|
||||
return this->Errors[YARA_ERROR_LEVEL_ERROR];
|
||||
}
|
||||
|
||||
// Set externals
|
||||
void CCompiler::SetCompilerExternals(Dictionary<String^, Object^>^ ExternalVariables)
|
||||
void YSCompiler::SetCompilerExternals(Dictionary<String^, Object^>^ externalVariables)
|
||||
{
|
||||
if (ExternalVariables)
|
||||
if (externalVariables)
|
||||
{
|
||||
marshal_context CTX;
|
||||
|
||||
for each (auto ExternalVariable in ExternalVariables)
|
||||
for each (auto externalVariable in externalVariables)
|
||||
{
|
||||
const char* VariablePointer = CTX.marshal_as<const char*>(ExternalVariable.Key);
|
||||
Type^ VariableType = ExternalVariable.Value->GetType();
|
||||
const char* VariablePointer = CTX.marshal_as<const char*>(externalVariable.Key);
|
||||
Type^ VariableType = externalVariable.Value->GetType();
|
||||
int ExternalError = ERROR_SUCCESS;
|
||||
|
||||
if (VariableType == Boolean::typeid)
|
||||
ExternalError = yr_compiler_define_boolean_variable(Compiler, VariablePointer, (bool)ExternalVariable.Value);
|
||||
ExternalError = yr_compiler_define_boolean_variable(compiler, VariablePointer, (bool)externalVariable.Value);
|
||||
else if (VariableType == Double::typeid)
|
||||
ExternalError = yr_compiler_define_float_variable(Compiler, VariablePointer, (double)ExternalVariable.Value);
|
||||
ExternalError = yr_compiler_define_float_variable(compiler, VariablePointer, (double)externalVariable.Value);
|
||||
else if (VariableType == Int64::typeid || VariableType == Int32::typeid)
|
||||
ExternalError = yr_compiler_define_integer_variable(Compiler, VariablePointer, (Int64)ExternalVariable.Value);
|
||||
ExternalError = yr_compiler_define_integer_variable(compiler, VariablePointer, (Int64)externalVariable.Value);
|
||||
else if (VariableType == String::typeid)
|
||||
ExternalError = yr_compiler_define_string_variable(Compiler, VariablePointer, CTX.marshal_as<const char*>((String^)ExternalVariable.Value));
|
||||
ExternalError = yr_compiler_define_string_variable(compiler, VariablePointer, CTX.marshal_as<const char*>((String^)externalVariable.Value));
|
||||
else
|
||||
throw gcnew NotSupportedException(String::Format("Unsupported external variable: '{0}'", VariableType->Name));
|
||||
|
||||
if (ExternalError != ERROR_SUCCESS)
|
||||
ErrorUtility::ThrowOnError("(Compiler) Error during external variable intialization");
|
||||
YSException::ThrowOnError("(Compiler) Error during external variable intialization");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Callback
|
||||
void CCompiler::SetCompilerCallback()
|
||||
void YSCompiler::SetCompilerCallback()
|
||||
{
|
||||
YaraCompilerCallback^ CompilerCallback = gcnew YaraCompilerCallback(this, &CCompiler::HandleCompilerCallback);
|
||||
GCHandle CallbackHandle = GCHandle::Alloc(CompilerCallback);
|
||||
YR_COMPILER_CALLBACK_FUNC CallbackPointer = (YR_COMPILER_CALLBACK_FUNC)(Marshal::GetFunctionPointerForDelegate(CompilerCallback)).ToPointer();
|
||||
yr_compiler_set_callback(Compiler, CallbackPointer, NULL);
|
||||
YaraCompilerCallback^ compilerCallback = gcnew YaraCompilerCallback(this, &YSCompiler::HandleCompilerCallback);
|
||||
GCHandle callbackHandle = GCHandle::Alloc(compilerCallback);
|
||||
YR_COMPILER_CALLBACK_FUNC callbackPointer = (YR_COMPILER_CALLBACK_FUNC)(Marshal::GetFunctionPointerForDelegate(compilerCallback)).ToPointer();
|
||||
yr_compiler_set_callback(compiler, callbackPointer, NULL);
|
||||
}
|
||||
|
||||
void CCompiler::HandleCompilerCallback(int ErrorLevel, const char* Filename, int LineNumber, const char* Message, void* UserData)
|
||||
void YSCompiler::HandleCompilerCallback(int errorLevel, const char* filename, int lineNumber, const char* message, void* userData)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ErrorLevel);
|
||||
UNREFERENCED_PARAMETER(UserData);
|
||||
UNREFERENCED_PARAMETER(errorLevel);
|
||||
UNREFERENCED_PARAMETER(userData);
|
||||
|
||||
String^ errorLevel = "ERROR";
|
||||
String^ file = filename ? marshal_as<String^>(filename) : "[unknown]";
|
||||
|
||||
if (ErrorLevel == YARA_ERROR_LEVEL_WARNING)
|
||||
{
|
||||
errorLevel = "WARNING";
|
||||
auto msg = String::Format("{0} on line {1}",
|
||||
marshal_as<String^>(message), lineNumber);
|
||||
|
||||
switch (errorLevel) {
|
||||
case YARA_ERROR_LEVEL_WARNING:
|
||||
warnings->AddReport(file, msg);
|
||||
break;
|
||||
|
||||
case YARA_ERROR_LEVEL_ERROR:
|
||||
errors->AddReport(file, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
auto msg = String::Format("{0}: {1} on line {2} in file: {3}",
|
||||
errorLevel, marshal_as<String^>(Message), LineNumber,
|
||||
Filename ? marshal_as<String^>(Filename) : "[none]");
|
||||
|
||||
Errors[ErrorLevel]->Add(msg);
|
||||
}
|
||||
}
|
||||
+18
-12
@@ -3,25 +3,31 @@
|
||||
namespace YaraSharp
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention::Cdecl)]
|
||||
delegate void YaraCompilerCallback(int ErrorLevel, const char* Filename, int LineNumber, const char* Message, void* UserData);
|
||||
delegate void YaraCompilerCallback(int errorLevel, const char* filename, int lineNumber, const char* message, void* userData);
|
||||
|
||||
public ref class CCompiler sealed
|
||||
public ref class YSCompiler sealed
|
||||
{
|
||||
initonly YR_COMPILER* Compiler;
|
||||
initonly Dictionary<int, List<String^>^>^ Errors;
|
||||
YSReport^ errors;
|
||||
YSReport^ warnings;
|
||||
initonly YR_COMPILER* compiler;
|
||||
|
||||
public:
|
||||
CCompiler(Dictionary<String^, Object^>^ ExternalVariables);
|
||||
~CCompiler();
|
||||
YSCompiler(Dictionary<String^, Object^>^ externalVariables);
|
||||
~YSCompiler();
|
||||
|
||||
CRules^ GetRules();
|
||||
List<String^>^ GetErrors(Boolean IncludeWarnings);
|
||||
int AddFile(String^ FilePath);
|
||||
void AddFiles(List<String^>^ FilePathList);
|
||||
YSRules^ GetRules();
|
||||
YSReport^ GetErrors();
|
||||
YSReport^ GetWarnings();
|
||||
|
||||
void HandleCompilerCallback(int ErrorLevel, const char* Filename, int LineNumber, const char* Message, void* UserData);
|
||||
void AddFile(String^ FilePath);
|
||||
void TryAddFile(String^ FilePath, Dictionary<String^, Object^>^ externalVariables);
|
||||
void AddFiles(List<String^>^ filePathList, Dictionary<String^, Object^>^ externalVariables);
|
||||
|
||||
private:
|
||||
void BindFileToCompiler(YR_COMPILER* compiler, String^ filePath);
|
||||
|
||||
void SetCompilerCallback();
|
||||
void SetCompilerExternals(Dictionary<String^, Object^>^ ExternalVariables);
|
||||
void SetCompilerExternals(Dictionary<String^, Object^>^ externalVariables);
|
||||
void HandleCompilerCallback(int errorLevel, const char* filename, int lineNumber, const char* message, void* userData);
|
||||
};
|
||||
}
|
||||
+15
-6
@@ -1,11 +1,20 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// CContext
|
||||
// Context
|
||||
namespace YaraSharp
|
||||
{
|
||||
// Constructor
|
||||
CContext::CContext() { ErrorUtility::ThrowOnError(yr_initialize()); }
|
||||
// Destructor
|
||||
CContext::~CContext() { ErrorUtility::ThrowOnError(yr_finalize()); }
|
||||
void CContext::Destroy() { delete this; }
|
||||
YSContext::YSContext()
|
||||
{
|
||||
YSException::ThrowOnError(yr_initialize());
|
||||
}
|
||||
|
||||
YSContext::~YSContext()
|
||||
{
|
||||
YSException::ThrowOnError(yr_finalize());
|
||||
}
|
||||
|
||||
void YSContext::Destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -2,11 +2,11 @@
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
public ref class CContext sealed
|
||||
public ref class YSContext sealed
|
||||
{
|
||||
public:
|
||||
CContext();
|
||||
~CContext();
|
||||
YSContext();
|
||||
~YSContext();
|
||||
void Destroy();
|
||||
};
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// ErrorUtility
|
||||
// YSException
|
||||
namespace YaraSharp
|
||||
{
|
||||
void ErrorUtility::ThrowOnError(int error)
|
||||
void YSException::ThrowOnError(int error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
@@ -17,12 +17,12 @@ namespace YaraSharp
|
||||
throw gcnew Exception(String::Format("Yara error: {0}. Code {1}", NiceErrorCode(error), error));
|
||||
}
|
||||
}
|
||||
void ErrorUtility::ThrowOnError(String^ error)
|
||||
void YSException::ThrowOnError(String^ error)
|
||||
{
|
||||
throw gcnew Exception(String::Format("Error: {0}", error));
|
||||
}
|
||||
|
||||
String^ ErrorUtility::NiceErrorCode(int error)
|
||||
String^ YSException::NiceErrorCode(int error)
|
||||
{
|
||||
// TODO: nice erros
|
||||
switch (error)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
public ref class ErrorUtility abstract sealed
|
||||
public ref class YSException abstract sealed
|
||||
{
|
||||
private:
|
||||
static String^ NiceErrorCode(int error);
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// Matches
|
||||
namespace YaraSharp
|
||||
{
|
||||
// Rule compilation
|
||||
YSCompiler^ YSInstance::CompileFromFiles(List<String^>^ FilePathList, Dictionary<String^, Object^>^ externalVariables)
|
||||
{
|
||||
// TODO: add namespace support
|
||||
|
||||
YSCompiler^ compiler = gcnew YSCompiler(externalVariables);
|
||||
compiler->AddFiles(FilePathList, externalVariables);
|
||||
|
||||
return compiler;
|
||||
}
|
||||
|
||||
// Scanning region
|
||||
List<YSMatches^>^ YSInstance::ScanFile(String^ path, YSRules^ rules, Dictionary<String^, Object^>^ externalVariables, int timeout)
|
||||
{
|
||||
YSScanner^ FScanner = gcnew YSScanner(rules, externalVariables);
|
||||
|
||||
List<YSMatches^>^ results = FScanner->ScanFile(path);
|
||||
delete FScanner;
|
||||
|
||||
return results;
|
||||
}
|
||||
// (not yet tested)
|
||||
List<YSMatches^>^ YSInstance::ScanProcess(int pID, YSRules^ rules, Dictionary<String^, Object^>^ externalVariables, int timeout)
|
||||
{
|
||||
YSScanner^ PScanner = gcnew YSScanner(rules, externalVariables);
|
||||
|
||||
List<YSMatches^>^ results = PScanner->ScanProcess(pID);
|
||||
delete PScanner;
|
||||
|
||||
return results;
|
||||
}
|
||||
// (not yet tested)
|
||||
List<YSMatches^>^ YSInstance::ScanMemory(uint8_t* buffer, int length, YSRules^ rules, Dictionary<String^, Object^>^ externalVariables, int timeout)
|
||||
{
|
||||
YSScanner^ MScanner = gcnew YSScanner(rules, externalVariables);
|
||||
|
||||
List<YSMatches^>^ results = MScanner->ScanMemory(buffer, length);
|
||||
delete MScanner;
|
||||
|
||||
return results;
|
||||
}
|
||||
// (not yet tested)
|
||||
List<YSMatches^>^ YSInstance::ScanMemory(array<uint8_t>^ buffer, YSRules^ rules, Dictionary<String^, Object^>^ externalVariables, int timeout)
|
||||
{
|
||||
if (buffer == nullptr || buffer->Length == 0)
|
||||
return gcnew List<YSMatches^>();
|
||||
else
|
||||
{
|
||||
pin_ptr<uint8_t> bufferPointer = &buffer[0];
|
||||
return ScanMemory(bufferPointer, buffer->Length, rules, externalVariables, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
Version^ YSInstance::GetVersion()
|
||||
{
|
||||
return Assembly::GetExecutingAssembly()->GetName()->Version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
public ref class YSInstance
|
||||
{
|
||||
public:
|
||||
YSCompiler^ CompileFromFiles(List<String^>^ filePathList, Dictionary<String^, Object^>^ externalVariables);
|
||||
|
||||
List<YSMatches^>^ ScanFile(String^ path, YSRules^ rules, Dictionary<String^, Object^>^ externalVariables, int timeout);
|
||||
List<YSMatches^>^ ScanProcess(int pID, YSRules^ rules, Dictionary<String^, Object^>^ externalVariables, int timeout);
|
||||
List<YSMatches^>^ ScanMemory(array<uint8_t>^ buffer, YSRules^ rules, Dictionary<String^, Object^>^ externalVariables, int timeout);
|
||||
List<YSMatches^>^ ScanMemory(uint8_t* buffer, int length, YSRules^ rules, Dictionary<String^, Object^>^ externalVariables, int timeout);
|
||||
|
||||
static Version^ GetVersion();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// Matches
|
||||
namespace YaraSharp
|
||||
{
|
||||
YSMatches::YSMatches()
|
||||
{
|
||||
Rule = nullptr;
|
||||
Matches = gcnew Dictionary<String^, List<YSMatch^>^>();
|
||||
}
|
||||
|
||||
YSMatches::YSMatches(YR_RULE * matchingRule)
|
||||
{
|
||||
Rule = gcnew YSRule(matchingRule);
|
||||
Matches = gcnew Dictionary<String^, List<YSMatch^>^>();
|
||||
|
||||
YR_STRING* stringEntry;
|
||||
YR_MATCH* matchEntry;
|
||||
|
||||
yr_rule_strings_foreach(matchingRule, stringEntry)
|
||||
{
|
||||
auto identifier = marshal_as<String^>(stringEntry->identifier);
|
||||
|
||||
yr_string_matches_foreach(stringEntry, matchEntry)
|
||||
{
|
||||
if (!Matches->ContainsKey(identifier))
|
||||
Matches->Add(identifier, gcnew List<YSMatch^>());
|
||||
|
||||
Matches[identifier]->Add(gcnew YSMatch(matchEntry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Match
|
||||
namespace YaraSharp
|
||||
{
|
||||
YSMatch::YSMatch()
|
||||
{
|
||||
Base = 0;
|
||||
Offset = 0;
|
||||
Data = gcnew array<uint8_t>(0);
|
||||
}
|
||||
|
||||
YSMatch::YSMatch(YR_MATCH* match)
|
||||
{
|
||||
/*
|
||||
int64_t base; // Base address for the match
|
||||
int64_t offset; // Offset relative to base for the match
|
||||
int32_t match_length; // Match length
|
||||
int32_t data_length;
|
||||
const uint8_t* data;
|
||||
*/
|
||||
|
||||
Base = match->base;
|
||||
Offset = match->offset;
|
||||
|
||||
Data = gcnew array<uint8_t>(match->match_length);
|
||||
Marshal::Copy(IntPtr((void *)match->data), Data, 0, match->data_length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
public ref class YSMatch sealed
|
||||
{
|
||||
public:
|
||||
|
||||
property uint64_t Base;
|
||||
property uint64_t Offset;
|
||||
property array<uint8_t>^ Data;
|
||||
|
||||
YSMatch();
|
||||
YSMatch(YR_MATCH* match);
|
||||
};
|
||||
|
||||
public ref class YSMatches sealed
|
||||
{
|
||||
public:
|
||||
|
||||
property YSRule^ Rule;
|
||||
property Dictionary<String^, List<YSMatch^>^>^ Matches;
|
||||
|
||||
YSMatches();
|
||||
YSMatches(YR_RULE* matchingRule);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
YSReport::YSReport()
|
||||
{
|
||||
files = gcnew Dictionary<String^, List<String^>^>();
|
||||
}
|
||||
YSReport::~YSReport()
|
||||
{
|
||||
files->Clear();
|
||||
delete files;
|
||||
files = nullptr;
|
||||
}
|
||||
void YSReport::AddReport(String^ file, String^ description)
|
||||
{
|
||||
if (!files->ContainsKey(file))
|
||||
{
|
||||
files->Add(file, gcnew List<String^>());
|
||||
}
|
||||
|
||||
files[file]->Add(description);
|
||||
|
||||
}
|
||||
void YSReport::MergeReports(YSReport^ report)
|
||||
{
|
||||
Dictionary<String^, List<String^>^>^ reportFiles = report->Dump();
|
||||
|
||||
for each(KeyValuePair<String^, List<String^>^> entry in reportFiles)
|
||||
{
|
||||
String^ file = entry.Key;
|
||||
for each(String^ description in entry.Value)
|
||||
{
|
||||
AddReport(file, description);
|
||||
}
|
||||
}
|
||||
}
|
||||
bool YSReport::IsEmpty()
|
||||
{
|
||||
return files->Keys->Count == 0 ? true : false;
|
||||
}
|
||||
|
||||
List<String^>^ YSReport::GetFiles()
|
||||
{
|
||||
return gcnew List<String^>(files->Keys);
|
||||
}
|
||||
Dictionary<String^, List<String^>^>^ YSReport::Dump()
|
||||
{
|
||||
return files;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
public ref class YSReport
|
||||
{
|
||||
Dictionary<String^, List<String^>^>^ files;
|
||||
public:
|
||||
YSReport();
|
||||
~YSReport();
|
||||
|
||||
bool IsEmpty();
|
||||
List<String^>^ GetFiles();
|
||||
Dictionary<String^, List<String^>^>^ Dump();
|
||||
|
||||
void MergeReports(YSReport^ report);
|
||||
void AddReport(String^ file, String^ description);
|
||||
};
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// CMatches
|
||||
namespace YaraSharp
|
||||
{
|
||||
CMatches::CMatches()
|
||||
{
|
||||
Rule = nullptr;
|
||||
Matches = gcnew Dictionary<String^, List<CMatch^>^>();
|
||||
}
|
||||
|
||||
CMatches::CMatches(YR_RULE * MatchingRule)
|
||||
{
|
||||
Rule = gcnew CRule(MatchingRule);
|
||||
Matches = gcnew Dictionary<String^, List<CMatch^>^>();
|
||||
|
||||
YR_STRING* StringEntry;
|
||||
YR_MATCH* MatchEntry;
|
||||
|
||||
yr_rule_strings_foreach(MatchingRule, StringEntry)
|
||||
{
|
||||
auto identifier = marshal_as<String^>(StringEntry->identifier);
|
||||
|
||||
yr_string_matches_foreach(StringEntry, MatchEntry)
|
||||
{
|
||||
if (!Matches->ContainsKey(identifier))
|
||||
Matches->Add(identifier, gcnew List<CMatch^>());
|
||||
|
||||
Matches[identifier]->Add(gcnew CMatch(MatchEntry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CMatch
|
||||
namespace YaraSharp
|
||||
{
|
||||
CMatch::CMatch()
|
||||
{
|
||||
Base = 0;
|
||||
Offset = 0;
|
||||
Data = gcnew array<uint8_t>(0);
|
||||
}
|
||||
|
||||
CMatch::CMatch(YR_MATCH* Match)
|
||||
{
|
||||
/*
|
||||
int64_t base; // Base address for the match
|
||||
int64_t offset; // Offset relative to base for the match
|
||||
int32_t match_length; // Match length
|
||||
int32_t data_length;
|
||||
const uint8_t* data;
|
||||
*/
|
||||
|
||||
Base = Match->base;
|
||||
Offset = Match->offset;
|
||||
|
||||
Data = gcnew array<uint8_t>(Match->match_length);
|
||||
Marshal::Copy(IntPtr((void *)Match->data), Data, 0, Match->data_length);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
public ref class CMatch sealed
|
||||
{
|
||||
public:
|
||||
|
||||
property uint64_t Base;
|
||||
property uint64_t Offset;
|
||||
property array<uint8_t>^ Data;
|
||||
|
||||
CMatch();
|
||||
CMatch(YR_MATCH* Match);
|
||||
};
|
||||
|
||||
public ref class CMatches sealed
|
||||
{
|
||||
public:
|
||||
|
||||
property CRule^ Rule;
|
||||
property Dictionary<String^, List<CMatch^>^>^ Matches;
|
||||
|
||||
CMatches();
|
||||
CMatches(YR_RULE* MatchingRule);
|
||||
};
|
||||
}
|
||||
+55
-42
@@ -1,84 +1,97 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// CRules
|
||||
// Rules
|
||||
namespace YaraSharp
|
||||
{
|
||||
CRules::operator YR_RULES*() { return Rules; }
|
||||
CRules::CRules(YR_RULES* rules) : Rules(rules) { }
|
||||
CRules::~CRules() { if (Rules) yr_rules_destroy(Rules); }
|
||||
void CRules::Destroy() { delete this; }
|
||||
}
|
||||
// CRule
|
||||
namespace YaraSharp
|
||||
{
|
||||
CRule::CRule()
|
||||
YSRules::operator YR_RULES*()
|
||||
{
|
||||
return rules;
|
||||
}
|
||||
YSRules::YSRules(YR_RULES* rules)
|
||||
{
|
||||
this->rules = rules;
|
||||
}
|
||||
YSRules::~YSRules()
|
||||
{
|
||||
if (rules)
|
||||
{
|
||||
yr_rules_destroy(rules);
|
||||
}
|
||||
}
|
||||
void YSRules::Destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
// YSRule
|
||||
namespace YaraSharp
|
||||
{
|
||||
YSRule::YSRule()
|
||||
{
|
||||
Namespace = nullptr;
|
||||
Identifier = nullptr;
|
||||
Tags = gcnew List<String^>();
|
||||
Strings = gcnew List<String^>();
|
||||
Meta = gcnew Dictionary<String^, Object^>();
|
||||
}
|
||||
CRule::CRule(YR_RULE* Rule)
|
||||
YSRule::YSRule(YR_RULE* Rule)
|
||||
{
|
||||
Namespace = nullptr;
|
||||
Tags = CRule::GetRuleTags(Rule);
|
||||
Meta = CRule::GetRuleMeta(Rule);
|
||||
Strings = CRule::GetRuleStrings(Rule);
|
||||
Tags = YSRule::GetRuleTags(Rule);
|
||||
Meta = YSRule::GetRuleMeta(Rule);
|
||||
Strings = YSRule::GetRuleStrings(Rule);
|
||||
Identifier = gcnew String(Rule->identifier);
|
||||
}
|
||||
|
||||
List<String^>^ CRule::GetRuleTags(YR_RULE* Rule)
|
||||
List<String^>^ YSRule::GetRuleTags(YR_RULE* rule)
|
||||
{
|
||||
List<String^>^ Result = gcnew List<String^>();
|
||||
List<String^>^ result = gcnew List<String^>();
|
||||
|
||||
const char* TagEntry;
|
||||
yr_rule_tags_foreach(Rule, TagEntry)
|
||||
Result->Add(gcnew String(TagEntry));
|
||||
const char* tagEntry;
|
||||
yr_rule_tags_foreach(rule, tagEntry)
|
||||
result->Add(gcnew String(tagEntry));
|
||||
|
||||
return Result;
|
||||
return result;
|
||||
}
|
||||
List<String^>^ CRule::GetRuleStrings(YR_RULE* Rule)
|
||||
List<String^>^ YSRule::GetRuleStrings(YR_RULE* rule)
|
||||
{
|
||||
List<String^>^ Result = gcnew List<String^>();
|
||||
List<String^>^ result = gcnew List<String^>();
|
||||
|
||||
YR_STRING* StringEntry;
|
||||
yr_rule_strings_foreach(Rule, StringEntry)
|
||||
Result->Add(gcnew String(StringEntry->identifier));
|
||||
YR_STRING* stringEntry;
|
||||
yr_rule_strings_foreach(rule, stringEntry)
|
||||
result->Add(gcnew String(stringEntry->identifier));
|
||||
|
||||
return Result;
|
||||
return result;
|
||||
}
|
||||
Dictionary<String^, Object^>^ CRule::GetRuleMeta(YR_RULE* Rule)
|
||||
Dictionary<String^, Object^>^ YSRule::GetRuleMeta(YR_RULE* rule)
|
||||
{
|
||||
Dictionary<String^, Object^>^ Result = gcnew Dictionary<String^, Object^>();
|
||||
Dictionary<String^, Object^>^ result = gcnew Dictionary<String^, Object^>();
|
||||
|
||||
YR_META* MetaEntry;
|
||||
yr_rule_metas_foreach(Rule, MetaEntry)
|
||||
YR_META* metaEntry;
|
||||
yr_rule_metas_foreach(rule, metaEntry)
|
||||
{
|
||||
if (MetaEntry->identifier == NULL)
|
||||
if (metaEntry->identifier == NULL)
|
||||
throw gcnew NullReferenceException("(Meta) Çíà÷åíèå íå ìîæåò áûòü ïóñòûì");
|
||||
|
||||
String^ MetaID = gcnew String(MetaEntry->identifier);
|
||||
Object^ MetaValue = nullptr;
|
||||
String^ metaID = gcnew String(metaEntry->identifier);
|
||||
Object^ metaValue = nullptr;
|
||||
|
||||
switch (MetaEntry->type)
|
||||
switch (metaEntry->type)
|
||||
{
|
||||
case META_TYPE_BOOLEAN:
|
||||
MetaValue = (bool)(MetaEntry->integer == 1);
|
||||
metaValue = (bool)(metaEntry->integer == 1);
|
||||
break;
|
||||
case META_TYPE_INTEGER:
|
||||
MetaValue = (Int32)MetaEntry->integer;
|
||||
metaValue = (Int32)metaEntry->integer;
|
||||
break;
|
||||
case META_TYPE_STRING:
|
||||
MetaValue = gcnew String(MetaEntry->string);
|
||||
metaValue = gcnew String(metaEntry->string);
|
||||
break;
|
||||
}
|
||||
|
||||
// Distinct
|
||||
if (!Result->ContainsKey(MetaID))
|
||||
Result->Add(MetaID, MetaValue);
|
||||
if (!result->ContainsKey(metaID))
|
||||
result->Add(metaID, metaValue);
|
||||
}
|
||||
|
||||
return Result;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+11
-12
@@ -2,33 +2,32 @@
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
public ref class CRules sealed
|
||||
public ref class YSRules sealed
|
||||
{
|
||||
YR_RULES* Rules;
|
||||
YR_RULES* rules;
|
||||
|
||||
public:
|
||||
CRules(YR_RULES* rules);
|
||||
YSRules(YR_RULES* rules);
|
||||
operator YR_RULES*();
|
||||
void Destroy();
|
||||
~CRules();
|
||||
~YSRules();
|
||||
};
|
||||
|
||||
|
||||
public ref class CRule sealed
|
||||
public ref class YSRule sealed
|
||||
{
|
||||
public:
|
||||
property String^ Namespace;
|
||||
property String^ Identifier;
|
||||
property List<String^>^ Tags;
|
||||
property Dictionary<String^, Object^>^ Meta;
|
||||
property List<String^>^ Strings;
|
||||
property Dictionary<String^, Object^>^ Meta;
|
||||
|
||||
CRule();
|
||||
CRule(YR_RULE* Rule);
|
||||
YSRule();
|
||||
YSRule(YR_RULE* rule);
|
||||
|
||||
private:
|
||||
List<String^>^ CRule::GetRuleTags(YR_RULE* Rule);
|
||||
List<String^>^ CRule::GetRuleStrings(YR_RULE* Rule);
|
||||
Dictionary<String^, Object^>^ CRule::GetRuleMeta(YR_RULE* Rule);
|
||||
List<String^>^ GetRuleTags(YR_RULE* rule);
|
||||
List<String^>^ GetRuleStrings(YR_RULE* rule);
|
||||
Dictionary<String^, Object^>^ GetRuleMeta(YR_RULE* rule);
|
||||
};
|
||||
}
|
||||
|
||||
+42
-37
@@ -1,87 +1,92 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// CScanner
|
||||
// Scanner
|
||||
namespace YaraSharp
|
||||
{
|
||||
// Constructor
|
||||
CScanner::CScanner(CRules^ rules, Dictionary<String^, Object^>^ ExternalVariables)
|
||||
YSScanner::YSScanner(YSRules^ rules, Dictionary<String^, Object^>^ externalVariables)
|
||||
{
|
||||
YR_SCANNER* TestScanner;
|
||||
ErrorUtility::ThrowOnError(yr_scanner_create((YR_RULES*)rules, &TestScanner));
|
||||
Scanner = TestScanner;
|
||||
YSException::ThrowOnError(yr_scanner_create((YR_RULES*)rules, &TestScanner));
|
||||
scanner = TestScanner;
|
||||
|
||||
Matches = gcnew List<CMatches^>();
|
||||
matches = gcnew List<YSMatches^>();
|
||||
|
||||
// TODO: add timeout support
|
||||
|
||||
SetScannerExternals(ExternalVariables);
|
||||
|
||||
SetScannerExternals(externalVariables);
|
||||
SetScannerCallback();
|
||||
}
|
||||
// Destructor
|
||||
CScanner::~CScanner() { if (Scanner) yr_scanner_destroy(Scanner); }
|
||||
|
||||
|
||||
YSScanner::~YSScanner()
|
||||
{
|
||||
if (scanner)
|
||||
{
|
||||
yr_scanner_destroy(scanner);
|
||||
}
|
||||
}
|
||||
|
||||
// Scan region
|
||||
List<CMatches^>^ CScanner::ScanProcess(int PID)
|
||||
List<YSMatches^>^ YSScanner::ScanProcess(int pID)
|
||||
{
|
||||
ErrorUtility::ThrowOnError(yr_scanner_scan_proc(Scanner, PID));
|
||||
return Matches;
|
||||
YSException::ThrowOnError(yr_scanner_scan_proc(scanner, pID));
|
||||
return matches;
|
||||
}
|
||||
|
||||
|
||||
List<CMatches^>^ CScanner::ScanFile(String^ Path)
|
||||
List<YSMatches^>^ YSScanner::ScanFile(String^ Path)
|
||||
{
|
||||
ErrorUtility::ThrowOnError(yr_scanner_scan_file(Scanner,
|
||||
(marshal_as<std::wstring>(Path)).c_str()));
|
||||
return Matches;
|
||||
YSException::ThrowOnError(yr_scanner_scan_file(scanner,
|
||||
(marshal_as<std::wstring>(Path)).c_str()));
|
||||
return matches;
|
||||
}
|
||||
List<CMatches^>^ CScanner::ScanMemory(uint8_t* Buffer, int Length)
|
||||
List<YSMatches^>^ YSScanner::ScanMemory(uint8_t* Buffer, int Length)
|
||||
{
|
||||
ErrorUtility::ThrowOnError(yr_scanner_scan_mem(Scanner, Buffer, Length));
|
||||
return Matches;
|
||||
YSException::ThrowOnError(yr_scanner_scan_mem(scanner, Buffer, Length));
|
||||
return matches;
|
||||
}
|
||||
|
||||
// Set externals
|
||||
void CScanner::SetScannerExternals(Dictionary<String^, Object^>^ ExternalVariables)
|
||||
void YSScanner::SetScannerExternals(Dictionary<String^, Object^>^ externalVariables)
|
||||
{
|
||||
if (ExternalVariables)
|
||||
if (externalVariables)
|
||||
{
|
||||
marshal_context CTX;
|
||||
|
||||
for each (auto ExternalVariable in ExternalVariables)
|
||||
for each (auto externalVariable in externalVariables)
|
||||
{
|
||||
const char* VariablePointer = CTX.marshal_as<const char*>(ExternalVariable.Key);
|
||||
Type^ VariableType = ExternalVariable.Value->GetType();
|
||||
const char* VariablePointer = CTX.marshal_as<const char*>(externalVariable.Key);
|
||||
Type^ VariableType = externalVariable.Value->GetType();
|
||||
int ExternalError = ERROR_SUCCESS;
|
||||
|
||||
if (VariableType == Boolean::typeid)
|
||||
ExternalError = yr_scanner_define_boolean_variable(Scanner, VariablePointer, (bool)ExternalVariable.Value);
|
||||
ExternalError = yr_scanner_define_boolean_variable(scanner, VariablePointer, (bool)externalVariable.Value);
|
||||
else if (VariableType == Double::typeid)
|
||||
ExternalError = yr_scanner_define_float_variable(Scanner, VariablePointer, (double)ExternalVariable.Value);
|
||||
ExternalError = yr_scanner_define_float_variable(scanner, VariablePointer, (double)externalVariable.Value);
|
||||
else if (VariableType == Int64::typeid || VariableType == Int32::typeid)
|
||||
ExternalError = yr_scanner_define_integer_variable(Scanner, VariablePointer, (Int64)ExternalVariable.Value);
|
||||
ExternalError = yr_scanner_define_integer_variable(scanner, VariablePointer, (Int64)externalVariable.Value);
|
||||
else if (VariableType == String::typeid)
|
||||
ExternalError = yr_scanner_define_string_variable(Scanner, VariablePointer, CTX.marshal_as<const char*>((String^)ExternalVariable.Value));
|
||||
ExternalError = yr_scanner_define_string_variable(scanner, VariablePointer, CTX.marshal_as<const char*>((String^)externalVariable.Value));
|
||||
else
|
||||
throw gcnew NotSupportedException(String::Format("Unsupported external variable: '{0}'", VariableType->Name));
|
||||
|
||||
if (ExternalError != ERROR_SUCCESS)
|
||||
ErrorUtility::ThrowOnError("(Scanner) Error during external variable intialization");
|
||||
YSException::ThrowOnError("(Scanner) Error during external variable intialization");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Callback
|
||||
void CScanner::SetScannerCallback()
|
||||
void YSScanner::SetScannerCallback()
|
||||
{
|
||||
YaraScanCallback^ ScannerCallback = gcnew YaraScanCallback(this, &CScanner::HandleScannerCallback);
|
||||
YaraScanCallback^ ScannerCallback = gcnew YaraScanCallback(this, &YSScanner::HandleScannerCallback);
|
||||
GCHandle CallbackHandle = GCHandle::Alloc(ScannerCallback);
|
||||
YR_CALLBACK_FUNC CallbackPointer = (YR_CALLBACK_FUNC)Marshal::GetFunctionPointerForDelegate(ScannerCallback).ToPointer();
|
||||
yr_scanner_set_callback(Scanner, CallbackPointer, NULL);
|
||||
yr_scanner_set_callback(scanner, CallbackPointer, NULL);
|
||||
}
|
||||
int CScanner::HandleScannerCallback(int message, void* data, void* context)
|
||||
int YSScanner::HandleScannerCallback(int message, void* data, void* context)
|
||||
{
|
||||
if (message == CALLBACK_MSG_RULE_MATCHING)
|
||||
Matches->Add(gcnew CMatches((YR_RULE*)data));
|
||||
matches->Add(gcnew YSMatches((YR_RULE*)data));
|
||||
|
||||
return CALLBACK_CONTINUE;
|
||||
}
|
||||
|
||||
+11
-11
@@ -3,23 +3,23 @@
|
||||
namespace YaraSharp
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention::Cdecl)]
|
||||
delegate int YaraScanCallback(int Message, void* Data, void* Context);
|
||||
delegate int YaraScanCallback(int message, void* data, void* context);
|
||||
|
||||
public ref class CScanner sealed
|
||||
public ref class YSScanner sealed
|
||||
{
|
||||
initonly YR_SCANNER * Scanner;
|
||||
List<CMatches^>^ Matches;
|
||||
initonly YR_SCANNER * scanner;
|
||||
List<YSMatches^>^ matches;
|
||||
|
||||
public:
|
||||
CScanner(CRules^ rules, Dictionary<String^, Object^>^ ExternalVariables);
|
||||
~CScanner();
|
||||
YSScanner(YSRules^ rules, Dictionary<String^, Object^>^ externalVariables);
|
||||
~YSScanner();
|
||||
|
||||
List<CMatches^>^ ScanProcess(int PID);
|
||||
List<CMatches^>^ ScanFile(String^ Path);
|
||||
List<CMatches^>^ ScanMemory(uint8_t* Buffer, int Length);
|
||||
int HandleScannerCallback(int Message, void* Data, void* Context);
|
||||
List<YSMatches^>^ ScanProcess(int pID);
|
||||
List<YSMatches^>^ ScanFile(String^ path);
|
||||
List<YSMatches^>^ ScanMemory(uint8_t* buffer, int length);
|
||||
int HandleScannerCallback(int message, void* data, void* context);
|
||||
private:
|
||||
void SetScannerCallback();
|
||||
void SetScannerExternals(Dictionary<String^, Object^>^ ExternalVariables);
|
||||
void SetScannerExternals(Dictionary<String^, Object^>^ externalVariables);
|
||||
};
|
||||
}
|
||||
+3
-2
@@ -14,10 +14,11 @@ using namespace System::Collections::Generic;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
|
||||
#include "yara.h"
|
||||
#include "Report.h"
|
||||
#include "Exceptions.h"
|
||||
#include "Context.h"
|
||||
#include "Rules.h"
|
||||
#include "Compiler.h"
|
||||
#include "Result.h"
|
||||
#include "Matches.h"
|
||||
#include "Scanner.h"
|
||||
#include "YaraSharp.h"
|
||||
#include "Instance.h"
|
||||
@@ -1,112 +0,0 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// CMatches
|
||||
namespace YaraSharp
|
||||
{
|
||||
// Check list of yara files
|
||||
Dictionary<String^, List<String^>^>^ CYaraSharp::CheckYaraRules([Out] List<String^>^ FilePathList, Dictionary<String^, Object^>^ ExternalVariables)
|
||||
{
|
||||
Dictionary<String^, List<String^>^>^ CompilationErrors = gcnew Dictionary<String^, List<String^>^>();
|
||||
|
||||
// Iterative check
|
||||
for (int i = 0; i < FilePathList->Count; i++)
|
||||
{
|
||||
CCompiler^ TestCompiler = gcnew CCompiler(ExternalVariables);
|
||||
|
||||
if (TestCompiler->AddFile(FilePathList[i]))
|
||||
{
|
||||
if (CompilationErrors->ContainsKey(FilePathList[i]))
|
||||
{
|
||||
CompilationErrors[FilePathList[i]]->AddRange(TestCompiler->GetErrors(false));
|
||||
}
|
||||
else
|
||||
{
|
||||
CompilationErrors->Add(FilePathList[i], TestCompiler->GetErrors(false));
|
||||
}
|
||||
|
||||
FilePathList->Remove(FilePathList[i--]);
|
||||
}
|
||||
else if (TestCompiler->GetErrors(true)->Count > 0)
|
||||
{
|
||||
if (CompilationErrors->ContainsKey(FilePathList[i]))
|
||||
{
|
||||
CompilationErrors[FilePathList[i]]->AddRange(TestCompiler->GetErrors(true));
|
||||
}
|
||||
else
|
||||
{
|
||||
CompilationErrors->Add(FilePathList[i], TestCompiler->GetErrors(true));
|
||||
}
|
||||
}
|
||||
|
||||
delete TestCompiler;
|
||||
}
|
||||
|
||||
return CompilationErrors;
|
||||
}
|
||||
|
||||
// Rule compilation
|
||||
CRules^ CYaraSharp::CompileFromFiles(List<String^>^ FilePathList, Dictionary<String^, Object^>^ ExternalVariables,
|
||||
[Out] Dictionary<String^, List<String^>^>^% CompilationErrors)
|
||||
{
|
||||
// TODO: add namespace support
|
||||
|
||||
// First: check
|
||||
CompilationErrors = CheckYaraRules(FilePathList, ExternalVariables);
|
||||
|
||||
// Second: compile
|
||||
CCompiler^ Compiler = gcnew CCompiler(ExternalVariables);
|
||||
Compiler->AddFiles(FilePathList);
|
||||
CRules^ Result = Compiler->GetRules();
|
||||
delete Compiler;
|
||||
|
||||
// Return compiled rules
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Scanning region
|
||||
List<CMatches^>^ CYaraSharp::ScanFile(String^ Path, CRules^ Rules, Dictionary<String^, Object^>^ ExternalVariables, int Timeout)
|
||||
{
|
||||
CScanner^ FScanner = gcnew CScanner(Rules, ExternalVariables);
|
||||
|
||||
List<CMatches^>^ Results = FScanner->ScanFile(Path);
|
||||
delete FScanner;
|
||||
|
||||
return Results;
|
||||
}
|
||||
// (not yet tested)
|
||||
List<CMatches^>^ CYaraSharp::ScanProcess(int PID, CRules^ Rules, Dictionary<String^, Object^>^ ExternalVariables, int Timeout)
|
||||
{
|
||||
CScanner^ PScanner = gcnew CScanner(Rules, ExternalVariables);
|
||||
|
||||
List<CMatches^>^ Results = PScanner->ScanProcess(PID);
|
||||
delete PScanner;
|
||||
|
||||
return Results;
|
||||
}
|
||||
// (not yet tested)
|
||||
List<CMatches^>^ CYaraSharp::ScanMemory(uint8_t* Buffer, int Length, CRules^ Rules, Dictionary<String^, Object^>^ ExternalVariables, int Timeout)
|
||||
{
|
||||
CScanner^ MScanner = gcnew CScanner(Rules, ExternalVariables);
|
||||
|
||||
List<CMatches^>^ Results = MScanner->ScanMemory(Buffer, Length);
|
||||
delete MScanner;
|
||||
|
||||
return Results;
|
||||
}
|
||||
// (not yet tested)
|
||||
List<CMatches^>^ CYaraSharp::ScanMemory(array<uint8_t>^ Buffer, CRules^ Rules, Dictionary<String^, Object^>^ ExternalVariables, int Timeout)
|
||||
{
|
||||
if (Buffer == nullptr || Buffer->Length == 0)
|
||||
return gcnew List<CMatches^>();
|
||||
else
|
||||
{
|
||||
pin_ptr<uint8_t> BufferPointer = &Buffer[0];
|
||||
return ScanMemory(BufferPointer, Buffer->Length, Rules, ExternalVariables, Timeout);
|
||||
}
|
||||
}
|
||||
|
||||
Version^ CYaraSharp::GetVersion()
|
||||
{
|
||||
return Assembly::GetExecutingAssembly()->GetName()->Version;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
public ref class CYaraSharp
|
||||
{
|
||||
private:
|
||||
Dictionary<String^, List<String^>^>^ CheckYaraRules([Out] List<String^>^ FilePathList, Dictionary<String^, Object^>^ ExternalVariables);
|
||||
|
||||
public:
|
||||
CRules^ CompileFromFiles(List<String^>^ FilePathList,
|
||||
Dictionary<String^, Object^>^ ExternalVariables,
|
||||
[Out] Dictionary<String^, List<String^>^>^% CompilationErrors);
|
||||
|
||||
List<CMatches^>^ ScanFile(String^ Path, CRules^ Rules, Dictionary<String^, Object^>^ ExternalVariables, int Timeout);
|
||||
List<CMatches^>^ ScanProcess(int PID, CRules^ Rules, Dictionary<String^, Object^>^ ExternalVariables, int Timeout);
|
||||
List<CMatches^>^ ScanMemory(array<uint8_t>^ Buffer, CRules^ Rules, Dictionary<String^, Object^>^ ExternalVariables, int Timeout);
|
||||
List<CMatches^>^ ScanMemory(uint8_t* Buffer, int Length, CRules^ Rules, Dictionary<String^, Object^>^ ExternalVariables, int Timeout);
|
||||
|
||||
static Version^ GetVersion();
|
||||
};
|
||||
}
|
||||
Binary file not shown.
@@ -156,12 +156,13 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Compiler.h" />
|
||||
<ClInclude Include="Context.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="YaraSharp.h" />
|
||||
<ClInclude Include="Report.h" />
|
||||
<ClInclude Include="Instance.h" />
|
||||
<ClInclude Include="Exceptions.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="Rules.h" />
|
||||
<ClInclude Include="Scanner.h" />
|
||||
<ClInclude Include="Result.h" />
|
||||
<ClInclude Include="Matches.h" />
|
||||
<ClInclude Include="Stdafx.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -169,7 +170,8 @@
|
||||
<ClCompile Include="Compiler.cpp" />
|
||||
<ClCompile Include="Context.cpp" />
|
||||
<ClCompile Include="Exceptions.cpp" />
|
||||
<ClCompile Include="Result.cpp" />
|
||||
<ClCompile Include="Report.cpp" />
|
||||
<ClCompile Include="Matches.cpp" />
|
||||
<ClCompile Include="Rules.cpp" />
|
||||
<ClCompile Include="Scanner.cpp" />
|
||||
<ClCompile Include="Stdafx.cpp">
|
||||
@@ -178,7 +180,10 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="YaraSharp.cpp" />
|
||||
<ClCompile Include="Instance.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="YaraSharp.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -26,15 +26,18 @@
|
||||
<ClInclude Include="Scanner.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Result.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="YaraSharp.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Context.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Report.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Matches.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Instance.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -46,12 +49,6 @@
|
||||
<ClCompile Include="Stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Rules.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Result.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Exceptions.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -61,11 +58,23 @@
|
||||
<ClCompile Include="Scanner.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="YaraSharp.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Context.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Report.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Rules.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Matches.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Instance.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="YaraSharp.rc" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,8 +1,9 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by dll.rc
|
||||
// Used by YaraSharp.rc
|
||||
//
|
||||
|
||||
// Ñëåäóþùèå ñòàíäàðòíûå çíà÷åíèÿ äëÿ íîâûõ îáúåêòîâ
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using YaraSharp;
|
||||
|
||||
namespace YaraSharpUnitTests
|
||||
@@ -25,16 +24,17 @@ namespace YaraSharpUnitTests
|
||||
string yaraRuleFile = Path.Combine(TestDataDirectory, $"{inputFileBase}.yar");
|
||||
string yaraInputFile = Path.Combine(TestDataDirectory, $"{inputFileBase}.txt");
|
||||
|
||||
CYaraSharp yaraInstance = new CYaraSharp();
|
||||
YSInstance yaraInstance = new YSInstance();
|
||||
|
||||
using (CContext context = new CContext())
|
||||
using (YSContext context = new YSContext())
|
||||
{
|
||||
using (CCompiler compiler = new CCompiler(null))
|
||||
using (YSCompiler compiler = new YSCompiler(null))
|
||||
{
|
||||
compiler.AddFile(yaraRuleFile);
|
||||
List<string> compilerErrors = compiler.GetErrors(true);
|
||||
YSReport compilerErrors = compiler.GetErrors();
|
||||
YSReport compilerWarnings = compiler.GetWarnings();
|
||||
|
||||
CScanner scanner = new CScanner(compiler.GetRules(), null);
|
||||
YSScanner scanner = new YSScanner(compiler.GetRules(), null);
|
||||
Assert.IsTrue(scanner.ScanFile(yaraInputFile).Any(r => r.Rule.Identifier == "WarningRule"));
|
||||
}
|
||||
}
|
||||
|
||||
+20
-11
@@ -11,34 +11,43 @@ namespace YaraTest
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// Get Version
|
||||
Version DllVersion = CYaraSharp.GetVersion();
|
||||
Version DllVersion = YSInstance.GetVersion();
|
||||
|
||||
// All API calls happens here
|
||||
YaraSharp.CYaraSharp YSInstance = new CYaraSharp();
|
||||
YSInstance instance = new YSInstance();
|
||||
|
||||
// Get list of YARA rules
|
||||
List<string> ruleFilenames = Directory.GetFiles(@"D:\Test\yara", "*.yar", SearchOption.AllDirectories).ToList();
|
||||
|
||||
// Declare external variables (could be null)
|
||||
Dictionary<string, object> Externals = new Dictionary<string, object>()
|
||||
Dictionary<string, object> externals = new Dictionary<string, object>()
|
||||
{
|
||||
{ "filename", string.Empty },
|
||||
{ "filepath", string.Empty },
|
||||
{ "extension", string.Empty }
|
||||
};
|
||||
|
||||
// Errors occured during rule compilation: ignored_file : List<reasons>
|
||||
Dictionary<string, List<string>> Errors = new Dictionary<string, List<string>>();
|
||||
|
||||
// Context is where yara is initialized
|
||||
// From yr_initialize() to yr_finalize()
|
||||
using (YaraSharp.CContext YSContext = new YaraSharp.CContext())
|
||||
using (YSContext context = new YSContext())
|
||||
{
|
||||
// Compiling rules
|
||||
using (YaraSharp.CRules YSRules = YSInstance.CompileFromFiles(Directory.GetFiles(@"<dir with signatures>", "*.yar", SearchOption.AllDirectories).ToList(), Externals, out Errors))
|
||||
using (YSCompiler compiler = instance.CompileFromFiles(ruleFilenames, externals))
|
||||
{
|
||||
// Get compiled rules
|
||||
YSRules rules = compiler.GetRules();
|
||||
|
||||
// Get errors
|
||||
YSReport errors = compiler.GetErrors();
|
||||
// Get warnings
|
||||
YSReport warnings = compiler.GetWarnings();
|
||||
|
||||
|
||||
// Some file to test yara rules
|
||||
string Filename = @"\\?\<path to file>";
|
||||
string Filename = @"";
|
||||
|
||||
// Get matches
|
||||
List<YaraSharp.CMatches> Matches = YSInstance.ScanFile(Filename, YSRules,
|
||||
List<YSMatches> Matches = instance.ScanFile(Filename, rules,
|
||||
new Dictionary<string, object>()
|
||||
{
|
||||
{ "filename", Alphaleonis.Win32.Filesystem.Path.GetFileName(Filename) },
|
||||
@@ -48,7 +57,7 @@ namespace YaraTest
|
||||
0);
|
||||
|
||||
// Iterate over matches
|
||||
foreach (YaraSharp.CMatches Match in Matches)
|
||||
foreach (YSMatches Match in Matches)
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>YaraSharp</id>
|
||||
<version>1.2.2</version>
|
||||
<version>1.3.0</version>
|
||||
<title>YaraSharp</title>
|
||||
<authors>stellarbears</authors>
|
||||
<owners>stellarbears</owners>
|
||||
|
||||
Reference in New Issue
Block a user