#include "hlapi/hlapi.h" #include #include #include #include #include #include #include #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) FILE* dfile; extern int vtTLBHits, vtTLBMisses; static unsigned long readbench(const WinProcess& process, size_t start, size_t end, size_t chunkSize, size_t chunkCount, size_t totalSize, size_t *readCount, size_t *totalRead) { end -= chunkSize; if (end <= start) { chunkSize = (end + chunkSize) - start; end = start + 1; } void** buf = (void**)malloc(chunkCount * sizeof(void*)); for (size_t i = 0; i < chunkCount; i++) buf[i] = malloc(chunkSize); std::vector info; info.resize(chunkCount); size_t read = 0; *readCount = 0; *totalRead = 0; std::random_device rd; std::mt19937 eng(rd()); std::uniform_int_distribution distr(start, end); std::uniform_int_distribution distrp(0, 0x2000); size_t addr = distr(eng); for (size_t i = 0; i < chunkCount; i++) { size_t addrp = distrp(eng); info[i].local = (uint64_t)buf[i]; info[i].size = chunkSize; info[i].remote = addr + addrp; } auto beginTime = std::chrono::high_resolution_clock::now(); while(read < totalSize) { addr = distr(eng); for (size_t i = 0; i < chunkCount; i++) { size_t addrp = distrp(eng); info[i].local = (uint64_t)buf[i]; info[i].size = chunkSize; info[i].remote = addr + addrp; } (*totalRead) += VMemReadMul(&process.ctx->process, process.proc.dirBase, info.data(), chunkCount); read += chunkSize * chunkCount; (*readCount)++; } auto endTime = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < chunkCount; i++) free(buf[i]); free(buf); *totalRead = read; return std::chrono::duration_cast(endTime - beginTime).count(); } static const size_t chunkSizes[] = { 0x10000, 0x1000, 0x100, 0x10, 0x8 }; static const size_t chunkCounts[] = { 32, 8, 1 }; static const size_t readSize = 64; static void runfullbench(FILE* out, const WinProcess& process, size_t start, size_t end) { size_t readCount; size_t totalRead; for (const size_t i : chunkSizes) { fprintf(out, "0x%lx", i); for (const size_t o : chunkCounts) { unsigned long time = readbench(process, start, end, i, o, 0x100000 * readSize, &readCount, &totalRead); double speed = ((double)(totalRead / 0x100000) * 10e5) / time; double callSpeed = ((double)readCount * 10e5) / time; fprintf(out, ", %.2lf, %.2lf", speed, callSpeed); } fprintf(out, "\n"); } } __attribute__((constructor)) static void init() { FILE* out = stdout; pid_t pid = 0; #if (LMODE() != MODE_EXTERNAL()) pid = getpid(); #endif fprintf(out, "Using Mode: %s\n", TOSTRING(LMODE)); vmread_dfile = out; try { WinContext ctx(pid); ctx.processList.Refresh(); fprintf(out, "Process List:\nPID\tVIRT\t\t\tPHYS\t\tBASE\t\tNAME\n"); for (auto& i : ctx.processList) fprintf(out, "%.4lx\t%.16lx\t%.9lx\t%.9lx\t%s\n", i.proc.pid, i.proc.process, i.proc.physProcess, i.proc.dirBase, i.proc.name); for (auto& i : ctx.processList) { if (!strcasecmp("steam.exe", i.proc.name)) { fprintf(out, "\nLooping process %lx:\t%s\n", i.proc.pid, i.proc.name); PEB peb = i.GetPeb(); short magic = i.Read(peb.ImageBaseAddress); fprintf(out, "\tBase:\t%lx\tMagic:\t%hx (valid: %hhx)\n", peb.ImageBaseAddress, magic, (char)(magic == IMAGE_DOS_SIGNATURE)); fprintf(out, "\tExports:\n"); for (auto& o : i.modules) { fprintf(out, "\t%.8lx\t%.8lx\t%lx\t%s\n", o.info.baseAddress, o.info.entryPoint, o.info.sizeOfModule, o.info.name); if (!strcmp("friendsui.DLL", o.info.name)) { for (auto& u : o.exports) fprintf(out, "\t\t%lx\t%s\n", u.address, u.name); } } } } WinProcess* processes[] = { ctx.processList.FindProc("System"), ctx.processList.FindProc("Steam.exe"), ctx.processList.FindProc("System") }; for (auto& proc : processes) for (auto& i : ctx.systemModuleList.Get(proc)) if (!strcasecmp(i.info.name, "win32kbase.sys")) fprintf(out, "%s kmod export count: %zu\n", i.info.name, i.exports.getSize()); WinProcess* steam = ctx.processList.FindProcNoCase("Steam.exe"); if (steam) { WinDll* mod = steam->modules.GetModuleInfo("friendsui.DLL"); if (mod) { fprintf(out, "Performing memory benchmark...\n"); SetMemCacheTime(1000); FlushTlb(GetTlb()); runfullbench(out, *steam, mod->info.baseAddress, mod->info.baseAddress + mod->info.sizeOfModule); SetMemCacheTime(GetDefaultMemCacheTime()); } } } catch (VMException& e) { fprintf(out, "Initialization error: %d\n", e.value); } fclose(out); } int main() { return 0; }