Question

Trying to make a script for disk imaging (such as .dd format) in python. Originally started as a project to get another hex debugger and kinda got more interested in trying to get raw data from the drive. which turned into wanting to be able to image the drive first. Anyways, I've been looking around for about a week or so and found the best way get get information from the drive on smaller drives appears to be something like:

with file("/dev/sda") as f:
 i=file("~/imagingtest.dd", "wb")
 i.write(f.read(SIZE))

with size being the disk size. Problem is, which seems to be a well known issue, trying to use large disks shows up as (even in my case total size of 250059350016 bytes):

"OverflowError: Python int too large to convert to C long"

Is there a more appropriate way to get around this issue? As it works fine for a small flash drive, but trying to image a drive, fails.

I've seen mention of possibly just iterating by sector size (512) per the number of sectors (in my case 488397168) however would like to verify exactly how to do this in a way that would be functional.

Thanks in advance for any assistance, sorry for any ignorance you easily notice.

Was it helpful?

Solution

Yes, that's how you should do it. Though you could go higher than the sector size if you wanted.

with open("/dev/sda",'rb') as f:
    with open("~/imagingtest.dd", "wb") as i:
        while True:
            if i.write(f.read(512)) == 0:
                break

OTHER TIPS

Read the data in blocks. When you reach the end of the device, .read(blocksize) will return the empty string.

You can use iter() with a sentinel to do this easily in a loop:

from functools import partial

blocksize = 12345

with open("/dev/sda", 'rb') as f:
    for block in iter(partial(f.read, blocksize), ''):
        # do something with the data block

You really want to open the device in binary mode, 'rb' if you want to make sure no line translations take place.

However, if you are trying to create copy into another file, you want to look at shutil.copyfile():

import shutil

shutil.copyfile('/dev/sda', 'destinationfile')

and it'll take care of the opening, reading and writing for you. If you want to have more control of the blocksize used for that, use shutil.copyfileobj(), open the file objects yourself and specify a blocksize:

import shutil

blocksize = 12345

with open("/dev/sda", 'rb') as f, open('destinationfile', 'wb') as dest:
    shutil.copyfileobj(f, dest, blocksize)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top