Skip to content

Instantly share code, notes, and snippets.

@icewall
Created August 3, 2016 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save icewall/056c6f49a84df7005b0d538494dffea2 to your computer and use it in GitHub Desktop.
Save icewall/056c6f49a84df7005b0d538494dffea2 to your computer and use it in GitHub Desktop.
classes helping update some VHD structures checksum
import os
import sys
import struct
class vhdStruct(object):
def __init__(self):
self._structSize = None
self._buffer = None
self._checsumOffset = None
self._offset = None
def calculateChecksum(self):
checksum = 0
for i in range(0,self._structSize):
if i >= self._checksumOffset and i < self._checksumOffset + 4:
continue
checksum += ord(self._buffer[i])
checksum = (~checksum) & 0xffffffff
return checksum
def getChecksumOffset(self):
return self._offset + self._checksumOffset
class vhdFooter(vhdStruct):
DISK_TYPE_OFFSET = 0x3c
CHECKSUM_OFFSET = 0x40
def __init__(self,buffer,offset):
self._buffer = buffer
self._offset = offset
self._checksumOffset = vhdFooter.CHECKSUM_OFFSET
self._structSize = len(buffer)
def getDiskType(self):
return struct.unpack(">I",self._buffer[vhdFooter.DISK_TYPE_OFFSET:vhdFooter.DISK_TYPE_OFFSET+4])[0]
def getDiskTypeByte(self):
return ord(self._buffer[vhdFooter.DISK_TYPE_OFFSET+3])
class vhdDynamicHeader(vhdStruct):
CHECKSUM_OFFSET = 0x24
def __init__(self,buffer,offset):
self._buffer = buffer
self._checksumOffset = vhdDynamicHeader.CHECKSUM_OFFSET
self._structSize = len(buffer)
self._offset = offset
class vhd(object):
FOOTER_SIZE = 512
VHD_FIXED = 2
VHD_DYNAMIC = 3
def __init__(self,filePath):
self.__filePath = filePath
self.__fw = None
stats = os.stat(filePath)
if stats.st_size < vhd.FOOTER_SIZE:
print "File size is less than 512 bytes"
return
try:
self.__fw = file(filePath,'rb+')
self.__fw.seek(-vhd.FOOTER_SIZE,os.SEEK_END)
offset = self.__fw.tell()
self.footer = vhdFooter(self.__fw.read(vhd.FOOTER_SIZE), offset)
if self.footer.getDiskType() == vhd.VHD_DYNAMIC:
self.__fw.seek(0,os.SEEK_SET)
self.footerCopy = vhdFooter( self.__fw.read(vhd.FOOTER_SIZE),0)
self.dynamicHeader = vhdDynamicHeader( self.__fw.read(1024), vhd.FOOTER_SIZE )
except Exception as e:
print e.message
def updateFile(self,updates):
for update in updates:
offset,value = update
self.__fw.seek(offset,os.SEEK_SET)
self.__fw.write( struct.pack(">I",value) )
def close(self):
if not self.__fw:
self.__fw.close()
if __name__ == "__main__":
v = vhd(r't:\vdisk_dynamic_test.vhd')
updates = []
if v.footer.getDiskType() == vhd.VHD_DYNAMIC:
updates.append( (v.footerCopy.getChecksumOffset(),v.footerCopy.calculateChecksum()) )
updates.append( (v.dynamicHeader.getChecksumOffset(),v.dynamicHeader.calculateChecksum()) )
updates.append( ( v.footer.getChecksumOffset(), v.footer.calculateChecksum() ) )
v.updateFile(updates)
v.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment