temp restore
This commit is contained in:
@@ -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')
|
||||||
|
@@ -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),偏移 0x30,QWORD(8 字节)
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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()
|
||||||
|
@@ -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.
Reference in New Issue
Block a user