Skip to content

Commit baca5f7

Browse files
committed
Pattern Matching rewritten
1 parent a43659c commit baca5f7

File tree

3 files changed

+69
-21
lines changed

3 files changed

+69
-21
lines changed

src/core/patternmatching.cpp

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,58 @@ PatternMatching::PatternMatching(string path)
1616
}
1717
}
1818

19-
vector<Match*> PatternMatching::hasMatches(wstring str) {
19+
vector<Match*> PatternMatching::hasMatches(vector<uint8_t> &content) {
2020
vector<Match*> res;
21+
vector<vector<uint8_t>> patterns;
22+
vector<string> colors;
23+
vector<string> messages;
2124
for (auto& e : this->jconfig["PatternMatching"]) {
22-
wstring tmp = str;
23-
unsigned long pos = 0;
24-
try {
25-
string sregex = e["regex"].get<string>();
26-
wstring wsregex = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(sregex);
27-
std::wregex re(wsregex);
28-
std::wsmatch match;
29-
while (regex_search(tmp, match, re)) {
30-
unsigned long len = match.str(0).size();
31-
res.push_back(new Match(e["color"].get<string>(), e["message"].get<string>(), match.position(0) + pos, len));
32-
tmp = match.suffix();
33-
pos += match.position(0) + len;
25+
if (e.contains("string")) {
26+
vector<uint8_t> bytes;
27+
string str = e["string"].get<string>();
28+
for(uint8_t byte : str) {
29+
bytes.push_back(byte);
30+
}
31+
patterns.push_back(bytes);
32+
colors.push_back(e["color"].get<string>());
33+
messages.push_back(e["message"].get<string>());
34+
} else if (e.contains("bytes")) {
35+
string strbytes = e["bytes"].get<string>();
36+
stringstream converter;
37+
vector<uint8_t> bytes;
38+
for(size_t i = 0; i < strbytes.length(); i+=2) {
39+
converter << std::hex << strbytes.substr(i,2);
40+
short byte;
41+
converter >> byte;
42+
bytes.push_back(byte & 0xFF);
43+
converter.str(string());
44+
converter.clear();
45+
}
46+
patterns.push_back(bytes);
47+
colors.push_back(e["color"].get<string>());
48+
messages.push_back(e["message"].get<string>());
49+
}
50+
}
51+
52+
//Search patterns in content
53+
unsigned long pos = 0;
54+
uint8_t *content_ptr = content.data(); //Use pointers to be faster
55+
for (pos = 0; pos < content.size(); pos++) {
56+
for (size_t p = 0; p < patterns.size(); p++) {
57+
uint8_t *pattern_ptr = patterns[p].data();
58+
size_t size = patterns[p].size();
59+
if (content.size() - pos < size)
60+
continue;
61+
size_t i;
62+
for (i = 0; i < size; i++) {
63+
if (content_ptr[pos+i] != pattern_ptr[i])
64+
break;
65+
}
66+
bool found = (i == size);
67+
if ((found) && (res.size() < MAX_PATTERN_RESULTS)) {
68+
res.push_back(new Match(colors[p], messages[p], pos, size));
69+
pos+=size;
3470
}
35-
} catch (std::regex_error& e) {
36-
cerr << "Regex syntax error:" << endl << e.what() << endl;
3771
}
3872
}
3973
return res;

src/core/patternmatching.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <codecvt>
99
#include "json.h"
1010

11+
#define MAX_PATTERN_RESULTS 100
12+
1113
using json = nlohmann::json;
1214
using namespace std;
1315

@@ -36,7 +38,7 @@ class PatternMatching
3638
{
3739
public:
3840
PatternMatching(string path);
39-
vector<Match *> hasMatches(wstring pattern);
41+
vector<Match *> hasMatches(vector<uint8_t> &content);
4042
private:
4143
json jconfig;
4244
};

src/fhex.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -327,20 +327,32 @@ void Fhex::on_menu_find_patterns_click() {
327327

328328
void Fhex::findPatterns() {
329329
clearFloatingLabels();
330+
this->listOffsets->clear();
330331
this->statusBar.setText("Searching patterns..");
331332
this->statusBar.repaint();
332-
long patterns = 0;
333+
unsigned long patterns = 0;
333334
vector<Match *> matches = this->hexEditor->findPatterns();
335+
size_t size = matches.size();
334336
for (Match *m : matches) {
337+
if (patterns > MAX_PATTERN_RESULTS) {
338+
break;
339+
}
335340
// render highlight area
336341
QString style("QLabel { color: #fbfbfb; padding: 2px; background-color: ");
337342
style += m->color.c_str();
338343
style += " };";
339-
addFloatingLabel(m->index, m->length, m->message.c_str(), style, true);
344+
//Show comments only if the windows is maximized, otherwise probably we don't have enough space
345+
addFloatingLabel(m->index, m->length, m->message.c_str(), style, this->windowState().testFlag(Qt::WindowMaximized));
346+
this->listOffsets->addItem("0x" + QString::number(m->index, 16));
340347
delete m;
341348
patterns++;
342349
}
343-
this->statusBar.setText("Found " + QString::number(patterns) + " patterns");
350+
if (size > MAX_PATTERN_RESULTS) {
351+
this->statusBar.setText("Found " + QString::number(size) + " patterns. Limit exceeded, showing labels only for first " + QString::number(MAX_PATTERN_RESULTS));
352+
} else {
353+
this->statusBar.setText("Found " + QString::number(patterns) + " patterns");
354+
}
355+
this->listOffsets->setVisible(true);
344356
}
345357

346358
void Fhex::on_menu_find_click() {
@@ -755,8 +767,8 @@ void Fhex::addFloatingLabel(qint64 offset, int len, QString text, QString style,
755767
style = "QLabel { background-color: rgb(150, 150, 150, 50); color: #ffffff; }";
756768
commentLabel->setStyleSheet(style);
757769
commentLabel->setText(text);
758-
commentLabel->move(p.x() + (this->width() / 2), p.y());
759-
commentLabel->adjustSize();
770+
commentLabel->move(p.x() + (this->width() / 2.5), p.y());
771+
commentLabel->resize(this->qhex->getPxCharWidth() * text.size(), this->qhex->getPxCharHeight());
760772
commentLabel->show();
761773
this->floatingLabels.push_back(commentLabel);
762774
}

0 commit comments

Comments
 (0)