Last active
August 10, 2021 12:57
-
-
Save al3xtjames/b6a9db46b14061d4c995 to your computer and use it in GitHub Desktop.
Deprecated - Use https://github.com/al3xtjames/MacGen instead
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Simple Main Logic Board (MLB) Serial Generator Script by TheRacerMaster | |
# Based off the work of Hanger1, AGuyWhoIsBored & Alien:X | |
# NOTE: This is a simple script that doesn't do any checking of other SMBIOS values. It needs valid SMBIOS data which includes the following: | |
# - Valid SmUUID value in Clover config.plist under SMBIOS (generated using uuidgen) | |
# - ROM value set to UseMacAddr0 in Clover config.plist (uses MAC address of your first NIC as ROM value) | |
# - Properly formatted serial number (doesn't have to be a real one, just formatted properly) in Clover config.plist under SMBIOS | |
# - Don't use a generic serial number (such as Clover's default)! It needs to be at least semi-unique. | |
# - Try using a generated serial number that isn't real (but formatted correctly) from Clover Configurator, Chameleon Wizard, etc. | |
# - You can check if a serial number is real here: https://selfsolve.apple.com/agreementWarrantyDynamic.do | |
# | |
# After getting a value, insert it in Clover config.plist under RtVariables -> MLB, then reboot | |
# Try logging into iMessage. If you get a customer code, call Apple and go through the process. | |
# iMessage should work after going through the customer support process. | |
# | |
# Changelog: | |
# Version 1.1 - Add user input support; you can now input a serial number (as an argument: ./simpleMLB.sh XXXXXXXXXXXX) and the script will use that to generate a MLB | |
# Version 1.2 - Add more input checks for valid serial number and working internet connection; added support for generating 13 character MLB (does it if serial number is 11 characters) | |
# Version 1.3 - Fixed some bugs; removed internet connection requirement; now, the script gets week and year numbers from the serial number itself (more accurate than random generation) | |
# Version 1.4 - Added debug mode which prints info about the serial number and each step of the MLB generation process | |
# If user input is valid, use that instead of the serial number of the current machine from IORegistry | |
if [ ! -z "$1" -a ${#1} == 11 ]; then | |
MLBFormat=1 # 11 character SN = 13 character MLB | |
SN="$1" | |
elif [ ! -z "$1" -a ${#1} == 12 ]; then | |
MLBFormat=2 # 12 character SN = 17 character MLB | |
SN="$1" | |
# Otherwise use the serial number of the current machine from IORegistry | |
else | |
SN=$(ioreg -l | awk '/IOPlatformSerialNumber/ { print $4;}' | cut -d'"' -f2) | |
if [ ${#SN} == 11 ]; then | |
MLBFormat=1 | |
elif [ ${#SN} == 12 ]; then | |
MLBFormat=2 | |
else | |
echo "Error: Invalid serial number in IORegistry!" | |
exit 128 | |
fi | |
fi | |
# Check for debug mode | |
if [ "$1" == "-debug" ] || [ "$2" == "-debug" ]; then | |
debug=1 | |
fi | |
# Debug | |
if [ "$debug" == 1 ]; then | |
if [ "$MLBFormat" == 1 ]; then | |
echo "Input serial number:" $SN "(12 characters)" | |
else | |
echo "Input serial number:" $SN "(13 characters)" | |
fi | |
fi | |
# Get the manufacture year from the serial number | |
if [ "$MLBFormat" == 1 ]; then | |
serialNumberYear=$(echo $SN | cut -c 3) # 11-digit serials store the year in the serial number, so we'll just use that | |
else | |
serialNumberYear=$(echo $SN | cut -c 4) # 12-digit serials store them as letters, so we'll need to decode them first | |
case "$serialNumberYear" in | |
C | D) manufactureYear=0;; | |
F | G) manufactureYear=1;; | |
H | J) manufactureYear=2;; | |
K | L) manufactureYear=3;; | |
M | N) manufactureYear=4;; | |
P | Q) manufactureYear=5;; | |
R | S) manufactureYear=6;; | |
T | V) manufactureYear=7;; | |
W | X) manufactureYear=8;; | |
Y | Z) manufactureYear=9;; | |
*) | |
echo "Error: Invalid serial number (reason: invalid year)!" | |
exit 128;; | |
esac | |
fi | |
# Debug | |
if [ "$debug" == 1 ]; then | |
if [ "$MLBFormat" == 1 ]; then | |
case "$serialNumberYear" in | |
0) year=2010;; | |
1) year=2011;; | |
2) year=2002;; | |
3) year=2003;; | |
4) year=2004;; | |
5) year=2005;; | |
6) year=2006;; | |
7) year=2007;; | |
8) year=2008;; | |
9) year=2009;; | |
esac | |
else | |
case "$manufactureYear" in | |
0) year=2010;; | |
1) year=2011;; | |
2) year=2012;; | |
3) year=2013;; | |
4) year=2014;; | |
5) year=2015;; | |
6) year=2016;; | |
7) year=2017;; | |
8) year=2018;; | |
9) year=2019;; | |
esac | |
fi | |
echo "Year of manufacture (from serial number):" $year | |
fi | |
# Get the week number from the serial number | |
if [ "$MLBFormat" == 1 ]; then # 11-digit serial numbers store the week number as two digits, so no decoding needed | |
if [[ $(echo $SN | cut -c 4-5) =~ ^-?[01-53]+$ ]]; then | |
weekNumber=$(echo $SN | cut -c 4-5) | |
else | |
echo "Error: Invalid serial number (reason: invalid week number)!" | |
exit 128 | |
fi | |
else | |
serialNumberYear=$(echo $SN | cut -c 4) | |
case "$serialNumberYear" in | |
D | G | J | L | N | Q | S | V | X | Z) weekNumber=27;; # These serial number year values are offset by 27 weeks | |
esac | |
serialNumberWeek=$(echo $SN | cut -c 5) | |
case "$serialNumberWeek" in | |
[1-9]) ((weekNumber+=$serialNumberWeek));; | |
C) ((weekNumber+=10));; | |
D) ((weekNumber+=11));; | |
F) ((weekNumber+=12));; | |
G) ((weekNumber+=13));; | |
H) ((weekNumber+=14));; | |
K) ((weekNumber+=15));; | |
L) ((weekNumber+=16));; | |
M) ((weekNumber+=17));; | |
N) ((weekNumber+=18));; | |
P) ((weekNumber+=19));; | |
Q) ((weekNumber+=20));; | |
R) ((weekNumber+=21));; | |
S) ((weekNumber+=22));; | |
T) ((weekNumber+=23));; | |
U) ((weekNumber+=24));; | |
V) ((weekNumber+=25));; | |
W) ((weekNumber+=26));; | |
X) ((weekNumber+=27));; | |
Y) ((weekNumber+=28));; | |
*) | |
echo "Error: Invalid serial number (reason: invalid week number)!" | |
exit 128;; | |
esac | |
fi | |
# Debug | |
if [ "$debug" == 1 ]; then | |
echo "Week of manufacture (from serial number):" $weekNumber | |
fi | |
if [ "$MLBFormat" == 1 ]; then | |
# Get the PP value (manufacture location) from the serial number | |
PP=$(echo $SN | cut -c 1-2) | |
# Get the SSSS value (production number) from the serial number | |
SSSS=$(echo $SN | cut -c 6-8) | |
# Generate a random (yet valid) CCCC value (model ID) | |
BASE62=($(echo {0..9} {a..z} {A..Z})) | |
partNumber=$(echo $(($RANDOM*7584284)) | cut -c 1-8) | |
for i in $(bc <<< "obase=36; $partNumber"); do | |
echo ${BASE62[$(( 10#$i ))]} | tr "\\n" "," | tr -d , >> tmpCCCC | |
done | |
CCCC=$(cat tmpCCCC | cut -c 1-4 | tr '[:lower:]' '[:upper:]') | |
rm tmpCCCC | |
# TODO: Base the CCCC off the model identifier in the 11-digit serial | |
MLB=$PP$serialNumberYear$weekNumber"0"$SSSS$CCCC | |
# Debug/Print MLB | |
if [ "$debug" == 1 ]; then | |
case "$PP" in | |
F | FC | XA | XB | QP | G8) location="United States";; | |
RN) location="Mexico";; | |
CK) location="Ireland";; | |
SE | E) location="Singapore";; | |
MB) location-"Malaysia";; | |
PT | CY) location="Korea";; | |
EE | QT | UV) location="Taiwan";; | |
1C | 4H | W8 | YM | VM | MQ | 7J) location="China";; | |
RM) location="Refurbished/Remanufactured";; | |
esac | |
echo "Manufacture location (from serial number):" $location | |
echo "Production number (from serial number):" $SSSS | |
echo "Generated CCCC value:" $CCCC | |
echo "Generated Main Logic Board (MLB) serial number:" $MLB "(13 characters)" | |
else | |
echo $MLB # Print the generated MLB value | |
fi | |
elif [ "$MLBFormat" = 2 ]; then | |
# Get the SSS value (manufacture location) from the serial number | |
SSS=$(echo $SN | cut -c1-3) | |
# Generate a random (yet valid) TTT value (board serial) | |
declare -a TTTCodes=('200' '600' '403' '404' '405' '303' '108' '207' '609' '501' '306' '102' '701' '301' '501' '101' '300' '130' '100' '270' '310' '902' '104' '401' '902' '500' '700' '802') | |
TTTIndex=$( jot -r 1 0 $((${#TTTCodes[@]} - 1)) ) | |
TTT=${TTTCodes[TTTIndex]} | |
# Generate a random (yet valid) CC value | |
declare -a CCCodes=('GU' '4N' 'J9' 'QX' 'OP' 'CD' 'GU') | |
CCIndex=$( jot -r 1 0 $((${#CCCodes[@]} - 1)) ) | |
CC=${CCCodes[CCIndex]} | |
# Generate a random (yet valid) EEEE value | |
declare -a EEEECodes=('DYWF' 'F117' 'F502' 'F505' 'F9GY' 'F9H0' 'F9H1' 'F9H2' 'DYWD' 'F504' 'F116' 'F503' 'F2FR' 'F653' 'F49P' 'F651' 'F49R' 'F652' 'DYW3' 'F64V' 'F0V5' 'F64W' 'FF4G' 'FF4H' 'FF4J' 'FF4K' 'FF4L' 'FF4M' 'FF4N' 'FF4P' 'DNY3' 'DP00' 'DJWK' 'DM66' 'DNJK' 'DKG1' 'DM65' 'DNJJ' 'DKG2' 'DM67' 'DNJL' 'DJWM' 'DMT3' 'DMT5' 'DJWN' 'DM69' 'DJWP' 'DM6C') | |
EEEEIndex=$( jot -r 1 0 $((${#EEEECodes[@]} - 1)) ) | |
EEEE=${EEEECodes[EEEEIndex]} | |
# Generating a random (yet valid) KK value | |
declare -a KKCodes=('1H' '1M' 'AD' '1F' 'A8' 'UE' 'JA' 'JC' '8C' 'CB' 'FB') | |
KKIndex=$( jot -r 1 0 $((${#KKCodes[@]} - 1)) ) | |
KK=${KKCodes[KKIndex]} | |
MLB=$SSS$manufactureYear$weekNumber$TTT$CC$EEEE$KK | |
# Debug/Print MLB | |
if [ "$debug" == 1 ]; then | |
case "$SSS" in | |
CK2) location="Cork, Ireland";; | |
C02) location="Quanta Computer, China";; | |
esac | |
echo "Manufacture location (from serial number):" $location | |
echo "Generated TTT value:" $TTT | |
echo "Generated CC value:" $CC | |
echo "Generated EEEE value:" $EEEE | |
echo "Generated KK value:" $KK | |
echo "Generated Main Logic Board (MLB) serial number:" $MLB "(17 characters)" | |
else | |
echo $MLB # Print the generated MLB value | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Shouldn't line 50 be 11 characters and line 52 be 12 characters?
Line 112 always fails for me as the regexp doesn't find the characters. This works for me:
if [[ $(echo $SN | cut -c 4-5) =~ ^(-|[0-4])[0-9]|[5][0-3]+$ ]]; then