📄 tm_lookup.c
字号:
* * @param hdb_info Hash database to analyze * @param hash The hash type that was used to make the index. * * @return 1 on error and 0 on success */static uint8_thdb_setupindex(TSK_HDB_INFO * hdb_info, uint8_t htype){ char head[TSK_HDB_MAXLEN]; char *ptr; if ((htype != TSK_HDB_HTYPE_MD5_ID) && (htype != TSK_HDB_HTYPE_SHA1_ID)) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_setupindex: Invalid hash type : %d", htype); return 1; } if (hdb_setuphash(hdb_info, htype)) { return 1; } /* Verify the index exists, get its size, and open it */#ifdef TSK_WIN32 { HANDLE hWin; DWORD szLow, szHi; if (-1 == GetFileAttributes(hdb_info->idx_fname)) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_MISSING; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_setupindex: Error finding index file: %"PRIttocTSK, hdb_info->idx_fname); return 1; } if ((hWin = CreateFile(hdb_info->idx_fname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_OPEN; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_setupindex: Error opening index file: %"PRIttocTSK, hdb_info->idx_fname); return 1; } hdb_info->hIdx = _fdopen(_open_osfhandle((intptr_t) hWin, _O_RDONLY), "r"); if (hdb_info->hIdx == NULL) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_OPEN; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_setupindex: Error converting Windows handle to C handle"); return 1; } szLow = GetFileSize(hWin, &szHi); if (szLow == 0xffffffff) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_OPEN; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_setupindex: Error getting size of index file: %"PRIttocTSK" - %d", hdb_info->idx_fname, (int)GetLastError()); return 1; } hdb_info->idx_size = szLow | ((uint64_t) szHi << 32); }#else { struct stat sb; if (stat(hdb_info->idx_fname, &sb) < 0) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_MISSING; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_setupindex: Error finding index file: %s", hdb_info->idx_fname); return 1; } hdb_info->idx_size = sb.st_size; if (NULL == (hdb_info->hIdx = fopen(hdb_info->idx_fname, "r"))) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_OPEN; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_setupindex: Error opening index file: %s", hdb_info->idx_fname); return 1; } }#endif /* Do some testing on the first line */ if (NULL == fgets(head, TSK_HDB_MAXLEN, hdb_info->hIdx)) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_READIDX; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_setupindex: Header line of index file"); return 1; } if (strncmp(head, TSK_HDB_IDX_HEAD_STR, strlen(TSK_HDB_IDX_HEAD_STR)) != 0) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_setupindex: Invalid index file: Missing header line"); return 1; } /* Set the offset to the start of the index entries */ hdb_info->idx_off = (uint16_t) strlen(head); /* Skip the space */ ptr = &head[strlen(TSK_HDB_IDX_HEAD_STR) + 1]; ptr[strlen(ptr) - 1] = '\0'; if ((ptr[strlen(ptr) - 1] == 10) || (ptr[strlen(ptr) - 1] == 13)) { ptr[strlen(ptr) - 1] = '\0'; hdb_info->idx_llen++; // make the expected index length longer to account for different cr/nl/etc. } /* Verify the header value in the index */ if (strcmp(ptr, TSK_HDB_DBTYPE_NSRL_STR) == 0) { if ((hdb_info->db_type != TSK_HDB_DBTYPE_NSRL_ID) && (hdb_info->db_type != TSK_HDB_DBTYPE_IDXONLY_ID)) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_indexsetup: DB detected as %s, index type has NSRL", ptr); return 1; } } else if (strcmp(ptr, TSK_HDB_DBTYPE_MD5SUM_STR) == 0) { if ((hdb_info->db_type != TSK_HDB_DBTYPE_MD5SUM_ID) && (hdb_info->db_type != TSK_HDB_DBTYPE_IDXONLY_ID)) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_indexsetup: DB detected as %s, index type has MD5SUM", ptr); return 1; } } else if (strcmp(ptr, TSK_HDB_DBTYPE_HK_STR) == 0) { if ((hdb_info->db_type != TSK_HDB_DBTYPE_HK_ID) && (hdb_info->db_type != TSK_HDB_DBTYPE_IDXONLY_ID)) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_indexsetup: DB detected as %s, index type has hashkeeper", ptr); return 1; } } else if (hdb_info->db_type != TSK_HDB_DBTYPE_IDXONLY_ID) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_setupindex: Unknown Database Type in index header: %s", ptr); return 1; } /* Do some sanity checking */ if (((hdb_info->idx_size - hdb_info->idx_off) % hdb_info->idx_llen) != 0) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_CORRUPT; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_setupindex: Error, size of index file is not a multiple of row size"); return 1; } /* allocate a buffer for a row */ if ((hdb_info->idx_lbuf = tsk_malloc(hdb_info->idx_llen + 1)) == NULL) return 1; return 0;}/** * \ingroup hashdblib * Search the index for a text/ASCII hash value * * @param hdb_info Open hash database (with index) * @param hash Hash value to search for (NULL terminated string) * @param flags Flags to use in lookup * @param action Callback function to call for each hash db entry * (not called if QUICK flag is given) * @param ptr Pointer to data to pass to each callback * * @return -1 on error, 0 if hash value not found, and 1 if value was found. */int8_ttsk_hdb_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash, TSK_HDB_FLAG_ENUM flags, TSK_HDB_LOOKUP_FN action, void *ptr){ TSK_OFF_T poffset; TSK_OFF_T up; // Offset of the first byte past the upper limit that we are looking in TSK_OFF_T low; // offset of the first byte of the lower limit that we are looking in int cmp; uint8_t wasFound = 0; size_t i; uint8_t htype; /* Sanity checks on the hash input */ if (strlen(hash) == TSK_HDB_HTYPE_MD5_LEN) { htype = TSK_HDB_HTYPE_MD5_ID; } else if (strlen(hash) == TSK_HDB_HTYPE_SHA1_LEN) { htype = TSK_HDB_HTYPE_SHA1_ID; } else { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_lookup: Invalid hash length: %s", hash); return -1; } for (i = 0; i < strlen(hash); i++) { if (isxdigit((int) hash[i]) == 0) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_lookup: Invalid hash value (hex only): %s", hash); return -1; } } /* See if we have had a lookup yet -- and therefore initialized the variables */ if (hdb_info->hIdx == NULL) { if (hdb_setupindex(hdb_info, htype)) return -1; } /* Sanity check */ if (hdb_info->hash_len != strlen(hash)) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_lookup: Hash passed is different size than expected (%d vs %Zd)", hdb_info->hash_len, strlen(hash)); return -1; } low = hdb_info->idx_off; up = hdb_info->idx_size; poffset = 0; while (1) { TSK_OFF_T offset; /* If top and bottom are the same, it's not there */ if (up == low) { return 0; } /* Get the middle of the windows that we are looking at */ offset = rounddown(((up - low) / 2), hdb_info->idx_llen); /* Sanity Check */ if ((offset % hdb_info->idx_llen) != 0) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_CORRUPT; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_lookup: Error, new offset is not a multiple of the line length"); return -1; } /* The middle offset is relative to the low offset, so add them */ offset += low; /* If we didn't move, then it's not there */ if (poffset == offset) { return 0; } /* Seek to the offset and read it */ if (0 != fseeko(hdb_info->hIdx, offset, SEEK_SET)) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_READIDX; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_lookup: Error seeking in search: %" PRIuOFF, offset); return -1; } if (NULL == fgets(hdb_info->idx_lbuf, (int) hdb_info->idx_llen + 1, hdb_info->hIdx)) { if (feof(hdb_info->hIdx)) { return 0; } tsk_error_reset(); tsk_errno = TSK_ERR_HDB_READIDX; snprintf(tsk_errstr, TSK_ERRSTR_L, "Error reading index file: %lu", (unsigned long) offset); return -1; } /* Sanity Check */ if ((strlen(hdb_info->idx_lbuf) < hdb_info->idx_llen) || (hdb_info->idx_lbuf[hdb_info->hash_len] != '|')) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_CORRUPT; snprintf(tsk_errstr, TSK_ERRSTR_L, "Invalid line in index file: %lu (%s)", (unsigned long) (offset / hdb_info->idx_llen), hdb_info->idx_lbuf); return -1; } /* Set the delimter to NULL so we can treat the hash as a string */ hdb_info->idx_lbuf[hdb_info->hash_len] = '\0'; cmp = strcasecmp(hdb_info->idx_lbuf, hash); /* The one we just read is too small, so set the new lower bound * at the start of the next row */ if (cmp < 0) { low = offset + hdb_info->idx_llen; } /* The one we just read is too big, so set the upper bound at this * entry */ else if (cmp > 0) { up = offset; } /* We found it */ else { wasFound = 1; if ((flags & TSK_HDB_FLAG_QUICK) || (hdb_info->db_type == TSK_HDB_DBTYPE_IDXONLY_ID)) { return 1; } else { TSK_OFF_T tmpoff, db_off;#ifdef TSK_WIN32 db_off = _atoi64(&hdb_info->idx_lbuf[hdb_info->hash_len + 1]);#else db_off = strtoull(&hdb_info->idx_lbuf[hdb_info->hash_len + 1], NULL, 10);#endif /* Print the one that we found first */ if (hdb_info-> getentry(hdb_info, hash, db_off, flags, action, ptr)) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "hdb_lookup"); return -1; } /* there could be additional entries both before and after * this entry - but we can restrict ourselves to the up * and low bounds from our previous hunting */ tmpoff = offset - hdb_info->idx_llen; while (tmpoff >= low) { /* Break if we are at the header */ if (tmpoff <= 0) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -