temp restore
This commit is contained in:
@@ -25,5 +25,5 @@ def ClearTableRecordsWithReset(db_path, table_name):
|
||||
if __name__ == '__main__':
|
||||
# ClearTableRecordsWithReset(db_path='../src/db_ntfs_info.db', table_name='db_path')
|
||||
# ClearTableRecordsWithReset(db_path='../src/db_ntfs_info.db', table_name='db_device')
|
||||
# ClearTableRecordsWithReset(db_path='../src/db_ntfs_info.db', table_name='db_config')
|
||||
ClearTableRecordsWithReset(db_path='../src/db_ntfs_info.db', table_name='db_node')
|
||||
ClearTableRecordsWithReset(db_path='../src/db_ntfs_info.db', table_name='db_config')
|
||||
# ClearTableRecordsWithReset(db_path='../src/db_ntfs_info.db', table_name='db_node')
|
||||
|
@@ -8,9 +8,10 @@ def GetNTFSBootInfo(volume_letter):
|
||||
- Bytes per sector
|
||||
- Sectors per cluster
|
||||
- Cluster size (bytes)
|
||||
- $MFT 起始簇号
|
||||
|
||||
参数:
|
||||
volume_letter: 卷标字符串,例如 'C'
|
||||
volume_letter: str,卷标字符串,例如 'C'
|
||||
|
||||
返回:
|
||||
dict 包含上述信息
|
||||
@@ -62,10 +63,15 @@ def GetNTFSBootInfo(volume_letter):
|
||||
# 计算簇大小
|
||||
cluster_size = bytes_per_sector * sectors_per_cluster
|
||||
|
||||
# 解析 $MFT 起始簇号(LCN),偏移 0x30,QWORD(8 字节)
|
||||
mft_lcn_bytes = buffer[0x30:0x38]
|
||||
mft_lcn = int.from_bytes(mft_lcn_bytes, byteorder='little', signed=False)
|
||||
|
||||
return {
|
||||
"BytesPerSector": bytes_per_sector,
|
||||
"SectorsPerCluster": sectors_per_cluster,
|
||||
"ClusterSize": cluster_size
|
||||
"ClusterSize": cluster_size,
|
||||
"MftPosition": mft_lcn
|
||||
}
|
||||
|
||||
|
||||
|
@@ -2,6 +2,8 @@ import hashlib
|
||||
import random
|
||||
import sqlite3
|
||||
|
||||
from mft_analyze import GetFile80hPattern
|
||||
|
||||
|
||||
# 工具函数:获取文件扩展名
|
||||
def GetFileExtension(name: str) -> str:
|
||||
@@ -64,7 +66,23 @@ def GetFileHash(full_path: str) -> str:
|
||||
|
||||
# 获取分片数(1~4)
|
||||
def GetExtentCount(full_path: str) -> int:
|
||||
return random.randint(1, 4)
|
||||
try:
|
||||
pattern = GetFile80hPattern(full_path)
|
||||
if not pattern:
|
||||
return 1 # 默认值
|
||||
|
||||
# 取第一个80h属性(通常文件只有一个80h属性)
|
||||
attr = pattern[0]
|
||||
|
||||
if attr['is_resident']:
|
||||
return 1 # 常驻属性只有一个分片
|
||||
else:
|
||||
# 非常驻属性需要解析实际分片数
|
||||
# 这里简化为从sequence中解析,实际可能需要更复杂的解析
|
||||
return 1 # 简化处理,实际应根据数据结构解析
|
||||
except Exception as e:
|
||||
print(f"❌ 获取ExtentCount出错: {e}, 使用默认值1")
|
||||
return 1 # 出错时返回默认值
|
||||
|
||||
|
||||
# 获取随机位置
|
||||
@@ -77,6 +95,53 @@ def GetRandomLength() -> int:
|
||||
return random.randint(1000, 9999)
|
||||
|
||||
|
||||
def GetFileLocation(full_path: str) -> int:
|
||||
try:
|
||||
pattern = GetFile80hPattern(full_path)
|
||||
if not pattern:
|
||||
return GetRandomLocation() # 回退到随机值
|
||||
|
||||
attr = pattern[0]
|
||||
if attr['is_resident']:
|
||||
# 常驻属性: start_byte + offset + content_offset
|
||||
# 解析content_offset (sequence第三个元素的后4字节)
|
||||
content_offset_bytes = attr['sequence'][2].split()[4:8]
|
||||
content_offset = int.from_bytes(
|
||||
bytes.fromhex(''.join(content_offset_bytes)),
|
||||
byteorder='little'
|
||||
)
|
||||
return attr['start_byte'] + attr['offset'] + content_offset
|
||||
else:
|
||||
# 非常驻属性需要解析runlist
|
||||
# 这里简化为返回start_byte
|
||||
return attr['start_byte']
|
||||
except Exception as e:
|
||||
print(f"❌ 获取Location出错: {e}, 使用随机值")
|
||||
return GetRandomLocation() # 出错时返回随机值
|
||||
|
||||
|
||||
def GetFileLength(full_path: str) -> int:
|
||||
try:
|
||||
pattern = GetFile80hPattern(full_path)
|
||||
if not pattern:
|
||||
return GetRandomLength() # 回退到随机值
|
||||
|
||||
attr = pattern[0]
|
||||
if attr['is_resident']:
|
||||
# 常驻属性: 解析sequence第三个元素的前4字节
|
||||
content_length_bytes = attr['sequence'][2].split()[0:4]
|
||||
return int.from_bytes(
|
||||
bytes.fromhex(''.join(content_length_bytes)),
|
||||
byteorder='little'
|
||||
)
|
||||
else:
|
||||
# 非常驻属性: 从属性头中解析实际大小
|
||||
return attr['attribute_length'] # 简化处理
|
||||
except Exception as e:
|
||||
print(f"❌ 获取Length出错: {e}, 使用随机值")
|
||||
return GetRandomLength() # 出错时返回随机值
|
||||
|
||||
|
||||
# 主函数:将 db_path 数据导入 db_node
|
||||
def InsertNodeDataToDB(db_path='../src/db_ntfs_info.db', table_name='db_node'):
|
||||
conn = sqlite3.connect(db_path)
|
||||
@@ -166,4 +231,4 @@ def InsertNodeDataToDB(db_path='../src/db_ntfs_info.db', table_name='db_node'):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
InsertNodeDataToDB()
|
||||
InsertNodeDataToDB()
|
||||
|
@@ -76,6 +76,7 @@ def GetFileMftEntry(file_path):
|
||||
print(f"Looking up MFT entry for: {rel_path}")
|
||||
|
||||
mft_entry = find_file_mft_entry(fs, rel_path)
|
||||
print(f"MFT Entry: {mft_entry}")
|
||||
if mft_entry is None:
|
||||
raise RuntimeError("Could not find MFT entry for the specified file.")
|
||||
|
||||
@@ -102,7 +103,9 @@ def CalculateFileMftStartSector(mft_entry, volume_letter="Z"):
|
||||
config_data = GetNTFSBootInfo(volume_letter)
|
||||
# 计算文件 MFT Entry 的起始扇区号
|
||||
start_sector = config_data["MftPosition"] * 8 + mft_entry * 2
|
||||
|
||||
if start_sector < 0:
|
||||
raise ValueError("起始扇区号不能为负数")
|
||||
print(f"文件 MFT Entry 的起始扇区号: {start_sector}")
|
||||
return start_sector
|
||||
|
||||
|
||||
@@ -214,10 +217,11 @@ def GetFile80hPattern(file_path):
|
||||
try:
|
||||
mft_entry_value = GetFileMftEntry(file_path)
|
||||
StartSector = CalculateFileMftStartSector(mft_entry_value, volume_letter)
|
||||
print(f"\n文件的相关信息以及80属性内容:")
|
||||
print(Get80hPattern(StartSector, volume_letter))
|
||||
except Exception as e:
|
||||
print(f"❌ Error: {e}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
GetFile80hPattern(r"Z:\demo.jpg")
|
||||
GetFile80hPattern(r"Z:\hello.txt")
|
||||
|
Binary file not shown.
Reference in New Issue
Block a user