Skip to content

Commit 5a38f64

Browse files
YaraX solver in GatoROM CLI, inclusion of library. #132
1 parent 0886aa3 commit 5a38f64

File tree

6 files changed

+168
-10
lines changed

6 files changed

+168
-10
lines changed

CMakeLists.txt

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
cmake_minimum_required(VERSION 3.5)
2+
include(CMakeFindDependencyMacro)
3+
4+
configure_file(config.h.in config.h)
25

36
# X86 is no longer supported, but you could edit this to bring it back.
47
# set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
@@ -15,8 +18,26 @@ set(CMAKE_AUTORCC ON)
1518
set(CMAKE_CXX_STANDARD 17)
1619
set(CMAKE_CXX_STANDARD_REQUIRED ON)
1720

18-
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Widgets LinguistTools Charts PrintSupport Core Quick Qml)
19-
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools Charts PrintSupport Core Quick Qml)
21+
#find_package(QT NAMES Qt6 REQUIRED COMPONENTS Widgets LinguistTools Charts PrintSupport Core Quick Qml)
22+
find_package(Qt6 REQUIRED COMPONENTS Widgets LinguistTools Charts PrintSupport Core Quick Qml)
23+
24+
# Optional packages.
25+
# https://virustotal.github.io/yara-x/docs/api/c/c-/
26+
#find_library(YARAX NAMES yara_x_capi)
27+
#find_library(YARAX NAMES libyara_x_capi.a)
28+
29+
30+
find_package(PkgConfig REQUIRED)
31+
pkg_check_modules(YARAX REQUIRED IMPORTED_TARGET yara_x_capi)
32+
33+
34+
# Check if the library was found
35+
if (YARAX_FOUND)
36+
set(YARAX ${YARAX_STATIC_LIBRARIES} )
37+
message(STATUS "Found yarax: ${YARAX}")
38+
else()
39+
message(STATUS "Yarax not found. Will build without it.")
40+
endif()
2041

