Vra

Hopelik het jy al gehoor van die netjiese hack waarmee jy 'n JPG en 'n zip-lêer te kombineer in 'n enkele lêer en dit is 'n geldige (of ten minste leesbaar) lêer vir beide formate. Wel, het ek besef dat sedert JPG kan arbitrêre dinge aan die einde, en zip by die begin, kan jy nog 'n formaat te hou in daar - in die middel. Vir die doeleindes van hierdie vraag, neem die middel data is arbitrêre binêre data gewaarborg om nie te bots met die JPG of zip formate (wat beteken dat dit nie die magie zip kop 0x04034b50 bevat). Illustrasie:

0xFFD8 <- start jpg data end -> 0xFFD9 ... ARBITRARY BINARY DATA ... 0x04034b50 <- start zip file ... EOF

Ek catting soos volg:

  

kat "mss_1600.jpg" filea fileb   filea fileb filea fileb filea   fileb filea fileb filea fileb filea   fileb filea fileb filea fileb filea   fileb filea fileb filea fileb filea   fileb "null.bytes"   "Randomzipfile.zip"> temp.zip

Dit produseer 'n 6318 KB lêer. Dit nie oop in 7-Zip. Maar toe ek kat een minder 'n dubbele "(so in plaas van 13 filea en b se 12):

  

kat "mss_1600.jpg" filea fileb   filea fileb filea fileb filea   fileb filea fileb filea fileb filea   fileb filea fileb filea fileb filea   fileb filea fileb filea fileb   "Null.bytes" "randomzipfile.zip">   temp.zip

Dit produseer 'n 5996 KB lêer wat nie oop in 7-Zip.

Ek weet my arbitrêre binêre data nie die magie Zip File Selected om dit skroef. Ek het naslaanlêers van die werk jpg + data + rits en die nie-werkende jpg + data + rits (red-as oorsaak van die leser dink hulle is beelde, en voeg die rits uitbreidings jouself).

Ek wil weet hoekom dit nie werk nie met 13 kombinasies en nie met 12. Vir bonus punte, moet ek om hierdie te kry op 'n manier.

Was dit nuttig?

Oplossing

Eintlik is dit 'n twee deel antwoord regtig :)

In die eerste plek maak nie saak wat mense sê zip lêers kan nie tegnies word woordeliks sit aan die einde van lêers. Die einde van die sentrale gids rekord het 'n waarde wat die byte vanaf die begin van die huidige skyf dui (as jy net een Zip lêer het, wat beteken dat die huidige lêer). Nou 'n baie verwerkers ignoreer hierdie, alhoewel Windows 'n gids zip nie, sodat jy nodig het om daardie waarde te verbeter om dit te laat werk in Windows Explorer (nie dat jy dalk omgee; P) Sien Zip APPNOTE vir meer inligting oor die lêer formaat. Basies vind jy in 'n blok redakteur (of skryf 'n instrument) om die "offset van aanvang van sentrale gids met betrekking tot die begin skyf aantal" waarde te vind. vind dan die eerste "sentrale lêer header handtekening" (hex van 504b0102) en stel die waarde na wat verreken.

Nou helaas dit beteken nie los 7zip maar dit is te danke aan die manier 7zip probeer om die lêer formaat raai. Basies sal dit net soek die eerste ~ 4MiB vir die binêre ry 504b0304, indien dit nie vind dit dit veronderstel dit is nie Zip en probeer sy ander argief formate. Dit is natuurlik hoekom die toevoeging van nog 'n lêer breek dinge, dit stoot dit oor die limiet vir die soektog.

Nou om dit op te los wat jy hoef te doen is voeg daardie blok string na die jpeg sonder om te breek dit. Een manier om dit te doen, is om by te voeg net na die FFD8 JPEG SOI header die volgende blok data, FFEF0005504B030400. Wat voeg 'n persoonlike blok met jou ry en korrek is so jpeg kop moet net ignoreer dit.

Ander wenke

Ek afgelaai die bron vir 7-Zip en uitgepluis het wat veroorsaak dat dit gebeur.

In CPP / 7zip / UI / Common / OpenArchive.cpp, sal jy sien die volgende:

// Static-SFX (for Linux) can be big.
const UInt64 kMaxCheckStartPosition = 1 << 22;

Dit beteken dat slegs die eerste 4194304 grepe van die lêer sal gesoek word vir die kop. As dit nie daar is gevind, 7-Zip beskou dit as 'n ongeldige lêer.

Jy kan dit beperk deur die verandering van 1 << 22 om 1 << 23 verdubbel. Ek getoets dat verandering deur die herstel van 7-Zip en dit werk.

wysig : Om rondom hierdie kwessie te kry, kan jy laai die bron , maak die bogenoemde verandering, en bou dit. Ek het dit opgebou met behulp van VS 2008 Open die VSA opdrag prompt gaan na onttrek-bron-plek \ CPP \ 7zip \ Bundels en tipe 'nMaak. Dan in die Alone gids run '7za t nonworking.jpg en jy moet sien "Alles is OK".

So vir enigiemand anders om hierdie vraag, hier is die storie:

Ja, Andy is letterlik korrek aan te voer waarom 7-Zip is die versuim op die lêer, maar dit help nie om my probleem, want ek kan nie presies kry mense om my weergawe van 7-Zip gebruik.

tyranid het my egter die oplossing.

  • Eerstens, die byvoeging van 'n klein bytestring om die JPG as hy suggereer sal laat 7-Zip dit oop te maak. Dit is egter 'n bietjie af van 'n geldige JPG fragment, wat dit nodig het om FFEF00 wees 07 504B030400 - die lengte was af met 2 grepe
  • .
  • Dit laat 7-Zip dit oop te maak, maar nie onttrek lêers, is dit nie in stilte. Dit is omdat die inskrywings in die sentrale gids hê interne verwysings / neutraliseer wat na die ingang van die lêer. Aangesien jy sit 'n klomp van die dinge voor dit, jy nodig het om al die verwysings reg te stel!
  • Om die rits oop met Windows gebou in zip ondersteuning te hê, moet jy, as tyranid sê, korrek is die "offset van aanvang van sentrale gids met betrekking tot die begin skyf aantal". Hier is 'n luislang script om die laaste twee doen, alhoewel dit 'n fragment, nie copypasta-gereed-om-te gebruik

#Now we need to read the file and rewrite all the zip headers.  Fun!
torewrite = open(magicfilename, 'rb')
magicdata = torewrite.read()
torewrite.close()

#Change the Central Repository's Offset
offsetOfCentralRepro = magicdata.find('\x50\x4B\x01\x02') #this is the beginning of the central repo
start = len(magicdata) - 6 #it so happens, that on my files, the point is stored 2 bytes from the end.  so datadatadatdaata OF FS ET !! 00 00 EOF where OFFSET!! is the 4 bytes 00 00 are the last two bytes, then EOF
magicdata = magicdata[:start] + pack('I', offsetOfCentralRepro) + magicdata[start+4:]

#Now change the individual offsets in the central directory files
startOfCentralDirectoryEntry = magicdata.find('\x50\x4B\x01\x02', 0) #find the first central directory entry
startOfFileDirectoryEntry = magicdata.find('\x50\x4B\x03\x04', 10) #find the first file entry (we start at 10 because we have to skip past the first fake entry in the jpg)
while startOfCentralDirectoryEntry > 0:
    #Now I move a magic number of bytes past the entry (really! It's 42!)
    startOfCentralDirectoryEntry = startOfCentralDirectoryEntry + 42

    #get the current offset just to output something to the terminal
    (oldoffset,) = unpack('I', magicdata[startOfCentralDirectoryEntry : startOfCentralDirectoryEntry+4])
    print "Old Offset: ", oldoffset, " New Offset: ", startOfFileDirectoryEntry , " at ", startOfCentralDirectoryEntry
    #now replace it
    magicdata = magicdata[:startOfCentralDirectoryEntry] + pack('I', startOfFileDirectoryEntry) + magicdata[startOfCentralDirectoryEntry+4:]

    #now I move to the next central directory entry, and the next file entry
    startOfCentralDirectoryEntry = magicdata.find('\x50\x4B\x01\x02', startOfCentralDirectoryEntry)
    startOfFileDirectoryEntry = magicdata.find('\x50\x4B\x03\x04', startOfFileDirectoryEntry+1)

#Finally write the rewritten headers' data
towrite = open(magicfilename, 'wb')
towrite.write(magicdata)
towrite.close()

Jy kan hibriede JPG + zip lêers te produseer met behulp van DotNetZip . DotNetZip kan red na 'n stroom, en dit is intelligent genoeg om die oorspronklike geneutraliseer van 'n pre-bestaande stroom erken voordat dit begin skryf zip inhoud in dit. Daarom in pseudokode, kan jy 'n JPG kry + ZIP hierdie manier:

 open stream on an existing JPG file for update
 seek to the end of that stream
 open or create a zip file
 call ZipFile.Save to write zip content to the JPG stream
 close

Al die skyf is korrek gedink. Dieselfde tegniek word gebruik om 'n self-extracting argief produseer. Jy kan die stroom op die EXE oopmaak, dan probeer om die einde, en skryf die zip inhoud aan daardie stroom. Al die skyf is korrek bereken as jy dit op hierdie manier doen.

Nog 'n ding - met betrekking tot een van die kommentaar in 'n ander post ... zip kan arbitrêre data in die begin en aan die einde van die lêer. Daar is geen vereiste sover ek weet dat die ritssluiter sentrale gids moet wees aan die einde van die lêer, maar dit is tipies.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top