Hello, i made a log searcher in python a while ago https://xss.pro/threads/80528/, but python was slow as shit for such job, so i remade it in c++
Compile: download a compiler and run
Time: Searched a 10gb logs folder in ~1 minute on an old pc
Note: under linux systems it gives the error: https://stackoverflow.com/questions/73479857/ mid search and exit due to underlying OS API
C++:
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <filesystem>
#include <regex>
#include <system_error>
#include <future>
#include <thread>
#include <vector>
using namespace std;
namespace fs = filesystem;
bool VerboseEnabled = false;
void processLogsAsync(const vector<string>& keywords, const string& sourceDirectory, const string& destinationDirectory, promise<void>&& promise) {
unordered_map<string, ofstream> keywordFiles;
unordered_map<string, int> keywordCount;
fs::create_directories(destinationDirectory);
for (const auto& keyword : keywords) {
string existingFile = destinationDirectory + "/" + keyword + ".txt";
if (fs::exists(existingFile)) {
fs::remove(existingFile);
}
}
error_code ec;
for (auto it = fs::recursive_directory_iterator(sourceDirectory, ec); it != fs::recursive_directory_iterator(); it.increment(ec)) {
if (ec) {
if (VerboseEnabled) cerr << "Error" /*accessing: " << sourceDirectory*/ << ": " << ec.message() << "\n";
ec.clear();
continue;
}
const auto& entry = *it;
if (entry.is_regular_file() && entry.path().extension() == ".txt") {
string filename = entry.path().filename().string();
regex pattern("password", regex_constants::icase);
if (regex_search(filename, pattern)) {
ifstream file(entry.path(), ios::binary);
if (!file) {
if (VerboseEnabled) cerr << "Error opening file " << entry.path() << "\n";
continue;
}
string line;
while (getline(file, line)) {
for (const auto& keyword : keywords) {
if (line.find(keyword) != string::npos) {
if (keywordFiles.find(keyword) == keywordFiles.end()) {
string outputFile = destinationDirectory + "/" + keyword + ".txt";
keywordFiles[keyword] = ofstream(outputFile, ios::app);
keywordCount[keyword] = 0;
}
keywordFiles[keyword] << line << endl;
keywordCount[keyword]++;
for (int i = 0; i < 2 && getline(file, line); ++i) {
keywordFiles[keyword] << line << endl;
}
keywordFiles[keyword] << endl;
}
}
}
}
}
}
for (auto& [keyword, file] : keywordFiles) {
file.close();
}
for (const auto& pair : keywords) {
if (keywordCount.find(pair) != keywordCount.end()) {
cout << "Found " << keywordCount[pair] << " credentials for " << pair << " in " << destinationDirectory << "/" << pair << ".txt" << endl;
} else {
cout << "No credentials found for " << pair << endl;
}
}
promise.set_value();
}
void processLogs(const vector<string>& keywords, const string& sourceDirectory, const string& destinationDirectory) {
const unsigned int numThreads = thread::hardware_concurrency();
vector<future<void>> futures;
// Split the keywords into smaller chunks for multithreading
const size_t chunkSize = (keywords.size() + numThreads - 1) / numThreads;
for (size_t i = 0; i < keywords.size(); i += chunkSize) {
const size_t end = min(i + chunkSize, keywords.size());
vector<string> chunk(keywords.begin() + i, keywords.begin() + end);
promise<void> promise;
future<void> future = promise.get_future();
futures.push_back(move(future));
thread thread(processLogsAsync, chunk, sourceDirectory, destinationDirectory, move(promise));
thread.detach();
}
// Wait for all threads to finish
for (auto& future : futures) {
future.get();
}
}
// Function to split keywords arguments (netflix.com,paypal.com)
vector<string> split(const string& s, char delimiter) {
vector<string> tokens;
string token;
istringstream tokenStream(s);
while (getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}
int main(int argc, char* argv[]) {
if (argc < 2 || string(argv[1]) == "-h" || string(argv[1]) == "--help") {
cout << "Usage: " << argv[0] << " -k \"netflix.com,paypal.com\" -l Logs -o Results" << endl;
cout << " -h, --help Display this help message." << endl;
cout << " -k <Keywords> Comma-separated list of keywords to search for." << endl;
cout << " -l <Logs> Directory containing logs files." << endl;
cout << " -o <destination> (Optional) Directory to store search results. Default: 'Results'" << endl;
cout << " -v <verbose> (Optional) Turn on verbose If set." << endl;
cout << endl;
return 1;
}
vector<string> keywords;
string sourceDirectory;
string destinationDirectory;
for (int i = 1; i < argc; ++i) {
string arg(argv[i]);
//TODO: Read keywords from file
if (arg == "-k") {
if (i + 1 < argc) {
keywords = split(argv[++i], ',');
} else {
cerr << "Error: Missing keywords after -k flag." << endl;
return 1;
}
}
else if (arg == "-l") {
if (i + 1 < argc) {
sourceDirectory = argv[++i];
} else {
cerr << "Error: Missing source directory after -l flag." << endl;
return 1;
}
}
else if (arg == "-o") {
if (i + 1 < argc) {
destinationDirectory = argv[++i];
} else {
cerr << "Error: Missing destination directory after -o flag." << endl;
return 1;
}
}
else if (arg == "-v") {
cout << "Verbose Mode Enabled" << endl;
bool* verbosePtr = &VerboseEnabled;
*verbosePtr = true;
}
else {
cerr << "Error: Unknown argument: " << arg << endl;
return 1;
}
}
if (destinationDirectory.empty()) {
destinationDirectory = "Results";
}
processLogs(keywords, sourceDirectory, destinationDirectory);
return 0;
}
Compile: download a compiler and run
g++ log_searcher.cpp -o log_searcher.exe -lstdc++fs -std=c++17Time: Searched a 10gb logs folder in ~1 minute on an old pc
Note: under linux systems it gives the error: https://stackoverflow.com/questions/73479857/ mid search and exit due to underlying OS API
Последнее редактирование:
