|
9 | 9 | #include "hacklib/Patch.h" |
10 | 10 | #include "hacklib/PatternScanner.h" |
11 | 11 | #include "hacklib/Process.h" |
| 12 | +#include "hacklib/BitManip.h" |
12 | 13 | #include <chrono> |
13 | 14 | #include <cstdio> |
14 | 15 | #include <functional> |
15 | 16 | #include <iostream> |
16 | 17 | #include <stdexcept> |
17 | 18 | #include <thread> |
| 19 | +#include <algorithm> |
18 | 20 |
|
19 | 21 |
|
20 | 22 | #define HL_ASSERT(cond, format, ...) \ |
@@ -144,6 +146,59 @@ static void ExpectException(F func) |
144 | 146 | } |
145 | 147 |
|
146 | 148 |
|
| 149 | +#define ASSERT_EQ(a, b) HL_ASSERT((a) == (b), #a " == " #b) |
| 150 | +static void TestBitManip() |
| 151 | +{ |
| 152 | + ASSERT_EQ(hl::HasOverlap(0, 1, 2, 3), false); |
| 153 | + ASSERT_EQ(hl::HasOverlap(2, 3, 0, 1), false); |
| 154 | + ASSERT_EQ(hl::HasOverlap(0, 1, 1, 2), false); |
| 155 | + ASSERT_EQ(hl::HasOverlap(1, 2, 0, 1), false); |
| 156 | + ASSERT_EQ(hl::HasOverlap(0, 1, 0, 1), true); |
| 157 | + ASSERT_EQ(hl::HasOverlap(0, 1, 0, 3), true); |
| 158 | + ASSERT_EQ(hl::HasOverlap(5, 7, 6, 8), true); |
| 159 | + ASSERT_EQ(hl::HasOverlap(6, 8, 5, 7), true); |
| 160 | + |
| 161 | + ASSERT_EQ(hl::HasOverlapInclusive(0, 1, 2, 3), false); |
| 162 | + ASSERT_EQ(hl::HasOverlapInclusive(2, 3, 0, 1), false); |
| 163 | + ASSERT_EQ(hl::HasOverlapInclusive(0, 1, 1, 2), true); |
| 164 | + ASSERT_EQ(hl::HasOverlapInclusive(1, 2, 0, 1), true); |
| 165 | + ASSERT_EQ(hl::HasOverlapInclusive(0, 1, 0, 1), true); |
| 166 | + ASSERT_EQ(hl::HasOverlapInclusive(0, 1, 0, 3), true); |
| 167 | + ASSERT_EQ(hl::HasOverlapInclusive(5, 7, 6, 8), true); |
| 168 | + ASSERT_EQ(hl::HasOverlapInclusive(6, 8, 5, 7), true); |
| 169 | + |
| 170 | + ASSERT_EQ(hl::Align(0x0, 0x10), 0x0); |
| 171 | + ASSERT_EQ(hl::Align(0x5, 0x10), 0x10); |
| 172 | + ASSERT_EQ(hl::Align(0x15, 0x10), 0x20); |
| 173 | + ASSERT_EQ(hl::Align(0x25, 0x10), 0x30); |
| 174 | + ASSERT_EQ(hl::Align(0x10, 0x10), 0x10); |
| 175 | + ASSERT_EQ(hl::Align(0x11, 0x10), 0x20); |
| 176 | + ASSERT_EQ(hl::Align(0x1f, 0x10), 0x20); |
| 177 | + ASSERT_EQ(hl::Align(0xffffffff, 0x10u), 0x0); |
| 178 | + |
| 179 | + ASSERT_EQ(hl::AlignDown(0x0, 0x10), 0x0); |
| 180 | + ASSERT_EQ(hl::AlignDown(0x5, 0x10), 0x0); |
| 181 | + ASSERT_EQ(hl::AlignDown(0x15, 0x10), 0x10); |
| 182 | + ASSERT_EQ(hl::AlignDown(0x25, 0x10), 0x20); |
| 183 | + ASSERT_EQ(hl::AlignDown(0x10, 0x10), 0x10); |
| 184 | + ASSERT_EQ(hl::AlignDown(0x11, 0x10), 0x10); |
| 185 | + ASSERT_EQ(hl::AlignDown(0x1f, 0x10), 0x10); |
| 186 | + ASSERT_EQ(hl::AlignDown(0xffffffff, 0x10u), 0xfffffff0); |
| 187 | + |
| 188 | + ASSERT_EQ(hl::MakeMask<uint8_t>(0, 0), 0x0); |
| 189 | + ASSERT_EQ(hl::MakeMask<uint8_t>(0, 1), 0x1); |
| 190 | + ASSERT_EQ(hl::MakeMask<uint8_t>(0, 2), 0x3); |
| 191 | + ASSERT_EQ(hl::MakeMask<uint8_t>(0, 4), 0xf); |
| 192 | + ASSERT_EQ(hl::MakeMask<uint8_t>(0, 8), 0xff); |
| 193 | + ASSERT_EQ(hl::MakeMask<uint16_t>(0, 16), 0xffff); |
| 194 | + |
| 195 | + ASSERT_EQ(hl::MakeMask<uint8_t>(1, 0), 0x0); |
| 196 | + ASSERT_EQ(hl::MakeMask<uint8_t>(1, 1), 0x2); |
| 197 | + ASSERT_EQ(hl::MakeMask<uint8_t>(1, 7), 0xfe); |
| 198 | + |
| 199 | + ASSERT_EQ(hl::MakeMask<uint64_t>(0, 64), 0xffffffffffffffffull); |
| 200 | +} |
| 201 | + |
147 | 202 | static void TestMemory() |
148 | 203 | { |
149 | 204 | void* mem = g_dummyCode.data(); |
@@ -242,7 +297,12 @@ static void TestInject() |
242 | 297 | libName = "lib" + libName + ".so"; |
243 | 298 | #endif |
244 | 299 |
|
245 | | - auto process = hl::LaunchProcess("./hl_test", { "--child" }); |
| 300 | +#ifdef WIN32 |
| 301 | + std::string procName = "hl_test"; |
| 302 | +#else |
| 303 | + std::string procName = "./hl_test"; |
| 304 | +#endif |
| 305 | + auto process = hl::LaunchProcess(procName, { "--child" }); |
246 | 306 |
|
247 | 307 | // Give the child time to set everything up. |
248 | 308 | std::this_thread::sleep_for(std::chrono::milliseconds(200)); |
@@ -437,6 +497,25 @@ static void TestHooks() |
437 | 497 | HL_ASSERT(cbCounter == 0, "Hook not undone"); |
438 | 498 | } |
439 | 499 |
|
| 500 | +static void TestExeFile() |
| 501 | +{ |
| 502 | +#ifdef WIN32 |
| 503 | + std::string fileName = "hl_test.exe"; |
| 504 | +#else |
| 505 | + std::string fileName = "hl_test"; |
| 506 | +#endif |
| 507 | + hl::ExeFile exeFile; |
| 508 | + HL_ASSERT(exeFile.loadFromFile(fileName), "ExeFile::loadFromFile failed"); |
| 509 | + auto relocs = exeFile.hasRelocs(); |
| 510 | + HL_ASSERT(relocs, "ExeFile::getRelocations returned non-empty list"); |
| 511 | + auto sections = exeFile.getSections(); |
| 512 | + HL_ASSERT(sections.size() > 1, "ExeFile::getSections returned wrong number of sections"); |
| 513 | + auto numCodeSections = |
| 514 | + std::count_if(sections.begin(), sections.end(), [](const hl::ExeFile::Section& section) |
| 515 | + { return section.type == hl::ExeFile::SectionType::Code && section.name == ".text"; }); |
| 516 | + HL_ASSERT(numCodeSections > 0, "Must find at least one code section"); |
| 517 | +} |
| 518 | + |
440 | 519 | #ifdef WIN32 |
441 | 520 | static int vehCounter1 = 0; |
442 | 521 | static int vehCounter2 = 0; |
@@ -509,12 +588,14 @@ class TestMain : public hl::Main |
509 | 588 | SetupLogging(); |
510 | 589 | TestCrashHandler(); |
511 | 590 |
|
| 591 | + HL_TEST(TestBitManip); |
512 | 592 | HL_TEST(TestMemory); |
513 | 593 | HL_TEST(TestInject); |
514 | 594 | HL_TEST(TestModules); |
515 | 595 | HL_TEST(TestPatch); |
516 | 596 | HL_TEST(TestPatternScan); |
517 | 597 | HL_TEST(TestHooks); |
| 598 | + HL_TEST(TestExeFile); |
518 | 599 | HL_TEST(TestVEH); |
519 | 600 |
|
520 | 601 | HL_LOG_RAW("==========\nTests finished successfully.\n"); |
|
0 commit comments