예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
파일: sha2.hpp 프로젝트: herumi/cybozulib
inline uint64_t rot64(uint64_t x, int s)
{
#ifdef _MSC_VER
	return _rotr64(x, s);
#else
	return (x >> s) | (x << (64 - s));
#endif
}
예제 #5
0
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);
}
예제 #6
0
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));
    }
}
예제 #7
0
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);
	}

}
예제 #8
0
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 = &sol;
		}

		// 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]);
		}
	}
}