Skip to content
This repository has been archived by the owner on Aug 12, 2023. It is now read-only.

Commit

Permalink
Hard simplification.
Browse files Browse the repository at this point in the history
  • Loading branch information
RenardDev committed Feb 6, 2022
1 parent fe854db commit a0cfaa7
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 1,719 deletions.
188 changes: 11 additions & 177 deletions ClassFromRTTI/ClassFromRTTI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,193 +21,27 @@ typedef bool(__fastcall* fnIsTrue)(void* ecx, void* edx);
typedef const char*(__fastcall* fnHelloWorld)(void* ecx, void* edx);

int main() {
RTTI cRTTI1; // Default
RTTI cRTTI2(true, true, true, true, false); // With caching
RTTI cRTTI3(false, false, false, true, true); // With min iterations
RTTI cRTTI4(true, true, true, true, true); // With cache and min iterations

HMODULE hTestDLL = LoadLibrary(TEXT("TestDLL.dll"));
if (!hTestDLL) {
printf("Error: TestDLL.dll not found.\n");
return -1;
}

printf("For start press <Enter>\n");
_CRT_UNUSED(getchar());

uintptr_t unTestingRVA = cRTTI2.GetVTableOffsetFromModule(hTestDLL, "TestingDLL");
printf("TestingDLL (RVA) = 0x%IX\n", unTestingRVA);

#ifdef BENCHMARK_TEST
high_resolution_clock::time_point t1;
high_resolution_clock::time_point t2;

// Stage 1
printf("# Stage 1\n");
t1 = high_resolution_clock::now();
for (unsigned char i = 0; i < 100; ++i) {
if (unTestingRVA != cRTTI1.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (100 calls)...............................= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

t1 = high_resolution_clock::now();
for (unsigned short i = 0; i < 1'000; ++i) {
if (unTestingRVA != cRTTI1.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (1 000 calls).............................= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

t1 = high_resolution_clock::now();
for (unsigned int i = 0; i < 10'000; ++i) {
if (unTestingRVA != cRTTI1.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (10 000 calls)............................= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

t1 = high_resolution_clock::now();
for (unsigned int i = 0; i < 50'000; i++) {
if (unTestingRVA != cRTTI1.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (50 000 calls)............................= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

// Stage 2
printf("# Stage 2\n");
t1 = high_resolution_clock::now();
for (unsigned char i = 0; i < 100; ++i) {
if (unTestingRVA != cRTTI2.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (100 calls + Cache).......................= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

t1 = high_resolution_clock::now();
for (unsigned short i = 0; i < 1'000; ++i) {
if (unTestingRVA != cRTTI2.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (1 000 calls + Cache).....................= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

t1 = high_resolution_clock::now();
for (unsigned int i = 0; i < 10'000; ++i) {
if (unTestingRVA != cRTTI2.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (10 000 calls + Cache)....................= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

t1 = high_resolution_clock::now();
for (unsigned int i = 0; i < 50'000; i++) {
if (unTestingRVA != cRTTI2.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (50 000 calls + Cache)....................= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

// Stage 3
printf("# Stage 3\n");
t1 = high_resolution_clock::now();
for (unsigned char i = 0; i < 100; ++i) {
if (unTestingRVA != cRTTI3.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (100 calls + MinIterations)...............= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

t1 = high_resolution_clock::now();
for (unsigned short i = 0; i < 1'000; ++i) {
if (unTestingRVA != cRTTI3.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (1 000 calls + MinIterations).............= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

t1 = high_resolution_clock::now();
for (unsigned int i = 0; i < 10'000; ++i) {
if (unTestingRVA != cRTTI3.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (10 000 calls + MinIterations)............= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

t1 = high_resolution_clock::now();
for (unsigned int i = 0; i < 50'000; i++) {
if (unTestingRVA != cRTTI3.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (50 000 calls + MinIterations)............= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

// Stage 4
printf("# Stage 4\n");
t1 = high_resolution_clock::now();
for (unsigned char i = 0; i < 100; ++i) {
if (unTestingRVA != cRTTI4.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (100 calls + Cache + MinIterations).......= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

t1 = high_resolution_clock::now();
for (unsigned short i = 0; i < 1'000; ++i) {
if (unTestingRVA != cRTTI4.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (1 000 calls + Cache + MinIterations).....= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

t1 = high_resolution_clock::now();
for (unsigned int i = 0; i < 10'000; ++i) {
if (unTestingRVA != cRTTI4.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (10 000 calls + Cache + MinIterations)....= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());

t1 = high_resolution_clock::now();
for (unsigned int i = 0; i < 50'000; i++) {
if (unTestingRVA != cRTTI4.GetVTableOffsetFromModule(hTestDLL, "TestingDLL")) {
printf("Error: Data error!\n");
}
}
t2 = high_resolution_clock::now();
printf("Bench (50 000 calls + Cache + MinIterations)....= %lld ms\n", duration_cast<std::chrono::milliseconds>(t2 - t1).count());
#endif // BENCHMARK_TEST

if (!unTestingRVA) {
printf("Error: TestingDLL RVA VTable not found.\n");
void* pTesting = FindRTTI(hTestDLL, ".?AVTestingDLL@@"); // ".?AV<NAME>@@"
if (!pTesting) {
printf("Error: TestingDLL VTable not found.\n");
return -1;
}

void** pTestingDLL_VT = reinterpret_cast<void**>(reinterpret_cast<char*>(hTestDLL) + unTestingRVA);

fnIsTrue IsTrue = reinterpret_cast<fnIsTrue>(pTestingDLL_VT[0]);
fnHelloWorld HelloWorld = reinterpret_cast<fnHelloWorld>(pTestingDLL_VT[1]);
void** pTestingVTable = reinterpret_cast<void**>(pTesting);
fnIsTrue IsTrue = reinterpret_cast<fnIsTrue>(pTestingVTable[0]);
fnHelloWorld HelloWorld = reinterpret_cast<fnHelloWorld>(pTestingVTable[1]);

printf("# Result:\n");
printf("IsTrue = %s\n", IsTrue(pTestingDLL_VT, nullptr) ? "true" : "false");
printf("HelloWorld = %s\n", HelloWorld(pTestingDLL_VT, nullptr));
printf("RESULT:\n");
printf(" > hTestDLL (0x%IX)\n", reinterpret_cast<uintptr_t>(hTestDLL));
printf(" > pTestingVTable (0x%IX)\n", reinterpret_cast<uintptr_t>(pTestingVTable));
printf(" > IsTrue (0x%IX) = %s\n", reinterpret_cast<uintptr_t>(&(pTestingVTable[0])), IsTrue(pTestingVTable, nullptr) ? "true" : "false");
printf(" > HelloWorld (0x%IX) = %s\n", reinterpret_cast<uintptr_t>(&(pTestingVTable[1])), HelloWorld(pTestingVTable, nullptr));

return 0;
}
Loading

0 comments on commit a0cfaa7

Please # to comment.