UINT64 _inline longhash1(UINT64 key) { key += ~(key << 32); key ^= _rotr64(key,22); key += ~(key << 13); key ^= _rotr64(key,8); key += (key << 3); key ^= _rotr64(key,15); key += ~(key << 27); key ^= _rotr64(key,31); return key; }
void addKnight(solution *sol, int attackSquare, int* coverage) { knight* knightPrint = placements[attackSquare]; if (knightPrint == NULL) { knightPrint = (knight*)calloc(1, sizeof(knight)); int y = knightsYX[attackSquare][0]; int x = knightsYX[attackSquare][1]; knightPrint->placement[y] |= _rotr64(UNIT, x); knightPrint->coverage[y] |= _rotr64(UNIT, x); if ((y >= STEP_X) && (x >= STEP_Y)) { knightPrint->coverage[y - STEP_X] |= _rotr64(UNIT, (x - STEP_Y)); } if (y >= STEP_X) { knightPrint->coverage[y - STEP_X] |= _rotr64(UNIT, (x + STEP_Y)); } if (x >= STEP_Y) { knightPrint->coverage[y + STEP_X] |= _rotr64(UNIT, (x - STEP_Y)); } knightPrint->coverage[y + STEP_X] |= _rotr64(UNIT, (x + STEP_Y)); if ((y >= STEP_Y) && (x >= STEP_X)) { knightPrint->coverage[y - STEP_Y] |= _rotr64(UNIT, (x - STEP_X)); } if (y >= STEP_Y) { knightPrint->coverage[y - STEP_Y] |= _rotr64(UNIT, (x + STEP_X)); } if (x >= STEP_X) { knightPrint->coverage[y + STEP_Y] |= _rotr64(UNIT, (x - STEP_X)); } knightPrint->coverage[y + STEP_Y] |= _rotr64(UNIT, (x + STEP_X)); placements[attackSquare] = knightPrint; } long long* solPtr = (long long*)sol; long long* knightPtr = (long long*)knightPrint; long long cover = 0; for (int i = sizeof(solution) / sizeof(long long); i > 0; i--, solPtr++, knightPtr++) { *solPtr |= *knightPtr; if (i <= 64) { cover += _mm_popcnt_u64(*solPtr); } } *coverage = (int)cover; }
EXTERN_C static PgContextBase* WinXpDecryptPatchGuardContext( __in PatchGuardContextInfo& Info) { // The first some bytes can simply be XOR-ed auto pgContext = reinterpret_cast<ULONG64*>(Info.PgContext); static const auto NUMBER_OF_TIMES_TO_DECRYPT = FIELD_OFFSET(PgContextBase, ExAcquireResourceSharedLite) / sizeof(ULONG64); C_ASSERT(NUMBER_OF_TIMES_TO_DECRYPT == 0x19); for (SIZE_T i = 0; i < NUMBER_OF_TIMES_TO_DECRYPT; ++i) { pgContext[i] ^= Info.XorKey; } // The above decrypts ContextSizeInQWord field, so let's decrypt the // remaining bytes according to the value. Note that this decryption // requires key location. auto decryptionKey = Info.XorKey; auto decryptedPgContext = reinterpret_cast<PgContextBase*>(pgContext); for (auto i = decryptedPgContext->ContextSizeInQWord; i; --i) { pgContext[i + NUMBER_OF_TIMES_TO_DECRYPT - 1] ^= decryptionKey; decryptionKey = _rotr64(decryptionKey, static_cast<UCHAR>(i)); } // Once decryption is completed, ExAcquireResourceSharedLite field should // be the same as the value taken from a symbol. ASSERT(decryptedPgContext->ExAcquireResourceSharedLite == g_WinXSymbols.ExAcquireResourceSharedLite); return decryptedPgContext; }
inline uint64_t rot64(uint64_t x, int s) { #ifdef _MSC_VER return _rotr64(x, s); #else return (x >> s) | (x << (64 - s)); #endif }
void dumpSolutions(int attack, int knightNumber, int coverage, const char* fileName, bool showCoverage, int counter) { FILE* inFile = mkSolDir(attack, coverage, knightNumber, fileName, true, false, counter); FILE* outFile = mkSolDir(attack, coverage, knightNumber, fileName, false, true, 0); initialiseXYs(); int maxSize = knightsYX[attack][1] > knightsYX[attack][0] ? knightsYX[attack][1] : knightsYX[attack][0]; maxSize += HASH_BORDER; if (maxSize >= MAX_GRID) { maxSize = MAX_GRID; } char* grid = (char*)malloc(maxSize + 1); char format[10]; sprintf(format, "%%.%ds\n", (maxSize + 1)); solution sol; size_t loop = readSolution(&sol, inFile); while (loop) { for (int row = 0; row <= maxSize; row++) { char* start = grid; unsigned long long test = UNIT; for (int loop = 0; loop <= maxSize; loop++) { if (sol.knights[row] & test) { *start = 'K'; } else if ((sol.coverage[row] & test) && showCoverage) { *start = '*'; } else { *start = '.'; } start++; test = _rotr64(test, 1); } fprintf(outFile, format, grid); } fprintf(outFile, "\n\n"); loop = readSolution(&sol, inFile); } fclose(inFile); fclose(outFile); }
EXTERN_C static void WinXpEncryptPatchGuardContext( __in PatchGuardContextInfo& Info, __in PgContextBase* DecryptedPgContext) { const auto pgContextSize = DecryptedPgContext->ContextSizeInQWord; auto pgContext = reinterpret_cast<ULONG64*>(Info.PgContext); static const auto NUMBER_OF_TIMES_TO_ENCRYPT = FIELD_OFFSET(PgContextBase, ExAcquireResourceSharedLite) / sizeof(ULONG64); C_ASSERT(NUMBER_OF_TIMES_TO_ENCRYPT == 0x19); for (SIZE_T i = 0; i < NUMBER_OF_TIMES_TO_ENCRYPT; ++i) { pgContext[i] ^= Info.XorKey; } auto decryptionKey = Info.XorKey; for (auto i = pgContextSize; i; --i) { pgContext[i + NUMBER_OF_TIMES_TO_ENCRYPT - 1] ^= decryptionKey; decryptionKey = _rotr64(decryptionKey, static_cast<UCHAR>(i)); } }
void tidySolutions(int attack, int knightNumber, int coverage, int counter) { FILE* inFile = mkSolDir(attack, coverage, knightNumber, maximisedFile, true, false, counter); FILE* duplicatesOutFile = NULL; FILE* tidiedOutFile = NULL; solution sol; solutionTree = (solutionLeaf *)malloc(sizeof(solutionLeaf) * MAX_SOLUTIONS); solutionLeaf* slot = solutionTree; unsigned long long count = 0; bool error = false; initialiseXYs(); int pos = knightsYX[attack][1] > knightsYX[attack][0] ? knightsYX[attack][1] : knightsYX[attack][0]; if (pos + HASH_BORDER >= MAX_GRID) { printf("Cannot hash more than %d rows", (MAX_GRID - HASH_BORDER)); return; } long long currentPosition = _ftelli64(inFile); size_t loop = readSolution(&sol, inFile); unsigned long long mask = _rotr64(MASK, pos); while (loop) { int offset = 0; int multiplierIndex = 0; unsigned long long rowHash = 0; unsigned long long hash = 0; for (int row = 0; row < pos; row++) { unsigned long long part = (sol.coverage[row] & mask); if (offset < pos) { part = _rotl64(part, pos - offset); } else if (offset > pos) { part = _rotr64(part, offset - pos); } rowHash |= part; offset += HASH_BORDER; if (offset > MAX_GRID) { offset -= MAX_GRID; if (multiplierIndex == 0) { hash |= rowHash; } else { hash |= (rowHash + 1) * multiplier[multiplierIndex]; multiplierIndex++; } } } for (int row = pos; row < pos + HASH_BORDER; row++) { hash |= (_rotr64(sol.coverage[row], MAX_GRID - HASH_BORDER - pos) + 1) * multiplier[multiplierIndex]; multiplierIndex++; } slot->hash = hash; slot->bigger = NULL; slot->equal = NULL; slot->lesser = NULL; slot->solutionOffset = currentPosition; if (count > 0) { solutionLeaf* root = solutionTree; while (true) { if (hash == root->hash) { if (root->equal == NULL) { root->equal = slot; break; } else { root = root->equal; } } else if (hash > root->hash) { if (root->bigger == NULL) { root->bigger = slot; break; } else { root = root->bigger; } } else if (hash < root->hash) { if (root->lesser == NULL) { root->lesser = slot; break; } else { root = root->lesser; } } } } slot++; count++; currentPosition = _ftelli64(inFile); loop = readSolution(&sol, inFile); if ((count == MAX_SOLUTIONS) && loop) { printf("Too many solutions to manage."); error = true; break; } } fclose(inFile); if (error) { return; } inFile = mkSolDir(attack, coverage, knightNumber, maximisedFile, true, false, counter); tidiedOutFile = mkSolDir(attack, coverage, knightNumber, tidiedFile, false, false, 0); slot = solutionTree; readSolution(&sol, inFile); solution compare; while (count) { if (slot->equal == NULL) { //Could be in a maximised file less than counter! writeSolution(&sol, tidiedOutFile); slot++; } else { solutionLeaf* test = slot->equal; int state = STATE_KEEP; while (test != NULL) { _fseeki64(inFile, test->solutionOffset, SEEK_SET); readSolution(&compare, inFile); int cmp = memcmp(sol.coverage, compare.coverage, sizeof(unsigned long long) * MAX_GRID); if (cmp == 0) { cmp = memcmp(sol.knights, compare.knights, sizeof(unsigned long long) * MAX_GRID); if (cmp == 0) { state = STATE_SCRAP; break; } else { state = STATE_DUPLICATE; } } test = test->equal; } if (state == STATE_KEEP) { writeSolution(&sol, tidiedOutFile); } else if (state == STATE_DUPLICATE) { if (duplicatesOutFile == NULL) { duplicatesOutFile = mkSolDir(attack, coverage, knightNumber, duplicatesFile, false, false, 0); } writeSolution(&sol, duplicatesOutFile); } slot++; _fseeki64(inFile, slot->solutionOffset, SEEK_SET); } readSolution(&sol, inFile); count--; } fclose(inFile); fclose(tidiedOutFile); if (duplicatesOutFile != NULL) { fclose(duplicatesOutFile); } }
void maximiseSolutions(int attack, int knightSoFar, int coverage, int counter) { FILE* inFile; FILE* outFile[MAX_GRID * MAX_GRID]; solution sol; solution flippedSol; solution* assessedSol; memset(outFile, 0, sizeof(outFile)); inFile = mkSolDir(attack, coverage, knightSoFar, solutionFile, true, false, counter); size_t loop = readSolution(&sol, inFile); while (loop) { bool flip = false; unsigned long long column = UNIT; for (int row = 0; row < MAX_GRID; row++) { unsigned long long columnImpact = UNIT; unsigned long long columnVal = 0; for (int i = 0; i < MAX_GRID; i++) { if (sol.knights[i] & column) { columnVal |= columnImpact; } columnImpact = _rotr64(columnImpact, 1); } if (!flip) { if (sol.knights[row] > columnVal) { break; } else if (sol.knights[row] < columnVal) { flip = true; } } flippedSol.knights[row] = columnVal; column = _rotr64(column, 1); } if (flip) { assessedSol = &flippedSol; unsigned long long column = UNIT; for (int row = 0; row < MAX_GRID; row++) { unsigned long long columnImpact = UNIT; unsigned long long columnVal = 0; for (int i = 0; i < MAX_GRID; i++) { if (sol.coverage[i] & column) { columnVal |= columnImpact; } columnImpact = _rotr64(columnImpact, 1); } flippedSol.coverage[row] = columnVal; column = _rotr64(column, 1); } } else { assessedSol = / } // find next square to attack // In folder int newAttack = 0; bool exit = false; for (int maxLine = 0; (maxLine < MAX_GRID) && !exit; maxLine++) { unsigned long long test = UNIT; for (int x = 0; x <= maxLine; x++) { if ((assessedSol->coverage[maxLine] & test) == 0) { exit = true; break; } test = _rotr64(test, 1); newAttack++; } if ((maxLine < MAX_GRID - 1) && !exit) { for (int y = 0; y <= maxLine; y++) { if ((assessedSol->coverage[y] & test) == 0) { exit = true; break; } newAttack++; } } } if (outFile[newAttack] == NULL) { outFile[newAttack] = mkSolDir(newAttack, coverage, knightSoFar, maximisedFile, false, false, 0); } writeSolution(assessedSol, outFile[newAttack]); loop = readSolution(&sol, inFile); } fclose(inFile); for (int i = 0; i < MAX_GRID * MAX_GRID; i++) { if (outFile[i] != NULL) { fclose(outFile[i]); } } }