Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ading2210
GitHub Repository: ading2210/shimboot
Path: blob/main/shim_utils.sh
402 views
1
#!/bin/bash
2
3
#utilties for reading shim disk images
4
5
run_binwalk() {
6
if binwalk -h | grep -- '--run-as' >/dev/null; then
7
binwalk "$@" --run-as=root
8
else
9
binwalk "$@"
10
fi
11
}
12
13
#extract the initramfs from a kernel image
14
extract_initramfs() {
15
local kernel_bin="$1"
16
local working_dir="$2"
17
local output_dir="$3"
18
19
#extract the compressed kernel image from the partition data
20
local kernel_file="$(basename $kernel_bin)"
21
local binwalk_out=$(run_binwalk --extract $kernel_bin --directory=$working_dir)
22
local stage1_file=$(echo $binwalk_out | pcregrep -o1 "\d+\s+0x([0-9A-F]+)\s+gzip compressed data")
23
local stage1_dir="$working_dir/_$kernel_file.extracted"
24
local stage1_path="$stage1_dir/$stage1_file"
25
26
#extract the initramfs cpio archive from the kernel image
27
run_binwalk --extract $stage1_path --directory=$stage1_dir > /dev/null
28
local stage2_dir="$stage1_dir/_$stage1_file.extracted/"
29
local cpio_file=$(file $stage2_dir/* | pcregrep -o1 "([0-9A-F]+):\s+ASCII cpio archive")
30
local cpio_path="$stage2_dir/$cpio_file"
31
32
rm -rf $output_dir
33
cat $cpio_path | cpio -D $output_dir -imd --quiet
34
}
35
36
extract_initramfs_arm() {
37
local kernel_bin="$1"
38
local working_dir="$2"
39
local output_dir="$3"
40
41
#extract the kernel lz4 archive from the partition
42
local binwalk_out="$(run_binwalk $kernel_bin)"
43
local lz4_offset="$(echo "$binwalk_out" | pcregrep -o1 "(\d+).+?LZ4 compressed data" | head -n1)"
44
local lz4_file="$working_dir/kernel.lz4"
45
local kernel_img="$working_dir/kernel_decompressed.bin"
46
dd if=$kernel_bin of=$lz4_file iflag=skip_bytes,count_bytes skip=$lz4_offset
47
lz4 -d $lz4_file $kernel_img -q || true
48
49
#extract the initramfs cpio archive from the kernel image
50
local extracted_dir="$working_dir/_kernel_decompressed.bin.extracted"
51
run_binwalk --extract $kernel_img --directory=$working_dir > /dev/null
52
local cpio_file=$(file $extracted_dir/* | pcregrep -o1 "([0-9A-F]+):\s+ASCII cpio archive")
53
local cpio_path="$extracted_dir/$cpio_file"
54
55
rm -rf $output_dir
56
cat $cpio_path | cpio -D $output_dir -imd --quiet
57
}
58
59
copy_kernel() {
60
local shim_path="$1"
61
local kernel_dir="$2"
62
63
local shim_loop=$(create_loop "${shim_path}")
64
local kernel_loop="${shim_loop}p2" #KERN-A should always be p2
65
66
dd if=$kernel_loop of=$kernel_dir/kernel.bin bs=1M status=progress
67
losetup -d $shim_loop
68
}
69
70
#copy the kernel image then extract the initramfs
71
extract_initramfs_full() {
72
local shim_path="$1"
73
local rootfs_dir="$2"
74
local kernel_bin="$3"
75
local arch="$4"
76
local kernel_dir=/tmp/shim_kernel
77
78
echo "copying the shim kernel"
79
rm -rf $kernel_dir
80
mkdir $kernel_dir -p
81
copy_kernel $shim_path $kernel_dir
82
83
echo "extracting initramfs from kernel (this may take a while)"
84
if [ "$arch" = "arm64" ]; then
85
extract_initramfs_arm $kernel_dir/kernel.bin $kernel_dir $rootfs_dir
86
else
87
extract_initramfs $kernel_dir/kernel.bin $kernel_dir $rootfs_dir
88
fi
89
90
if [ "$kernel_bin" ]; then
91
cp $kernel_dir/kernel.bin $kernel_bin
92
fi
93
rm -rf $kernel_dir
94
}
95