Skip to content

Commit 2e29fac

Browse files
committed
Adding bit diff finder - wip tool to generate dict that can be used for computing crc for novel messages
1 parent eabff31 commit 2e29fac

File tree

2 files changed

+318
-19
lines changed

2 files changed

+318
-19
lines changed

analysis/bit_diff_finder.ipynb

+313
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 48,
6+
"metadata": {
7+
"collapsed": false
8+
},
9+
"outputs": [],
10+
"source": [
11+
"import pandas as pd\n",
12+
"%matplotlib inline\n",
13+
"import matplotlib\n",
14+
"import numpy as np\n",
15+
"import matplotlib.pyplot as plt\n",
16+
"import dateutil\n",
17+
"import analysis\n",
18+
"import itertools\n",
19+
"\n",
20+
"packets = analysis.parse_packet_file('data/all.txt')\n",
21+
"packets += analysis.parse_packet_file('data/temp_basals.txt')\n",
22+
"\n",
23+
"\n",
24+
"# Select valid packets of a particular length\n",
25+
"packets = filter(lambda x: x.is_valid() and x.body_len == 10, packets)\n",
26+
"\n",
27+
"# Uncomment if you want to work with less data (faster while developing)\n",
28+
"packets = packets[0:100]"
29+
]
30+
},
31+
{
32+
"cell_type": "code",
33+
"execution_count": 49,
34+
"metadata": {
35+
"collapsed": false
36+
},
37+
"outputs": [],
38+
"source": [
39+
"def diff(m1,m2):\n",
40+
" xored_bytes = [ord(a) ^ ord(b) for a,b in zip(m1,m2)]\n",
41+
" return xored_bytes\n",
42+
"\n",
43+
"def bits(data):\n",
44+
" return np.unpackbits(np.frombuffer(data, dtype=np.uint8))\n",
45+
"\n",
46+
"def join_ints(ints):\n",
47+
" return ':'.join(str(x) for x in ints)"
48+
]
49+
},
50+
{
51+
"cell_type": "code",
52+
"execution_count": 61,
53+
"metadata": {
54+
"collapsed": false
55+
},
56+
"outputs": [],
57+
"source": [
58+
"class DiffMessage(object):\n",
59+
"\n",
60+
" # data is passed in like this: ((m1,c1),(m2,c2))\n",
61+
" def __init__(self, combination):\n",
62+
" self.m1 = combination[0][0]\n",
63+
" self.c1 = combination[0][1]\n",
64+
" self.m2 = combination[1][0]\n",
65+
" self.c2 = combination[1][1]\n",
66+
" \n",
67+
" # diffs\n",
68+
" self.dm = diff(self.m1, self.m2)\n",
69+
" self.dc = diff(self.c1, self.c2)\n",
70+
" \n",
71+
" # diff stats\n",
72+
" diff_bits = np.unpackbits(np.array(self.dm, dtype=np.uint8))\n",
73+
" self.diff_bits_count = diff_bits.sum()\n",
74+
" self.diff_bits_key = join_ints(np.where(diff_bits)[0].tolist())\n",
75+
" \n",
76+
" self.confirmations = 0\n",
77+
" self.conflicts = 0\n",
78+
" \n",
79+
" def update_observation(self, other):\n",
80+
" if other.dc == self.dc:\n",
81+
" self.confirmations += 1\n",
82+
" else:\n",
83+
" self.conflicts += 1\n",
84+
" \n",
85+
" def __str__(self):\n",
86+
" return \"%s: msg=%s, crc=%s\" % (self.diff_bits_key, self.dm, self.dc)\n",
87+
" \n"
88+
]
89+
},
90+
{
91+
"cell_type": "code",
92+
"execution_count": 4,
93+
"metadata": {
94+
"collapsed": false
95+
},
96+
"outputs": [
97+
{
98+
"name": "stdout",
99+
"output_type": "stream",
100+
"text": [
101+
"2016-06-26T20:33:28.412197 ID1:1f01482a PTYPE:PDM SEQ:13 ID2:1f01482a B9:10 BLEN:3 MTYPE:0e01 BODY:00802c CRC:88\n"
102+
]
103+
}
104+
],
105+
"source": [
106+
"print packets[0]"
107+
]
108+
},
109+
{
110+
"cell_type": "code",
111+
"execution_count": 5,
112+
"metadata": {
113+
"collapsed": false
114+
},
115+
"outputs": [
116+
{
117+
"name": "stdout",
118+
"output_type": "stream",
119+
"text": [
120+
"1f01482aad1f01482a10030e0100802c88\n"
121+
]
122+
}
123+
],
124+
"source": [
125+
"print packets[0].tx_data().encode('hex')"
126+
]
127+
},
128+
{
129+
"cell_type": "code",
130+
"execution_count": 67,
131+
"metadata": {
132+
"collapsed": false
133+
},
134+
"outputs": [],
135+
"source": [
136+
"# This expresses our theory about which bits are CRC, and which bits\n",
137+
"# are included in CRC calculation. Takes a full message and splits it\n",
138+
"# into message,crc\n",
139+
"def parts(data):\n",
140+
" msg = data[5:-3] # Everything except ID1, byte 4 (sequence & flags), packet crc, and 16bit chksum\n",
141+
" chksum = data[-3:-1]\n",
142+
" return (msg, chksum)\n",
143+
"\n",
144+
"data = [parts(p.tx_data()) for p in packets]\n",
145+
"#diffs = [DiffMessage(c) for c in itertools.combinations(data, 2)]\n",
146+
"\n",
147+
"cracked_bits_dict = {}\n",
148+
"for c in itertools.combinations(data, 2):\n",
149+
" d = DiffMessage(c)\n",
150+
" if d.diff_bits_count == 0:\n",
151+
" continue\n",
152+
" if d.diff_bits_key in cracked_bits_dict:\n",
153+
" cracked_bits_dict[d.diff_bits_key].update_observation(d)\n",
154+
" else:\n",
155+
" cracked_bits_dict[d.diff_bits_key] = d\n",
156+
" \n"
157+
]
158+
},
159+
{
160+
"cell_type": "code",
161+
"execution_count": 68,
162+
"metadata": {
163+
"collapsed": false
164+
},
165+
"outputs": [
166+
{
167+
"data": {
168+
"text/plain": [
169+
"['36', '35', '34']"
170+
]
171+
},
172+
"execution_count": 68,
173+
"metadata": {},
174+
"output_type": "execute_result"
175+
}
176+
],
177+
"source": [
178+
"[key for key in cracked_bits_dict.keys() if len(key.split(':')) == 1]"
179+
]
180+
},
181+
{
182+
"cell_type": "code",
183+
"execution_count": 76,
184+
"metadata": {
185+
"collapsed": false
186+
},
187+
"outputs": [
188+
{
189+
"name": "stdout",
190+
"output_type": "stream",
191+
"text": [
192+
"36:80:115: msg=[0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 128, 0, 0, 0, 16, 0], crc=[129, 61]\n"
193+
]
194+
}
195+
],
196+
"source": [
197+
"print cracked_bits_dict['36:80:115']"
198+
]
199+
},
200+
{
201+
"cell_type": "code",
202+
"execution_count": 73,
203+
"metadata": {
204+
"collapsed": false
205+
},
206+
"outputs": [
207+
{
208+
"data": {
209+
"text/plain": [
210+
"['35:36',\n",
211+
" '35:80',\n",
212+
" '78:114',\n",
213+
" '80:116',\n",
214+
" '80:115',\n",
215+
" '34:35',\n",
216+
" '34:36',\n",
217+
" '35:37',\n",
218+
" '34:117',\n",
219+
" '34:116',\n",
220+
" '36:116',\n",
221+
" '35:116',\n",
222+
" '35:117',\n",
223+
" '36:37']"
224+
]
225+
},
226+
"execution_count": 73,
227+
"metadata": {},
228+
"output_type": "execute_result"
229+
}
230+
],
231+
"source": [
232+
"[key for key in cracked_bits_dict.keys() if len(key.split(':')) == 2]"
233+
]
234+
},
235+
{
236+
"cell_type": "code",
237+
"execution_count": 56,
238+
"metadata": {
239+
"collapsed": false,
240+
"scrolled": false
241+
},
242+
"outputs": [
243+
{
244+
"data": {
245+
"text/plain": [
246+
"['36:78:114',\n",
247+
" '34:37:117',\n",
248+
" '36:80:116',\n",
249+
" '36:80:115',\n",
250+
" '79:115:117',\n",
251+
" '79:115:116',\n",
252+
" '35:36:37',\n",
253+
" '35:115:116',\n",
254+
" '79:80:114',\n",
255+
" '34:36:117',\n",
256+
" '34:36:116',\n",
257+
" '34:35:80',\n",
258+
" '36:37:117',\n",
259+
" '35:37:117',\n",
260+
" '35:36:80',\n",
261+
" '34:35:117',\n",
262+
" '36:79:80',\n",
263+
" '34:116:117',\n",
264+
" '79:114:116',\n",
265+
" '79:114:117',\n",
266+
" '79:114:115',\n",
267+
" '34:35:36',\n",
268+
" '34:36:80',\n",
269+
" '34:80:115',\n",
270+
" '34:80:116',\n",
271+
" '34:80:117',\n",
272+
" '35:36:116',\n",
273+
" '35:79:115',\n",
274+
" '36:116:117',\n",
275+
" '35:116:117',\n",
276+
" '36:79:115',\n",
277+
" '35:80:116',\n",
278+
" '35:36:117',\n",
279+
" '80:115:117']"
280+
]
281+
},
282+
"execution_count": 56,
283+
"metadata": {},
284+
"output_type": "execute_result"
285+
}
286+
],
287+
"source": [
288+
"[key for key in cracked_bits_dict.keys() if len(key.split(':')) == 3]"
289+
]
290+
}
291+
],
292+
"metadata": {
293+
"kernelspec": {
294+
"display_name": "Python 2",
295+
"language": "python",
296+
"name": "python2"
297+
},
298+
"language_info": {
299+
"codemirror_mode": {
300+
"name": "ipython",
301+
"version": 2
302+
},
303+
"file_extension": ".py",
304+
"mimetype": "text/x-python",
305+
"name": "python",
306+
"nbconvert_exporter": "python",
307+
"pygments_lexer": "ipython2",
308+
"version": "2.7.11"
309+
}
310+
},
311+
"nbformat": 4,
312+
"nbformat_minor": 0
313+
}

