temp restore

This commit is contained in:
Burgess Leo
2025-05-19 13:25:07 +08:00
parent b2e14fdbe0
commit 07a4ae7a74
5 changed files with 83 additions and 8 deletions

View File

@@ -25,5 +25,5 @@ def ClearTableRecordsWithReset(db_path, table_name):
if __name__ == '__main__': 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_path')
# ClearTableRecordsWithReset(db_path='../src/db_ntfs_info.db', table_name='db_device') # 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_config')
ClearTableRecordsWithReset(db_path='../src/db_ntfs_info.db', table_name='db_node') # ClearTableRecordsWithReset(db_path='../src/db_ntfs_info.db', table_name='db_node')

View File

@@ -8,9 +8,10 @@ def GetNTFSBootInfo(volume_letter):
- Bytes per sector - Bytes per sector
- Sectors per cluster - Sectors per cluster
- Cluster size (bytes) - Cluster size (bytes)
- $MFT 起始簇号
参数: 参数:
volume_letter: 卷标字符串,例如 'C' volume_letter: str卷标字符串,例如 'C'
返回: 返回:
dict 包含上述信息 dict 包含上述信息
@@ -62,10 +63,15 @@ def GetNTFSBootInfo(volume_letter):
# 计算簇大小 # 计算簇大小
cluster_size = bytes_per_sector * sectors_per_cluster cluster_size = bytes_per_sector * sectors_per_cluster
# 解析 $MFT 起始簇号LCN偏移 0x30QWORD8 字节)
mft_lcn_bytes = buffer[0x30:0x38]
mft_lcn = int.from_bytes(mft_lcn_bytes, byteorder='little', signed=False)
return { return {
"BytesPerSector": bytes_per_sector, "BytesPerSector": bytes_per_sector,
"SectorsPerCluster": sectors_per_cluster, "SectorsPerCluster": sectors_per_cluster,
"ClusterSize": cluster_size "ClusterSize": cluster_size,
"MftPosition": mft_lcn
} }

View File

@@ -2,6 +2,8 @@ import hashlib
import random import random
import sqlite3 import sqlite3
from mft_analyze import GetFile80hPattern
# 工具函数:获取文件扩展名 # 工具函数:获取文件扩展名
def GetFileExtension(name: str) -> str: def GetFileExtension(name: str) -> str:
@@ -64,7 +66,23 @@ def GetFileHash(full_path: str) -> str:
# 获取分片数1~4 # 获取分片数1~4
def GetExtentCount(full_path: str) -> int: 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) 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 # 主函数:将 db_path 数据导入 db_node
def InsertNodeDataToDB(db_path='../src/db_ntfs_info.db', table_name='db_node'): def InsertNodeDataToDB(db_path='../src/db_ntfs_info.db', table_name='db_node'):
conn = sqlite3.connect(db_path) 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__': if __name__ == '__main__':
InsertNodeDataToDB() InsertNodeDataToDB()

View File

@@ -76,6 +76,7 @@ def GetFileMftEntry(file_path):
print(f"Looking up MFT entry for: {rel_path}") print(f"Looking up MFT entry for: {rel_path}")
mft_entry = find_file_mft_entry(fs, rel_path) mft_entry = find_file_mft_entry(fs, rel_path)
print(f"MFT Entry: {mft_entry}")
if mft_entry is None: if mft_entry is None:
raise RuntimeError("Could not find MFT entry for the specified file.") 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) config_data = GetNTFSBootInfo(volume_letter)
# 计算文件 MFT Entry 的起始扇区号 # 计算文件 MFT Entry 的起始扇区号
start_sector = config_data["MftPosition"] * 8 + mft_entry * 2 start_sector = config_data["MftPosition"] * 8 + mft_entry * 2
if start_sector < 0:
raise ValueError("起始扇区号不能为负数")
print(f"文件 MFT Entry 的起始扇区号: {start_sector}")
return start_sector return start_sector
@@ -214,10 +217,11 @@ def GetFile80hPattern(file_path):
try: try:
mft_entry_value = GetFileMftEntry(file_path) mft_entry_value = GetFileMftEntry(file_path)
StartSector = CalculateFileMftStartSector(mft_entry_value, volume_letter) StartSector = CalculateFileMftStartSector(mft_entry_value, volume_letter)
print(f"\n文件的相关信息以及80属性内容")
print(Get80hPattern(StartSector, volume_letter)) print(Get80hPattern(StartSector, volume_letter))
except Exception as e: except Exception as e:
print(f"❌ Error: {e}") print(f"❌ Error: {e}")
if __name__ == '__main__': if __name__ == '__main__':
GetFile80hPattern(r"Z:\demo.jpg") GetFile80hPattern(r"Z:\hello.txt")

Binary file not shown.