Skip to content

Commit

Permalink
test hashes search, add fps limiter and std::string in config.hpp
Browse files Browse the repository at this point in the history
  • Loading branch information
ate47 committed Sep 24, 2024
1 parent 4db7b89 commit a742798
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 59 deletions.
164 changes: 145 additions & 19 deletions src/acts/tools/hash.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include <includes.hpp>
#include <core/config.hpp>
#include <rapidcsv.h>
#include "tools/tools_ui.hpp"
#include "tools/tools_nui.hpp"
#include "tools/hashes/hash_scanner.hpp"
#include "actscli.hpp"

namespace {
Expand Down Expand Up @@ -204,27 +206,39 @@ namespace {
Edit_SetText(info.hashLookupEditRet, discstr.c_str());
}
}
struct HashAlg {
const char* id;
const char* desc;
std::function<uint64_t(const char* text)> hashFunc;
char buffer[0x20]{ 0 };
bool selected{};
};

bool hash_nui() {
static char hashBuff[0x100];
static HashAlg algs[]
{
{ "h64", "fnv1a", [](const char* text) -> uint64_t { return hashutils::Hash64A(text); } },
{ "res", "iw res", [](const char* text) -> uint64_t { return hashutils::HashIWRes(text); } },
{ "h32", "t89 canon", [](const char* text) -> uint64_t { return hashutils::Hash32(text); } },
{ "iw9", "mwii/iii canon", [](const char* text) -> uint64_t { return hashutils::HashJupScr(text); } },
{ "bo6", "bo6 canon", [](const char* text) -> uint64_t { return hashutils::HashT10Scr(text); } },
{ "t7", "t7 fnv1a", [](const char* text) -> uint64_t { return hashutils::HashT7(text); } },
{ "tag", "IW tag", [](const char* text) -> uint64_t { return hashutils::HashIWTag(text); } },
{ "dvar", "IW Dvar", [](const char* text) -> uint64_t { return hashutils::HashIWDVar(text); } },
};

struct HashAlg {
const char* desc;
std::function<uint64_t(const char* text)> hashFunc;
char buffer[0x20]{ 0 };
};
static void SyncAlgCfg() {
static std::once_flag of;

static HashAlg algs[]
{
{ "fnv1a", [](const char* text) -> uint64_t { return hashutils::Hash64A(text); } },
{ "iw res", [](const char* text) -> uint64_t { return hashutils::HashIWRes(text); } },
{ "t89 canon", [](const char* text) -> uint64_t { return hashutils::Hash32(text); } },
{ "mwii/iii canon", [](const char* text) -> uint64_t { return hashutils::HashJupScr(text); } },
{ "bo6 canon", [](const char* text) -> uint64_t { return hashutils::HashT10Scr(text); } },
{ "t7 fnv1a", [](const char* text) -> uint64_t { return hashutils::HashT7(text); } },
{ "IW tag", [](const char* text) -> uint64_t { return hashutils::HashIWTag(text); } },
{ "IW Dvar", [](const char* text) -> uint64_t { return hashutils::HashIWDVar(text); } },
};
std::call_once(of, [] {
for (HashAlg& alg : algs) {
alg.selected = core::config::GetBool(std::format("hash.alg.{}", alg.id), true);
}
});
}

bool hash_nui() {
static char hashBuff[0x100];
SyncAlgCfg();

ImGui::SeparatorText("Hashes");

Expand Down Expand Up @@ -334,6 +348,117 @@ namespace {
return false;
}

constexpr uint64_t HASH_MASK = 0xFFFFFFFFFFFFFFF; // remove 2 last bits to match fnv1a63 and greyhound hashes

bool hashsearch_nui() {
static char guessIn[0x100]{ 0 };
static char guessInCpy[sizeof(guessIn)]{0};
static char loadPath[0x100]{ 0 };
static std::string guessOut{};
static std::unordered_set<uint64_t> hashes{};
auto LoadHashes = [] {
hashes.clear();
std::vector<std::filesystem::path> files{};

utils::GetFileRecurse(loadPath, files, [](const std::filesystem::path& p) {
std::string name = p.string();
return
name.ends_with(".gsc") || name.ends_with(".csc")
|| name.ends_with(".csv") || name.ends_with(".tsv")
|| name.ends_with(".dec.lua")
|| name.ends_with(".json");
});

std::unordered_set<uint64_t> tmp{};
// TODO: add loading bar
tool::hash::scanner::ScanHashes(files, tmp);

for (uint64_t t : tmp) {
hashes.insert(t & HASH_MASK);
}
};
{
static std::once_flag of;

std::call_once(of, [&LoadHashes] {
std::string loadPathCfg = core::config::GetString("hash.path", "");

snprintf(loadPath, sizeof(loadPath), "%s", loadPathCfg.c_str());
if (!loadPathCfg.empty() && core::config::GetBool("hash.loadPathAtStart", false)) {
LoadHashes();
}
});
}
SyncAlgCfg();
bool c = false;

ImGui::SeparatorText("Hash searcher");

if (hashes.empty()) {
ImGui::Text("No hash loaded");
}
else {
ImGui::Text("%llu hash(es) loaded", hashes.size());
}

if (ImGui::InputText("Path", loadPath, sizeof(loadPath))) {
core::config::SetString("hash.path", loadPath);
c = true;
}

if (ImGui::Button("Load hashes")) {
LoadHashes();
}


bool edit{};
if (ImGui::InputText("Guess", guessIn, sizeof(guessIn))) {
edit = true;
}

if (ImGui::BeginCombo("Selected hashes", nullptr, ImGuiComboFlags_NoPreview)) {
for (HashAlg& alg : algs) {
if (ImGui::Checkbox(alg.desc, &alg.selected)) {
core::config::SetBool(std::format("hash.alg.{}", alg.id), alg.selected);
c = true;
edit = true;
}
}
ImGui::EndCombo();
}

if (edit) {
guessOut = {};
if (*guessIn) {
size_t guessInLen = std::strlen(guessIn);
memcpy(guessInCpy, guessIn, guessInLen);

// expand by reducing the len
for (size_t i = guessInLen; i > 0; i--) {
guessInCpy[i] = 0;

for (HashAlg& alg : algs) {
if (!alg.selected) {
continue;
}

uint64_t v = alg.hashFunc(guessInCpy);

auto it = hashes.find(v & HASH_MASK);

if (it != hashes.end()) {
guessOut += std::format("{:x},{}\n", v, guessInCpy);
}
}
}
}
}

ImGui::InputTextMultiline("Output", guessOut.data(), guessOut.length(), ImVec2(0, 200), ImGuiInputTextFlags_ReadOnly);

return c;
}

int Render(HWND window, HINSTANCE hInstance) {
std::wstring hashw = utils::StrToWStr(info.hash);
std::wstring valw = utils::StrToWStr(info.val);
Expand Down Expand Up @@ -1123,11 +1248,12 @@ namespace {

return tool::OK;
}

}

ADD_TOOL_UI("hash", L"Hash", Render, Update, Resize);
ADD_TOOL_NUI("hash", "Hash", hash_nui);
ADD_TOOL_NUI("hashsearch", "Searcher", hashsearch_nui);

ADD_TOOL("lookup", "hash", " (string)*", "lookup strings", nullptr, lookuptool);
ADD_TOOL("h32", "hash", " (string)*", "hash strings", nullptr, hash32);
Expand Down
87 changes: 47 additions & 40 deletions src/acts/tools/hashes/hash_scanner.cpp
Original file line number Diff line number Diff line change
@@ -1,37 +1,18 @@
#include <includes.hpp>
#include "hash_scanner.hpp"
#include <regex>
#include <future>

namespace {
namespace tool::hash::scanner {

int hashscan(Process& proc, int argc, const char* argv[]) {
if (argc < 4) {
return tool::BAD_USAGE;
}


std::vector<std::filesystem::path> files{};

LOG_TRACE("Load file(s)...");
utils::GetFileRecurse(argv[2], files, [](const std::filesystem::path& p) {
auto name = p.string();
return
name.ends_with(".gsc") || name.ends_with(".csc")
|| name.ends_with(".csv") || name.ends_with(".tsv")
|| name.ends_with(".dec.lua")
|| name.ends_with(".json");
});
LOG_TRACE("{} file(s) loaded...", files.size());

std::unordered_set<uint64_t> hashes{};

std::regex pattern{ "(hash|file|var|function|namespace|event|script)_([0-9a-fA-F]{1,16})" };
void ScanHashes(const std::vector<std::filesystem::path>& files, std::unordered_set<uint64_t>& hashes) {
static std::regex pattern{ "(hash|file|var|function|namespace|event|script)_([0-9a-fA-F]{1,16})" };

std::string buffer{};
for (const auto& p : files) {
for (const std::filesystem::path& p : files) {
if (!utils::ReadFile(p, buffer)) {
LOG_ERROR("Can't read file.");
return false;
LOG_ERROR("Can't read file {}.", p.string());
continue;
}
auto rbegin = std::sregex_iterator(buffer.begin(), buffer.end(), pattern);
auto rend = std::sregex_iterator();
Expand All @@ -43,27 +24,53 @@ namespace {
}
// TODO: async
}
}
namespace {

LOG_INFO("Find {} hash(es)", hashes.size());
int hashscan(Process& proc, int argc, const char* argv[]) {
if (argc < 4) {
return tool::BAD_USAGE;
}

std::ofstream output{ argv[3] };
std::vector<std::filesystem::path> files{};

if (!output) {
LOG_ERROR("Can't open {}", argv[3]);
return tool::BASIC_ERROR;
}
LOG_TRACE("Load file(s)...");
utils::GetFileRecurse(argv[2], files, [](const std::filesystem::path& p) {
std::string name = p.string();
return
name.ends_with(".gsc") || name.ends_with(".csc")
|| name.ends_with(".csv") || name.ends_with(".tsv")
|| name.ends_with(".dec.lua")
|| name.ends_with(".json");
});
LOG_TRACE("{} file(s) loaded...", files.size());

for (uint64_t h : hashes) {
output << "hash_" << std::hex << h << "\n";
}
std::unordered_set<uint64_t> hashes{};
ScanHashes(files, hashes);

output.close();
LOG_INFO("Find {} hash(es)", hashes.size());

LOG_INFO("Dump into {}", argv[3]);
std::ofstream output{ argv[3] };

return tool::OK;
}
if (!output) {
LOG_ERROR("Can't open {}", argv[3]);
return tool::BASIC_ERROR;
}

for (uint64_t h : hashes) {
output << "hash_" << std::hex << h << "\n";
}

output.close();

LOG_INFO("Dump into {}", argv[3]);

return tool::OK;
}

ADD_TOOL("hashscan", "hash", " [dir] [output]", "scan hashes in a directory", nullptr, hashscan);
ADD_TOOL("hashscan", "hash", " [dir] [output]", "scan hashes in a directory", nullptr, hashscan);

}


}
7 changes: 7 additions & 0 deletions src/acts/tools/hashes/hash_scanner.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

namespace tool::hash::scanner {
void ScanHashes(const std::vector<std::filesystem::path>& files, std::unordered_set<uint64_t>& hashes);


}
21 changes: 21 additions & 0 deletions src/acts/tools/tools_nui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ namespace tool::nui {
class ActsConfig {
std::vector<float> floor{};
size_t len{};
long long lastTime{};
int fps{ 120 };
int nextLen{ 100 };
float farLen{ 20 };
float color[3]{ 1, 1, 1 };
Expand All @@ -56,6 +58,7 @@ namespace tool::nui {

void LoadCfg() {
enabled = core::config::GetBool("nui.bg.enabled", enabled);
fps = (int)core::config::GetInteger("nui.bg.fps", fps);
loadHashStartup = core::config::GetBool("nui.loadHashesStartup", loadHashStartup);
triangles = core::config::GetBool("nui.bg.triangles", triangles);
nextLen = (int)core::config::GetInteger("nui.bg.spikes", nextLen);
Expand Down Expand Up @@ -100,6 +103,7 @@ namespace tool::nui {
bool c = false;
ImGui::SeparatorText("Background Config");
c |= ImGui::Checkbox("Enabled", &enabled);
c |= ImGui::SliderInt("Max fps", &fps, 1, 240);

if (enabled) {
c |= ImGui::SliderInt("Spikes", &nextLen, 2, 200);
Expand All @@ -121,6 +125,7 @@ namespace tool::nui {

if (c) {
core::config::SetBool("nui.bg.enabled", enabled);
core::config::SetInteger("nui.bg.fps", fps);
core::config::SetBool("nui.loadHashesStartup", loadHashStartup);
core::config::SetInteger("nui.bg.spikes", nextLen);
core::config::SetDouble("nui.bg.far", (double)farLen);
Expand Down Expand Up @@ -152,6 +157,20 @@ namespace tool::nui {
glVertex3f(x, y, z);
};

void PreLoop() {
lastTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}

void WaitFPS() const {
long long time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();

long long towait = lastTime - time + (1000 / fps);

if (towait > 0) {
Sleep((DWORD)towait);
}
}

void Render() {
if (!enabled) {
return;
Expand Down Expand Up @@ -376,6 +395,7 @@ namespace tool::nui {
bg.LoadCfg();

while (!nui.ShouldClose()) {
bg.PreLoop();
nui.Loop();

ImVec2 vec{};
Expand Down Expand Up @@ -405,6 +425,7 @@ namespace tool::nui {
bg.Render();

nui.Render();
bg.WaitFPS();
}
}
namespace {
Expand Down
Loading

0 comments on commit a742798

Please sign in to comment.