analysis/crcplay.ipynb

+5-19
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
"import numpy as np\n",
1717
"import matplotlib.pyplot as plt\n",
1818
"\n",
19-
"\n",
2019
"# Flip a bit in a messsage\n",
2120
"def flip_bit(msg, idx):\n",
2221
" bit_offset = idx % 8\n",
@@ -42,18 +41,7 @@
4241
"metadata": {
4342
"collapsed": false
4443
},
45-
"outputs": [
46-
{
47-
"data": {
48-
"text/plain": [
49-
"'000000000c00000000000000000000000341'"
50-
]
51-
},
52-
"execution_count": 2,
53-
"metadata": {},
54-
"output_type": "execute_result"
55-
}
56-
],
44+
"outputs": [],
5745
"source": [
5846
"# 1f014829080a1d1802ad2800002bdfff83c5 xor \n",
5947
"# 1f014829100a1d1802ad2800002bdfff014b = \n",
@@ -68,9 +56,7 @@
6856
"# 000000000c00000000000000000000000341\n",
6957
"\n",
7058
"# C2 = 0341\n",
71-
"# B1 xor B2 = 000000000c0000000000000000000000 0341\n",
72-
"diff1 = xor_strings(\"1f02d5af180a1d1801d9180000102fff020a\".decode('hex'), \"1f02d5af140a1d1801d9180000102fff014b\".decode('hex'))\n",
73-
"diff1.encode('hex')"
59+
"# B1 xor B2 = 000000000c0000000000000000000000 0341\n"
7460
]
7561
},
7662
{
@@ -82,7 +68,7 @@
8268
},
8369
{
8470
"cell_type": "code",
85-
"execution_count": 51,
71+
"execution_count": 3,
8672
"metadata": {
8773
"collapsed": false
8874
},
@@ -166,7 +152,7 @@
166152
},
167153
{
168154
"cell_type": "code",
169-
"execution_count": 56,
155+
"execution_count": 4,
170156
"metadata": {
171157
"collapsed": true
172158
},
@@ -209,7 +195,7 @@
209195
},
210196
{
211197
"cell_type": "code",
212-
"execution_count": 62,
198+
"execution_count": 5,
213199
"metadata": {
214200
"collapsed": false
215201
},

0 commit comments

Comments
 (0)