U盘数据恢复笔记(3)谁解其中味
本帖最后由 天堂雨 于 2023-7-28 23:23 编辑U盘数据恢复笔记(3)谁解其中味
U盘没有物理性损坏,R-Sdudio可找到大部分数据,下面用winhex结合R-Sdudio手工恢复根目录被破坏的数据.
本帖最后由 天堂雨 于 2023-7-28 18:47 编辑
基础知识EXFAT是微软开发设计的文件系统,详细见https://learn.microsoft.com/zh-cn/windows/win32/fileio/exfat-specification此文件是机器翻译的,读起来有些难理解.可查看对应的英文原版https://learn.microsoft.com/en-us/windows/win32/fileio/exfat-specification 本帖最后由 天堂雨 于 2023-7-28 19:00 编辑
修订分区引导记录DBR
因为EXFAT分区前24扇区保留分区重要信息,现需手工重建.其中第0扇区记录分区的基本信息,用WINHEX的模板查看和修改,第1扇区至第8扇区仅在最后有55AA结束标记第9扇区至第10扇区全0填充第11扇区为校验码扇区,是4字节的前11扇区的校验码,其中分区参数的6AH(106)、6BH(107)两字节为分区卷标记,70H(112)分区卷不参与计算校验码。使用WINHEX的脚本计算校验码
扇区Offset内容
00000HDBR
10200H仅55AA结束标记
20400H仅55AA结束标记
30600H仅55AA结束标记
40800H仅55AA结束标记
50A00H仅55AA结束标记
60C00H仅55AA结束标记
70E00H仅55AA结束标记
81000仅55AA结束标记
91200H全0填充
101400H全0填充
111600H校验码扇区
121800HDBR备份
131A00H仅55AA结束标记
141C00H仅55AA结束标记
151E00H仅55AA结束标记
162000H仅55AA结束标记
172200H仅55AA结束标记
182400H仅55AA结束标记
192600H仅55AA结束标记
202800H仅55AA结束标记
212A00H全0填充
222C00H全0填充
232E00H校验码扇区
// 此文件用于计算 EXFAT前11个扇区除106-106(磁盘标记2字节)和112磁盘使用百分比1字节之外的校验和
//指定打开的驱动器,要选择正确的EXFAT所在分区的盘符驱动器!!!!
Open :?
Assign Checksum 0
Assign BytesPerSector (512)
Assign NumberOfBytes (BytesPerSector*11)
MessageBox NumberOfBytes
Assign Index 0
Assign one_byte 0
{
IfEqual 106 Index
Inc Index
EndIf
IfEqual 107 Index
Inc Index
EndIf
IfEqual 112 Index
Inc Index
EndIf
Assign hight_bit 0
IfEqual (Checksum&1) 1
Assign hight_bit 0x00000080
EndIf
Goto Index
Read one_byte 1
Assign Checksum (hight_bit+Checksum/2+one_byte)
IfEqual (NumberOfBytes-1) Index
ExitLoop
EndIf
Inc Index
}
MessageBox Checksum
//将校验和写入第11个扇区,校验和4字节,共计写512/4次
Assign START_POS (512*11)
Assign nums (512/4)
Goto START_POS
{
Write Checksum
}
//将校验和写入第23个扇区,校验和4字节,共计写512/4次
Assign START_POS (512*23)
Assign nums (512/4)
Goto START_POS
{
Write Checksum
}
//记得保存,修改才能生效
//Save
代码见上文,愿意友情支持积分的请付费下载.
将上述代码保存为DBR_boot_sector_checksum.whs放到winhex所在目录也是可以的
本帖最后由 天堂雨 于 2023-7-28 19:17 编辑
修订根目录特殊项
大写字符表$UpCase也需要在根目录项填写校验码,此处直接复制一个新格式化的U盘的$UpCase到第4扇区,修订根目录项82H的校验码修订目录项82H的$Bitmap簇位图数据根据需要根目录下的卷标目录项83H,也可以不要卷标目录项
本帖最后由 天堂雨 于 2023-7-28 19:23 编辑
修订根目录文件夹等
根据R-STUDIO显示所在扇区,记录到excel表格中,转换计算出簇号
用winhex的85H等项目修订起始簇号,然后再计算校验码,并写入文件名校验码.
// 此文件用于计算 EXFAT 文件目录的SetChecksum 字段校验和
// 默认取SecondaryCount=2,即文件共计有32X(2+1)=96字节组成
// 如文件名较长,应根据实际情况修改SecondaryCount值
// 计算出结果后将数据填入目录条目的第2、3字节
//根目录区域修改前
//Offset 0001020304050607 08090A0B0C0D0E0F
//9830400(960000H):0300000000000000 0000000000000000
//9830416(960010H):0000000000000000 0000000000000000
//9830432(960020H):8100000000000000 0000000000000000
//9830448(960030H):0000000002000000 77A9030000000000
//9830464(960040H):820000000DD319E6 0000000000000000
//9830480(960050H):0000000004000000 CC16000000000000
//9830496(960060H):8502F51F20000000 3D68F1567203F356
//9830512(960070H):7203F3569800A0A0 A000000000000000
//9830528(960080H):C003000B34410000 1D00000000000000
//9830544(960090H):0000000008000000 1D00000000000000
//9830560(9600A0H):C100610075007400 6F00720075006E00
//9830576(9600B0H):2E0069006E006600 0000000000000000
//根目录区域修改后
//Offset 0001020304050607 08090A0B0C0D0E0F
//9830400(960000H):0300000000000000 0000000000000000
//9830416(960010H):0000000000000000 0000000000000000
//9830432(960020H):8100000000000000 0000000000000000
//9830448(960030H):0000000002000000 77A9030000000000
//9830464(960040H):820000000DD319E6 0000000000000000
//9830480(960050H):0000000004000000 CC16000000000000
//9830496(960060H):8502F50920000000 3D68F1567203F356
//9830512(960070H):7203F3569800A0A0 A000000000000000
//9830528(960080H):C003000B34410000 1D00000000000000
//9830544(960090H):0000000008000000 1D00000000000000
//9830560(9600A0H):C100610075007400 6F00720075006E00
//9830576(9600B0H):2E0069006E006600 0000000000000000
//示例计算出来的校验和为2549,转换为16进制为 09 F5,小头在前 F5 09,
//因此在9830498、9830499处两字节修改为 09 F5
//GetUserInputI cur_position "请输入文件条目起始位置(如 9830496):"
//CurrentPos 不能放到表达式中参与运算
//数字可以用常规10进制,或者形式如0x3E之类的16进制
MessageBox "请将光标放在0x85H开头的行上面"
Assign cur_position CurrentPos
Assign move_offset 0
IfGreater (cur_position%16) 0
Assign move_offset (0-(cur_position%16))
EndIf
//Assign SecondaryCount 3
//Assign Checksum 0
Assign one_byte 0
Assign Index 0
Move move_offset
//读入首字节=0x85
Read one_byte 1
//输入第1字节辅助项目数量=SecondaryCount
Read SecondaryCount 1
//读入第2,3字节校验码
Read Checksum 2
Assign OriginalChecksum Checksum
Assign Checksum 0
Move -4
//回退到首字节位置
Assign one_bytestr "1111"
Assign dir_enrty_offset CurrentPos
//如果首字节不是0x85,终止程序
IfGreater one_byte 0x85
MessageBox "首字节不是0x85退出"
JumpTo ContinueHere
EndIf
IfGreater 0x85 one_byte
MessageBox "首字节不是0x85退出"
JumpTo ContinueHere
EndIf
//如果首字节是0x85,开始计算校验和
//第2,3字节是校验和,不参与计算
Assign NumberOfBytes ((SecondaryCount+1)*32)
{
IfEqual 2 Index
Inc Index
EndIf
IfEqual 3 Index
Inc Index
EndIf
Assign hight_bit 0
IfEqual (Checksum&1) 1
Assign hight_bit 0x0080
EndIf
Goto (Index+dir_enrty_offset)
Read one_byte 1
Assign Checksum (hight_bit+Checksum/2+one_byte)
IfEqual (NumberOfBytes-1) Index
ExitLoop
EndIf
Inc Index
}
IntToStr StrChecksum Checksum
IntToStr strOriginalChecksum OriginalChecksum
Assign move_offset (0-NumberOfBytes+2)
Move move_offset
Write Checksum
Assign toshowMsg"原始校验和:"
StrCat toshowMsg strOriginalChecksum
StrCat toshowMsg "计算的校验和:"
StrCat toshowMsg StrChecksum
MessageBox toshowMsg
Label ContinueHere
代码见上文,愿意友情支持积分的请付费下载.
将上述代码保存为EntrySetChecksum_general.whs放到winhex所在目录也是可以的
本帖最后由 天堂雨 于 2023-7-28 19:26 编辑
用OSFMount加载故障备份故障U盘
感谢分享 NMR 发表于 2023-7-28 22:50
感谢分享
感谢阅读和关注
页:
[1]