int main() { char buf[1024]; char c; int i; printf("请输入字符串:\n"); gets(buf); for(i = 0;i < strlen(buf);i++) { if(!isupper(buf[i]) && !islower(buf[i])) { perror("字符串只可以包含大小写字母!\n"); exit(1); } } LoadHashTable(buf); if(Locate(buf, c)) { printf("第一个只出现一次的字符为:"); putchar(c); } else perror("没有出现一次的字母!"); printf("\n"); return 0; }
static int MD5MatchTest01(void) { ROHashTable *hash = ROHashInit(4, 16); if (hash == NULL) { return 0; } if (LoadHashTable(hash, "d80f93a93dc5f3ee945704754d6e0a36", "file", 1, DETECT_FILEMD5) != 1) return 0; if (LoadHashTable(hash, "92a49985b384f0d993a36e4c2d45e206", "file", 2, DETECT_FILEMD5) != 1) return 0; if (LoadHashTable(hash, "11adeaacc8c309815f7bc3e33888f281", "file", 3, DETECT_FILEMD5) != 1) return 0; if (LoadHashTable(hash, "22e10a8fe02344ade0bea8836a1714af", "file", 4, DETECT_FILEMD5) != 1) return 0; if (LoadHashTable(hash, "c3db2cbf02c68f073afcaee5634677bc", "file", 5, DETECT_FILEMD5) != 1) return 0; if (LoadHashTable(hash, "7ed095da259638f42402fb9e74287a17", "file", 6, DETECT_FILEMD5) != 1) return 0; if (ROHashInitFinalize(hash) != 1) { return 0; } if (MD5MatchLookupString(hash, "d80f93a93dc5f3ee945704754d6e0a36") != 1) return 0; if (MD5MatchLookupString(hash, "92a49985b384f0d993a36e4c2d45e206") != 1) return 0; if (MD5MatchLookupString(hash, "11adeaacc8c309815f7bc3e33888f281") != 1) return 0; if (MD5MatchLookupString(hash, "22e10a8fe02344ade0bea8836a1714af") != 1) return 0; if (MD5MatchLookupString(hash, "c3db2cbf02c68f073afcaee5634677bc") != 1) return 0; if (MD5MatchLookupString(hash, "7ed095da259638f42402fb9e74287a17") != 1) return 0; /* shouldn't match */ if (MD5MatchLookupString(hash, "33333333333333333333333333333333") == 1) return 0; ROHashFree(hash); return 1; }
bool WINAPI SFileOpenArchive( const char * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMpq) { TFileStream * pStream = NULL; // Open file stream TMPQArchive * ha = NULL; // Archive handle ULONGLONG FileSize = 0; // Size of the file int nError = ERROR_SUCCESS; // Verify the parameters if (szMpqName == NULL || *szMpqName == 0 || phMpq == NULL) nError = ERROR_INVALID_PARAMETER; // One time initialization of MPQ cryptography InitializeMpqCryptography(); dwPriority = dwPriority; // Open the MPQ archive file if (nError == ERROR_SUCCESS) { if (!(dwFlags & MPQ_OPEN_ENCRYPTED)) { pStream = FileStream_OpenFile(szMpqName, (dwFlags & MPQ_OPEN_READ_ONLY) ? false : true); if (pStream == NULL) nError = GetLastError(); } else { pStream = FileStream_OpenEncrypted(szMpqName); if (pStream == NULL) nError = GetLastError(); } } // Allocate the MPQhandle if (nError == ERROR_SUCCESS) { FileStream_GetSize(pStream, FileSize); if ((ha = ALLOCMEM(TMPQArchive, 1)) == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; } // Initialize handle structure and allocate structure for MPQ header if (nError == ERROR_SUCCESS) { memset(ha, 0, sizeof(TMPQArchive)); ha->pStream = pStream; pStream = NULL; // Remember if the archive is open for write if (ha->pStream->StreamFlags & (STREAM_FLAG_READ_ONLY | STREAM_FLAG_ENCRYPTED_FILE)) ha->dwFlags |= MPQ_FLAG_READ_ONLY; // Also remember if we shall check sector CRCs when reading file if (dwFlags & MPQ_OPEN_CHECK_SECTOR_CRC) ha->dwFlags |= MPQ_FLAG_CHECK_SECTOR_CRC; } // Find the offset of MPQ header within the file if (nError == ERROR_SUCCESS) { ULONGLONG SearchPos = 0; DWORD dwHeaderID; while (SearchPos < FileSize) { DWORD dwBytesAvailable = MPQ_HEADER_SIZE_V4; // Cut the bytes available, if needed if ((FileSize - SearchPos) < MPQ_HEADER_SIZE_V4) dwBytesAvailable = (DWORD)(FileSize - SearchPos); // Read the eventual MPQ header if (!FileStream_Read(ha->pStream, &SearchPos, ha->HeaderData, dwBytesAvailable)) { nError = GetLastError(); break; } // There are AVI files from Warcraft III with 'MPQ' extension. if (SearchPos == 0 && IsAviFile(ha->HeaderData)) { nError = ERROR_AVI_FILE; break; } // If there is the MPQ user data signature, process it dwHeaderID = BSWAP_INT32_UNSIGNED(*(LPDWORD)ha->HeaderData); if (dwHeaderID == ID_MPQ_USERDATA && ha->pUserData == NULL) { // Ignore the MPQ user data completely if the caller wants to open the MPQ as V1.0 if ((dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0) { // Fill the user data header ha->pUserData = &ha->UserData; memcpy(ha->pUserData, ha->HeaderData, sizeof(TMPQUserData)); BSWAP_TMPQUSERDATA(ha->pUserData); // Remember the position of the user data and continue search ha->UserDataPos = SearchPos; SearchPos += ha->pUserData->dwHeaderOffs; continue; } } // There must be MPQ header signature if (dwHeaderID == ID_MPQ) { // Save the position where the MPQ header has been found if (ha->pUserData == NULL) ha->UserDataPos = SearchPos; ha->pHeader = (TMPQHeader *)ha->HeaderData; ha->MpqPos = SearchPos; // Now convert the header to version 4 BSWAP_TMPQHEADER(ha->pHeader); ConvertMpqHeaderToFormat4(ha, FileSize, dwFlags); break; } // Move to the next possible offset SearchPos += 0x200; } // If we haven't found MPQ header in the file, it's an error if (ha->pHeader == NULL) nError = ERROR_BAD_FORMAT; } // Fix table positions according to format if (nError == ERROR_SUCCESS) { // W3x Map Protectors use the fact that War3's Storm.dll ignores the MPQ user data, // and probably ignores the MPQ format version as well. The trick is to // fake MPQ format 2, with an improper hi-word position of hash table and block table // We can overcome such protectors by forcing opening the archive as MPQ v 1.0 if (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) { ha->pHeader->wFormatVersion = MPQ_FORMAT_VERSION_1; ha->pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1; ha->dwFlags |= MPQ_FLAG_READ_ONLY; ha->pUserData = NULL; } // Both MPQ_OPEN_NO_LISTFILE or MPQ_OPEN_NO_ATTRIBUTES trigger read only mode if (dwFlags & (MPQ_OPEN_NO_LISTFILE | MPQ_OPEN_NO_ATTRIBUTES)) ha->dwFlags |= MPQ_FLAG_READ_ONLY; // Set the size of file sector ha->dwSectorSize = (0x200 << ha->pHeader->wSectorSize); // Verify if any of the tables doesn't start beyond the end of the file nError = VerifyMpqTablePositions(ha, FileSize); } // Read the hash table. // "interface.MPQ.part" in trial version of World of Warcraft // has compressed block table and hash table. if (nError == ERROR_SUCCESS) { // // Note: We will not check if the hash table is properly decrypted. // Some MPQ protectors corrupt the hash table by rewriting part of it. // Hash table, the way how it works, allows arbitrary values for unused entries. // nError = LoadHashTable(ha); } // Read Het and Bet tables, if they are present if (nError == ERROR_SUCCESS) { nError = LoadHetAndBetTable(ha); if (ha->pHetTable || ha->pBetTable) ha->dwFlags |= MPQ_FLAG_READ_ONLY; } // Now, build the file table. It will be built by combining // the block table, hi-block table, (attributes) and (listfile). if (nError == ERROR_SUCCESS) { nError = BuildFileTable(ha, FileSize); } // Verify the block table, if no kind of protection was detected if (nError == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_PROTECTED) == 0) { TFileEntry * pFileTableEnd = ha->pFileTable + ha->pHeader->dwBlockTableSize; TFileEntry * pFileEntry = ha->pFileTable; // ULONGLONG ArchiveSize = 0; ULONGLONG RawFilePos; // Parse all file entries for (pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) { // If that file entry is valid, check the file position if (pFileEntry->dwFlags & MPQ_FILE_EXISTS) { // Get the 64-bit file position, // relative to the begin of the file RawFilePos = ha->MpqPos + pFileEntry->ByteOffset; // Begin of the file must be within range if (RawFilePos > FileSize) { nError = ERROR_FILE_CORRUPT; break; } // End of the file must be within range RawFilePos += pFileEntry->dwCmpSize; if (RawFilePos > FileSize) { nError = ERROR_FILE_CORRUPT; break; } // Also, we remember end of the file // if (RawFilePos > ArchiveSize) // ArchiveSize = RawFilePos; } } } // Load the "(attributes)" file and merge it to the file table if (nError == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_ATTRIBUTES) == 0) { // Ignore result of the operation. (attributes) is optional. SAttrLoadAttributes(ha); } // Load the internal listfile and include it to the file table if (nError == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_LISTFILE) == 0) { // Ignore result of the operation. (listfile) is optional. SFileAddListFile((HANDLE)ha, NULL); } // Test the indexes from BET and BET table #ifdef __STORMLIB_TEST__ if (nError == ERROR_SUCCESS) { TestNewHashBlockTables(ha); } #endif // Cleanup and exit if (nError != ERROR_SUCCESS) { FileStream_Close(pStream); FreeMPQArchive(ha); SetLastError(nError); ha = NULL; } *phMpq = ha; return (nError == ERROR_SUCCESS); }
/** * \brief Parse the filemd5, filesha1 or filesha256 keyword * * \param det_ctx pattern matcher thread local data * \param str Pointer to the user provided option * \param type the hash algorithm * * \retval hash pointer to DetectFileHashData on success * \retval NULL on failure */ static DetectFileHashData *DetectFileHashParse (const DetectEngineCtx *de_ctx, char *str, uint32_t type) { DetectFileHashData *filehash = NULL; FILE *fp = NULL; char *filename = NULL; /* We have a correct hash algorithm option */ filehash = SCMalloc(sizeof(DetectFileHashData)); if (unlikely(filehash == NULL)) goto error; memset(filehash, 0x00, sizeof(DetectFileHashData)); if (strlen(str) && str[0] == '!') { filehash->negated = 1; str++; } if (type == DETECT_FILEMD5) { filehash->hash = ROHashInit(18, 16); } else if (type == DETECT_FILESHA1) { filehash->hash = ROHashInit(18, 20); } else if (type == DETECT_FILESHA256) { filehash->hash = ROHashInit(18, 32); } if (filehash->hash == NULL) { goto error; } /* get full filename */ filename = DetectLoadCompleteSigPath(de_ctx, str); if (filename == NULL) { goto error; } char line[8192] = ""; fp = fopen(filename, "r"); if (fp == NULL) { SCLogError(SC_ERR_OPENING_RULE_FILE, "opening hash file %s: %s", filename, strerror(errno)); goto error; } int line_no = 0; while(fgets(line, (int)sizeof(line), fp) != NULL) { size_t valid = 0, len = strlen(line); line_no++; while (strchr(hexcodes, line[valid]) != NULL && valid++ < len); /* lines that do not contain sequentially any valid character are ignored */ if (valid == 0) continue; /* ignore anything after the sequence of valid characters */ line[valid] = '\0'; if (LoadHashTable(filehash->hash, line, filename, line_no, type) != 1) { goto error; } } fclose(fp); fp = NULL; if (ROHashInitFinalize(filehash->hash) != 1) { goto error; } SCLogInfo("Hash hash table size %u bytes%s", ROHashMemorySize(filehash->hash), filehash->negated ? ", negated match" : ""); SCFree(filename); return filehash; error: if (filehash != NULL) DetectFileHashFree(filehash); if (fp != NULL) fclose(fp); if (filename != NULL) SCFree(filename); return NULL; }