mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-11 14:02:52 +02:00
688e508175
Bruteforce it. Some executables are just using inno archival but some are simple LZMA. This patch handles both of them, and also the event where you have LZMA compressed files (even LZMA compressed files within LZMA compressed archives) within any inno/lzma compressed executable. It recursively scans inside a vendor update, to find a me.bin files for neutering with me_cleaner. This is in preparation for two new ports in Libreboot: * HP EliteBook 8560w * Apple MacBook Air 4,2 (2011) This script can literally be used with multiple vendors now. It is no longer specific just to Lenovo. I originally did this and other recent commits to the file, as one big commit, but I decided to split it all up into small commits.
224 lines
5.6 KiB
Bash
Executable File
224 lines
5.6 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
|
|
# SPDX-FileCopyrightText: 2022 Caleb La Grange <thonkpeasant@protonmail.com>
|
|
# SPDX-FileCopyrightText: 2022 Ferass El Hafidi <vitali64pmemail@protonmail.com>
|
|
# SPDX-FileCopyrightText: 2023 Leah Rowe <info@minifree.org>
|
|
# SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
_7ztest="a"
|
|
mecleaner="$(pwd)/me_cleaner/me_cleaner.py"
|
|
me7updateparser="$(pwd)/resources/blobs/me7_update_parser.py"
|
|
board="${1}"
|
|
# A shorthand for each board, to avoid duplicating configs per flash size
|
|
board_short=${board%%_*mb}
|
|
|
|
set -- "resources/coreboot/${board}/config/*"
|
|
. ${1} 2>/dev/null
|
|
. "resources/coreboot/${board}/board.cfg"
|
|
|
|
if [ "${CONFIG_HAVE_MRC}" = "y" ]; then
|
|
printf 'haswell board detected, downloading mrc\n'
|
|
needs="${needs} MRC"
|
|
fi
|
|
|
|
if [ "${CONFIG_HAVE_IFD_BIN}" = "y" ]; then
|
|
printf 'board needs intel firmware descriptor\n'
|
|
needs="${needs} IFD"
|
|
fi
|
|
|
|
if [ "${CONFIG_HAVE_ME_BIN}" = "y" ]; then
|
|
printf 'board needs intel management engine\n'
|
|
needs="${needs} ME"
|
|
fi
|
|
|
|
if [ "${CONFIG_HAVE_GBE_BIN}" = "y" ]; then
|
|
printf 'board needs gigabit ethernet firmware\n'
|
|
needs="${needs} GBE"
|
|
fi
|
|
|
|
# Quickly exit without wasting more time if there are no blobs needed (GM45)
|
|
if [ -z ${needs+x} ]; then
|
|
printf 'No binary blobs needed for this board\n'
|
|
exit 0
|
|
fi
|
|
|
|
while read -r line ; do
|
|
case ${line} in
|
|
DL_hash*)
|
|
set ${line}
|
|
dl_hash=${2}
|
|
;;
|
|
DL_url*)
|
|
set ${line}
|
|
dl_url=${2}
|
|
;;
|
|
DL_url_bkup*)
|
|
set ${line}
|
|
dl_url_bkup=${2}
|
|
;;
|
|
esac
|
|
done << EOF
|
|
$(eval "awk ' /\{.*${board_short}.*}{/ {flag=1;next} /\}/{flag=0} flag { print }' resources/blobs/sources")
|
|
EOF
|
|
|
|
Main() {
|
|
Build_deps
|
|
Download_needed
|
|
}
|
|
|
|
Fail(){
|
|
printf "\nERROR: $@\n"
|
|
exit 1
|
|
}
|
|
|
|
Build_deps(){
|
|
if [ ! -d me_cleaner ]; then
|
|
printf "downloading me_cleaner\n"
|
|
./download me_cleaner || Fail 'could not download me_cleaner'
|
|
fi
|
|
|
|
if [ ! -d coreboot/default ]; then
|
|
printf "downloading coreboot\n"
|
|
./download coreboot default || Fail 'could not download coreboot'
|
|
fi
|
|
|
|
if [ ! -f "coreboot/default/util/ifdtool/ifdtool" ]; then
|
|
printf "building ifdtool from coreboot\n"
|
|
make -C coreboot/default/util/ifdtool || Fail 'could not build ifdtool'
|
|
fi
|
|
}
|
|
|
|
Download_needed(){
|
|
for need in ${needs}; do
|
|
case ${need} in
|
|
*ME*)
|
|
Download_me || _failed="${_failed} me"
|
|
;;
|
|
*MRC*)
|
|
./download mrc || _failed="${_failed} mrc"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ ! -z ${_failed+x} ]; then
|
|
Fail "failed to obtain ${_failed}\nYou may try manually extracting blobs with './blobutil extract'"
|
|
fi
|
|
}
|
|
|
|
Download_me() {
|
|
printf "Downloading neutered ME for board: `%s`\n" ${board}
|
|
|
|
Fetch_update || return 1
|
|
Extract_me || return 1
|
|
|
|
return 0
|
|
}
|
|
|
|
Fetch_update() {
|
|
printf "Fetching vendor update for board: `%s`\n" ${board}
|
|
|
|
if [ -z "${dl_url+x}" ]; then
|
|
printf "No vendor update specified for board: `%s`\n" ${board}
|
|
return 1
|
|
fi
|
|
|
|
Vendor_checksum blobs/me.exe || \
|
|
curl ${dl_url} > blobs/me.exe || curl ${dl_url_bkup} > blobs/me.exe
|
|
|
|
Vendor_checksum blobs/me.exe || Fail \
|
|
"Cannot guarantee intergity of vendor update for board: `${board}`"
|
|
|
|
return 0
|
|
}
|
|
|
|
Vendor_checksum() {
|
|
if [ ! -f "blobs/me.exe" ]; then
|
|
printf "Vendor update not found on disk for board: `%s`\n" ${board}
|
|
return 1
|
|
fi
|
|
if [ "$(sha1sum blobs/me.exe | awk '{print $1}')" != "${dl_hash}" ]; then
|
|
printf "Bad checksum on vendor update for board: `%s`\n" ${board}
|
|
rm blobs/me.exe
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
Extract_me(){
|
|
printf "Extracting neutered ME for ${board}\n"
|
|
|
|
_me_destination=${CONFIG_ME_BIN_PATH#../../}
|
|
|
|
if [ ! -d "${_me_destination%/*}" ]; then
|
|
mkdir -p ${_me_destination%/*}
|
|
fi
|
|
|
|
if [ -d "blobs/app" ]; then
|
|
rm -r blobs/app
|
|
fi
|
|
|
|
if [ -f "${_me_destination}" ]; then
|
|
printf 'me already downloaded\n'
|
|
return 0
|
|
fi
|
|
|
|
printf 'extracting and stripping intel management engine\n'
|
|
innoextract blobs/me.exe -d blobs \
|
|
|| 7z x blobs/me.exe -oblobs/app \
|
|
|| Fail 'could not extract me executable with innoextract'
|
|
|
|
Bruteforce_extract_me "$(pwd)/${_me_destination}" "$(pwd)/blobs/app" \
|
|
|| return 1
|
|
|
|
printf "Truncated and cleaned me output to ${_me_destination}\n"
|
|
return 0
|
|
}
|
|
|
|
# cursed, carcinogenic code. TODO rewrite it better
|
|
Bruteforce_extract_me() {
|
|
_me_destination="${1}"
|
|
cdir="${2}" # must be an absolute path, not relative
|
|
|
|
if [ -f "${_me_destination}" ]; then
|
|
return 0
|
|
fi
|
|
|
|
(
|
|
printf "Entering %s\n" "${cdir}"
|
|
cd "${cdir}" || exit 1
|
|
for i in *; do
|
|
if [ -f "${_me_destination}" ]; then
|
|
# me.bin found, so avoid needless further traversal
|
|
break
|
|
elif [ -L "${i}" ]; then
|
|
# symlinks are a security risk, in this context
|
|
continue
|
|
elif [ -f "${i}" ]; then
|
|
"${mecleaner}" -r -t -O "${_me_destination}" "${i}" \
|
|
&& break # (we found me.bin)
|
|
"${me7updateparser}" -O ${_me_destination} "${i}" \
|
|
&& break
|
|
_7ztest="${_7ztest}a"
|
|
7z x "${i}" -o${_7ztest} || continue
|
|
Bruteforce_extract_me "${_me_destination}" "${cdir}/${_7ztest}"
|
|
cdir="${1}"
|
|
cd "${cdir}"
|
|
elif [ -d "$i" ]; then
|
|
Bruteforce_extract_me "${_me_destination}" "${cdir}/${i}"
|
|
cdir="${1}"
|
|
cd "${cdir}"
|
|
else
|
|
printf "SKIPPING: %s\n" "${i}"
|
|
fi
|
|
done
|
|
)
|
|
if [ ! -f "${_me_destination}" ]; then
|
|
printf "me.bin not found in vendor update for board: `%s`\n" ${board}
|
|
return 1
|
|
else
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
Main
|