Skip to content

Instantly share code, notes, and snippets.

@windwiny
Last active August 29, 2015 14:01
Show Gist options
  • Select an option

  • Save windwiny/4fea8fcb55654e332fbc to your computer and use it in GitHub Desktop.

Select an option

Save windwiny/4fea8fcb55654e332fbc to your computer and use it in GitHub Desktop.
show hdisk gpt part info
require 'zlib'
def show_lba0(rawdata)
puts "LBA0 ( MBR or PMBR )"
mbr = rawdata[446...512]
if mbr.size!=66 || mbr[-2..-1].unpack('CC') != [0x55, 0xaa]
puts "Not valid MRB part data"
puts
return
end
pss = []
4.times do |n|
dx = mbr[n*16,16]
i=0
x1 = dx[i...i+=1].unpack('C')[0] #part state (00-> not active, 80-> active)
x2 = dx[i...i+=1].unpack('C')[0] # begin disk head
v1 = dx[i...i+=1].unpack('C')[0]
x3 = v1&0b111111 # begin sector
x4 = ((v1&0b11000000)<<2) + dx[i...i+=1].unpack('C')[0] # begin cylinder
x5 = dx[i...i+=1].unpack('C')[0] #filesystem flag
x6 = dx[i...i+=1].unpack('C')[0] # end disk head
v1 = dx[i...i+=1].unpack('C')[0]
x7 = v1&0b111111 # end sector
x8 = ((v1&0b11000000)<<2) + dx[i...i+=1].unpack('C')[0] # end cylinder
x9 = dx[i...i+=4].unpack('I')[0] # begin sector(obs)
x10 = dx[i...i+=4].unpack('I')[0] * 512 # part size, sector number
pss << [x1, x2, x3, x4, x5, x6, x7, x8, x9, x10]
end
puts "partstate | begin head | sector | cylinder | fs flag | end head | sector | cylinder | obs pos(sector) | part size(byte)"
pss.each do |x|
p x
end
puts
end
def show_lba1(rawdata)
puts "LBA1 ( GPT info table )"
dx = rawdata[512, 512]
dx2 = dx.clone[0..91]
dx2[16, 4]="\x00\x00\x00\x00"
if (a=Zlib.crc32(dx2).to_s(16)) != (b=dx[16, 4].unpack('L')[0].to_s(16))
puts "crc check error #{a} #{b} #{dx[16, 4].bytes}"
puts
return
end
i = 0
p dx[i...i+=8].unpack('a*')[0] # 'EFI PART'
p dx[i...i+=4].unpack('cccc') #[0,0,1,0]
p dx[i...i+=4].unpack('I')[0] #92 if version==1.0
p dx[i...i+=4].unpack('L')[0].to_s(16) #set to 0, this 92 bytes crc32
p dx[i...i+=4].unpack('cccc') #[0,0,0,0]
p dx[i...i+=8].unpack('q')[0] #this lba position
p dx[i...i+=8].unpack('q')[0] #backup lba position
p dx[i...i+=8].unpack('q')[0] #first part lba
p dx[i...i+=8].unpack('q')[0] #last part lba
p dx[i...i+=16].unpack('C*').map { |e| "%02X"%e }.join # harddisk UUID
p dx[i...i+=8].unpack('q')[0] #partitem begin lba , 2 if master
p dx[i...i+=4].unpack('I')[0] #partitem, default 128
p dx[i...i+=4].unpack('I')[0] #partitem size, default 128
p dx[i...i+=4].unpack('I')[0].to_s(16) #crc32
puts
end
def show_lbax(rawdata)
puts "LBA2..33 ( GPT partitem infos )"
ps = rawdata[1024, 128*128]
pss = []
128.times do |n|
dx = ps[n*128, 128]
break if dx.empty?
next if dx == "\x00" * 128
i = 0
x1 = dx[i...i+=16].unpack('C*').map { |e| "%02X"%e }.join # part type UUID
x2 = dx[i...i+=16].unpack('C*').map { |e| "%02X"%e }.join # part UUID
x3 = bb = dx[i...i+=8].unpack('q')[0] #begin lba
x4 = ee = dx[i...i+=8].unpack('q')[0] #end lba
x5 = dx[i...i+=8].unpack('q')[0] #attrib
x6 = dx[i...i+=72].unpack('S') # 32's UTF-16
x7 = (ee-bb+1)*512
pss << [x1, x2, x3, x4, x5, x6, x7]
end
puts "part type UUID | part UUID | begin lba | end lba | attrib | 32's UTF-16 | part size (byte)"
pss.each do |x|
p x
end
puts
end
if __FILE__ == $0
if ARGV.size != 1
abort %Q{syntax:
dd if=/dev/sda of=sda.img bs=512 count=35
ruby showgpt.rb sda.img}
end
rawdata = File.binread(ARGV[0])
show_lba0(rawdata)
show_lba1(rawdata)
show_lbax(rawdata)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment