Portál AbcLinuxu, 1. května 2025 04:52
dd
-čkem zkopíroval image na desktop, a sháněl něco čím to opravit. Nástrojů hafo (jak pro win tak pro lin), ovšem žádný nefungoval, tak jsem ho musel napsat sám.
Tento zápisek je pro případ, že by Windows Mobile 6 opět napadlo že zápis náhodného sektoru do root dir je dobrý nápad, a já bych to musel psát znovu. Algoritmus: načte se FAT, identifikují se konce chainů (0xffff marker), zpětně se dojde na začátek chainu, načte se cluster a otestuje se jestli je to začátek adresáře. Pokud ano a ..
ukazuje na cluster 0, je tento chain adresářem odkazovaným z root dir. Takto nalezené adresáře se proto zapíšou jako nová root dir. Soubory v root dir mě nezajímají, to co jsem potřeboval bylo v adresářích. Jejich jména si skript samozřejmě musí vyvyslet.
Vážně by mě zajímalo co se vlastně stalo. FAT i data byly v pořádku, jen byl přepsán root dir. Taky jsem si všiml že poslední dva bajty boot sectoru nebyly jak má správně být 0xaa, 0x55 ale 0xff, 0x55.
from struct import unpack, pack from string import split from array import array # read boot sec f = open('image', 'r+') bps, spc, res, fats, rdir, spf, secs, fat = \ unpack('<11xHBHBH3xH8xI18x8s450x', f.read(512)) fat = split(fat)[0] if fat != "FAT16": raise rdir = (rdir * 32 + bps - 1) / bps clu0 = res + fats * spf + rdir clus = (secs - clu0) / spc print "DISK: %d + %d * %d %s + %d" % (res, fats, spf, fat, rdir) print "DATA: %d * %d * %d" % (clus, spc, bps) # read fat prev = {} f.seek(res * bps) for i, x in enumerate(array("H", f.read(spf * bps))): prev.setdefault(x, []).append(i) # process chains root = '' for i in prev[0xffff]: chain = [] while 1: chain.append(i) try: i, = prev[i] except: break if i < 2 or len(chain) > 5: continue # read first 2 dir entries f.seek((clu0 + (i - 2) * spc) * bps) n1, c1, s1, n2, c2, s2 = unpack('<' + '12s14xHI'*2, f.read(64)) if n1 == '. \x10' and c1 == i and s1 == 0 and \ n2 == '.. \x10' and c2 == 0 and s2 == 0: root += 'DIR%-5d \x10' % i + pack('<14xHI', i, 0) # write new root dir if len(root) > rdir * bps: raise f.seek((res + fats * spf) * bps) f.write(root + '\0' * (rdir * bps - len(root)))
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.