void MFNWorkunitWordlistSession::handle_read(const boost::system::error_code& error, size_t bytes_transferred) { //printf("In session::handle_read()\n"); //printf("Buffer (%d): %c\n", bytes_transferred, data_[0]); if (!error) { // Sleep if the list is too big already. while (this->networkPlainQueue->GetTotalWordsQueued() > MAX_PENDING_WORD_COUNT) { //printf("Sleeping for wordcount...\n"); CHSleep(1); } if (bytes_transferred > 0) { std::copy((uint8_t*)&data_[0], ((uint8_t*) &data_[0]) + bytes_transferred, std::back_inserter(this->charBuffer)); } if (this->charBuffer.size() > 10000000) { this->addWordsToQueue(); } socket_.async_read_some(boost::asio::buffer(data_, max_length), boost::bind(&MFNWorkunitWordlistSession::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else { // Report the disconnect //printf("\n\nDSC: %s\n", this->hostIpAddress); fflush(stdout); this->addWordsToQueue(); delete this; } }
void MFNHashTypePlain::RunGPUWorkunit(CHWorkunitRobustElement* WU) { trace_printf("MFNHashTypePlain::RunGPUWorkunit()\n"); /** * High-res timer - this should work properly on both Windows & Posix. */ CHHiresTimer Timer, WorkunitTimer; uint64_t perThread, start_point = 0; uint64_t step_count = 0; uint64_t tempPerStep = 0; WorkunitTimer.start(); // Kernel run time: seconds float ref_time = 0.0f; // Kernel run time: Milliseconds float ref_time_ms = 0.0f; float ref_time_total = 0.0f; // Default number per steps. As this is updated quickly, this just needs to be in the ballpark. if (this->perStep == 0) { this->perStep = 50; } klaunch_printf("Thread %d total kernel width: %d\n", this->threadId, this->TotalKernelWidth); klaunch_printf("Thread %d blocks/threads/vec: %d/%d/%d\n", this->threadId, this->GPUBlocks, this->GPUThreads, this->VectorWidth); // Calculate how many iterations per thread - divide total by the number of // total threads, then add one to deal with truncation. perThread = WU->EndPoint - WU->StartPoint; perThread /= (this->TotalKernelWidth); perThread++; klaunch_printf("Total kernel width: %d\n", this->TotalKernelWidth); klaunch_printf("perThread: %d\n", perThread); // Set up the password start points for loading as blocks. this->setStartPasswords32(perThread, start_point + WU->StartPoint); // Copy them to the GPU. this->copyStartPointsToDevice(); // Start the timer. Timer.start(); while (start_point <= perThread) { step_count++; //this->setStartPoints(perThread, start_point + WU->StartPoint); if ((start_point + this->perStep) > perThread) { klaunch_printf("start_point: %lu\n", start_point); klaunch_printf("per_thread: %lu\n", perThread); klaunch_printf("Will overrun by %lu\n", (start_point + this->perStep) - perThread); tempPerStep = this->perStep; this->perStep = (perThread - start_point) + 1; klaunch_printf("Final per_step: %lu\n", this->perStep); } // We sync here and wait for the GPU to finish. this->synchronizeThreads(); ref_time = Timer.getElapsedTime(); ref_time_ms = Timer.getElapsedTimeInMilliSec(); klaunch_printf("ref_time: %f s\n", ref_time); ref_time_total += ref_time; // Run this roughly every second, or every step if target_ms is >500 if ((step_count < 5) || (this->kernelTimeMs > 500) || (step_count % (1000 / this->kernelTimeMs) == 0)) { this->copyDeviceFoundPasswordsToHost(); this->outputFoundHashes(); // Only set the crack speed if we have set one... if (step_count > 5) { this->Display->setThreadCrackSpeed(this->threadId, (float) (this->TotalKernelWidth * this->perStep) / (ref_time)); } // If the current execution time is not correct, adjust. if ((ref_time_ms > 0) && (step_count > 2) && ((ref_time_ms < (this->kernelTimeMs * 0.9)) || (ref_time_ms > (this->kernelTimeMs * 1.1)))) { this->perStep = (uint64_t) ((float) this->perStep * ((float) this->kernelTimeMs / ref_time_ms)); if (0) { printf("\nThread %d Adjusting passwords per step to %d\n", this->gpuDeviceId, (unsigned int) this->perStep); } } } // If we are to pause, hang here. if (global_interface.pause) { while (global_interface.pause) { // Just hang out until the pause is broken... CHSleep(1); } } // Exit option if (global_interface.exit) { return; } //this->copyStartPointsToDevice(); //this->synchronizeThreads(); Timer.start(); klaunch_printf("Launching kernel: \n"); klaunch_printf(" start_point: %lu\n", start_point); klaunch_printf(" perStep: %lu\n", this->perStep); this->launchKernel(); // Increment start point by however many we did start_point += this->perStep; } this->synchronizeThreads(); // Perform a final rate calculation. // In some cases, the device is too fast for the normal speed reporting // to get triggered. Timer.stop(); ref_time = Timer.getElapsedTime(); this->Display->setThreadCrackSpeed(this->threadId, (float) (this->TotalKernelWidth * this->perStep) / (ref_time)); this->copyDeviceFoundPasswordsToHost(); this->outputFoundHashes(); WorkunitTimer.stop(); klaunch_printf("Workunit rate: %f\n", (WU->EndPoint - WU->StartPoint) / WorkunitTimer.getElapsedTime()); klaunch_printf("Workunit timer: %f\n", WorkunitTimer.getElapsedTime()); klaunch_printf("ref_time_total: %f\n", ref_time_total); if (tempPerStep) { klaunch_printf("Correcting perStep from current %lu to perm %lu\n", this->perStep, tempPerStep); this->perStep = tempPerStep; } return; }
void MFNHashTypePlain::crackPasswordLength(int passwordLength) { trace_printf("MFNHashTypePlain::crackPasswordLength(%d)\n", passwordLength); uint64_t i; char statusBuffer[1000]; struct CHWorkunitRobustElement WU; // New cracking - do NOT need to rendezvous threads. this->threadRendezvous = 0; // Acquire a setup mutex if we're the first thread. this->MFNHashTypePlainMutex.lock(); // If static data is not set up, do so. // This data is shared across all instances. if (!this->staticDataInitialized) { this->threadRendezvous = 0; mt_printf("Thread %d doing MFNHashTypePlain setup.\n", this->threadId); this->Display->setPasswordLen(passwordLength); this->passwordLength = passwordLength; // Determine the password length in words. If not a multiple of 4, round up. // Include the end padding bit in this calculation. this->passwordLengthWords = (this->passwordLength + 1); if (passwordLengthWords % 4) { passwordLengthWords = (passwordLengthWords + 4) & 0xfffc; } // Get the raw list of hashes. this->activeHashesRaw = this->HashFile->ExportUncrackedHashList(); // Get the active charset. this->currentCharset = this->Charset->getCharset(); mt_printf("Thread %d Charset length: %d\n", this->threadId, this->currentCharset.size()); // If the charset length is 1, it is a single charset. Tag as such. if (this->currentCharset.size() == 1) { this->isSingleCharset = 1; } else { this->isSingleCharset = 0; } this->setupCharsetArrays(); this->Display->Refresh(); // Preprocess all the hashes for the current password length. for (i = 0; i < this->activeHashesRaw.size(); i++) { this->activeHashesProcessed.push_back(this->preProcessHash(this->activeHashesRaw[i])); } // Sort and unique the hashes. this->sortHashes(); // Set up the device-format hash list this->copyHashesIntoDeviceFormat(); // If this is *not* a server-only instance, create bitmaps if (!this->CommandLineData->GetIsServerOnly()) { this->createLookupBitmaps(); } this->staticDataInitialized = 1; } this->MFNHashTypePlainMutex.unlock(); // Retrieve our client ID. this->ClientId = this->Workunit->GetClientId(); sprintf(statusBuffer, "Td %d: CID %d.", this->threadId, this->ClientId); this->Display->addStatusLine(statusBuffer); // If the device ID is 0, the device is the fastest in the system. // This is true for CUDA, and possibly OpenCL. If this thread is for // a non-zero device, wait a second. This allows the fastest GPU to // take the work. Otherwise, we don't care what order they enter. if (this->gpuDeviceId) { CHSleep(1); } // Do all the device-specific setup. this->setupDevice(); // Reset the per-step data for the new password length. this->perStep = 0; // Allocate the thread and GPU memory. this->allocateThreadAndDeviceMemory(); // Copy all the run data to the device. this->copyDataToDevice(); // Copy the kernel-specific constant data to the device. this->copyConstantDataToDevice(); // I... *think* we're ready to rock! // As long as we aren't supposed to exit, keep running. while(!global_interface.exit && !this->threadRendezvous) { WU = this->Workunit->GetNextWorkunit(ClientId); if (!WU.IsValid) { // If a null workunit came in, rendezvous the threads. this->threadRendezvous = 1; // Workunit came back null - sprintf(statusBuffer, "Td %d: out of WU.", this->threadId); this->Display->addStatusLine(statusBuffer); break; } if (this->CommandLineData->GetDevDebug()) { printf("Thread %d has workunit ID %d\n", this->threadId, WU.WorkUnitID); } this->RunGPUWorkunit(&WU); // If we are NOT aborting, submit the unit. // If we are force-exiting, do not submit the workunit! if (!global_interface.exit) { this->Workunit->SubmitWorkunit(WU); } this->Display->Refresh(); //sprintf(this->statusBuffer, "WU rate: %0.1f", this->Workunit->GetAverageRate()); //this->Display->addStatusLine(this->statusBuffer); } // Done with cracking - out of workunits. Clean up & wait. // Free memory. this->freeThreadAndDeviceMemory(); // Do final device teardown. this->teardownDevice(); // Report speed of 0. this->Display->setThreadCrackSpeed(this->threadId, 0); // Wait until all workunits are back from remote systems. if (this->Workunit->GetNumberOfCompletedWorkunits() < this->Workunit->GetNumberOfWorkunits()) { sprintf(statusBuffer, "Waiting for workunits..."); this->Display->addStatusLine(statusBuffer); } while (this->Workunit->GetNumberOfCompletedWorkunits() < this->Workunit->GetNumberOfWorkunits()) { CHSleep(1); //printf("Completed WU: %d\n", this->Workunit->GetNumberOfCompletedWorkunits()); //printf("Total WU: %d\n", this->Workunit->GetNumberOfWorkunits()); this->Display->Refresh(); // Make termination work properly for the server if (global_interface.exit) { break; } } this->staticDataInitialized = 0; }
// Runs the multiforcer in standalone or network server mode. void runStandaloneOrServerMode() { int i; CHCharsetNew *Charset; MFNWorkunitBase *Workunit; CHHashFileV *HashFile; MFNDisplay *Display; char printBuffer[1000]; MFNHashClassLauncher HashClassLauncher; MFNHashIdentifiers *HashIdentifiers; MFNNetworkServer *NetworkServer = NULL; MFNGeneralInformation *GeneralInformation; MFNCommandLineData *CommandLineData; uint32_t hashId; int maxPasswordLength = 0; CommandLineData = MultiforcerGlobalClassFactory.getCommandlinedataClass(); // Default size. May be overridden. int WorkunitSize = 32; std::vector<uint8_t> RestoreData; std::string ResumeFilename; { char ResumeTimestampBuffer[1024]; struct timeval resume_time; time_t resume_time_t; // Get the resume filename with timestamp. gettimeofday(&resume_time, NULL); resume_time_t=resume_time.tv_sec; memset(ResumeTimestampBuffer, 0, sizeof(ResumeTimestampBuffer)); strftime(ResumeTimestampBuffer, 128, "%Y-%m-%d-%H-%M-%S", localtime(&resume_time_t)); ResumeFilename = "CM-Resume-"; ResumeFilename += ResumeTimestampBuffer; ResumeFilename += ".mfr"; } // Determine the hash type HashIdentifiers = MultiforcerGlobalClassFactory.getHashIdentifiersClass(); if (!HashIdentifiers) { printf("Cannot get hash identifiers class!\n"); exit(1); } hashId = HashIdentifiers->GetHashIdFromString(CommandLineData->GetHashTypeString()); if (hashId == MFN_HASHTYPE_UNDEFINED) { printf("Invalid hash type %s!\n", CommandLineData->GetHashTypeString().c_str()); HashIdentifiers->PrintAllHashTypes(); exit(1); } GeneralInformation = MultiforcerGlobalClassFactory.getGeneralInformationClass(); GeneralInformation->setCharsetClassId(CH_CHARSET_NEW_CLASS_ID); GeneralInformation->setHashId(hashId); GeneralInformation->setPasswordLength(CommandLineData->GetMinPasswordLength()); // Get our classes MultiforcerGlobalClassFactory.setCharsetClassType(CH_CHARSET_NEW_CLASS_ID); if (CommandLineData->GetDebug()) { MultiforcerGlobalClassFactory.setDisplayClassType(MFN_DISPLAY_CLASS_DEBUG); } else if (CommandLineData->GetDaemon()) { MultiforcerGlobalClassFactory.setDisplayClassType(MFN_DISPLAY_CLASS_DAEMON); } else { MultiforcerGlobalClassFactory.setDisplayClassType(MFN_DISPLAY_CLASS_CURSES); } // If this is a wordlist class, use a wordlist workunit. if (HashIdentifiers->GetHasWordlist()) { MultiforcerGlobalClassFactory.setWorkunitClassType(MFN_WORKUNIT_WORDLIST_CLASS_ID); } else { MultiforcerGlobalClassFactory.setWorkunitClassType(MFN_WORKUNIT_ROBUST_CLASS_ID); } // Set up the hash specific stuff. MultiforcerGlobalClassFactory.setHashfileClassType(HashIdentifiers->GetHashData().HashFileIdentifier); HashClassLauncher.setHashType(HashIdentifiers->GetHashData().HashTypeIdentifier); Charset = MultiforcerGlobalClassFactory.getCharsetClass(); if (!Charset) { printf("Cannot get charset class!\n"); exit(1); } Workunit = MultiforcerGlobalClassFactory.getWorkunitClass(); if (!Workunit) { printf("Cannot get workunit class!\n"); exit(1); } HashFile = MultiforcerGlobalClassFactory.getHashfileClass(); if (!HashFile) { printf("Cannot get hashfile class!\n"); exit(1); } Display = MultiforcerGlobalClassFactory.getDisplayClass(); if (!Display) { printf("Cannot get display class!\n"); exit(1); } if (CommandLineData->GetDevDebug()) { Workunit->EnableDebugOutput(); } /* if (CommandLineData->GetUseRestoreFile()) { if (!RobustWorkunit->LoadStateFromFile(CommandLineData->GetRestoreFileName())) { printf("Loading state from file failed.\n"); exit(1); } RestoreData = RobustWorkunit->GetResumeMetadata(); CommandLineData->SetDataFromRestore(RestoreData); // Overwrite the existing one as we progress. RobustWorkunit->SetResumeFile(ResumeFilename); } else { RobustWorkunit->SetResumeFile(ResumeFilename); } */ // Set the hash type being used. //HashTypes.SetHashId(CommandLineData->GetHashType()); // Get the HashType class and HashFile class /* */ // If an output file is to be used, set it here. if (CommandLineData->GetOutputFileName().length()) { HashFile->SetFoundHashesOutputFilename(CommandLineData->GetOutputFileName()); } // If the workunit size was set on the command line, use it here. if (CommandLineData->GetWorkunitBits()) { WorkunitSize = CommandLineData->GetWorkunitBits(); } else { WorkunitSize = HashIdentifiers->GetDefaultWorkunitSizeBits(); } if (!Charset->readCharsetFromFile(CommandLineData->GetCharsetFileName())) { printf("Cannot open charset!\n"); exit(1); } //printf("Charset opened properly.\n"); if (!HashFile->OpenHashFile(CommandLineData->GetHashListFileName())) { printf("Cannot open hash file!\n"); exit(1); } //printf("Hashfile opened properly.\n"); // Add hex output option if desired. HashFile->SetAddHexOutput(CommandLineData->GetAddHexOutput()); HashFile->setPrintAlgorithm(CommandLineData->GetPrintAlgorithms()); // If requested bring the network online and assign types to it if (CommandLineData->GetIsNetworkServer()) { MultiforcerGlobalClassFactory.setNetworkServerPort(CommandLineData->GetNetworkPort()); NetworkServer = MultiforcerGlobalClassFactory.getNetworkServerClass(); NetworkServer->startNetwork(); // Update the display with the server info. char portBuffer[16]; sprintf(portBuffer, "%d", CommandLineData->GetNetworkPort()); Display->setSystemMode(SYSTEM_MODE_SERVER, std::string(portBuffer)); } Display->setHashName(HashIdentifiers->GetHashData().HashDescriptor); if (!CommandLineData->GetIsServerOnly()) { if (!HashClassLauncher.addAllDevices(CommandLineData->GetDevicesToUse())) { printf("Cannot add devices!\n"); exit(1); } } // Pick the desired max length. if (CommandLineData->GetMaxPasswordLength()) { maxPasswordLength = CommandLineData->GetMaxPasswordLength(); } else { maxPasswordLength = HashIdentifiers->GetMaxSupportedLength(); } for (i = CommandLineData->GetMinPasswordLength(); i <= maxPasswordLength; i++) { uint64_t NumberOfPasswords; GeneralInformation->setPasswordLength(i); Display->setPasswordLen(i); // Set the status line to indicate where we are. sprintf(printBuffer, "Starting pw len %d", i); Display->addStatusLine(printBuffer); // If no hashes are left, exit. if (HashFile->GetUncrackedHashCount() == 0) { global_interface.exit = 1; strcpy(global_interface.exit_message, "All hashes found! Exiting!\n"); break; } NumberOfPasswords = Charset->getPasswordSpaceSize(i); // Check for errors from charset and break. if (global_interface.exit) { break; } /* // Provide the correct metadata to the workunit class RestoreData = CommandLineData->GetRestoreData(i); RobustWorkunit->SetResumeMetadata(RestoreData); // If we are NOT restoring, create new workunits. if (!CommandLineData->GetUseRestoreFile()) { RobustWorkunit->CreateWorkunits(NumberOfPasswords, WorkunitSize, i); } if (global_interface.exit) { break; } */ Workunit->CreateWorkunits(NumberOfPasswords, WorkunitSize, i); // If there are threads running locally, launch them. if (!CommandLineData->GetIsServerOnly()) { HashClassLauncher.launchThreads(i); } // Wait until all the workunits are completed. This is useful in // server-only mode. while (Workunit->GetNumberOfCompletedWorkunits() < Workunit->GetNumberOfWorkunits()) { CHSleep(1); Display->Refresh(); // Make termination work properly for the server if (global_interface.exit) { // Break from the while loop. break; } } // Break from the password length loop. if (global_interface.exit) { break; } } delete Workunit; delete Display; HashFile->PrintAllFoundHashes(); // If we are outputting unfound hashes, do it now. if (CommandLineData->GetUnfoundOutputFileName().length()) { HashFile->OutputUnfoundHashesToFile(CommandLineData->GetUnfoundOutputFileName()); } }
/** * This function will wait for a server to arrive, do all the setup for the * instance, and will continue until the server disconnects, at which point this * function will return. */ void runNetworkOneConnect() { MFNCommandLineData *CommandLineData; MFNNetworkClient *NetworkClient; MFNHashIdentifiers *HashIdentifiers; MFNGeneralInformation *GeneralInformation; MFNDisplay *Display; MFNHashClassLauncher HashClassLauncher; CommandLineData = MultiforcerGlobalClassFactory.getCommandlinedataClass(); GeneralInformation = MultiforcerGlobalClassFactory.getGeneralInformationClass(); HashIdentifiers = MultiforcerGlobalClassFactory.getHashIdentifiersClass(); // Set up the network client class. This will wait until a connection is // created, or until the user exits. MultiforcerGlobalClassFactory.setNetworkClientPort(CommandLineData->GetNetworkPort()); MultiforcerGlobalClassFactory.setNetworkClientRemoteHost(CommandLineData->GetNetworkRemoteHostname()); MultiforcerGlobalClassFactory.setNetworkClientOneshot(0); NetworkClient = MultiforcerGlobalClassFactory.getNetworkClientClass(); // If the user has requested an exit, we can just terminate now. if (global_interface.user_exit) { exit(0); } // Update the general information structure to continue setup. NetworkClient->updateGeneralInfo(); // Set the hash ID from the server, and continue setting up the system. HashIdentifiers->SetHashId(GeneralInformation->getHashId()); MultiforcerGlobalClassFactory.setCharsetClassType(CH_CHARSET_NEW_CLASS_ID); if (CommandLineData->GetDebug()) { MultiforcerGlobalClassFactory.setDisplayClassType(MFN_DISPLAY_CLASS_DEBUG); } else if (CommandLineData->GetDaemon()) { MultiforcerGlobalClassFactory.setDisplayClassType(MFN_DISPLAY_CLASS_DAEMON); } else { MultiforcerGlobalClassFactory.setDisplayClassType(MFN_DISPLAY_CLASS_CURSES); } MultiforcerGlobalClassFactory.setWorkunitClassType(MFN_WORKUNIT_NETWORK_CLASS_ID); // Set up the hash specific stuff based on the general information. MultiforcerGlobalClassFactory.setHashfileClassType(HashIdentifiers->GetHashData().HashFileIdentifier); HashClassLauncher.setHashType(HashIdentifiers->GetHashData().HashTypeIdentifier); NetworkClient->updateCharset(); // TODO: This should handle non-existent devices cleanly. if (!HashClassLauncher.addAllDevices(CommandLineData->GetDevicesToUse())) { printf("Cannot add devices!\n"); exit(1); } // Display online - no more output! Display = MultiforcerGlobalClassFactory.getDisplayClass(); Display->setHashName(HashIdentifiers->GetHashData().HashDescriptor); // Loop until the server has gone away while (!global_interface.exit) { // Get the password length/etc. NetworkClient->updateGeneralInfo(); MultiforcerGlobalClassFactory.getWorkunitClass()-> setPasswordLength(GeneralInformation->getPasswordLength()); Display->setPasswordLen(GeneralInformation->getPasswordLength()); NetworkClient->updateUncrackedHashes(); // Only run if there are hashes to crack. if (MultiforcerGlobalClassFactory.getHashfileClass()->GetUncrackedHashCount()) { HashClassLauncher.launchThreads(GeneralInformation->getPasswordLength()); } else { // No hashes left - why should we continue to try and run? CHSleep(5); break; } } // Reset for future runs. global_interface.exit = 0; // Out of the main loop - clean up. MultiforcerGlobalClassFactory.destroyCharsetClass(); MultiforcerGlobalClassFactory.destroyHashfileClass(); MultiforcerGlobalClassFactory.destroyNetworkClientClass(); MultiforcerGlobalClassFactory.destroyWorkunitClass(); MultiforcerGlobalClassFactory.destroyDisplayClass(); }