一个改MBR里分区表的bash脚本, 它有两个用法:
1) 把分区表打出来
./utils/pt -l hd.img
2) 修改分区表
1) 把分区表打出来
./utils/pt -l hd.img
2) 修改分区表
./utils/pt -c hd.img 3 status=80 chs=11,22,33 partitionType=5f lastchs=12,34,56 lba=a100 noOfSector=0
The above command line will modify the 4th partition table (first one is 0), change the status to 0x80, chs to 11,22,33 and etc.
#!/bin/bash
function printHelp(){
echo "Usage : "
echo " ./pt <file name>"
echo
echo " -l : list partition table"
echo " -l n : list n'th partition entry"
}
function writeByte(){
echo -ne \\x$1 | dd conv=notrunc bs=1 count=1 of=$3 seek=$2 &> /dev/null
}
function writeInt(){
echo -ne \\x00 | dd conv=notrunc bs=1 count=1 of=$3 seek=$2 &> /dev/null
echo -ne \\x00 | dd conv=notrunc bs=1 count=1 of=$3 seek=$(($2+1)) &> /dev/null
echo -ne \\x00 | dd conv=notrunc bs=1 count=1 of=$3 seek=$(($2+2)) &> /dev/null
echo -ne \\x00 | dd conv=notrunc bs=1 count=1 of=$3 seek=$(($2+3)) &> /dev/null
temp=$1
while [ ${#temp} -lt 8 ]; do
temp="0"$temp
done
b1=`echo $temp| cut -c7-8`
b2=`echo $temp| cut -c5-6`
b3=`echo $temp| cut -c3-4`
b4=`echo $temp| cut -c1-2`
echo -ne \\x$b1 | dd conv=notrunc bs=1 count=1 of=$3 seek=$2 &> /dev/null
echo -ne \\x$b2 | dd conv=notrunc bs=1 count=1 of=$3 seek=$(($2+1)) &> /dev/null
echo -ne \\x$b3 | dd conv=notrunc bs=1 count=1 of=$3 seek=$(($2+2)) &> /dev/null
echo -ne \\x$b4 | dd conv=notrunc bs=1 count=1 of=$3 seek=$(($2+3)) &> /dev/null
}
function getByte(){
start=$(($2+1))
let b=0x`cat $1 | head -c $start|tail -c 1|od -An -t x1 | tr -d ' '`
echo $b
}
function getInt(){
start=$(($2+4))
let b=0x`cat $1 | head -c $start|tail -c 4|od -An -t x4 | tail -1 | tr -d ' '`
echo $b
}
function dumpPartitionEntry(){
printf "status\t\t: %x\n" $1
printf "CHS\t\t: %x %x %x\n" $2 $3 $4
printf "partition type\t: %x\n" $5
printf "last CHS\t: %x %x %x\n" $6 $7 $8
printf "lba\t\t: %x\n" $9
printf "no of sectors\t: %d\n" ${10}
}
#Bad arguments
if [ $# -eq 0 ]; then
printHelp
exit 1
fi
ARGS=`getopt -o "l,c" -l "help" \
-n "getopt.sh" -- "$@"`
while true;
do
case "$1" in
-l)
if [ -z "$2" ]; then
echo "parameter error"
exit;
fi
if [ -z "$3" ]; then
filename=$2
offset=446
for i in {1..4}
do
status1=`getByte "$filename" $((offset+0))`
c1=`getByte "$filename" $((offset+1))`
h1=`getByte "$filename" $((offset+2))`
s1=`getByte "$filename" $((offset+3))`
type1=`getByte "$filename" $((offset+4))`
lastC1=`getByte "$filename" $((offset+5))`
lastH1=`getByte "$filename" $((offset+6))`
lastS1=`getByte "$filename" $((offset+7))`
lba1=`getInt "$filename" $((offset+8))`
noOfSector1=`getInt "$filename" $((offset+12))`
dumpPartitionEntry $status1 $c1 $h1 $s1 $type1 $lastC1 $lastH1 $lastS1 $lba1 $noOfSector1
echo
offset=$(($offset+16))
done
exit;
else
echo "list "$2
fi
shift;;
-c)
if [ -z "$3" ]; then
echo "parameter error"
exit;
fi
if [ $3 -gt 3 ]; then
echo "partition no cannot larger than 3"
exit;
fi
filename=$2
for temp in $4 $5 $6 $7 $8 $9
do
command=`echo $temp | cut -d= -f1`
para=`echo $temp| cut -d= -f2`
if [ $command = "status" ]; then
offset=$((446+16*$3))
writeByte $para $offset $filename
elif [ $command = "chs" ]; then
offset1=$((447+16*$3+0))
offset2=$((447+16*$3+1))
offset3=$((447+16*$3+2))
c=`echo $para | cut -d, -f1`
h=`echo $para | cut -d, -f2`
s=`echo $para | cut -d, -f3`
writeByte $c $offset1 $filename
writeByte $h $offset2 $filename
writeByte $s $offset3 $filename
command=`echo $temp | cut -d= -f1`
elif [ $command = "partitionType" ]; then
offset=$((450+16*$3))
writeByte $para $offset $filename
elif [ $command = "lastchs" ]; then
offset1=$((451+16*$3+0))
offset2=$((451+16*$3+1))
offset3=$((451+16*$3+2))
c=`echo $para | cut -d, -f1`
h=`echo $para | cut -d, -f2`
s=`echo $para | cut -d, -f3`
writeByte $c $offset1 $filename
writeByte $h $offset2 $filename
writeByte $s $offset3 $filename
elif [ $command = "lba" ]; then
offset=$((454+16*$3))
writeInt $para $offset $filename
elif [ $command = "noOfSector" ]; then
offset=$((458+16*$3))
writeInt $para $offset $filename
else
echo "you have specific wrong command after -c"
exit;
fi
done
exit;
shift;;
--help)
printHelp
shift;;
*)
echo "wrong command : "
shift
break;;
esac
done