clalancette / pycdlib

Python library to read and write ISOs
GNU Lesser General Public License v2.1
147 stars 38 forks source link

Corrupted Windows Image on Rebuilt Install ISO #89

Closed utkonos closed 1 year ago

utkonos commented 2 years ago

I hope this is a different problem from #45 since that one is marked as fixed. I have run into a very similar problem. For a Windows ISO where I am trying to inject the autounattend.xml at the root of the Windows ISO: the install.wim file is getting corrupted for some reason. I have opened both files in a hex editor and I can see that rather than being truncated, it appears that the first chunk of the file up to a certain offset is being repeated over and over up to the expected size in the new file.

I extracted the file from the new ISO and in the hex editor, I picked out a few bytes at the end of the file:

image

Searching for those bytes, I find them repeated over and over:

image

Here is the code snippet that I'm using to make the new ISO:

import io
import pathlib
import pycdlib
desktop = pathlib.Path().home().joinpath('Desktop')
iso_path = desktop.joinpath('Win10_1703_English_x64.iso')
iso = pycdlib.PyCdlib()
iso.open(iso_path)
filename = 'autounattend.xml'
xml_path = desktop.joinpath(filename)
au = xml_path.read_bytes()
iso.add_fp(io.BytesIO(au), len(au), udf_path=f'/{filename}')
iso.write('new.iso')

SHA256 hash of the original ISO: b842a801bf1dedf3acbfd909f91fb2a741eef20fda133daa1878e46a07ec9237

SHA256 of the original install.wim: 6806be51af9783affe2710314328d158f6d4058033ba888216f6bef0766c84e7 SHA256 of the resulting install.win: 74480bdab0309f683bfa6708fe2556c220855ae82ac1cbafba8f1f72aeba4361

utkonos commented 2 years ago

There is a workaround for this. If the install.wim file is split using DISM, everything works as expected. I chose FileSize:500 to be safe, but I bet as long as that value is smaller than where the chunk repeats for the first time in the screenshot above, it should work fine.

To do this, just extract install.wim from the ISO. Then run DISM like so:

Dism /Split-Image /ImageFile:install.wim /SWMFile:install.swm /FileSize:500 /CheckIntegrity

Place all the new swm files in a folder on the desktop named Images.

Then the following process for editing the ISO:

import io
import pathlib
import pycdlib
desktop = pathlib.Path().home().joinpath('Desktop')
iso_path = desktop.joinpath('Win10_1703_English_x64.iso')
iso = pycdlib.PyCdlib()
iso.open(iso_path)
iso.rm_file(udf_path='/sources/install.wim')
filename = 'autounattend.xml'
xml_path = desktop.joinpath(filename)
au = xml_path.read_bytes()
iso.add_fp(io.BytesIO(au), len(au), udf_path=f'/{filename}')
for image in desktop.joinpath('Images').glob('*.swm'):
    data = image.read_bytes()
    iso.add_fp(io.BytesIO(data), len(data), udf_path=f'/sources/{image.name}')
iso.write('new.iso')
clalancette commented 1 year ago

Sorry, I know you opened this a very long time ago and I never responded.

I was finally able to get my hands on a copy of a Windows ISO, and I was able to add in an autounattend.xml file using the (original) code you have above. I just used kind of a stock file, that was only 3K bytes long. Regardless, this seemed to work fine for me and there was no corruption either in this file or in the install.wim file. Maybe a larger autounattend.xml will cause the issue? If you could attach the file you are using to this issue, then I can try again and see if there is any difference. Thanks.

utkonos commented 1 year ago

I'm no longer able to reproduce the issue.

clalancette commented 1 year ago

I'm no longer able to reproduce the issue.

OK, thanks for the confirmation! I have put a bunch of fixes in since May, so hopefully one of those did it for you. Feel free to reopen if you see this again.