//----------------------------------------------------------------- // Block hashing: Calculate the MD5 hash value for a 4096 block //----------------------------------------------------------------- LPMD5BLOCK md5Block(BYTE rgbFile[], DWORD dwFileOffset, DWORD dwRunLength) { HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; BYTE rgbHash[MD5LEN]; DWORD cbHash = MD5LEN; DWORD cbRead; LPMD5BLOCK MD5Block = NULL; DWORD i; // Allocate space for the MD5BLOCK MD5Block = MYALLOC0(sizeof(MD5BLOCK)); // Set the data to read to the specified run length cbRead = dwRunLength; // Get handle to the crypto provider if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { printf(">>> ERROR: fileshot.c: md5Block: CryptAcquireContext"); return MD5Block; } // Initiate hashing for stream of data using MD5 algorithm if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { printf(">>> ERROR: fileshot.c: md5Block: CryptCreateHash"); return MD5Block; } // Add the data to the hash object if (!CryptHashData(hHash, rgbFile, cbRead, 0)) { CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); printf(">>> ERROR: fileshot.c: md5Block: CryptHashData"); return MD5Block; } // Retrieve the hash if (!CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) { printf(">>> ERROR: fileshot.c: md5Block: CryptGetHashParam"); } // Copy the hash to the MD5BLOCK (stored as a BYTE) i = 0; while (i < MD5LEN) { MD5Block->bMD5Hash[i] = rgbHash[i]; i++; } // Set next MD5Block to NULL for the current working MD5BLOCK MD5Block->lpNextMD5Block = NULL; // Return the MD5BLOCK (the first/father) return MD5Block; }
//----------------------------------------------------------------- // Block hashing: Append a MD5BLOCK to the last MD5BLOCK //----------------------------------------------------------------- VOID pushBlock(LPMD5BLOCK firstMD5Block, LPMD5BLOCK MD5Block) { LPMD5BLOCK current = firstMD5Block; // Find the last MD5BLOCK in list while (current->lpNextMD5Block != NULL) { current = current->lpNextMD5Block; } // Allocate space, append populated MD5BLOCK and set the next to NULL current->lpNextMD5Block = MYALLOC0(sizeof(MD5BLOCK)); current->lpNextMD5Block = MD5Block; current->lpNextMD5Block->lpNextMD5Block = NULL; }
// ---------------------------------------------------------------------- // Display snapshot overview to standard output // ---------------------------------------------------------------------- VOID DisplayShotInfo(LPSNAPSHOT lpShot) { LPTSTR lpszInfoBox; lpszInfoBox = MYALLOC0(SIZEOF_INFOBOX * sizeof(TCHAR)); _sntprintf(lpszInfoBox, SIZEOF_INFOBOX, TEXT(" %s %u\n %s %u\n %s %u\n %s %u\n\0"), asLangTexts[iszTextKey].lpszText, lpShot->stCounts.cKeys, asLangTexts[iszTextValue].lpszText, lpShot->stCounts.cValues, asLangTexts[iszTextDir].lpszText, lpShot->stCounts.cDirs, asLangTexts[iszTextFile].lpszText, lpShot->stCounts.cFiles ); lpszInfoBox[SIZEOF_INFOBOX - 1] = (TCHAR)'\0'; // safety NULL char printf(" > %s\n", "Snapshot overview:"); wprintf(L"%s", lpszInfoBox); MYFREE(lpszInfoBox); }
BOOL SetSnapRegs(HWND hDlg) //tfx 保存信息到配置文件 { BYTE nFlag; LPSTR lpString; HANDLE hTest; //1.8.2,someone do not want to create a regshot.ini when there isn't one. :O hTest = CreateFile(lpRegshotIni,GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hTest==INVALID_HANDLE_VALUE) return FALSE; CloseHandle(hTest); //nFlag=(BYTE)(SendMessage(GetDlgItem(hDlg,IDC_RADIO1),BM_GETCHECK,(WPARAM)0,(LPARAM)0) //1.7 // |SendMessage(GetDlgItem(hDlg,IDC_RADIO2),BM_GETCHECK,(WPARAM)0,(LPARAM)0)<<1 // |SendMessage(GetDlgItem(hDlg,IDC_CHECKDIR),BM_GETCHECK,(WPARAM)0,(LPARAM)0)<<2); nFlag=(BYTE)(SendMessage(GetDlgItem(hDlg,IDC_RADIO1),BM_GETCHECK,(WPARAM)0,(LPARAM)0)| SendMessage(GetDlgItem(hDlg,IDC_CHECKDIR),BM_GETCHECK,(WPARAM)0,(LPARAM)0)<<1); lpString=MYALLOC0(EXTDIRLEN+2); //sprintf(lpString,"%s=%d",INI_FLAG,nFlag); //1.7 solokey //WritePrivateProfileSection(INI_SETUP,lpString,lpRegshotIni); //1.7 solokey ,can only have one key. //1.8.1 sprintf(lpString,"%d",nFlag); WritePrivateProfileString(INI_SETUP,INI_FLAG,lpString,lpRegshotIni); sprintf(lpString,"%d",bUseLongRegHead); WritePrivateProfileString(INI_SETUP,INI_USELONGREGHEAD,lpString,lpRegshotIni); if(GetDlgItemText(hDlg,IDC_EDITDIR,lpString,EXTDIRLEN+2)!=0) WritePrivateProfileString(INI_SETUP,INI_EXTDIR,lpString,lpRegshotIni); if(GetDlgItemText(hDlg,IDC_EDITPATH,lpString,MAX_PATH)!=0) WritePrivateProfileString(INI_SETUP,INI_OUTDIR,lpString,lpRegshotIni); MYFREE(lpString); MYFREE(lpRegshotIni); MYFREE(lpSnapRegsStr); MYFREE(lpSnapFilesStr); MYFREE(lpSnapKey); MYFREE(lpSnapReturn); return TRUE; }
// ---------------------------------------------------------------------- // Create DFXML and RegXML reports of system changes between 2 snapshots // ---------------------------------------------------------------------- BOOL OpenAPXMLReport(LPTSTR lpszReportBaseName) { LPTSTR lpszOutputPath; LPTSTR lpszAPXMLExtension = TEXT(".apxml"); size_t cchString; // Get the current working directory for the APXML report lpszOutputPath = MYALLOC0(MAX_PATH * sizeof(TCHAR)); GetCurrentDirectory(MAX_PATH + 1, lpszOutputPath); // Add a backslash to the current working directory cchString = _tcslen(lpszOutputPath); if ((0 < cchString) && ((TCHAR)'\\' != *(lpszOutputPath + cchString - 1))) { *(lpszOutputPath + cchString) = (TCHAR)'\\'; *(lpszOutputPath + cchString + 1) = (TCHAR)'\0'; cchString++; } // Append APXML report base name to output path _tcscat(lpszOutputPath, lpszReportBaseName); // Append APXML file extension _tcscat(lpszOutputPath, lpszAPXMLExtension); // Inform user of the output file printf(" > APXML output: %ws\n", lpszOutputPath); hFileAPXML = CreateFile(lpszOutputPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); // All done. Free stuff. Return True. MYFREE(lpszOutputPath); return TRUE; }
// ---------------------------------------------------------------------- // Display snapshot comaprison results to standard output // ---------------------------------------------------------------------- VOID DisplayResultInfo() { LPTSTR lpszInfoBox; lpszInfoBox = MYALLOC0(SIZEOF_INFOBOX * sizeof(TCHAR)); _sntprintf(lpszInfoBox, SIZEOF_INFOBOX, TEXT(" %s %u\n %s %u\n %s %u\n %s %u\n %s %u\n %s %u\n %s %u\n %s %u\n %s %u\n %s %u\n %s %u\n %s %u\n\0"), asLangTexts[iszTextKeyAdd].lpszText, CompareResult.stcAdded.cKeys, asLangTexts[iszTextKeyDel].lpszText, CompareResult.stcDeleted.cKeys, asLangTexts[iszTextValAdd].lpszText, CompareResult.stcAdded.cValues, asLangTexts[iszTextValModi].lpszText, CompareResult.stcModified.cValues, asLangTexts[iszTextValDel].lpszText, CompareResult.stcDeleted.cValues, asLangTexts[iszTextDirAdd].lpszText, CompareResult.stcAdded.cDirs, asLangTexts[iszTextDirModi].lpszText, CompareResult.stcModified.cDirs, asLangTexts[iszTextDirDel].lpszText, CompareResult.stcDeleted.cDirs, asLangTexts[iszTextFileAdd].lpszText, CompareResult.stcAdded.cFiles, asLangTexts[iszTextFileModi].lpszText, CompareResult.stcModified.cFiles, asLangTexts[iszTextFileDel].lpszText, CompareResult.stcDeleted.cFiles, asLangTexts[iszTextTotal].lpszText, CompareResult.stcChanged.cAll ); lpszInfoBox[SIZEOF_INFOBOX - 1] = (TCHAR)'\0'; // safety NULL char printf(" > %s\n", "Results overview:"); wprintf(L"%s", lpszInfoBox); MYFREE(lpszInfoBox); }
// ---------------------------------------------------------------------- // Get file snap shot // ---------------------------------------------------------------------- VOID GetFilesSnap(LPSNAPSHOT lpShot, LPTSTR lpszFullName, LPFILECONTENT lpFatherFC, LPFILECONTENT *lplpCaller) { LPFILECONTENT lpFC; HANDLE hFile; BOOL calculateHash = TRUE; BOOL found = FALSE; // Full dir/file name is already given // Extra local block to reduce stack usage due to recursive calls { LPTSTR lpszFindFileName; lpszFindFileName = NULL; // Get father file data if not already provided (=called from FileShot) // lpFatherFC only equals "C:\" and is called once at start if (NULL == lpFatherFC) { // Check if file is to be GENERIC excluded if ((NULL == lpszFullName) || (((TCHAR)'.' == lpszFullName[0]) // fast exclusion for 99% of the cases && ((0 == _tcscmp(lpszFullName, TEXT("."))) || (0 == _tcscmp(lpszFullName, TEXT("..")))))) { return; } // Create new file content lpFatherFC = MYALLOC0(sizeof(FILECONTENT)); // Set file name length lpFatherFC->cchFileName = _tcslen(lpszFullName); // Copy file name to new buffer for directory search and more lpszFindFileName = MYALLOC((lpFatherFC->cchFileName + 4 + 1) * sizeof(TCHAR)); // +4 for "\*.*" search when directory (later in routine) _tcscpy(lpszFindFileName, lpszFullName); // Special case if root dir of a drive was specified, needs trailing backslash otherwise current dir of that drive is used if ((TCHAR)':' == lpszFindFileName[lpFatherFC->cchFileName - 1]) { lpszFindFileName[lpFatherFC->cchFileName] = (TCHAR)'\\'; lpszFindFileName[lpFatherFC->cchFileName + 1] = (TCHAR)'\0'; } //printf("lpszFullName: %ws\n", lpszFullName); //printf("lpszFindFileName: %ws\n", lpszFindFileName); hFile = FindFirstFile(lpszFullName, &FindData); if (INVALID_HANDLE_VALUE != hFile) { FindClose(hFile); } else { // Workaround for some cases in Windows Vista and later ZeroMemory(&FindData, sizeof(FindData)); hFile = CreateFile(lpszFullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (INVALID_HANDLE_VALUE != hFile) { BY_HANDLE_FILE_INFORMATION FileInformation; BOOL bResult; bResult = GetFileInformationByHandle(hFile, &FileInformation); if (bResult) { FindData.dwFileAttributes = FileInformation.dwFileAttributes; FindData.ftCreationTime = FileInformation.ftCreationTime; FindData.ftLastAccessTime = FileInformation.ftLastAccessTime; FindData.ftLastWriteTime = FileInformation.ftLastWriteTime; FindData.nFileSizeHigh = FileInformation.nFileSizeHigh; FindData.nFileSizeLow = FileInformation.nFileSizeLow; } else { FindData.dwFileAttributes = GetFileAttributes(lpszFullName); if (INVALID_FILE_ATTRIBUTES == FindData.dwFileAttributes) { FindData.dwFileAttributes = 0; } bResult = GetFileTime(hFile, &FindData.ftCreationTime, &FindData.ftLastAccessTime, &FindData.ftLastWriteTime); if (!bResult) { FindData.ftCreationTime.dwLowDateTime = 0; FindData.ftCreationTime.dwHighDateTime = 0; FindData.ftLastAccessTime.dwLowDateTime = 0; FindData.ftLastAccessTime.dwHighDateTime = 0; FindData.ftLastWriteTime.dwLowDateTime = 0; FindData.ftLastWriteTime.dwHighDateTime = 0; } FindData.nFileSizeLow = GetFileSize(hFile, &FindData.nFileSizeHigh); if (INVALID_FILE_SIZE == FindData.nFileSizeLow) { FindData.nFileSizeHigh = 0; FindData.nFileSizeLow = 0; } } CloseHandle(hFile); } } // Remove previously added backslash (if any) lpszFindFileName[lpFatherFC->cchFileName] = (TCHAR)'\0'; // Copy pointer to current file into caller's pointer if (NULL != lplpCaller) { *lplpCaller = lpFatherFC; } // Increase dir/file count if (ISFILE(FindData.dwFileAttributes)) { lpShot->stCounts.cFiles++; } else { lpShot->stCounts.cDirs++; } // Copy file name lpFatherFC->lpszFileName = MYALLOC((lpFatherFC->cchFileName + 1) * sizeof(TCHAR)); _tcscpy(lpFatherFC->lpszFileName, lpszFullName); // Copy file data lpFatherFC->nWriteDateTimeLow = FindData.ftLastWriteTime.dwLowDateTime; lpFatherFC->nWriteDateTimeHigh = FindData.ftLastWriteTime.dwHighDateTime; lpFatherFC->nAccessDateTimeLow = FindData.ftLastWriteTime.dwLowDateTime; lpFatherFC->nAccessDateTimeHigh = FindData.ftLastWriteTime.dwHighDateTime; lpFatherFC->nFileSizeLow = FindData.nFileSizeLow; lpFatherFC->nFileSizeHigh = FindData.nFileSizeHigh; lpFatherFC->nFileAttributes = FindData.dwFileAttributes; // Set "lpFirstSubFC" pointer for storing the first child's pointer lplpCaller = &lpFatherFC->lpFirstSubFC; } // If father is a file, then leave (=special case when called from FileShot) if (ISFILE(lpFatherFC->nFileAttributes)) { if (NULL != lpszFindFileName) { MYFREE(lpszFindFileName); } return; } // Process all entries of directory // a) Create search pattern and start search if (NULL == lpszFindFileName) { lpszFindFileName = lpszFullName; } _tcscat(lpszFindFileName, TEXT("\\*.*")); hFile = FindFirstFile(lpszFindFileName, &FindData); if (lpszFindFileName != lpszFullName) { MYFREE(lpszFindFileName); } } // End of extra local block if (INVALID_HANDLE_VALUE == hFile) { // error: nothing in dir, no access, etc. //printf(">>> ERROR: fileshot.c: getFileSnap: INVALID_HANDLE_VALUE: %ws\n", lpszFullName); return; } // b) process entry then find next do { lpszFullName = NULL; //BOOL calculateHash = TRUE; //BOOL found = FALSE; // Check if file is to be GENERIC excluded (dot dirs) if ((NULL == FindData.cFileName) || (((TCHAR)'.' == FindData.cFileName[0]) // fast exclusion for 99% of the cases && ((0 == _tcscmp(FindData.cFileName, TEXT("."))) || (0 == _tcscmp(FindData.cFileName, TEXT("..")))))) { continue; // ignore this entry and continue with next file } // Create new file content lpFC = MYALLOC0(sizeof(FILECONTENT)); // Set father of current key lpFC->lpFatherFC = lpFatherFC; // Set file name length lpFC->cchFileName = _tcslen(FindData.cFileName); // Allocate memory copy file name to FILECONTENT lpFC->lpszFileName = MYALLOC0((lpFC->cchFileName + 1) * sizeof(TCHAR)); _tcscpy(lpFC->lpszFileName, FindData.cFileName); // Static blacklist for directories if (ISDIR(FindData.dwFileAttributes)) { if (performStaticBlacklisting) { LPTSTR lpszFullPath; lpszFullPath = GetWholeFileName(lpFC, 4); found = TrieSearchPath(blacklistDIRS->children, lpszFullPath); if (found) { lpShot->stCounts.cFilesBlacklist++; MYFREE(lpszFullPath); FreeAllFileContents(lpFC); // Increase value count for display purposes lpShot->stCounts.cDirsBlacklist++; // Ignore this entry and continue with next brother value continue; } else { MYFREE(lpszFullPath); } } } // Check if the file system entry is a symbolic link // If so, skip as it actually resides somewhere else on the file system! if (ISSYM(FindData.dwFileAttributes)) { if (ISFILE(FindData.dwFileAttributes)) { lpShot->stCounts.cFilesBlacklist++; } else { lpShot->stCounts.cDirsBlacklist++; } continue; } // Blacklisting implementation for files if (ISFILE(FindData.dwFileAttributes)) { if (dwBlacklist == 1) { // First snapshot, therefore populate the Trie (Prefix Tree) // Get the full file path LPTSTR lpszFullPath; lpszFullPath = GetWholeFileName(lpFC, 4); // Add full path to file blacklist prefix tree, then free path TrieAdd(&blacklistFILES, lpszFullPath); MYFREE(lpszFullPath); // Increase value count for display purposes lpShot->stCounts.cFiles++; // Ignore this entry and continue with next brother value //continue; } else if (dwBlacklist == 2) { // Not the first snapshot, so either: // 1) If blacklisting enabled: Ignore file if its in the blacklist // 2) If hashing enabled (and not blacklisting): Mark file as not to be hashed LPTSTR lpszFullPath; lpszFullPath = GetWholeFileName(lpFC, 4); found = TrieSearchPath(blacklistFILES->children, lpszFullPath); if (found) { if (performDynamicBlacklisting) { MYFREE(lpszFullPath); FreeAllFileContents(lpFC); // Increase value count for display purposes lpShot->stCounts.cFilesBlacklist++; // Ignore this entry and continue with next brother value continue; } if (performSHA1Hashing || performMD5Hashing) { lpShot->stCounts.cFiles++; MYFREE(lpszFullPath); calculateHash = FALSE; } } else { MYFREE(lpszFullPath); } } } // Copy pointer to current file into caller's pointer if (NULL != lplpCaller) { *lplpCaller = lpFC; } // Increase dir/file count if (ISFILE(FindData.dwFileAttributes)) { lpShot->stCounts.cFiles++; } else { lpShot->stCounts.cDirs++; } // Copy file data lpFC->nWriteDateTimeLow = FindData.ftLastWriteTime.dwLowDateTime; lpFC->nWriteDateTimeHigh = FindData.ftLastWriteTime.dwHighDateTime; lpFC->nAccessDateTimeLow = FindData.ftLastWriteTime.dwLowDateTime; lpFC->nAccessDateTimeHigh = FindData.ftLastWriteTime.dwHighDateTime; lpFC->nFileSizeLow = FindData.nFileSizeLow; lpFC->nFileSizeHigh = FindData.nFileSizeHigh; lpFC->nFileAttributes = FindData.dwFileAttributes; // Calculate file hash (computationally intensive!) // This should only be executed in the following scenarios: // 1) If the file system entry is a data file // 2) If the data file is not blacklisted (previously known) if (ISFILE(FindData.dwFileAttributes)) { if (dwBlacklist == 2 && calculateHash) { if (performSHA1Hashing) { lpFC->cchSHA1 = 40; lpFC->lpszSHA1 = MYALLOC((lpFC->cchSHA1 + 1) * sizeof(TCHAR)); _tcscpy(lpFC->lpszSHA1, CalculateSHA1(GetWholeFileName(lpFC, 4))); } if (performMD5Hashing) { lpFC->cchMD5 = 32; lpFC->lpszMD5 = MYALLOC((lpFC->cchMD5 + 1) * sizeof(TCHAR)); _tcscpy(lpFC->lpszMD5, CalculateMD5(GetWholeFileName(lpFC, 4))); } if (performMD5BlockHashing) { LPMD5BLOCK theMD5Block = CalculateMD5Blocks(GetWholeFileName(lpFC, 4), dwHashBlockSize); lpFC->lpMD5Block = MYALLOC0(sizeof(MD5BLOCK)); lpFC->lpMD5Block = theMD5Block; } } } // Print file system shot status if ((dwBlacklist == 2 && performDynamicBlacklisting) || (performStaticBlacklisting)) { printf(" > Dirs: %d Files: %d Blacklisted Dirs: %d Blacklisted Files: %d\r", lpShot->stCounts.cDirs, lpShot->stCounts.cFiles, lpShot->stCounts.cDirsBlacklist, lpShot->stCounts.cFilesBlacklist); } else { printf(" > Dirs: %d Files: %d\r", lpShot->stCounts.cDirs, lpShot->stCounts.cFiles); } // ATTENTION!!! FindData will be INVALID from this point on, due to recursive calls // If the entry is a directory, then do a recursive call for it // Pass this entry as father and "lpFirstSubFC" pointer for storing the first child's pointer if (ISDIR(lpFC->nFileAttributes)) { if (NULL == lpszFullName) { lpszFullName = GetWholeFileName(lpFC, 4); // +4 for "\*.*" search (in recursive call) } GetFilesSnap(lpShot, lpszFullName, lpFC, &lpFC->lpFirstSubFC); } if (NULL != lpszFullName) { MYFREE(lpszFullName); } // Set "lpBrotherFC" pointer for storing the next brother's pointer lplpCaller = &lpFC->lpBrotherFC; } while (FindNextFile(hFile, &FindData)); FindClose(hFile); }
//----------------------------------------------------------------- // Calculate the MD5 hash value from a previously matched file name //----------------------------------------------------------------- LPTSTR CalculateMD5(LPTSTR FileName) { HANDLE hashFile = NULL; BOOL bResult = FALSE; HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; DWORD cbRead = 0; DWORD cbHash = MD5LEN; BYTE rgbFile[BUFSIZE]; BYTE rgbHash[MD5LEN]; CHAR rgbDigits[] = "0123456789abcdef"; LPTSTR md5HashString; DWORD i; // Open the file to perform hash hashFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (INVALID_HANDLE_VALUE == hashFile) { return TEXT("ERROR_OPENING_FILE\0"); } // Get handle to the crypto provider if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { CloseHandle(hashFile); return TEXT("HASHING_FAILED\0"); } if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { CloseHandle(hashFile); return TEXT("HASHING_FAILED\0"); } while (bResult = ReadFile(hashFile, rgbFile, BUFSIZE, &cbRead, NULL)) { if (0 == cbRead) { break; } if (!CryptHashData(hHash, rgbFile, cbRead, 0)) { CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hashFile); return TEXT("HASHING_FAILED\0"); } } if (!bResult) { CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hashFile); return TEXT("ERROR_READING_FILE\0"); } // Finally got here with no errors, now calculate the SHA1 hash value md5HashString = MYALLOC0((MD5LEN * 2 + 1) * sizeof(TCHAR)); _tcscpy_s(md5HashString, 1, TEXT("")); if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) { for (i = 0; i < cbHash; i++) { _sntprintf(md5HashString + (i * 2), 2, TEXT("%02x\0"), rgbHash[i]); } } CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); CloseHandle(hashFile); return md5HashString; }
//----------------------------------------------------------------- // Block hashing: From a file, calculate the MD5 hash value for // a block size of 512 or 4096 bytes in length //----------------------------------------------------------------- LPMD5BLOCK CalculateMD5Blocks(LPTSTR FileName, DWORD dwBlockSize) { HANDLE hashFile = NULL; BOOL bResult = FALSE; DWORD cbRead = 0; CHAR rgbDigits[] = "0123456789abcdef"; DWORD dwFileOffset = 0; BYTE* rgbFile; LPMD5BLOCK MD5Block; LPMD5BLOCK firstMD5Block; // Allocate space for the MD5BLOCK and actual block of data firstMD5Block = MYALLOC0(sizeof(LPMD5BLOCK)); rgbFile = MYALLOC0(dwBlockSize); // Open the file to perform hash hashFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); // Check for an invalid file handle if (INVALID_HANDLE_VALUE == hashFile) { printf(">>> ERROR: CalculateMD5Blocks: ERROR_OPENING_FILE"); } // Read input file in 512 byte blocks; calculate MD5 and entropy for each block while (bResult = ReadFile(hashFile, rgbFile, dwBlockSize, &cbRead, NULL)) { INT *hist; INT histlen; DOUBLE H; LPTSTR lpszEntropy; // If number of read bytes is 0, break loop due to EOF if (0 == cbRead) { break; } // Calculate the MD5 hash value of block MD5Block = md5Block(rgbFile, dwFileOffset, cbRead); // Calculate the entropy value of block // First get the histogram hist = MYALLOC0(cbRead * sizeof(INT)); histlen = makehist(rgbFile, hist, cbRead); H = entropy(hist, histlen, cbRead); // Second, calculate the actual block entropy lpszEntropy = MYALLOC0(10 * sizeof(TCHAR)); swprintf_s(lpszEntropy, 10, L"%f", H); // Add entropy value to block structure MD5Block->fEntropy = H; // Check block structure was created if (MD5Block == NULL) { printf(">>> ERROR: CalculateMD5Blocks: Error creating MD5BLOCK"); break; } // Add block to FILECONTENT if (dwFileOffset == 0) { firstMD5Block = MD5Block; } else { pushBlock(firstMD5Block, MD5Block); } // Increase the file offset based on number of bytes read dwFileOffset += cbRead; } // Close the file handle CloseHandle(hashFile); // Return the first block (linked to all other blocks) return firstMD5Block; }
// ---------------------------------------------------------------------- // File Shot Engine // ---------------------------------------------------------------------- VOID FileShot(LPSNAPSHOT lpShot) { UINT cchExtDir; // Determine the Windows directory for file system scanning lpszExtDir = MYALLOC0(MAX_PATH * sizeof(TCHAR)); lpszWindowsDirName = MYALLOC0(MAX_PATH * sizeof(TCHAR)); GetSystemWindowsDirectory(lpszWindowsDirName, MAX_PATH); // length incl. NULL character GetVolumePathName(lpszWindowsDirName, lpszExtDir, MAX_PATH); lpszExtDir[MAX_PATH] = (TCHAR)'\0'; // Set the length of the Windows directory cchExtDir = _tcslen(lpszExtDir); //printf("%ws\n", lpszExtDir); if (0 < cchExtDir) { LPHEADFILE *lplpHFPrev; LPTSTR lpszSubExtDir; size_t i; lplpHFPrev = &lpShot->lpHF; lpszSubExtDir = lpszExtDir; for (i = 0; i <= cchExtDir; i++) { // Split each directory in string if (((TCHAR)';' == lpszExtDir[i]) || ((TCHAR)'\0' == lpszExtDir[i])) { LPHEADFILE lpHF; size_t j; lpszExtDir[i] = (TCHAR)'\0'; j = i; // remove all trailing spaces and backslashes while (0 < j) { --j; if (((TCHAR)'\\' == lpszExtDir[j]) || ((TCHAR)' ' == lpszExtDir[j])) { lpszExtDir[j] = (TCHAR)'\0'; } else { break; } } // if anything is left then process this directory if ((0 < j) && ((TCHAR)'\0' != lpszExtDir[j])) { lpHF = MYALLOC0(sizeof(HEADFILE)); *lplpHFPrev = lpHF; lplpHFPrev = &lpHF->lpBrotherHF; GetFilesSnap(lpShot, lpszSubExtDir, NULL, &lpHF->lpFirstFC); } lpszSubExtDir = &lpszExtDir[i + 1]; } } } // Update total count of all items lpShot->stCounts.cAll = lpShot->stCounts.cDirs + lpShot->stCounts.cFiles; // Print final file system shot count if ((dwBlacklist == 2 && performDynamicBlacklisting) || (performStaticBlacklisting)) { printf(" > Dirs: %d Files: %d Blacklisted Dirs: %d Blacklisted Files: %d\n", lpShot->stCounts.cDirs, lpShot->stCounts.cFiles, lpShot->stCounts.cDirsBlacklist, lpShot->stCounts.cFilesBlacklist); } else { printf(" > Dirs: %d Files: %d\n", lpShot->stCounts.cDirs, lpShot->stCounts.cFiles); } }
BOOL GetSnapRegs(HWND hDlg) //tfx 取配置文件信息 { int i; BYTE nFlag; lpSnapKey=MYALLOC(20); lpSnapRegs=MYALLOC0(sizeof(LPSTR)*MAXREGSHOT); lpSnapRegsStr=MYALLOC0(SIZEOF_REGSHOT); if(GetPrivateProfileSection(INI_SKIPREGKEY,lpSnapRegsStr,SIZEOF_REGSHOT,lpRegshotIni)>0) { for(i=0;i<MAXREGSHOT-1;i++) { sprintf(lpSnapKey,"%d%s",i,"="); if((lpSnapReturn=AtPos(lpSnapRegsStr,lpSnapKey,SIZEOF_REGSHOT))!=NULL) { *(lpSnapRegs+i)=(DWORD)lpSnapReturn; //dwSnapFiles++; } else { break; } } } lpSnapFiles=MYALLOC0(sizeof(LPSTR)*MAXREGSHOT); lpSnapFilesStr=MYALLOC0(SIZEOF_REGSHOT); if(GetPrivateProfileSection(INI_SKIPDIR,lpSnapFilesStr,SIZEOF_REGSHOT,lpRegshotIni)) { for(i=0;i<MAXREGSHOT-1;i++) { sprintf(lpSnapKey,"%d%s",i,"="); if((lpSnapReturn=AtPos(lpSnapFilesStr,lpSnapKey,SIZEOF_REGSHOT))!=NULL) { *(lpSnapFiles+i)=(DWORD)lpSnapReturn; //dwSnapFiles++; } else { break; } } } nFlag=(BYTE)GetPrivateProfileInt(INI_SETUP,INI_FLAG,1,lpRegshotIni); //default from 0 to 1 in 1.8.2 (TEXT) //if(nFlag!=0) { SendMessage(GetDlgItem(hDlg,IDC_RADIO1),BM_SETCHECK,(WPARAM)(nFlag&0x01),(LPARAM)0); SendMessage(GetDlgItem(hDlg,IDC_RADIO2),BM_SETCHECK,(WPARAM)((nFlag&0x01)^0x01),(LPARAM)0); //SendMessage(GetDlgItem(hDlg,IDC_CHECKDIR),BM_SETCHECK,(WPARAM)((nFlag&0x04)>>1),(LPARAM)0); //1.7 SendMessage(GetDlgItem(hDlg,IDC_CHECKDIR),BM_SETCHECK,(WPARAM)((nFlag&0x02)>>1),(LPARAM)0); } /*else delete in 1.8.1 { SendMessage(GetDlgItem(hDlg,IDC_RADIO1),BM_SETCHECK,(WPARAM)0x01,(LPARAM)0); SendMessage(GetDlgItem(hDlg,IDC_RADIO2),BM_SETCHECK,(WPARAM)0x00,(LPARAM)0); SendMessage(GetDlgItem(hDlg,IDC_CHECKDIR),BM_SETCHECK,(WPARAM)0x00,(LPARAM)0); } */ //added in 1.8.1 for compatible with undoreg1.46 bUseLongRegHead=GetPrivateProfileInt(INI_SETUP,INI_USELONGREGHEAD,0,lpRegshotIni)!=0 ? TRUE:FALSE; if(GetPrivateProfileString(INI_SETUP,INI_EXTDIR,NULL,lpExtDir,MAX_PATH,lpRegshotIni)!=0) SetDlgItemText(hDlg,IDC_EDITDIR,lpExtDir); else SetDlgItemText(hDlg,IDC_EDITDIR,lpWindowsDirName); if(GetPrivateProfileString(INI_SETUP,INI_OUTDIR,NULL,lpOutputpath,MAX_PATH,lpRegshotIni)!=0) SetDlgItemText(hDlg,IDC_EDITPATH,lpOutputpath); else SetDlgItemText(hDlg,IDC_EDITPATH,lpTempPath); SendMessage(hDlg,WM_COMMAND,(WPARAM)IDC_CHECKDIR,(LPARAM)0); return TRUE; }