#include "UserInterface/StdAfx.h" #include "UserInterface/ProcessCRC.h" #include #include #include const char * stristr(const char * big, const char * little); bool GetProcessInformation(std::string & exeFileName, LPCVOID * ppvAddress); bool __GetExeCRC(DWORD & r_dwProcCRC, DWORD & r_dwFileCRC); int main() { int failures = 0; auto check = [&failures](bool ok, const char *name) { if (!ok) { std::fprintf(stderr, "FAIL %s\n", name); ++failures; } }; static const BYTE xorTable[8] = { 102, 30, 188, 44, 39, 201, 43, 5 }; // stristr (40250): case-insensitive, and it compares one character less than the needle's length. const char * hay = "C:\\Game\\METIN2.BIN"; check(stristr(hay, "metin2.bin") == hay + 8, "stristr case fold"); check(stristr(hay, "metin2.biX") == hay + 8, "stristr ignores the last needle character"); check(stristr(hay, "client.exe") == NULL, "stristr miss"); // Before BuildProcessCRC the cube is zero: the pieces are the XOR table, index cycling & 7. bool pristine = true; for (int i = 0; i < 16; ++i) pristine &= GetProcessCRCMagicCubePiece() == xorTable[i & 7]; check(pristine, "pieces before BuildProcessCRC"); // ADAPTED: no module snapshot -> ProcCRC 0; FileCRC is the CRC32 of GetExcutedFileName, as in 40250. std::string exe; LPCVOID base = NULL; check(!GetProcessInformation(exe, &base), "GetProcessInformation finds no module"); DWORD proc = 1, file = 0; check(__GetExeCRC(proc, file) && proc == 0, "__GetExeCRC proc 0"); GetExcutedFileName(exe); check(file == GetFileCRC32(exe.c_str()), "__GetExeCRC file CRC"); // BuildProcessCRC interleaves proc/file bytes low to high and restarts the index. GetProcessCRCMagicCubePiece(); BuildProcessCRC(); BYTE expect[8]; for (int i = 0; i < 4; ++i) { expect[2 * i] = BYTE(proc >> (8 * i)); expect[2 * i + 1] = BYTE(file >> (8 * i)); } bool built = true; for (int i = 0; i < 8; ++i) built &= GetProcessCRCMagicCubePiece() == BYTE(expect[i] ^ xorTable[i]); check(built, "pieces after BuildProcessCRC"); return failures ? 1 : 0; }