forked from osresearch/airbreak
-
Notifications
You must be signed in to change notification settings - Fork 0
/
patch-airsense
executable file
·140 lines (115 loc) · 4.12 KB
/
patch-airsense
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/bin/bash
die() { echo >&2 "$*" ; exit 1 ; }
IN=$1
OUT=$2
if [ -z "$IN" -o -z "$OUT" ]; then
die "Usage: $0: stm32.bin stm32-unlocked.bin"
fi
if [ ! -r "$IN" ]; then
die "$IN: can not open input file"
fi
patch() {
offset=`printf "%d" $1`
printf "patching %08x\n" $1
dd bs=1 seek=$offset conv=notrunc of="$OUT" status=none
}
shasum=$( sha256sum $IN | cut -f 1 -d " " )
if [ $shasum = "533b91127aa22e05b933db203ad56c449dc12a8c3fd62f57bd88c472a8061775" ]; then
version="401"
elif [ $shasum = "363a204ba217f31223e929365d58b8f5ce038a7681e362fe157e190c2eacbd30" ]; then
version="306"
else
die "$IN: incompatible firmware version."
fi
echo "Found firmware version: $version"
cp "$IN" "$OUT" || die "$OUT: copy failed"
# also patch up the jump instruction that checks for tamper
printf '\xc0\x46' | patch 0xf0 \
|| die "startup patch failed" \
# and add a message so that we know this is a modified firmware
printf 'HACKED!' | patch 0x17500 || die failed
printf 'NOT FOR USE\x0' | patch 0x1a540 || die failed
printf 'WARNING! WARNING! Ventilator test firmware: Not for humans!\x00' | patch 0x1b860 || die failed
BUILD_FLAGS=0
patch_code() {
#if you want to add the extra breath mode
BUILD_FLAGS=$(( BUILD_FLAGS | (1 << 0) ))
if [ -r breath.bin ] && [ $version = "401" ] ; then
echo "Including breath.bin"
cat breath.bin | patch 0xbb734 || die "binary patch failed"
elif [ -r breath.bin ] && [ $version = "306" ] ; then
echo "Including breath.bin"
cat breath.bin | patch 0xbb4d4 || die "binary patch failed"
else
die "breath.bin not found, did you run make?"
fi
if [ -r graph.bin ]; then
echo "Including graph.bin"
cat graph.bin | patch 0xfd000 || die "graph patch failed"
printf '\x01\xd0\x0f\x08' | patch 0xf9c88 || die "graph fixup failed"
fi
}
unlock_ui_limits() {
BUILD_FLAGS=$(( BUILD_FLAGS | (1 << 1) ))
# patch UI limits to range between 1 and 30
printf '\xdc\x05\x00\x00\x32\x00' | patch 0x4fa8 || die failed
printf '\xdc\x05\x00\x00\x32\x00' | patch 0x4fc4 || die failed
printf '\xdc\x05\x00\x00\x32\x00' | patch 0x7eb0 || die failed
printf '\xdc\x05\x00\x00\x32\x00' | patch 0x7ee8 || die failed
printf '\xdc\x05\x00\x00\x32\x00' | patch 0x7ecc || die failed
}
extra_debug() {
BUILD_FLAGS=$(( BUILD_FLAGS | (1 << 2) ))
# set config variable 0xc value to 4 == enable more debugging data on display
# if you set it to \x0f it will enable four separate display pages of info in sleep report mode
printf '\x04' | patch 0x84a8 || die failed
}
extra_modes() {
BUILD_FLAGS=$(( BUILD_FLAGS | (1 << 3) ))
# add more mode entries, set config 0x0 mask to all bits high
# default is 0x3, which only enables mode 1 (CPAP) and 2 (AutoSet)
# ---> This is the real magic <---
printf '\xff\xff' | patch 0x8590 || die failed
}
extra_menu() {
BUILD_FLAGS=$(( BUILD_FLAGS | (1 << 4) ))
# try enabling extra menu items
printf '\x01\x20' | patch 0x66470
}
# If you want all menu items to always be visible, let this section run
all_menu() {
BUILD_FLAGS=$(( BUILD_FLAGS | (1 << 5) ))
# force status bit 5 always on -- always editable
printf '\x01\x20' | patch 0x6e502
# force status bit 4 always on -- this makes all the inputs show up, regardless of mode
printf '\x01\x20' | patch 0x6e4c4
}
gui_config () {
BUILD_FLAGS=$(( BUILD_FLAGS | (1 << 6) ))
# enable all of the editable options in the settings menu
# by turning on bit 1 of the config entries. All of these variables
# are listed in the gui_create_menus function
GUI_CONFIG=0x4ef4
GUI_CONFIG_SIZE=0x1c
GUI_CONFIG_OFFSET=30
for var in \
0x2f 0x1ec 0x1ed 0x24 0x25 0x1d3 0x1d6 0x1d5 0x1d7 0x26 \
0x1d9 0x1e0 0x1e1 0x1e2 0x1e5 0x1e4 0x1e6 0x1e7 0x1e9 0x1ea 0x1eb \
; do
# set config byte 0 bit 0, 1 and 2, which makes it active
ADDR=`perl -e "printf '%d', $GUI_CONFIG + ($var - $GUI_CONFIG_OFFSET) * $GUI_CONFIG_SIZE"`
printf '\x07\x00' | patch $ADDR
done
}
patch_code
unlock_ui_limits
extra_debug
extra_modes
extra_menu
#all_menu
gui_config
FLAGSTR=$(printf 'FLAGS=0x%02x' $BUILD_FLAGS)
printf $FLAGSTR | patch 0x17588
COMMIT_HASH=$(git log -n1 --format=format:"%H" | head -c 7)
printf 'GIT=%s\x00' $COMMIT_HASH | patch 0x17764
sha256sum $OUT