2142
# GoodASM as a disassembler and library.
2243
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/goodasm/CMakeLists.txt")
@@ -54,12 +75,11 @@ set(GATOROM_SOURCES
5475
gatograderbytes.h gatograderbytes.cpp
5576
gatograderstring.h gatograderstring.cpp
5677
gatograderascii.h gatograderascii.cpp
57-
gatograderyara.h gatograderyara.cpp
78+
gatograderyara.h gatograderyara.cpp # Old Yara from CLI.
79+
gatograderyarax.h gatograderyarax.cpp # New Yara-X from library.
5880
gatogradergoodasm.h gatogradergoodasm.cpp
5981
# Decoders that are new to GatoRom.
6082
gatodecoderinfo.h gatodecoderinfo.cpp # Just info, no details.
61-
# gatodecoderarm6.h gatodecoderarm6.cpp # MYK82 Clipper Chip Decoder. Use cols-left instead.
62-
# gatodecodermsp430.h gatodecodermsp430.cpp # MSP430 ROM
6383
gatodecodertlcsfont.h gatodecodertlcsfont.cpp # TMP47C434N Font ROM
6484
gatodecoderz86x1.h gatodecoderz86x1.cpp # Zilog Z8 Z86x1
6585
gatodecodercolsdownlswap.h gatodecodercolsdownlswap.cpp # Used in NEC uCOM4 Micros
@@ -97,7 +117,6 @@ set(MRT_SOURCES
97117
romdecoderasciidamage.h romdecoderasciidamage.cpp
98118
romdecoderjson.h romdecoderjson.cpp
99119
romdecodercsv.h romdecodercsv.cpp
100-
# romdecodermarc4.h romdecodermarc4.cpp # Deprecated, needs to move to gatorom.
101120
romdecoderphotograph.h romdecoderphotograph.cpp
102121
romdecoderhistogram.h romdecoderhistogram.cpp
103122
romencoderdiff.h romencoderdiff.cpp
@@ -133,12 +152,17 @@ if(NOT WIN32)
133152
endif()
134153

135154

155+
156+
157+
136158
qt_add_executable(maskromtool
137159
MANUAL_FINALIZATION
138160
${MRT_SOURCES}
139161
)
140162
qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
141-
target_link_libraries(maskromtool PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Charts Qt${QT_VERSION_MAJOR}::PrintSupport libgoodasm ${READLINE})
163+
target_link_libraries(maskromtool PRIVATE Qt6::Widgets
164+
Qt6::Charts Qt6::PrintSupport
165+
libgoodasm ${READLINE} PkgConfig::YARAX)
142166

143167

144168
set_target_properties(maskromtool PROPERTIES
@@ -156,7 +180,9 @@ if(WIN32)
156180
MANUAL_FINALIZATION
157181
${MRT_SOURCES}
158182
)
159-
target_link_libraries(maskromtoolcli PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Charts Qt${QT_VERSION_MAJOR}::PrintSupport libgoodasm ${READLINE})
183+
target_link_libraries(maskromtoolcli PRIVATE Qt6::Widgets
184+
Qt6::Charts Qt6::PrintSupport
185+
libgoodasm ${READLINE} ${YARAX_LIBRARIES} )
160186
qt_finalize_executable(maskromtoolcli)
161187
install(TARGETS maskromtoolcli DESTINATION bin)
162188
endif()
@@ -173,7 +199,8 @@ add_executable(gatorom
173199
# CLI
174200
gatomain.cpp
175201
)
176-
target_link_libraries(gatorom Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::PrintSupport libgoodasm ${READLINE})
202+
target_link_libraries(gatorom Qt6::Core
203+
Qt6::PrintSupport libgoodasm ${READLINE} ${YARAX_LIBRARIES})
177204

178205
install(TARGETS gatorom
179206
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

config.h.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
// I don't know why this doesn't work.
3+
#define MASKROMTOOL_VERSION_STRING "${PROJECT_VERSION}"
4+
5+
// We don't want to fail when this library is missing.
6+
#cmakedefine01 YARAX_FOUND

gatograderyarax.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include <QDebug>
2+
#include "gatograderyarax.h"
3+
4+
/* VERY IMPORTANT:
5+
*
6+
* YaraX is lovely, but it's a Rust project that many C++
7+
* developers will not know how to build. We work around
8+
* this by the YARAX_FOUND definition, so that the feature
9+
* gracefully degrades when YaraX is missing.
10+
*
11+
* In any changes to this executable, your code must compile
12+
* with or without YaraX.
13+
*/
14+
15+
#ifdef YARAX_FOUND
16+
17+
GatoGraderYaraX::GatoGraderYaraX(QString rule) {
18+
//Someday we might hold more than one rule.
19+
this->rule=rule;
20+
21+
//First compile the rules.
22+
YRX_RESULT res=yrx_compile(rule.toStdString().c_str(), &rules);
23+
if(res!=YRX_SUCCESS){
24+
qDebug()<<QString(yrx_last_error());
25+
}
26+
27+
//Then build a scanner.
28+
res=yrx_scanner_create(rules, &scanner);
29+
if(res!=YRX_SUCCESS){
30+
qDebug()<<QString(yrx_last_error());
31+
}
32+
}
33+
34+
GatoGraderYaraX::~GatoGraderYaraX(){
35+
if(scanner) yrx_scanner_destroy(scanner);
36+
if(rules) yrx_rules_destroy(rules);
37+
}
38+
39+
static void callback(const struct YRX_RULE *rule, void *user_data){
40+
GatoGraderYaraX* grader=(GatoGraderYaraX*) user_data;
41+
grader->match++;
42+
}
43+
44+
int GatoGraderYaraX::grade(QByteArray ba){
45+
assert(scanner);
46+
47+
//Scan the bytes.
48+
this->match=0; //Reset match count.
49+
yrx_scanner_on_matching_rule(scanner, callback, (void*) this);
50+
YRX_RESULT res=yrx_scanner_scan(scanner,(uint8_t*) ba.data(), ba.length());
51+
return this->match*100; //Did we get a match?
52+
}
53+
54+
55+
#endif //YARAX_FOUND

gatograderyarax.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#ifndef GATOGRADERYARAX_H
2+
#define GATOGRADERYARAX_H
3+
4+
/* VERY IMPORTANT:
5+
*
6+
* YaraX is lovely, but it's a Rust project that many C++
7+
* developers will not know how to build. We work around
8+
* this by the YARAX_FOUND definition, so that the feature
9+
* gracefully degrades when YaraX is missing.
10+
*
11+
* In any changes to this executable, your code must compile
12+
* with or without YaraX.
13+
*/
14+
15+
#include "gatosolver.h"
16+
#include "config.h" //Needed for "YARAX_FOUND" from Cmake.
17+
18+
#ifdef YARAX_FOUND
19+
20+
//Library is C, not C++, so name mangling must be disabled.
21+
extern "C" {
22+
#include <yara_x.h>
23+
}
24+
25+
26+
class GatoGraderYaraX : public GatoGrader
27+
{
28+
public:
29+
GatoGraderYaraX(QString rule);
30+
~GatoGraderYaraX();
31+
int grade(QByteArray ba);
32+
33+
//Incremented on a callback.
34+
int match=0;
35+
36+
private:
37+
YRX_RULES* rules=0;
38+
YRX_SCANNER* scanner=0;
39+
QString rule="";
40+
};
41+
42+
#endif // YARAX_FOUND
43+
#endif // GATOGRADERYARAX_H

gatomain.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
#include "gatograderstring.h"
3333
#include "gatograderascii.h"
3434
#include "gatograderyara.h"
35+
#include "gatograderyarax.h"
3536
#include "gatogradergoodasm.h"
36-
#include "extern/goodasm/goodasm.h"
3737

3838

3939
/* This is a quick CLI wrapper for GatoROM, which you might run on textfiles
@@ -236,6 +236,12 @@ int main(int argc, char *argv[]) {
236236
""
237237
);
238238
parser.addOption(solveyaraOption);
239+
QCommandLineOption solveyaraxOption(QStringList()<<"solve-yarax",
240+
"YaraX rule file.",
241+
"rule",
242+
""
243+
);
244+
parser.addOption(solveyaraxOption);
239245
QCommandLineOption solvegoodasmOption(QStringList()<<"solve-goodasm",
240246
"GoodASM Language Solver",
241247
"lang",
@@ -411,6 +417,7 @@ int main(int argc, char *argv[]) {
411417
QString bytes=parser.value(bytesOption);
412418
QString string=parser.value(stringOption);
413419
QString yararule=parser.value(solveyaraOption);
420+
QString yaraxrule=parser.value(solveyaraxOption);
414421
QString goodasmsolver=parser.value(solvegoodasmOption);
415422
if(goodasmsolver.startsWith("goodasm/"))
416423
goodasmsolver=goodasmsolver.right(goodasmsolver.length()-QString("goodasm/").length());
@@ -429,6 +436,14 @@ int main(int argc, char *argv[]) {
429436
grader=new GatoGraderASCII();
430437
}else if(parser.isSet(solveyaraOption)){
431438
grader=new GatoGraderYara(yararule);
439+
}else if(parser.isSet(solveyaraxOption)){
440+
#ifdef YARAX_FOUND
441+
QFile source(yaraxrule);
442+
source.open(QFile::ReadOnly);
443+
grader=new GatoGraderYaraX(source.readAll());
444+
#else
445+
qDebug()<<"YaraX not linked.";
446+
#endif
432447
}else if(parser.isSet(solvegoodasmOption)){
433448
gr->arch=goodasmsolver;
434449
grader=new GatoGraderGoodAsm(gr->goodasm());

gatotests/gameboy/gameboy.yar

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
// The GameBoy boot ROM contains a bitmap of Nintendo's logo, compared
3+
// against a matching bitmap in every cartridge. Here we check for the
4+
// first row of the logo.
5+
6+
rule gameboy {
7+
strings:
8+
$nintendo = {CE ED 66 66 CC 0D 00 0B 03 73 00 83 00 0C 00 0D}
9+
10+
condition:
11+
$nintendo
12+
}

0 commit comments

Comments
 (0)