mirror of
https://github.com/stellarbear/YaraSharp
synced 2026-06-08 17:36:09 +00:00
Добавьте файлы проекта.
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
#*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27428.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "YaraSharp", "YaraSharp\YaraSharp.vcxproj", "{C005E3B9-2474-4FEA-B5F4-7BB897111E8F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libyara", "yara-master\windows\vs2015\libyara\libyara.vcxproj", "{E236CE39-D8F3-4DB6-985C-F2794FF17746}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C005E3B9-2474-4FEA-B5F4-7BB897111E8F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C005E3B9-2474-4FEA-B5F4-7BB897111E8F}.Debug|x64.Build.0 = Debug|x64
|
||||
{C005E3B9-2474-4FEA-B5F4-7BB897111E8F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{C005E3B9-2474-4FEA-B5F4-7BB897111E8F}.Debug|x86.Build.0 = Debug|Win32
|
||||
{C005E3B9-2474-4FEA-B5F4-7BB897111E8F}.Release|x64.ActiveCfg = Release|x64
|
||||
{C005E3B9-2474-4FEA-B5F4-7BB897111E8F}.Release|x64.Build.0 = Release|x64
|
||||
{C005E3B9-2474-4FEA-B5F4-7BB897111E8F}.Release|x86.ActiveCfg = Release|Win32
|
||||
{C005E3B9-2474-4FEA-B5F4-7BB897111E8F}.Release|x86.Build.0 = Release|Win32
|
||||
{E236CE39-D8F3-4DB6-985C-F2794FF17746}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E236CE39-D8F3-4DB6-985C-F2794FF17746}.Debug|x64.Build.0 = Debug|x64
|
||||
{E236CE39-D8F3-4DB6-985C-F2794FF17746}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{E236CE39-D8F3-4DB6-985C-F2794FF17746}.Debug|x86.Build.0 = Debug|Win32
|
||||
{E236CE39-D8F3-4DB6-985C-F2794FF17746}.Release|x64.ActiveCfg = Release|x64
|
||||
{E236CE39-D8F3-4DB6-985C-F2794FF17746}.Release|x64.Build.0 = Release|x64
|
||||
{E236CE39-D8F3-4DB6-985C-F2794FF17746}.Release|x86.ActiveCfg = Release|Win32
|
||||
{E236CE39-D8F3-4DB6-985C-F2794FF17746}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {246FEDB8-B2A1-4051-85E1-F39A6026767B}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
using namespace System;
|
||||
using namespace System::Reflection;
|
||||
using namespace System::Runtime::CompilerServices;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
using namespace System::Security::Permissions;
|
||||
|
||||
//
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
//
|
||||
[assembly:AssemblyTitleAttribute(L"YaraSharp")];
|
||||
[assembly:AssemblyDescriptionAttribute(L"")];
|
||||
[assembly:AssemblyConfigurationAttribute(L"")];
|
||||
[assembly:AssemblyCompanyAttribute(L"")];
|
||||
[assembly:AssemblyProductAttribute(L"YaraSharp")];
|
||||
[assembly:AssemblyCopyrightAttribute(L"Copyright (c) 2018")];
|
||||
[assembly:AssemblyTrademarkAttribute(L"")];
|
||||
[assembly:AssemblyCultureAttribute(L"")];
|
||||
|
||||
//
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the value or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly:AssemblyVersionAttribute("1.0.*")];
|
||||
|
||||
[assembly:ComVisible(false)];
|
||||
|
||||
[assembly:CLSCompliantAttribute(true)];
|
||||
@@ -0,0 +1,100 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// CCompiler
|
||||
namespace YaraSharp
|
||||
{
|
||||
// Êîíñòðóêòîð
|
||||
CCompiler::CCompiler(Dictionary<String^, Object^>^ ExternalVariables)
|
||||
{
|
||||
YR_COMPILER* TestCompiler;
|
||||
ErrorUtility::ThrowOnError(yr_compiler_create(&TestCompiler));
|
||||
Compiler = TestCompiler;
|
||||
|
||||
Errors = gcnew List<String^>();
|
||||
|
||||
CompilerCallback = gcnew YaraCompilerCallback(this, &CCompiler::HandleCompilerCallback);
|
||||
auto funcPtr = Marshal::GetFunctionPointerForDelegate(CompilerCallback).ToPointer();
|
||||
yr_compiler_set_callback(Compiler, static_cast<YR_COMPILER_CALLBACK_FUNC>(funcPtr), nullptr);
|
||||
|
||||
SetCompilerExternals(ExternalVariables);
|
||||
}
|
||||
// Äåñòðóêòîð
|
||||
CCompiler::~CCompiler() { if (Compiler) yr_compiler_destroy(Compiler); }
|
||||
|
||||
// Äîáàâëåíèå ïðàâèë â êîëëåêöèþ èç ôàéëà
|
||||
int CCompiler::AddFile(String^ FilePath)
|
||||
{
|
||||
FILE* File;
|
||||
Errors->Clear();
|
||||
auto NativePath = marshal_as<std::string>(FilePath);
|
||||
|
||||
auto FileOpenError = fopen_s(&File, NativePath.c_str(), "r");
|
||||
|
||||
if (FileOpenError)
|
||||
ErrorUtility::ThrowOnError(String::Format("Îøèáêà îòêðûòèÿ ôàéëà: {0}", FileOpenError));
|
||||
|
||||
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);
|
||||
}
|
||||
// Óñòàíîâêà externals
|
||||
void CCompiler::SetCompilerExternals(Dictionary<String^, Object^>^ ExternalVariables)
|
||||
{
|
||||
if (ExternalVariables)
|
||||
{
|
||||
marshal_context CTX;
|
||||
|
||||
for each (auto ExternalVariable in ExternalVariables)
|
||||
{
|
||||
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);
|
||||
else if (VariableType == Double::typeid)
|
||||
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);
|
||||
else if (VariableType == String::typeid)
|
||||
ExternalError = yr_compiler_define_string_variable(Compiler, VariablePointer, CTX.marshal_as<const char*>((String^)ExternalVariable.Value));
|
||||
else
|
||||
throw gcnew NotSupportedException(String::Format("Íåïîääåðæèâàåìûé òèï external variable: '{0}'", VariableType->Name));
|
||||
|
||||
if (ExternalError != ERROR_SUCCESS)
|
||||
ErrorUtility::ThrowOnError("(Compiler) Íå óäàëîñü èíèöèàëèçèðîâàòü external variable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Îáðàáîòêà îòâåòà
|
||||
void CCompiler::HandleCompilerCallback(int ErrorLevel, const char* Filename, int LineNumber, const char* Message, void* UserData)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ErrorLevel);
|
||||
UNREFERENCED_PARAMETER(UserData);
|
||||
|
||||
auto msg = String::Format("{0} â ñòðîêå {1} â ôàéëå: {2}",
|
||||
marshal_as<String^>(Message), LineNumber,
|
||||
Filename ? marshal_as<String^>(Filename) : "[none]");
|
||||
|
||||
Errors->Add(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention::Cdecl)]
|
||||
delegate void YaraCompilerCallback(int ErrorLevel, const char* Filename, int LineNumber, const char* Message, void* UserData);
|
||||
|
||||
public ref class CCompiler sealed
|
||||
{
|
||||
public:
|
||||
initonly YR_COMPILER* Compiler;
|
||||
initonly List<String^>^ Errors;
|
||||
YaraCompilerCallback ^ CompilerCallback;
|
||||
|
||||
CCompiler(Dictionary<String^, Object^>^ ExternalVariables);
|
||||
~CCompiler();
|
||||
|
||||
CRules^ GetRules();
|
||||
int AddFile(String^ FilePath);
|
||||
void AddFiles(List<String^>^ FilePathList);
|
||||
|
||||
private:
|
||||
void SetCompilerExternals(Dictionary<String^, Object^>^ ExternalVariables);
|
||||
void HandleCompilerCallback(int ErrorLevel, const char* Filename, int LineNumber, const char* Message, void* UserData);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// CContext
|
||||
namespace YaraSharp
|
||||
{
|
||||
// Êîíñòðóêòîð
|
||||
CContext::CContext() { ErrorUtility::ThrowOnError(yr_initialize()); }
|
||||
// Äåñòðóêòîð
|
||||
CContext::~CContext() { ErrorUtility::ThrowOnError(yr_finalize()); }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
public ref class CContext sealed
|
||||
{
|
||||
public:
|
||||
CContext();
|
||||
~CContext();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// ErrorUtility
|
||||
namespace YaraSharp
|
||||
{
|
||||
void ErrorUtility::ThrowOnError(int error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case ERROR_SUCCESS:
|
||||
return;
|
||||
|
||||
case ERROR_INSUFICIENT_MEMORY:
|
||||
throw gcnew OutOfMemoryException();
|
||||
|
||||
default:
|
||||
throw gcnew Exception(String::Format("Yara error: {0}. Code {1}", NiceErrorCode(error), error));
|
||||
}
|
||||
}
|
||||
void ErrorUtility::ThrowOnError(String^ error)
|
||||
{
|
||||
throw gcnew Exception(String::Format("Error: {0}", error));
|
||||
}
|
||||
|
||||
String^ ErrorUtility::NiceErrorCode(int error)
|
||||
{
|
||||
// TODO: ñäåëàòü íîðìàëüíîå îïèñàíèó
|
||||
switch (error)
|
||||
{
|
||||
case ERROR_INSUFICIENT_MEMORY:
|
||||
return "ERROR_INSUFICIENT_MEMORY";
|
||||
case ERROR_COULD_NOT_ATTACH_TO_PROCESS:
|
||||
return "COULD_NOT_ATTACH_TO_PROCESS";
|
||||
case ERROR_COULD_NOT_OPEN_FILE:
|
||||
return "ERROR_COULD_NOT_OPEN_FILE";
|
||||
case ERROR_COULD_NOT_MAP_FILE:
|
||||
return "ERROR_COULD_NOT_MAP_FILE";
|
||||
case ERROR_INVALID_FILE:
|
||||
return "ERROR_INVALID_FILE";
|
||||
case ERROR_CORRUPT_FILE:
|
||||
return "ERROR_CORRUPT_FILE";
|
||||
case ERROR_UNSUPPORTED_FILE_VERSION:
|
||||
return "ERROR_UNSUPPORTED_FILE_VERSION";
|
||||
case ERROR_INVALID_REGULAR_EXPRESSION:
|
||||
return "ERROR_INVALID_REGULAR_EXPRESSION";
|
||||
case ERROR_INVALID_HEX_STRING:
|
||||
return "ERROR_INVALID_HEX_STRING";
|
||||
case ERROR_SYNTAX_ERROR:
|
||||
return "ERROR_SYNTAX_ERROR";
|
||||
case ERROR_LOOP_NESTING_LIMIT_EXCEEDED:
|
||||
return "ERROR_LOOP_NESTING_LIMIT_EXCEEDED";
|
||||
case ERROR_DUPLICATED_LOOP_IDENTIFIER:
|
||||
return "ERROR_DUPLICATED_LOOP_IDENTIFIER";
|
||||
case ERROR_DUPLICATED_IDENTIFIER:
|
||||
return "ERROR_DUPLICATED_IDENTIFIER";
|
||||
case ERROR_DUPLICATED_TAG_IDENTIFIER:
|
||||
return "ERROR_DUPLICATED_TAG_IDENTIFIER";
|
||||
case ERROR_DUPLICATED_META_IDENTIFIER:
|
||||
return "ERROR_DUPLICATED_META_IDENTIFIER";
|
||||
case ERROR_DUPLICATED_STRING_IDENTIFIER:
|
||||
return "ERROR_DUPLICATED_STRING_IDENTIFIER";
|
||||
case ERROR_UNREFERENCED_STRING:
|
||||
return "ERROR_UNREFERENCED_STRING";
|
||||
case ERROR_UNDEFINED_STRING:
|
||||
return "ERROR_UNDEFINED_STRING";
|
||||
case ERROR_UNDEFINED_IDENTIFIER:
|
||||
return "ERROR_UNDEFINED_IDENTIFIER";
|
||||
case ERROR_MISPLACED_ANONYMOUS_STRING:
|
||||
return "ERROR_MISPLACED_ANONYMOUS_STRING";
|
||||
case ERROR_INCLUDES_CIRCULAR_REFERENCE:
|
||||
return "ERROR_INCLUDES_CIRCULAR_REFERENCE";
|
||||
case ERROR_INCLUDE_DEPTH_EXCEEDED:
|
||||
return "ERROR_INCLUDE_DEPTH_EXCEEDED";
|
||||
case ERROR_WRONG_TYPE:
|
||||
return "ERROR_WRONG_TYPE";
|
||||
case ERROR_EXEC_STACK_OVERFLOW:
|
||||
return "ERROR_EXEC_STACK_OVERFLOW";
|
||||
case ERROR_SCAN_TIMEOUT:
|
||||
return "ERROR_SCAN_TIMEOUT";
|
||||
case ERROR_TOO_MANY_SCAN_THREADS:
|
||||
return "ERROR_TOO_MANY_SCAN_THREADS";
|
||||
case ERROR_CALLBACK_ERROR:
|
||||
return "ERROR_CALLBACK_ERROR";
|
||||
case ERROR_INVALID_ARGUMENT:
|
||||
return "ERROR_INVALID_ARGUMENT";
|
||||
case ERROR_TOO_MANY_MATCHES:
|
||||
return "ERROR_TOO_MANY_MATCHES";
|
||||
case ERROR_INTERNAL_FATAL_ERROR:
|
||||
return "ERROR_INTERNAL_FATAL_ERROR";
|
||||
case ERROR_NESTED_FOR_OF_LOOP:
|
||||
return "ERROR_NESTED_FOR_OF_LOOP";
|
||||
case ERROR_INVALID_FIELD_NAME:
|
||||
return "ERROR_INVALID_FIELD_NAME";
|
||||
case ERROR_UNKNOWN_MODULE:
|
||||
return "ERROR_UNKNOWN_MODULE";
|
||||
case ERROR_NOT_A_STRUCTURE:
|
||||
return "ERROR_NOT_A_STRUCTURE";
|
||||
case ERROR_NOT_INDEXABLE:
|
||||
return "ERROR_NOT_INDEXABLE";
|
||||
case ERROR_NOT_A_FUNCTION:
|
||||
return "ERROR_NOT_A_FUNCTION";
|
||||
case ERROR_INVALID_FORMAT:
|
||||
return "ERROR_INVALID_FORMAT";
|
||||
case ERROR_TOO_MANY_ARGUMENTS:
|
||||
return "ERROR_TOO_MANY_ARGUMENTS";
|
||||
case ERROR_WRONG_ARGUMENTS:
|
||||
return "ERROR_WRONG_ARGUMENTS";
|
||||
case ERROR_WRONG_RETURN_TYPE:
|
||||
return "ERROR_WRONG_RETURN_TYPE";
|
||||
case ERROR_DUPLICATED_STRUCTURE_MEMBER:
|
||||
return "ERROR_DUPLICATED_STRUCTURE_MEMBER";
|
||||
case ERROR_EMPTY_STRING:
|
||||
return "ERROR_EMPTY_STRING";
|
||||
case ERROR_DIVISION_BY_ZERO:
|
||||
return "ERROR_DIVISION_BY_ZERO";
|
||||
case ERROR_REGULAR_EXPRESSION_TOO_LARGE:
|
||||
return "ERROR_REGULAR_EXPRESSION_TOO_LARGE";
|
||||
case ERROR_TOO_MANY_RE_FIBERS:
|
||||
return "ERROR_TOO_MANY_RE_FIBERS";
|
||||
case ERROR_COULD_NOT_READ_PROCESS_MEMORY:
|
||||
return "ERROR_COULD_NOT_READ_PROCESS_MEMORY";
|
||||
case ERROR_INVALID_EXTERNAL_VARIABLE_TYPE:
|
||||
return "ERROR_INVALID_EXTERNAL_VARIABLE_TYPE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
public ref class ErrorUtility abstract sealed
|
||||
{
|
||||
private:
|
||||
static String^ NiceErrorCode(int error);
|
||||
|
||||
public:
|
||||
static void ThrowOnError(int error);
|
||||
static void ThrowOnError(String^ error);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
#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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#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);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// CRules
|
||||
namespace YaraSharp
|
||||
{
|
||||
CRules::operator YR_RULES*() { return Rules; }
|
||||
CRules::CRules(YR_RULES* rules) : Rules(rules) { }
|
||||
CRules::~CRules() { if (Rules) yr_rules_destroy(Rules); }
|
||||
}
|
||||
// CRule
|
||||
namespace YaraSharp
|
||||
{
|
||||
CRule::CRule()
|
||||
{
|
||||
Namespace = nullptr;
|
||||
Identifier = nullptr;
|
||||
Tags = gcnew List<String^>();
|
||||
// Strings = gcnew List<String^>();
|
||||
Meta = gcnew Dictionary<String^, Object^>();
|
||||
}
|
||||
CRule::CRule(YR_RULE* Rule)
|
||||
{
|
||||
Namespace = nullptr;
|
||||
Tags = CRule::GetRuleTags(Rule);
|
||||
Meta = CRule::GetRuleMeta(Rule);
|
||||
// Strings = CRule::GetRuleStrings(Rule);
|
||||
Identifier = gcnew String(Rule->identifier);
|
||||
}
|
||||
|
||||
List<String^>^ CRule::GetRuleTags(YR_RULE* Rule)
|
||||
{
|
||||
List<String^>^ Result = gcnew List<String^>();
|
||||
|
||||
const char* TagEntry;
|
||||
yr_rule_tags_foreach(Rule, TagEntry)
|
||||
Result->Add(gcnew String(TagEntry));
|
||||
|
||||
return Result;
|
||||
}
|
||||
List<String^>^ CRule::GetRuleStrings(YR_RULE* Rule)
|
||||
{
|
||||
List<String^>^ Result = gcnew List<String^>();
|
||||
|
||||
YR_STRING* StringEntry;
|
||||
yr_rule_strings_foreach(Rule, StringEntry)
|
||||
Result->Add(gcnew String(StringEntry->identifier));
|
||||
|
||||
return Result;
|
||||
}
|
||||
Dictionary<String^, Object^>^ CRule::GetRuleMeta(YR_RULE* Rule)
|
||||
{
|
||||
Dictionary<String^, Object^>^ Result = gcnew Dictionary<String^, Object^>();
|
||||
|
||||
YR_META* MetaEntry;
|
||||
yr_rule_metas_foreach(Rule, MetaEntry)
|
||||
{
|
||||
if (MetaEntry->identifier == NULL)
|
||||
throw gcnew NullReferenceException("(Meta) Çíà÷åíèå íå ìîæåò áûòü ïóñòûì");
|
||||
|
||||
String^ MetaID = gcnew String(MetaEntry->identifier);
|
||||
Object^ MetaValue = nullptr;
|
||||
|
||||
switch (MetaEntry->type)
|
||||
{
|
||||
case META_TYPE_BOOLEAN:
|
||||
MetaValue = (bool)(MetaEntry->integer == 1);
|
||||
break;
|
||||
case META_TYPE_INTEGER:
|
||||
MetaValue = (Int32)MetaEntry->integer;
|
||||
break;
|
||||
case META_TYPE_STRING:
|
||||
MetaValue = gcnew String(MetaEntry->string);
|
||||
break;
|
||||
}
|
||||
|
||||
// Îòñåèâàåì äóáëèêàòû
|
||||
if (!Result->ContainsKey(MetaID))
|
||||
Result->Add(MetaID, MetaValue);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
public ref class CRules sealed
|
||||
{
|
||||
YR_RULES* Rules;
|
||||
|
||||
public:
|
||||
CRules(YR_RULES* rules);
|
||||
operator YR_RULES*();
|
||||
~CRules();
|
||||
};
|
||||
|
||||
|
||||
public ref class CRule sealed
|
||||
{
|
||||
public:
|
||||
property String^ Namespace;
|
||||
property String^ Identifier;
|
||||
property List<String^>^ Tags;
|
||||
property Dictionary<String^, Object^>^ Meta;
|
||||
// property List<String^>^ Strings;
|
||||
// Íåñêîëüêî áåñïîëåçíî, ïîñêîëüêó â Match óæå èìååòñÿ êëþ÷,
|
||||
// ñîîòâåòâóþùèé íàéäåííîìó ñîâïàäåíèþ
|
||||
|
||||
CRule();
|
||||
CRule(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);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// CScanner
|
||||
namespace YaraSharp
|
||||
{
|
||||
// Êîíñòðóêòîð
|
||||
CScanner::CScanner(CRules^ rules, Dictionary<String^, Object^>^ ExternalVariables)
|
||||
{
|
||||
YR_SCANNER* TestScanner;
|
||||
ErrorUtility::ThrowOnError(yr_scanner_create((YR_RULES*)rules, &TestScanner));
|
||||
Scanner = TestScanner;
|
||||
|
||||
ScanCallback = gcnew YaraScanCallback(this, &CScanner::HandleScannerCallback);
|
||||
auto funcPtr = Marshal::GetFunctionPointerForDelegate(ScanCallback).ToPointer();
|
||||
yr_scanner_set_callback(Scanner, static_cast<YR_CALLBACK_FUNC>(funcPtr), nullptr);
|
||||
|
||||
SetScannerExternals(ExternalVariables);
|
||||
}
|
||||
// Äåñòðóêòîð
|
||||
CScanner::~CScanner() { if (Scanner) yr_scanner_destroy(Scanner); }
|
||||
|
||||
// Óñòàíîâêà externals
|
||||
void CScanner::SetScannerExternals(Dictionary<String^, Object^>^ ExternalVariables)
|
||||
{
|
||||
if (ExternalVariables)
|
||||
{
|
||||
marshal_context CTX;
|
||||
|
||||
for each (auto ExternalVariable in ExternalVariables)
|
||||
{
|
||||
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);
|
||||
else if (VariableType == Double::typeid)
|
||||
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);
|
||||
else if (VariableType == String::typeid)
|
||||
ExternalError = yr_scanner_define_string_variable(Scanner, VariablePointer, CTX.marshal_as<const char*>((String^)ExternalVariable.Value));
|
||||
else
|
||||
throw gcnew NotSupportedException(String::Format("Íåïîääåðæèâàåìûé òèï external variable: '{0}'", VariableType->Name));
|
||||
|
||||
if (ExternalError != ERROR_SUCCESS)
|
||||
ErrorUtility::ThrowOnError("(Scanner) Íå óäàëîñü èíèöèàëèçèðîâàòü external variable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Îáðàáîòêà îòâåòà
|
||||
int CScanner::HandleScannerCallback(int message, void* data, void* context)
|
||||
{
|
||||
if (message == CALLBACK_MSG_RULE_MATCHING)
|
||||
{
|
||||
auto resultsHandle = GCHandle::FromIntPtr(IntPtr(context));
|
||||
auto results = (List<CMatches^>^)resultsHandle.Target;
|
||||
|
||||
results->Add(gcnew CMatches((YR_RULE*)data));
|
||||
}
|
||||
|
||||
return CALLBACK_CONTINUE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention::Cdecl)]
|
||||
delegate int YaraScanCallback(int Message, void* Data, void* Context);
|
||||
|
||||
public ref class CScanner sealed
|
||||
{
|
||||
public:
|
||||
YR_SCANNER * Scanner;
|
||||
YaraScanCallback^ ScanCallback;
|
||||
|
||||
CScanner(CRules^ rules, Dictionary<String^, Object^>^ ExternalVariables);
|
||||
~CScanner();
|
||||
|
||||
private:
|
||||
void SetScannerExternals(Dictionary<String^, Object^>^ ExternalVariables);
|
||||
int HandleScannerCallback(int Message, void* Data, void* Context);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// YaraSharp.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
@@ -0,0 +1,24 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently,
|
||||
// but are changed infrequently
|
||||
|
||||
#pragma once
|
||||
#include <msclr\marshal.h>
|
||||
#include <msclr\marshal_cppstd.h>
|
||||
#include <msclr\lock.h>
|
||||
|
||||
using namespace System;
|
||||
using namespace System::IO;
|
||||
using namespace System::Text;
|
||||
using namespace msclr::interop;
|
||||
using namespace System::Collections::Generic;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
|
||||
#include "yara.h"
|
||||
#include "Exceptions.h"
|
||||
#include "Context.h"
|
||||
#include "Rules.h"
|
||||
#include "Compiler.h"
|
||||
#include "Result.h"
|
||||
#include "Scanner.h"
|
||||
#include "YaraSharp.h"
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
public ref class YaraExternal
|
||||
{
|
||||
public:
|
||||
YaraExternal();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
// CMatches
|
||||
namespace YaraSharp
|
||||
{
|
||||
// Ïðîâåðêà ïðàâèë
|
||||
Dictionary<String^, List<String^>^>^ CYaraSharp::CheckYaraRules([Out] List<String^>^ FilePathList, Dictionary<String^, Object^>^ ExternalVariables)
|
||||
{
|
||||
Dictionary<String^, List<String^>^>^ CompilationErrors =
|
||||
gcnew Dictionary<String^, List<String^>^>();
|
||||
|
||||
// Ïîñëåäîâàòåëüíàÿ ïðîâåðêà
|
||||
for (int i = 0; i < FilePathList->Count; i++)
|
||||
{
|
||||
CCompiler^ TestCompiler = gcnew CCompiler(ExternalVariables);
|
||||
|
||||
if (TestCompiler->AddFile(FilePathList[i]))
|
||||
{
|
||||
CompilationErrors->Add(FilePathList[i], TestCompiler->Errors);
|
||||
FilePathList->Remove(FilePathList[i--]);
|
||||
}
|
||||
}
|
||||
|
||||
// Îäíîâðåìåííàÿ ïðîâåðêà
|
||||
bool SuccessFlag = false;
|
||||
while (!SuccessFlag)
|
||||
{
|
||||
SuccessFlag = true;
|
||||
CCompiler^ TestCompiler = gcnew CCompiler(ExternalVariables);
|
||||
for each (auto FilePath in FilePathList)
|
||||
{
|
||||
if (TestCompiler->AddFile(FilePath))
|
||||
{
|
||||
CompilationErrors->Add(FilePath, TestCompiler->Errors);
|
||||
FilePathList->Remove(FilePath);
|
||||
SuccessFlag = false;
|
||||
|
||||
//  ñëó÷àå îøèáêè íåîáõîäèìî ñîçäàâàòü íîâûé êîìïèëÿòîð
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CompilationErrors;
|
||||
}
|
||||
// Êîìïèëÿöèÿ ïðàâèë
|
||||
CRules^ CYaraSharp::CompileFromFiles(CCompiler^ Compiler, List<String^>^ FilePathList, Dictionary<String^, Object^>^ ExternalVariables,
|
||||
[Out] Dictionary<String^, List<String^>^>^% CompilationErrors)
|
||||
{
|
||||
// TODO: äîáàâèòü ïîääåðæêó namespace
|
||||
|
||||
// Ïðîâåðêà ïðàâèë íà êîððåêòíîñòü
|
||||
CompilationErrors = CheckYaraRules(FilePathList, ExternalVariables);
|
||||
|
||||
// Êîìïèëÿöèÿ ïðàâèë
|
||||
Compiler->AddFiles(FilePathList);
|
||||
|
||||
// Âîçâðàùàåì ñêîìïèëèðîâàííûå ïðàâèëà
|
||||
return Compiler->GetRules();
|
||||
}
|
||||
|
||||
// Ñêàíèðîâàíèå ôàéëà
|
||||
List<CMatches^>^ CYaraSharp::ScanFile(String^ Path, CRules^ Rules, Dictionary<String^, Object^>^ ExternalVariables, int Timeout)
|
||||
{
|
||||
CScanner^ FScanner = gcnew CScanner(Rules, ExternalVariables);
|
||||
|
||||
if (!File::Exists(Path))
|
||||
throw gcnew FileNotFoundException(Path);
|
||||
|
||||
auto results = gcnew List<CMatches^>();
|
||||
auto nativePath = marshal_as<std::string>(Path);
|
||||
GCHandle resultsHandle = GCHandle::Alloc(results);
|
||||
|
||||
ErrorUtility::ThrowOnError(
|
||||
yr_rules_scan_file(Rules, nativePath.c_str(), 0, FScanner->Scanner->callback,
|
||||
GCHandle::ToIntPtr(resultsHandle).ToPointer(), Timeout));
|
||||
|
||||
return results;
|
||||
}
|
||||
// Ñêàíèðîâàíèå ïðîöåññà
|
||||
List<CMatches^>^ CYaraSharp::ScanProcess(int PID, CRules^ Rules, int Timeout, Dictionary<String^, Object^>^ ExternalVariables)
|
||||
{
|
||||
CScanner^ PScanner = gcnew CScanner(Rules, ExternalVariables);
|
||||
|
||||
auto results = gcnew List<CMatches^>();
|
||||
GCHandle resultsHandle = GCHandle::Alloc(results);
|
||||
|
||||
ErrorUtility::ThrowOnError(
|
||||
yr_rules_scan_proc(Rules, PID, 0, PScanner->Scanner->callback,
|
||||
GCHandle::ToIntPtr(resultsHandle).ToPointer(), Timeout));
|
||||
|
||||
return results;
|
||||
}
|
||||
// Ñêàíèðîâàíèå ïàìÿòè
|
||||
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);
|
||||
}
|
||||
}
|
||||
// Ñêàíèðîâàíèå ïàìÿòè
|
||||
List<CMatches^>^ CYaraSharp::ScanMemory(uint8_t* Buffer, int Length, CRules^ Rules, Dictionary<String^, Object^>^ ExternalVariables, int Timeout)
|
||||
{
|
||||
CScanner^ MScanner = gcnew CScanner(Rules, ExternalVariables);
|
||||
|
||||
auto results = gcnew List<CMatches^>();
|
||||
GCHandle resultsHandle = GCHandle::Alloc(results);
|
||||
|
||||
ErrorUtility::ThrowOnError(
|
||||
yr_rules_scan_mem(Rules, Buffer, Length, 0, MScanner->Scanner->callback,
|
||||
GCHandle::ToIntPtr(resultsHandle).ToPointer(), Timeout));
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
namespace YaraSharp
|
||||
{
|
||||
public ref class CYaraSharp
|
||||
{
|
||||
private:
|
||||
// Ïðîâåðêà ôàéëîâ
|
||||
Dictionary<String^, List<String^>^>^ CheckYaraRules(List<String^>^ FilePathList, Dictionary<String^, Object^>^ ExternalVariables);
|
||||
|
||||
public:
|
||||
// Êîìïèëÿöèÿ ïðàâèë
|
||||
CRules^ CompileFromFiles(CCompiler^ Compiler,
|
||||
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, int Timeout, Dictionary<String^, Object^>^ ExternalVariables);
|
||||
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);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C005E3B9-2474-4FEA-B5F4-7BB897111E8F}</ProjectGuid>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<Keyword>ManagedCProj</Keyword>
|
||||
<RootNamespace>YaraNET</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)Build\$(Configuration)\x86\</OutDir>
|
||||
<IntDir>$(MSBuildProjectDirectory)\Configuration\x86\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)Build\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(MSBuildProjectDirectory)\Configuration\$(Platform)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)Build\$(Configuration)\x86\</OutDir>
|
||||
<IntDir>$(MSBuildProjectDirectory)\Configuration\x86\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)Build\$(Configuration)\$(Platform)\</OutDir>
|
||||
<IntDir>$(MSBuildProjectDirectory)\Configuration\$(Platform)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)yara-master\libyara\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)yara-master\windows\vs2015\libyara\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>libyara32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(SolutionDir)Build\$(Configuration)\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)yara-master\libyara\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<OutputFile>$(SolutionDir)Build\$(Configuration)\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)yara-master\windows\vs2015\libyara\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)yara-master\libyara\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<OutputFile>$(SolutionDir)Build\$(Configuration)\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)yara-master\windows\vs2015\libyara\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>libyara32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)yara-master\libyara\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<OutputFile>$(SolutionDir)Build\$(Configuration)\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)yara-master\windows\vs2015\libyara\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Compiler.h" />
|
||||
<ClInclude Include="Context.h" />
|
||||
<ClInclude Include="YaraSharp.h" />
|
||||
<ClInclude Include="Exceptions.h" />
|
||||
<ClInclude Include="Rules.h" />
|
||||
<ClInclude Include="Scanner.h" />
|
||||
<ClInclude Include="Result.h" />
|
||||
<ClInclude Include="Stdafx.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AssemblyInfo.cpp" />
|
||||
<ClCompile Include="Compiler.cpp" />
|
||||
<ClCompile Include="Context.cpp" />
|
||||
<ClCompile Include="Exceptions.cpp" />
|
||||
<ClCompile Include="Result.cpp" />
|
||||
<ClCompile Include="Rules.cpp" />
|
||||
<ClCompile Include="Scanner.cpp" />
|
||||
<ClCompile Include="Stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="YaraSharp.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Compiler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Exceptions.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Rules.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AssemblyInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<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>
|
||||
<ClCompile Include="Compiler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<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>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="YARA.Jansson.x64" version="1.1.0" targetFramework="native" />
|
||||
<package id="YARA.Jansson.x86" version="1.1.0" targetFramework="native" />
|
||||
<package id="YARA.OpenSSL.x64" version="1.1.0" targetFramework="native" />
|
||||
<package id="YARA.OpenSSL.x86" version="1.1.0" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -0,0 +1,84 @@
|
||||
# Generic auto-generated build files
|
||||
*~
|
||||
*.a
|
||||
*.la
|
||||
*.lai
|
||||
*.lo
|
||||
*.Plo
|
||||
*.Po
|
||||
*.o
|
||||
*.so
|
||||
*.so.[0-9][0-9]*
|
||||
*.so.[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*
|
||||
*.Tpo
|
||||
*.m4
|
||||
*.dSYM
|
||||
.deps
|
||||
.libs
|
||||
INSTALL
|
||||
Makefile
|
||||
Makefile.in
|
||||
stamp-h1
|
||||
|
||||
# Specific auto-generated build files
|
||||
/ABOUT-NLS
|
||||
/aclocal.m4
|
||||
/ar-lib
|
||||
/autom4te.cache/
|
||||
/build-aux
|
||||
/compile
|
||||
/config.guess
|
||||
/config.h
|
||||
/config.h.in
|
||||
/config.log
|
||||
/config.rpath
|
||||
/config.status
|
||||
/config.sub
|
||||
/configure
|
||||
/depcomp
|
||||
/install-sh
|
||||
/libtool
|
||||
/ltmain.sh
|
||||
/missing
|
||||
/test-driver
|
||||
/ylwrap
|
||||
/m4
|
||||
!/m4/acx_pthread.m4
|
||||
|
||||
# Project specific files
|
||||
/yara
|
||||
/yarac
|
||||
/libyara/modules/.dirstamp
|
||||
|
||||
# Linux and Mac files
|
||||
*.swp
|
||||
.DS_Store
|
||||
|
||||
# Files generated by tests
|
||||
test-alignment
|
||||
test-alignment.log
|
||||
test-alignment.trs
|
||||
test-rules
|
||||
test-rules.log
|
||||
test-rules.trs
|
||||
test-suite.log
|
||||
test-pe
|
||||
test-pe.log
|
||||
test-pe.trs
|
||||
test-macho
|
||||
test-macho.log
|
||||
test-macho.trs
|
||||
|
||||
# Visual Studio files
|
||||
Release/
|
||||
Debug/
|
||||
x64/
|
||||
*.obj
|
||||
*.suo
|
||||
*.sdf
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.VC.db
|
||||
|
||||
# NuGet
|
||||
windows/*/packages/
|
||||
@@ -0,0 +1,80 @@
|
||||
language: c
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
env: CONFIGFLAGS="CFLAGS=-m64 --enable-cuckoo --enable-magic"
|
||||
# The certificate for scan.coverity.com is too new and is not recognized by
|
||||
# wget. This command adds the certificate to /etc/ssl/certs/ca-certificates.crt
|
||||
# See: https://github.com/travis-ci/travis-ci/issues/6142
|
||||
before_install: echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-certificates.crt
|
||||
install: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y autoconf automake libtool libjansson-dev libmagic-dev libssl-dev
|
||||
- os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
env: CONFIGFLAGS="CFLAGS=-m32 --enable-cuckoo --enable-magic"
|
||||
install: |
|
||||
sudo dpkg --add-architecture i386 && sudo rm -rf /etc/apt/sources.list.d/
|
||||
sudo apt-get update
|
||||
sudo apt-get remove postgresql-9.3
|
||||
sudo apt-get upgrade -y gcc
|
||||
sudo apt-get install -y gcc-multilib autoconf automake libtool libjansson-dev:i386 libmagic-dev:i386 libssl-dev:i386
|
||||
- os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
env: CONFIGFLAGS=--host=x86_64-w64-mingw32
|
||||
install: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y gcc-mingw-w64 autoconf automake libtool
|
||||
- os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
env: CONFIGFLAGS=--host=i686-w64-mingw32
|
||||
install: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y gcc-mingw-w64 autoconf automake libtool
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
- os: osx
|
||||
osx_image: xcode8.3
|
||||
- os: osx
|
||||
osx_image: xcode9.2
|
||||
|
||||
before_script: ./bootstrap.sh
|
||||
|
||||
script: |
|
||||
rvm get head # Workaround for Travis CI issue https://github.com/travis-ci/travis-ci/issues/6307
|
||||
set -e
|
||||
unset CC # A pre-set CC overrides --host settings.
|
||||
./configure $CONFIGFLAGS
|
||||
make clean && make
|
||||
case "$CONFIGFLAGS" in
|
||||
*--host=*mingw*) ;;
|
||||
*) make check ;;
|
||||
esac
|
||||
set +e
|
||||
|
||||
after_failure: if [ -e test-suite.log ]; then cat test-suite.log; fi
|
||||
|
||||
env:
|
||||
global:
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
- secure: "JWobvJ94pWt/xVciQURkNFS3I+gyu2IyZPKYEs6HDlHrpHs4BoVDZeRjmgx0s6aDeQjKJHowGDu17IlbnCkKzXrZErEJkA+Oc/d0SwgXKiUU9WYiaGBJjJUoYZw66QIEuGGKkF4uQ7EIcW/vN7wzrCDyAiPeOPUjVP4Tc2XRzmkSfakfmf9cE5nqT84DPUYiRegM7iepMrZi9kEaAoboBuETT+6eUKdERRadM0QNjZmCYMEMjtFj3lE51Ey2stGqZdKJvJN0FUmxGoaXCFFAsNmZPnFeDkqTf0a+MzxG2m4nnIXyNC/nT5XLItKHog4KROHb4tUpCZJ4iJhcw3loWMCtkZqB2fq2PaOkKk2zxPr3HLCn7ltmOzReBEDjEg68UqWydRW5534JGosbcA9IfshS1VqnZLgGwQHieXNeqhJUumt1DpON7AQEiEzbzAk0y2VcPlDPuCt9QS1k+zPMZLzbwgvs1ZOH39oFESW+iEDdzZjbhyC3J6azTHFcnA7r5SsYe1pzcSUaYtS1ehhb0lU/442JSHw2j00Nv9qFycYNvDrRNQNBxLziVustT0WJoVdFlkKy16iu1tUYOVXKgmMfqUDINfU6zRz3DskVuB9MZzq/4cMdK4jMRIDNZWvye1BzM7o/PiJoNaQc/6iav2RD+5YV46bBr60TqnYyjlM="
|
||||
|
||||
# Disable Coverity due to a problem with their certificate that makes it fail
|
||||
# in Travis-CI.
|
||||
#
|
||||
#addons:
|
||||
# coverity_scan:
|
||||
# project:
|
||||
# name: "plusvic/yara"
|
||||
# description: "Build submitted via Travis CI"
|
||||
# notification_email: plusvic@gmail.com
|
||||
# build_command_prepend: "./configure; make clean"
|
||||
# build_command: "make -j 4"
|
||||
# branch_pattern: master
|
||||
@@ -0,0 +1,16 @@
|
||||
# This is the official list of YARA authors for copyright purposes.
|
||||
# This file is distinct from the CONTRIBUTORS files.
|
||||
# See the latter for an explanation.
|
||||
|
||||
# Names should be added to this file as
|
||||
# Name or Organization <email address>
|
||||
# The email address is not required for organizations.
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
Google Inc.
|
||||
Hilko Bengen <bengen@hilluzination.de>
|
||||
Joachim Metz <joachim.metz@gmail.com>
|
||||
Stefan Buehlmann <stefan.buehlmann@joebox.org>
|
||||
Victor M. Alvarez <plusvic@gmail.com>;<vmalvarez@virustotal.com>
|
||||
Wesley Shields <wxs@atarininja.org>
|
||||
@@ -0,0 +1,38 @@
|
||||
# This is the official list of people who can contribute
|
||||
# (and typically have contributed) code to the YARA repository.
|
||||
# The AUTHORS file lists the copyright holders; this file
|
||||
# lists people. For example, Google employees are listed here
|
||||
# but not in AUTHORS, because Google holds the copyright.
|
||||
#
|
||||
# The submission process automatically checks to make sure
|
||||
# that people submitting code are listed in this file (by email address).
|
||||
#
|
||||
# Names should be added to this file only after verifying that
|
||||
# the individual or the individual's organization has agreed to
|
||||
# the appropriate Contributor License Agreement, found here:
|
||||
#
|
||||
# http://code.google.com/legal/individual-cla-v1.0.html
|
||||
# http://code.google.com/legal/corporate-cla-v1.0.html
|
||||
#
|
||||
# The agreement for individuals can be filled out on the web.
|
||||
#
|
||||
# When adding J Random Contributor's name to this file,
|
||||
# either J's name or J's organization's name should be
|
||||
# added to the AUTHORS file, depending on whether the
|
||||
# individual or corporate CLA was used.
|
||||
|
||||
# Names should be added to this file like so:
|
||||
# Name <email address>
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
Anthony Desnos <adesnos@google.com>
|
||||
Christian Blichmann <cblichmann@google.com>
|
||||
Hilko Bengen <bengen@hilluzination.de>
|
||||
Joachim Metz <joachim.metz@gmail.com>
|
||||
Karl Hiramoto <karl.hiramoto@virustotal.com>
|
||||
Mike Wiacek <mjwiacek@google.com>
|
||||
Shane Huntley <shuntley@google.com>
|
||||
Stefan Buehlmann <stefan.buehlmann@joebox.org>
|
||||
Victor M. Alvarez <plusvic@gmail.com>;<vmalvarez@virustotal.com>
|
||||
Wesley Shields <wxs@atarininja.org>
|
||||
@@ -0,0 +1,26 @@
|
||||
Copyright (c) 2007-2016. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,69 @@
|
||||
AM_CFLAGS=-std=gnu99 -Wall -I$(srcdir)/libyara/include
|
||||
|
||||
if DEBUG
|
||||
AM_CFLAGS+=-g
|
||||
endif
|
||||
|
||||
if OPTIMIZATION
|
||||
AM_CFLAGS+=-O3
|
||||
else
|
||||
AM_CFLAGS+=-O0
|
||||
endif
|
||||
|
||||
if ADDRESS_SANITIZER
|
||||
AM_CFLAGS+=-fsanitize=address
|
||||
endif
|
||||
|
||||
# Build the library in the hand subdirectory first.
|
||||
SUBDIRS = libyara
|
||||
DIST_SUBDIRS = libyara
|
||||
|
||||
ACLOCAL_AMFLAGS=-I m4
|
||||
|
||||
bin_PROGRAMS = yara yarac
|
||||
|
||||
yara_SOURCES = args.c args.h common.h threading.c threading.h yara.c
|
||||
yara_LDADD = libyara/.libs/libyara.a
|
||||
|
||||
yarac_SOURCES = args.c args.h common.h yarac.c
|
||||
yarac_LDADD = libyara/.libs/libyara.a
|
||||
|
||||
TESTS = $(check_PROGRAMS)
|
||||
check_PROGRAMS = test-alignment test-api test-rules test-pe test-elf test-version
|
||||
|
||||
# The -fsanitize=address option makes test-exception fail. Include the test
|
||||
# only if the option is not enabled.
|
||||
|
||||
if !ADDRESS_SANITIZER
|
||||
check_PROGRAMS+=test-exception
|
||||
endif
|
||||
|
||||
test_alignment_SOURCES = tests/test-alignment.c
|
||||
test_rules_SOURCES = tests/test-rules.c tests/util.c
|
||||
test_rules_LDADD = libyara/.libs/libyara.a
|
||||
test_pe_SOURCES = tests/test-pe.c tests/util.c
|
||||
test_pe_LDADD = libyara/.libs/libyara.a
|
||||
test_elf_SOURCES = tests/test-elf.c tests/util.c
|
||||
test_elf_LDADD = libyara/.libs/libyara.a
|
||||
test_exception_SOURCES = tests/test-exception.c tests/util.c
|
||||
test_exception_LDADD = libyara/.libs/libyara.a
|
||||
test_version_SOURCES = tests/test-version.c
|
||||
test_api_LDADD = libyara/.libs/libyara.a
|
||||
test_api_SOURCES = tests/test-api.c tests/util.c
|
||||
|
||||
if MACHO_MODULE
|
||||
check_PROGRAMS+=test-macho
|
||||
test_macho_SOURCES = tests/test-macho.c tests/util.c
|
||||
test_macho_LDADD = libyara/.libs/libyara.a
|
||||
endif
|
||||
|
||||
if DEX_MODULE
|
||||
check_PROGRAMS+=test-dex
|
||||
test_dex_SOURCES = tests/test-dex.c tests/util.c
|
||||
test_dex_LDADD = libyara/.libs/libyara.a
|
||||
endif
|
||||
|
||||
# man pages
|
||||
man1_MANS = yara.man yarac.man
|
||||
|
||||
EXTRA_DIST = $(man1_MANS) README.md bootstrap.sh
|
||||
@@ -0,0 +1,111 @@
|
||||
[](https://gitter.im/VirusTotal/yara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://travis-ci.org/VirusTotal/yara)
|
||||
[](https://ci.appveyor.com/project/plusvic/yara)
|
||||
[](https://scan.coverity.com/projects/plusvic-yara)
|
||||
|
||||
|
||||
|
||||
## YARA in a nutshell
|
||||
|
||||
YARA is a tool aimed at (but not limited to) helping malware researchers to
|
||||
identify and classify malware samples. With YARA you can create descriptions of
|
||||
malware families (or whatever you want to describe) based on textual or binary
|
||||
patterns. Each description, a.k.a rule, consists of a set of strings and a
|
||||
boolean expression which determine its logic. Let's see an example:
|
||||
|
||||
```
|
||||
rule silent_banker : banker
|
||||
{
|
||||
meta:
|
||||
description = "This is just an example"
|
||||
threat_level = 3
|
||||
in_the_wild = true
|
||||
|
||||
strings:
|
||||
$a = {6A 40 68 00 30 00 00 6A 14 8D 91}
|
||||
$b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9}
|
||||
$c = "UVODFRYSIHLNWPEJXQZAKCBGMT"
|
||||
|
||||
condition:
|
||||
$a or $b or $c
|
||||
}
|
||||
```
|
||||
|
||||
The above rule is telling YARA that any file containing one of the three strings
|
||||
must be reported as *silent_banker*. This is just a simple example, more
|
||||
complex and powerful rules can be created by using wild-cards, case-insensitive
|
||||
strings, regular expressions, special operators and many other features that
|
||||
you'll find explained in [YARA's documentation](https://yara.readthedocs.org/).
|
||||
|
||||
YARA is multi-platform, running on Windows, Linux and Mac OS X, and can be used
|
||||
through its command-line interface or from your own Python scripts with the
|
||||
yara-python extension.
|
||||
|
||||
If you plan to use YARA to scan compressed files (.zip, .tar, etc) you should
|
||||
take a look at [yextend](https://github.com/BayshoreNetworks/yextend), a very
|
||||
helpful extension to YARA developed and open-sourced by Bayshore Networks.
|
||||
|
||||
## Who's using YARA
|
||||
|
||||
* [ActiveCanopy](https://activecanopy.com/)
|
||||
* [Adlice](http://www.adlice.com/)
|
||||
* [AlienVault](https://otx.alienvault.com/)
|
||||
* [Avast](https://www.avast.com/)
|
||||
* [BAE Systems](http://www.baesystems.com/home?r=ai)
|
||||
* [Bayshore Networks, Inc.](http://www.bayshorenetworks.com)
|
||||
* [BinaryAlert](https://github.com/airbnb/binaryalert)
|
||||
* [Blue Coat](http://www.bluecoat.com/products/malware-analysis-appliance)
|
||||
* [Blueliv](http://www.blueliv.com)
|
||||
* [Conix](http://www.conix.fr)
|
||||
* [CrowdStrike FMS](https://github.com/CrowdStrike/CrowdFMS)
|
||||
* [Cuckoo Sandbox](https://github.com/cuckoosandbox/cuckoo)
|
||||
* [ESET](https://www.eset.com)
|
||||
* [ESTsecurity](https://www.estsecurity.com)
|
||||
* [Fidelis XPS](http://www.fidelissecurity.com/network-security-appliance/Fidelis-XPS)
|
||||
* [FireEye, Inc.](http://www.fireeye.com)
|
||||
* [Fox-IT](https://www.fox-it.com)
|
||||
* [FSF](https://github.com/EmersonElectricCo/fsf)
|
||||
* [Guidance Software](http://www.guidancesoftware.com/endpointsecurity)
|
||||
* [Heroku](https://heroku.com)
|
||||
* [Hornetsecurity](https://www.hornetsecurity.com/en/)
|
||||
* [InQuest](http://www.inquest.net/)
|
||||
* [JASK](http://jask.io)
|
||||
* [Joe Security](https://www.joesecurity.org)
|
||||
* [jsunpack-n](http://jsunpack.jeek.org/)
|
||||
* [Kaspersky Lab](http://www.kaspersky.com)
|
||||
* [Koodous](https://koodous.com/)
|
||||
* [Laika BOSS](https://github.com/lmco/laikaboss)
|
||||
* [Lastline, Inc.](http://www.lastline.com)
|
||||
* [McAfee Advanced Threat Defense](http://mcafee.com/atd)
|
||||
* [Metaflows](http://www.metaflows.com)
|
||||
* [NBS System](https://www.nbs-system.com/)
|
||||
* [Nozomi Networks](http://www.nozominetworks.com)
|
||||
* [osquery](http://www.osquery.io)
|
||||
* [Payload Security](https://www.payload-security.com)
|
||||
* [PhishMe](http://phishme.com/)
|
||||
* [Picus Security](http://www.picussecurity.com/)
|
||||
* [Radare2](http://rada.re)
|
||||
* [Raytheon Cyber Products, Inc.](http://www.raytheoncyber.com/capabilities/products/sureview-threatprotection/)
|
||||
* [RedSocks Security](https://redsocks.eu/)
|
||||
* [ReversingLabs](http://reversinglabs.com)
|
||||
* [root9B](https://www.root9b.com)
|
||||
* [RSA ECAT](http://www.emc.com/security/rsa-ecat.htm)
|
||||
* [SpamStopsHere](https://www.spamstopshere.com)
|
||||
* [stoQ](http://stoq.punchcyber.com)
|
||||
* [Symantec](http://www.symantec.com)
|
||||
* [Tanium](http://www.tanium.com/)
|
||||
* [Tenable Network Security](https://www.tenable.com/)
|
||||
* [The DigiTrust Group](http://www.digitrustgroup.com/)
|
||||
* [ThreatConnect](https://www.threatconnect.com/)
|
||||
* [ThreatStream, Inc.](http://threatstream.com)
|
||||
* [Thug](https://github.com/buffer/thug)
|
||||
* [Trend Micro](http://www.trendmicro.com)
|
||||
* [VirusTotal Intelligence](https://www.virustotal.com/intelligence/)
|
||||
* [VMRay](https://www.vmray.com/)
|
||||
* [We Watch Your Website](http://www.wewatchyourwebsite.com/)
|
||||
* [Websense](http://www.websense.com)
|
||||
* [x64dbg](http://x64dbg.com)
|
||||
* [YALIH](https://github.com/Masood-M/YALIH)
|
||||
* [Scanii](https://scanii.com)
|
||||
|
||||
Are you using it? Want to see your site listed here?
|
||||
@@ -0,0 +1,24 @@
|
||||
# AppVeyor CI for Windows
|
||||
|
||||
version: 3.7.{build}
|
||||
|
||||
pull_requests:
|
||||
do_not_increment_build_number: true
|
||||
|
||||
configuration: Release
|
||||
|
||||
platform:
|
||||
- x64
|
||||
- x86
|
||||
|
||||
before_build:
|
||||
- ps: nuget restore windows/vs2015/yara.sln
|
||||
|
||||
build:
|
||||
project: windows/vs2015/yara.sln
|
||||
verbosity: minimal
|
||||
|
||||
artifacts:
|
||||
- path: windows\**\*.exe
|
||||
|
||||
test: off
|
||||
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
Copyright (c) 2014. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "args.h"
|
||||
|
||||
#define args_is_long_arg(arg) \
|
||||
(arg[0] == '-' && arg[1] == '-' && arg[2] != '\0')
|
||||
|
||||
|
||||
#define args_is_short_arg(arg) \
|
||||
(arg[0] == '-' && arg[1] != '-' && arg[1] != '\0')
|
||||
|
||||
|
||||
args_option_t* args_get_short_option(
|
||||
args_option_t *options,
|
||||
const char opt)
|
||||
{
|
||||
while (options->type != ARGS_OPT_END)
|
||||
{
|
||||
if (opt == options->short_name)
|
||||
return options;
|
||||
|
||||
options++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
args_option_t* args_get_long_option(
|
||||
args_option_t *options,
|
||||
const char* arg)
|
||||
{
|
||||
arg += 2; // skip starting --
|
||||
|
||||
while (options->type != ARGS_OPT_END)
|
||||
{
|
||||
if (options->long_name != NULL)
|
||||
{
|
||||
size_t l = strlen(options->long_name);
|
||||
|
||||
if ((arg[l] == '\0' || arg[l] == '=') &&
|
||||
strstr(arg, options->long_name) == arg)
|
||||
{
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
options++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
args_error_type_t args_parse_option(
|
||||
args_option_t* opt,
|
||||
const char* opt_arg,
|
||||
int* opt_arg_was_used)
|
||||
{
|
||||
char *endptr = NULL;
|
||||
|
||||
if (opt_arg_was_used != NULL)
|
||||
*opt_arg_was_used = 0;
|
||||
|
||||
if (opt->count == opt->max_count)
|
||||
return ARGS_ERROR_TOO_MANY;
|
||||
|
||||
switch (opt->type)
|
||||
{
|
||||
case ARGS_OPT_BOOLEAN:
|
||||
*(int*) opt->value = 1;
|
||||
break;
|
||||
|
||||
case ARGS_OPT_INTEGER:
|
||||
|
||||
if (opt_arg == NULL)
|
||||
return ARGS_ERROR_REQUIRED_INTEGER_ARG;
|
||||
|
||||
*(int*) opt->value = strtol(opt_arg, &endptr, 0);
|
||||
|
||||
if (*endptr != '\0')
|
||||
return ARGS_ERROR_REQUIRED_INTEGER_ARG;
|
||||
|
||||
if (opt_arg_was_used != NULL)
|
||||
*opt_arg_was_used = 1;
|
||||
|
||||
break;
|
||||
|
||||
case ARGS_OPT_STRING:
|
||||
|
||||
if (opt_arg == NULL)
|
||||
return ARGS_ERROR_REQUIRED_STRING_ARG;
|
||||
|
||||
if (opt->max_count > 1)
|
||||
((const char**)opt->value)[opt->count] = opt_arg;
|
||||
else
|
||||
*(const char**) opt->value = opt_arg;
|
||||
|
||||
if (opt_arg_was_used != NULL)
|
||||
*opt_arg_was_used = 1;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
opt->count++;
|
||||
|
||||
return ARGS_ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
void args_print_error(
|
||||
args_error_type_t error,
|
||||
const char* option)
|
||||
{
|
||||
switch(error)
|
||||
{
|
||||
case ARGS_ERROR_UNKNOWN_OPT:
|
||||
fprintf(stderr, "unknown option `%s`\n", option);
|
||||
break;
|
||||
case ARGS_ERROR_TOO_MANY:
|
||||
fprintf(stderr, "too many `%s` options\n", option);
|
||||
break;
|
||||
case ARGS_ERROR_REQUIRED_INTEGER_ARG:
|
||||
fprintf(stderr, "option `%s` requires an integer argument\n", option);
|
||||
break;
|
||||
case ARGS_ERROR_REQUIRED_STRING_ARG:
|
||||
fprintf(stderr, "option `%s` requires a string argument\n", option);
|
||||
break;
|
||||
case ARGS_ERROR_UNEXPECTED_ARG:
|
||||
fprintf(stderr, "option `%s` doesn't expect an argument\n", option);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int args_parse(
|
||||
args_option_t *options,
|
||||
int argc,
|
||||
const char **argv)
|
||||
{
|
||||
args_error_type_t error = ARGS_ERROR_OK;
|
||||
|
||||
int i = 1; // start with i = 1, argv[0] is the program name
|
||||
int o = 0;
|
||||
|
||||
while (i < argc)
|
||||
{
|
||||
const char* arg = argv[i];
|
||||
|
||||
if (args_is_long_arg(arg))
|
||||
{
|
||||
args_option_t* opt = args_get_long_option(options, arg);
|
||||
|
||||
if (opt != NULL)
|
||||
{
|
||||
const char* equal = strchr(arg, '=');
|
||||
|
||||
if (equal)
|
||||
error = args_parse_option(opt, equal + 1, NULL);
|
||||
else
|
||||
error = args_parse_option(opt, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = ARGS_ERROR_UNKNOWN_OPT;
|
||||
}
|
||||
}
|
||||
else if (args_is_short_arg(arg))
|
||||
{
|
||||
for (int j = 1; arg[j] != '\0'; j++)
|
||||
{
|
||||
args_option_t* opt = args_get_short_option(options, arg[j]);
|
||||
|
||||
if (opt != NULL)
|
||||
{
|
||||
if (arg[j + 1] == '\0')
|
||||
{
|
||||
int arg_used;
|
||||
|
||||
// short option followed by a space, argv[i + 1] could be
|
||||
// an argument for the option (i.e: -a <arg>)
|
||||
error = args_parse_option(opt, argv[i + 1], &arg_used);
|
||||
|
||||
// argv[i + 1] was actually an argument to the option, skip it.
|
||||
if (arg_used)
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// short option followed by another option (i.e: -ab), no
|
||||
// argument for this option
|
||||
error = args_parse_option(opt, NULL, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = ARGS_ERROR_UNKNOWN_OPT;
|
||||
}
|
||||
|
||||
if (error != ARGS_ERROR_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argv[o++] = arg;
|
||||
}
|
||||
|
||||
if (error != ARGS_ERROR_OK)
|
||||
{
|
||||
args_print_error(error, arg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
void args_print_usage(
|
||||
args_option_t *options,
|
||||
int help_alignment)
|
||||
{
|
||||
char buffer[128];
|
||||
|
||||
for (; options->type != ARGS_OPT_END; options++)
|
||||
{
|
||||
int len = sprintf(buffer, " ");
|
||||
|
||||
if (options->short_name != '\0')
|
||||
len += sprintf(buffer + len, "-%c", options->short_name);
|
||||
else
|
||||
len += sprintf(buffer + len, " ");
|
||||
|
||||
if (options->short_name != '\0' && options->long_name != NULL)
|
||||
len += sprintf(buffer + len, ", ");
|
||||
|
||||
if (options->long_name != NULL)
|
||||
len += sprintf(buffer + len, "--%s", options->long_name);
|
||||
|
||||
if (options->type == ARGS_OPT_STRING ||
|
||||
options->type == ARGS_OPT_INTEGER)
|
||||
{
|
||||
len += sprintf(
|
||||
buffer + len,
|
||||
"%s%s",
|
||||
(options->long_name != NULL) ? "=" : " ",
|
||||
options->type_help);
|
||||
}
|
||||
|
||||
printf("%-*s%s\n", help_alignment, buffer, options->help);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
Copyright (c) 2014. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARGPARSE_H
|
||||
#define ARGPARSE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum _args_error_type {
|
||||
ARGS_ERROR_OK,
|
||||
ARGS_ERROR_UNKNOWN_OPT,
|
||||
ARGS_ERROR_TOO_MANY,
|
||||
ARGS_ERROR_REQUIRED_INTEGER_ARG,
|
||||
ARGS_ERROR_REQUIRED_STRING_ARG,
|
||||
ARGS_ERROR_UNEXPECTED_ARG,
|
||||
} args_error_type_t;
|
||||
|
||||
|
||||
typedef enum _args_option_type {
|
||||
// special
|
||||
ARGS_OPT_END,
|
||||
ARGS_OPT_GROUP,
|
||||
// options with no arguments
|
||||
ARGS_OPT_BOOLEAN,
|
||||
// options with arguments (optional or required)
|
||||
ARGS_OPT_INTEGER,
|
||||
ARGS_OPT_STRING,
|
||||
} args_option_type_t;
|
||||
|
||||
|
||||
typedef struct _args_option {
|
||||
args_option_type_t type;
|
||||
const char short_name;
|
||||
const char *long_name;
|
||||
void *value;
|
||||
int max_count;
|
||||
const char *help;
|
||||
const char *type_help;
|
||||
int count;
|
||||
} args_option_t;
|
||||
|
||||
|
||||
#define OPT_BOOLEAN(short_name, long_name, value, ...) \
|
||||
{ ARGS_OPT_BOOLEAN, short_name, long_name, value, 1, __VA_ARGS__ }
|
||||
|
||||
#define OPT_INTEGER(short_name, long_name, value, ...) \
|
||||
{ ARGS_OPT_INTEGER, short_name, long_name, value, 1, __VA_ARGS__ }
|
||||
|
||||
#define OPT_STRING_MULTI(short_name, long_name, value, max_count, ...) \
|
||||
{ ARGS_OPT_STRING, short_name, long_name, value, max_count, __VA_ARGS__ }
|
||||
|
||||
#define OPT_STRING(short_name, long_name, value, ...) \
|
||||
OPT_STRING_MULTI(short_name, long_name, value, 1, __VA_ARGS__)
|
||||
|
||||
#define OPT_END() { ARGS_OPT_END, 0 }
|
||||
|
||||
|
||||
int args_parse(
|
||||
args_option_t *options,
|
||||
int argc,
|
||||
const char **argv);
|
||||
|
||||
|
||||
void args_print_usage(
|
||||
args_option_t *options,
|
||||
int alignment);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
autoreconf --force --install
|
||||
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
./bootstrap.sh
|
||||
./configure
|
||||
make
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
Copyright (c) 2017. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#define exit_with_code(code) { result = code; goto _exit; }
|
||||
|
||||
|
||||
int compile_files(
|
||||
YR_COMPILER* compiler,
|
||||
int argc,
|
||||
const char** argv)
|
||||
{
|
||||
for (int i = 0; i < argc - 1; i++)
|
||||
{
|
||||
const char* ns;
|
||||
const char* file_name;
|
||||
char* colon = (char*) strchr(argv[i], ':');
|
||||
int errors;
|
||||
|
||||
// Namespace delimiter must be a colon not followed by a slash or backslash
|
||||
if (colon && *(colon + 1) != '\\' && *(colon + 1) != '/')
|
||||
{
|
||||
file_name = colon + 1;
|
||||
*colon = '\0';
|
||||
ns = argv[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
file_name = argv[i];
|
||||
ns = NULL;
|
||||
}
|
||||
|
||||
FILE* rule_file = fopen(file_name, "r");
|
||||
|
||||
if (rule_file == NULL)
|
||||
{
|
||||
fprintf(stderr, "error: could not open file: %s\n", file_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
errors = yr_compiler_add_file(compiler, rule_file, ns, file_name);
|
||||
|
||||
fclose(rule_file);
|
||||
|
||||
if (errors > 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int is_integer(const char *str)
|
||||
{
|
||||
if (*str == '-')
|
||||
str++;
|
||||
|
||||
while(*str)
|
||||
{
|
||||
if (!isdigit(*str))
|
||||
return FALSE;
|
||||
str++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int is_float(const char *str)
|
||||
{
|
||||
int has_dot = FALSE;
|
||||
|
||||
if (*str == '-') // skip the minus sign if present
|
||||
str++;
|
||||
|
||||
if (*str == '.') // float can't start with a dot
|
||||
return FALSE;
|
||||
|
||||
while(*str)
|
||||
{
|
||||
if (*str == '.')
|
||||
{
|
||||
if (has_dot) // two dots, not a float
|
||||
return FALSE;
|
||||
|
||||
has_dot = TRUE;
|
||||
}
|
||||
else if (!isdigit(*str))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
str++;
|
||||
}
|
||||
|
||||
return has_dot; // to be float must contain a dot
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,308 @@
|
||||
AC_INIT([yara], [3.7.0], [vmalvarez@virustotal.com])
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
AC_CONFIG_SRCDIR([yara.c])
|
||||
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
# AC_PROG_CC sets CFLAGS to "-g -O2" if it wasn't previously set. Let's set
|
||||
# an empty CFLAGS
|
||||
: ${CFLAGS=""}
|
||||
|
||||
no_std_allocator="-fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free"
|
||||
|
||||
# automake 1.12 seems to require AM_PROG_AR, but automake 1.11 doesn't
|
||||
# recognize it
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AM_PROG_LEX
|
||||
AC_PROG_YACC
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
LT_INIT
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
case $host_alias in
|
||||
i?86-*-mingw*) CFLAGS="$CFLAGS -D__MINGW_USE_VC2005_COMPAT" ;;
|
||||
esac
|
||||
|
||||
case $host_os in
|
||||
darwin*) CFLAGS="$CFLAGS -I/opt/local/include"
|
||||
# Starting with Mac OS X 10.11 (El Capitan) the OpenSSL headers
|
||||
# are in /usr/local/opt/openssl/include
|
||||
CFLAGS="$CFLAGS -DUSE_MACH_PROC -I/usr/local/opt/openssl/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/opt/openssl/lib"
|
||||
mach=yes
|
||||
proc_interface=mach
|
||||
jemalloc_prefix=je_ ;;
|
||||
mingw*) CFLAGS="$CFLAGS -DUSE_WINDOWS_PROC"
|
||||
proc_interface=windows
|
||||
jemalloc_prefix= ;;
|
||||
linux*|netbsd*|dragonfly*|kfreebsd*)
|
||||
CFLAGS="$CFLAGS -DUSE_LINUX_PROC"
|
||||
proc_interface=linux
|
||||
jemalloc_prefix= ;;
|
||||
freebsd*)
|
||||
CFLAGS="$CFLAGS -DUSE_FREEBSD_PROC"
|
||||
proc_interface=freebsd
|
||||
jemalloc_prefix= ;;
|
||||
openbsd*)
|
||||
CFLAGS="$CFLAGS -DUSE_OPENBSD_PROC"
|
||||
proc_interface=openbsd
|
||||
jemalloc_prefix= ;;
|
||||
*)
|
||||
CFLAGS="$CFLAGS -DUSE_NO_PROC"
|
||||
proc_interface=none
|
||||
jemalloc_prefix= ;;
|
||||
esac
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
ACX_PTHREAD(
|
||||
[LIBS="$PTHREAD_LIBS $LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
CC="$PTHREAD_CC"],
|
||||
[AC_MSG_ERROR([pthread API support is required.])])
|
||||
|
||||
AC_CHECK_LIB(m, isnan)
|
||||
AC_CHECK_LIB(m, log2)
|
||||
AC_CHECK_FUNCS([strlcpy strlcat memmem timegm _mkgmtime])
|
||||
|
||||
AC_ARG_ENABLE([debug],
|
||||
[AS_HELP_STRING([--enable-debug], [compiles with -g option])],
|
||||
[if test x$enableval = xyes; then
|
||||
debug=true
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE([optimization],
|
||||
[AS_HELP_STRING([--disable-optimization], [disable compiler optimizations with -O0])],
|
||||
[if test x$enableval = xyes; then
|
||||
optimization=false
|
||||
fi],
|
||||
[optimization=true])
|
||||
|
||||
AC_ARG_ENABLE([address-sanitizer],
|
||||
[AS_HELP_STRING([--enable-address-sanitizer], [compiles with -fsanitize=address])],
|
||||
[if test x$enableval = xyes; then
|
||||
address_sanitizer=true
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE([profiling],
|
||||
[AS_HELP_STRING([--enable-profiling], [enable rules profiling support])],
|
||||
[if test x$enableval = xyes; then
|
||||
profiling_enabled=true
|
||||
CFLAGS="$CFLAGS -DPROFILING_ENABLED"
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE([cuckoo],
|
||||
[AS_HELP_STRING([--enable-cuckoo], [enable cuckoo module])],
|
||||
[if test x$enableval = xyes; then
|
||||
build_cuckoo_module=true
|
||||
AC_CHECK_HEADERS([jansson.h],,
|
||||
AC_MSG_ERROR([please install Jansson library]))
|
||||
AC_CHECK_LIB(jansson, json_loadb,,
|
||||
AC_MSG_ERROR([please install Jansson library]))
|
||||
CFLAGS="$CFLAGS -DCUCKOO_MODULE"
|
||||
PC_REQUIRES_PRIVATE="$PC_REQUIRES_PRIVATE jansson"
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE([magic],
|
||||
[AS_HELP_STRING([--enable-magic], [enable magic module])],
|
||||
[if test x$enableval = xyes; then
|
||||
build_magic_module=true
|
||||
AC_CHECK_HEADERS([magic.h],,
|
||||
AC_MSG_ERROR([please install libmagic library]))
|
||||
AC_CHECK_LIB(magic, magic_open,,
|
||||
AC_MSG_ERROR([please install libmagic library]))
|
||||
CFLAGS="$CFLAGS -DMAGIC_MODULE"
|
||||
PC_LIBS_PRIVATE="$PC_LIBS_PRIVATE -lmagic"
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE([dotnet],
|
||||
[AS_HELP_STRING([--enable-dotnet], [enable dotnet module])],
|
||||
[if test x$enableval = xyes; then
|
||||
build_dotnet_module=true
|
||||
CFLAGS="$CFLAGS -DDOTNET_MODULE"
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE([macho],
|
||||
[AS_HELP_STRING([--enable-macho], [enable macho module])],
|
||||
[if test x$enableval = xyes; then
|
||||
build_macho_module=true
|
||||
CFLAGS="$CFLAGS -DMACHO_MODULE"
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE([dex],
|
||||
[AS_HELP_STRING([--enable-dex], [enable dex module])],
|
||||
[if test x$enableval = xyes; then
|
||||
build_dex_module=true
|
||||
CFLAGS="$CFLAGS -DDEX_MODULE"
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE([debug-dex],
|
||||
[AS_HELP_STRING([--enable-debug-dex], [enable dex module debugging])],
|
||||
[if test x$enableval = xyes; then
|
||||
debug_dex_module=true
|
||||
CFLAGS="$CFLAGS -DDEBUG_DEX_MODULE"
|
||||
fi])
|
||||
|
||||
AC_ARG_WITH([jemalloc],
|
||||
[AS_HELP_STRING([--with-jemalloc],
|
||||
[use jemalloc to debug heap-related issues])],
|
||||
[if test x$withval = xyes; then
|
||||
mallctl=mallctl
|
||||
malloc_stats_print=malloc_stats_print
|
||||
AC_CHECK_LIB(jemalloc, $jemalloc_prefix$mallctl,,
|
||||
AC_MSG_ERROR([please install jemalloc library]))
|
||||
CFLAGS="$CFLAGS -DJEMALLOC -Dmallctl=$jemalloc_prefix$mallctl -Dmalloc_stats_print=$jemalloc_prefix$malloc_stats_print $no_std_allocator"
|
||||
fi])
|
||||
|
||||
AC_ARG_WITH([tcmalloc],
|
||||
[AS_HELP_STRING([--with-tcmalloc],
|
||||
[use tcmalloc as the default heap allocator])],
|
||||
[if test x$withval = xyes; then
|
||||
if test "x$with_jemalloc" = "xyes"; then
|
||||
AC_MSG_ERROR([Cannot compile with both tcmalloc and jemalloc])
|
||||
fi
|
||||
AC_CHECK_LIB(tcmalloc, tc_cfree,,
|
||||
AC_MSG_ERROR([please install https://github.com/gperftools/gperftools]))
|
||||
CFLAGS="$CFLAGS -DTCMALLOC $no_std_allocator"
|
||||
fi])
|
||||
|
||||
AC_ARG_WITH([cpu-profiler],
|
||||
[AS_HELP_STRING([--with-cpu-profiler],
|
||||
[compile with CPU profiling support])],
|
||||
[if test x$withval = xyes; then
|
||||
AC_CHECK_LIB(profiler, ProfilerStart,,
|
||||
AC_MSG_ERROR([please install https://github.com/gperftools/gperftools]))
|
||||
fi])
|
||||
|
||||
AC_ARG_WITH([crypto],
|
||||
AS_HELP_STRING([--without-crypto],
|
||||
[ignore presence of OpenSSL and disable it]))
|
||||
|
||||
AS_IF([test "x$with_crypto" != "xno"],
|
||||
[
|
||||
AC_CHECK_HEADERS([openssl/md5.h],, [have_crypto=no])
|
||||
AC_CHECK_HEADERS([openssl/sha.h],, [have_crypto=no])
|
||||
AC_CHECK_HEADERS([openssl/asn1.h],, [have_crypto=no])
|
||||
AC_CHECK_HEADERS([openssl/crypto.h],, [have_crypto=no])
|
||||
AC_CHECK_HEADERS([openssl/bio.h],, [have_crypto=no])
|
||||
AC_CHECK_HEADERS([openssl/pkcs7.h],, [have_crypto=no])
|
||||
AC_CHECK_HEADERS([openssl/x509.h],, [have_crypto=no])
|
||||
AC_CHECK_HEADERS([openssl/safestack.h],, [have_crypto=no])
|
||||
AC_CHECK_LIB(crypto, MD5_Init,, [have_crypto=no])
|
||||
AC_CHECK_LIB(crypto, MD5_Update,, [have_crypto=no])
|
||||
AC_CHECK_LIB(crypto, MD5_Final,, [have_crypto=no])
|
||||
AC_CHECK_LIB(crypto, SHA256_Init,, [have_crypto=no])
|
||||
AC_CHECK_LIB(crypto, SHA256_Update,, [have_crypto=no])
|
||||
AC_CHECK_LIB(crypto, SHA256_Final,, [have_crypto=no])
|
||||
],
|
||||
[
|
||||
have_crypto=no
|
||||
])
|
||||
|
||||
|
||||
AS_IF([test "x$have_crypto" = "xno"],
|
||||
[
|
||||
AS_IF([test "x$with_crypto" = "xyes"],
|
||||
[
|
||||
AC_MSG_ERROR([please install OpenSSL library])
|
||||
],
|
||||
[
|
||||
AC_MSG_WARN([
|
||||
|
||||
*****************************************************************
|
||||
Could not find OpenSSL library. Some features in "pe" module
|
||||
have been disabled. If you want to enable all features please
|
||||
install OpenSSL and run this script again.
|
||||
*****************************************************************
|
||||
])
|
||||
AC_MSG_CHECKING([for Microsoft Crypto API])
|
||||
AC_CHECK_HEADERS([wincrypt.h],
|
||||
[
|
||||
AC_MSG_RESULT([The "hash" module functions will be provided through the Microsoft Crypto API])
|
||||
# FIXME: Add PC_LIBS_PRIVATE entries?
|
||||
build_hash_module=true
|
||||
],
|
||||
[],
|
||||
[#include <windows.h>])
|
||||
AC_MSG_CHECKING([for MacOSX Common Crypto API])
|
||||
AC_CHECK_HEADERS([CommonCrypto/CommonCrypto.h],
|
||||
[
|
||||
AC_MSG_RESULT([
|
||||
*****************************************************************
|
||||
As an alternative to OpenSSL the "hash" module functions will
|
||||
be provided through the MacOSX Common Crypto API.
|
||||
*****************************************************************
|
||||
])
|
||||
# FIXME: Add PC_LIBS_PRIVATE entries?
|
||||
build_hash_module=true
|
||||
])
|
||||
AS_IF([test x$build_hash_module = xtrue],
|
||||
[
|
||||
build_hash_module=true
|
||||
CFLAGS="$CFLAGS -DHASH_MODULE"
|
||||
],
|
||||
[
|
||||
AC_MSG_WARN([
|
||||
|
||||
*****************************************************************
|
||||
Could not find alternative APIs for hash functions. The "hash"
|
||||
module has been disabled.
|
||||
*****************************************************************
|
||||
])
|
||||
])
|
||||
])
|
||||
],
|
||||
[
|
||||
build_hash_module=true
|
||||
CFLAGS="$CFLAGS -DHASH_MODULE"
|
||||
PC_REQUIRES_PRIVATE="$PC_REQUIRES_PRIVATE libcrypto"
|
||||
])
|
||||
|
||||
AS_IF([test "x$mach" != "xyes"],
|
||||
[
|
||||
AC_CHECK_FUNCS([clock_gettime],,
|
||||
AC_MSG_ERROR([clock_gettime not supported in your OS.]))
|
||||
],)
|
||||
|
||||
AM_CONDITIONAL([DEBUG], [test x$debug = xtrue])
|
||||
AM_CONDITIONAL([PROFILING_ENABLED], [test x$profiling_enabled = xtrue])
|
||||
AM_CONDITIONAL([OPTIMIZATION], [test x$optimization = xtrue])
|
||||
AM_CONDITIONAL([ADDRESS_SANITIZER], [test x$address_sanitizer = xtrue])
|
||||
AM_CONDITIONAL([CUCKOO_MODULE], [test x$build_cuckoo_module = xtrue])
|
||||
AM_CONDITIONAL([MAGIC_MODULE], [test x$build_magic_module = xtrue])
|
||||
AM_CONDITIONAL([HASH_MODULE], [test x$build_hash_module = xtrue])
|
||||
AM_CONDITIONAL([DOTNET_MODULE], [test x$build_dotnet_module = xtrue])
|
||||
AM_CONDITIONAL([MACHO_MODULE], [test x$build_macho_module = xtrue])
|
||||
AM_CONDITIONAL([GCC], [test "x$GCC" = xyes])
|
||||
AM_CONDITIONAL([DEX_MODULE], [test x$build_dex_module = xtrue])
|
||||
AM_CONDITIONAL([DEBUG_DEX_MODULE], [test x$debug_dex_module = xtrue])
|
||||
|
||||
AM_CONDITIONAL([USE_WINDOWS_PROC], [test x$proc_interface = xwindows ])
|
||||
AM_CONDITIONAL([USE_LINUX_PROC], [test x$proc_interface = xlinux ])
|
||||
AM_CONDITIONAL([USE_FREEBSD_PROC], [test x$proc_interface = xfreebsd ])
|
||||
AM_CONDITIONAL([USE_OPENBSD_PROC], [test x$proc_interface = xopenbsd ])
|
||||
AM_CONDITIONAL([USE_MACH_PROC], [test x$proc_interface = xmach ])
|
||||
AM_CONDITIONAL([USE_NO_PROC], [test x$proc_interface = xnone ])
|
||||
AS_IF(
|
||||
[test x$proc_interface != xnone],[AC_DEFINE([HAVE_SCAN_PROC_IMPL],[1])],
|
||||
[test x$proc_interface = xnone],[AC_DEFINE([HAVE_SCAN_PROC_IMPL],[0])])
|
||||
|
||||
AC_SUBST([PC_REQUIRES_PRIVATE])
|
||||
AC_SUBST([PC_LIBS_PRIVATE])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_CONFIG_FILES([libyara/Makefile])
|
||||
AC_CONFIG_FILES([libyara/yara.pc])
|
||||
|
||||
AC_OUTPUT
|
||||
Vendored
+35
@@ -0,0 +1,35 @@
|
||||
%define name yara-python
|
||||
%define version 3.2.0
|
||||
%define unmangled_version 3.2.0
|
||||
%define release 1
|
||||
|
||||
Summary: Python bindings for YARA malware research tool
|
||||
Name: %{name}
|
||||
Version: %{version}
|
||||
Release: %{release}
|
||||
Source0: %{name}-%{unmangled_version}.tar.gz
|
||||
License: Apache License 2.0
|
||||
Group: Development/Libraries
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
|
||||
Prefix: %{_prefix}
|
||||
Vendor: Victor M. Alvarez <plusvic@gmail.com;vmalvarez@virustotal.com>
|
||||
BuildRequires: gcc python-devel
|
||||
BuildRequires: libyara-devel
|
||||
|
||||
%description
|
||||
YARA is a tool aimed at (but not limited to) helpingmalware researchers to identify and classify malwaresamples. With YARA you can create descriptions of malware families (or whatever you want to describe)based on textual or binary patterns.
|
||||
|
||||
%prep
|
||||
%setup -n %{name}-%{unmangled_version}
|
||||
|
||||
%build
|
||||
env CFLAGS="$RPM_OPT_FLAGS" python setup.py build
|
||||
|
||||
%install
|
||||
python setup.py install -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files -f INSTALLED_FILES
|
||||
%defattr(-,root,root)
|
||||
Vendored
+85
@@ -0,0 +1,85 @@
|
||||
##
|
||||
## Copyright (c) 2007-2015. The YARA Authors. All Rights Reserved.
|
||||
## Licensed under the Apache License, Version 2.0 (the "License");
|
||||
## you may not use this file except in compliance with the License.
|
||||
## You may obtain a copy of the License at
|
||||
## http://www.apache.org/licenses/LICENSE-2.0
|
||||
## Unless required by applicable law or agreed to in writing, software
|
||||
## distributed under the License is distributed on an "AS IS" BASIS,
|
||||
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
## See the License for the specific language governing permissions and
|
||||
## limitations under the License.
|
||||
##
|
||||
|
||||
Name: yara
|
||||
Version: 3.2.0
|
||||
Release: 1
|
||||
License: Apache License 2.0
|
||||
Summary: A malware identification and classification tool
|
||||
Url: http://plusvic.github.io/yara/
|
||||
Group: System/Filesystems
|
||||
Source: yara-%{version}.tar.gz
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
BuildRequires: autoconf automake libtool
|
||||
|
||||
%description
|
||||
YARA is a tool aimed at helping malware researchers to identify and classify
|
||||
malware samples. With YARA you can create descriptions of malware families
|
||||
based on textual or binary patterns contained on samples of those families.
|
||||
|
||||
%package -n libyara
|
||||
Summary: Library to support the yara malware identification tool
|
||||
Group: System/Libraries
|
||||
|
||||
%description -n libyara
|
||||
YARA is a tool aimed at helping malware researchers to identify and classify
|
||||
malware samples. With YARA you can create descriptions of malware families
|
||||
based on textual or binary patterns contained on samples of those families.
|
||||
|
||||
%package -n yara-devel
|
||||
Summary: Development files to support the yara malware identification tool
|
||||
Group: Development/Libraries/C and C++
|
||||
Requires: libyara = %{version}-%{release}
|
||||
|
||||
%description -n yara-devel
|
||||
YARA is a tool aimed at helping malware researchers to identify and classify
|
||||
malware samples. With YARA you can create descriptions of malware families
|
||||
based on textual or binary patterns contained on samples of those families.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
./bootstrap.sh
|
||||
./configure
|
||||
make
|
||||
|
||||
%install
|
||||
make install DESTDIR=%{buildroot} bindir=%{_bindir} libdir=%{_libdir} includedir=%{_includedir} mandir=%{_mandir} INSTALL="install -p"
|
||||
|
||||
%post -n libyara -p /sbin/ldconfig
|
||||
|
||||
%postun -n libyara -p /sbin/ldconfig
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%{_bindir}/yara
|
||||
%{_bindir}/yarac
|
||||
%{_mandir}/man1/*
|
||||
|
||||
%files -n libyara
|
||||
%defattr(-,root,root)
|
||||
%{_libdir}/libyara.so*
|
||||
%{_libdir}/pkgconfig/yara.pc
|
||||
|
||||
%files -n yara-devel
|
||||
%defattr(-,root,root)
|
||||
%{_includedir}/yara.h
|
||||
%{_includedir}/yara/*
|
||||
%{_libdir}/libyara.a
|
||||
%{_libdir}/libyara.la
|
||||
|
||||
|
||||
%changelog
|
||||
* Sat Jan 25 2015 Domingo Kiser <domingo.kiser@gmail.com> 3.2.0-1
|
||||
Initial Creation.
|
||||
@@ -0,0 +1,784 @@
|
||||
*********
|
||||
The C API
|
||||
*********
|
||||
|
||||
You can integrate YARA into your C/C++ project by using the API provided by the
|
||||
*libyara* library. This API gives you access to every YARA feature and it's the
|
||||
same API used by the command-line tools ``yara`` and ``yarac``.
|
||||
|
||||
Initializing and finalizing *libyara*
|
||||
=====================================
|
||||
|
||||
The first thing your program must do when using *libyara* is initializing the
|
||||
library. This is done by calling the :c:func:`yr_initialize` function. This
|
||||
function allocates any resources needed by the library and initializes internal
|
||||
data structures. Its counterpart is :c:func:`yr_finalize`, which must be called
|
||||
when you are finished using the library.
|
||||
|
||||
In a multi-threaded program only the main thread must call
|
||||
:c:func:`yr_initialize` and :c:func:`yr_finalize`, but any additional thread
|
||||
using the library must call :c:func:`yr_finalize_thread` before exiting.
|
||||
|
||||
|
||||
Compiling rules
|
||||
===============
|
||||
|
||||
Before using your rules to scan any data you need to compile them into binary
|
||||
form. For that purpose you'll need a YARA compiler, which can be created with
|
||||
:c:func:`yr_compiler_create`. After being used, the compiler must be destroyed
|
||||
with :c:func:`yr_compiler_destroy`.
|
||||
|
||||
You can use :c:func:`yr_compiler_add_file`, :c:func:`yr_compiler_add_fd`, or
|
||||
:c:func:`yr_compiler_add_string` to add one or more input sources to be
|
||||
compiled. Both of these functions receive an optional namespace. Rules added
|
||||
under the same namespace behave as if they were contained within the same
|
||||
source file or string, so, rule identifiers must be unique among all the sources
|
||||
sharing a namespace. If the namespace argument is ``NULL`` the rules are put
|
||||
in the *default* namespace.
|
||||
|
||||
The :c:func:`yr_compiler_add_file`, :c:func:`yr_compiler_add_fd`, and
|
||||
:c:func:`yr_compiler_add_string` functions return
|
||||
the number of errors found in the source code. If the rules are correct they
|
||||
will return 0. If any of these functions return an error the compiler can't used
|
||||
anymore, neither for adding more rules nor getting the compiled rules.
|
||||
|
||||
For obtaining detailed error information you must set a callback
|
||||
function by using :c:func:`yr_compiler_set_callback` before calling
|
||||
any of the compiling functions. The callback function has the following
|
||||
prototype:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void callback_function(
|
||||
int error_level,
|
||||
const char* file_name,
|
||||
int line_number,
|
||||
const char* message,
|
||||
void* user_data)
|
||||
|
||||
.. versionchanged:: 3.3.0
|
||||
|
||||
Possible values for ``error_level`` are ``YARA_ERROR_LEVEL_ERROR`` and
|
||||
``YARA_ERROR_LEVEL_WARNING``. The arguments ``file_name`` and ``line_number``
|
||||
contains the file name and line number where the error or warning occurs.
|
||||
``file_name`` is the one passed to :c:func:`yr_compiler_add_file` or
|
||||
:c:func:`yr_compiler_add_fd`. It can be ``NULL`` if you passed ``NULL`` or if
|
||||
you're using :c:func:`yr_compiler_add_string`. The ``user_data`` pointer is the
|
||||
same you passed to :c:func:`yr_compiler_set_callback`.
|
||||
|
||||
By default, for rules containing references to other files
|
||||
(``include "filename.yara"``), yara will try to find those files on disk.
|
||||
However, if you want to fetch the imported rules from another source (eg: from a
|
||||
database or remote service), a callback function can be set with
|
||||
:c:func:`yr_compiler_set_include_callback`.
|
||||
The callback receives the following parameters:
|
||||
* ``include_name``: name of the requested file.
|
||||
* ``calling_rule_filename``: the requesting file name (NULL if not a file).
|
||||
* ``calling_rule_namespace``: namespace (NULL if undefined).
|
||||
* ``user_data`` pointer is the same you passed to :c:func:`yr_compiler_set_include_callback`.
|
||||
It should return the requested file's content as a null-terminated string. The
|
||||
memory for this string should be allocated by the callback function. Once it is
|
||||
safe to free the memory used to return the callback's result, the include_free
|
||||
function passed to :c:func:`yr_compiler_set_include_callback` will be called.
|
||||
If the memory does not need to be freed, NULL can be passed as include_free
|
||||
instead. You can completely disable support for includes by setting a NULL
|
||||
callback function with :c:func:`yr_compiler_set_include_callback`.
|
||||
|
||||
The callback function has the following prototype:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
const char* include_callback(
|
||||
const char* include_name,
|
||||
const char* calling_rule_filename,
|
||||
const char* calling_rule_namespace,
|
||||
void* user_data);
|
||||
|
||||
The free function has the following prototype:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void include_free(
|
||||
const char* callback_result_ptr,
|
||||
void* user_data);
|
||||
|
||||
After you successfully added some sources you can get the compiled rules
|
||||
using the :c:func:`yr_compiler_get_rules` function. You'll get a pointer to
|
||||
a :c:type:`YR_RULES` structure which can be used to scan your data as
|
||||
described in :ref:`scanning-data`. Once :c:func:`yr_compiler_get_rules` is
|
||||
invoked you can not add more sources to the compiler, but you can get multiple
|
||||
instances of the compiled rules by calling :c:func:`yr_compiler_get_rules`
|
||||
multiple times.
|
||||
|
||||
Each instance of :c:type:`YR_RULES` must be destroyed with
|
||||
:c:func:`yr_rules_destroy`.
|
||||
|
||||
|
||||
Saving and retrieving compiled rules
|
||||
====================================
|
||||
|
||||
Compiled rules can be saved to a file and retrieved later by using
|
||||
:c:func:`yr_rules_save` and :c:func:`yr_rules_load`. Rules compiled and saved
|
||||
in one machine can be loaded in another machine as long as they have the same
|
||||
endianness, no matter the operating system or if they are 32-bit or 64-bit
|
||||
systems. However files saved with older versions of YARA may not work with
|
||||
newer versions due to changes in the file layout.
|
||||
|
||||
You can also save and retrieve your rules to and from generic data streams by
|
||||
using functions :c:func:`yr_rules_save_stream` and
|
||||
:c:func:`yr_rules_load_stream`. These functions receive a pointer to a
|
||||
:c:type:`YR_STREAM` structure, defined as:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
typedef struct _YR_STREAM
|
||||
{
|
||||
void* user_data;
|
||||
|
||||
YR_STREAM_READ_FUNC read;
|
||||
YR_STREAM_WRITE_FUNC write;
|
||||
|
||||
} YR_STREAM;
|
||||
|
||||
You must provide your own implementation for ``read`` and ``write`` functions.
|
||||
The ``read`` function is used by :c:func:`yr_rules_load_stream` to read data
|
||||
from your stream and the ``write`` function is used by
|
||||
:c:func:`yr_rules_save_stream` to write data into your stream.
|
||||
|
||||
Your ``read`` and ``write`` functions must respond to these prototypes:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
size_t read(
|
||||
void* ptr,
|
||||
size_t size,
|
||||
size_t count,
|
||||
void* user_data);
|
||||
|
||||
size_t write(
|
||||
const void* ptr,
|
||||
size_t size,
|
||||
size_t count,
|
||||
void* user_data);
|
||||
|
||||
The ``ptr`` argument is a pointer to the buffer where the ``read`` function
|
||||
should put the read data, or where the ``write`` function will find the data
|
||||
that needs to be written to the stream. In both cases ``size`` is the size of
|
||||
each element being read or written and ``count`` the number of elements. The
|
||||
total size of the data being read or written is ``size`` * ``count``. Both
|
||||
functions must return the total number of elements read or written.
|
||||
|
||||
The ``user_data`` pointer is the same you specified in the
|
||||
:c:type:`YR_STREAM` structure. You can use it to pass arbitrary data to your
|
||||
``read`` and ``write`` functions.
|
||||
|
||||
|
||||
.. _scanning-data:
|
||||
|
||||
Scanning data
|
||||
=============
|
||||
|
||||
Once you have an instance of :c:type:`YR_RULES` you can use it with either
|
||||
:c:func:`yr_rules_scan_file`, :c:func:`yr_rules_scan_fd` or
|
||||
:c:func:`yr_rules_scan_mem`. The results from the scan are returned to your
|
||||
program via a callback function. The callback has the following prototype:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int callback_function(
|
||||
int message,
|
||||
void* message_data,
|
||||
void* user_data);
|
||||
|
||||
Possible values for ``message`` are::
|
||||
|
||||
CALLBACK_MSG_RULE_MATCHING
|
||||
CALLBACK_MSG_RULE_NOT_MATCHING
|
||||
CALLBACK_MSG_SCAN_FINISHED
|
||||
CALLBACK_MSG_IMPORT_MODULE
|
||||
CALLBACK_MSG_MODULE_IMPORTED
|
||||
|
||||
Your callback function will be called once for each rule with either
|
||||
a ``CALLBACK_MSG_RULE_MATCHING`` or ``CALLBACK_MSG_RULE_NOT_MATCHING`` message,
|
||||
depending if the rule is matching or not. In both cases a pointer to the
|
||||
:c:type:`YR_RULE` structure associated with the rule is passed in the
|
||||
``message_data`` argument. You just need to perform a typecast from
|
||||
``void*`` to ``YR_RULE*`` to access the structure.
|
||||
|
||||
This callback is also called with the ``CALLBACK_MSG_IMPORT_MODULE`` message.
|
||||
All modules referenced by an ``import`` statement in the rules are imported
|
||||
once for every file being scanned. In this case ``message_data`` points to a
|
||||
:c:type:`YR_MODULE_IMPORT` structure. This structure contains a ``module_name``
|
||||
field pointing to a null terminated string with the name of the module being
|
||||
imported and two other fields ``module_data`` and ``module_data_size``. These
|
||||
fields are initially set to ``NULL`` and ``0``, but your program can assign a
|
||||
pointer to some arbitrary data to ``module_data`` while setting
|
||||
``module_data_size`` to the size of the data. This way you can pass additional
|
||||
data to those modules requiring it, like the :ref:`Cuckoo-module` for example.
|
||||
|
||||
Once a module is imported the callback is called again with the
|
||||
CALLBACK_MSG_MODULE_IMPORTED. When this happens ``message_data`` points to a
|
||||
:c:type:`YR_OBJECT_STRUCTURE` structure. This structure contains all the
|
||||
information provided by the module about the currently scanned file.
|
||||
|
||||
Lastly, the callback function is also called with the
|
||||
``CALLBACK_MSG_SCAN_FINISHED`` message when the scan is finished. In this case
|
||||
``message_data`` is ``NULL``.
|
||||
|
||||
Your callback function must return one of the following values::
|
||||
|
||||
CALLBACK_CONTINUE
|
||||
CALLBACK_ABORT
|
||||
CALLBACK_ERROR
|
||||
|
||||
If it returns ``CALLBACK_CONTINUE`` YARA will continue normally,
|
||||
``CALLBACK_ABORT`` will abort the scan but the result from the
|
||||
``yr_rules_scan_XXXX`` function will be ``ERROR_SUCCESS``. On the other hand
|
||||
``CALLBACK_ERROR`` will abort the scanning too, but the result from
|
||||
``yr_rules_scan_XXXX`` will be ``ERROR_CALLBACK_ERROR``.
|
||||
|
||||
|
||||
The ``user_data`` argument passed to your callback function is the same you
|
||||
passed ``yr_rules_scan_XXXX``. This pointer is not touched by YARA, it's just a
|
||||
way for your program to pass arbitrary data to the callback function.
|
||||
|
||||
All ``yr_rules_scan_XXXX`` functions receive a ``flags`` argument and a
|
||||
``timeout`` argument. The only flag defined at this time is
|
||||
``SCAN_FLAGS_FAST_MODE``, so you must pass either this flag or a zero value.
|
||||
The ``timeout`` argument forces the function to return after the specified
|
||||
number of seconds approximately, with a zero meaning no timeout at all.
|
||||
|
||||
The ``SCAN_FLAGS_FAST_MODE`` flag makes the scanning a little faster by avoiding
|
||||
multiple matches of the same string when not necessary. Once the string was
|
||||
found in the file it's subsequently ignored, implying that you'll have a
|
||||
single match for the string, even if it appears multiple times in the scanned
|
||||
data. This flag has the same effect of the ``-f`` command-line option described
|
||||
in :ref:`command-line`.
|
||||
|
||||
|
||||
API reference
|
||||
=============
|
||||
|
||||
Data structures
|
||||
---------------
|
||||
|
||||
.. c:type:: YR_COMPILER
|
||||
|
||||
Data structure representing a YARA compiler.
|
||||
|
||||
.. c:type:: YR_MATCH
|
||||
|
||||
Data structure representing a string match.
|
||||
|
||||
.. c:member:: int64_t base
|
||||
|
||||
Base offset/address for the match. While scanning a file this field is
|
||||
usually zero, while scanning a process memory space this field is the
|
||||
virtual address of the memory block where the match was found.
|
||||
|
||||
.. c:member:: int64_t offset
|
||||
|
||||
Offset of the match relative to *base*.
|
||||
|
||||
.. c:member:: int32_t match_length
|
||||
|
||||
Length of the matching string
|
||||
|
||||
.. c:member:: const uint8_t* data
|
||||
|
||||
Pointer to a buffer containing a portion of the matching string.
|
||||
|
||||
.. c:member:: int32_t data_length
|
||||
|
||||
Length of ``data`` buffer. ``data_length`` is the minimum of
|
||||
``match_length`` and ``MAX_MATCH_DATA``.
|
||||
|
||||
.. versionchanged:: 3.5.0
|
||||
|
||||
.. c:type:: YR_META
|
||||
|
||||
Data structure representing a metadata value.
|
||||
|
||||
.. c:member:: const char* identifier
|
||||
|
||||
Meta identifier.
|
||||
|
||||
.. c:member:: int32_t type
|
||||
|
||||
One of the following metadata types:
|
||||
|
||||
``META_TYPE_NULL``
|
||||
``META_TYPE_INTEGER``
|
||||
``META_TYPE_STRING``
|
||||
``META_TYPE_BOOLEAN``
|
||||
|
||||
.. c:type:: YR_MODULE_IMPORT
|
||||
|
||||
.. c:member:: const char* module_name
|
||||
|
||||
Name of the module being imported.
|
||||
|
||||
.. c:member:: void* module_data
|
||||
|
||||
Pointer to additional data passed to the module. Initially set to
|
||||
``NULL``, your program is responsible for setting this pointer while
|
||||
handling the CALLBACK_MSG_IMPORT_MODULE message.
|
||||
|
||||
.. c:member:: size_t module_data_size
|
||||
|
||||
Size of additional data passed to module. Your program must set the
|
||||
appropriate value if ``module_data`` is modified.
|
||||
|
||||
.. c:type:: YR_RULE
|
||||
|
||||
Data structure representing a single rule.
|
||||
|
||||
.. c:member:: const char* identifier
|
||||
|
||||
Rule identifier.
|
||||
|
||||
.. c:member:: const char* tags
|
||||
|
||||
Pointer to a sequence of null terminated strings with tag names. An
|
||||
additional null character marks the end of the sequence. Example:
|
||||
``tag1\0tag2\0tag3\0\0``. To iterate over the tags you can use
|
||||
:c:func:`yr_rule_tags_foreach`.
|
||||
|
||||
.. c:member:: YR_META* metas
|
||||
|
||||
Pointer to a sequence of :c:type:`YR_META` structures. To iterate over the
|
||||
structures use :c:func:`yr_rule_metas_foreach`.
|
||||
|
||||
.. c:member:: YR_STRING* strings
|
||||
|
||||
Pointer to a sequence of :c:type:`YR_STRING` structures. To iterate over the
|
||||
structures use :c:func:`yr_rule_strings_foreach`.
|
||||
|
||||
.. c:member:: YR_NAMESPACE* ns
|
||||
|
||||
Pointer to a :c:type:`YR_NAMESPACE` structure.
|
||||
|
||||
.. c:type:: YR_RULES
|
||||
|
||||
Data structure representing a set of compiled rules.
|
||||
|
||||
.. c:type:: YR_STREAM
|
||||
|
||||
.. versionadded:: 3.4.0
|
||||
|
||||
Data structure representing a stream used with functions
|
||||
:c:func:`yr_rules_load_stream` and :c:func:`yr_rules_save_stream`.
|
||||
|
||||
.. c:member:: void* user_data
|
||||
|
||||
A user-defined pointer.
|
||||
|
||||
.. c:member:: YR_STREAM_READ_FUNC read
|
||||
|
||||
A pointer to the stream's read function provided by the user.
|
||||
|
||||
.. c:member:: YR_STREAM_WRITE_FUNC write
|
||||
|
||||
A pointer to the stream's write function provided by the user.
|
||||
|
||||
.. c:type:: YR_STRING
|
||||
|
||||
Data structure representing a string declared in a rule.
|
||||
|
||||
.. c:member:: const char* identifier
|
||||
|
||||
String identifier.
|
||||
|
||||
.. c:type:: YR_NAMESPACE
|
||||
|
||||
Data structure representing a rule namespace.
|
||||
|
||||
.. c:member:: const char* name
|
||||
|
||||
Rule namespace.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. c:function:: int yr_initialize(void)
|
||||
|
||||
Initialize the library. Must be called by the main thread before using any
|
||||
other function. Return :c:macro:`ERROR_SUCCESS` on success another error
|
||||
code in case of error. The list of possible return codes vary according
|
||||
to the modules compiled into YARA.
|
||||
|
||||
.. c:function:: int yr_finalize(void)
|
||||
|
||||
Finalize the library. Must be called by the main free to release any
|
||||
resource allocated by the library. Return :c:macro:`ERROR_SUCCESS` on
|
||||
success another error code in case of error. The list of possible return
|
||||
codes vary according to the modules compiled into YARA.
|
||||
|
||||
.. c:function:: void yr_finalize_thread(void)
|
||||
|
||||
Any thread using the library, except the main thread, must call this
|
||||
function when it finishes using the library.
|
||||
|
||||
.. c:function:: int yr_compiler_create(YR_COMPILER** compiler)
|
||||
|
||||
Create a YARA compiler. You must pass the address of a pointer to a
|
||||
:c:type:`YR_COMPILER`, the function will set the pointer to the newly
|
||||
allocated compiler. Returns one of the following error codes:
|
||||
|
||||
:c:macro:`ERROR_SUCCESS`
|
||||
|
||||
:c:macro:`ERROR_INSUFFICIENT_MEMORY`
|
||||
|
||||
.. c:function:: void yr_compiler_destroy(YR_COMPILER* compiler)
|
||||
|
||||
Destroy a YARA compiler.
|
||||
|
||||
.. c:function:: void yr_compiler_set_callback(YR_COMPILER* compiler, YR_COMPILER_CALLBACK_FUNC callback, void* user_data)
|
||||
|
||||
.. versionchanged:: 3.3.0
|
||||
|
||||
Set a callback for receiving error and warning information. The *user_data*
|
||||
pointer is passed to the callback function.
|
||||
|
||||
|
||||
.. c:function:: void yr_compiler_set_include_callback(YR_COMPILER* compiler, YR_COMPILER_INCLUDE_CALLBACK_FUNC callback, YR_COMPILER_INCLUDE_FREE_FUNC include_free, void* user_data)
|
||||
|
||||
.. versionadded:: 3.7.0
|
||||
|
||||
Set a callback to provide rules from a custom source when ``include``
|
||||
directive is invoked. The *user_data* pointer is untouched and passed back to
|
||||
the callback function and to the free function. Once the callback's result
|
||||
is no longer needed, the include_free function will be called. If the memory
|
||||
does not need to be freed, include_free can be set to NULL. If *callback* is
|
||||
set to ``NULL`` support for include directives is disabled.
|
||||
|
||||
|
||||
.. c:function:: int yr_compiler_add_file(YR_COMPILER* compiler, FILE* file, const char* namespace, const char* file_name)
|
||||
|
||||
Compile rules from a *file*. Rules are put into the specified *namespace*,
|
||||
if *namespace* is ``NULL`` they will be put into the default namespace.
|
||||
*file_name* is the name of the file for error reporting purposes and can be
|
||||
set to ``NULL``. Returns the number of errors found during compilation.
|
||||
|
||||
|
||||
.. c:function:: int yr_compiler_add_fd(YR_COMPILER* compiler, YR_FILE_DESCRIPTOR rules_fd, const char* namespace, const char* file_name)
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
Compile rules from a *file descriptor*. Rules are put into the specified *namespace*,
|
||||
if *namespace* is ``NULL`` they will be put into the default namespace.
|
||||
*file_name* is the name of the file for error reporting purposes and can be
|
||||
set to ``NULL``. Returns the number of errors found during compilation.
|
||||
|
||||
|
||||
.. c:function:: int yr_compiler_add_string(YR_COMPILER* compiler, const char* string, const char* namespace_)
|
||||
|
||||
Compile rules from a *string*. Rules are put into the specified *namespace*,
|
||||
if *namespace* is ``NULL`` they will be put into the default namespace.
|
||||
Returns the number of errors found during compilation.
|
||||
|
||||
.. c:function:: int yr_compiler_get_rules(YR_COMPILER* compiler, YR_RULES** rules)
|
||||
|
||||
Get the compiled rules from the compiler. Returns one of the following error
|
||||
codes:
|
||||
|
||||
:c:macro:`ERROR_SUCCESS`
|
||||
|
||||
:c:macro:`ERROR_INSUFFICIENT_MEMORY`
|
||||
|
||||
.. c:function:: int yr_compiler_define_integer_variable(YR_COMPILER* compiler, const char* identifier, int64_t value)
|
||||
|
||||
Defines an integer external variable.
|
||||
|
||||
.. c:function:: int yr_compiler_define_float_variable(YR_COMPILER* compiler, const char* identifier, double value)
|
||||
|
||||
Defines a float external variable.
|
||||
|
||||
.. c:function:: int yr_compiler_define_boolean_variable(YR_COMPILER* compiler, const char* identifier, int value)
|
||||
|
||||
Defines a boolean external variable.
|
||||
|
||||
.. c:function:: int yr_compiler_define_string_variable(YR_COMPILER* compiler, const char* identifier, const char* value)
|
||||
|
||||
Defines a string external variable.
|
||||
|
||||
.. c:function:: void yr_rules_destroy(YR_RULES* rules)
|
||||
|
||||
Destroy compiled rules.
|
||||
|
||||
.. c:function:: int yr_rules_save(YR_RULES* rules, const char* filename)
|
||||
|
||||
Save compiled *rules* into the file specified by *filename*. Only rules
|
||||
obtained from :c:func:`yr_compiler_get_rules` can be saved. Those obtained
|
||||
from :c:func:`yr_rules_load` or :c:func:`yr_rules_load_stream` can not be
|
||||
saved. Returns one of the following error codes:
|
||||
|
||||
:c:macro:`ERROR_SUCCESS`
|
||||
|
||||
:c:macro:`ERROR_COULD_NOT_OPEN_FILE`
|
||||
|
||||
.. c:function:: int yr_rules_save_stream(YR_RULES* rules, YR_STREAM* stream)
|
||||
|
||||
.. versionadded:: 3.4.0
|
||||
|
||||
Save compiled *rules* into *stream*. Only rules obtained from
|
||||
:c:func:`yr_compiler_get_rules` can be saved. Those obtained from
|
||||
:c:func:`yr_rules_load` or :c:func:`yr_rules_load_stream` can not be saved.
|
||||
Returns one of the following error codes:
|
||||
|
||||
:c:macro:`ERROR_SUCCESS`
|
||||
|
||||
.. c:function:: int yr_rules_load(const char* filename, YR_RULES** rules)
|
||||
|
||||
Load compiled rules from the file specified by *filename*. Returns one of the
|
||||
following error codes:
|
||||
|
||||
:c:macro:`ERROR_SUCCESS`
|
||||
|
||||
:c:macro:`ERROR_INSUFFICIENT_MEMORY`
|
||||
|
||||
:c:macro:`ERROR_COULD_NOT_OPEN_FILE`
|
||||
|
||||
:c:macro:`ERROR_INVALID_FILE`
|
||||
|
||||
:c:macro:`ERROR_CORRUPT_FILE`
|
||||
|
||||
:c:macro:`ERROR_UNSUPPORTED_FILE_VERSION`
|
||||
|
||||
.. c:function:: int yr_rules_load_stream(YR_STREAM* stream, YR_RULES** rules)
|
||||
|
||||
.. versionadded:: 3.4.0
|
||||
|
||||
Load compiled rules from *stream*. Rules loaded this way can not be saved
|
||||
back using :c:func:`yr_rules_save_stream`. Returns one of the following error
|
||||
codes:
|
||||
|
||||
:c:macro:`ERROR_SUCCESS`
|
||||
|
||||
:c:macro:`ERROR_INSUFFICIENT_MEMORY`
|
||||
|
||||
:c:macro:`ERROR_INVALID_FILE`
|
||||
|
||||
:c:macro:`ERROR_CORRUPT_FILE`
|
||||
|
||||
:c:macro:`ERROR_UNSUPPORTED_FILE_VERSION`
|
||||
|
||||
.. c:function:: int yr_rules_scan_mem(YR_RULES* rules, const uint8_t* buffer, size_t buffer_size, int flags, YR_CALLBACK_FUNC callback, void* user_data, int timeout)
|
||||
|
||||
Scan a memory buffer. Returns one of the following error codes:
|
||||
|
||||
:c:macro:`ERROR_SUCCESS`
|
||||
|
||||
:c:macro:`ERROR_INSUFFICIENT_MEMORY`
|
||||
|
||||
:c:macro:`ERROR_TOO_MANY_SCAN_THREADS`
|
||||
|
||||
:c:macro:`ERROR_SCAN_TIMEOUT`
|
||||
|
||||
:c:macro:`ERROR_CALLBACK_ERROR`
|
||||
|
||||
:c:macro:`ERROR_TOO_MANY_MATCHES`
|
||||
|
||||
|
||||
.. c:function:: int yr_rules_scan_file(YR_RULES* rules, const char* filename, int flags, YR_CALLBACK_FUNC callback, void* user_data, int timeout)
|
||||
|
||||
Scan a file. Returns one of the following error codes:
|
||||
|
||||
:c:macro:`ERROR_SUCCESS`
|
||||
|
||||
:c:macro:`ERROR_INSUFFICIENT_MEMORY`
|
||||
|
||||
:c:macro:`ERROR_COULD_NOT_MAP_FILE`
|
||||
|
||||
:c:macro:`ERROR_ZERO_LENGTH_FILE`
|
||||
|
||||
:c:macro:`ERROR_TOO_MANY_SCAN_THREADS`
|
||||
|
||||
:c:macro:`ERROR_SCAN_TIMEOUT`
|
||||
|
||||
:c:macro:`ERROR_CALLBACK_ERROR`
|
||||
|
||||
:c:macro:`ERROR_TOO_MANY_MATCHES`
|
||||
|
||||
.. c:function:: int yr_rules_scan_fd(YR_RULES* rules, YR_FILE_DESCRIPTOR fd, int flags, YR_CALLBACK_FUNC callback, void* user_data, int timeout)
|
||||
|
||||
Scan a file descriptor. In POSIX systems ``YR_FILE_DESCRIPTOR`` is an ``int``,
|
||||
as returned by the `open()` function. In Windows ``YR_FILE_DESCRIPTOR`` is a
|
||||
``HANDLE`` as returned by `CreateFile()`.
|
||||
|
||||
|
||||
Returns one of the following error codes:
|
||||
|
||||
:c:macro:`ERROR_SUCCESS`
|
||||
|
||||
:c:macro:`ERROR_INSUFFICIENT_MEMORY`
|
||||
|
||||
:c:macro:`ERROR_COULD_NOT_MAP_FILE`
|
||||
|
||||
:c:macro:`ERROR_ZERO_LENGTH_FILE`
|
||||
|
||||
:c:macro:`ERROR_TOO_MANY_SCAN_THREADS`
|
||||
|
||||
:c:macro:`ERROR_SCAN_TIMEOUT`
|
||||
|
||||
:c:macro:`ERROR_CALLBACK_ERROR`
|
||||
|
||||
:c:macro:`ERROR_TOO_MANY_MATCHES`
|
||||
|
||||
.. c:function:: yr_rule_tags_foreach(rule, tag)
|
||||
|
||||
Iterate over the tags of a given rule running the block of code that follows
|
||||
each time with a different value for *tag* of type ``const char*``. Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
const char* tag;
|
||||
|
||||
/* rule is a YR_RULE object */
|
||||
|
||||
yr_rule_tags_foreach(rule, tag)
|
||||
{
|
||||
..do something with tag
|
||||
}
|
||||
|
||||
.. c:function:: yr_rule_metas_foreach(rule, meta)
|
||||
|
||||
Iterate over the :c:type:`YR_META` structures associated with a given rule
|
||||
running the block of code that follows each time with a different value for
|
||||
*meta*. Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
YR_META* meta;
|
||||
|
||||
/* rule is a YR_RULE object */
|
||||
|
||||
yr_rule_metas_foreach(rule, meta)
|
||||
{
|
||||
..do something with meta
|
||||
}
|
||||
|
||||
.. c:function:: yr_rule_strings_foreach(rule, string)
|
||||
|
||||
Iterate over the :c:type:`YR_STRING` structures associated with a given rule
|
||||
running the block of code that follows each time with a different value for
|
||||
*string*. Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
YR_STRING* string;
|
||||
|
||||
/* rule is a YR_RULE object */
|
||||
|
||||
yr_rule_strings_foreach(rule, string)
|
||||
{
|
||||
..do something with string
|
||||
}
|
||||
|
||||
.. c:function:: yr_string_matches_foreach(string, match)
|
||||
|
||||
Iterate over the :c:type:`YR_MATCH` structures associated with a given string
|
||||
running the block of code that follows each time with a different value for
|
||||
*match*. Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
YR_MATCH* match;
|
||||
|
||||
/* string is a YR_STRING object */
|
||||
|
||||
yr_string_matches_foreach(string, match)
|
||||
{
|
||||
..do something with match
|
||||
}
|
||||
|
||||
.. c:function:: yr_rules_foreach(rules, rule)
|
||||
|
||||
Iterate over each :c:type:`YR_RULE` in a :c:type:`YR_RULES` object running
|
||||
the block of code that follows each time with a different value for
|
||||
*rule*. Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
YR_RULE* rule;
|
||||
|
||||
/* rules is a YR_RULES object */
|
||||
|
||||
yr_rules_foreach(rules, rule)
|
||||
{
|
||||
..do something with rule
|
||||
}
|
||||
|
||||
.. c:function:: yr_rule_disable(rule)
|
||||
|
||||
.. versionadded:: 3.7.0
|
||||
|
||||
Disable the specified rule. Disabled rules are completely ignored during
|
||||
the scanning process and they won't match. If the disabled rule is used in
|
||||
the condition of some other rule the value for the disabled rule is neither
|
||||
true nor false but undefined. For more information about undefined values
|
||||
see :ref:`undefined-values`.
|
||||
|
||||
.. c:function:: yr_rule_enable(rule)
|
||||
|
||||
.. versionadded:: 3.7.0
|
||||
|
||||
Enables the specified rule. After being disabled with :c:func:`yr_rule_disable`
|
||||
a rule can be enabled again by using this function.
|
||||
|
||||
|
||||
Error codes
|
||||
-----------
|
||||
|
||||
.. c:macro:: ERROR_SUCCESS
|
||||
|
||||
Everything went fine.
|
||||
|
||||
.. c:macro:: ERROR_INSUFFICIENT_MEMORY
|
||||
|
||||
Insufficient memory to complete the operation.
|
||||
|
||||
.. c:macro:: ERROR_COULD_NOT_OPEN_FILE
|
||||
|
||||
File could not be opened.
|
||||
|
||||
.. c:macro:: ERROR_COULD_NOT_MAP_FILE
|
||||
|
||||
File could not be mapped into memory.
|
||||
|
||||
.. c:macro:: ERROR_ZERO_LENGTH_FILE
|
||||
|
||||
File length is zero.
|
||||
|
||||
.. c:macro:: ERROR_INVALID_FILE
|
||||
|
||||
File is not a valid rules file.
|
||||
|
||||
.. c:macro:: ERROR_CORRUPT_FILE
|
||||
|
||||
Rules file is corrupt.
|
||||
|
||||
.. c:macro:: ERROR_UNSUPPORTED_FILE_VERSION
|
||||
|
||||
File was generated by a different YARA and can't be loaded by this version.
|
||||
|
||||
.. c:macro:: ERROR_TOO_MANY_SCAN_THREADS
|
||||
|
||||
Too many threads trying to use the same :c:type:`YR_RULES` object
|
||||
simultaneously. The limit is defined by ``MAX_THREADS`` in
|
||||
*./include/yara/limits.h*
|
||||
|
||||
.. c:macro:: ERROR_SCAN_TIMEOUT
|
||||
|
||||
Scan timed out.
|
||||
|
||||
.. c:macro:: ERROR_CALLBACK_ERROR
|
||||
|
||||
Callback returned an error.
|
||||
|
||||
.. c:macro:: ERROR_TOO_MANY_MATCHES
|
||||
|
||||
Too many matches for some string in your rules. This usually happens when
|
||||
your rules contains very short or very common strings like ``01 02`` or
|
||||
``FF FF FF FF``. The limit is defined by ``MAX_STRING_MATCHES`` in
|
||||
*./include/yara/limits.h*
|
||||
@@ -0,0 +1,166 @@
|
||||
.. _command-line:
|
||||
|
||||
**********************************
|
||||
Running YARA from the command-line
|
||||
**********************************
|
||||
|
||||
In order to invoke YARA you’ll need two things: a file with the rules you want
|
||||
to use (either in source code or compiled form) and the target to be scanned.
|
||||
The target can be a file, a folder, or a process. ::
|
||||
|
||||
yara [OPTIONS] RULES_FILE TARGET
|
||||
|
||||
|
||||
``RULES_FILE`` can be passed directly in source code form, or can be previously
|
||||
compiled with the ``yarac`` tool. You may prefer to use your rules in compiled
|
||||
form if you are going to invoke YARA multiple times with the same rules. This
|
||||
way you’ll save time, because for YARA it is faster to load compiled rules than
|
||||
compiling the same rules over and over again.
|
||||
|
||||
You can also pass multiple source files to `yara` like in the following example::
|
||||
|
||||
yara [OPTIONS] RULES_FILE_1 RULES_FILE_2 RULES_FILE_3 TARGET
|
||||
|
||||
Notice however that this only works for rules in source form. When invoking YARA
|
||||
with compiled rules a single file is accepted.
|
||||
|
||||
In the example above all rules share the same "default" namespace, which means
|
||||
that rule identifiers must be unique among all files. However you can specify a
|
||||
namespace for individual files. For example ::
|
||||
|
||||
yara [OPTIONS] namespace1:RULES_FILE_1 RULES_FILE_2 RULES_FILE_3 TARGET
|
||||
|
||||
In this case ``RULE_FILE_1`` uses ``namespace1`` while ``RULES_FILE_2`` and
|
||||
``RULES_FILE_3`` share the default namespace.
|
||||
|
||||
In all cases rules will be applied to the target specified as the last argument
|
||||
to YARA, if it’s a path to a directory all the files contained in it will be
|
||||
scanned. By default YARA does not attempt to scan directories recursively, but
|
||||
you can use the ``-r`` option for that.
|
||||
|
||||
Available options are:
|
||||
|
||||
.. program:: yara
|
||||
|
||||
.. option:: -t <tag> --tag=<tag>
|
||||
|
||||
Print rules tagged as <tag> and ignore the rest.
|
||||
|
||||
.. option:: -i <identifier> --identifier=<identifier>
|
||||
|
||||
Print rules named <identifier> and ignore the rest.
|
||||
|
||||
.. option:: -c --count
|
||||
|
||||
Print only number of matches.
|
||||
|
||||
.. option:: -n
|
||||
|
||||
Print not satisfied rules only (negate).
|
||||
|
||||
.. option:: -D --print-module-data
|
||||
|
||||
Print module data.
|
||||
|
||||
.. option:: -g --print-tags
|
||||
|
||||
Print tags.
|
||||
|
||||
.. option:: -m --print-meta
|
||||
|
||||
Print metadata.
|
||||
|
||||
.. option:: -s --print-strings
|
||||
|
||||
Print matching strings.
|
||||
|
||||
.. option:: -L --print-string-length
|
||||
|
||||
Print length of matching strings.
|
||||
|
||||
.. option:: -e --print-namespace
|
||||
|
||||
Print rules' namespace.
|
||||
|
||||
.. option:: -p <number> --threads=<number>
|
||||
|
||||
Use the specified <number> of threads to scan a directory.
|
||||
|
||||
.. option:: -l <number> --max-rules=<number>
|
||||
|
||||
Abort scanning after matching a number of rules.
|
||||
|
||||
.. option:: -a <seconds> --timeout=<seconds>
|
||||
|
||||
Abort scanning after a number of seconds has elapsed.
|
||||
|
||||
.. option:: -k <slots> --stack-size=<slots>
|
||||
|
||||
Allocate a stack size of "slots" number of slots. Default: 16384. This
|
||||
will allow you to use larger rules, albeit with more memory overhead.
|
||||
|
||||
.. versionadded:: 3.5.0
|
||||
|
||||
.. option:: --max-strings-per-rule=<number>
|
||||
|
||||
Set maximum number of strings per rule (default=10000). If a rule has more
|
||||
then the specified number of strings an error will occur.
|
||||
|
||||
.. versionadded:: 3.7.0
|
||||
|
||||
.. option:: -d <identifier>=<value>
|
||||
|
||||
Define external variable.
|
||||
|
||||
.. option:: -x <module>=<file>
|
||||
|
||||
Pass file's content as extra data to module.
|
||||
|
||||
.. option:: -r --recursive
|
||||
|
||||
Recursively search for directories.
|
||||
|
||||
.. option:: -f --fast-scan
|
||||
|
||||
Fast matching mode.
|
||||
|
||||
.. option:: -w --no-warnings
|
||||
|
||||
Disable warnings.
|
||||
|
||||
.. option:: --fail-on-warnings
|
||||
|
||||
Treat warnings as errors. Has no effect if used with --no-warnings.
|
||||
|
||||
.. option:: -v --version
|
||||
|
||||
Show version information.
|
||||
|
||||
.. option:: -h --help
|
||||
|
||||
Show help.
|
||||
|
||||
Here you have some examples:
|
||||
|
||||
* Apply rule in */foo/bar/rules* to all files in the current directory.
|
||||
Subdirectories are not scanned::
|
||||
|
||||
yara /foo/bar/rules .
|
||||
|
||||
* Apply rules in */foo/bar/rules* to *bazfile*. Only reports rules tagged as
|
||||
*Packer* or *Compiler*::
|
||||
|
||||
yara -t Packer -t Compiler /foo/bar/rules bazfile
|
||||
|
||||
* Scan all files in the */foo* directory and its subdirectories::
|
||||
|
||||
yara -r /foo
|
||||
|
||||
* Defines three external variables *mybool*, *myint* and *mystring*::
|
||||
|
||||
yara -d mybool=true -d myint=5 -d mystring="my string" /foo/bar/rules bazfile
|
||||
|
||||
* Apply rules in */foo/bar/rules* to *bazfile* while passing the content of
|
||||
*cuckoo_json_report* to the cuckoo module::
|
||||
|
||||
yara -x cuckoo=cuckoo_json_report /foo/bar/rules bazfile
|
||||
@@ -0,0 +1,267 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# yara documentation build configuration file, created by
|
||||
# sphinx-quickstart on Tue Jul 8 11:04:03 2014.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = []
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'yara'
|
||||
copyright = u'2014-2017, VirusTotal'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '3.7'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '3.7.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
|
||||
try:
|
||||
import sphinx_rtd_theme
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
||||
except:
|
||||
html_theme = "default"
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'yaradoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'yara.tex', u'yara Documentation',
|
||||
u'Victor M. Alvarez', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'yara', u'yara Documentation',
|
||||
[u'Victor M. Alvarez'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'yara', u'yara Documentation',
|
||||
u'Victor M. Alvarez', 'yara', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
@@ -0,0 +1,140 @@
|
||||
***************
|
||||
Getting started
|
||||
***************
|
||||
|
||||
YARA is a multi-platform program running on Windows, Linux and Mac OS X. You can
|
||||
find the latest release at https://github.com/VirusTotal/yara/releases.
|
||||
|
||||
.. _compiling-yara:
|
||||
|
||||
Compiling and installing YARA
|
||||
=============================
|
||||
|
||||
Download the source tarball and get prepared for compiling it::
|
||||
|
||||
tar -zxf yara-3.7.0.tar.gz
|
||||
cd yara-3.7.0
|
||||
./bootstrap.sh
|
||||
|
||||
Make sure you have ``automake``, ``libtool``, ``make`` and ``gcc`` installed
|
||||
in your system. Ubuntu and Debian users can use::
|
||||
|
||||
sudo apt-get install automake libtool make gcc
|
||||
|
||||
If you plan to modify YARA's source code you may also need ``flex`` and
|
||||
``bison`` for generating lexers and parsers::
|
||||
|
||||
sudo apt-get install flex bison
|
||||
|
||||
Compile and install YARA in the standard way::
|
||||
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
|
||||
Run the test cases to make sure that everything is fine::
|
||||
|
||||
make check
|
||||
|
||||
Some of YARA's features depend on the OpenSSL library. Those features are
|
||||
enabled only if you have the OpenSSL library installed in your system. If not,
|
||||
YARA is going to work fine but you won't be able to use the disabled features.
|
||||
The ``configure`` script will automatically detect if OpenSSL is installed or
|
||||
not. If you want to enforce the OpenSSL-dependent features you must pass
|
||||
``--with-crypto`` to the ``configure`` script. Ubuntu and Debian users can use
|
||||
``sudo apt-get install libssl-dev`` to install the OpenSSL library.
|
||||
|
||||
The following modules are not compiled into YARA by default:
|
||||
|
||||
* cuckoo
|
||||
* magic
|
||||
* dotnet
|
||||
|
||||
If you plan to use them you must pass the corresponding ``--enable-<module
|
||||
name>`` arguments to the ``configure`` script.
|
||||
|
||||
For example::
|
||||
|
||||
./configure --enable-cuckoo
|
||||
./configure --enable-magic
|
||||
./configure --enable-dotnet
|
||||
./configure --enable-cuckoo --enable-magic --enable-dotnet
|
||||
|
||||
Modules usually depend on external libraries, depending on the modules you
|
||||
choose to install you'll need the following libraries:
|
||||
|
||||
* cuckoo:
|
||||
Depends on `Jansson <http://www.digip.org/jansson/>`_ for parsing JSON.
|
||||
Some Ubuntu and Debian versions already include a package named
|
||||
``libjansson-dev``, if ``sudo apt-get install libjansson-dev`` doesn't
|
||||
work for you then get the source code from
|
||||
`its repository <https://github.com/akheron/jansson>`_.
|
||||
|
||||
|
||||
* magic:
|
||||
Depends on *libmagic*, a library used by the Unix standard program
|
||||
`file <http://en.wikipedia.org/wiki/File_(command)>`_.
|
||||
Ubuntu, Debian and CentOS include a package
|
||||
``libmagic-dev``. The source code can be found
|
||||
`here <ftp://ftp.astron.com/pub/file/>`_.
|
||||
|
||||
|
||||
Installing on Windows
|
||||
---------------------
|
||||
|
||||
Compiled binaries for Windows in both 32 and 64 bit flavors can be found in the
|
||||
link below. Just download the version you want, unzip the archive, and put the
|
||||
``yara.exe`` and ``yarac.exe`` binaries anywhere in your disk.
|
||||
|
||||
To install the ``yara-python`` extension download and execute the installer
|
||||
corresponding to the version of Python you're using.
|
||||
|
||||
`Download Windows binaries <https://www.dropbox.com/sh/umip8ndplytwzj1/AADdLRsrpJL1CM1vPVAxc5JZa?dl=0>`_
|
||||
|
||||
|
||||
Installing on Mac OS X with Homebrew
|
||||
------------------------------------
|
||||
|
||||
To install YARA using `Homebrew <https://brew.sh>`_, simply type
|
||||
``brew install yara``.
|
||||
|
||||
|
||||
Installing yara-python
|
||||
----------------------
|
||||
|
||||
If you plan to use YARA from your Python scripts you need to install the
|
||||
``yara-python`` extension. Please refer to https://github.com/VirusTotal/yara-python
|
||||
for instructions on how to install it.
|
||||
|
||||
|
||||
Running YARA for the first time
|
||||
===============================
|
||||
|
||||
Now that you have installed YARA you can write a very simple rule and use the
|
||||
command-line tool to scan some file::
|
||||
|
||||
echo "rule dummy { condition: true }" > my_first_rule
|
||||
yara my_first_rule my_first_rule
|
||||
|
||||
Don't get confused by the repeated ``my_first_rule`` in the arguments to
|
||||
``yara``, I'm just passing the same file as both the rules and the file to
|
||||
be scanned. You can pass any file you want to be scanned (second argument).
|
||||
|
||||
If everything goes fine you should get the following output::
|
||||
|
||||
dummy my_first_rule
|
||||
|
||||
Which means that the file ``my_first_rule`` is matching the rule named ``dummy``.
|
||||
|
||||
If you get an error like this::
|
||||
|
||||
yara: error while loading shared libraries: libyara.so.2: cannot open shared
|
||||
object file: No such file or directory
|
||||
|
||||
It means that the loader is not finding the ``libyara`` library which is
|
||||
located in ``/usr/local/lib``. In some Linux flavors the loader doesn't look for
|
||||
libraries in this path by default, we must instruct it to do so by adding
|
||||
``/usr/local/lib`` to the loader configuration file ``/etc/ld.so.conf``::
|
||||
|
||||
sudo echo "/usr/local/lib" >> /etc/ld.so.conf
|
||||
sudo ldconfig
|
||||
@@ -0,0 +1,45 @@
|
||||
.. yara documentation master file, created by
|
||||
sphinx-quickstart on Tue Jul 8 11:04:03 2014.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to YARA's documentation!
|
||||
================================
|
||||
|
||||
YARA is a tool aimed at (but not limited to) helping malware researchers to
|
||||
identify and classify malware samples. With YARA you can create descriptions of malware families (or whatever you want to describe) based on textual or binary patterns. Each description, a.k.a rule, consists of a set of strings and a
|
||||
boolean expression which determine its logic. Let's see an example::
|
||||
|
||||
rule silent_banker : banker
|
||||
{
|
||||
meta:
|
||||
description = "This is just an example"
|
||||
thread_level = 3
|
||||
in_the_wild = true
|
||||
strings:
|
||||
$a = {6A 40 68 00 30 00 00 6A 14 8D 91}
|
||||
$b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9}
|
||||
$c = "UVODFRYSIHLNWPEJXQZAKCBGMT"
|
||||
condition:
|
||||
$a or $b or $c
|
||||
}
|
||||
|
||||
The above rule is telling YARA that any file containing one of the three strings
|
||||
must be reported as silent_banker. This is just a simple example, more complex
|
||||
and powerful rules can be created by using wild-cards, case-insensitive strings, regular expressions, special operators and many other features that you'll find explained in this documentation.
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
gettingstarted
|
||||
writingrules
|
||||
modules
|
||||
writingmodules
|
||||
commandline
|
||||
yarapython
|
||||
capi
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=_build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. xml to make Docutils-native XML files
|
||||
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
%SPHINXBUILD% 2> nul
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\yara.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\yara.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdf" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf
|
||||
cd %BUILDDIR%/..
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdfja" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf-ja
|
||||
cd %BUILDDIR%/..
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "xml" (
|
||||
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pseudoxml" (
|
||||
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
@@ -0,0 +1,25 @@
|
||||
*******
|
||||
Modules
|
||||
*******
|
||||
|
||||
Modules are the method YARA provides for extending its features. They allow you
|
||||
to define data structures and functions which can be used in your rules to
|
||||
express more complex conditions. Here you'll find described some modules
|
||||
officially distributed with YARA, but you can also learn how to write your own
|
||||
modules in the :ref:`writing-modules` section.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
PE <modules/pe>
|
||||
ELF <modules/elf>
|
||||
Cuckoo <modules/cuckoo>
|
||||
Magic <modules/magic>
|
||||
Hash <modules/hash>
|
||||
Math <modules/math>
|
||||
Dotnet <modules/dotnet>
|
||||
Time <modules/time>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
.. _cuckoo-module:
|
||||
|
||||
#############
|
||||
Cuckoo module
|
||||
#############
|
||||
|
||||
The Cuckoo module enables you to create YARA rules based on behavioral
|
||||
information generated by `Cuckoo sandbox <https://www.cuckoosandbox.org/>`_.
|
||||
While scanning a PE file with YARA, you can pass additional information about
|
||||
its behavior to the ``cuckoo`` module and create rules based not only on what
|
||||
it *contains*, but also on what it *does*.
|
||||
|
||||
.. important::
|
||||
This module is not built into YARA by default, to learn how to include it
|
||||
refer to :ref:`compiling-yara`. Good news for Windows users: this module
|
||||
is already included in the official Windows binaries.
|
||||
|
||||
Suppose that you're interested in executable files sending a HTTP request to
|
||||
http://someone.doingevil.com. In previous versions of YARA you had to settle
|
||||
with::
|
||||
|
||||
rule evil_doer
|
||||
{
|
||||
strings:
|
||||
$evil_domain = "http://someone.doingevil.com"
|
||||
|
||||
condition:
|
||||
$evil_domain
|
||||
}
|
||||
|
||||
|
||||
The problem with this rule is that the domain name could be contained in the
|
||||
file for perfectly valid reasons not related with sending HTTP requests to
|
||||
http://someone.doingevil.com. Furthermore, the malicious executable could
|
||||
contain the domain name ciphered or obfuscated, in which case your rule
|
||||
would be completely useless.
|
||||
|
||||
But now with the ``cuckoo`` module you can take the behavior report generated
|
||||
for the executable file by your Cuckoo sandbox, pass it alongside the
|
||||
executable file to YARA, and write a rule like this::
|
||||
|
||||
import "cuckoo"
|
||||
|
||||
rule evil_doer
|
||||
{
|
||||
condition:
|
||||
cuckoo.network.http_request(/http:\/\/someone\.doingevil\.com/)
|
||||
}
|
||||
|
||||
Of course you can mix your behavior-related conditions with good old
|
||||
string-based conditions::
|
||||
|
||||
import "cuckoo"
|
||||
|
||||
rule evil_doer
|
||||
{
|
||||
strings:
|
||||
$some_string = { 01 02 03 04 05 06 }
|
||||
|
||||
condition:
|
||||
$some_string and
|
||||
cuckoo.network.http_request(/http:\/\/someone\.doingevil\.com/)
|
||||
}
|
||||
|
||||
|
||||
But how do we pass the behavior information to the ``cuckoo`` module? Well, in
|
||||
the case of the command-line tool you must use the ``-x`` option in this way::
|
||||
|
||||
$yara -x cuckoo=behavior_report_file rules_file pe_file
|
||||
|
||||
|
||||
``behavior_report_file`` is the path to a file containing the behavior file
|
||||
generated by the Cuckoo sandbox in JSON format.
|
||||
|
||||
If you are using ``yara-python`` then you must pass the behavior report in the
|
||||
``modules_data`` argument for the ``match`` method:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import yara
|
||||
rules = yara.compile('./rules_file')
|
||||
report_file = open('./behavior_report_file')
|
||||
report_data = report_file.read()
|
||||
rules.match(pe_file, modules_data={'cuckoo': bytes(report_data)})
|
||||
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. default-domain:: c
|
||||
|
||||
.. type:: network
|
||||
|
||||
.. function:: http_request(regexp)
|
||||
|
||||
Function returning true if the program sent a HTTP request to a URL
|
||||
matching the provided regular expression.
|
||||
|
||||
*Example: cuckoo.network.http_request(/evil\\.com/)*
|
||||
|
||||
.. function:: http_get(regexp)
|
||||
|
||||
Similar to :func:`http_request`, but only takes into account GET
|
||||
requests.
|
||||
|
||||
.. function:: http_post(regexp)
|
||||
|
||||
Similar to :func:`http_request`, but only takes into account POST
|
||||
requests.
|
||||
|
||||
.. function:: dns_lookup(regexp)
|
||||
|
||||
Function returning true if the program sent a domain name resolution
|
||||
request for a domain matching the provided regular expression.
|
||||
|
||||
*Example: cuckoo.network.dns_lookup(/evil\\.com/)*
|
||||
|
||||
.. type:: registry
|
||||
|
||||
.. function:: key_access(regexp)
|
||||
|
||||
Function returning true if the program accessed a registry entry
|
||||
matching the provided regular expression.
|
||||
|
||||
*Example: cuckoo.registry.key_access(/\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run/)*
|
||||
|
||||
.. type:: filesystem
|
||||
|
||||
.. function:: file_access(regexp)
|
||||
|
||||
Function returning true if the program accessed a file matching the
|
||||
provided regular expression.
|
||||
|
||||
*Example: cuckoo.filesystem.file_access(/autoexec\\.bat/)*
|
||||
|
||||
.. type:: sync
|
||||
|
||||
.. function:: mutex(regexp)
|
||||
|
||||
Function returning true if the program opens or creates a mutex matching
|
||||
the provided regular expression.
|
||||
|
||||
*Example: cuckoo.sync.mutex(/EvilMutexName/)*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
|
||||
.. _dotnet-module:
|
||||
|
||||
#############
|
||||
dotnet module
|
||||
#############
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
The dotnet module allows you to create more fine-grained rules for .NET files by
|
||||
using attributes and features of the .NET file format. Let's see some examples::
|
||||
|
||||
import "dotnet"
|
||||
|
||||
rule not_exactly_five_streams
|
||||
{
|
||||
condition:
|
||||
dotnet.number_of_streams != 5
|
||||
}
|
||||
|
||||
rule blop_stream
|
||||
{
|
||||
condition:
|
||||
for any i in (0..dotnet.number_of_streams - 1):
|
||||
(dotnet.streams[i].name == "#Blop")
|
||||
}
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. c:type:: version
|
||||
|
||||
The version string contained in the metadata root.
|
||||
|
||||
*Example: dotnet.version == "v2.0.50727"*
|
||||
|
||||
.. c:type:: module_name
|
||||
|
||||
The name of the module.
|
||||
|
||||
*Example: dotnet.module_name == "axs"*
|
||||
|
||||
.. c:type:: number_of_streams
|
||||
|
||||
The number of streams in the file.
|
||||
|
||||
.. c:type:: streams
|
||||
|
||||
A zero-based array of stream objects, one for each stream contained in the
|
||||
file. Individual streams can be accessed by using the [] operator. Each
|
||||
stream object has the following attributes:
|
||||
|
||||
.. c:member:: name
|
||||
|
||||
Stream name.
|
||||
|
||||
.. c:member:: offset
|
||||
|
||||
Stream offset.
|
||||
|
||||
.. c:member:: size
|
||||
|
||||
Stream size.
|
||||
|
||||
*Example: dotnet.streams[0].name == "#~"*
|
||||
|
||||
.. c:type:: number_of_guids
|
||||
|
||||
The number of GUIDs in the guids array.
|
||||
|
||||
.. c:type:: guids
|
||||
|
||||
A zero-based array of strings, one for each GUID. Individual guids can be
|
||||
accessed by using the [] operator.
|
||||
|
||||
*Example: dotnet.guids[0] == "99c08ffd-f378-a891-10ab-c02fe11be6ef"*
|
||||
|
||||
.. c:type:: number_of_resources
|
||||
|
||||
The number of resources in the .NET file. These are different from normal PE
|
||||
resources.
|
||||
|
||||
.. c:type:: resources
|
||||
|
||||
A zero-based array of resource objects, one for each resource the .NET file
|
||||
has. Individual resources can be accessed by using the [] operator. Each
|
||||
resource object has the following attributes:
|
||||
|
||||
.. c:member:: offset
|
||||
|
||||
Offset for the resource data.
|
||||
|
||||
.. c:member:: length
|
||||
|
||||
Length of the resource data.
|
||||
|
||||
.. c:member:: name
|
||||
|
||||
Name of the resource (string).
|
||||
|
||||
*Example: uint16be(dotnet.resources[0].offset) == 0x4d5a*
|
||||
|
||||
.. c:type:: assembly
|
||||
|
||||
Object for .NET assembly information.
|
||||
|
||||
.. c:member:: version
|
||||
|
||||
An object with integer values representing version information for this
|
||||
assembly. Attributes are:
|
||||
|
||||
``major``
|
||||
``minor``
|
||||
``build_number``
|
||||
``revision_number``
|
||||
|
||||
.. c:member:: name
|
||||
|
||||
String containing the assembly name.
|
||||
|
||||
.. c:member:: culture
|
||||
|
||||
String containing the culture (language/country/region) for this
|
||||
assembly.
|
||||
|
||||
*Example: dotnet.assembly.name == "Keylogger"*
|
||||
|
||||
*Example: dotnet.assembly.version.major == 7 and dotnet.assembly.version.minor == 0*
|
||||
|
||||
.. c:type:: number_of_modulerefs
|
||||
|
||||
The number of module references in the .NET file.
|
||||
|
||||
.. c:type:: modulerefs
|
||||
|
||||
A zero-based array of strings, one for each module reference the .NET file
|
||||
has. Individual module references can be accessed by using the []
|
||||
operator.
|
||||
|
||||
*Example: dotnet.modulerefs[0] == "kernel32"*
|
||||
|
||||
.. c:type:: typelib
|
||||
|
||||
The typelib of the file.
|
||||
|
||||
.. c:type:: assembly_refs
|
||||
|
||||
Object for .NET assembly reference information.
|
||||
|
||||
.. c:member:: version
|
||||
|
||||
An object with integer values representing version information for this
|
||||
assembly. Attributes are:
|
||||
|
||||
``major``
|
||||
``minor``
|
||||
``build_number``
|
||||
``revision_number``
|
||||
|
||||
.. c:member:: name
|
||||
|
||||
String containing the assembly name.
|
||||
|
||||
.. c:member:: public_key_or_token
|
||||
|
||||
String containing the public key or token which identifies the author of
|
||||
this assembly.
|
||||
|
||||
.. c:type:: number_of_user_strings
|
||||
|
||||
The number of user strings in the file.
|
||||
|
||||
.. c:type:: user_strings
|
||||
|
||||
An zero-based array of user strings, one for each stream contained in the
|
||||
file. Individual strings can be accessed by using the [] operator.
|
||||
@@ -0,0 +1,377 @@
|
||||
|
||||
.. _elf-module:
|
||||
|
||||
##########
|
||||
ELF module
|
||||
##########
|
||||
|
||||
.. versionadded:: 3.2.0
|
||||
|
||||
The ELF module is very similar to the :ref:`pe-module`, but for ELF files. This
|
||||
module exposes most of the fields present in an ELF header. Let's see some
|
||||
examples::
|
||||
|
||||
import "elf"
|
||||
|
||||
rule single_section
|
||||
{
|
||||
condition:
|
||||
elf.number_of_sections == 1
|
||||
}
|
||||
|
||||
rule elf_64
|
||||
{
|
||||
condition:
|
||||
elf.machine == elf.EM_X86_64
|
||||
}
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. c:type:: type
|
||||
|
||||
Integer with one of the following values:
|
||||
|
||||
.. c:type:: ET_NONE
|
||||
|
||||
No file type.
|
||||
|
||||
.. c:type:: ET_REL
|
||||
|
||||
Relocatable file.
|
||||
|
||||
.. c:type:: ET_EXEC
|
||||
|
||||
Executable file.
|
||||
|
||||
.. c:type:: ET_DYN
|
||||
|
||||
Shared object file.
|
||||
|
||||
.. c:type:: ET_CORE
|
||||
|
||||
Core file.
|
||||
|
||||
*Example: elf.type == elf.ET_EXEC*
|
||||
|
||||
.. c:type:: machine
|
||||
|
||||
Integer with one of the following values:
|
||||
|
||||
.. c:type:: EM_M32
|
||||
.. c:type:: EM_SPARC
|
||||
.. c:type:: EM_386
|
||||
.. c:type:: EM_68K
|
||||
.. c:type:: EM_88K
|
||||
.. c:type:: EM_860
|
||||
.. c:type:: EM_MIPS
|
||||
.. c:type:: EM_MIPS_RS3_LE
|
||||
.. c:type:: EM_PPC
|
||||
.. c:type:: EM_PPC64
|
||||
.. c:type:: EM_ARM
|
||||
.. c:type:: EM_X86_64
|
||||
.. c:type:: EM_AARCH64
|
||||
|
||||
*Example: elf.machine == elf.EM_X86_64*
|
||||
|
||||
.. c:type:: entry_point
|
||||
|
||||
Entry point raw offset or virtual address depending on whether YARA is
|
||||
scanning a file or process memory respectively. This is equivalent to the
|
||||
deprecated ``entrypoint`` keyword.
|
||||
|
||||
.. c:type:: number_of_sections
|
||||
|
||||
Number of sections in the ELF file.
|
||||
|
||||
.. c:type:: sections
|
||||
|
||||
A zero-based array of section objects, one for each section the ELF has.
|
||||
Individual sections can be accessed by using the [] operator. Each section
|
||||
object has the following attributes:
|
||||
|
||||
.. c:member:: name
|
||||
|
||||
Section's name.
|
||||
|
||||
*Example: elf.sections[3].name == ".bss"*
|
||||
|
||||
.. c:member:: size
|
||||
|
||||
Section's size in bytes. Unless the section type is SHT_NOBITS, the
|
||||
section occupies sh_size bytes in the file. A section of
|
||||
:c:type:`SHT_NOBITS` may have a non-zero size, but it occupies no space
|
||||
in the file.
|
||||
|
||||
.. c:member:: offset
|
||||
|
||||
Offset from the beginning of the file to the first byte in the section.
|
||||
One section type, :c:type:`SHT_NOBITS` described below, occupies no
|
||||
space in the file, and its :c:member:`offset` member locates the
|
||||
conceptual placement in the file.
|
||||
|
||||
.. c:member:: type
|
||||
|
||||
Integer with one of the following values:
|
||||
|
||||
.. c:type:: SHT_NULL
|
||||
|
||||
This value marks the section as inactive; it does not have
|
||||
an associated section. Other members of the section header have
|
||||
undefined values.
|
||||
|
||||
.. c:type:: SHT_PROGBITS
|
||||
|
||||
The section holds information defined by the program, whose format
|
||||
and meaning are determined solely by the program.
|
||||
|
||||
.. c:type:: SHT_SYMTAB
|
||||
|
||||
The section holds a symbol table.
|
||||
|
||||
.. c:type:: SHT_STRTAB
|
||||
|
||||
The section holds a string table. An object file may have multiple
|
||||
string table sections.
|
||||
|
||||
.. c:type:: SHT_RELA
|
||||
|
||||
The section holds relocation entries.
|
||||
|
||||
.. c:type:: SHT_HASH
|
||||
|
||||
The section holds a symbol hash table.
|
||||
|
||||
.. c:type:: SHT_DYNAMIC
|
||||
|
||||
The section holds information for dynamic linking.
|
||||
|
||||
.. c:type:: SHT_NOTE
|
||||
|
||||
The section holds information that marks the file in some way.
|
||||
|
||||
.. c:type:: SHT_NOBITS
|
||||
|
||||
A section of this type occupies no space in the file but otherwise resembles :c:type:`SHT_PROGBITS`.
|
||||
|
||||
.. c:type:: SHT_REL
|
||||
|
||||
The section holds relocation entries.
|
||||
|
||||
.. c:type:: SHT_SHLIB
|
||||
|
||||
This section type is reserved but has unspecified semantics.
|
||||
|
||||
.. c:type:: SHT_DYNSYM
|
||||
|
||||
This section holds dynamic linking symbols.
|
||||
|
||||
.. c:member:: flags
|
||||
|
||||
Integer with section's flags as defined below:
|
||||
|
||||
.. c:type:: SHF_WRITE
|
||||
|
||||
The section contains data that should be writable during process
|
||||
execution.
|
||||
|
||||
.. c:type:: SHF_ALLOC
|
||||
|
||||
The section occupies memory during process execution. Some control sections do not reside in the memory image of an object file; this attribute is off for those sections.
|
||||
|
||||
.. c:type:: SHF_EXECINSTR
|
||||
|
||||
The section contains executable machine instructions.
|
||||
|
||||
*Example: elf.sections[2].flags & elf.SHF_WRITE*
|
||||
|
||||
.. c:member:: address
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
The virtual address the section starts at.
|
||||
|
||||
|
||||
.. c:type:: number_of_segments
|
||||
|
||||
.. versionadded:: 3.4.0
|
||||
|
||||
Number of segments in the ELF file.
|
||||
|
||||
.. c:type:: segments
|
||||
|
||||
.. versionadded:: 3.4.0
|
||||
|
||||
A zero-based array of segment objects, one for each segment the ELF has.
|
||||
Individual segments can be accessed by using the [] operator. Each segment
|
||||
object has the following attributes:
|
||||
|
||||
.. c:member:: alignment
|
||||
|
||||
Value to which the segments are aligned in memory and in the file.
|
||||
|
||||
.. c:member:: file_size
|
||||
|
||||
Number of bytes in the file image of the segment. It may be zero.
|
||||
|
||||
.. c:member:: flags
|
||||
|
||||
A combination of the following segment flags:
|
||||
|
||||
.. c:type:: PF_R
|
||||
|
||||
The segment is readable.
|
||||
|
||||
.. c:type:: PF_W
|
||||
|
||||
The segment is writable.
|
||||
|
||||
.. c:type:: PF_X
|
||||
|
||||
The segment is executable.
|
||||
|
||||
.. c:member:: memory_size
|
||||
|
||||
In-memory segment size.
|
||||
|
||||
.. c:member:: offset
|
||||
|
||||
Offset from the beginning of the file where the segment resides.
|
||||
|
||||
.. c:member:: physical_address
|
||||
|
||||
On systems for which physical addressing is relevant, contains the
|
||||
segment's physical address.
|
||||
|
||||
.. c:member:: type
|
||||
|
||||
Type of segment indicated by one of the following values:
|
||||
|
||||
.. c:type:: PT_NULL
|
||||
.. c:type:: PT_LOAD
|
||||
.. c:type:: PT_DYNAMIC
|
||||
.. c:type:: PT_INTERP
|
||||
.. c:type:: PT_NOTE
|
||||
.. c:type:: PT_SHLIB
|
||||
.. c:type:: PT_PHDR
|
||||
.. c:type:: PT_LOPROC
|
||||
.. c:type:: PT_HIPROC
|
||||
.. c:type:: PT_GNU_STACK
|
||||
|
||||
.. c:member:: virtual_address
|
||||
|
||||
Virtual address at which the segment resides in memory.
|
||||
|
||||
.. c:type:: dynamic_section_entries
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
Number of entries in the dynamic section in the ELF file.
|
||||
|
||||
.. c:type:: dynamic
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
A zero-based array of dynamic objects, one for each entry in found in the
|
||||
ELF's dynamic section. Individual dynamic objects can be accessed by using
|
||||
the [] operator. Each dynamic object has the following attributes:
|
||||
|
||||
.. c:member:: type
|
||||
|
||||
Value that describes the type of dynamic section. Builtin values are:
|
||||
|
||||
.. c:type:: DT_NULL
|
||||
.. c:type:: DT_NEEDED
|
||||
.. c:type:: DT_PLTRELSZ
|
||||
.. c:type:: DT_PLTGOT
|
||||
.. c:type:: DT_HASH
|
||||
.. c:type:: DT_STRTAB
|
||||
.. c:type:: DT_SYMTAB
|
||||
.. c:type:: DT_RELA
|
||||
.. c:type:: DT_RELASZ
|
||||
.. c:type:: DT_RELAENT
|
||||
.. c:type:: DT_STRSZ
|
||||
.. c:type:: DT_SYMENT
|
||||
.. c:type:: DT_INIT
|
||||
.. c:type:: DT_FINI
|
||||
.. c:type:: DT_SONAME
|
||||
.. c:type:: DT_RPATH
|
||||
.. c:type:: DT_SYMBOLIC
|
||||
.. c:type:: DT_REL
|
||||
.. c:type:: DT_RELSZ
|
||||
.. c:type:: DT_RELENT
|
||||
.. c:type:: DT_PLTREL
|
||||
.. c:type:: DT_DEBUG
|
||||
.. c:type:: DT_TEXTREL
|
||||
.. c:type:: DT_JMPREL
|
||||
.. c:type:: DT_BIND_NOW
|
||||
.. c:type:: DT_INIT_ARRAY
|
||||
.. c:type:: DT_FINI_ARRAY
|
||||
.. c:type:: DT_INIT_ARRAYSZ
|
||||
.. c:type:: DT_FINI_ARRAYSZ
|
||||
.. c:type:: DT_RUNPATH
|
||||
.. c:type:: DT_FLAGS
|
||||
.. c:type:: DT_ENCODING
|
||||
|
||||
.. c:member:: value
|
||||
|
||||
A value associated with the given type. The type of value (address,
|
||||
size, etc.) is dependant on the type of dynamic entry.
|
||||
|
||||
.. c:type:: symtab_entries
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
Number of entries in the symbol table found in the ELF file.
|
||||
|
||||
.. c:type:: symtab
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
A zero-based array of symbol objects, one for each entry in found in the
|
||||
ELF's SYMBTAB. Individual symbol objects can be accessed by using the []
|
||||
operator. Each symbol object has the following attributes:
|
||||
|
||||
.. c:member:: name
|
||||
|
||||
The symbol's name.
|
||||
|
||||
.. c:member:: value
|
||||
|
||||
A value associated with the symbol. Generally a virtual address.
|
||||
|
||||
.. c:member:: size
|
||||
|
||||
The symbol's size.
|
||||
|
||||
.. c:member:: type
|
||||
|
||||
The type of symbol. Built values are:
|
||||
|
||||
.. c:type:: STT_NOTYPE
|
||||
.. c:type:: STT_OBJECT
|
||||
.. c:type:: STT_FUNC
|
||||
.. c:type:: STT_SECTION
|
||||
.. c:type:: STT_FILE
|
||||
.. c:type:: STT_COMMON
|
||||
.. c:type:: STT_TLS
|
||||
|
||||
.. c:member:: bind
|
||||
|
||||
The binding of the symbol. Builtin values are:
|
||||
|
||||
.. c:type:: STB_LOCAL
|
||||
.. c:type:: STB_GLOBAL
|
||||
.. c:type:: STB_WEAK
|
||||
|
||||
.. c:member:: shndx
|
||||
|
||||
The section index which the symbol is associated with.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
|
||||
.. _hash-module:
|
||||
|
||||
###########
|
||||
Hash module
|
||||
###########
|
||||
|
||||
.. versionadded:: 3.2.0
|
||||
|
||||
The Hash module allows you to calculate hashes (MD5, SHA1, SHA256) from portions
|
||||
of your file and create signatures based on those hashes.
|
||||
|
||||
.. important::
|
||||
This module depends on the OpenSSL library. Please refer to
|
||||
:ref:`compiling-yara` for information about how to build OpenSSL-dependant
|
||||
features into YARA.
|
||||
|
||||
Good news for Windows users: this module is already included in the official
|
||||
Windows binaries.
|
||||
|
||||
.. c:function:: md5(offset, size)
|
||||
|
||||
Returns the MD5 hash for *size* bytes starting at *offset*. When scanning a
|
||||
running process the *offset* argument should be a virtual address within
|
||||
the process address space. The returned string is always in lowercase.
|
||||
|
||||
*Example: hash.md5(0, filesize) == "feba6c919e3797e7778e8f2e85fa033d"*
|
||||
|
||||
.. c:function:: md5(string)
|
||||
|
||||
Returns the MD5 hash for the given string.
|
||||
|
||||
*Example: hash.md5("dummy") == "275876e34cf609db118f3d84b799a790"*
|
||||
|
||||
.. c:function:: sha1(offset, size)
|
||||
|
||||
Returns the SHA1 hash for the *size* bytes starting at *offset*. When
|
||||
scanning a running process the *offset* argument should be a virtual address
|
||||
within the process address space. The returned string is always in
|
||||
lowercase.
|
||||
|
||||
.. c:function:: sha1(string)
|
||||
|
||||
Returns the SHA1 hash for the given string.
|
||||
|
||||
.. c:function:: sha256(offset, size)
|
||||
|
||||
Returns the SHA256 hash for the *size* bytes starting at *offset*. When
|
||||
scanning a running process the *offset* argument should be a virtual address
|
||||
within the process address space. The returned string is always in
|
||||
lowercase.
|
||||
|
||||
.. c:function:: sha256(string)
|
||||
|
||||
Returns the SHA256 hash for the given string.
|
||||
|
||||
.. c:function:: checksum32(offset, size)
|
||||
|
||||
Returns a 32-bit checksum for the *size* bytes starting at *offset*. The
|
||||
checksum is just the sum of all the bytes (unsigned).
|
||||
|
||||
.. c:function:: checksum32(string)
|
||||
|
||||
Returns a 32-bit checksum for the given string. The checksum is just the
|
||||
sum of all the bytes in the string (unsigned).
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
.. _magic-module:
|
||||
|
||||
############
|
||||
Magic module
|
||||
############
|
||||
|
||||
.. versionadded:: 3.1.0
|
||||
|
||||
The Magic module allows you to identify the type of the file based on the
|
||||
output of `file <http://en.wikipedia.org/wiki/File_(command)>`_, the standard
|
||||
Unix command.
|
||||
|
||||
.. important::
|
||||
This module is not built into YARA by default, to learn how to include it
|
||||
refer to :ref:`compiling-yara`. Bad news for Windows users: **this module is
|
||||
not supported on Windows**.
|
||||
|
||||
There are two functions in this module: :c:func:`type` and :c:func:`mime_type`.
|
||||
The first one returns the descriptive string returned by *file*, for example,
|
||||
if you run *file* against some PDF document you'll get something like this::
|
||||
|
||||
$file some.pdf
|
||||
some.pdf: PDF document, version 1.5
|
||||
|
||||
The :c:func:`type` function would return *"PDF document, version 1.5"* in this
|
||||
case. Using the :c:func:`mime_type` function is similar to passing the
|
||||
``--mime`` argument to *file*.::
|
||||
|
||||
$file --mime some.pdf
|
||||
some.pdf: application/pdf; charset=binary
|
||||
|
||||
|
||||
:c:func:`mime_type` would return *"application/pdf"*, without the charset part.
|
||||
|
||||
By experimenting a little with the *file* command you can learn which output to
|
||||
expect for different file types. These are a few examples:
|
||||
|
||||
* JPEG image data, JFIF standard 1.01
|
||||
* PE32 executable for MS Windows (GUI) Intel 80386 32-bit
|
||||
* PNG image data, 1240 x 1753, 8-bit/color RGBA, non-interlaced
|
||||
* ASCII text, with no line terminators
|
||||
* Zip archive data, at least v2.0 to extract
|
||||
|
||||
|
||||
|
||||
.. c:function:: type()
|
||||
|
||||
Function returning a string with the type of the file.
|
||||
|
||||
*Example: magic.type() contains "PDF"*
|
||||
|
||||
|
||||
.. c:function:: mime_type()
|
||||
|
||||
Function returning a string with the MIME type of the file.
|
||||
|
||||
*Example: magic.mime_type() == "application/pdf"*
|
||||
@@ -0,0 +1,100 @@
|
||||
|
||||
.. _math-module:
|
||||
|
||||
###########
|
||||
Math module
|
||||
###########
|
||||
|
||||
.. versionadded:: 3.3.0
|
||||
|
||||
The Math module allows you to calculate certain values from portions of your
|
||||
file and create signatures based on those results.
|
||||
|
||||
.. important::
|
||||
Where noted these functions return floating point numbers. YARA is able to
|
||||
convert integers to floating point numbers during most operations. For
|
||||
example this will convert 7 to 7.0 automatically, because the return type
|
||||
of the entropy function is a floating point value:
|
||||
|
||||
*math.entropy(0, filesize) >= 7*
|
||||
|
||||
The one exception to this is when a function requires a floating point
|
||||
number as an argument. For example, this will cause a syntax error because
|
||||
the arguments must be floating point numbers:
|
||||
|
||||
*math.in_range(2, 1, 3)*
|
||||
|
||||
.. c:function:: entropy(offset, size)
|
||||
|
||||
Returns the entropy for *size* bytes starting at *offset*. When scanning a
|
||||
running process the *offset* argument should be a virtual address within
|
||||
the process address space. The returned value is a float.
|
||||
|
||||
*Example: math.entropy(0, filesize) >= 7*
|
||||
|
||||
.. c:function:: entropy(string)
|
||||
|
||||
Returns the entropy for the given string.
|
||||
|
||||
*Example: math.entropy("dummy") > 7*
|
||||
|
||||
.. c:function:: monte_carlo_pi(offset, size)
|
||||
|
||||
Returns the percentage away from Pi for the *size* bytes starting at
|
||||
*offset* when run through the Monte Carlo from Pi test. When scanning a
|
||||
running process the *offset* argument should be a virtual address within
|
||||
the process address space. The returned value is a float.
|
||||
|
||||
*Example: math.monte_carlo_pi(0, filesize) < 0.07*
|
||||
|
||||
.. c:function:: monte_carlo_pi(string)
|
||||
|
||||
Return the percentage away from Pi for the given string.
|
||||
|
||||
.. c:function:: serial_correlation(offset, size)
|
||||
|
||||
Returns the serial correlation for the *size* bytes starting at *offset*.
|
||||
When scanning a running process the *offset* argument should be a virtual
|
||||
address within the process address space. The returned value is a float
|
||||
between 0.0 and 1.0.
|
||||
|
||||
*Example: math.serial_correlation(0, filesize) < 0.2*
|
||||
|
||||
.. c:function:: serial_correlation(string)
|
||||
|
||||
Return the serial correlation for the given string.
|
||||
|
||||
.. c:function:: mean(offset, size)
|
||||
|
||||
Returns the mean for the *size* bytes starting at *offset*. When scanning
|
||||
a running process the *offset* argument should be a virtual address within
|
||||
the process address space. The returned value is a float.
|
||||
|
||||
*Example: math.mean(0, filesize) < 72.0*
|
||||
|
||||
.. c:function:: mean(string)
|
||||
|
||||
Return the mean for the given string.
|
||||
|
||||
.. c:function:: deviation(offset, size, mean)
|
||||
|
||||
Returns the deviation from the mean for the *size* bytes starting at
|
||||
*offset*. When scanning a running process the *offset* argument should be
|
||||
a virtual address within the process address space. The returned value is
|
||||
a float.
|
||||
|
||||
The mean of an equally distributed random sample of bytes is 127.5, which
|
||||
is available as the constant math.MEAN_BYTES.
|
||||
|
||||
*Example: math.deviation(0, filesize, math.MEAN_BYTES) == 64.0*
|
||||
|
||||
.. c:function:: deviation(string, mean)
|
||||
|
||||
Return the deviation from the mean for the given string.
|
||||
|
||||
.. c:function:: in_range(test, lower, upper)
|
||||
|
||||
Returns true if the *test* value is between *lower* and *upper* values. The
|
||||
comparisons are inclusive.
|
||||
|
||||
*Example: math.in_range(math.deviation(0, filesize, math.MEAN_BYTES), 63.9, 64,1)*
|
||||
@@ -0,0 +1,661 @@
|
||||
|
||||
.. _pe-module:
|
||||
|
||||
#########
|
||||
PE module
|
||||
#########
|
||||
|
||||
The PE module allows you to create more fine-grained rules for PE files by
|
||||
using attributes and features of the PE file format. This module exposes most of
|
||||
the fields present in a PE header and provides functions which can be used to
|
||||
write more expressive and targeted rules. Let's see some examples::
|
||||
|
||||
import "pe"
|
||||
|
||||
rule single_section
|
||||
{
|
||||
condition:
|
||||
pe.number_of_sections == 1
|
||||
}
|
||||
|
||||
rule control_panel_applet
|
||||
{
|
||||
condition:
|
||||
pe.exports("CPlApplet")
|
||||
}
|
||||
|
||||
rule is_dll
|
||||
{
|
||||
condition:
|
||||
pe.characteristics & pe.DLL
|
||||
}
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. c:type:: machine
|
||||
|
||||
.. versionchanged:: 3.3.0
|
||||
|
||||
Integer with one of the following values:
|
||||
|
||||
.. c:type:: MACHINE_UNKNOWN
|
||||
.. c:type:: MACHINE_AM33
|
||||
.. c:type:: MACHINE_AMD64
|
||||
.. c:type:: MACHINE_ARM
|
||||
.. c:type:: MACHINE_ARMNT
|
||||
.. c:type:: MACHINE_ARM64
|
||||
.. c:type:: MACHINE_EBC
|
||||
.. c:type:: MACHINE_I386
|
||||
.. c:type:: MACHINE_IA64
|
||||
.. c:type:: MACHINE_M32R
|
||||
.. c:type:: MACHINE_MIPS16
|
||||
.. c:type:: MACHINE_MIPSFPU
|
||||
.. c:type:: MACHINE_MIPSFPU16
|
||||
.. c:type:: MACHINE_POWERPC
|
||||
.. c:type:: MACHINE_POWERPCFP
|
||||
.. c:type:: MACHINE_R4000
|
||||
.. c:type:: MACHINE_SH3
|
||||
.. c:type:: MACHINE_SH3DSP
|
||||
.. c:type:: MACHINE_SH4
|
||||
.. c:type:: MACHINE_SH5
|
||||
.. c:type:: MACHINE_THUMB
|
||||
.. c:type:: MACHINE_WCEMIPSV2
|
||||
|
||||
*Example: pe.machine == pe.MACHINE_AMD64*
|
||||
|
||||
.. c:type:: checksum
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
Integer with the "PE checksum" as stored in the OptionalHeader
|
||||
|
||||
.. c:type:: calculate_checksum
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
Function that calculates the "PE checksum"
|
||||
|
||||
*Example: pe.checksum == pe.calculate_checksum()*
|
||||
|
||||
.. c:type:: subsystem
|
||||
|
||||
Integer with one of the following values:
|
||||
|
||||
.. c:type:: SUBSYSTEM_UNKNOWN
|
||||
.. c:type:: SUBSYSTEM_NATIVE
|
||||
.. c:type:: SUBSYSTEM_WINDOWS_GUI
|
||||
.. c:type:: SUBSYSTEM_WINDOWS_CUI
|
||||
.. c:type:: SUBSYSTEM_OS2_CUI
|
||||
.. c:type:: SUBSYSTEM_POSIX_CUI
|
||||
.. c:type:: SUBSYSTEM_NATIVE_WINDOWS
|
||||
.. c:type:: SUBSYSTEM_WINDOWS_CE_GUI
|
||||
.. c:type:: SUBSYSTEM_EFI_APPLICATION
|
||||
.. c:type:: SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
|
||||
.. c:type:: SUBSYSTEM_EFI_RUNTIME_DRIVER
|
||||
.. c:type:: SUBSYSTEM_XBOX
|
||||
.. c:type:: SUBSYSTEM_WINDOWS_BOOT_APPLICATION
|
||||
|
||||
*Example: pe.subsystem == pe.SUBSYSTEM_NATIVE*
|
||||
|
||||
.. c:type:: timestamp
|
||||
|
||||
PE timestamp.
|
||||
|
||||
.. c:type:: entry_point
|
||||
|
||||
Entry point raw offset or virtual address depending on whether YARA is
|
||||
scanning a file or process memory respectively. This is equivalent to the
|
||||
deprecated ``entrypoint`` keyword.
|
||||
|
||||
.. c:type:: image_base
|
||||
|
||||
Image base relative virtual address.
|
||||
|
||||
.. c:type:: characteristics
|
||||
|
||||
Bitmap with PE FileHeader characteristics. Individual characteristics
|
||||
can be inspected by performing a bitwise AND operation with the
|
||||
following constants:
|
||||
|
||||
.. c:type:: RELOCS_STRIPPED
|
||||
.. c:type:: EXECUTABLE_IMAGE
|
||||
.. c:type:: LINE_NUMS_STRIPPED
|
||||
.. c:type:: LOCAL_SYMS_STRIPPED
|
||||
.. c:type:: AGGRESIVE_WS_TRIM
|
||||
.. c:type:: LARGE_ADDRESS_AWARE
|
||||
.. c:type:: BYTES_REVERSED_LO
|
||||
.. c:type:: MACHINE_32BIT
|
||||
.. c:type:: DEBUG_STRIPPED
|
||||
.. c:type:: REMOVABLE_RUN_FROM_SWAP
|
||||
.. c:type:: NET_RUN_FROM_SWAP
|
||||
.. c:type:: SYSTEM
|
||||
.. c:type:: DLL
|
||||
.. c:type:: UP_SYSTEM_ONLY
|
||||
.. c:type:: BYTES_REVERSED_HI
|
||||
|
||||
*Example: pe.characteristics & pe.DLL*
|
||||
|
||||
.. c:type:: linker_version
|
||||
|
||||
An object with two integer attributes, one for each major and minor linker
|
||||
version.
|
||||
|
||||
.. c:member:: major
|
||||
|
||||
Major linker version.
|
||||
|
||||
.. c:member:: minor
|
||||
|
||||
Minor linker version.
|
||||
|
||||
.. c:type:: os_version
|
||||
|
||||
An object with two integer attributes, one for each major and minor OS
|
||||
version.
|
||||
|
||||
.. c:member:: major
|
||||
|
||||
Major OS version.
|
||||
|
||||
.. c:member:: minor
|
||||
|
||||
Minor OS version.
|
||||
|
||||
.. c:type:: image_version
|
||||
|
||||
An object with two integer attributes, one for each major and minor image
|
||||
version.
|
||||
|
||||
.. c:member:: major
|
||||
|
||||
Major image version.
|
||||
|
||||
.. c:member:: minor
|
||||
|
||||
Minor image version.
|
||||
|
||||
.. c:type:: subsystem_version
|
||||
|
||||
An object with two integer attributes, one for each major and minor subsystem
|
||||
version.
|
||||
|
||||
.. c:member:: major
|
||||
|
||||
Major subsystem version.
|
||||
|
||||
.. c:member:: minor
|
||||
|
||||
Minor subsystem version.
|
||||
|
||||
.. c:type:: dll_characteristics
|
||||
|
||||
Bitmap with PE OptionalHeader DllCharacteristics. Do not confuse these
|
||||
flags with the PE FileHeader Characteristics. Individual
|
||||
characteristics can be inspected by performing a bitwise AND
|
||||
operation with the following constants:
|
||||
|
||||
.. c:type:: DYNAMIC_BASE
|
||||
|
||||
File can be relocated - also marks the file as ASLR compatible
|
||||
|
||||
.. c:type:: FORCE_INTEGRITY
|
||||
.. c:type:: NX_COMPAT
|
||||
|
||||
Marks the file as DEP compatible
|
||||
|
||||
.. c:type:: NO_ISOLATION
|
||||
.. c:type:: NO_SEH
|
||||
|
||||
The file does not contain structured exception handlers, this must be
|
||||
set to use SafeSEH
|
||||
|
||||
.. c:type:: NO_BIND
|
||||
.. c:type:: WDM_DRIVER
|
||||
|
||||
Marks the file as a Windows Driver Model (WDM) device driver.
|
||||
|
||||
.. c:type:: TERMINAL_SERVER_AWARE
|
||||
|
||||
Marks the file as terminal server compatible
|
||||
|
||||
.. c:type:: number_of_sections
|
||||
|
||||
Number of sections in the PE.
|
||||
|
||||
.. c:type:: sections
|
||||
|
||||
.. versionadded:: 3.3.0
|
||||
|
||||
A zero-based array of section objects, one for each section the PE has.
|
||||
Individual sections can be accessed by using the [] operator. Each section
|
||||
object has the following attributes:
|
||||
|
||||
.. c:member:: name
|
||||
|
||||
Section name.
|
||||
|
||||
.. c:member:: characteristics
|
||||
|
||||
Section characteristics.
|
||||
|
||||
.. c:member:: virtual_address
|
||||
|
||||
Section virtual address.
|
||||
|
||||
.. c:member:: virtual_size
|
||||
|
||||
Section virtual size.
|
||||
|
||||
.. c:member:: raw_data_offset
|
||||
|
||||
Section raw offset.
|
||||
|
||||
.. c:member:: raw_data_size
|
||||
|
||||
Section raw size.
|
||||
|
||||
*Example: pe.sections[0].name == ".text"*
|
||||
|
||||
Individual section characteristics can be inspected using a bitwise AND
|
||||
operation with the following constants:
|
||||
|
||||
.. c:type:: SECTION_CNT_CODE
|
||||
.. c:type:: SECTION_CNT_INITIALIZED_DATA
|
||||
.. c:type:: SECTION_CNT_UNINITIALIZED_DATA
|
||||
.. c:type:: SECTION_GPREL
|
||||
.. c:type:: SECTION_MEM_16BIT
|
||||
.. c:type:: SECTION_LNK_NRELOC_OVFL
|
||||
.. c:type:: SECTION_MEM_DISCARDABLE
|
||||
.. c:type:: SECTION_MEM_NOT_CACHED
|
||||
.. c:type:: SECTION_MEM_NOT_PAGED
|
||||
.. c:type:: SECTION_MEM_SHARED
|
||||
.. c:type:: SECTION_MEM_EXECUTE
|
||||
.. c:type:: SECTION_MEM_READ
|
||||
.. c:type:: SECTION_MEM_WRITE
|
||||
|
||||
*Example: pe.sections[1].characteristics & SECTION_CNT_CODE*
|
||||
|
||||
.. c:type:: overlay
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
A structure containing the following integer members:
|
||||
|
||||
.. c:member:: offset
|
||||
|
||||
Overlay section offset.
|
||||
|
||||
.. c:member:: size
|
||||
|
||||
Overlay section size.
|
||||
|
||||
*Example: uint8(0x0d) at pe.overlay.offset and pe.overlay.size > 1024*
|
||||
|
||||
.. c:type:: number_of_resources
|
||||
|
||||
Number of resources in the PE.
|
||||
|
||||
.. c:type:: resource_timestamp
|
||||
|
||||
Resource timestamp. This is stored as an integer.
|
||||
|
||||
.. c:type:: resource_version
|
||||
|
||||
An object with two integer attributes, major and minor versions.
|
||||
|
||||
.. c:member:: major
|
||||
|
||||
Major resource version.
|
||||
|
||||
.. c:member:: minor
|
||||
|
||||
Minor resource version.
|
||||
|
||||
.. c:type:: resources
|
||||
|
||||
.. versionchanged:: 3.3.0
|
||||
|
||||
A zero-based array of resource objects, one for each resource the PE has.
|
||||
Individual resources can be accessed by using the [] operator. Each
|
||||
resource object has the following attributes:
|
||||
|
||||
.. c:member:: offset
|
||||
|
||||
Offset for the resource data.
|
||||
|
||||
.. c:member:: length
|
||||
|
||||
Length of the resource data.
|
||||
|
||||
.. c:member:: type
|
||||
|
||||
Type of the resource (integer).
|
||||
|
||||
.. c:member:: id
|
||||
|
||||
ID of the resource (integer).
|
||||
|
||||
.. c:member:: language
|
||||
|
||||
Language of the resource (integer).
|
||||
|
||||
.. c:member:: type_string
|
||||
|
||||
Type of the resource as a string, if specified.
|
||||
|
||||
.. c:member:: name_string
|
||||
|
||||
Name of the resource as a string, if specified.
|
||||
|
||||
.. c:member:: language_string
|
||||
|
||||
Language of the resource as a string, if specified.
|
||||
|
||||
All resources must have a type, id (name), and language specified. They can
|
||||
be either an integer or string, but never both, for any given level.
|
||||
|
||||
*Example: pe.resources[0].type == pe.RESOURCE_TYPE_RCDATA*
|
||||
|
||||
*Example: pe.resources[0].name_string == "F\\x00I\\x00L\\x00E\\x00"*
|
||||
|
||||
Resource types can be inspected using the following constants:
|
||||
|
||||
.. c:type:: RESOURCE_TYPE_CURSOR
|
||||
.. c:type:: RESOURCE_TYPE_BITMAP
|
||||
.. c:type:: RESOURCE_TYPE_ICON
|
||||
.. c:type:: RESOURCE_TYPE_MENU
|
||||
.. c:type:: RESOURCE_TYPE_DIALOG
|
||||
.. c:type:: RESOURCE_TYPE_STRING
|
||||
.. c:type:: RESOURCE_TYPE_FONTDIR
|
||||
.. c:type:: RESOURCE_TYPE_FONT
|
||||
.. c:type:: RESOURCE_TYPE_ACCELERATOR
|
||||
.. c:type:: RESOURCE_TYPE_RCDATA
|
||||
.. c:type:: RESOURCE_TYPE_MESSAGETABLE
|
||||
.. c:type:: RESOURCE_TYPE_GROUP_CURSOR
|
||||
.. c:type:: RESOURCE_TYPE_GROUP_ICON
|
||||
.. c:type:: RESOURCE_TYPE_VERSION
|
||||
.. c:type:: RESOURCE_TYPE_DLGINCLUDE
|
||||
.. c:type:: RESOURCE_TYPE_PLUGPLAY
|
||||
.. c:type:: RESOURCE_TYPE_VXD
|
||||
.. c:type:: RESOURCE_TYPE_ANICURSOR
|
||||
.. c:type:: RESOURCE_TYPE_ANIICON
|
||||
.. c:type:: RESOURCE_TYPE_HTML
|
||||
.. c:type:: RESOURCE_TYPE_MANIFEST
|
||||
|
||||
For more information refer to:
|
||||
|
||||
http://msdn.microsoft.com/en-us/library/ms648009(v=vs.85).aspx
|
||||
|
||||
.. c:type:: version_info
|
||||
|
||||
.. versionadded:: 3.2.0
|
||||
|
||||
Dictionary containing the PE's version information. Typical keys are:
|
||||
|
||||
``Comments``
|
||||
``CompanyName``
|
||||
``FileDescription``
|
||||
``FileVersion``
|
||||
``InternalName``
|
||||
``LegalCopyright``
|
||||
``LegalTrademarks``
|
||||
``OriginalFilename``
|
||||
``ProductName``
|
||||
``ProductVersion``
|
||||
|
||||
For more information refer to:
|
||||
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646987(v=vs.85).aspx
|
||||
|
||||
*Example: pe.version_info["CompanyName"] contains "Microsoft"*
|
||||
|
||||
.. c:type:: number_of_signatures
|
||||
|
||||
Number of authenticode signatures in the PE.
|
||||
|
||||
.. c:type:: signatures
|
||||
|
||||
A zero-based array of signature objects, one for each authenticode
|
||||
signature in the PE file. Usually PE files have a single signature.
|
||||
|
||||
.. c:member:: issuer
|
||||
|
||||
A string containing information about the issuer. These are some
|
||||
examples::
|
||||
|
||||
"/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Code Signing PCA"
|
||||
|
||||
"/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Code Signing 2010 CA"
|
||||
|
||||
"/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO Code Signing CA 2"
|
||||
|
||||
.. c:member:: subject
|
||||
|
||||
A string containing information about the subject.
|
||||
|
||||
.. c:member:: version
|
||||
|
||||
Version number.
|
||||
|
||||
.. c:member:: algorithm
|
||||
|
||||
Algorithm used for this signature. Usually "sha1WithRSAEncryption".
|
||||
|
||||
.. c:member:: serial
|
||||
|
||||
A string containing the serial number. This is an example::
|
||||
|
||||
"52:00:e5:aa:25:56:fc:1a:86:ed:96:c9:d4:4b:33:c7"
|
||||
|
||||
.. c:member:: not_before
|
||||
|
||||
Unix timestamp on which the validity period for this signature begins.
|
||||
|
||||
.. c:member:: not_after
|
||||
|
||||
Unix timestamp on which the validity period for this signature ends.
|
||||
|
||||
.. c:member:: valid_on(timestamp)
|
||||
|
||||
Function returning true if the signature was valid on the date
|
||||
indicated by *timestamp*. The following sentence::
|
||||
|
||||
pe.signatures[n].valid_on(timestamp)
|
||||
|
||||
Is equivalent to::
|
||||
|
||||
timestamp >= pe.signatures[n].not_before and timestamp <= pe.signatures[n].not_after
|
||||
|
||||
.. c:type:: rich_signature
|
||||
|
||||
Structure containing information about the PE's rich signature as
|
||||
documented `here <http://www.ntcore.com/files/richsign.htm>`_.
|
||||
|
||||
.. c:member:: offset
|
||||
|
||||
Offset where the rich signature starts. It will be undefined if the
|
||||
file doesn't have a rich signature.
|
||||
|
||||
.. c:member:: length
|
||||
|
||||
Length of the rich signature, not including the final "Rich" marker.
|
||||
|
||||
.. c:member:: key
|
||||
|
||||
Key used to encrypt the data with XOR.
|
||||
|
||||
.. c:member:: raw_data
|
||||
|
||||
Raw data as it appears in the file.
|
||||
|
||||
.. c:member:: clear_data
|
||||
|
||||
Data after being decrypted by XORing it with the key.
|
||||
|
||||
.. c:function:: version(version, [toolid])
|
||||
|
||||
.. versionadded:: 3.5.0
|
||||
|
||||
Function returning true if the PE has the specified *version* in the PE's rich
|
||||
signature. Provide the optional *toolid* argument to only match when both match
|
||||
for one entry. More information can be found here:
|
||||
|
||||
http://www.ntcore.com/files/richsign.htm
|
||||
|
||||
*Example: pe.rich_signature.version(21005)*
|
||||
|
||||
.. c:function:: toolid(toolid, [version])
|
||||
|
||||
.. versionadded:: 3.5.0
|
||||
|
||||
Function returning true if the PE has the specified *id* in the PE's rich
|
||||
signature. Provide the optional *version* argument to only match when both
|
||||
match for one entry. More information can be found here:
|
||||
|
||||
http://www.ntcore.com/files/richsign.htm
|
||||
|
||||
*Example: pe.rich_signature.toolid(222)*
|
||||
|
||||
.. c:function:: exports(function_name)
|
||||
|
||||
Function returning true if the PE exports *function_name* or
|
||||
false otherwise.
|
||||
|
||||
*Example: pe.exports("CPlApplet")*
|
||||
|
||||
.. c:function:: exports(ordinal)
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
Function returning true if the PE exports *ordinal* or
|
||||
false otherwise.
|
||||
|
||||
*Example: pe.exports(72)*
|
||||
|
||||
.. c:function:: exports(/regular_expression/)
|
||||
|
||||
.. versionadded:: 3.7.1
|
||||
|
||||
Function returning true if the PE exports *regular_expression* or
|
||||
false otherwise.
|
||||
|
||||
*Example: pe.exports(/^AXS@@/)*
|
||||
|
||||
.. c:type:: number_of_exports
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
Number of exports in the PE.
|
||||
|
||||
.. c:type:: number_of_imports
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
Number of imports in the PE.
|
||||
|
||||
.. c:function:: imports(dll_name, function_name)
|
||||
|
||||
Function returning true if the PE imports *function_name* from *dll_name*,
|
||||
or false otherwise. *dll_name* is case insensitive.
|
||||
|
||||
*Example: pe.imports("kernel32.dll", "WriteProcessMemory")*
|
||||
|
||||
.. c:function:: imports(dll_name)
|
||||
|
||||
.. versionadded:: 3.5.0
|
||||
|
||||
Function returning true if the PE imports anything from *dll_name*,
|
||||
or false otherwise. *dll_name* is case insensitive.
|
||||
|
||||
*Example: pe.imports("kernel32.dll")*
|
||||
|
||||
.. c:function:: imports(dll_name, ordinal)
|
||||
|
||||
.. versionadded:: 3.5.0
|
||||
|
||||
Function returning true if the PE imports *ordinal* from *dll_name*,
|
||||
or false otherwise. *dll_name* is case insensitive.
|
||||
|
||||
*Example: pe.imports("WS2_32.DLL", 3)*
|
||||
|
||||
.. c:function:: locale(locale_identifier)
|
||||
|
||||
.. versionadded:: 3.2.0
|
||||
|
||||
Function returning true if the PE has a resource with the specified locale
|
||||
identifier. Locale identifiers are 16-bit integers and can be found here:
|
||||
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/dd318693(v=vs.85).aspx
|
||||
|
||||
*Example: pe.locale(0x0419) // Russian (RU)*
|
||||
|
||||
.. c:function:: language(language_identifier)
|
||||
|
||||
.. versionadded:: 3.2.0
|
||||
|
||||
Function returning true if the PE has a resource with the specified language
|
||||
identifier. Language identifiers are 8-bit integers and can be found here:
|
||||
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/dd318693(v=vs.85).aspx
|
||||
|
||||
*Example: pe.language(0x0A) // Spanish*
|
||||
|
||||
.. c:function:: imphash()
|
||||
|
||||
.. versionadded:: 3.2.0
|
||||
|
||||
Function returning the import hash or imphash for the PE. The imphash is
|
||||
a MD5 hash of the PE's import table after some normalization. The imphash
|
||||
for a PE can be also computed with `pefile <http://code.google.com/p/pefile/>`_ and you can find more information in
|
||||
`Mandiant's blog <https://www.mandiant.com/blog/tracking-malware-import-hashing/>`_.
|
||||
|
||||
*Example: pe.imphash() == "b8bb385806b89680e13fc0cf24f4431e"*
|
||||
|
||||
.. c:function:: section_index(name)
|
||||
|
||||
Function returning the index into the sections array for the section that has
|
||||
*name*. *name* is case sensitive.
|
||||
|
||||
*Example: pe.section_index(".TEXT")*
|
||||
|
||||
.. c:function:: section_index(addr)
|
||||
|
||||
.. versionadded:: 3.3.0
|
||||
|
||||
Function returning the index into the sections array for the section that has
|
||||
*addr*. *addr* can be an offset into the file or a memory address.
|
||||
|
||||
*Example: pe.section_index(pe.entry_point)*
|
||||
|
||||
.. c:function:: is_dll()
|
||||
|
||||
.. versionadded:: 3.5.0
|
||||
|
||||
Function returning true if the PE is a DLL.
|
||||
|
||||
*Example: pe.is_dll()*
|
||||
|
||||
.. c:function:: is_32bit()
|
||||
|
||||
.. versionadded:: 3.5.0
|
||||
|
||||
Function returning true if the PE is 32bits.
|
||||
|
||||
*Example: pe.is_32bit()*
|
||||
|
||||
.. c:function:: is_64bit()
|
||||
|
||||
.. versionadded:: 3.5.0
|
||||
|
||||
Function returning true if the PE is 64bits.
|
||||
|
||||
*Example: pe.is_64bit()*
|
||||
|
||||
.. c:function:: rva_to_offset(addr)
|
||||
|
||||
.. versionadded:: 3.6.0
|
||||
|
||||
Function returning the file offset for RVA *addr*.
|
||||
|
||||
*Example: pe.rva_to_offset(pe.entry_point)*
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
.. _time-module:
|
||||
|
||||
############
|
||||
Time module
|
||||
############
|
||||
|
||||
.. versionadded:: 3.7.0
|
||||
|
||||
The Time module allows you to use temporal conditions in your YARA rules.
|
||||
|
||||
.. c:function:: now()
|
||||
|
||||
Function returning an integer which is the number of seconds since January
|
||||
1, 1970.
|
||||
|
||||
*Example: pe.timestamp > time.now()*
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,385 @@
|
||||
**********************
|
||||
Using YARA from Python
|
||||
**********************
|
||||
|
||||
YARA can be also used from Python through the ``yara-python`` library. Once
|
||||
the library is built and installed as described in :ref:`compiling-yara`
|
||||
you'll have access to the full potential of YARA from your Python scripts.
|
||||
|
||||
The first step is importing the YARA library:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import yara
|
||||
|
||||
Then you will need to compile your YARA rules before applying them to your data,
|
||||
the rules can be compiled from a file path:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
rules = yara.compile(filepath='/foo/bar/myrules')
|
||||
|
||||
The default argument is filepath, so you don't need to explicitly specify its
|
||||
name:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
rules = yara.compile('/foo/bar/myrules')
|
||||
|
||||
You can also compile your rules from a file object:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
fh = open('/foo/bar/myrules')
|
||||
rules = yara.compile(file=fh)
|
||||
fh.close()
|
||||
|
||||
Or you can compile them directly from a Python string:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
rules = yara.compile(source='rule dummy { condition: true }')
|
||||
|
||||
If you want to compile a group of files or strings at the same time you can do
|
||||
it by using the ``filepaths`` or ``sources`` named arguments:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
rules = yara.compile(filepaths={
|
||||
|
||||
'namespace1':'/my/path/rules1',
|
||||
'namespace2':'/my/path/rules2'
|
||||
})
|
||||
|
||||
rules = yara.compile(sources={
|
||||
|
||||
'namespace1':'rule dummy { condition: true }',
|
||||
'namespace2':'rule dummy { condition: false }'
|
||||
})
|
||||
|
||||
Notice that both ``filepaths`` and ``sources`` must be dictionaries with keys
|
||||
of string type. The dictionary keys are used as a namespace identifier, allowing
|
||||
to differentiate between rules with the same name in different sources, as
|
||||
occurs in the second example with the *dummy* name.
|
||||
|
||||
The ``compile`` method also has an optional boolean parameter named
|
||||
``includes`` which allows you to control whether or not the include directive
|
||||
should be accepted in the source files, for example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
rules = yara.compile('/foo/bar/my_rules', includes=False)
|
||||
|
||||
|
||||
If the source file contains include directives the previous line would raise
|
||||
an exception.
|
||||
|
||||
If includes are used, a python callback can be set to define a custom source for
|
||||
the imported files (by default they are read from disk). This callback function
|
||||
is set through the ``include_callback`` optional parameter.
|
||||
It receives the following parameters:
|
||||
*``requested_filename``: file requested with 'include'
|
||||
*``filename``: file containing the 'include' directive if applicable, else None
|
||||
*``namespace``: namespace
|
||||
And returns the requested rules sources as a single string.
|
||||
|
||||
.. code-block:: python
|
||||
import yara
|
||||
import sys
|
||||
if sys.version_info >= (3, 0):
|
||||
import urllib.request as urllib
|
||||
else:
|
||||
import urllib as urllib
|
||||
|
||||
def mycallback(requested_filename, filename, namespace):
|
||||
if requested_filename == 'req.yara':
|
||||
uf = urllib.urlopen('https://pastebin.com/raw/siZ2sMTM')
|
||||
sources = uf.read()
|
||||
if sys.version_info >= (3, 0):
|
||||
sources = str(sources, 'utf-8')
|
||||
return sources
|
||||
else:
|
||||
raise Exception(filename+": Can't fetch "+requested_filename)
|
||||
|
||||
rules = yara.compile(source='include "req.yara" rule r{ condition: true }',
|
||||
include_callback=mycallback)
|
||||
|
||||
If you are using external variables in your rules you must define those
|
||||
external variables either while compiling the rules, or while applying the
|
||||
rules to some file. To define your variables at the moment of compilation you
|
||||
should pass the ``externals`` parameter to the ``compile`` method. For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
rules = yara.compile('/foo/bar/my_rules’,
|
||||
externals= {'var1': 'some string’, 'var2': 4, 'var3': True})
|
||||
|
||||
The ``externals`` parameter must be a dictionary with the names of the variables
|
||||
as keys and an associated value of either string, integer or boolean type.
|
||||
|
||||
The ``compile`` method also accepts the optional boolean argument
|
||||
``error_on_warning``. This arguments tells YARA to raise an exception when a
|
||||
warning is issued during compilation. Such warnings are typically issued when
|
||||
your rules contains some construct that could be slowing down the scanning.
|
||||
The default value for the ``error_on_warning`` argument is False.
|
||||
|
||||
|
||||
In all cases ``compile`` returns an instance of the class :py:class:`yara.Rules`
|
||||
Rules. This class has a ``save`` method that can be used to save the compiled
|
||||
rules to a file:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
rules.save('/foo/bar/my_compiled_rules')
|
||||
|
||||
The compiled rules can be loaded later by using the ``load`` method:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
rules = yara.load('/foo/bar/my_compiled_rules')
|
||||
|
||||
Starting with YARA 3.4 both ``save`` and ``load`` accept file objects. For
|
||||
example, you can save your rules to a memory buffer with this code:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import StringIO
|
||||
|
||||
buff = StringIO.StringIO()
|
||||
rules.save(file=buff)
|
||||
|
||||
The saved rules can be loaded from the memory buffer:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
buff.seek(0)
|
||||
rule = yara.load(file=buff)
|
||||
|
||||
The result of ``load`` is also an instance of the class :py:class:`yara.Rules`.
|
||||
|
||||
Instances of ``Rules`` also have a ``match`` method, which allows you to apply
|
||||
the rules to a file:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
matches = rules.match('/foo/bar/my_file')
|
||||
|
||||
But you can also apply the rules to a Python string:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
with open('/foo/bar/my_file', 'rb') as f:
|
||||
matches = rules.match(data=f.read())
|
||||
|
||||
Or to a running process:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
matches = rules.match(pid=1234)
|
||||
|
||||
As in the case of ``compile``, the ``match`` method can receive definitions for
|
||||
external variables in the ``externals`` argument.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
matches = rules.match('/foo/bar/my_file',
|
||||
externals= {'var1': 'some other string', 'var2': 100})
|
||||
|
||||
External variables defined during compile-time don’t need to be defined again
|
||||
in subsequent calls to the ``match`` method. However you can redefine
|
||||
any variable as needed, or provide additional definitions that weren’t provided
|
||||
during compilation.
|
||||
|
||||
In some situations involving a very large set of rules or huge files the
|
||||
``match`` method can take too much time to run. In those situations you may
|
||||
find useful the ``timeout`` argument:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
matches = rules.match('/foo/bar/my_huge_file', timeout=60)
|
||||
|
||||
If the ``match`` function does not finish before the specified number of
|
||||
seconds elapsed, a ``TimeoutError`` exception is raised.
|
||||
|
||||
You can also specify a callback function when invoking the ``match`` method. By
|
||||
default, the provided function will be called for every rule, no matter if
|
||||
matching or not. You can choose when your callback function is called by setting
|
||||
the ``which_callbacks`` parameter to one of ``yara.CALLBACK_MATCHES``,
|
||||
``yara.CALLBACK_NON_MATCHES`` or ``yara.CALLBACK_ALL``. The default is to use
|
||||
``yara.CALLBACK_ALL``. Your callback function should expect a single parameter
|
||||
of dictionary type, and should return ``CALLBACK_CONTINUE`` to proceed to the
|
||||
next rule or ``CALLBACK_ABORT`` to stop applying rules to your data.
|
||||
|
||||
Here is an example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import yara
|
||||
|
||||
def mycallback(data):
|
||||
print data
|
||||
return yara.CALLBACK_CONTINUE
|
||||
|
||||
matches = rules.match('/foo/bar/my_file', callback=mycallback, which_callbacks=yara.CALLBACK_MATCHES)
|
||||
|
||||
The passed dictionary will be something like this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
'tags': ['foo', 'bar'],
|
||||
'matches': True,
|
||||
'namespace': 'default',
|
||||
'rule': 'my_rule',
|
||||
'meta': {},
|
||||
'strings': [(81L, '$a', 'abc'), (141L, '$b', 'def')]
|
||||
}
|
||||
|
||||
The *matches* field indicates if the rule matches the data or not. The
|
||||
*strings* fields is a list of matching strings, with vectors of the form::
|
||||
|
||||
(<offset>, <string identifier>, <string data>)
|
||||
|
||||
The ``match`` method returns a list of instances of the class ``Match``.
|
||||
Instances of this class have the same attributes as the dictionary passed to the
|
||||
callback function.
|
||||
|
||||
|
||||
You can also specify a module callback function when invoking the ``match``
|
||||
method. The provided function will be called for every imported module that
|
||||
scanned a file. Your callback function should expect a single parameter of
|
||||
dictionary type, and should return ``CALLBACK_CONTINUE`` to proceed to the next
|
||||
rule or ``CALLBACK_ABORT`` to stop applying rules to your data.
|
||||
|
||||
Here is an example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import yara
|
||||
|
||||
def modules_callback(data):
|
||||
print data
|
||||
return yara.CALLBACK_CONTINUE
|
||||
|
||||
matches = rules.match('/foo/bar/my_file', modules_callback=modules_callback)
|
||||
|
||||
The passed dictionary will contain the information from the module.
|
||||
|
||||
|
||||
You may also find that the default sizes for the stack for the matching engine in
|
||||
yara or the default size for the maximum number of strings per rule is too low. In
|
||||
the C libyara API, you can modify these using the ``YR_CONFIG_STACK_SIZE`` and
|
||||
``YR_CONFIG_MAX_STRINGS_PER_RULE`` variables via the ``yr_set_configuration``
|
||||
function in libyara. The command-line tool exposes these as the ``--stack-size``
|
||||
(``-k``) and ``--max-strings-per-rule`` command-line arguments. In order to set
|
||||
these values via the Python API, you can use ``yara.set_config`` with either or
|
||||
both ``stack_size`` and ``max_strings_per_rule`` provided as kwargs. At the time
|
||||
of this writing, the default stack size was ``16384`` and the default maximum
|
||||
strings per rule was ``10000``.
|
||||
|
||||
Here are a few example calls:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
yara.set_config(stack_size=65536)
|
||||
yara.set_config(max_strings_per_rule=50000, stack_size=65536)
|
||||
yara.set_config(max_strings_per_rule=20000)
|
||||
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. py:module:: yara
|
||||
|
||||
.. py:function:: yara.compile(...)
|
||||
|
||||
Compile YARA sources.
|
||||
|
||||
Either *filepath*, *source*, *file*, *filepaths* or *sources* must be
|
||||
provided. The remaining arguments are optional.
|
||||
|
||||
:param str filepath: Path to the source file.
|
||||
:param str source: String containing the rules code.
|
||||
:param file-object file: Source file as a file object.
|
||||
:param dict filepaths: Dictionary where keys are namespaces and values are
|
||||
paths to source files.
|
||||
:param dict sources: Dictionary where keys are namespaces and values are
|
||||
strings containing rules code.
|
||||
:param dict externals: Dictionary with external variables. Keys are variable
|
||||
names and values are variable values.
|
||||
:param boolean includes: True if include directives are allowed or False
|
||||
otherwise. Default value: *True*.
|
||||
:param boolean error_on_warning: If true warnings are treated as errors,
|
||||
raising an exception.
|
||||
:return: Compiled rules object.
|
||||
:rtype: :py:class:`yara.Rules`
|
||||
:raises YaraSyntaxError: If a syntax error was found.
|
||||
:raises YaraError: If an error occurred.
|
||||
|
||||
.. py:function:: yara.load(...)
|
||||
|
||||
.. versionchanged:: 3.4.0
|
||||
|
||||
Load compiled rules from a path or file object. Either *filepath* or
|
||||
*file* must be provided.
|
||||
|
||||
:param str filepath: Path to a compiled rules file
|
||||
:param file-object file: A file object supporting the ``read`` method.
|
||||
:return: Compiled rules object.
|
||||
:rtype: :py:class:`yara.Rules`
|
||||
:raises: **YaraError**: If an error occurred while loading the file.
|
||||
|
||||
.. py:function:: yara.set_config(...)
|
||||
|
||||
Set the configuration variables accessible through the yr_set_configuration
|
||||
API.
|
||||
|
||||
Provide either *stack_size* or *max_strings_per_rule*. These kwargs take
|
||||
unsigned integer values as input and will assign the provided value to the
|
||||
yr_set_configuration(...) variables YR_CONFIG_STACK_SIZE and
|
||||
YR_CONFIG_MAX_STRINGS_PER_RULE, respectively.
|
||||
|
||||
:param int stack_size: Stack size to use for YR_CONFIG_STACK_SIZE
|
||||
:param int max_strings_per_rule: Maximum number of strings to allow per
|
||||
yara rule. Will be mapped to YR_CONFIG_MAX_STRINGS_PER_RULE.
|
||||
:return: None
|
||||
:rtype: **NoneType**
|
||||
:raises: **YaraError**: If an error occurred.
|
||||
|
||||
.. py:class:: Rules
|
||||
|
||||
Instances of this class are returned by :py:func:`yara.compile` and
|
||||
represents a set of compiled rules.
|
||||
|
||||
.. py:method:: match(filepath, pid, data, externals=None, callback=None, fast=False, timeout=None, modules_data=None, modules_callback=None)
|
||||
|
||||
Scan a file, process memory or data string.
|
||||
|
||||
Either *filepath*, *pid* or *data* must be provided. The remaining
|
||||
arguments are optional.
|
||||
|
||||
:param str filepath: Path to the file to be scanned.
|
||||
:param int pid: Process id to be scanned.
|
||||
:param str data: Data to be scanned.
|
||||
:param dict externals: Dictionary with external variables. Keys are variable
|
||||
names and values are variable values.
|
||||
:param function callback: Callback function invoked for each rule.
|
||||
:param bool fast: If true performs a fast mode scan.
|
||||
:param int timeout: Aborts the scanning when the number of specified seconds
|
||||
have elapsed.
|
||||
:param dict modules_data: Dictionary with additional data to modules. Keys
|
||||
are module names and values are *bytes* objects containing the additional
|
||||
data.
|
||||
:param function modules_callback: Callback function invoked for each module.
|
||||
:raises YaraTimeoutError: If the timeout was reached.
|
||||
:raises YaraError: If an error occurred during the scan.
|
||||
|
||||
.. py:method:: save(...)
|
||||
|
||||
.. versionchanged:: 3.4.0
|
||||
|
||||
Save compiled rules to a file. Either *filepath* or *file* must be provided.
|
||||
|
||||
:param str filepath: Path to the file.
|
||||
:param file-object file: A file object supporting the ``write`` method.
|
||||
:raises: **YaraError**: If an error occurred while saving the file.
|
||||
Binary file not shown.
@@ -0,0 +1,33 @@
|
||||
/L20"YARA rules" YARA_LANG Line Comment = // Block Comment On = /* Block Comment Off = */ Escape Char = \ String Chars = " File Extensions = YAR
|
||||
/Marker Characters = "//"
|
||||
/Delimiters = ~!@%^&*()-+=|\/{}[]<>:;"' , .?
|
||||
/Function String = "rule [a-zA-Z0-9_]*"
|
||||
/Indent Strings = "{"
|
||||
/Unindent Strings = "}"
|
||||
/Open Brace Strings = "{" "(" "["
|
||||
/Close Brace Strings = "}" ")" "]"
|
||||
|
||||
/C1"YARA Keywords"
|
||||
and at any all ascii
|
||||
condition contains
|
||||
entrypoint
|
||||
for false filesize fullword
|
||||
global
|
||||
is in include int8 int16 int32
|
||||
meta matches
|
||||
nocase not
|
||||
or of
|
||||
private
|
||||
rule rva
|
||||
section strings
|
||||
them true
|
||||
uint8 uint16 uint32
|
||||
wide
|
||||
|
||||
/C4"YARA Strings"
|
||||
"
|
||||
// /
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="2800px" height="2800px" viewBox="0 0 2800 2800" enable-background="new 0 0 2800 2800" xml:space="preserve">
|
||||
<g>
|
||||
<defs>
|
||||
<rect id="SVGID_1_" width="2800" height="2800"/>
|
||||
</defs>
|
||||
<clipPath id="SVGID_2_">
|
||||
<use xlink:href="#SVGID_1_" overflow="visible"/>
|
||||
</clipPath>
|
||||
<path clip-path="url(#SVGID_2_)" fill-rule="evenodd" clip-rule="evenodd" fill="#C42A2B" d="M879.408,1390.265
|
||||
c0,96.75,0.138,296,0.138,296s-86.502-0.023-126.786,0.082c-4.489,0.007-6.872,0.252-5.338-6.005
|
||||
c2.298-9.372,4.265-19.155,7.469-27.977c2.122-5.844,5.241-10.942,7.444-16.512c2.302-5.814,6.336-12.029,1.66-18.827
|
||||
c-2.173-3.167-4.587-5.339-8.635-5.176c-8.573,0.345-17.162,1.06-25.717,0.795c-6.21-0.186-12.714-0.085-18.247-4.046
|
||||
c-4.425-3.164-6.256-6.485-9.051-12.415c-1.726-3.66-2.442-6.129-2.842-9.799c-1.005-9.217,2.249-13.657,5.294-19.848
|
||||
c5.829-11.851,11.624-22.12,17.867-32.878c5.584-9.623,12.827-18.289,19.391-27.336c11.743-16.177,23.752-32.205,33.866-49.446
|
||||
c3.918-6.676,8.181-13.621,7.407-22.375c-0.781-8.847-4.462-13.378-12.623-16.859c-7.263-3.094-14.767-5.554-22.161-8.013
|
||||
c-7.987-2.657-16.111-5.037-24.1-7.866c-7.632-2.703-15.252-5.31-22.866-8.156c-1.996-0.746-1.644-0.622-3.473-1.209
|
||||
c-0.573-0.184-3.692-0.89-3.762-1.259c-0.162-0.844,0.647-0.889,1.234-1.109c5.999-2.251,11.033-3.756,16.537-5.736
|
||||
c5.989-2.155,12.163-4.076,18.316-5.758c4.9-1.339,9.72-2.936,14.606-4.31c5.715-1.606,11.366-3.449,17.046-5.186
|
||||
c4.994-1.527,10.104-2.916,14.998-4.516c8.632-2.822,17.748-5.195,21.505-13.748c0.517-1.177,0.75-2.611,0.889-3.954
|
||||
c1.135-10.837-1.698-20.822-5.442-30.95c-2.75-7.443-5.601-14.92-7.936-22.56c-2.438-7.976-5.795-15.667-8.285-23.628
|
||||
c-1.357-4.346-2.603-8.874-3.726-13.123c-1.838-6.951-3.178-13.781-4.649-20.449c-2.67-12.102-3.295-24.021-3.397-36.139
|
||||
c-0.069-8.351,1.674-16.247,7.236-22.996c3.467-4.208,7.099-6.853,12.829-8.463c10.68-3,25.52-3.515,40.042-2.178
|
||||
c8.177,0.753,17.732,0.923,20.459-7.923c1.015-3.291,0.526-7.372,0.578-11.03c0.149-10.551-0.691-20.045-0.214-32.101
|
||||
c0.178-4.487,0.545-9.524,0.576-14.341c0.046-6.884,0.004-6.884,7.11-6.882c6.197,0,24.888,0.134,24.888,0.134
|
||||
s0.006,3.228-0.004,5.815c-0.201,65.246-0.132,130.493-0.132,195.741V1390.265z"/>
|
||||
<path clip-path="url(#SVGID_2_)" fill-rule="evenodd" clip-rule="evenodd" fill="#C42A2B" d="M735.789,1094.061
|
||||
c-14.538,4.643-27.112,12.524-38.714,21.756c-9.016,7.173-16.059,16.18-22.051,26.303c-5.76,9.721-9.635,19.965-11.518,30.739
|
||||
c-0.983,5.627-0.969,11.637-1.026,17.47c-0.08,8.429-0.634,17,0.64,25.259c1.339,8.679,2.627,17.432,4.99,26.021
|
||||
c1.597,5.806,2.757,11.831,4.414,17.671c1.717,6.054,3.96,12.618,5.413,17.83c1.041,3.734,2.21,7.502,3.192,11.153
|
||||
c2.373,8.813,4.79,17.518,7.705,26.272c1.31,3.934,0.966,2.669,3.067,10.72c1.802,6.906-1.418,10.151-8.207,12.175
|
||||
c-9.051,2.697-17.968,5.726-26.873,8.965c-7.453,2.711-15.11,5.165-22.781,7.365c-6.61,1.895-11.986,8.472-13.65,15.025
|
||||
c-2.341,9.22-3.519,17.742-4.868,27.048c-0.604,4.167-1.018,8.825-1.332,13.282c-1.018,14.424,3.936,15.239,14.787,19.709
|
||||
c7.319,3.02,14.729,5.794,22.112,8.703c3.719,1.466,7.673,2.826,11.349,4.254c3.235,1.257,6.064,2.438,8.573,4.125
|
||||
c2.685,1.803,1.633,4.901-0.179,7.702c-7.473,11.561-16.215,22.144-24.817,32.835c-12.469,15.488-24.241,31.541-33.894,48.882
|
||||
c-6.146,11.041-10.32,23.152-14.826,35.085c-6.512,17.236-8.302,34.808-5.441,52.141c0.856,5.189,2.493,9.838,3.927,14.665
|
||||
c2.453,8.252,6.012,16.253,11.395,23.267c8.319,10.838,18.791,18.688,31.551,23.518c0.753,0.287,1.936,0.244,1.821,1.347
|
||||
c-0.125,1.188-1.354,0.811-2.086,0.819c-7.916,0.08-15.835,0.108-23.754,0.112c-16.871,0.014-55.885-0.013-55.885-0.013
|
||||
s0.309-176.078,0.309-261.638c0-108.286-0.309-330.435-0.309-330.435s115.598-0.133,170.343-0.133H735.789z"/>
|
||||
<path clip-path="url(#SVGID_2_)" d="M1050.408,1213.489v216.623c0,34.472,18.1,51.705,54.319,51.705h85.734v-268.328h93.587v359.95
|
||||
c0,37.962-9.929,63.259-29.777,75.917c-19.858,12.648-32.181,20.174-36.979,22.579c-4.804,2.394-10.256,4.685-16.36,6.871
|
||||
c-6.983,1.741-15.165,3.271-24.542,4.582c-9.386,1.308-20.185,1.964-32.397,1.964H961.402v-75.915h189.792
|
||||
c10.47,0,19.634-3.713,27.487-11.13c7.854-7.424,11.78-16.359,11.78-26.832v-13.743h-107.33c-21.822,0-39.381-2.392-52.684-7.198
|
||||
c-13.313-4.797-29.123-16.361-47.448-34.688c-18.324-18.321-27.487-44.501-27.487-78.531v-223.825H1050.408z"/>
|
||||
<path clip-path="url(#SVGID_2_)" d="M1424.1,1557.731c-28.796,0-52.91-9.489-72.315-28.467
|
||||
c-19.42-18.981-29.124-42.429-29.124-70.357c0-29.665,9.049-54.204,27.16-73.625c18.099-19.408,40.904-29.122,68.391-29.122
|
||||
h162.957v-18.324c0-15.269-5.238-27.263-15.707-35.997c-10.467-8.722-25.52-13.088-45.153-13.088h-174.743v-75.263h149.215h28.144
|
||||
h30.102c17.885,0,33.921,2.843,48.106,8.53c14.175,5.684,27.26,14.203,39.267,25.574c11.99,11.37,20.826,26.013,26.502,43.93
|
||||
c5.669,17.926,8.51,41.312,8.51,70.159v196.05H1424.1z M1581.168,1481.816v-60.864H1462.06c-11.353,0-20.944,3.271-28.796,9.815
|
||||
c-7.854,6.546-11.783,14.623-11.783,24.213c0,7.425,3.488,13.743,10.474,18.982c6.974,5.233,15.707,7.854,26.178,7.854H1581.168z"
|
||||
/>
|
||||
<path clip-path="url(#SVGID_2_)" d="M1723.18,1213.489h94.893v47.121c6.109-15.892,15.813-28.918,29.129-39.083
|
||||
c13.302-10.154,30.858-15.237,52.683-15.237c5.233,0,12.431,0.879,21.597,2.638v80.477h-103.408v268.327h-94.893V1213.489z"/>
|
||||
<path clip-path="url(#SVGID_2_)" d="M2032.729,1557.731c-28.794,0-52.91-9.489-72.316-28.467
|
||||
c-19.42-18.981-29.124-42.429-29.124-70.357c0-29.665,9.05-54.204,27.159-73.625c18.101-19.408,40.903-29.122,68.393-29.122
|
||||
h162.959v-18.324c0-15.269-5.238-27.263-15.707-35.997c-10.473-8.722-25.523-13.088-45.158-13.088h-174.74v-75.263h149.217h28.139
|
||||
h30.105c17.887,0,33.92,2.843,48.102,8.53c14.178,5.684,27.264,14.203,39.27,25.574c11.994,11.37,20.83,26.013,26.506,43.93
|
||||
c5.662,17.926,8.506,41.312,8.506,70.159v196.05H2032.729z M2189.799,1481.816v-60.864h-119.115
|
||||
c-11.346,0-20.941,3.271-28.793,9.815c-7.855,6.546-11.78,14.623-11.78,24.213c0,7.425,3.489,13.743,10.473,18.982
|
||||
c6.975,5.233,15.707,7.854,26.176,7.854H2189.799z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.0 KiB |
Binary file not shown.
@@ -0,0 +1,184 @@
|
||||
|
||||
MODULES = modules/tests.c
|
||||
MODULES += modules/pe.c
|
||||
MODULES += modules/elf.c
|
||||
MODULES += modules/math.c
|
||||
MODULES += modules/time.c
|
||||
|
||||
# This isn't really a module, but needs to be compiled with them.
|
||||
MODULES += modules/pe_utils.c
|
||||
|
||||
if CUCKOO_MODULE
|
||||
MODULES += modules/cuckoo.c
|
||||
endif
|
||||
|
||||
if MAGIC_MODULE
|
||||
MODULES += modules/magic.c
|
||||
endif
|
||||
|
||||
if HASH_MODULE
|
||||
MODULES += modules/hash.c
|
||||
endif
|
||||
|
||||
if DOTNET_MODULE
|
||||
MODULES += modules/dotnet.c
|
||||
endif
|
||||
|
||||
if MACHO_MODULE
|
||||
MODULES += modules/macho.c
|
||||
endif
|
||||
|
||||
if DEX_MODULE
|
||||
MODULES += modules/dex.c
|
||||
endif
|
||||
|
||||
#
|
||||
# Add your modules here:
|
||||
#
|
||||
# MODULES += modules/yourmodule.c
|
||||
#
|
||||
|
||||
AM_YFLAGS=-d
|
||||
|
||||
AM_CFLAGS=-Wall -Wno-deprecated-declarations -std=gnu99 -I$(srcdir)/include
|
||||
|
||||
if DEBUG
|
||||
AM_CFLAGS+=-g
|
||||
endif
|
||||
|
||||
if OPTIMIZATION
|
||||
AM_CFLAGS+=-O3
|
||||
else
|
||||
AM_CFLAGS+=-O0
|
||||
endif
|
||||
|
||||
if ADDRESS_SANITIZER
|
||||
AM_CFLAGS+=-fsanitize=address
|
||||
endif
|
||||
|
||||
if GCC
|
||||
AM_CFLAGS+=-fvisibility=hidden
|
||||
endif
|
||||
|
||||
ACLOCAL_AMFLAGS=-I m4
|
||||
|
||||
include_HEADERS = include/yara.h
|
||||
|
||||
yaraincludedir = $(includedir)/yara
|
||||
yarainclude_HEADERS = \
|
||||
include/yara/ahocorasick.h \
|
||||
include/yara/arena.h \
|
||||
include/yara/atoms.h \
|
||||
include/yara/compiler.h \
|
||||
include/yara/error.h \
|
||||
include/yara/exec.h \
|
||||
include/yara/exefiles.h \
|
||||
include/yara/filemap.h \
|
||||
include/yara/hash.h \
|
||||
include/yara/integers.h \
|
||||
include/yara/libyara.h \
|
||||
include/yara/limits.h \
|
||||
include/yara/mem.h \
|
||||
include/yara/modules.h \
|
||||
include/yara/object.h \
|
||||
include/yara/parser.h \
|
||||
include/yara/proc.h \
|
||||
include/yara/re.h \
|
||||
include/yara/rules.h \
|
||||
include/yara/scan.h \
|
||||
include/yara/scanner.h \
|
||||
include/yara/sizedstr.h \
|
||||
include/yara/stopwatch.h \
|
||||
include/yara/stream.h \
|
||||
include/yara/strutils.h \
|
||||
include/yara/threading.h \
|
||||
include/yara/types.h \
|
||||
include/yara/utils.h
|
||||
|
||||
noinst_HEADERS = \
|
||||
crypto.h \
|
||||
exception.h \
|
||||
include/yara/dotnet.h \
|
||||
include/yara/elf.h \
|
||||
include/yara/endian.h \
|
||||
include/yara/globals.h \
|
||||
include/yara/hex_lexer.h \
|
||||
include/yara/lexer.h \
|
||||
include/yara/pe.h \
|
||||
include/yara/pe_utils.h \
|
||||
include/yara/re_lexer.h \
|
||||
modules/module_list
|
||||
|
||||
|
||||
lib_LTLIBRARIES = libyara.la
|
||||
|
||||
libyara_la_LDFLAGS = -version-number 3:7:0
|
||||
|
||||
BUILT_SOURCES = \
|
||||
lexer.c \
|
||||
hex_lexer.c \
|
||||
re_lexer.c \
|
||||
grammar.c \
|
||||
hex_grammar.c \
|
||||
re_grammar.c
|
||||
|
||||
libyara_la_SOURCES = \
|
||||
$(MODULES) \
|
||||
grammar.y \
|
||||
ahocorasick.c \
|
||||
arena.c \
|
||||
atoms.c \
|
||||
compiler.c \
|
||||
endian.c \
|
||||
exec.c \
|
||||
exefiles.c \
|
||||
filemap.c \
|
||||
hash.c \
|
||||
hex_grammar.y \
|
||||
hex_lexer.l \
|
||||
lexer.l \
|
||||
libyara.c \
|
||||
mem.c \
|
||||
modules.c \
|
||||
object.c \
|
||||
parser.c \
|
||||
proc.c \
|
||||
re.c \
|
||||
re_grammar.y \
|
||||
re_lexer.l \
|
||||
rules.c \
|
||||
scan.c \
|
||||
scanner.c \
|
||||
sizedstr.c \
|
||||
stopwatch.c \
|
||||
strutils.c \
|
||||
stream.c \
|
||||
threading.c
|
||||
|
||||
|
||||
if USE_WINDOWS_PROC
|
||||
libyara_la_SOURCES += proc/windows.c
|
||||
endif
|
||||
|
||||
if USE_LINUX_PROC
|
||||
libyara_la_SOURCES += proc/linux.c
|
||||
endif
|
||||
|
||||
if USE_FREEBSD_PROC
|
||||
libyara_la_SOURCES += proc/freebsd.c
|
||||
endif
|
||||
|
||||
if USE_OPENBSD_PROC
|
||||
libyara_la_SOURCES += proc/openbsd.c
|
||||
endif
|
||||
|
||||
if USE_MACH_PROC
|
||||
libyara_la_SOURCES += proc/mach.c
|
||||
endif
|
||||
|
||||
if USE_NO_PROC
|
||||
libyara_la_SOURCES += proc/none.c
|
||||
endif
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
nodist_pkgconfig_DATA = yara.pc
|
||||
@@ -0,0 +1,969 @@
|
||||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <yara/arena.h>
|
||||
#include <yara/ahocorasick.h>
|
||||
#include <yara/error.h>
|
||||
#include <yara/utils.h>
|
||||
#include <yara/mem.h>
|
||||
|
||||
|
||||
|
||||
typedef struct _QUEUE_NODE
|
||||
{
|
||||
YR_AC_STATE* value;
|
||||
|
||||
struct _QUEUE_NODE* previous;
|
||||
struct _QUEUE_NODE* next;
|
||||
|
||||
} QUEUE_NODE;
|
||||
|
||||
|
||||
typedef struct _QUEUE
|
||||
{
|
||||
QUEUE_NODE* head;
|
||||
QUEUE_NODE* tail;
|
||||
|
||||
} QUEUE;
|
||||
|
||||
|
||||
//
|
||||
// _yr_ac_queue_push
|
||||
//
|
||||
// Pushes a state in a queue.
|
||||
//
|
||||
// Args:
|
||||
// QUEUE* queue - The queue
|
||||
// YR_AC_STATE* state - The state
|
||||
//
|
||||
// Returns:
|
||||
// ERROR_SUCCESS if succeed or the corresponding error code otherwise.
|
||||
//
|
||||
|
||||
static int _yr_ac_queue_push(
|
||||
QUEUE* queue,
|
||||
YR_AC_STATE* value)
|
||||
{
|
||||
QUEUE_NODE* pushed_node;
|
||||
|
||||
pushed_node = (QUEUE_NODE*) yr_malloc(sizeof(QUEUE_NODE));
|
||||
|
||||
if (pushed_node == NULL)
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
|
||||
pushed_node->previous = queue->tail;
|
||||
pushed_node->next = NULL;
|
||||
pushed_node->value = value;
|
||||
|
||||
if (queue->tail != NULL)
|
||||
queue->tail->next = pushed_node;
|
||||
else // queue is empty
|
||||
queue->head = pushed_node;
|
||||
|
||||
queue->tail = pushed_node;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// _yr_ac_queue_pop
|
||||
//
|
||||
// Pops a state from a queue.
|
||||
//
|
||||
// Args:
|
||||
// QUEUE* queue - The queue
|
||||
//
|
||||
// Returns:
|
||||
// Pointer to the poped state.
|
||||
//
|
||||
|
||||
static YR_AC_STATE* _yr_ac_queue_pop(
|
||||
QUEUE* queue)
|
||||
{
|
||||
YR_AC_STATE* result;
|
||||
QUEUE_NODE* popped_node;
|
||||
|
||||
if (queue->head == NULL)
|
||||
return NULL;
|
||||
|
||||
popped_node = queue->head;
|
||||
queue->head = popped_node->next;
|
||||
|
||||
if (queue->head)
|
||||
queue->head->previous = NULL;
|
||||
else // queue is empty
|
||||
queue->tail = NULL;
|
||||
|
||||
result = popped_node->value;
|
||||
|
||||
yr_free(popped_node);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// _yr_ac_queue_is_empty
|
||||
//
|
||||
// Checks if a queue is empty.
|
||||
//
|
||||
// Args:
|
||||
// QUEUE* queue - The queue
|
||||
//
|
||||
// Returns:
|
||||
// TRUE if queue is empty, FALSE otherwise.
|
||||
//
|
||||
|
||||
static int _yr_ac_queue_is_empty(
|
||||
QUEUE* queue)
|
||||
{
|
||||
return queue->head == NULL;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// _yr_ac_next_state
|
||||
//
|
||||
// Given an automaton state and an input symbol, returns the new state
|
||||
// after reading the input symbol.
|
||||
//
|
||||
// Args:
|
||||
// YR_AC_STATE* state - Automaton state
|
||||
// uint8_t input - Input symbol
|
||||
//
|
||||
// Returns:
|
||||
// Pointer to the next automaton state.
|
||||
//
|
||||
|
||||
static YR_AC_STATE* _yr_ac_next_state(
|
||||
YR_AC_STATE* state,
|
||||
uint8_t input)
|
||||
{
|
||||
YR_AC_STATE* next_state = state->first_child;
|
||||
|
||||
while (next_state != NULL)
|
||||
{
|
||||
if (next_state->input == input)
|
||||
return next_state;
|
||||
|
||||
next_state = next_state->siblings;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// _yr_ac_state_create
|
||||
//
|
||||
// Creates a new automaton state, the automaton will transition from
|
||||
// the given state to the new state after reading the input symbol.
|
||||
//
|
||||
// Args:
|
||||
// YR_AC_STATE* state - Origin state
|
||||
// uint8_t input - Input symbol
|
||||
//
|
||||
// Returns:
|
||||
// YR_AC_STATE* pointer to the newly allocated state or NULL in case
|
||||
// of error.
|
||||
|
||||
static YR_AC_STATE* _yr_ac_state_create(
|
||||
YR_AC_STATE* state,
|
||||
uint8_t input)
|
||||
{
|
||||
YR_AC_STATE* new_state = (YR_AC_STATE*) yr_malloc(sizeof(YR_AC_STATE));
|
||||
|
||||
if (new_state == NULL)
|
||||
return NULL;
|
||||
|
||||
new_state->input = input;
|
||||
new_state->depth = state->depth + 1;
|
||||
new_state->matches = NULL;
|
||||
new_state->failure = NULL;
|
||||
new_state->t_table_slot = 0;
|
||||
new_state->first_child = NULL;
|
||||
new_state->siblings = state->first_child;
|
||||
state->first_child = new_state;
|
||||
|
||||
return new_state;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// _yr_ac_state_destroy
|
||||
//
|
||||
|
||||
static int _yr_ac_state_destroy(
|
||||
YR_AC_STATE* state)
|
||||
{
|
||||
YR_AC_STATE* child_state = state->first_child;
|
||||
|
||||
while (child_state != NULL)
|
||||
{
|
||||
YR_AC_STATE* next_child_state = child_state->siblings;
|
||||
_yr_ac_state_destroy(child_state);
|
||||
child_state = next_child_state;
|
||||
}
|
||||
|
||||
yr_free(state);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// _yr_ac_create_failure_links
|
||||
//
|
||||
// Create failure links for each automaton state. This function must
|
||||
// be called after all the strings have been added to the automaton.
|
||||
//
|
||||
|
||||
static int _yr_ac_create_failure_links(
|
||||
YR_AC_AUTOMATON* automaton)
|
||||
{
|
||||
YR_AC_STATE* current_state;
|
||||
YR_AC_STATE* failure_state;
|
||||
YR_AC_STATE* temp_state;
|
||||
YR_AC_STATE* state;
|
||||
YR_AC_STATE* transition_state;
|
||||
YR_AC_STATE* root_state;
|
||||
YR_AC_MATCH* match;
|
||||
|
||||
QUEUE queue;
|
||||
|
||||
queue.head = NULL;
|
||||
queue.tail = NULL;
|
||||
|
||||
root_state = automaton->root;
|
||||
|
||||
// Set the failure link of root state to itself.
|
||||
root_state->failure = root_state;
|
||||
|
||||
// Push root's children and set their failure link to root.
|
||||
|
||||
state = root_state->first_child;
|
||||
|
||||
while (state != NULL)
|
||||
{
|
||||
FAIL_ON_ERROR(_yr_ac_queue_push(&queue, state));
|
||||
state->failure = root_state;
|
||||
state = state->siblings;
|
||||
}
|
||||
|
||||
// Traverse the trie in BFS order calculating the failure link
|
||||
// for each state.
|
||||
|
||||
while (!_yr_ac_queue_is_empty(&queue))
|
||||
{
|
||||
current_state = _yr_ac_queue_pop(&queue);
|
||||
|
||||
match = current_state->matches;
|
||||
|
||||
if (match != NULL)
|
||||
{
|
||||
while (match->next != NULL)
|
||||
match = match->next;
|
||||
|
||||
if (match->backtrack > 0)
|
||||
match->next = root_state->matches;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_state->matches = root_state->matches;
|
||||
}
|
||||
|
||||
transition_state = current_state->first_child;
|
||||
|
||||
while (transition_state != NULL)
|
||||
{
|
||||
FAIL_ON_ERROR(_yr_ac_queue_push(&queue, transition_state));
|
||||
failure_state = current_state->failure;
|
||||
|
||||
while (1)
|
||||
{
|
||||
temp_state = _yr_ac_next_state(
|
||||
failure_state, transition_state->input);
|
||||
|
||||
if (temp_state != NULL)
|
||||
{
|
||||
transition_state->failure = temp_state;
|
||||
|
||||
if (transition_state->matches == NULL)
|
||||
{
|
||||
transition_state->matches = temp_state->matches;
|
||||
}
|
||||
else
|
||||
{
|
||||
match = transition_state->matches;
|
||||
|
||||
while (match != NULL && match->next != NULL)
|
||||
match = match->next;
|
||||
|
||||
match->next = temp_state->matches;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (failure_state == root_state)
|
||||
{
|
||||
transition_state->failure = root_state;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
failure_state = failure_state->failure;
|
||||
}
|
||||
}
|
||||
} // while(1)
|
||||
|
||||
transition_state = transition_state->siblings;
|
||||
}
|
||||
|
||||
} // while(!__yr_ac_queue_is_empty(&queue))
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// _yr_ac_transitions_subset
|
||||
//
|
||||
// Returns true if the transitions for state s2 are a subset of the transitions
|
||||
// for state s1. In other words, if at state s2 input X is accepted, it must be
|
||||
// accepted in s1 too.
|
||||
//
|
||||
|
||||
static int _yr_ac_transitions_subset(
|
||||
YR_AC_STATE* s1,
|
||||
YR_AC_STATE* s2)
|
||||
{
|
||||
uint8_t set[32];
|
||||
|
||||
YR_AC_STATE* state = s1->first_child;
|
||||
|
||||
memset(set, 0, 32);
|
||||
|
||||
while (state != NULL)
|
||||
{
|
||||
set[state->input / 8] |= 1 << state->input % 8;
|
||||
state = state->siblings;
|
||||
}
|
||||
|
||||
state = s2->first_child;
|
||||
|
||||
while (state != NULL)
|
||||
{
|
||||
if (!(set[state->input / 8] & 1 << state->input % 8))
|
||||
return FALSE;
|
||||
|
||||
state = state->siblings;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// _yr_ac_optimize_failure_links
|
||||
//
|
||||
// Removes unnecessary failure links.
|
||||
//
|
||||
|
||||
static int _yr_ac_optimize_failure_links(
|
||||
YR_AC_AUTOMATON* automaton)
|
||||
{
|
||||
QUEUE queue = { NULL, NULL};
|
||||
|
||||
// Push root's children.
|
||||
|
||||
YR_AC_STATE* root_state = automaton->root;
|
||||
YR_AC_STATE* state = root_state->first_child;
|
||||
|
||||
while (state != NULL)
|
||||
{
|
||||
FAIL_ON_ERROR(_yr_ac_queue_push(&queue, state));
|
||||
state = state->siblings;
|
||||
}
|
||||
|
||||
while (!_yr_ac_queue_is_empty(&queue))
|
||||
{
|
||||
YR_AC_STATE* current_state = _yr_ac_queue_pop(&queue);
|
||||
|
||||
if (current_state->failure != root_state)
|
||||
{
|
||||
if (_yr_ac_transitions_subset(current_state, current_state->failure))
|
||||
current_state->failure = current_state->failure->failure;
|
||||
}
|
||||
|
||||
// Push childrens of current_state
|
||||
state = current_state->first_child;
|
||||
|
||||
while (state != NULL)
|
||||
{
|
||||
FAIL_ON_ERROR(_yr_ac_queue_push(&queue, state));
|
||||
state = state->siblings;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// _yr_ac_find_suitable_transition_table_slot
|
||||
//
|
||||
// Find a place within the transition table where the transitions for the given
|
||||
// state can be put. The function first searches for an unused slot to put the
|
||||
// failure link, then it checks if the slots corresponding to the state
|
||||
// transitions (wich are at offsets 1 to 256 relative to the failure link ) are
|
||||
// available too.
|
||||
//
|
||||
|
||||
static int _yr_ac_find_suitable_transition_table_slot(
|
||||
YR_AC_AUTOMATON* automaton,
|
||||
YR_AC_STATE* state,
|
||||
uint32_t* slot)
|
||||
{
|
||||
YR_AC_STATE* child_state;
|
||||
|
||||
uint32_t i = automaton->t_table_unused_candidate;
|
||||
|
||||
int first_unused = TRUE;
|
||||
int found = FALSE;
|
||||
|
||||
while (!found)
|
||||
{
|
||||
// Check if there is enough room in the table to hold 257 items
|
||||
// (1 failure link + 256 transitions) starting at offset i. If there's
|
||||
// no room double the table size.
|
||||
|
||||
if (automaton->tables_size - i < 257)
|
||||
{
|
||||
size_t t_bytes_size = automaton->tables_size *
|
||||
sizeof(YR_AC_TRANSITION);
|
||||
|
||||
size_t m_bytes_size = automaton->tables_size *
|
||||
sizeof(YR_AC_MATCH_TABLE_ENTRY);
|
||||
|
||||
automaton->t_table = (YR_AC_TRANSITION_TABLE) yr_realloc(
|
||||
automaton->t_table, t_bytes_size * 2);
|
||||
|
||||
automaton->m_table = (YR_AC_MATCH_TABLE) yr_realloc(
|
||||
automaton->m_table, m_bytes_size * 2);
|
||||
|
||||
if (automaton->t_table == NULL || automaton->m_table == NULL)
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
|
||||
memset((uint8_t*) automaton->t_table + t_bytes_size, 0, t_bytes_size);
|
||||
memset((uint8_t*) automaton->m_table + m_bytes_size, 0, m_bytes_size);
|
||||
|
||||
automaton->tables_size *= 2;
|
||||
}
|
||||
|
||||
if (YR_AC_UNUSED_TRANSITION_SLOT(automaton->t_table[i]))
|
||||
{
|
||||
// A unused slot in the table has been found and could be a potential
|
||||
// candidate. Let's check if table slots for the transitions are
|
||||
// unused too.
|
||||
|
||||
found = TRUE;
|
||||
child_state = state->first_child;
|
||||
|
||||
while (child_state != NULL)
|
||||
{
|
||||
if (YR_AC_USED_TRANSITION_SLOT(
|
||||
automaton->t_table[child_state->input + i + 1]))
|
||||
{
|
||||
found = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
child_state = child_state->siblings;
|
||||
}
|
||||
|
||||
// If this is the first unused entry we found, use it as the first
|
||||
// candidate in the next call to this function.
|
||||
|
||||
if (first_unused)
|
||||
{
|
||||
automaton->t_table_unused_candidate = found ? i + 1 : i;
|
||||
first_unused = FALSE;
|
||||
}
|
||||
|
||||
if (found)
|
||||
*slot = i;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// _yr_ac_build_transition_table
|
||||
//
|
||||
// Builds the transition table for the automaton. The transition table (T) is a
|
||||
// large array of 64-bits integers. Each state in the automaton is represented
|
||||
// by an offset S within the array. The integer stored in T[S] is the failure
|
||||
// link for state S, it contains the offset for the next state when no valid
|
||||
// transition exists for the next input byte.
|
||||
//
|
||||
// At position T[S+1+B] (where B is a byte) we can find the transition (if any)
|
||||
// that must be followed from state S if the next input is B. The value in
|
||||
// T[S+1+B] contains the offset for next state or 0. The 0 means that no
|
||||
// valid transition exists from state S when next input is B, and the failure
|
||||
// link must be used instead.
|
||||
//
|
||||
// The transition table for state S starts at T[S] and spans the next 257
|
||||
// slots in the array (1 for the failure link and 256 for all the possible
|
||||
// transitions). But many of those slots are for invalid transitions, so
|
||||
// the transitions for multiple states can be interleaved as long as they don't
|
||||
// collide. For example, instead of having this transition table with state S1
|
||||
// and S2 separated by a large number of slots:
|
||||
//
|
||||
// S1 S2
|
||||
// +------+------+------+------+-- ~ --+------+------+------+-- ~ --+
|
||||
// | FLS1 | X | - | - | - | Y | FLS2 | Z | - |
|
||||
// +------+------+------+------+-- ~ --+------+------+------+-- ~ --+
|
||||
//
|
||||
// We can interleave the transitions for states S1 and S2 and get this other
|
||||
// transition table, which is more compact:
|
||||
//
|
||||
// S1 S2
|
||||
// +------+------+------+------+-- ~ --+------+
|
||||
// | FLS1 | X | FLS2 | Z | - | Y |
|
||||
// +------+------+------+------+-- ~ --+------+
|
||||
//
|
||||
// And how do we know that transition Z belongs to state S2 and not S1? Or that
|
||||
// transition Y belongs to S1 and not S2? Because each slot of the array not
|
||||
// only contains the offset for the state where the transition points to, it
|
||||
// also contains the offset of the transition relative to its owner state. So,
|
||||
// the value for the owner offset would be 1 for transitions X, because X
|
||||
// belongs to state S1 and it's located 1 position away from S1. The same occurs
|
||||
// for Z, it belongs to S2 and it's located one position away from S2 so its
|
||||
// owner offset is 1. If we are in S1 and next byte is 2, we are going to read
|
||||
// the transition at T[S1+1+2] which is Z. But we know that transition Z is not
|
||||
// a valid transition for state S1 because the owner offset for Z is 1 not 3.
|
||||
//
|
||||
// A more detailed description can be found in: http://goo.gl/lE6zG
|
||||
|
||||
|
||||
static int _yr_ac_build_transition_table(
|
||||
YR_AC_AUTOMATON* automaton)
|
||||
{
|
||||
YR_AC_STATE* state;
|
||||
YR_AC_STATE* child_state;
|
||||
YR_AC_STATE* root_state = automaton->root;
|
||||
|
||||
uint32_t slot;
|
||||
|
||||
QUEUE queue = { NULL, NULL};
|
||||
|
||||
automaton->tables_size = 1024;
|
||||
|
||||
automaton->t_table = (YR_AC_TRANSITION_TABLE) yr_malloc(
|
||||
automaton->tables_size * sizeof(YR_AC_TRANSITION));
|
||||
|
||||
automaton->m_table = (YR_AC_MATCH_TABLE) yr_malloc(
|
||||
automaton->tables_size * sizeof(YR_AC_MATCH_TABLE_ENTRY));
|
||||
|
||||
if (automaton->t_table == NULL || automaton->m_table == NULL)
|
||||
{
|
||||
yr_free(automaton->t_table);
|
||||
yr_free(automaton->m_table);
|
||||
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
memset(automaton->t_table, 0,
|
||||
automaton->tables_size * sizeof(YR_AC_TRANSITION));
|
||||
|
||||
memset(automaton->m_table, 0,
|
||||
automaton->tables_size * sizeof(YR_AC_MATCH_TABLE_ENTRY));
|
||||
|
||||
automaton->t_table[0] = YR_AC_MAKE_TRANSITION(0, 0, YR_AC_USED_FLAG);
|
||||
automaton->m_table[0].match = root_state->matches;
|
||||
|
||||
// Index 0 is for root node. Unused indexes start at 1.
|
||||
automaton->t_table_unused_candidate = 1;
|
||||
|
||||
child_state = root_state->first_child;
|
||||
|
||||
while (child_state != NULL)
|
||||
{
|
||||
child_state->t_table_slot = child_state->input + 1;
|
||||
automaton->t_table[child_state->input + 1] = YR_AC_MAKE_TRANSITION(
|
||||
0, child_state->input + 1, YR_AC_USED_FLAG);
|
||||
|
||||
FAIL_ON_ERROR(_yr_ac_queue_push(&queue, child_state));
|
||||
child_state = child_state->siblings;
|
||||
}
|
||||
|
||||
while (!_yr_ac_queue_is_empty(&queue))
|
||||
{
|
||||
state = _yr_ac_queue_pop(&queue);
|
||||
|
||||
FAIL_ON_ERROR(_yr_ac_find_suitable_transition_table_slot(
|
||||
automaton,
|
||||
state,
|
||||
&slot));
|
||||
|
||||
automaton->t_table[state->t_table_slot] |= ((uint64_t) slot << 32);
|
||||
|
||||
state->t_table_slot = slot;
|
||||
|
||||
automaton->t_table[slot] = YR_AC_MAKE_TRANSITION(
|
||||
state->failure->t_table_slot, 0, YR_AC_USED_FLAG);
|
||||
|
||||
automaton->m_table[slot].match = state->matches;
|
||||
|
||||
// Push childrens of current_state
|
||||
|
||||
child_state = state->first_child;
|
||||
|
||||
while (child_state != NULL)
|
||||
{
|
||||
child_state->t_table_slot = slot + child_state->input + 1;
|
||||
automaton->t_table[child_state->t_table_slot] = YR_AC_MAKE_TRANSITION(
|
||||
0, child_state->input + 1, YR_AC_USED_FLAG);
|
||||
|
||||
FAIL_ON_ERROR(_yr_ac_queue_push(&queue, child_state));
|
||||
|
||||
child_state = child_state->siblings;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// _yr_ac_print_automaton_state
|
||||
//
|
||||
// Prints automaton state for debug purposes. This function is invoked by
|
||||
// yr_ac_print_automaton, is not intended to be used stand-alone.
|
||||
//
|
||||
|
||||
static void _yr_ac_print_automaton_state(
|
||||
YR_AC_STATE* state)
|
||||
{
|
||||
int i;
|
||||
int child_count;
|
||||
|
||||
YR_AC_MATCH* match;
|
||||
YR_AC_STATE* child_state;
|
||||
|
||||
for (i = 0; i < state->depth; i++)
|
||||
printf(" ");
|
||||
|
||||
child_state = state->first_child;
|
||||
child_count = 0;
|
||||
|
||||
while(child_state != NULL)
|
||||
{
|
||||
child_count++;
|
||||
child_state = child_state->siblings;
|
||||
}
|
||||
|
||||
printf("%p childs:%d depth:%d failure:%p",
|
||||
state, child_count, state->depth, state->failure);
|
||||
|
||||
match = state->matches;
|
||||
|
||||
while (match != NULL)
|
||||
{
|
||||
printf("\n");
|
||||
|
||||
for (i = 0; i < state->depth + 1; i++)
|
||||
printf(" ");
|
||||
|
||||
printf("%s = ", match->string->identifier);
|
||||
|
||||
if (STRING_IS_HEX(match->string))
|
||||
{
|
||||
printf("{ ");
|
||||
|
||||
for (i = 0; i < yr_min(match->string->length, 10); i++)
|
||||
printf("%02x ", match->string->string[i]);
|
||||
|
||||
printf("}");
|
||||
}
|
||||
else if (STRING_IS_REGEXP(match->string))
|
||||
{
|
||||
printf("/");
|
||||
|
||||
for (i = 0; i < yr_min(match->string->length, 10); i++)
|
||||
printf("%c", match->string->string[i]);
|
||||
|
||||
printf("/");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\"");
|
||||
|
||||
for (i = 0; i < yr_min(match->string->length, 10); i++)
|
||||
printf("%c", match->string->string[i]);
|
||||
|
||||
printf("\"");
|
||||
}
|
||||
|
||||
match = match->next;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
child_state = state->first_child;
|
||||
|
||||
while(child_state != NULL)
|
||||
{
|
||||
_yr_ac_print_automaton_state(child_state);
|
||||
child_state = child_state->siblings;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// yr_ac_automaton_create
|
||||
//
|
||||
// Creates a new automaton
|
||||
//
|
||||
|
||||
int yr_ac_automaton_create(
|
||||
YR_AC_AUTOMATON** automaton)
|
||||
{
|
||||
YR_AC_AUTOMATON* new_automaton;
|
||||
YR_AC_STATE* root_state;
|
||||
|
||||
new_automaton = (YR_AC_AUTOMATON*) yr_malloc(sizeof(YR_AC_AUTOMATON));
|
||||
root_state = (YR_AC_STATE*) yr_malloc(sizeof(YR_AC_STATE));
|
||||
|
||||
if (new_automaton == NULL || root_state == NULL)
|
||||
{
|
||||
yr_free(new_automaton);
|
||||
yr_free(root_state);
|
||||
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
root_state->depth = 0;
|
||||
root_state->matches = NULL;
|
||||
root_state->failure = NULL;
|
||||
root_state->first_child = NULL;
|
||||
root_state->siblings = NULL;
|
||||
root_state->t_table_slot = 0;
|
||||
|
||||
new_automaton->root = root_state;
|
||||
new_automaton->m_table = NULL;
|
||||
new_automaton->t_table = NULL;
|
||||
new_automaton->tables_size = 0;
|
||||
|
||||
*automaton = new_automaton;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// yr_ac_automaton_destroy
|
||||
//
|
||||
// Destroys automaton
|
||||
//
|
||||
|
||||
int yr_ac_automaton_destroy(
|
||||
YR_AC_AUTOMATON* automaton)
|
||||
{
|
||||
_yr_ac_state_destroy(automaton->root);
|
||||
|
||||
yr_free(automaton->t_table);
|
||||
yr_free(automaton->m_table);
|
||||
yr_free(automaton);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// yr_ac_add_string
|
||||
//
|
||||
// Adds a string to the automaton. This function is invoked once for each
|
||||
// string defined in the rules.
|
||||
//
|
||||
|
||||
int yr_ac_add_string(
|
||||
YR_AC_AUTOMATON* automaton,
|
||||
YR_STRING* string,
|
||||
YR_ATOM_LIST_ITEM* atom,
|
||||
YR_ARENA* matches_arena)
|
||||
{
|
||||
int result = ERROR_SUCCESS;
|
||||
int i;
|
||||
|
||||
YR_AC_STATE* state;
|
||||
YR_AC_STATE* next_state;
|
||||
YR_AC_MATCH* new_match;
|
||||
|
||||
// For each atom create the states in the automaton.
|
||||
|
||||
while (atom != NULL)
|
||||
{
|
||||
state = automaton->root;
|
||||
|
||||
for (i = 0; i < atom->atom_length; i++)
|
||||
{
|
||||
next_state = _yr_ac_next_state(state, atom->atom[i]);
|
||||
|
||||
if (next_state == NULL)
|
||||
{
|
||||
next_state = _yr_ac_state_create(state, atom->atom[i]);
|
||||
|
||||
if (next_state == NULL)
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
state = next_state;
|
||||
}
|
||||
|
||||
result = yr_arena_allocate_struct(
|
||||
matches_arena,
|
||||
sizeof(YR_AC_MATCH),
|
||||
(void**) &new_match,
|
||||
offsetof(YR_AC_MATCH, string),
|
||||
offsetof(YR_AC_MATCH, forward_code),
|
||||
offsetof(YR_AC_MATCH, backward_code),
|
||||
offsetof(YR_AC_MATCH, next),
|
||||
EOL);
|
||||
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
new_match->backtrack = state->depth + atom->backtrack;
|
||||
new_match->string = string;
|
||||
new_match->forward_code = atom->forward_code;
|
||||
new_match->backward_code = atom->backward_code;
|
||||
new_match->next = state->matches;
|
||||
state->matches = new_match;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
atom = atom->next;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// yr_ac_compile
|
||||
//
|
||||
|
||||
int yr_ac_compile(
|
||||
YR_AC_AUTOMATON* automaton,
|
||||
YR_ARENA* arena,
|
||||
YR_AC_TABLES* tables)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
FAIL_ON_ERROR(_yr_ac_create_failure_links(automaton));
|
||||
FAIL_ON_ERROR(_yr_ac_optimize_failure_links(automaton));
|
||||
FAIL_ON_ERROR(_yr_ac_build_transition_table(automaton));
|
||||
|
||||
FAIL_ON_ERROR(yr_arena_reserve_memory(
|
||||
arena,
|
||||
automaton->tables_size * sizeof(tables->transitions[0]) +
|
||||
automaton->tables_size * sizeof(tables->matches[0])));
|
||||
|
||||
FAIL_ON_ERROR(yr_arena_write_data(
|
||||
arena,
|
||||
automaton->t_table,
|
||||
sizeof(YR_AC_TRANSITION),
|
||||
(void**) &tables->transitions));
|
||||
|
||||
for (i = 1; i < automaton->tables_size; i++)
|
||||
{
|
||||
FAIL_ON_ERROR(yr_arena_write_data(
|
||||
arena,
|
||||
automaton->t_table + i,
|
||||
sizeof(YR_AC_TRANSITION),
|
||||
NULL));
|
||||
}
|
||||
|
||||
FAIL_ON_ERROR(yr_arena_write_data(
|
||||
arena,
|
||||
automaton->m_table,
|
||||
sizeof(YR_AC_MATCH_TABLE_ENTRY),
|
||||
(void**) &tables->matches));
|
||||
|
||||
FAIL_ON_ERROR(yr_arena_make_ptr_relocatable(
|
||||
arena,
|
||||
tables->matches,
|
||||
offsetof(YR_AC_MATCH_TABLE_ENTRY, match),
|
||||
EOL));
|
||||
|
||||
for (i = 1; i < automaton->tables_size; i++)
|
||||
{
|
||||
void* ptr;
|
||||
|
||||
FAIL_ON_ERROR(yr_arena_write_data(
|
||||
arena,
|
||||
automaton->m_table + i,
|
||||
sizeof(YR_AC_MATCH_TABLE_ENTRY),
|
||||
(void**) &ptr));
|
||||
|
||||
FAIL_ON_ERROR(yr_arena_make_ptr_relocatable(
|
||||
arena,
|
||||
ptr,
|
||||
offsetof(YR_AC_MATCH_TABLE_ENTRY, match),
|
||||
EOL));
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// yr_ac_print_automaton
|
||||
//
|
||||
// Prints automaton for debug purposes.
|
||||
//
|
||||
|
||||
void yr_ac_print_automaton(YR_AC_AUTOMATON* automaton)
|
||||
{
|
||||
printf("-------------------------------------------------------\n");
|
||||
_yr_ac_print_automaton_state(automaton->root);
|
||||
printf("-------------------------------------------------------\n");
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
Copyright (c) 2017. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_CRYPTO_H
|
||||
#define YR_CRYPTO_H
|
||||
|
||||
#define YR_MD5_LEN 16
|
||||
#define YR_SHA1_LEN 20
|
||||
#define YR_SHA256_LEN 32
|
||||
|
||||
#if defined(HAVE_LIBCRYPTO)
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
typedef MD5_CTX yr_md5_ctx;
|
||||
typedef SHA_CTX yr_sha1_ctx;
|
||||
typedef SHA256_CTX yr_sha256_ctx;
|
||||
|
||||
#define yr_md5_init(ctx) \
|
||||
MD5_Init(ctx)
|
||||
#define yr_md5_update(ctx,data,len) \
|
||||
MD5_Update(ctx,data,len)
|
||||
#define yr_md5_final(digest,ctx) \
|
||||
MD5_Final(digest,ctx)
|
||||
|
||||
#define yr_sha1_init(ctx) \
|
||||
SHA1_Init(ctx)
|
||||
#define yr_sha1_update(ctx,data,len) \
|
||||
SHA1_Update(ctx,data,len)
|
||||
#define yr_sha1_final(digest,ctx) \
|
||||
SHA1_Final(digest,ctx)
|
||||
|
||||
#define yr_sha256_init(ctx) \
|
||||
SHA256_Init(ctx)
|
||||
#define yr_sha256_update(ctx,data,len) \
|
||||
SHA256_Update(ctx,data,len)
|
||||
#define yr_sha256_final(digest,ctx) \
|
||||
SHA256_Final(digest,ctx)
|
||||
|
||||
#elif defined(HAVE_WINCRYPT_H)
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
HCRYPTPROV yr_cryptprov;
|
||||
|
||||
typedef HCRYPTHASH yr_md5_ctx;
|
||||
typedef HCRYPTHASH yr_sha1_ctx;
|
||||
typedef HCRYPTHASH yr_sha256_ctx;
|
||||
|
||||
#define yr_md5_init(ctx) \
|
||||
CryptCreateHash(yr_cryptprov, CALG_MD5, 0, 0, ctx)
|
||||
#define yr_md5_update(ctx,data,len) \
|
||||
CryptHashData(*ctx, (const BYTE*)data, len, 0)
|
||||
#define yr_md5_final(digest,ctx) { \
|
||||
DWORD len = YR_MD5_LEN; \
|
||||
CryptGetHashParam(*ctx, HP_HASHVAL, digest, &len, 0); \
|
||||
CryptDestroyHash(*ctx); \
|
||||
}
|
||||
|
||||
#define yr_sha1_init(ctx) \
|
||||
CryptCreateHash(yr_cryptprov, CALG_SHA1, 0, 0, ctx)
|
||||
#define yr_sha1_update(ctx,data,len) \
|
||||
CryptHashData(*ctx, (const BYTE*)data, len, 0)
|
||||
#define yr_sha1_final(digest,ctx) { \
|
||||
DWORD len = YR_SHA1_LEN; \
|
||||
CryptGetHashParam(*ctx, HP_HASHVAL, digest, &len, 0); \
|
||||
CryptDestroyHash(*ctx); \
|
||||
}
|
||||
|
||||
#define yr_sha256_init(ctx) \
|
||||
CryptCreateHash(yr_cryptprov, CALG_SHA_256, 0, 0, ctx)
|
||||
#define yr_sha256_update(ctx,data,len) \
|
||||
CryptHashData(*ctx, (const BYTE*)data, len, 0)
|
||||
#define yr_sha256_final(digest,ctx) { \
|
||||
DWORD len = YR_SHA256_LEN; \
|
||||
CryptGetHashParam(*ctx, HP_HASHVAL, digest, &len, 0); \
|
||||
CryptDestroyHash(*ctx); \
|
||||
}
|
||||
|
||||
#elif defined(HAVE_COMMONCRYPTO_COMMONCRYPTO_H)
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
|
||||
typedef CC_MD5_CTX yr_md5_ctx;
|
||||
typedef CC_SHA1_CTX yr_sha1_ctx;
|
||||
typedef CC_SHA256_CTX yr_sha256_ctx;
|
||||
|
||||
#define yr_md5_init(ctx) \
|
||||
CC_MD5_Init(ctx)
|
||||
#define yr_md5_update(ctx,data,len) \
|
||||
CC_MD5_Update(ctx, data, len)
|
||||
#define yr_md5_final(digest,ctx) \
|
||||
CC_MD5_Final(digest, ctx)
|
||||
|
||||
#define yr_sha1_init(ctx) \
|
||||
CC_SHA1_Init(ctx)
|
||||
#define yr_sha1_update(ctx,data,len) \
|
||||
CC_SHA1_Update(ctx, data, len)
|
||||
#define yr_sha1_final(digest,ctx) \
|
||||
CC_SHA1_Final(digest, ctx)
|
||||
|
||||
#define yr_sha256_init(ctx) \
|
||||
CC_SHA256_Init(ctx)
|
||||
#define yr_sha256_update(ctx,data,len) \
|
||||
CC_SHA256_Update(ctx, data, len)
|
||||
#define yr_sha256_final(digest,ctx) \
|
||||
CC_SHA256_Final(digest, ctx)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright (c) 2017. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <yara/endian.h>
|
||||
|
||||
uint16_t _yr_bswap16(uint16_t x)
|
||||
{
|
||||
return (x >> 8 | x << 8);
|
||||
}
|
||||
|
||||
uint32_t _yr_bswap32(uint32_t x)
|
||||
{
|
||||
return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) |
|
||||
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24));
|
||||
}
|
||||
|
||||
uint64_t _yr_bswap64(uint64_t x)
|
||||
{
|
||||
return ((((x) & 0xff00000000000000ull) >> 56)
|
||||
| (((x) & 0x00ff000000000000ull) >> 40)
|
||||
| (((x) & 0x0000ff0000000000ull) >> 24)
|
||||
| (((x) & 0x000000ff00000000ull) >> 8)
|
||||
| (((x) & 0x00000000ff000000ull) << 8)
|
||||
| (((x) & 0x0000000000ff0000ull) << 24)
|
||||
| (((x) & 0x000000000000ff00ull) << 40)
|
||||
| (((x) & 0x00000000000000ffull) << 56));
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
Copyright (c) 2015. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_EXCEPTION_H
|
||||
#define YR_EXCEPTION_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#if _WIN32 || __CYGWIN__
|
||||
|
||||
#include <windows.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
jmp_buf *exc_jmp_buf[MAX_THREADS];
|
||||
|
||||
static LONG CALLBACK exception_handler(
|
||||
PEXCEPTION_POINTERS ExceptionInfo)
|
||||
{
|
||||
int tidx = yr_get_tidx();
|
||||
|
||||
switch(ExceptionInfo->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
case EXCEPTION_IN_PAGE_ERROR:
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
if (tidx != -1 && exc_jmp_buf[tidx] != NULL)
|
||||
longjmp(*exc_jmp_buf[tidx], 1);
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#include <excpt.h>
|
||||
|
||||
#define YR_TRYCATCH(_do_,_try_clause_,_catch_clause_) \
|
||||
do \
|
||||
{ \
|
||||
if (_do_) \
|
||||
{ \
|
||||
__try \
|
||||
{ _try_clause_ } \
|
||||
__except(exception_handler(GetExceptionInformation())) \
|
||||
{ _catch_clause_ } \
|
||||
} \
|
||||
else \
|
||||
{ _try_clause_ } \
|
||||
} while(0)
|
||||
|
||||
#else
|
||||
|
||||
#define YR_TRYCATCH(_do_,_try_clause_,_catch_clause_) \
|
||||
do \
|
||||
{ \
|
||||
if (_do_) \
|
||||
{ \
|
||||
jmp_buf jb; \
|
||||
HANDLE exh = AddVectoredExceptionHandler(1, exception_handler); \
|
||||
int tidx = yr_get_tidx(); \
|
||||
assert(tidx != -1); \
|
||||
exc_jmp_buf[tidx] = &jb; \
|
||||
if (setjmp(jb) == 0) \
|
||||
{ _try_clause_ } \
|
||||
else \
|
||||
{ _catch_clause_ } \
|
||||
exc_jmp_buf[tidx] = NULL; \
|
||||
RemoveVectoredExceptionHandler(exh); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_try_clause_ \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
sigjmp_buf *exc_jmp_buf[MAX_THREADS];
|
||||
|
||||
static void exception_handler(int sig) {
|
||||
if (sig == SIGBUS || sig == SIGSEGV)
|
||||
{
|
||||
int tidx = yr_get_tidx();
|
||||
|
||||
if (tidx != -1 && exc_jmp_buf[tidx] != NULL)
|
||||
siglongjmp(*exc_jmp_buf[tidx], 1);
|
||||
|
||||
assert(FALSE); // We should not reach this point.
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct sigaction sa;
|
||||
|
||||
#define YR_TRYCATCH(_do_,_try_clause_, _catch_clause_) \
|
||||
do \
|
||||
{ \
|
||||
if (_do_) \
|
||||
{ \
|
||||
struct sigaction old_sigbus_act; \
|
||||
struct sigaction old_sigsegv_act; \
|
||||
struct sigaction act; \
|
||||
act.sa_handler = exception_handler; \
|
||||
act.sa_flags = 0; /* SA_ONSTACK? */ \
|
||||
sigfillset(&act.sa_mask); \
|
||||
sigaction(SIGBUS, &act, &old_sigbus_act); \
|
||||
sigaction(SIGSEGV, &act, &old_sigsegv_act); \
|
||||
int tidx = yr_get_tidx(); \
|
||||
assert(tidx != -1); \
|
||||
sigjmp_buf jb; \
|
||||
exc_jmp_buf[tidx] = &jb; \
|
||||
if (sigsetjmp(jb, 1) == 0) \
|
||||
{ _try_clause_ } \
|
||||
else \
|
||||
{ _catch_clause_ } \
|
||||
exc_jmp_buf[tidx] = NULL; \
|
||||
sigaction(SIGBUS, &old_sigbus_act, NULL); \
|
||||
sigaction(SIGSEGV, &old_sigsegv_act, NULL); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_try_clause_ \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,426 @@
|
||||
/*
|
||||
Copyright (c) 2007-2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <yara/endian.h>
|
||||
#include <yara/pe.h>
|
||||
#include <yara/elf.h>
|
||||
#include <yara/exec.h>
|
||||
#include <yara/utils.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x < y)?(x):(y))
|
||||
#endif
|
||||
|
||||
|
||||
PIMAGE_NT_HEADERS32 yr_get_pe_header(
|
||||
const uint8_t* buffer,
|
||||
size_t buffer_length)
|
||||
{
|
||||
PIMAGE_DOS_HEADER mz_header;
|
||||
PIMAGE_NT_HEADERS32 pe_header;
|
||||
|
||||
size_t headers_size = 0;
|
||||
|
||||
if (buffer_length < sizeof(IMAGE_DOS_HEADER))
|
||||
return NULL;
|
||||
|
||||
mz_header = (PIMAGE_DOS_HEADER) buffer;
|
||||
|
||||
if (yr_le16toh(mz_header->e_magic) != IMAGE_DOS_SIGNATURE)
|
||||
return NULL;
|
||||
|
||||
if ((int32_t) yr_le32toh(mz_header->e_lfanew) < 0)
|
||||
return NULL;
|
||||
|
||||
headers_size = yr_le32toh(mz_header->e_lfanew) + \
|
||||
sizeof(pe_header->Signature) + \
|
||||
sizeof(IMAGE_FILE_HEADER);
|
||||
|
||||
if (buffer_length < headers_size)
|
||||
return NULL;
|
||||
|
||||
pe_header = (PIMAGE_NT_HEADERS32) (buffer + yr_le32toh(mz_header->e_lfanew));
|
||||
|
||||
headers_size += sizeof(IMAGE_OPTIONAL_HEADER32);
|
||||
|
||||
if (yr_le32toh(pe_header->Signature) == IMAGE_NT_SIGNATURE &&
|
||||
(yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_I386 ||
|
||||
yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_AMD64) &&
|
||||
buffer_length > headers_size)
|
||||
{
|
||||
return pe_header;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint64_t yr_pe_rva_to_offset(
|
||||
PIMAGE_NT_HEADERS32 pe_header,
|
||||
uint64_t rva,
|
||||
size_t buffer_length)
|
||||
{
|
||||
int i = 0;
|
||||
PIMAGE_SECTION_HEADER section;
|
||||
DWORD section_rva;
|
||||
DWORD section_offset;
|
||||
|
||||
section = IMAGE_FIRST_SECTION(pe_header);
|
||||
section_rva = 0;
|
||||
section_offset = 0;
|
||||
|
||||
while(i < MIN(yr_le16toh(pe_header->FileHeader.NumberOfSections), 60))
|
||||
{
|
||||
if ((uint8_t*) section - \
|
||||
(uint8_t*) pe_header + sizeof(IMAGE_SECTION_HEADER) < buffer_length)
|
||||
{
|
||||
if (rva >= section->VirtualAddress &&
|
||||
section_rva <= yr_le32toh(section->VirtualAddress))
|
||||
{
|
||||
section_rva = yr_le32toh(section->VirtualAddress);
|
||||
section_offset = yr_le32toh(section->PointerToRawData);
|
||||
}
|
||||
|
||||
section++;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return section_offset + (rva - section_rva);
|
||||
}
|
||||
|
||||
|
||||
int yr_get_elf_type(
|
||||
const uint8_t* buffer,
|
||||
size_t buffer_length)
|
||||
{
|
||||
elf_ident_t* elf_ident;
|
||||
|
||||
if (buffer_length < sizeof(elf_ident_t))
|
||||
return 0;
|
||||
|
||||
elf_ident = (elf_ident_t*) buffer;
|
||||
|
||||
if (yr_le32toh(elf_ident->magic) != ELF_MAGIC)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (elf_ident->_class) {
|
||||
case ELF_CLASS_32:
|
||||
if (buffer_length < sizeof(elf32_header_t))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case ELF_CLASS_64:
|
||||
if (buffer_length < sizeof(elf64_header_t))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Unexpected class */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return elf_ident->_class;
|
||||
}
|
||||
|
||||
|
||||
static uint64_t yr_elf_rva_to_offset_32(
|
||||
elf32_header_t* elf_header,
|
||||
uint64_t rva,
|
||||
size_t buffer_length)
|
||||
{
|
||||
// if the binary is an executable then prefer the program headers to resolve
|
||||
// the offset
|
||||
if (yr_le16toh(elf_header->type) == ELF_ET_EXEC)
|
||||
{
|
||||
int i;
|
||||
elf32_program_header_t* program;
|
||||
if (yr_le32toh(elf_header->ph_offset) == 0 ||
|
||||
yr_le16toh(elf_header->ph_entry_count == 0))
|
||||
return 0;
|
||||
|
||||
// check to prevent integer wraps
|
||||
if (ULONG_MAX - yr_le16toh(elf_header->ph_entry_count) <
|
||||
sizeof(elf32_program_header_t) * yr_le16toh(elf_header->ph_entry_count))
|
||||
return 0;
|
||||
|
||||
// check that 'ph_offset' doesn't wrap when added to the
|
||||
// size of entries.
|
||||
if(ULONG_MAX - yr_le32toh(elf_header->ph_offset) <
|
||||
sizeof(elf32_program_header_t) * yr_le16toh(elf_header->ph_entry_count))
|
||||
return 0;
|
||||
|
||||
// ensure we don't exceed the buffer size
|
||||
if (yr_le32toh(elf_header->ph_offset) + sizeof(elf32_program_header_t) *
|
||||
yr_le16toh(elf_header->ph_entry_count) > buffer_length)
|
||||
return 0;
|
||||
|
||||
program = (elf32_program_header_t*)
|
||||
((uint8_t*) elf_header + yr_le32toh(elf_header->ph_offset));
|
||||
|
||||
for (i = 0; i < yr_le16toh(elf_header->ph_entry_count); i++)
|
||||
{
|
||||
if (rva >= yr_le32toh(program->virt_addr) &&
|
||||
rva < yr_le32toh(program->virt_addr) + yr_le32toh(program->mem_size))
|
||||
{
|
||||
return yr_le32toh(program->offset) + (rva - yr_le32toh(program->virt_addr));
|
||||
}
|
||||
|
||||
program++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
elf32_section_header_t* section;
|
||||
|
||||
if (yr_le32toh(elf_header->sh_offset) == 0 ||
|
||||
yr_le16toh(elf_header->sh_entry_count == 0))
|
||||
return 0;
|
||||
|
||||
// check to prevent integer wraps
|
||||
|
||||
if (ULONG_MAX - yr_le16toh(elf_header->sh_entry_count) <
|
||||
sizeof(elf32_section_header_t) * yr_le16toh(elf_header->sh_entry_count))
|
||||
return 0;
|
||||
|
||||
// check that 'sh_offset' doesn't wrap when added to the
|
||||
// size of entries.
|
||||
|
||||
if (ULONG_MAX - yr_le32toh(elf_header->sh_offset) <
|
||||
sizeof(elf32_section_header_t) * yr_le16toh(elf_header->sh_entry_count))
|
||||
return 0;
|
||||
|
||||
if (yr_le32toh(elf_header->sh_offset) + sizeof(elf32_section_header_t) *
|
||||
yr_le16toh(elf_header->sh_entry_count) > buffer_length)
|
||||
return 0;
|
||||
|
||||
section = (elf32_section_header_t*)
|
||||
((unsigned char*) elf_header + yr_le32toh(elf_header->sh_offset));
|
||||
|
||||
for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++)
|
||||
{
|
||||
if (yr_le32toh(section->type) != ELF_SHT_NULL &&
|
||||
yr_le32toh(section->type) != ELF_SHT_NOBITS &&
|
||||
rva >= yr_le32toh(section->addr) &&
|
||||
rva < yr_le32toh(section->addr) + yr_le32toh(section->size))
|
||||
{
|
||||
// prevent integer wrapping with the return value
|
||||
|
||||
if (ULONG_MAX - yr_le32toh(section->offset) < (rva - yr_le32toh(section->addr)))
|
||||
return 0;
|
||||
else
|
||||
return yr_le32toh(section->offset) + (rva - yr_le32toh(section->addr));
|
||||
}
|
||||
|
||||
section++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static uint64_t yr_elf_rva_to_offset_64(
|
||||
elf64_header_t* elf_header,
|
||||
uint64_t rva,
|
||||
size_t buffer_length)
|
||||
{
|
||||
// if the binary is an executable then prefer the program headers to resolve
|
||||
// the offset
|
||||
if (yr_le16toh(elf_header->type) == ELF_ET_EXEC)
|
||||
{
|
||||
int i;
|
||||
elf64_program_header_t* program;
|
||||
if (yr_le64toh(elf_header->ph_offset) == 0 ||
|
||||
yr_le16toh(elf_header->ph_entry_count == 0))
|
||||
return 0;
|
||||
|
||||
// check that 'ph_offset' doesn't wrap when added to the
|
||||
// size of entries.
|
||||
if(ULONG_MAX - yr_le64toh(elf_header->ph_offset) <
|
||||
sizeof(elf64_program_header_t) * yr_le16toh(elf_header->ph_entry_count))
|
||||
return 0;
|
||||
|
||||
// ensure we don't exceed the buffer size
|
||||
if (yr_le64toh(elf_header->ph_offset) + sizeof(elf64_program_header_t) *
|
||||
yr_le16toh(elf_header->ph_entry_count) > buffer_length)
|
||||
return 0;
|
||||
|
||||
program = (elf64_program_header_t*)
|
||||
((uint8_t*) elf_header + yr_le64toh(elf_header->ph_offset));
|
||||
|
||||
for (i = 0; i < yr_le16toh(elf_header->ph_entry_count); i++)
|
||||
{
|
||||
if (rva >= yr_le64toh(program->virt_addr) &&
|
||||
rva < yr_le64toh(program->virt_addr) + yr_le64toh(program->mem_size))
|
||||
{
|
||||
return yr_le64toh(program->offset) + (rva - yr_le64toh(program->virt_addr));
|
||||
}
|
||||
|
||||
program++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
elf64_section_header_t* section;
|
||||
|
||||
if (yr_le64toh(elf_header->sh_offset) == 0 ||
|
||||
yr_le16toh(elf_header->sh_entry_count) == 0)
|
||||
return 0;
|
||||
|
||||
// check that 'sh_offset' doesn't wrap when added to the
|
||||
// size of entries.
|
||||
if(ULONG_MAX - yr_le64toh(elf_header->sh_offset) <
|
||||
sizeof(elf64_section_header_t) * yr_le16toh(elf_header->sh_entry_count))
|
||||
return 0;
|
||||
|
||||
if (yr_le64toh(elf_header->sh_offset) + sizeof(elf64_section_header_t) *
|
||||
yr_le16toh(elf_header->sh_entry_count) > buffer_length)
|
||||
return 0;
|
||||
|
||||
section = (elf64_section_header_t*)
|
||||
((uint8_t*) elf_header + yr_le64toh(elf_header->sh_offset));
|
||||
|
||||
for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++)
|
||||
{
|
||||
if (yr_le32toh(section->type) != ELF_SHT_NULL &&
|
||||
yr_le32toh(section->type) != ELF_SHT_NOBITS &&
|
||||
rva >= yr_le64toh(section->addr) &&
|
||||
rva < yr_le64toh(section->addr) + yr_le64toh(section->size))
|
||||
{
|
||||
return yr_le64toh(section->offset) + (rva - yr_le64toh(section->addr));
|
||||
}
|
||||
|
||||
section++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint64_t yr_get_entry_point_offset(
|
||||
const uint8_t* buffer,
|
||||
size_t buffer_length)
|
||||
{
|
||||
PIMAGE_NT_HEADERS32 pe_header;
|
||||
elf32_header_t* elf_header32;
|
||||
elf64_header_t* elf_header64;
|
||||
|
||||
pe_header = yr_get_pe_header(buffer, buffer_length);
|
||||
|
||||
if (pe_header != NULL)
|
||||
{
|
||||
return yr_pe_rva_to_offset(
|
||||
pe_header,
|
||||
yr_le32toh(pe_header->OptionalHeader.AddressOfEntryPoint),
|
||||
buffer_length - ((uint8_t*) pe_header - buffer));
|
||||
}
|
||||
|
||||
switch(yr_get_elf_type(buffer, buffer_length))
|
||||
{
|
||||
case ELF_CLASS_32:
|
||||
elf_header32 = (elf32_header_t*) buffer;
|
||||
return yr_elf_rva_to_offset_32(
|
||||
elf_header32,
|
||||
yr_le32toh(elf_header32->entry),
|
||||
buffer_length);
|
||||
|
||||
case ELF_CLASS_64:
|
||||
elf_header64 = (elf64_header_t*) buffer;
|
||||
return yr_elf_rva_to_offset_64(
|
||||
elf_header64,
|
||||
yr_le64toh(elf_header64->entry),
|
||||
buffer_length);
|
||||
}
|
||||
|
||||
return UNDEFINED;
|
||||
}
|
||||
|
||||
|
||||
uint64_t yr_get_entry_point_address(
|
||||
const uint8_t* buffer,
|
||||
size_t buffer_length,
|
||||
uint64_t base_address)
|
||||
{
|
||||
PIMAGE_NT_HEADERS32 pe_header;
|
||||
|
||||
elf32_header_t* elf_header32;
|
||||
elf64_header_t* elf_header64;
|
||||
|
||||
pe_header = yr_get_pe_header(buffer, buffer_length);
|
||||
|
||||
// If file is PE but not a DLL.
|
||||
|
||||
if (pe_header != NULL &&
|
||||
!(pe_header->FileHeader.Characteristics & IMAGE_FILE_DLL))
|
||||
return base_address + pe_header->OptionalHeader.AddressOfEntryPoint;
|
||||
|
||||
// If file is executable ELF, not shared library.
|
||||
|
||||
switch(yr_get_elf_type(buffer, buffer_length))
|
||||
{
|
||||
case ELF_CLASS_32:
|
||||
elf_header32 = (elf32_header_t*) buffer;
|
||||
|
||||
if (elf_header32->type == ELF_ET_EXEC)
|
||||
return elf_header32->entry;
|
||||
|
||||
break;
|
||||
|
||||
case ELF_CLASS_64:
|
||||
elf_header64 = (elf64_header_t*) buffer;
|
||||
|
||||
if (elf_header64->type == ELF_ET_EXEC)
|
||||
return elf_header64->entry;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return UNDEFINED;
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
Copyright (c) 2007-2015. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <yara/filemap.h>
|
||||
#include <yara/error.h>
|
||||
|
||||
|
||||
//
|
||||
// yr_filemap_map
|
||||
//
|
||||
// Maps a whole file into memory.
|
||||
//
|
||||
// Args:
|
||||
// const char* file_path - Path of the file to map.
|
||||
// YR_MAPPED_FILE* pmapped_file - Pointer to a YR_MAPPED_FILE that will be
|
||||
// filled with information about the mapping.
|
||||
// Returns:
|
||||
// One of the following error codes:
|
||||
// ERROR_SUCCESS
|
||||
// ERROR_INVALID_ARGUMENT
|
||||
// ERROR_COULD_NOT_OPEN_FILE
|
||||
// ERROR_COULD_NOT_MAP_FILE
|
||||
//
|
||||
|
||||
YR_API int yr_filemap_map(
|
||||
const char* file_path,
|
||||
YR_MAPPED_FILE* pmapped_file)
|
||||
{
|
||||
return yr_filemap_map_ex(file_path, 0, 0, pmapped_file);
|
||||
}
|
||||
|
||||
//
|
||||
// yr_filemap_map_fd
|
||||
//
|
||||
// Maps a portion of a file (specified by descriptor) into memory.
|
||||
//
|
||||
// Args:
|
||||
// YR_FILE_DESCRIPTOR file - File descriptor representing the file to
|
||||
// map
|
||||
// off_t offset - File offset where the mapping will begin.
|
||||
// This offset must be multiple of 1MB and not
|
||||
// greater than the actual file size.
|
||||
// size_t size - Number of bytes that will be mapped. If
|
||||
// zero or greater than the actual file size
|
||||
// all content until the end of the file will
|
||||
// be mapped.
|
||||
// YR_MAPPED_FILE* pmapped_file - Pointer to a YR_MAPPED_FILE struct that
|
||||
// will be filled with the new mapping.
|
||||
// Returns:
|
||||
// One of the following error codes:
|
||||
// ERROR_SUCCESS
|
||||
// ERROR_INVALID_ARGUMENT
|
||||
// ERROR_COULD_NOT_OPEN_FILE
|
||||
// ERROR_COULD_NOT_MAP_FILE
|
||||
//
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
|
||||
YR_API int yr_filemap_map_fd(
|
||||
YR_FILE_DESCRIPTOR file,
|
||||
off_t offset,
|
||||
size_t size,
|
||||
YR_MAPPED_FILE* pmapped_file)
|
||||
{
|
||||
LARGE_INTEGER fs;
|
||||
size_t file_size;
|
||||
|
||||
pmapped_file->file = file;
|
||||
pmapped_file->mapping = NULL;
|
||||
pmapped_file->data = NULL;
|
||||
pmapped_file->size = 0;
|
||||
|
||||
// Ensure that offset is aligned to 1MB
|
||||
if (offset >> 20 << 20 != offset)
|
||||
return ERROR_INVALID_ARGUMENT;
|
||||
|
||||
if (GetFileSizeEx(pmapped_file->file, &fs))
|
||||
{
|
||||
#ifdef _WIN64
|
||||
file_size = fs.QuadPart;
|
||||
#else
|
||||
file_size = fs.LowPart;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
pmapped_file->file = INVALID_HANDLE_VALUE;
|
||||
return ERROR_COULD_NOT_OPEN_FILE;
|
||||
}
|
||||
|
||||
if (offset > file_size)
|
||||
return ERROR_COULD_NOT_MAP_FILE;
|
||||
|
||||
if (size == 0)
|
||||
size = (size_t) (file_size - offset);
|
||||
|
||||
pmapped_file->size = yr_min(size, (size_t) (file_size - offset));
|
||||
|
||||
if (pmapped_file->size != 0)
|
||||
{
|
||||
pmapped_file->mapping = CreateFileMapping(
|
||||
pmapped_file->file,
|
||||
NULL,
|
||||
PAGE_READONLY,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (pmapped_file->mapping == NULL)
|
||||
{
|
||||
pmapped_file->file = INVALID_HANDLE_VALUE;
|
||||
pmapped_file->size = 0;
|
||||
return ERROR_COULD_NOT_MAP_FILE;
|
||||
}
|
||||
|
||||
pmapped_file->data = (const uint8_t*) MapViewOfFile(
|
||||
pmapped_file->mapping,
|
||||
FILE_MAP_READ,
|
||||
offset >> 32,
|
||||
offset & 0xFFFFFFFF,
|
||||
pmapped_file->size);
|
||||
|
||||
if (pmapped_file->data == NULL)
|
||||
{
|
||||
CloseHandle(pmapped_file->mapping);
|
||||
pmapped_file->mapping = NULL;
|
||||
pmapped_file->file = INVALID_HANDLE_VALUE;
|
||||
pmapped_file->size = 0;
|
||||
return ERROR_COULD_NOT_MAP_FILE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pmapped_file->mapping = NULL;
|
||||
pmapped_file->data = NULL;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
#else // POSIX
|
||||
|
||||
YR_API int yr_filemap_map_fd(
|
||||
YR_FILE_DESCRIPTOR file,
|
||||
off_t offset,
|
||||
size_t size,
|
||||
YR_MAPPED_FILE* pmapped_file)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
pmapped_file->file = file;
|
||||
pmapped_file->data = NULL;
|
||||
pmapped_file->size = 0;
|
||||
|
||||
// Ensure that offset is aligned to 1MB
|
||||
if (offset >> 20 << 20 != offset)
|
||||
return ERROR_INVALID_ARGUMENT;
|
||||
|
||||
if (fstat(file, &st) != 0 || S_ISDIR(st.st_mode))
|
||||
return ERROR_COULD_NOT_OPEN_FILE;
|
||||
|
||||
if (offset > st.st_size)
|
||||
return ERROR_COULD_NOT_MAP_FILE;
|
||||
|
||||
if (size == 0)
|
||||
size = (size_t) (st.st_size - offset);
|
||||
|
||||
pmapped_file->size = yr_min(size, (size_t) (st.st_size - offset));
|
||||
|
||||
if (pmapped_file->size != 0)
|
||||
{
|
||||
pmapped_file->data = (const uint8_t*) mmap(
|
||||
0,
|
||||
pmapped_file->size,
|
||||
PROT_READ,
|
||||
MAP_PRIVATE,
|
||||
pmapped_file->file,
|
||||
offset);
|
||||
|
||||
if (pmapped_file->data == MAP_FAILED)
|
||||
{
|
||||
pmapped_file->data = NULL;
|
||||
pmapped_file->size = 0;
|
||||
pmapped_file->file = -1;
|
||||
|
||||
return ERROR_COULD_NOT_MAP_FILE;
|
||||
}
|
||||
|
||||
madvise((void*) pmapped_file->data, pmapped_file->size, MADV_SEQUENTIAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
pmapped_file->data = NULL;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// yr_filemap_map_ex
|
||||
//
|
||||
// Maps a portion of a file (specified by path) into memory.
|
||||
//
|
||||
// Args:
|
||||
// const char* file_path - Path of the file to map.
|
||||
// off_t offset - File offset where the mapping will begin.
|
||||
// This offset must be multiple of 1MB and not
|
||||
// greater than the actual file size.
|
||||
// size_t size - Number of bytes that will be mapped. If
|
||||
// zero or greater than the actual file size
|
||||
// all content until the end of the file will
|
||||
// be mapped.
|
||||
// YR_MAPPED_FILE* pmapped_file - Pointer to a YR_MAPPED_FILE struct that
|
||||
// will be filled with the new mapping.
|
||||
// Returns:
|
||||
// One of the following error codes:
|
||||
// ERROR_SUCCESS
|
||||
// ERROR_INVALID_ARGUMENT
|
||||
// ERROR_COULD_NOT_OPEN_FILE
|
||||
// ERROR_COULD_NOT_MAP_FILE
|
||||
//
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
|
||||
YR_API int yr_filemap_map_ex(
|
||||
const char* file_path,
|
||||
off_t offset,
|
||||
size_t size,
|
||||
YR_MAPPED_FILE* pmapped_file)
|
||||
{
|
||||
YR_FILE_DESCRIPTOR fd;
|
||||
int result;
|
||||
|
||||
if (file_path == NULL)
|
||||
return ERROR_INVALID_ARGUMENT;
|
||||
|
||||
fd = CreateFileA(
|
||||
file_path,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_SEQUENTIAL_SCAN,
|
||||
NULL);
|
||||
|
||||
if (fd == INVALID_HANDLE_VALUE)
|
||||
return ERROR_COULD_NOT_OPEN_FILE;
|
||||
|
||||
result = yr_filemap_map_fd(fd, offset, size, pmapped_file);
|
||||
|
||||
if (result != ERROR_SUCCESS)
|
||||
CloseHandle(fd);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#else // POSIX
|
||||
|
||||
YR_API int yr_filemap_map_ex(
|
||||
const char* file_path,
|
||||
off_t offset,
|
||||
size_t size,
|
||||
YR_MAPPED_FILE* pmapped_file)
|
||||
{
|
||||
YR_FILE_DESCRIPTOR fd;
|
||||
int result;
|
||||
|
||||
if (file_path == NULL)
|
||||
return ERROR_INVALID_ARGUMENT;
|
||||
|
||||
fd = open(file_path, O_RDONLY);
|
||||
|
||||
if (fd == -1)
|
||||
return ERROR_COULD_NOT_OPEN_FILE;
|
||||
|
||||
result = yr_filemap_map_fd(fd, offset, size, pmapped_file);
|
||||
|
||||
if (result != ERROR_SUCCESS)
|
||||
close(fd);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// yr_filemap_unmap
|
||||
//
|
||||
// Unmaps a file mapping.
|
||||
//
|
||||
// Args:
|
||||
// YR_MAPPED_FILE* pmapped_file - Pointer to a YR_MAPPED_FILE that struct.
|
||||
//
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
YR_API void yr_filemap_unmap_fd(
|
||||
YR_MAPPED_FILE* pmapped_file)
|
||||
{
|
||||
if (pmapped_file->data != NULL)
|
||||
UnmapViewOfFile(pmapped_file->data);
|
||||
|
||||
if (pmapped_file->mapping != NULL)
|
||||
CloseHandle(pmapped_file->mapping);
|
||||
|
||||
pmapped_file->mapping = NULL;
|
||||
pmapped_file->data = NULL;
|
||||
pmapped_file->size = 0;
|
||||
}
|
||||
|
||||
YR_API void yr_filemap_unmap(
|
||||
YR_MAPPED_FILE* pmapped_file)
|
||||
{
|
||||
yr_filemap_unmap_fd(pmapped_file);
|
||||
|
||||
if (pmapped_file->file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(pmapped_file->file);
|
||||
pmapped_file->file = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
#else // POSIX
|
||||
|
||||
YR_API void yr_filemap_unmap_fd(
|
||||
YR_MAPPED_FILE* pmapped_file)
|
||||
{
|
||||
if (pmapped_file->data != NULL)
|
||||
munmap((void*) pmapped_file->data, pmapped_file->size);
|
||||
|
||||
pmapped_file->data = NULL;
|
||||
pmapped_file->size = 0;
|
||||
}
|
||||
|
||||
YR_API void yr_filemap_unmap(
|
||||
YR_MAPPED_FILE* pmapped_file)
|
||||
{
|
||||
yr_filemap_unmap_fd(pmapped_file);
|
||||
|
||||
if (pmapped_file->file != -1)
|
||||
{
|
||||
close(pmapped_file->file);
|
||||
pmapped_file->file = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,180 @@
|
||||
/* A Bison parser, made by GNU Bison 3.0.4.18-9674. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_YARA_YY_GRAMMAR_H_INCLUDED
|
||||
# define YY_YARA_YY_GRAMMAR_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int yara_yydebug;
|
||||
#endif
|
||||
|
||||
/* Token type. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
_DOT_DOT_ = 258,
|
||||
_RULE_ = 259,
|
||||
_PRIVATE_ = 260,
|
||||
_GLOBAL_ = 261,
|
||||
_META_ = 262,
|
||||
_STRINGS_ = 263,
|
||||
_CONDITION_ = 264,
|
||||
_IDENTIFIER_ = 265,
|
||||
_STRING_IDENTIFIER_ = 266,
|
||||
_STRING_COUNT_ = 267,
|
||||
_STRING_OFFSET_ = 268,
|
||||
_STRING_LENGTH_ = 269,
|
||||
_STRING_IDENTIFIER_WITH_WILDCARD_ = 270,
|
||||
_NUMBER_ = 271,
|
||||
_DOUBLE_ = 272,
|
||||
_INTEGER_FUNCTION_ = 273,
|
||||
_TEXT_STRING_ = 274,
|
||||
_HEX_STRING_ = 275,
|
||||
_REGEXP_ = 276,
|
||||
_ASCII_ = 277,
|
||||
_WIDE_ = 278,
|
||||
_XOR_ = 279,
|
||||
_NOCASE_ = 280,
|
||||
_FULLWORD_ = 281,
|
||||
_AT_ = 282,
|
||||
_FILESIZE_ = 283,
|
||||
_ENTRYPOINT_ = 284,
|
||||
_ALL_ = 285,
|
||||
_ANY_ = 286,
|
||||
_IN_ = 287,
|
||||
_OF_ = 288,
|
||||
_FOR_ = 289,
|
||||
_THEM_ = 290,
|
||||
_MATCHES_ = 291,
|
||||
_CONTAINS_ = 292,
|
||||
_IMPORT_ = 293,
|
||||
_TRUE_ = 294,
|
||||
_FALSE_ = 295,
|
||||
_OR_ = 296,
|
||||
_AND_ = 297,
|
||||
_EQ_ = 298,
|
||||
_NEQ_ = 299,
|
||||
_LT_ = 300,
|
||||
_LE_ = 301,
|
||||
_GT_ = 302,
|
||||
_GE_ = 303,
|
||||
_SHIFT_LEFT_ = 304,
|
||||
_SHIFT_RIGHT_ = 305,
|
||||
_NOT_ = 306,
|
||||
UNARY_MINUS = 307
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define _DOT_DOT_ 258
|
||||
#define _RULE_ 259
|
||||
#define _PRIVATE_ 260
|
||||
#define _GLOBAL_ 261
|
||||
#define _META_ 262
|
||||
#define _STRINGS_ 263
|
||||
#define _CONDITION_ 264
|
||||
#define _IDENTIFIER_ 265
|
||||
#define _STRING_IDENTIFIER_ 266
|
||||
#define _STRING_COUNT_ 267
|
||||
#define _STRING_OFFSET_ 268
|
||||
#define _STRING_LENGTH_ 269
|
||||
#define _STRING_IDENTIFIER_WITH_WILDCARD_ 270
|
||||
#define _NUMBER_ 271
|
||||
#define _DOUBLE_ 272
|
||||
#define _INTEGER_FUNCTION_ 273
|
||||
#define _TEXT_STRING_ 274
|
||||
#define _HEX_STRING_ 275
|
||||
#define _REGEXP_ 276
|
||||
#define _ASCII_ 277
|
||||
#define _WIDE_ 278
|
||||
#define _XOR_ 279
|
||||
#define _NOCASE_ 280
|
||||
#define _FULLWORD_ 281
|
||||
#define _AT_ 282
|
||||
#define _FILESIZE_ 283
|
||||
#define _ENTRYPOINT_ 284
|
||||
#define _ALL_ 285
|
||||
#define _ANY_ 286
|
||||
#define _IN_ 287
|
||||
#define _OF_ 288
|
||||
#define _FOR_ 289
|
||||
#define _THEM_ 290
|
||||
#define _MATCHES_ 291
|
||||
#define _CONTAINS_ 292
|
||||
#define _IMPORT_ 293
|
||||
#define _TRUE_ 294
|
||||
#define _FALSE_ 295
|
||||
#define _OR_ 296
|
||||
#define _AND_ 297
|
||||
#define _EQ_ 298
|
||||
#define _NEQ_ 299
|
||||
#define _LT_ 300
|
||||
#define _LE_ 301
|
||||
#define _GT_ 302
|
||||
#define _GE_ 303
|
||||
#define _SHIFT_LEFT_ 304
|
||||
#define _SHIFT_RIGHT_ 305
|
||||
#define _NOT_ 306
|
||||
#define UNARY_MINUS 307
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 216 "grammar.y" /* yacc.c:1915 */
|
||||
|
||||
EXPRESSION expression;
|
||||
SIZED_STRING* sized_string;
|
||||
char* c_string;
|
||||
int64_t integer;
|
||||
double double_;
|
||||
YR_STRING* string;
|
||||
YR_META* meta;
|
||||
YR_RULE* rule;
|
||||
|
||||
#line 169 "grammar.h" /* yacc.c:1915 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int yara_yyparse (void *yyscanner, YR_COMPILER* compiler);
|
||||
|
||||
#endif /* !YY_YARA_YY_GRAMMAR_H_INCLUDED */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,365 @@
|
||||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <yara/integers.h>
|
||||
#include <yara/hash.h>
|
||||
#include <yara/mem.h>
|
||||
#include <yara/error.h>
|
||||
|
||||
// Constant-time left rotate that does not invoke undefined behavior.
|
||||
// http://blog.regehr.org/archives/1063
|
||||
static uint32_t rotl32(uint32_t x, uint32_t shift) {
|
||||
assert(shift < 32);
|
||||
return (x << shift) | (x >> (-shift & 31));
|
||||
}
|
||||
|
||||
#define ROTATE_INT32(x, shift) \
|
||||
rotl32(x, shift % 32)
|
||||
|
||||
uint32_t byte_to_int32[] =
|
||||
{
|
||||
0xC3113E7F,0x4C353C5F,0x7423810B,0x258D264E,0xDAD39DED,0x75D0B694,0x98CE1216,
|
||||
0x93334482,0xC5C48EA5,0xF57E0E8B,0x5D7F3723,0x396B1B24,0xA8883D9F,0xB2A74A00,
|
||||
0xF8E171AE,0x3F01FBAB,0x5C1840CB,0xDDD833C4,0x8D8CCA34,0x32EF223A,0x1A05B871,
|
||||
0x9A9B6BFC,0x50406A0C,0xE7E1FC04,0x5E07D7F6,0x80B83660,0x20892A62,0xB2C6FEA6,
|
||||
0x6CEC7CAA,0x182F764B,0x3B0353E7,0x57FC2520,0x4B6812D4,0xACB654E4,0x23C75C04,
|
||||
0xB1DCD731,0xE3AF0733,0xF2366D39,0xC729671B,0xFF3BE6F2,0xABA37E34,0x3CDAFA38,
|
||||
0xAAD18D03,0xA8D35345,0x08E9A92C,0xF9324059,0x42D821BE,0x1BC152DD,0x5588811C,
|
||||
0x874A1F9A,0x6E83E9CD,0xDA6F3AF8,0x965D4670,0xA7A565C0,0x68D8A9AF,0xFC8FD8FD,
|
||||
0x8FF99FF9,0x4C9B42AE,0x2D066A8D,0x4D1802F7,0x557032B2,0x12BCF371,0xDC29D5AE,
|
||||
0x72EA361F,0xE2835B0B,0xDFC58966,0x13B0F34D,0x3FA02BCD,0xBF282E3D,0x7DC877F5,
|
||||
0xF4848A32,0x861E35F5,0x7FFA0D7F,0x515F2E4E,0x6B235D5C,0x55F46E24,0x35AD2C99,
|
||||
0x072654A8,0x05163F0F,0x9317B11A,0xAED1FC10,0x989444F0,0xDB3E1814,0x446C0CF1,
|
||||
0x660BF511,0x2F227D3A,0xFDBA0539,0xC649E621,0x5204D7CE,0x5FA386D0,0xE5F22005,
|
||||
0x97B6C8A1,0x4AB69EC2,0x5C7CA70D,0x39A48EC6,0x7BACF378,0x8D0ED3D1,0xE39DE582,
|
||||
0xC5FBE2AB,0x37E3D2D0,0x06F44724,0x73144144,0xBA57E905,0xB05B4307,0xAEED8D97,
|
||||
0xA68CCAC4,0xE30DA57E,0xED0F194B,0x8C2B9B7A,0x814575D5,0x79588493,0x81D3712A,
|
||||
0x3FA892F2,0x80F0BB94,0x44EAF51A,0x4E05F1D4,0xFC69F858,0x775E8D60,0x22B20DD7,
|
||||
0x170A87EA,0x1077DE52,0x3D5EC9FB,0x0B6EB1E5,0xF2F9CCAF,0xA76C7DEB,0xD8C2D873,
|
||||
0xF438C592,0x6239FEEC,0x26D3D2A9,0x30F6FADF,0x4B2984CC,0x6257F3DA,0x0E0583E2,
|
||||
0x143E5E61,0xBB2732BF,0x9653217A,0x027A84EA,0x95C9AE8B,0x89B8B82B,0x9F286485,
|
||||
0x29F622FE,0x52A3196B,0x8392D95F,0x33A79167,0xF5DEE92A,0x6E397DB9,0x11931C01,
|
||||
0x8DD2CD3B,0xF9E6003D,0xAB955AF4,0xD38725F9,0xDCF6F8AE,0x7667A958,0xE67AD995,
|
||||
0xB7CF979A,0xD88EBE5B,0x5BA889F0,0x078BDD90,0x447238F9,0x3135F672,0x187B95A8,
|
||||
0x0B7D5751,0xACD59D2A,0x9C5D1929,0x579E5022,0xEA90499B,0x59901800,0x82237DB5,
|
||||
0x7A375509,0xACA9A22A,0xEC96E649,0x69339DB0,0x081D0D9B,0xD72FB8B9,0xA4184653,
|
||||
0xC057321D,0xED19CAB9,0xB48F1E3E,0xB9DAC51E,0xDAED2FC7,0x7598CBBD,0x208DF346,
|
||||
0x044BE6EC,0x1C63E6EB,0xA15F64C1,0xE024A061,0x68309584,0x0758A68D,0xF274E9AE,
|
||||
0x0ABEA0CC,0xED4FB267,0x63D6EC46,0x9F28E026,0xF0694A17,0x9D6E9115,0xC4600FAD,
|
||||
0x5B121E99,0xD6B4A13B,0xF5364B8A,0x8514B254,0x0182F8DD,0xDB09F90B,0x78C70B32,
|
||||
0xD8EC3B02,0x8CD7084D,0xA4439838,0x72F35A3D,0x200B48A5,0xE2351444,0xA5552F5F,
|
||||
0xD8C1E746,0x0FE5EF3C,0xB6A47063,0x61F4E68B,0x08FED99B,0x7E461445,0x43CB8380,
|
||||
0x28BA03C8,0x21A7A2E2,0x43437ED6,0x2A9E6670,0x89B4A106,0xC6C2F4EE,0x9C4063CC,
|
||||
0x2FA0DF6C,0xB54DC409,0xCF01538F,0x616431D7,0x02CB0E4D,0x44FFF425,0xAAD5188E,
|
||||
0x0742E9BC,0xFFF41353,0x130F0A15,0x787BDC10,0x4A327B72,0x702989F7,0x5F704798,
|
||||
0x8156A1BB,0x2BCA3E74,0x1911A8C4,0x5E1F27D3,0x07949DC7,0xF24C2056,0xB4299EE6,
|
||||
0x9C7045D9,0xA8BF6307,0x7454AAD2,0x256425E5,0xD87DEF67,0xCFE95452,0xE7548DF7,
|
||||
0xA84956C7,0xD8402C60,0xCFBD0373,0x6B6CDAFE
|
||||
};
|
||||
|
||||
|
||||
uint32_t yr_hash(
|
||||
uint32_t seed,
|
||||
const void* buffer,
|
||||
size_t len)
|
||||
{
|
||||
const uint8_t* b = (uint8_t*) buffer;
|
||||
|
||||
uint32_t result = seed;
|
||||
size_t i;
|
||||
|
||||
assert(len > 0);
|
||||
|
||||
for (i = len - 1; i > 0; i--)
|
||||
{
|
||||
result ^= ROTATE_INT32(byte_to_int32[*b], i);
|
||||
b++;
|
||||
}
|
||||
|
||||
result ^= byte_to_int32[*b];
|
||||
return result;
|
||||
}
|
||||
|
||||
// _yr_hash_table_lookup
|
||||
//
|
||||
// Return the value associated to a given key and optionally remove it from
|
||||
// the hash table. Key can be any byte sequence, namespace is a null-terminated
|
||||
// string, and remove is a boolean.
|
||||
|
||||
static void* _yr_hash_table_lookup(
|
||||
YR_HASH_TABLE* table,
|
||||
const void* key,
|
||||
size_t key_length,
|
||||
const char* ns,
|
||||
int remove)
|
||||
{
|
||||
YR_HASH_TABLE_ENTRY* entry;
|
||||
YR_HASH_TABLE_ENTRY* prev_entry;
|
||||
|
||||
void* result;
|
||||
|
||||
uint32_t bucket_index = yr_hash(0, key, key_length);
|
||||
|
||||
if (ns != NULL)
|
||||
bucket_index = yr_hash(bucket_index, (uint8_t*) ns, strlen(ns));
|
||||
|
||||
bucket_index = bucket_index % table->size;
|
||||
prev_entry = NULL;
|
||||
entry = table->buckets[bucket_index];
|
||||
|
||||
while (entry != NULL)
|
||||
{
|
||||
int key_match = (
|
||||
(entry->key_length == key_length) &&
|
||||
(memcmp(entry->key, key, key_length) == 0));
|
||||
|
||||
int ns_match = (
|
||||
(entry->ns == ns) ||
|
||||
(entry->ns != NULL && ns != NULL && strcmp(entry->ns, ns) == 0));
|
||||
|
||||
if (key_match && ns_match)
|
||||
{
|
||||
result = entry->value;
|
||||
|
||||
if (remove)
|
||||
{
|
||||
if (prev_entry == NULL)
|
||||
table->buckets[bucket_index] = entry->next;
|
||||
else
|
||||
prev_entry->next = entry->next;
|
||||
|
||||
if (entry->ns != NULL)
|
||||
yr_free(entry->ns);
|
||||
|
||||
yr_free(entry->key);
|
||||
yr_free(entry);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
prev_entry = entry;
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
YR_API int yr_hash_table_create(
|
||||
int size,
|
||||
YR_HASH_TABLE** table)
|
||||
{
|
||||
YR_HASH_TABLE* new_table;
|
||||
int i;
|
||||
|
||||
new_table = (YR_HASH_TABLE*) yr_malloc(
|
||||
sizeof(YR_HASH_TABLE) + size * sizeof(YR_HASH_TABLE_ENTRY*));
|
||||
|
||||
if (new_table == NULL)
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
|
||||
new_table->size = size;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
new_table->buckets[i] = NULL;
|
||||
|
||||
*table = new_table;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
YR_API void yr_hash_table_clean(
|
||||
YR_HASH_TABLE* table,
|
||||
YR_HASH_TABLE_FREE_VALUE_FUNC free_value)
|
||||
{
|
||||
YR_HASH_TABLE_ENTRY* entry;
|
||||
YR_HASH_TABLE_ENTRY* next_entry;
|
||||
|
||||
int i;
|
||||
|
||||
if (table == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < table->size; i++)
|
||||
{
|
||||
entry = table->buckets[i];
|
||||
|
||||
while (entry != NULL)
|
||||
{
|
||||
next_entry = entry->next;
|
||||
|
||||
if (free_value != NULL)
|
||||
free_value(entry->value);
|
||||
|
||||
if (entry->ns != NULL)
|
||||
yr_free(entry->ns);
|
||||
|
||||
yr_free(entry->key);
|
||||
yr_free(entry);
|
||||
|
||||
entry = next_entry;
|
||||
}
|
||||
|
||||
table->buckets[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
YR_API void yr_hash_table_destroy(
|
||||
YR_HASH_TABLE* table,
|
||||
YR_HASH_TABLE_FREE_VALUE_FUNC free_value)
|
||||
{
|
||||
yr_hash_table_clean(table, free_value);
|
||||
yr_free(table);
|
||||
}
|
||||
|
||||
|
||||
YR_API void* yr_hash_table_lookup_raw_key(
|
||||
YR_HASH_TABLE* table,
|
||||
const void* key,
|
||||
size_t key_length,
|
||||
const char* ns)
|
||||
{
|
||||
return _yr_hash_table_lookup(table, key, key_length, ns, FALSE);
|
||||
}
|
||||
|
||||
|
||||
YR_API void* yr_hash_table_remove_raw_key(
|
||||
YR_HASH_TABLE* table,
|
||||
const void* key,
|
||||
size_t key_length,
|
||||
const char* ns)
|
||||
{
|
||||
return _yr_hash_table_lookup(table, key, key_length, ns, TRUE);
|
||||
}
|
||||
|
||||
|
||||
YR_API int yr_hash_table_add_raw_key(
|
||||
YR_HASH_TABLE* table,
|
||||
const void* key,
|
||||
size_t key_length,
|
||||
const char* ns,
|
||||
void* value)
|
||||
{
|
||||
YR_HASH_TABLE_ENTRY* entry;
|
||||
uint32_t bucket_index;
|
||||
|
||||
entry = (YR_HASH_TABLE_ENTRY*) yr_malloc(sizeof(YR_HASH_TABLE_ENTRY));
|
||||
|
||||
if (entry == NULL)
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
|
||||
entry->key = yr_malloc(key_length);
|
||||
|
||||
if (entry->key == NULL)
|
||||
{
|
||||
yr_free(entry);
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
if (ns != NULL)
|
||||
{
|
||||
entry->ns = yr_strdup(ns);
|
||||
|
||||
if (entry->ns == NULL)
|
||||
{
|
||||
yr_free(entry->key);
|
||||
yr_free(entry);
|
||||
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->ns = NULL;
|
||||
}
|
||||
|
||||
entry->key_length = key_length;
|
||||
entry->value = value;
|
||||
|
||||
memcpy(entry->key, key, key_length);
|
||||
|
||||
bucket_index = yr_hash(0, key, key_length);
|
||||
|
||||
if (ns != NULL)
|
||||
bucket_index = yr_hash(bucket_index, (uint8_t*) ns, strlen(ns));
|
||||
|
||||
bucket_index = bucket_index % table->size;
|
||||
|
||||
entry->next = table->buckets[bucket_index];
|
||||
table->buckets[bucket_index] = entry;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
YR_API void* yr_hash_table_lookup(
|
||||
YR_HASH_TABLE* table,
|
||||
const char* key,
|
||||
const char* ns)
|
||||
{
|
||||
return yr_hash_table_lookup_raw_key(
|
||||
table,
|
||||
(void*) key,
|
||||
strlen(key),
|
||||
ns);
|
||||
}
|
||||
|
||||
|
||||
YR_API void* yr_hash_table_remove(
|
||||
YR_HASH_TABLE* table,
|
||||
const char* key,
|
||||
const char* ns)
|
||||
{
|
||||
return yr_hash_table_remove_raw_key(
|
||||
table,
|
||||
(void*) key,
|
||||
strlen(key),
|
||||
ns);
|
||||
}
|
||||
|
||||
|
||||
YR_API int yr_hash_table_add(
|
||||
YR_HASH_TABLE* table,
|
||||
const char* key,
|
||||
const char* ns,
|
||||
void* value)
|
||||
{
|
||||
return yr_hash_table_add_raw_key(
|
||||
table,
|
||||
(void*) key,
|
||||
strlen(key),
|
||||
ns,
|
||||
value);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,80 @@
|
||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_HEX_YY_HEX_GRAMMAR_H_INCLUDED
|
||||
# define YY_HEX_YY_HEX_GRAMMAR_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int hex_yydebug;
|
||||
#endif
|
||||
|
||||
/* Token type. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
_BYTE_ = 258,
|
||||
_MASKED_BYTE_ = 259,
|
||||
_NUMBER_ = 260
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define _BYTE_ 258
|
||||
#define _MASKED_BYTE_ 259
|
||||
#define _NUMBER_ 260
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 86 "hex_grammar.y" /* yacc.c:1915 */
|
||||
|
||||
int64_t integer;
|
||||
RE_NODE *re_node;
|
||||
|
||||
#line 69 "hex_grammar.h" /* yacc.c:1915 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int hex_yyparse (void *yyscanner, HEX_LEX_ENVIRONMENT *lex_env);
|
||||
|
||||
#endif /* !YY_HEX_YY_HEX_GRAMMAR_H_INCLUDED */
|
||||
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
%{
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <yara/integers.h>
|
||||
#include <yara/utils.h>
|
||||
#include <yara/hex_lexer.h>
|
||||
#include <yara/limits.h>
|
||||
#include <yara/mem.h>
|
||||
#include <yara/error.h>
|
||||
|
||||
|
||||
#define STR_EXPAND(tok) #tok
|
||||
#define STR(tok) STR_EXPAND(tok)
|
||||
|
||||
#define YYERROR_VERBOSE
|
||||
|
||||
#define YYMALLOC yr_malloc
|
||||
#define YYFREE yr_free
|
||||
|
||||
#define mark_as_not_fast_regexp() \
|
||||
((RE_AST*) yyget_extra(yyscanner))->flags &= ~RE_FLAGS_FAST_REGEXP
|
||||
|
||||
#define fail_if_too_many_ast_levels(cleanup_code) \
|
||||
if (((RE_AST*) yyget_extra(yyscanner))->levels++ > RE_MAX_AST_LEVELS) \
|
||||
{ \
|
||||
{ cleanup_code } \
|
||||
yyerror(yyscanner, lex_env, "string too long"); \
|
||||
YYABORT; \
|
||||
}
|
||||
|
||||
#define fail_if(x, error) \
|
||||
if (x) \
|
||||
{ \
|
||||
lex_env->last_error_code = error; \
|
||||
YYABORT; \
|
||||
} \
|
||||
|
||||
#define destroy_node_if(x, node) \
|
||||
if (x) \
|
||||
{ \
|
||||
yr_re_node_destroy(node); \
|
||||
} \
|
||||
|
||||
%}
|
||||
|
||||
%name-prefix "hex_yy"
|
||||
%pure-parser
|
||||
|
||||
%parse-param {void *yyscanner}
|
||||
%parse-param {HEX_LEX_ENVIRONMENT *lex_env}
|
||||
|
||||
%lex-param {yyscan_t yyscanner}
|
||||
%lex-param {HEX_LEX_ENVIRONMENT *lex_env}
|
||||
|
||||
%union {
|
||||
int64_t integer;
|
||||
RE_NODE *re_node;
|
||||
}
|
||||
|
||||
%token <integer> _BYTE_
|
||||
%token <integer> _MASKED_BYTE_
|
||||
%token <integer> _NUMBER_
|
||||
|
||||
%type <re_node> tokens
|
||||
%type <re_node> token_sequence
|
||||
%type <re_node> token_or_range
|
||||
%type <re_node> token byte
|
||||
%type <re_node> alternatives
|
||||
%type <re_node> range
|
||||
|
||||
%destructor { yr_re_node_destroy($$); $$ = NULL; } tokens
|
||||
%destructor { yr_re_node_destroy($$); $$ = NULL; } token_sequence
|
||||
%destructor { yr_re_node_destroy($$); $$ = NULL; } token_or_range
|
||||
%destructor { yr_re_node_destroy($$); $$ = NULL; } token
|
||||
%destructor { yr_re_node_destroy($$); $$ = NULL; } byte
|
||||
%destructor { yr_re_node_destroy($$); $$ = NULL; } alternatives
|
||||
%destructor { yr_re_node_destroy($$); $$ = NULL; } range
|
||||
|
||||
%%
|
||||
|
||||
hex_string
|
||||
: '{' tokens '}'
|
||||
{
|
||||
RE_AST* re_ast = yyget_extra(yyscanner);
|
||||
re_ast->root_node = $2;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
tokens
|
||||
: token
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| token token
|
||||
{
|
||||
fail_if_too_many_ast_levels({
|
||||
yr_re_node_destroy($1);
|
||||
yr_re_node_destroy($2);
|
||||
});
|
||||
|
||||
$$ = yr_re_node_create(RE_NODE_CONCAT, $1, $2);
|
||||
|
||||
destroy_node_if($$ == NULL, $1);
|
||||
destroy_node_if($$ == NULL, $2);
|
||||
|
||||
fail_if($$ == NULL, ERROR_INSUFFICIENT_MEMORY);
|
||||
}
|
||||
| token token_sequence token
|
||||
{
|
||||
RE_NODE* new_concat;
|
||||
RE_NODE* leftmost_concat = NULL;
|
||||
RE_NODE* leftmost_node = $2;
|
||||
|
||||
fail_if_too_many_ast_levels({
|
||||
yr_re_node_destroy($1);
|
||||
yr_re_node_destroy($2);
|
||||
yr_re_node_destroy($3);
|
||||
});
|
||||
|
||||
$$ = NULL;
|
||||
|
||||
/*
|
||||
Some portions of the code (i.e: yr_re_split_at_chaining_point)
|
||||
expect a left-unbalanced tree where the right child of a concat node
|
||||
can't be another concat node. A concat node must be always the left
|
||||
child of its parent if the parent is also a concat. For this reason
|
||||
the can't simply create two new concat nodes arranged like this:
|
||||
|
||||
concat
|
||||
/ \
|
||||
/ \
|
||||
token's \
|
||||
subtree concat
|
||||
/ \
|
||||
/ \
|
||||
/ \
|
||||
token_sequence's token's
|
||||
subtree subtree
|
||||
|
||||
Instead we must insert the subtree for the first token as the
|
||||
leftmost node of the token_sequence subtree.
|
||||
*/
|
||||
|
||||
while (leftmost_node->type == RE_NODE_CONCAT)
|
||||
{
|
||||
leftmost_concat = leftmost_node;
|
||||
leftmost_node = leftmost_node->left;
|
||||
}
|
||||
|
||||
new_concat = yr_re_node_create(
|
||||
RE_NODE_CONCAT, $1, leftmost_node);
|
||||
|
||||
if (new_concat != NULL)
|
||||
{
|
||||
if (leftmost_concat != NULL)
|
||||
{
|
||||
leftmost_concat->left = new_concat;
|
||||
$$ = yr_re_node_create(RE_NODE_CONCAT, $2, $3);
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = yr_re_node_create(RE_NODE_CONCAT, new_concat, $3);
|
||||
}
|
||||
}
|
||||
|
||||
destroy_node_if($$ == NULL, $1);
|
||||
destroy_node_if($$ == NULL, $2);
|
||||
destroy_node_if($$ == NULL, $3);
|
||||
|
||||
fail_if($$ == NULL, ERROR_INSUFFICIENT_MEMORY);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
token_sequence
|
||||
: token_or_range
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| token_sequence token_or_range
|
||||
{
|
||||
fail_if_too_many_ast_levels({
|
||||
yr_re_node_destroy($1);
|
||||
yr_re_node_destroy($2);
|
||||
});
|
||||
|
||||
$$ = yr_re_node_create(RE_NODE_CONCAT, $1, $2);
|
||||
|
||||
destroy_node_if($$ == NULL, $1);
|
||||
destroy_node_if($$ == NULL, $2);
|
||||
|
||||
fail_if($$ == NULL, ERROR_INSUFFICIENT_MEMORY);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
token_or_range
|
||||
: token
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| range
|
||||
{
|
||||
$$ = $1;
|
||||
$$->greedy = FALSE;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
token
|
||||
: byte
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| '('
|
||||
{
|
||||
lex_env->inside_or++;
|
||||
}
|
||||
alternatives ')'
|
||||
{
|
||||
$$ = $3;
|
||||
lex_env->inside_or--;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
range
|
||||
: '[' _NUMBER_ ']'
|
||||
{
|
||||
if ($2 <= 0)
|
||||
{
|
||||
yyerror(yyscanner, lex_env, "invalid jump length");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
if (lex_env->inside_or && $2 > STRING_CHAINING_THRESHOLD)
|
||||
{
|
||||
yyerror(yyscanner, lex_env, "jumps over "
|
||||
STR(STRING_CHAINING_THRESHOLD)
|
||||
" now allowed inside alternation (|)");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
$$ = yr_re_node_create(RE_NODE_RANGE_ANY, NULL, NULL);
|
||||
|
||||
fail_if($$ == NULL, ERROR_INSUFFICIENT_MEMORY);
|
||||
|
||||
$$->start = (int) $2;
|
||||
$$->end = (int) $2;
|
||||
}
|
||||
| '[' _NUMBER_ '-' _NUMBER_ ']'
|
||||
{
|
||||
if (lex_env->inside_or &&
|
||||
($2 > STRING_CHAINING_THRESHOLD ||
|
||||
$4 > STRING_CHAINING_THRESHOLD) )
|
||||
{
|
||||
yyerror(yyscanner, lex_env, "jumps over "
|
||||
STR(STRING_CHAINING_THRESHOLD)
|
||||
" now allowed inside alternation (|)");
|
||||
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
if ($2 < 0 || $4 < 0)
|
||||
{
|
||||
yyerror(yyscanner, lex_env, "invalid negative jump length");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
if ($2 > $4)
|
||||
{
|
||||
yyerror(yyscanner, lex_env, "invalid jump range");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
$$ = yr_re_node_create(RE_NODE_RANGE_ANY, NULL, NULL);
|
||||
|
||||
fail_if($$ == NULL, ERROR_INSUFFICIENT_MEMORY);
|
||||
|
||||
$$->start = (int) $2;
|
||||
$$->end = (int) $4;
|
||||
}
|
||||
| '[' _NUMBER_ '-' ']'
|
||||
{
|
||||
if (lex_env->inside_or)
|
||||
{
|
||||
yyerror(yyscanner, lex_env,
|
||||
"unbounded jumps not allowed inside alternation (|)");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
if ($2 < 0)
|
||||
{
|
||||
yyerror(yyscanner, lex_env, "invalid negative jump length");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
$$ = yr_re_node_create(RE_NODE_RANGE_ANY, NULL, NULL);
|
||||
|
||||
fail_if($$ == NULL, ERROR_INSUFFICIENT_MEMORY);
|
||||
|
||||
$$->start = (int) $2;
|
||||
$$->end = INT_MAX;
|
||||
}
|
||||
| '[' '-' ']'
|
||||
{
|
||||
if (lex_env->inside_or)
|
||||
{
|
||||
yyerror(yyscanner, lex_env,
|
||||
"unbounded jumps not allowed inside alternation (|)");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
$$ = yr_re_node_create(RE_NODE_RANGE_ANY, NULL, NULL);
|
||||
|
||||
fail_if($$ == NULL, ERROR_INSUFFICIENT_MEMORY);
|
||||
|
||||
$$->start = 0;
|
||||
$$->end = INT_MAX;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
alternatives
|
||||
: tokens
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| alternatives '|' tokens
|
||||
{
|
||||
mark_as_not_fast_regexp();
|
||||
|
||||
fail_if_too_many_ast_levels({
|
||||
yr_re_node_destroy($1);
|
||||
yr_re_node_destroy($3);
|
||||
});
|
||||
|
||||
$$ = yr_re_node_create(RE_NODE_ALT, $1, $3);
|
||||
|
||||
destroy_node_if($$ == NULL, $1);
|
||||
destroy_node_if($$ == NULL, $3);
|
||||
|
||||
fail_if($$ == NULL, ERROR_INSUFFICIENT_MEMORY);
|
||||
}
|
||||
;
|
||||
|
||||
byte
|
||||
: _BYTE_
|
||||
{
|
||||
$$ = yr_re_node_create(RE_NODE_LITERAL, NULL, NULL);
|
||||
|
||||
fail_if($$ == NULL, ERROR_INSUFFICIENT_MEMORY);
|
||||
|
||||
$$->value = (int) $1;
|
||||
}
|
||||
| _MASKED_BYTE_
|
||||
{
|
||||
uint8_t mask = (uint8_t) ($1 >> 8);
|
||||
|
||||
if (mask == 0x00)
|
||||
{
|
||||
$$ = yr_re_node_create(RE_NODE_ANY, NULL, NULL);
|
||||
|
||||
fail_if($$ == NULL, ERROR_INSUFFICIENT_MEMORY);
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = yr_re_node_create(RE_NODE_MASKED_LITERAL, NULL, NULL);
|
||||
|
||||
fail_if($$ == NULL, ERROR_INSUFFICIENT_MEMORY);
|
||||
|
||||
$$->value = $1 & 0xFF;
|
||||
$$->mask = mask;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Lexical analyzer for hex strings */
|
||||
|
||||
%{
|
||||
|
||||
/* Disable warnings for unused functions in this file.
|
||||
|
||||
As we redefine YY_FATAL_ERROR macro to use our own function hex_yyfatal, the
|
||||
yy_fatal_error function generated by Flex is not actually used, causing a
|
||||
compiler warning. Flex doesn't offer any options to remove the yy_fatal_error
|
||||
function. When they include something like %option noyy_fatal_error as they do
|
||||
with noyywrap then we can remove this pragma.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <yara/globals.h>
|
||||
#include <yara/limits.h>
|
||||
#include <yara/error.h>
|
||||
#include <yara/mem.h>
|
||||
#include <yara/re.h>
|
||||
#include <yara/threading.h>
|
||||
#include <yara/strutils.h>
|
||||
#include <yara/hex_lexer.h>
|
||||
|
||||
#include "hex_grammar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#define ERROR_IF(x, error) \
|
||||
if (x) \
|
||||
{ \
|
||||
RE_AST* re_ast = yyget_extra(yyscanner); \
|
||||
re_ast->error_code = error; \
|
||||
YYABORT; \
|
||||
} \
|
||||
|
||||
%}
|
||||
|
||||
%option reentrant bison-bridge
|
||||
%option noyywrap
|
||||
%option nounistd
|
||||
%option noinput
|
||||
%option nounput
|
||||
%option never-interactive
|
||||
%option yylineno
|
||||
%option prefix="hex_yy"
|
||||
|
||||
%option outfile="lex.yy.c"
|
||||
|
||||
%option verbose
|
||||
%option warn
|
||||
|
||||
digit [0-9]
|
||||
letter [a-zA-Z]
|
||||
hexdigit [a-fA-F0-9]
|
||||
|
||||
%x comment
|
||||
%x range
|
||||
|
||||
%%
|
||||
|
||||
|
||||
<INITIAL>{hexdigit}{2} {
|
||||
|
||||
yylval->integer = xtoi(yytext);
|
||||
return _BYTE_;
|
||||
}
|
||||
|
||||
<INITIAL>{hexdigit}\? {
|
||||
|
||||
yytext[1] = '0'; // replace ? by 0
|
||||
yylval->integer = xtoi(yytext) | 0xF000 ;
|
||||
return _MASKED_BYTE_;
|
||||
}
|
||||
|
||||
\?{hexdigit} {
|
||||
|
||||
yytext[0] = '0'; // replace ? by 0
|
||||
yylval->integer = xtoi(yytext) | 0x0F00 ;
|
||||
return _MASKED_BYTE_;
|
||||
}
|
||||
|
||||
\?\? {
|
||||
|
||||
yylval->integer = 0x0000;
|
||||
return _MASKED_BYTE_;
|
||||
}
|
||||
|
||||
\[ {
|
||||
|
||||
BEGIN(range);
|
||||
return yytext[0];
|
||||
}
|
||||
|
||||
"/*"(.|\n)*"*/" // skip comments
|
||||
|
||||
"//".* // skip single-line comments
|
||||
|
||||
<range>\- {
|
||||
return yytext[0];
|
||||
}
|
||||
|
||||
<range>{digit}+ {
|
||||
|
||||
yylval->integer = atoi(yytext);
|
||||
return _NUMBER_;
|
||||
}
|
||||
|
||||
<range>\] {
|
||||
|
||||
BEGIN(INITIAL);
|
||||
return yytext[0];
|
||||
}
|
||||
|
||||
<range>[ \t\r\n] // skip whitespaces
|
||||
|
||||
<range>. {
|
||||
|
||||
yyerror(yyscanner, lex_env, "invalid character in hex string jump");
|
||||
yyterminate();
|
||||
}
|
||||
|
||||
[ \t\r\n] // skip whitespaces
|
||||
|
||||
[{}()|] { // pass valid characters to the parser
|
||||
|
||||
return yytext[0];
|
||||
}
|
||||
|
||||
. { // reject all other characters
|
||||
|
||||
yyerror(yyscanner, lex_env, "invalid character in hex string");
|
||||
yyterminate();
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
void yyfatal(
|
||||
yyscan_t yyscanner,
|
||||
const char *error_message)
|
||||
{
|
||||
jmp_buf* recovery_state = (jmp_buf*) yr_thread_storage_get_value(
|
||||
&yr_recovery_state_key);
|
||||
|
||||
longjmp(*recovery_state, 1);
|
||||
}
|
||||
|
||||
void yyerror(
|
||||
yyscan_t yyscanner,
|
||||
HEX_LEX_ENVIRONMENT* lex_env,
|
||||
const char *error_message)
|
||||
{
|
||||
// if lex_env->last_error_code was set to some error code before
|
||||
// don't overwrite it, we are interested in the first error, not in
|
||||
// subsequent errors like "syntax error, unexpected $end" caused by
|
||||
// early parser termination.
|
||||
|
||||
if (lex_env->last_error_code == ERROR_SUCCESS)
|
||||
{
|
||||
lex_env->last_error_code = ERROR_INVALID_HEX_STRING;
|
||||
|
||||
strlcpy(
|
||||
lex_env->last_error_message,
|
||||
error_message,
|
||||
sizeof(lex_env->last_error_message));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int yr_parse_hex_string(
|
||||
const char* hex_string,
|
||||
RE_AST** re_ast,
|
||||
RE_ERROR* error)
|
||||
{
|
||||
yyscan_t yyscanner;
|
||||
jmp_buf recovery_state;
|
||||
HEX_LEX_ENVIRONMENT lex_env;
|
||||
|
||||
lex_env.last_error_code = ERROR_SUCCESS;
|
||||
lex_env.inside_or = 0;
|
||||
|
||||
yr_thread_storage_set_value(&yr_recovery_state_key, &recovery_state);
|
||||
|
||||
if (setjmp(recovery_state) != 0)
|
||||
return ERROR_INTERNAL_FATAL_ERROR;
|
||||
|
||||
FAIL_ON_ERROR(yr_re_ast_create(re_ast));
|
||||
|
||||
// The RE_FLAGS_FAST_REGEXP flag indicates a regular expression can be
|
||||
// matched by faster algorithm. These regular expressions come from hex
|
||||
// strings that do not contain alternatives, like in:
|
||||
//
|
||||
// { ( 01 02 | 03 04) 05 06 }.
|
||||
//
|
||||
// This flag is unset later during parsing if alternatives are used.
|
||||
|
||||
(*re_ast)->flags |= RE_FLAGS_FAST_REGEXP;
|
||||
|
||||
// Set RE_FLAGS_DOT_ALL because in hex strings the "dot" (?? in this case)
|
||||
// must match all characters including new-line.
|
||||
|
||||
(*re_ast)->flags |= RE_FLAGS_DOT_ALL;
|
||||
|
||||
yylex_init(&yyscanner);
|
||||
yyset_extra(*re_ast, yyscanner);
|
||||
yy_scan_string(hex_string, yyscanner);
|
||||
yyparse(yyscanner, &lex_env);
|
||||
yylex_destroy(yyscanner);
|
||||
|
||||
if (lex_env.last_error_code != ERROR_SUCCESS)
|
||||
{
|
||||
strlcpy(error->message, lex_env.last_error_message, sizeof(error->message));
|
||||
return lex_env.last_error_code;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright (c) 2007-2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_YARA_H
|
||||
#define YR_YARA_H
|
||||
|
||||
#include "yara/utils.h"
|
||||
#include "yara/filemap.h"
|
||||
#include "yara/compiler.h"
|
||||
#include "yara/modules.h"
|
||||
#include "yara/object.h"
|
||||
#include "yara/libyara.h"
|
||||
#include "yara/error.h"
|
||||
#include "yara/stream.h"
|
||||
#include "yara/hash.h"
|
||||
#include "yara/scanner.h"
|
||||
#include "yara/mem.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _AHOCORASICK_H
|
||||
#define _AHOCORASICK_H
|
||||
|
||||
#include <yara/limits.h>
|
||||
#include <yara/atoms.h>
|
||||
#include <yara/types.h>
|
||||
|
||||
|
||||
#define YR_AC_ROOT_STATE 0
|
||||
#define YR_AC_NEXT_STATE(t) (t >> 32)
|
||||
#define YR_AC_INVALID_TRANSITION(t, c) (((t) & 0xFFFF) != c)
|
||||
|
||||
#define YR_AC_MAKE_TRANSITION(state, code, flags) \
|
||||
((uint64_t)((((uint64_t) state) << 32) | ((flags) << 16) | (code)))
|
||||
|
||||
#define YR_AC_USED_FLAG 0x1
|
||||
|
||||
#define YR_AC_USED_TRANSITION_SLOT(x) ((x) & (YR_AC_USED_FLAG << 16))
|
||||
#define YR_AC_UNUSED_TRANSITION_SLOT(x) (!YR_AC_USED_TRANSITION_SLOT(x))
|
||||
|
||||
|
||||
int yr_ac_automaton_create(
|
||||
YR_AC_AUTOMATON** automaton);
|
||||
|
||||
|
||||
int yr_ac_automaton_destroy(
|
||||
YR_AC_AUTOMATON* automaton);
|
||||
|
||||
|
||||
int yr_ac_add_string(
|
||||
YR_AC_AUTOMATON* automaton,
|
||||
YR_STRING* string,
|
||||
YR_ATOM_LIST_ITEM* atom,
|
||||
YR_ARENA* matches_arena);
|
||||
|
||||
|
||||
int yr_ac_compile(
|
||||
YR_AC_AUTOMATON* automaton,
|
||||
YR_ARENA* arena,
|
||||
YR_AC_TABLES* tables);
|
||||
|
||||
|
||||
void yr_ac_print_automaton(
|
||||
YR_AC_AUTOMATON* automaton);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_ARENA_H
|
||||
#define YR_ARENA_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <yara/integers.h>
|
||||
#include <yara/stream.h>
|
||||
|
||||
// Indicated that the arena is self-contained and stored in a single page. A
|
||||
// self-contained arenas is one that doesn't contains any pointers to outside
|
||||
// data. All pointers in a self-contained arena points at some address within
|
||||
// the arena.
|
||||
#define ARENA_FLAGS_COALESCED 1
|
||||
|
||||
// Each pages of an arena marked with this flag maintain a list of YR_RELOC
|
||||
// structures for keeping track of pointers stored within the arena. When the
|
||||
// arena is relocated this allows to fix those pointers that pointed to some
|
||||
// address within the relocated arena.
|
||||
#define ARENA_FLAGS_RELOCATABLE 2
|
||||
|
||||
#define ARENA_FILE_VERSION ((17 << 16) | MAX_THREADS)
|
||||
|
||||
#define EOL ((size_t) -1)
|
||||
|
||||
|
||||
typedef struct _YR_RELOC
|
||||
{
|
||||
uint32_t offset;
|
||||
struct _YR_RELOC* next;
|
||||
|
||||
} YR_RELOC;
|
||||
|
||||
|
||||
typedef struct _YR_ARENA_PAGE
|
||||
{
|
||||
uint8_t* new_address;
|
||||
uint8_t* address;
|
||||
|
||||
size_t size;
|
||||
size_t used;
|
||||
|
||||
YR_RELOC* reloc_list_head;
|
||||
YR_RELOC* reloc_list_tail;
|
||||
|
||||
struct _YR_ARENA_PAGE* next;
|
||||
struct _YR_ARENA_PAGE* prev;
|
||||
|
||||
} YR_ARENA_PAGE;
|
||||
|
||||
|
||||
typedef struct _YR_ARENA
|
||||
{
|
||||
int flags;
|
||||
|
||||
YR_ARENA_PAGE* page_list_head;
|
||||
YR_ARENA_PAGE* current_page;
|
||||
|
||||
} YR_ARENA;
|
||||
|
||||
|
||||
int yr_arena_create(
|
||||
size_t initial_size,
|
||||
int flags,
|
||||
YR_ARENA** arena);
|
||||
|
||||
|
||||
void yr_arena_destroy(
|
||||
YR_ARENA* arena);
|
||||
|
||||
|
||||
void* yr_arena_base_address(
|
||||
YR_ARENA* arena);
|
||||
|
||||
|
||||
void* yr_arena_next_address(
|
||||
YR_ARENA* arena,
|
||||
void* address,
|
||||
size_t offset);
|
||||
|
||||
|
||||
int yr_arena_coalesce(
|
||||
YR_ARENA* arena);
|
||||
|
||||
|
||||
int yr_arena_reserve_memory(
|
||||
YR_ARENA* arena,
|
||||
size_t size);
|
||||
|
||||
|
||||
int yr_arena_allocate_memory(
|
||||
YR_ARENA* arena,
|
||||
size_t size,
|
||||
void** allocated_memory);
|
||||
|
||||
|
||||
int yr_arena_allocate_struct(
|
||||
YR_ARENA* arena,
|
||||
size_t size,
|
||||
void** allocated_memory,
|
||||
...);
|
||||
|
||||
|
||||
int yr_arena_make_ptr_relocatable(
|
||||
YR_ARENA* arena,
|
||||
void* base,
|
||||
...);
|
||||
|
||||
|
||||
int yr_arena_write_data(
|
||||
YR_ARENA* arena,
|
||||
const void* data,
|
||||
size_t size,
|
||||
void** written_data);
|
||||
|
||||
|
||||
int yr_arena_write_string(
|
||||
YR_ARENA* arena,
|
||||
const char* string,
|
||||
char** written_string);
|
||||
|
||||
|
||||
int yr_arena_append(
|
||||
YR_ARENA* target_arena,
|
||||
YR_ARENA* source_arena);
|
||||
|
||||
|
||||
int yr_arena_load_stream(
|
||||
YR_STREAM* stream,
|
||||
YR_ARENA** arena);
|
||||
|
||||
|
||||
int yr_arena_save_stream(
|
||||
YR_ARENA* arena,
|
||||
YR_STREAM* stream);
|
||||
|
||||
|
||||
int yr_arena_duplicate(
|
||||
YR_ARENA* arena,
|
||||
YR_ARENA** duplicated);
|
||||
|
||||
|
||||
void yr_arena_print(
|
||||
YR_ARENA* arena);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_ATOMS_H
|
||||
#define YR_ATOMS_H
|
||||
|
||||
#include <yara/limits.h>
|
||||
#include <yara/re.h>
|
||||
|
||||
#define ATOM_TREE_LEAF 1
|
||||
#define ATOM_TREE_AND 2
|
||||
#define ATOM_TREE_OR 3
|
||||
|
||||
|
||||
typedef struct _ATOM_TREE_NODE
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t atom_length;
|
||||
uint8_t atom[MAX_ATOM_LENGTH];
|
||||
|
||||
uint8_t* forward_code;
|
||||
uint8_t* backward_code;
|
||||
|
||||
RE_NODE* recent_nodes[MAX_ATOM_LENGTH];
|
||||
|
||||
struct _ATOM_TREE_NODE* children_head;
|
||||
struct _ATOM_TREE_NODE* children_tail;
|
||||
struct _ATOM_TREE_NODE* next_sibling;
|
||||
|
||||
} ATOM_TREE_NODE;
|
||||
|
||||
|
||||
typedef struct _ATOM_TREE
|
||||
{
|
||||
ATOM_TREE_NODE* current_leaf;
|
||||
ATOM_TREE_NODE* root_node;
|
||||
|
||||
} ATOM_TREE;
|
||||
|
||||
|
||||
typedef struct _YR_ATOM_LIST_ITEM
|
||||
{
|
||||
uint8_t atom_length;
|
||||
uint8_t atom[MAX_ATOM_LENGTH];
|
||||
|
||||
uint16_t backtrack;
|
||||
|
||||
uint8_t* forward_code;
|
||||
uint8_t* backward_code;
|
||||
|
||||
struct _YR_ATOM_LIST_ITEM* next;
|
||||
|
||||
} YR_ATOM_LIST_ITEM;
|
||||
|
||||
|
||||
int yr_atoms_extract_from_re(
|
||||
RE_AST* re_ast,
|
||||
int flags,
|
||||
YR_ATOM_LIST_ITEM** atoms);
|
||||
|
||||
|
||||
int yr_atoms_extract_from_string(
|
||||
uint8_t* string,
|
||||
int string_length,
|
||||
int flags,
|
||||
YR_ATOM_LIST_ITEM** atoms);
|
||||
|
||||
|
||||
int yr_atoms_min_quality(
|
||||
YR_ATOM_LIST_ITEM* atom_list);
|
||||
|
||||
|
||||
void yr_atoms_list_destroy(
|
||||
YR_ATOM_LIST_ITEM* list_head);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_COMPILER_H
|
||||
#define YR_COMPILER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <yara/ahocorasick.h>
|
||||
#include <yara/arena.h>
|
||||
#include <yara/hash.h>
|
||||
#include <yara/utils.h>
|
||||
#include <yara/filemap.h>
|
||||
|
||||
|
||||
#define YARA_ERROR_LEVEL_ERROR 0
|
||||
#define YARA_ERROR_LEVEL_WARNING 1
|
||||
|
||||
|
||||
typedef void (*YR_COMPILER_CALLBACK_FUNC)(
|
||||
int error_level,
|
||||
const char* file_name,
|
||||
int line_number,
|
||||
const char* message,
|
||||
void* user_data);
|
||||
|
||||
|
||||
typedef const char* (*YR_COMPILER_INCLUDE_CALLBACK_FUNC)(
|
||||
const char* include_name,
|
||||
const char* calling_rule_filename,
|
||||
const char* calling_rule_namespace,
|
||||
void* user_data);
|
||||
|
||||
|
||||
typedef void (*YR_COMPILER_INCLUDE_FREE_FUNC)(
|
||||
const char* callback_result_ptr,
|
||||
void* user_data);
|
||||
|
||||
|
||||
typedef void (*YR_COMPILER_RE_AST_CALLBACK_FUNC)(
|
||||
const YR_RULE* rule,
|
||||
const char* string_identifier,
|
||||
const RE_AST* re_ast,
|
||||
void* user_data);
|
||||
|
||||
|
||||
typedef struct _YR_FIXUP
|
||||
{
|
||||
void* address;
|
||||
struct _YR_FIXUP* next;
|
||||
|
||||
} YR_FIXUP;
|
||||
|
||||
|
||||
typedef struct _YR_COMPILER
|
||||
{
|
||||
int errors;
|
||||
int current_line;
|
||||
int last_error;
|
||||
int last_error_line;
|
||||
int last_result;
|
||||
|
||||
jmp_buf error_recovery;
|
||||
|
||||
YR_ARENA* sz_arena;
|
||||
YR_ARENA* rules_arena;
|
||||
YR_ARENA* strings_arena;
|
||||
YR_ARENA* code_arena;
|
||||
YR_ARENA* re_code_arena;
|
||||
YR_ARENA* compiled_rules_arena;
|
||||
YR_ARENA* externals_arena;
|
||||
YR_ARENA* namespaces_arena;
|
||||
YR_ARENA* metas_arena;
|
||||
YR_ARENA* matches_arena;
|
||||
YR_ARENA* automaton_arena;
|
||||
|
||||
YR_AC_AUTOMATON* automaton;
|
||||
YR_HASH_TABLE* rules_table;
|
||||
YR_HASH_TABLE* objects_table;
|
||||
YR_HASH_TABLE* strings_table;
|
||||
YR_NAMESPACE* current_namespace;
|
||||
YR_RULE* current_rule;
|
||||
|
||||
YR_FIXUP* fixup_stack_head;
|
||||
|
||||
int namespaces_count;
|
||||
|
||||
uint8_t* loop_address[MAX_LOOP_NESTING];
|
||||
char* loop_identifier[MAX_LOOP_NESTING];
|
||||
int loop_depth;
|
||||
int loop_for_of_mem_offset;
|
||||
|
||||
char* file_name_stack[MAX_INCLUDE_DEPTH];
|
||||
int file_name_stack_ptr;
|
||||
|
||||
char last_error_extra_info[MAX_COMPILER_ERROR_EXTRA_INFO];
|
||||
|
||||
char lex_buf[LEX_BUF_SIZE];
|
||||
char* lex_buf_ptr;
|
||||
unsigned short lex_buf_len;
|
||||
|
||||
char include_base_dir[MAX_PATH];
|
||||
void* user_data;
|
||||
void* incl_clbk_user_data;
|
||||
void* re_ast_clbk_user_data;
|
||||
|
||||
YR_COMPILER_CALLBACK_FUNC callback;
|
||||
YR_COMPILER_INCLUDE_CALLBACK_FUNC include_callback;
|
||||
YR_COMPILER_INCLUDE_FREE_FUNC include_free;
|
||||
YR_COMPILER_RE_AST_CALLBACK_FUNC re_ast_callback;
|
||||
|
||||
|
||||
} YR_COMPILER;
|
||||
|
||||
|
||||
#define yr_compiler_set_error_extra_info(compiler, info) \
|
||||
strlcpy( \
|
||||
compiler->last_error_extra_info, \
|
||||
info, \
|
||||
sizeof(compiler->last_error_extra_info)); \
|
||||
|
||||
|
||||
#define yr_compiler_set_error_extra_info_fmt(compiler, fmt, ...) \
|
||||
snprintf( \
|
||||
compiler->last_error_extra_info, \
|
||||
sizeof(compiler->last_error_extra_info), \
|
||||
fmt, __VA_ARGS__);
|
||||
|
||||
|
||||
|
||||
int _yr_compiler_push_file_name(
|
||||
YR_COMPILER* compiler,
|
||||
const char* file_name);
|
||||
|
||||
|
||||
void _yr_compiler_pop_file_name(
|
||||
YR_COMPILER* compiler);
|
||||
|
||||
|
||||
const char* _yr_compiler_default_include_callback(
|
||||
const char* include_name,
|
||||
const char* calling_rule_filename,
|
||||
const char* calling_rule_namespace,
|
||||
void* user_data);
|
||||
|
||||
|
||||
YR_API int yr_compiler_create(
|
||||
YR_COMPILER** compiler);
|
||||
|
||||
|
||||
YR_API void yr_compiler_destroy(
|
||||
YR_COMPILER* compiler);
|
||||
|
||||
|
||||
YR_API void yr_compiler_set_callback(
|
||||
YR_COMPILER* compiler,
|
||||
YR_COMPILER_CALLBACK_FUNC callback,
|
||||
void* user_data);
|
||||
|
||||
|
||||
YR_API void yr_compiler_set_include_callback(
|
||||
YR_COMPILER* compiler,
|
||||
YR_COMPILER_INCLUDE_CALLBACK_FUNC include_callback,
|
||||
YR_COMPILER_INCLUDE_FREE_FUNC include_free,
|
||||
void* user_data);
|
||||
|
||||
|
||||
YR_API void yr_compiler_set_re_ast_callback(
|
||||
YR_COMPILER* compiler,
|
||||
YR_COMPILER_RE_AST_CALLBACK_FUNC re_ast_callback,
|
||||
void* user_data);
|
||||
|
||||
|
||||
YR_API int yr_compiler_add_file(
|
||||
YR_COMPILER* compiler,
|
||||
FILE* rules_file,
|
||||
const char* namespace_,
|
||||
const char* file_name);
|
||||
|
||||
|
||||
YR_API int yr_compiler_add_fd(
|
||||
YR_COMPILER* compiler,
|
||||
YR_FILE_DESCRIPTOR rules_fd,
|
||||
const char* namespace_,
|
||||
const char* file_name);
|
||||
|
||||
|
||||
YR_API int yr_compiler_add_string(
|
||||
YR_COMPILER* compiler,
|
||||
const char* rules_string,
|
||||
const char* namespace_);
|
||||
|
||||
|
||||
YR_API char* yr_compiler_get_error_message(
|
||||
YR_COMPILER* compiler,
|
||||
char* buffer,
|
||||
int buffer_size);
|
||||
|
||||
|
||||
YR_API char* yr_compiler_get_current_file_name(
|
||||
YR_COMPILER* compiler);
|
||||
|
||||
|
||||
YR_API int yr_compiler_define_integer_variable(
|
||||
YR_COMPILER* compiler,
|
||||
const char* identifier,
|
||||
int64_t value);
|
||||
|
||||
|
||||
YR_API int yr_compiler_define_boolean_variable(
|
||||
YR_COMPILER* compiler,
|
||||
const char* identifier,
|
||||
int value);
|
||||
|
||||
|
||||
YR_API int yr_compiler_define_float_variable(
|
||||
YR_COMPILER* compiler,
|
||||
const char* identifier,
|
||||
double value);
|
||||
|
||||
|
||||
YR_API int yr_compiler_define_string_variable(
|
||||
YR_COMPILER* compiler,
|
||||
const char* identifier,
|
||||
const char* value);
|
||||
|
||||
|
||||
YR_API int yr_compiler_get_rules(
|
||||
YR_COMPILER* compiler,
|
||||
YR_RULES** rules);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,138 @@
|
||||
#ifndef _DEX_H
|
||||
#define _DEX_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <yara/integers.h>
|
||||
#include <yara/types.h>
|
||||
|
||||
#define DEX_FILE_MAGIC_035 "dex\n035\x00"
|
||||
#define DEX_FILE_MAGIC_036 "dex\n036\x00"
|
||||
#define DEX_FILE_MAGIC_037 "dex\n037\x00"
|
||||
#define DEX_FILE_MAGIC_038 "dex\n038\x00"
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t magic[8];
|
||||
uint32_t checksum;
|
||||
uint8_t signature[20];
|
||||
uint32_t file_size;
|
||||
uint32_t header_size;
|
||||
uint32_t endian_tag;
|
||||
uint32_t link_size;
|
||||
uint32_t link_offset;
|
||||
uint32_t map_offset;
|
||||
uint32_t string_ids_size;
|
||||
uint32_t string_ids_offset;
|
||||
uint32_t type_ids_size;
|
||||
uint32_t type_ids_offset;
|
||||
uint32_t proto_ids_size;
|
||||
uint32_t proto_ids_offset;
|
||||
uint32_t field_ids_size;
|
||||
uint32_t field_ids_offset;
|
||||
uint32_t method_ids_size;
|
||||
uint32_t method_ids_offset;
|
||||
uint32_t class_defs_size;
|
||||
uint32_t class_defs_offset;
|
||||
uint32_t data_size;
|
||||
uint32_t data_offset;
|
||||
} dex_header_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t string_data_offset;
|
||||
} string_id_item_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t utf16_size;
|
||||
} string_data_item_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t descriptor_idx;
|
||||
} type_id_item_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t shorty_idx;
|
||||
uint32_t return_type_idx;
|
||||
uint32_t parameters_offset;
|
||||
} proto_id_item_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t class_idx;
|
||||
uint16_t type_idx;
|
||||
uint32_t name_idx;
|
||||
} field_id_item_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t class_idx;
|
||||
uint16_t proto_idx;
|
||||
uint32_t name_idx;
|
||||
} method_id_item_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t class_idx;
|
||||
uint32_t access_flags;
|
||||
uint32_t super_class_idx;
|
||||
uint32_t interfaces_off;
|
||||
uint32_t source_file_idx;
|
||||
uint32_t annotations_offset;
|
||||
uint32_t class_data_offset;
|
||||
uint32_t static_values_offset;
|
||||
} class_id_item_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t static_fields_size;
|
||||
uint32_t instance_fields_size;
|
||||
uint32_t direct_methods_size;
|
||||
uint32_t virtual_methods_size;
|
||||
} class_data_item_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t field_idx_diff;
|
||||
uint32_t access_flags;
|
||||
} encoded_field_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t method_idx_diff;
|
||||
uint32_t access_flags;
|
||||
uint32_t code_off;
|
||||
} encoded_method_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t registers_size;
|
||||
uint16_t ins_size;
|
||||
uint16_t outs_size;
|
||||
uint16_t tries_size;
|
||||
uint32_t debug_info_off;
|
||||
uint32_t insns_size;
|
||||
} code_item_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t type;
|
||||
uint16_t unused;
|
||||
uint32_t size;
|
||||
uint32_t offset;
|
||||
} map_item_t;
|
||||
|
||||
typedef struct _DEX
|
||||
{
|
||||
const uint8_t* data;
|
||||
size_t data_size;
|
||||
dex_header_t *header;
|
||||
YR_OBJECT* object;
|
||||
} DEX;
|
||||
|
||||
|
||||
#define fits_in_dex(dex, pointer, size) \
|
||||
((size_t) size <= dex->data_size && \
|
||||
(uint8_t*) (pointer) >= dex->data && \
|
||||
(uint8_t*) (pointer) <= dex->data + dex->data_size - size)
|
||||
|
||||
#define struct_fits_in_dex(dex, pointer, struct_type) \
|
||||
fits_in_dex(dex, pointer, sizeof(struct_type))
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,337 @@
|
||||
#ifndef YR_DOTNET_H
|
||||
#define YR_DOTNET_H
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
//
|
||||
// CLI header.
|
||||
// ECMA-335 Section II.25.3.3
|
||||
//
|
||||
typedef struct _CLI_HEADER {
|
||||
DWORD Size; // Called "Cb" in documentation.
|
||||
WORD MajorRuntimeVersion;
|
||||
WORD MinorRuntimeVersion;
|
||||
IMAGE_DATA_DIRECTORY MetaData;
|
||||
DWORD Flags;
|
||||
DWORD EntryPointToken;
|
||||
IMAGE_DATA_DIRECTORY Resources;
|
||||
IMAGE_DATA_DIRECTORY StrongNameSignature;
|
||||
ULONGLONG CodeManagerTable;
|
||||
IMAGE_DATA_DIRECTORY VTableFixups;
|
||||
ULONGLONG ExportAddressTableJumps;
|
||||
ULONGLONG ManagedNativeHeader;
|
||||
} CLI_HEADER, *PCLI_HEADER;
|
||||
|
||||
#define NET_METADATA_MAGIC 0x424a5342
|
||||
|
||||
//
|
||||
// CLI MetaData
|
||||
// ECMA-335 Section II.24.2.1
|
||||
//
|
||||
// Note: This is only part of the struct, as the rest of it is variable length.
|
||||
//
|
||||
typedef struct _NET_METADATA {
|
||||
DWORD Magic;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
DWORD Reserved;
|
||||
DWORD Length;
|
||||
char Version[0];
|
||||
} NET_METADATA, *PNET_METADATA;
|
||||
|
||||
#define DOTNET_STREAM_NAME_SIZE 32
|
||||
|
||||
//
|
||||
// CLI Stream Header
|
||||
// ECMA-335 Section II.24.2.2
|
||||
//
|
||||
typedef struct _STREAM_HEADER {
|
||||
DWORD Offset;
|
||||
DWORD Size;
|
||||
char Name[0];
|
||||
} STREAM_HEADER, *PSTREAM_HEADER;
|
||||
|
||||
|
||||
//
|
||||
// CLI #~ Stream Header
|
||||
// ECMA-335 Section II.24.2.6
|
||||
//
|
||||
typedef struct _TILDE_HEADER {
|
||||
DWORD Reserved1;
|
||||
BYTE MajorVersion;
|
||||
BYTE MinorVersion;
|
||||
BYTE HeapSizes;
|
||||
BYTE Reserved2;
|
||||
ULONGLONG Valid;
|
||||
ULONGLONG Sorted;
|
||||
} TILDE_HEADER, *PTILDE_HEADER;
|
||||
|
||||
// These are the bit positions in Valid which will be set if the table
|
||||
// exists.
|
||||
#define BIT_MODULE 0x00
|
||||
#define BIT_TYPEREF 0x01
|
||||
#define BIT_TYPEDEF 0x02
|
||||
#define BIT_FIELDPTR 0x03 // Not documented in ECMA-335
|
||||
#define BIT_FIELD 0x04
|
||||
#define BIT_METHODDEFPTR 0x05 // Not documented in ECMA-335
|
||||
#define BIT_METHODDEF 0x06
|
||||
#define BIT_PARAMPTR 0x07 // Not documented in ECMA-335
|
||||
#define BIT_PARAM 0x08
|
||||
#define BIT_INTERFACEIMPL 0x09
|
||||
#define BIT_MEMBERREF 0x0A
|
||||
#define BIT_CONSTANT 0x0B
|
||||
#define BIT_CUSTOMATTRIBUTE 0x0C
|
||||
#define BIT_FIELDMARSHAL 0x0D
|
||||
#define BIT_DECLSECURITY 0x0E
|
||||
#define BIT_CLASSLAYOUT 0x0F
|
||||
#define BIT_FIELDLAYOUT 0x10
|
||||
#define BIT_STANDALONESIG 0x11
|
||||
#define BIT_EVENTMAP 0x12
|
||||
#define BIT_EVENTPTR 0x13 // Not documented in ECMA-335
|
||||
#define BIT_EVENT 0x14
|
||||
#define BIT_PROPERTYMAP 0x15
|
||||
#define BIT_PROPERTYPTR 0x16 // Not documented in ECMA-335
|
||||
#define BIT_PROPERTY 0x17
|
||||
#define BIT_METHODSEMANTICS 0x18
|
||||
#define BIT_METHODIMPL 0x19
|
||||
#define BIT_MODULEREF 0x1A
|
||||
#define BIT_TYPESPEC 0x1B
|
||||
#define BIT_IMPLMAP 0x1C
|
||||
#define BIT_FIELDRVA 0x1D
|
||||
#define BIT_ENCLOG 0x1E // Not documented in ECMA-335
|
||||
#define BIT_ENCMAP 0x1F // Not documented in ECMA-335
|
||||
#define BIT_ASSEMBLY 0x20
|
||||
#define BIT_ASSEMBLYPROCESSOR 0x21
|
||||
#define BIT_ASSEMBLYOS 0x22
|
||||
#define BIT_ASSEMBLYREF 0x23
|
||||
#define BIT_ASSEMBLYREFPROCESSOR 0x24
|
||||
#define BIT_ASSEMBLYREFOS 0x25
|
||||
#define BIT_FILE 0x26
|
||||
#define BIT_EXPORTEDTYPE 0x27
|
||||
#define BIT_MANIFESTRESOURCE 0x28
|
||||
#define BIT_NESTEDCLASS 0x29
|
||||
#define BIT_GENERICPARAM 0x2A
|
||||
#define BIT_METHODSPEC 0x2B
|
||||
#define BIT_GENERICPARAMCONSTRAINT 0x2C
|
||||
// These are not documented in ECMA-335 nor is it clear what the format is.
|
||||
// They are for debugging information as far as I can tell.
|
||||
//#define BIT_DOCUMENT 0x30
|
||||
//#define BIT_METHODDEBUGINFORMATION 0x31
|
||||
//#define BIT_LOCALSCOPE 0x32
|
||||
//#define BIT_LOCALVARIABLE 0x33
|
||||
//#define BIT_LOCALCONSTANT 0x34
|
||||
//#define BIT_IMPORTSCOPE 0x35
|
||||
//#define BIT_STATEMACHINEMETHOD 0x36
|
||||
|
||||
|
||||
//
|
||||
// Element types. Note this is not a complete list as we aren't parsing all of
|
||||
// them. This only includes the ones we care about.
|
||||
// ECMA-335 Section II.23.1.16
|
||||
//
|
||||
#define ELEMENT_TYPE_STRING 0x0E
|
||||
|
||||
|
||||
// The string length of a typelib attribute is at most 0xFF.
|
||||
#define MAX_TYPELIB_SIZE 0xFF
|
||||
|
||||
//
|
||||
// Module table
|
||||
// ECMA-335 Section II.22.30
|
||||
//
|
||||
typedef struct _MODULE_TABLE {
|
||||
WORD Generation;
|
||||
union {
|
||||
WORD Name_Short;
|
||||
DWORD Name_Long;
|
||||
} Name;
|
||||
union {
|
||||
WORD Mvid_Short;
|
||||
DWORD Mvid_Long;
|
||||
} Mvid;
|
||||
union {
|
||||
WORD EncId_Short;
|
||||
DWORD EncId_Long;
|
||||
} EncId;
|
||||
union {
|
||||
WORD EncBaseId_Short;
|
||||
DWORD EncBaseId_Long;
|
||||
} EncBaseId;
|
||||
} MODULE_TABLE, *PMODULE_TABLE;
|
||||
|
||||
//
|
||||
// Assembly Table
|
||||
// ECMA-335 Section II.22.2
|
||||
//
|
||||
typedef struct _ASSEMBLY_TABLE {
|
||||
DWORD HashAlgId;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
WORD BuildNumber;
|
||||
WORD RevisionNumber;
|
||||
DWORD Flags;
|
||||
union {
|
||||
WORD PublicKey_Short;
|
||||
DWORD PublicKey_Long;
|
||||
} PublicKey;
|
||||
union {
|
||||
WORD Name_Short;
|
||||
DWORD Name_Long;
|
||||
} Name;
|
||||
} ASSEMBLY_TABLE, *PASSEMBLY_TABLE;
|
||||
|
||||
|
||||
//
|
||||
// Assembly Reference Table
|
||||
// ECMA-335 Section II.22.5
|
||||
//
|
||||
typedef struct _ASSEMBLYREF_TABLE {
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
WORD BuildNumber;
|
||||
WORD RevisionNumber;
|
||||
DWORD Flags;
|
||||
union {
|
||||
WORD PublicKeyOrToken_Short;
|
||||
DWORD PublicKeyOrToken_Long;
|
||||
} PublicKeyOrToken;
|
||||
union {
|
||||
WORD Name_Short;
|
||||
DWORD Name_Long;
|
||||
} Name;
|
||||
} ASSEMBLYREF_TABLE, *PASSEMBLYREF_TABLE;
|
||||
|
||||
|
||||
//
|
||||
// Manifest Resource Table
|
||||
// ECMA-335 Section II.22.24
|
||||
//
|
||||
typedef struct _MANIFESTRESOURCE_TABLE {
|
||||
DWORD Offset;
|
||||
DWORD Flags;
|
||||
union {
|
||||
WORD Name_Short;
|
||||
DWORD Name_Long;
|
||||
} Name;
|
||||
union {
|
||||
WORD Implementation_Short;
|
||||
DWORD Implementation_Long;
|
||||
} Implementation;
|
||||
} MANIFESTRESOURCE_TABLE, *PMANIFESTRESOURCE_TABLE;
|
||||
|
||||
//
|
||||
// ModuleRef Table
|
||||
// ECMA-335 Section II.22.31
|
||||
//
|
||||
// This is a short table, but necessary because the field size can change.
|
||||
//
|
||||
typedef struct _MODULEREF_TABLE {
|
||||
union {
|
||||
WORD Name_Short;
|
||||
DWORD Name_Long;
|
||||
} Name;
|
||||
} MODULEREF_TABLE, *PMODULEREF_TABLE;
|
||||
|
||||
|
||||
//
|
||||
// CustomAttribute Table
|
||||
// ECMA-335 Section II.22.10
|
||||
//
|
||||
typedef struct _CUSTOMATTRIBUTE_TABLE {
|
||||
union {
|
||||
WORD Parent_Short;
|
||||
DWORD Parent_Long;
|
||||
} Parent;
|
||||
union {
|
||||
WORD Type_Short;
|
||||
DWORD Type_Long;
|
||||
} Type;
|
||||
union {
|
||||
WORD Value_Short;
|
||||
DWORD Value_Long;
|
||||
} Value;
|
||||
} CUSTOMATTRIBUTE_TABLE, *PCUSTOMATTRIBUTE_TABLE;
|
||||
|
||||
|
||||
//
|
||||
// Constant TAble
|
||||
// ECMA-335 Section II.22.9
|
||||
//
|
||||
typedef struct _CONSTANT_TABLE {
|
||||
WORD Type;
|
||||
union {
|
||||
WORD Parent_Short;
|
||||
DWORD Parent_Long;
|
||||
} Parent;
|
||||
union {
|
||||
WORD Value_Short;
|
||||
DWORD Value_Long;
|
||||
} Value;
|
||||
} CONSTANT_TABLE, *PCONSTANT_TABLE;
|
||||
|
||||
|
||||
// Used to return offsets to the various headers.
|
||||
typedef struct _STREAMS {
|
||||
PSTREAM_HEADER guid;
|
||||
PSTREAM_HEADER tilde;
|
||||
PSTREAM_HEADER string;
|
||||
PSTREAM_HEADER blob;
|
||||
PSTREAM_HEADER us;
|
||||
} STREAMS, *PSTREAMS;
|
||||
|
||||
|
||||
// Used to return the value of parsing a #US or #Blob entry.
|
||||
// ECMA-335 Section II.24.2.4
|
||||
typedef struct _BLOB_PARSE_RESULT {
|
||||
uint8_t size; // Number of bytes parsed. This is the new offset.
|
||||
DWORD length; // Value of the bytes parsed. This is the blob length.
|
||||
} BLOB_PARSE_RESULT, *PBLOB_PARSE_RESULT;
|
||||
|
||||
|
||||
// Used to store the number of rows of each table.
|
||||
typedef struct _ROWS {
|
||||
uint32_t module;
|
||||
uint32_t moduleref;
|
||||
uint32_t assemblyref;
|
||||
uint32_t typeref;
|
||||
uint32_t methoddef;
|
||||
uint32_t memberref;
|
||||
uint32_t typedef_;
|
||||
uint32_t typespec;
|
||||
uint32_t field;
|
||||
uint32_t param;
|
||||
uint32_t property;
|
||||
uint32_t interfaceimpl;
|
||||
uint32_t event;
|
||||
uint32_t standalonesig;
|
||||
uint32_t assembly;
|
||||
uint32_t file;
|
||||
uint32_t exportedtype;
|
||||
uint32_t manifestresource;
|
||||
uint32_t genericparam;
|
||||
uint32_t genericparamconstraint;
|
||||
uint32_t methodspec;
|
||||
uint32_t assemblyrefprocessor;
|
||||
} ROWS, *PROWS;
|
||||
|
||||
|
||||
// Used to store the index sizes for the various tables.
|
||||
typedef struct _INDEX_SIZES {
|
||||
uint8_t string;
|
||||
uint8_t guid;
|
||||
uint8_t blob;
|
||||
uint8_t field;
|
||||
uint8_t methoddef;
|
||||
uint8_t memberref;
|
||||
uint8_t param;
|
||||
uint8_t event;
|
||||
uint8_t typedef_;
|
||||
uint8_t property;
|
||||
uint8_t moduleref;
|
||||
uint8_t assemblyrefprocessor;
|
||||
uint8_t assemblyref;
|
||||
uint8_t genericparam;
|
||||
} INDEX_SIZES, *PINDEX_SIZES;
|
||||
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _ELF_H
|
||||
#define _ELF_H
|
||||
|
||||
#include <yara/integers.h>
|
||||
|
||||
|
||||
// 32-bit ELF base types
|
||||
|
||||
typedef uint32_t elf32_addr_t;
|
||||
typedef uint16_t elf32_half_t;
|
||||
typedef uint32_t elf32_off_t;
|
||||
typedef uint32_t elf32_word_t;
|
||||
|
||||
// 64-bit ELF base types
|
||||
|
||||
typedef uint64_t elf64_addr_t;
|
||||
typedef uint16_t elf64_half_t;
|
||||
typedef uint64_t elf64_off_t;
|
||||
typedef uint32_t elf64_word_t;
|
||||
typedef uint64_t elf64_xword_t;
|
||||
|
||||
#define ELF_MAGIC 0x464C457F
|
||||
|
||||
#define ELF_ET_NONE 0x0000 // no type
|
||||
#define ELF_ET_REL 0x0001 // relocatable
|
||||
#define ELF_ET_EXEC 0x0002 // executable
|
||||
#define ELF_ET_DYN 0x0003 // Shared-Object-File
|
||||
#define ELF_ET_CORE 0x0004 // Corefile
|
||||
#define ELF_ET_LOPROC 0xFF00 // Processor-specific
|
||||
#define ELF_ET_HIPROC 0x00FF // Processor-specific
|
||||
|
||||
#define ELF_EM_NONE 0x0000 // no type
|
||||
#define ELF_EM_M32 0x0001 // AT&T WE 32100
|
||||
#define ELF_EM_SPARC 0x0002 // SPARC
|
||||
#define ELF_EM_386 0x0003 // Intel 80386
|
||||
#define ELF_EM_68K 0x0004 // Motorola 68000
|
||||
#define ELF_EM_88K 0x0005 // Motorola 88000
|
||||
#define ELF_EM_860 0x0007 // Intel 80860
|
||||
#define ELF_EM_MIPS 0x0008 // MIPS I Architecture
|
||||
#define ELF_EM_MIPS_RS3_LE 0x000A // MIPS RS3000 Little-endian
|
||||
#define ELF_EM_PPC 0x0014 // PowerPC
|
||||
#define ELF_EM_PPC64 0x0015 // 64-bit PowerPC
|
||||
#define ELF_EM_ARM 0x0028 // ARM
|
||||
#define ELF_EM_X86_64 0x003E // AMD/Intel x86_64
|
||||
#define ELF_EM_AARCH64 0x00B7 // 64-bit ARM
|
||||
|
||||
#define ELF_CLASS_NONE 0x0000
|
||||
#define ELF_CLASS_32 0x0001 // 32bit file
|
||||
#define ELF_CLASS_64 0x0002 // 64bit file
|
||||
|
||||
#define ELF_DATA_NONE 0x0000
|
||||
#define ELF_DATA_2LSB 0x0001
|
||||
#define ELF_DATA_2MSB 0x002
|
||||
|
||||
|
||||
#define ELF_SHT_NULL 0 // Section header table entry unused
|
||||
#define ELF_SHT_PROGBITS 1 // Program data
|
||||
#define ELF_SHT_SYMTAB 2 // Symbol table
|
||||
#define ELF_SHT_STRTAB 3 // String table
|
||||
#define ELF_SHT_RELA 4 // Relocation entries with addends
|
||||
#define ELF_SHT_HASH 5 // Symbol hash table
|
||||
#define ELF_SHT_DYNAMIC 6 // Dynamic linking information
|
||||
#define ELF_SHT_NOTE 7 // Notes
|
||||
#define ELF_SHT_NOBITS 8 // Program space with no data (bss)
|
||||
#define ELF_SHT_REL 9 // Relocation entries, no addends
|
||||
#define ELF_SHT_SHLIB 10 // Reserved
|
||||
#define ELF_SHT_DYNSYM 11 // Dynamic linker symbol table
|
||||
#define ELF_SHT_NUM 12 // Number of defined types
|
||||
|
||||
#define ELF_SHF_WRITE 0x1 // Section is writable
|
||||
#define ELF_SHF_ALLOC 0x2 // Section is present during execution
|
||||
#define ELF_SHF_EXECINSTR 0x4 // Section contains executable instructions
|
||||
|
||||
#define ELF_SHN_LORESERVE 0xFF00
|
||||
|
||||
#define ELF_PT_NULL 0 // The array element is unused
|
||||
#define ELF_PT_LOAD 1 // Loadable segment
|
||||
#define ELF_PT_DYNAMIC 2 // Segment contains dynamic linking info
|
||||
#define ELF_PT_INTERP 3 // Contains interpreter pathname
|
||||
#define ELF_PT_NOTE 4 // Location & size of auxiliary info
|
||||
#define ELF_PT_SHLIB 5 // Reserved, unspecified semantics
|
||||
#define ELF_PT_PHDR 6 // Location and size of program header table
|
||||
#define ELF_PT_TLS 7 // Thread-Local Storage
|
||||
#define ELF_PT_GNU_EH_FRAME 0x6474e550
|
||||
#define ELF_PT_GNU_STACK 0x6474e551
|
||||
|
||||
#define ELF_DT_NULL 0 // End of the dynamic entries
|
||||
#define ELF_DT_NEEDED 1 // Name of needed library
|
||||
#define ELF_DT_PLTRELSZ 2 // Size in bytes of PLT relocs
|
||||
#define ELF_DT_PLTGOT 3 // Processor defined value */
|
||||
#define ELF_DT_HASH 4 // Address of symbol hash table
|
||||
#define ELF_DT_STRTAB 5 // Address of string table
|
||||
#define ELF_DT_SYMTAB 6 // Address of symbol table
|
||||
#define ELF_DT_RELA 7 // Address of Rela relocs
|
||||
#define ELF_DT_RELASZ 8 // Total size of Rela relocs
|
||||
#define ELF_DT_RELAENT 9 // Size of one Rela reloc
|
||||
#define ELF_DT_STRSZ 10 // Size of string table
|
||||
#define ELF_DT_SYMENT 11 // Size of one symbol table entry
|
||||
#define ELF_DT_INIT 12 // Address of init function
|
||||
#define ELF_DT_FINI 13 // Address of termination function
|
||||
#define ELF_DT_SONAME 14 // Name of shared object
|
||||
#define ELF_DT_RPATH 15 // Library search path (deprecated)
|
||||
#define ELF_DT_SYMBOLIC 16 // Start symbol search here
|
||||
#define ELF_DT_REL 17 // Address of Rel relocs
|
||||
#define ELF_DT_RELSZ 18 // Total size of Rel relocs
|
||||
#define ELF_DT_RELENT 19 // Size of one Rel reloc
|
||||
#define ELF_DT_PLTREL 20 // Type of reloc in PLT
|
||||
#define ELF_DT_DEBUG 21 // For debugging; unspecified
|
||||
#define ELF_DT_TEXTREL 22 // Reloc might modify .text
|
||||
#define ELF_DT_JMPREL 23 // Address of PLT relocs
|
||||
#define ELF_DT_BIND_NOW 24 // Process relocations of object
|
||||
#define ELF_DT_INIT_ARRAY 25 // Array with addresses of init fct
|
||||
#define ELF_DT_FINI_ARRAY 26 // Array with addresses of fini fct
|
||||
#define ELF_DT_INIT_ARRAYSZ 27 // Size in bytes of DT_INIT_ARRAY
|
||||
#define ELF_DT_FINI_ARRAYSZ 28 // Size in bytes of DT_FINI_ARRAY
|
||||
#define ELF_DT_RUNPATH 29 // Library search path
|
||||
#define ELF_DT_FLAGS 30 // Flags for the object being loaded
|
||||
#define ELF_DT_ENCODING 32 // Start of encoded range
|
||||
|
||||
#define ELF_STT_NOTYPE 0 // Symbol type is unspecified
|
||||
#define ELF_STT_OBJECT 1 // Symbol is a data object
|
||||
#define ELF_STT_FUNC 2 // Symbol is a code object
|
||||
#define ELF_STT_SECTION 3 // Symbol associated with a section
|
||||
#define ELF_STT_FILE 4 // Symbol's name is file name
|
||||
#define ELF_STT_COMMON 5 // Symbol is a common data object
|
||||
#define ELF_STT_TLS 6 // Symbol is thread-local data object
|
||||
|
||||
#define ELF_STB_LOCAL 0 // Local symbol
|
||||
#define ELF_STB_GLOBAL 1 // Global symbol
|
||||
#define ELF_STB_WEAK 2 // Weak symbol
|
||||
|
||||
#define ELF_PF_X 0x1 // Segment is executable
|
||||
#define ELF_PF_W 0x2 // Segment is writable
|
||||
#define ELF_PF_R 0x4 // Segment is readable
|
||||
|
||||
#define ELF_PN_XNUM 0xffff
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t magic;
|
||||
uint8_t _class;
|
||||
uint8_t data;
|
||||
uint8_t version;
|
||||
uint8_t pad[8];
|
||||
uint8_t nident;
|
||||
|
||||
} elf_ident_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf_ident_t ident;
|
||||
elf32_half_t type;
|
||||
elf32_half_t machine;
|
||||
elf32_word_t version;
|
||||
elf32_addr_t entry;
|
||||
elf32_off_t ph_offset;
|
||||
elf32_off_t sh_offset;
|
||||
elf32_word_t flags;
|
||||
elf32_half_t header_size;
|
||||
elf32_half_t ph_entry_size;
|
||||
elf32_half_t ph_entry_count;
|
||||
elf32_half_t sh_entry_size;
|
||||
elf32_half_t sh_entry_count;
|
||||
elf32_half_t sh_str_table_index;
|
||||
|
||||
} elf32_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf_ident_t ident;
|
||||
elf64_half_t type;
|
||||
elf64_half_t machine;
|
||||
elf64_word_t version;
|
||||
elf64_addr_t entry;
|
||||
elf64_off_t ph_offset;
|
||||
elf64_off_t sh_offset;
|
||||
elf64_word_t flags;
|
||||
elf64_half_t header_size;
|
||||
elf64_half_t ph_entry_size;
|
||||
elf64_half_t ph_entry_count;
|
||||
elf64_half_t sh_entry_size;
|
||||
elf64_half_t sh_entry_count;
|
||||
elf64_half_t sh_str_table_index;
|
||||
|
||||
} elf64_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf32_word_t type;
|
||||
elf32_off_t offset;
|
||||
elf32_addr_t virt_addr;
|
||||
elf32_addr_t phys_addr;
|
||||
elf32_word_t file_size;
|
||||
elf32_word_t mem_size;
|
||||
elf32_word_t flags;
|
||||
elf32_word_t alignment;
|
||||
|
||||
} elf32_program_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf64_word_t type;
|
||||
elf64_word_t flags;
|
||||
elf64_off_t offset;
|
||||
elf64_addr_t virt_addr;
|
||||
elf64_addr_t phys_addr;
|
||||
elf64_xword_t file_size;
|
||||
elf64_xword_t mem_size;
|
||||
elf64_xword_t alignment;
|
||||
|
||||
} elf64_program_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf32_word_t name;
|
||||
elf32_word_t type;
|
||||
elf32_word_t flags;
|
||||
elf32_addr_t addr;
|
||||
elf32_off_t offset;
|
||||
elf32_word_t size;
|
||||
elf32_word_t link;
|
||||
elf32_word_t info;
|
||||
elf32_word_t align;
|
||||
elf32_word_t entry_size;
|
||||
|
||||
} elf32_section_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf64_word_t name;
|
||||
elf64_word_t type;
|
||||
elf64_xword_t flags;
|
||||
elf64_addr_t addr;
|
||||
elf64_off_t offset;
|
||||
elf64_xword_t size;
|
||||
elf64_word_t link;
|
||||
elf64_word_t info;
|
||||
elf64_xword_t align;
|
||||
elf64_xword_t entry_size;
|
||||
|
||||
} elf64_section_header_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf32_word_t tag;
|
||||
elf32_word_t val;
|
||||
|
||||
} elf32_dyn_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf64_xword_t tag;
|
||||
elf64_xword_t val;
|
||||
|
||||
} elf64_dyn_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf32_word_t name;
|
||||
elf32_addr_t value;
|
||||
elf32_word_t size;
|
||||
unsigned char info;
|
||||
unsigned char other;
|
||||
elf32_half_t shndx;
|
||||
|
||||
} elf32_sym_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
elf32_word_t name;
|
||||
unsigned char info;
|
||||
unsigned char other;
|
||||
elf32_half_t shndx;
|
||||
elf64_addr_t value;
|
||||
elf64_xword_t size;
|
||||
|
||||
} elf64_sym_t;
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
Copyright (c) 2016. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_ENDIAN_H
|
||||
#define YR_ENDIAN_H
|
||||
|
||||
#include <yara/integers.h>
|
||||
|
||||
|
||||
#if defined(__has_builtin)
|
||||
# if __has_builtin(__builtin_bswap16)
|
||||
# define yr_bswap16(x) __builtin_bswap16(x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(yr_bswap16) && defined(_MSC_VER)
|
||||
# define yr_bswap16(x) _byteswap_ushort(x)
|
||||
#endif
|
||||
|
||||
#if !defined(yr_bswap16)
|
||||
uint16_t _yr_bswap16(uint16_t x);
|
||||
# define yr_bswap16(x) _yr_bswap16(x)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__has_builtin)
|
||||
# if __has_builtin(__builtin_bswap32)
|
||||
# define yr_bswap32(x) __builtin_bswap32(x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(yr_bswap32) && defined(_MSC_VER)
|
||||
# define yr_bswap32(x) _byteswap_ulong(x)
|
||||
#endif
|
||||
|
||||
#if !defined(yr_bswap32)
|
||||
uint32_t _yr_bswap32(uint32_t x);
|
||||
#define yr_bswap32(x) _yr_bswap32(x)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__has_builtin)
|
||||
# if __has_builtin(__builtin_bswap64)
|
||||
# define yr_bswap64(x) __builtin_bswap64(x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(yr_bswap64) && defined(_MSC_VER)
|
||||
# define yr_bswap64(x) _byteswap_uint64(x)
|
||||
#endif
|
||||
|
||||
#if !defined(yr_bswap64)
|
||||
uint64_t _yr_bswap64(uint64_t x);
|
||||
#define yr_bswap64(x) _yr_bswap64(x)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WORDS_BIGENDIAN)
|
||||
#define yr_le16toh(x) yr_bswap16(x)
|
||||
#define yr_le32toh(x) yr_bswap32(x)
|
||||
#define yr_le64toh(x) yr_bswap64(x)
|
||||
#define yr_be16toh(x) (x)
|
||||
#define yr_be32toh(x) (x)
|
||||
#define yr_be64toh(x) (x)
|
||||
#else
|
||||
#define yr_le16toh(x) (x)
|
||||
#define yr_le32toh(x) (x)
|
||||
#define yr_le64toh(x) (x)
|
||||
#define yr_be16toh(x) yr_bswap16(x)
|
||||
#define yr_be32toh(x) yr_bswap32(x)
|
||||
#define yr_be64toh(x) yr_bswap64(x)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
Copyright (c) 2014. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_ERROR_H
|
||||
#define YR_ERROR_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifndef ERROR_SUCCESS
|
||||
#define ERROR_SUCCESS 0
|
||||
#endif
|
||||
|
||||
// ERROR_INSUFICIENT_MEMORY is misspelled but it's kept for backward
|
||||
// compatibility, as some other programs can be using it in this form.
|
||||
#define ERROR_INSUFICIENT_MEMORY 1
|
||||
|
||||
#define ERROR_INSUFFICIENT_MEMORY 1
|
||||
#define ERROR_COULD_NOT_ATTACH_TO_PROCESS 2
|
||||
#define ERROR_COULD_NOT_OPEN_FILE 3
|
||||
#define ERROR_COULD_NOT_MAP_FILE 4
|
||||
#define ERROR_INVALID_FILE 6
|
||||
#define ERROR_CORRUPT_FILE 7
|
||||
#define ERROR_UNSUPPORTED_FILE_VERSION 8
|
||||
#define ERROR_INVALID_REGULAR_EXPRESSION 9
|
||||
#define ERROR_INVALID_HEX_STRING 10
|
||||
#define ERROR_SYNTAX_ERROR 11
|
||||
#define ERROR_LOOP_NESTING_LIMIT_EXCEEDED 12
|
||||
#define ERROR_DUPLICATED_LOOP_IDENTIFIER 13
|
||||
#define ERROR_DUPLICATED_IDENTIFIER 14
|
||||
#define ERROR_DUPLICATED_TAG_IDENTIFIER 15
|
||||
#define ERROR_DUPLICATED_META_IDENTIFIER 16
|
||||
#define ERROR_DUPLICATED_STRING_IDENTIFIER 17
|
||||
#define ERROR_UNREFERENCED_STRING 18
|
||||
#define ERROR_UNDEFINED_STRING 19
|
||||
#define ERROR_UNDEFINED_IDENTIFIER 20
|
||||
#define ERROR_MISPLACED_ANONYMOUS_STRING 21
|
||||
#define ERROR_INCLUDES_CIRCULAR_REFERENCE 22
|
||||
#define ERROR_INCLUDE_DEPTH_EXCEEDED 23
|
||||
#define ERROR_WRONG_TYPE 24
|
||||
#define ERROR_EXEC_STACK_OVERFLOW 25
|
||||
#define ERROR_SCAN_TIMEOUT 26
|
||||
#define ERROR_TOO_MANY_SCAN_THREADS 27
|
||||
#define ERROR_CALLBACK_ERROR 28
|
||||
#define ERROR_INVALID_ARGUMENT 29
|
||||
#define ERROR_TOO_MANY_MATCHES 30
|
||||
#define ERROR_INTERNAL_FATAL_ERROR 31
|
||||
#define ERROR_NESTED_FOR_OF_LOOP 32
|
||||
#define ERROR_INVALID_FIELD_NAME 33
|
||||
#define ERROR_UNKNOWN_MODULE 34
|
||||
#define ERROR_NOT_A_STRUCTURE 35
|
||||
#define ERROR_NOT_INDEXABLE 36
|
||||
#define ERROR_NOT_A_FUNCTION 37
|
||||
#define ERROR_INVALID_FORMAT 38
|
||||
#define ERROR_TOO_MANY_ARGUMENTS 39
|
||||
#define ERROR_WRONG_ARGUMENTS 40
|
||||
#define ERROR_WRONG_RETURN_TYPE 41
|
||||
#define ERROR_DUPLICATED_STRUCTURE_MEMBER 42
|
||||
#define ERROR_EMPTY_STRING 43
|
||||
#define ERROR_DIVISION_BY_ZERO 44
|
||||
#define ERROR_REGULAR_EXPRESSION_TOO_LARGE 45
|
||||
#define ERROR_TOO_MANY_RE_FIBERS 46
|
||||
#define ERROR_COULD_NOT_READ_PROCESS_MEMORY 47
|
||||
#define ERROR_INVALID_EXTERNAL_VARIABLE_TYPE 48
|
||||
#define ERROR_REGULAR_EXPRESSION_TOO_COMPLEX 49
|
||||
#define ERROR_INVALID_MODULE_NAME 50
|
||||
#define ERROR_TOO_MANY_STRINGS 51
|
||||
#define ERROR_INTEGER_OVERFLOW 52
|
||||
#define ERROR_CALLBACK_REQUIRED 53
|
||||
#define ERROR_INVALID_OPERAND 54
|
||||
|
||||
|
||||
#define FAIL_ON_ERROR(x) { \
|
||||
int result = (x); \
|
||||
if (result != ERROR_SUCCESS) \
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define FAIL_ON_ERROR_WITH_CLEANUP(x, cleanup) { \
|
||||
int result = (x); \
|
||||
if (result != ERROR_SUCCESS) { \
|
||||
cleanup; \
|
||||
return result; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FAIL_ON_COMPILER_ERROR(x) { \
|
||||
compiler->last_result = (x); \
|
||||
if (compiler->last_result != ERROR_SUCCESS) \
|
||||
return compiler->last_result; \
|
||||
}
|
||||
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define assertf(expr, msg, ...) ((void)0)
|
||||
#else
|
||||
#define assertf(expr, msg, ...) \
|
||||
if(!(expr)) { \
|
||||
fprintf(stderr, "%s:%d: " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||
abort(); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
Copyright (c) 2013-2014. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_EXEC_H
|
||||
#define YR_EXEC_H
|
||||
|
||||
#include <yara/hash.h>
|
||||
#include <yara/scan.h>
|
||||
#include <yara/types.h>
|
||||
#include <yara/rules.h>
|
||||
|
||||
|
||||
#define LOOP_LOCAL_VARS 4
|
||||
|
||||
#define UNDEFINED 0xFFFABADAFABADAFFLL
|
||||
#define IS_UNDEFINED(x) ((size_t)(x) == (size_t) UNDEFINED)
|
||||
|
||||
#define OP_ERROR 0
|
||||
#define OP_HALT 255
|
||||
#define OP_NOP 254
|
||||
|
||||
#define OP_AND 1
|
||||
#define OP_OR 2
|
||||
#define OP_NOT 3
|
||||
#define OP_BITWISE_NOT 4
|
||||
#define OP_BITWISE_AND 5
|
||||
#define OP_BITWISE_OR 6
|
||||
#define OP_BITWISE_XOR 7
|
||||
#define OP_SHL 8
|
||||
#define OP_SHR 9
|
||||
#define OP_MOD 10
|
||||
#define OP_INT_TO_DBL 11
|
||||
#define OP_STR_TO_BOOL 12
|
||||
#define OP_PUSH 13
|
||||
#define OP_POP 14
|
||||
#define OP_CALL 15
|
||||
#define OP_OBJ_LOAD 16
|
||||
#define OP_OBJ_VALUE 17
|
||||
#define OP_OBJ_FIELD 18
|
||||
#define OP_INDEX_ARRAY 19
|
||||
#define OP_COUNT 20
|
||||
#define OP_LENGTH 21
|
||||
#define OP_FOUND 22
|
||||
#define OP_FOUND_AT 23
|
||||
#define OP_FOUND_IN 24
|
||||
#define OP_OFFSET 25
|
||||
#define OP_OF 26
|
||||
#define OP_PUSH_RULE 27
|
||||
#define OP_INIT_RULE 28
|
||||
#define OP_MATCH_RULE 29
|
||||
#define OP_INCR_M 30
|
||||
#define OP_CLEAR_M 31
|
||||
#define OP_ADD_M 32
|
||||
#define OP_POP_M 33
|
||||
#define OP_PUSH_M 34
|
||||
#define OP_SWAPUNDEF 35
|
||||
#define OP_JNUNDEF 36
|
||||
#define OP_JLE 37
|
||||
#define OP_FILESIZE 38
|
||||
#define OP_ENTRYPOINT 39
|
||||
#define OP_CONTAINS 40
|
||||
#define OP_MATCHES 41
|
||||
#define OP_IMPORT 42
|
||||
#define OP_LOOKUP_DICT 43
|
||||
#define OP_JFALSE 44
|
||||
#define OP_JTRUE 45
|
||||
|
||||
|
||||
#define _OP_EQ 0
|
||||
#define _OP_NEQ 1
|
||||
#define _OP_LT 2
|
||||
#define _OP_GT 3
|
||||
#define _OP_LE 4
|
||||
#define _OP_GE 5
|
||||
#define _OP_ADD 6
|
||||
#define _OP_SUB 7
|
||||
#define _OP_MUL 8
|
||||
#define _OP_DIV 9
|
||||
#define _OP_MINUS 10
|
||||
|
||||
|
||||
#define OP_INT_BEGIN 100
|
||||
#define OP_INT_EQ (OP_INT_BEGIN + _OP_EQ)
|
||||
#define OP_INT_NEQ (OP_INT_BEGIN + _OP_NEQ)
|
||||
#define OP_INT_LT (OP_INT_BEGIN + _OP_LT)
|
||||
#define OP_INT_GT (OP_INT_BEGIN + _OP_GT)
|
||||
#define OP_INT_LE (OP_INT_BEGIN + _OP_LE)
|
||||
#define OP_INT_GE (OP_INT_BEGIN + _OP_GE)
|
||||
#define OP_INT_ADD (OP_INT_BEGIN + _OP_ADD)
|
||||
#define OP_INT_SUB (OP_INT_BEGIN + _OP_SUB)
|
||||
#define OP_INT_MUL (OP_INT_BEGIN + _OP_MUL)
|
||||
#define OP_INT_DIV (OP_INT_BEGIN + _OP_DIV)
|
||||
#define OP_INT_MINUS (OP_INT_BEGIN + _OP_MINUS)
|
||||
#define OP_INT_END OP_INT_MINUS
|
||||
|
||||
#define OP_DBL_BEGIN 120
|
||||
#define OP_DBL_EQ (OP_DBL_BEGIN + _OP_EQ)
|
||||
#define OP_DBL_NEQ (OP_DBL_BEGIN + _OP_NEQ)
|
||||
#define OP_DBL_LT (OP_DBL_BEGIN + _OP_LT)
|
||||
#define OP_DBL_GT (OP_DBL_BEGIN + _OP_GT)
|
||||
#define OP_DBL_LE (OP_DBL_BEGIN + _OP_LE)
|
||||
#define OP_DBL_GE (OP_DBL_BEGIN + _OP_GE)
|
||||
#define OP_DBL_ADD (OP_DBL_BEGIN + _OP_ADD)
|
||||
#define OP_DBL_SUB (OP_DBL_BEGIN + _OP_SUB)
|
||||
#define OP_DBL_MUL (OP_DBL_BEGIN + _OP_MUL)
|
||||
#define OP_DBL_DIV (OP_DBL_BEGIN + _OP_DIV)
|
||||
#define OP_DBL_MINUS (OP_DBL_BEGIN + _OP_MINUS)
|
||||
#define OP_DBL_END OP_DBL_MINUS
|
||||
|
||||
#define OP_STR_BEGIN 140
|
||||
#define OP_STR_EQ (OP_STR_BEGIN + _OP_EQ)
|
||||
#define OP_STR_NEQ (OP_STR_BEGIN + _OP_NEQ)
|
||||
#define OP_STR_LT (OP_STR_BEGIN + _OP_LT)
|
||||
#define OP_STR_GT (OP_STR_BEGIN + _OP_GT)
|
||||
#define OP_STR_LE (OP_STR_BEGIN + _OP_LE)
|
||||
#define OP_STR_GE (OP_STR_BEGIN + _OP_GE)
|
||||
#define OP_STR_END OP_STR_GE
|
||||
|
||||
#define IS_INT_OP(x) ((x) >= OP_INT_BEGIN && (x) <= OP_INT_END)
|
||||
#define IS_DBL_OP(x) ((x) >= OP_DBL_BEGIN && (x) <= OP_DBL_END)
|
||||
#define IS_STR_OP(x) ((x) >= OP_STR_BEGIN && (x) <= OP_STR_END)
|
||||
|
||||
#define OP_READ_INT 240
|
||||
#define OP_INT8 (OP_READ_INT + 0)
|
||||
#define OP_INT16 (OP_READ_INT + 1)
|
||||
#define OP_INT32 (OP_READ_INT + 2)
|
||||
#define OP_UINT8 (OP_READ_INT + 3)
|
||||
#define OP_UINT16 (OP_READ_INT + 4)
|
||||
#define OP_UINT32 (OP_READ_INT + 5)
|
||||
#define OP_INT8BE (OP_READ_INT + 6)
|
||||
#define OP_INT16BE (OP_READ_INT + 7)
|
||||
#define OP_INT32BE (OP_READ_INT + 8)
|
||||
#define OP_UINT8BE (OP_READ_INT + 9)
|
||||
#define OP_UINT16BE (OP_READ_INT + 10)
|
||||
#define OP_UINT32BE (OP_READ_INT + 11)
|
||||
|
||||
|
||||
#define OPERATION(operator, op1, op2) \
|
||||
(IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (UNDEFINED) : (op1 operator op2)
|
||||
|
||||
|
||||
#define COMPARISON(operator, op1, op2) \
|
||||
(IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (0) : (op1 operator op2)
|
||||
|
||||
|
||||
int yr_execute_code(
|
||||
YR_SCAN_CONTEXT* context);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright (c) 2007. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_EXEFILES_H
|
||||
#define YR_EXEFILES_H
|
||||
|
||||
uint64_t yr_get_entry_point_offset(
|
||||
const uint8_t* buffer,
|
||||
size_t buffer_length);
|
||||
|
||||
|
||||
uint64_t yr_get_entry_point_address(
|
||||
const uint8_t* buffer,
|
||||
size_t buffer_length,
|
||||
uint64_t base_address);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright (c) 2007-2015. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_FILEMAP_H
|
||||
#define YR_FILEMAP_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define off_t int64_t
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#include <windows.h>
|
||||
#define YR_FILE_DESCRIPTOR HANDLE
|
||||
#else
|
||||
#define YR_FILE_DESCRIPTOR int
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <yara/integers.h>
|
||||
#include <yara/utils.h>
|
||||
|
||||
|
||||
typedef struct _YR_MAPPED_FILE
|
||||
{
|
||||
YR_FILE_DESCRIPTOR file;
|
||||
size_t size;
|
||||
const uint8_t* data;
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
HANDLE mapping;
|
||||
#endif
|
||||
|
||||
} YR_MAPPED_FILE;
|
||||
|
||||
|
||||
YR_API int yr_filemap_map(
|
||||
const char* file_path,
|
||||
YR_MAPPED_FILE* pmapped_file);
|
||||
|
||||
|
||||
YR_API int yr_filemap_map_fd(
|
||||
YR_FILE_DESCRIPTOR file,
|
||||
off_t offset,
|
||||
size_t size,
|
||||
YR_MAPPED_FILE* pmapped_file);
|
||||
|
||||
|
||||
YR_API int yr_filemap_map_ex(
|
||||
const char* file_path,
|
||||
off_t offset,
|
||||
size_t size,
|
||||
YR_MAPPED_FILE* pmapped_file);
|
||||
|
||||
|
||||
YR_API void yr_filemap_unmap(
|
||||
YR_MAPPED_FILE* pmapped_file);
|
||||
|
||||
|
||||
YR_API void yr_filemap_unmap_fd(
|
||||
YR_MAPPED_FILE* pmapped_file);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright (c) 2014. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_GLOBALS_H
|
||||
#define YR_GLOBALS_H
|
||||
|
||||
#include <yara/threading.h>
|
||||
|
||||
extern char yr_lowercase[256];
|
||||
extern char yr_altercase[256];
|
||||
|
||||
extern YR_THREAD_STORAGE_KEY yr_tidx_key;
|
||||
extern YR_THREAD_STORAGE_KEY yr_recovery_state_key;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
Copyright (c) 2013. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef YR_HASH_H
|
||||
#define YR_HASH_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <yara/utils.h>
|
||||
#include <yara/integers.h>
|
||||
|
||||
typedef struct _YR_HASH_TABLE_ENTRY
|
||||
{
|
||||
void* key;
|
||||
size_t key_length;
|
||||
char* ns;
|
||||
void* value;
|
||||
|
||||
struct _YR_HASH_TABLE_ENTRY* next;
|
||||
|
||||
} YR_HASH_TABLE_ENTRY;
|
||||
|
||||
|
||||
typedef struct _YR_HASH_TABLE
|
||||
{
|
||||
int size;
|
||||
|
||||
YR_HASH_TABLE_ENTRY* buckets[1];
|
||||
|
||||
} YR_HASH_TABLE;
|
||||
|
||||
|
||||
typedef int (*YR_HASH_TABLE_FREE_VALUE_FUNC)(void* value);
|
||||
|
||||
|
||||
uint32_t yr_hash(
|
||||
uint32_t seed,
|
||||
const void* buffer,
|
||||
size_t len);
|
||||
|
||||
|
||||
YR_API int yr_hash_table_create(
|
||||
int size,
|
||||
YR_HASH_TABLE** table);
|
||||
|
||||
|
||||
YR_API void yr_hash_table_clean(
|
||||
YR_HASH_TABLE* table,
|
||||
YR_HASH_TABLE_FREE_VALUE_FUNC free_value);
|
||||
|
||||
|
||||
YR_API void yr_hash_table_destroy(
|
||||
YR_HASH_TABLE* table,
|
||||
YR_HASH_TABLE_FREE_VALUE_FUNC free_value);
|
||||
|
||||
|
||||
YR_API void* yr_hash_table_lookup(
|
||||
YR_HASH_TABLE* table,
|
||||
const char* key,
|
||||
const char* ns);
|
||||
|
||||
|
||||
YR_API void* yr_hash_table_remove(
|
||||
YR_HASH_TABLE* table,
|
||||
const char* key,
|
||||
const char* ns);
|
||||
|
||||
|
||||
YR_API int yr_hash_table_add(
|
||||
YR_HASH_TABLE* table,
|
||||
const char* key,
|
||||
const char* ns,
|
||||
void* value);
|
||||
|
||||
|
||||
YR_API void* yr_hash_table_lookup_raw_key(
|
||||
YR_HASH_TABLE* table,
|
||||
const void* key,
|
||||
size_t key_length,
|
||||
const char* ns);
|
||||
|
||||
|
||||
YR_API void* yr_hash_table_remove_raw_key(
|
||||
YR_HASH_TABLE* table,
|
||||
const void* key,
|
||||
size_t key_length,
|
||||
const char* ns);
|
||||
|
||||
|
||||
YR_API int yr_hash_table_add_raw_key(
|
||||
YR_HASH_TABLE* table,
|
||||
const void* key,
|
||||
size_t key_length,
|
||||
const char* ns,
|
||||
void* value);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
Copyright (c) 2007. Victor M. Alvarez [plusvic@gmail.com].
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <yara/re.h>
|
||||
|
||||
#undef yyparse
|
||||
#undef yylex
|
||||
#undef yyerror
|
||||
#undef yyfatal
|
||||
#undef yychar
|
||||
#undef yydebug
|
||||
#undef yynerrs
|
||||
#undef yyget_extra
|
||||
#undef yyget_lineno
|
||||
|
||||
#undef YY_FATAL_ERROR
|
||||
#undef YY_DECL
|
||||
#undef LEX_ENV
|
||||
|
||||
#define yyparse hex_yyparse
|
||||
#define yylex hex_yylex
|
||||
#define yyerror hex_yyerror
|
||||
#define yyfatal hex_yyfatal
|
||||
#define yychar hex_yychar
|
||||
#define yydebug hex_yydebug
|
||||
#define yynerrs hex_yynerrs
|
||||
#define yyget_extra hex_yyget_extra
|
||||
#define yyget_lineno hex_yyget_lineno
|
||||
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_SCANNER_T
|
||||
#define YY_TYPEDEF_YY_SCANNER_T
|
||||
typedef void* yyscan_t;
|
||||
#endif
|
||||
|
||||
#define YY_EXTRA_TYPE RE_AST*
|
||||
#define YY_USE_CONST
|
||||
|
||||
|
||||
typedef struct _HEX_LEX_ENVIRONMENT
|
||||
{
|
||||
int inside_or;
|
||||
int last_error_code;
|
||||
char last_error_message[256];
|
||||
|
||||
} HEX_LEX_ENVIRONMENT;
|
||||
|
||||
|
||||
#define YY_FATAL_ERROR(msg) hex_yyfatal(yyscanner, msg)
|
||||
|
||||
#define LEX_ENV ((HEX_LEX_ENVIRONMENT*) lex_env)
|
||||
|
||||
#include <hex_grammar.h>
|
||||
|
||||
#define YY_DECL int hex_yylex \
|
||||
(YYSTYPE * yylval_param , yyscan_t yyscanner, HEX_LEX_ENVIRONMENT* lex_env)
|
||||
|
||||
|
||||
YY_EXTRA_TYPE yyget_extra(
|
||||
yyscan_t yyscanner);
|
||||
|
||||
int yylex(
|
||||
YYSTYPE* yylval_param,
|
||||
yyscan_t yyscanner,
|
||||
HEX_LEX_ENVIRONMENT* lex_env);
|
||||
|
||||
int yyparse(
|
||||
void *yyscanner,
|
||||
HEX_LEX_ENVIRONMENT *lex_env);
|
||||
|
||||
void yyerror(
|
||||
yyscan_t yyscanner,
|
||||
HEX_LEX_ENVIRONMENT* lex_env,
|
||||
const char *error_message);
|
||||
|
||||
void yyfatal(
|
||||
yyscan_t yyscanner,
|
||||
const char *error_message);
|
||||
|
||||
int yr_parse_hex_string(
|
||||
const char* hex_string,
|
||||
RE_AST** re_ast,
|
||||
RE_ERROR* error);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user