Aig na làithean PHDays 9 mu dheireadh chùm sinn farpais gus ionad pumpaidh gas a sheacadh - farpais
A dh 'aindeoin na diofar pharaimearan sàbhailteachd, bha co-dhèanamh bathar-cruaidh nan seasamh mar an ceudna: sreath Siemens Simatic PLC S7-300; putan dìon èiginn agus inneal tomhais cuideam (ceangailte ri cuir a-steach didseatach PLC (DI)); bhalbhaichean ag obair airson atmhorachd agus deflation adhair (ceangailte ri toraidhean didseatach PLC (DO)) - faic am figear gu h-ìosal.
Rinn an PLC, a rèir na leughaidhean cuideam agus a rèir a phrògram, co-dhùnadh am ball a spreadhadh no a thoirt a-steach (dh’ fhosgail agus dhùin e na bhalbhaichean co-fhreagarrach). Ach, bha modh smachd làimhe aig a h-uile ionad, a rinn e comasach smachd a chumail air staid nam bhalbhaichean gun bhacadh sam bith.
Bha na standan eadar-dhealaichte ann an iom-fhillteachd a bhith a’ comasachadh a’ mhodh seo: aig an ionad gun dìon bha e na b’ fhasa seo a dhèanamh, agus aig an ionad tèarainteachd àrd bha e na bu duilghe.
Chaidh còig de na sia duilgheadasan fhuasgladh ann an dà latha; Choisinn a 'chiad chom-pàirtiche 233 puingean (chuir e seachad seachdain ag ullachadh airson a' cho-fharpais). Trì buannaichean: I place - a1exdandy, II - Rubikoid, III - Ze.
Ach, rè PHDays, cha robh e comasach dha gin de na com-pàirtichean faighinn thairis air na trì seataichean, agus mar sin chuir sinn romhainn farpais air-loidhne a dhèanamh agus dh’ fhoillsich sinn an obair as duilghe tràth san Ògmhios. Dh'fheumadh com-pàirtichean an obair a chrìochnachadh taobh a-staigh mìos, lorg a 'bhratach, agus cunntas a thoirt air an fhuasgladh gu mionaideach agus ann an dòigh inntinneach.
Fon gearradh bidh sinn a’ foillseachadh mion-sgrùdadh air an fhuasgladh as fheàrr air a’ ghnìomh bhon fheadhainn a chaidh a chuir a-steach thairis air a’ mhìos, chaidh a lorg le Alexey Kovrizhnykh (a1exdandy) bhon chompanaidh Tèarainteachd Didseatach, a ghabh àite XNUMXd anns a’ cho-fharpais rè PhDays. Gu h-ìosal tha sinn a’ taisbeanadh an teacsa aige leis na beachdan againn.
Mion-sgrùdadh tùsail
Mar sin, bha tasglann anns an obair leis na faidhlichean a leanas:
- block_upload_traffic.pcapng
- DB100.bin
- sanasan.txt
Anns an fhaidhle hints.txt tha am fiosrachadh riatanach agus sanasan gus an obair fhuasgladh. Seo na tha ann:
- Dh'innis Petrovich dhomh an-dè gun urrainn dhut blocaichean a luchdachadh bho PlcSim gu Step7.
- Chaidh an t-sreath Siemens Simatic S7-300 PLC a chleachdadh aig an ionad.
- Tha PlcSim na emuladair PLC a leigeas leat prògraman a ruith agus dì-bhugachadh airson Siemens S7 PLCs.
Tha e coltach gu bheil am faidhle DB100.bin a’ toirt a-steach bloc dàta DB100 PLC: 00000000: 0100 0102 6e02 0401 0206 0100 0101 0102 ....n......... 00000010: 1002 0501 0202 2002 0501. .............. 0206: 0100 0102 00000020 0102 7702 0401 0206 0100a0103 ..w............. 0102: 0 02 00000030 0501 0202 1602 ................ 0501: 0206 0100 0104 0102 00000040 7502 0401a0206 0100 u............... 0105: 0102 0 02 0501 00000050 0202 1602 0501............0206. 0100: 0106 0102 3402 4 00000060 0401 0206 0100 .........&..... 0107: 0102c2602 0501 0202 00000070 4 02 0501 0206 .......... : 0100 0108 0102 3302 0401a3 00000080 0206 0100 ................ 0109: 0102 0 02 0501a 0202 1602 00000090 0501 ............ 0206a0100: 010 0102b 3702 0401 0206 7 000000 0 ......".....F... 0100b010: 0102 2202 0501c 0202 4602 ..0501 ... .. 000000c0: 0206d 0100 010a0102 3302 0401 0206 0100 3 ................ 000000d0: 010 0102e 0 02d0501 0202 1602 ... .f .... 0501e0206: 000000 0 0100 010 0102 6 02 0401 ........#...... 0206f0100: 010 000000 0 0102 1102 0501 .. . . . ..... 0202: 2302 0501 0206 0100 000000 0 0110 0102 ...... %......... 3502: 0401 0206 0100 0111 0102 5 .. . .....&. 00000100: 1202 0501 0202c2502 0501 0206 0100 ....L.....
Mar a tha an t-ainm a’ moladh, anns an fhaidhle block_upload_traffic.pcapng tha cnap de thrafaig luchdachadh suas bloca chun PLC.
Is fhiach a bhith mothachail gu robh an dump trafaic seo aig làrach na farpais rè na co-labhairt beagan na bu duilghe fhaighinn. Gus seo a dhèanamh, bha e riatanach an sgriobt a thuigsinn bhon fhaidhle pròiseict airson TeslaSCADA2. Bhon sin bha e comasach tuigsinn far an robh an dump a chaidh a chrioptachadh le bhith a’ cleachdadh RC4 suidhichte agus dè an iuchair a dh’ fheumar a chleachdadh gus a dhì-chrioptachadh. Gheibheadh dumpaichean de bhlocaichean dàta air an làrach a’ cleachdadh teachdaiche protocol S7. Airson seo chleachd mi an neach-dèiligidh demo bhon phasgan Snap7.
A’ toirt a-mach blocaichean giollachd chomharran bho dump trafaic
A’ coimhead air susbaint an dump, tuigidh tu gu bheil blocaichean giollachd chomharran OB1, FC1, FC2 agus FC3 ann:
Feumar na blocaichean sin a thoirt air falbh. Faodar seo a dhèanamh, mar eisimpleir, leis an sgriobt a leanas, an dèidh dhut an trafaic atharrachadh bhon chruth pcapng gu pcap roimhe:
#!/usr/bin/env python2
import struct
from scapy.all import *
packets = rdpcap('block_upload_traffic.pcap')
s7_hdr_struct = '>BBHHHHBB'
s7_hdr_sz = struct.calcsize(s7_hdr_struct)
tpkt_cotp_sz = 7
names = iter(['OB1.bin', 'FC1.bin', 'FC2.bin', 'FC3.bin'])
buf = ''
for packet in packets:
if packet.getlayer(IP).src == '10.0.102.11':
tpkt_cotp_s7 = str(packet.getlayer(TCP).payload)
if len(tpkt_cotp_s7) < tpkt_cotp_sz + s7_hdr_sz:
continue
s7 = tpkt_cotp_s7[tpkt_cotp_sz:]
s7_hdr = s7[:s7_hdr_sz]
param_sz = struct.unpack(s7_hdr_struct, s7_hdr)[4]
s7_param = s7[12:12+param_sz]
s7_data = s7[12+param_sz:]
if s7_param in ('x1ex00', 'x1ex01'): # upload
buf += s7_data[4:]
elif s7_param == 'x1f':
with open(next(names), 'wb') as f:
f.write(buf)
buf = ''
An dèidh sgrùdadh a dhèanamh air na blocaichean a thig às, chì thu gu bheil iad an-còmhnaidh a’ tòiseachadh le bytes 70 70 (pp). A-nis feumaidh tu ionnsachadh mar a nì thu mion-sgrùdadh orra. Tha an sanas sònrachaidh a’ moladh gum feum thu PlcSim a chleachdadh airson seo.
Faigh stiùireadh a ghabhas leughadh le daoine bho bhlocaichean
An toiseach, feuchaidh sinn ri S7-PlcSim a phrògramadh le bhith a’ luchdachadh grunn bhlocaichean le stiùireadh ath-aithris (= Q 0.0) a-steach ann a’ cleachdadh bathar-bog Simatic Manager, agus a’ sàbhaladh an PLC a gheibhear san emuladair don fhaidhle example.plc. Le bhith a’ coimhead air susbaint an fhaidhle, is urrainn dhut gu furasta toiseach nam blocaichean a chaidh a luchdachadh sìos a dhearbhadh leis an ainm-sgrìobhte 70 70, a lorg sinn na bu thràithe. Ro na blocaichean, a rèir coltais, tha meud a 'bhloc air a sgrìobhadh mar luach beag-endian 4-byte.
Às deidh dhuinn fiosrachadh fhaighinn mu structar faidhlichean plc, nochd am plana gnìomh a leanas airson prògraman PLC S7 a leughadh:
- A 'cleachdadh Simatic Manager, bidh sinn a' cruthachadh structar bloc ann an S7-PlcSim coltach ris an fhear a fhuair sinn bhon dump. Feumaidh meud nam blocaichean a bhith co-ionnan (tha seo air a choileanadh le bhith a 'lìonadh nam blocaichean leis an àireamh riatanach de stiùiridhean) agus an aithnichearan (OB1, FC1, FC2, FC3).
- Sàbhail am PLC gu faidhle.
- Cuiridh sinn na blocaichean bhon dump trafaic an àite susbaint nam blocaichean san fhaidhle a thig às. Tha toiseach nam blocaichean air a dhearbhadh leis an ainm-sgrìobhte.
- Bidh sinn a’ luchdachadh am faidhle a thig às a-steach gu S7-PlcSim agus a’ coimhead air susbaint nam blocaichean ann an Simatic Manager.
Faodar blocaichean a chuir an àite, mar eisimpleir, leis a’ chòd a leanas:
with open('original.plc', 'rb') as f:
plc = f.read()
blocks = []
for fname in ['OB1.bin', 'FC1.bin', 'FC2.bin', 'FC3.bin']:
with open(fname, 'rb') as f:
blocks.append(f.read())
i = plc.find(b'pp')
for block in blocks:
plc = plc[:i] + block + plc[i+len(block):]
i = plc.find(b'pp', i + 1)
with open('target.plc', 'wb') as f:
f.write(plc)
Ghabh Alexei slighe is dòcha nas duilghe, ach fhathast ceart. Ghabh sinn ris gun cleachdadh com-pàirtichean am prògram NetToPlcSim gus am b’ urrainn dha PlcSim conaltradh thairis air an lìonra, blocaichean a luchdachadh suas gu PlcSim tro Snap7, agus an uairsin na blocaichean sin a luchdachadh sìos mar phròiseact bho PlcSim a’ cleachdadh na h-àrainneachd leasachaidh.
Le bhith a’ fosgladh am faidhle a thig às ann an S7-PlcSim, faodaidh tu na blocaichean ath-sgrìobhte a leughadh a’ cleachdadh an Simatic Manager. Tha na prìomh ghnìomhan smachd inneal air an clàradh ann am bloc FC1. Gu sònraichte cudromach tha an caochladair #TEMP0, a tha, nuair a thèid a thionndadh air, a rèir coltais a’ suidheachadh smachd PLC gu modh làimhe stèidhichte air luachan cuimhne bit M2.2 agus M2.3. Tha an luach #TEMP0 air a shuidheachadh le gnìomh FC3.
Gus an duilgheadas fhuasgladh, feumaidh tu gnìomh FC3 a sgrùdadh agus tuigsinn dè a dh’ fheumar a dhèanamh gus am bi e loidsigeach air ais.
Chaidh na blocaichean giullachd chomharran PLC aig an ionad Tèarainteachd Ìosal aig làrach na farpais a chuir air dòigh san aon dòigh, ach gus luach an caochladair #TEMP0 a shuidheachadh, bha e gu leòr an loidhne mo shlighe ninja a sgrìobhadh a-steach don bhloc DB1. Bha e furasta a bhith a’ sgrùdadh an luach ann am bloc agus cha robh feum air eòlas domhainn air cànan prògramadh a’ bhloc. Gu dearbh, aig ìre Tèarainteachd Àrd, bidh e tòrr nas duilghe smachd làimhe a choileanadh agus feumar tuigse fhaighinn air iom-fhillteachd cànan STL (aon de na dòighean air an S7 PLC a phrògramadh).
Bloc air ais FC3
Susbaint a’ bhloc FC3 ann an riochdachadh STL:
L B#16#0
T #TEMP13
T #TEMP15
L P#DBX 0.0
T #TEMP4
CLR
= #TEMP14
M015: L #TEMP4
LAR1
OPN DB 100
L DBLG
TAR1
<=D
JC M016
L DW#16#0
T #TEMP0
L #TEMP6
L W#16#0
<>I
JC M00d
L P#DBX 0.0
LAR1
M00d: L B [AR1,P#0.0]
T #TEMP5
L W#16#1
==I
JC M007
L #TEMP5
L W#16#2
==I
JC M008
L #TEMP5
L W#16#3
==I
JC M00f
L #TEMP5
L W#16#4
==I
JC M00e
L #TEMP5
L W#16#5
==I
JC M011
L #TEMP5
L W#16#6
==I
JC M012
JU M010
M007: +AR1 P#1.0
L P#DBX 0.0
LAR2
L B [AR1,P#0.0]
L C#8
*I
+AR2
+AR1 P#1.0
L B [AR1,P#0.0]
JL M003
JU M001
JU M002
JU M004
M003: JU M005
M001: OPN DB 101
L B [AR2,P#0.0]
T #TEMP0
JU M006
M002: OPN DB 101
L B [AR2,P#0.0]
T #TEMP1
JU M006
M004: OPN DB 101
L B [AR2,P#0.0]
T #TEMP2
JU M006
M00f: +AR1 P#1.0
L B [AR1,P#0.0]
L C#8
*I
T #TEMP11
+AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP7
L P#M 100.0
LAR2
L #TEMP7
L C#8
*I
+AR2
TAR2 #TEMP9
TAR1 #TEMP4
OPN DB 101
L P#DBX 0.0
LAR1
L #TEMP11
+AR1
LAR2 #TEMP9
L B [AR2,P#0.0]
T B [AR1,P#0.0]
L #TEMP4
LAR1
JU M006
M008: +AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP3
+AR1 P#1.0
L B [AR1,P#0.0]
JL M009
JU M00b
JU M00a
JU M00c
M009: JU M005
M00b: L #TEMP3
T #TEMP0
JU M006
M00a: L #TEMP3
T #TEMP1
JU M006
M00c: L #TEMP3
T #TEMP2
JU M006
M00e: +AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP7
L P#M 100.0
LAR2
L #TEMP7
L C#8
*I
+AR2
TAR2 #TEMP9
+AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP8
L P#M 100.0
LAR2
L #TEMP8
L C#8
*I
+AR2
TAR2 #TEMP10
TAR1 #TEMP4
LAR1 #TEMP9
LAR2 #TEMP10
L B [AR1,P#0.0]
L B [AR2,P#0.0]
AW
INVI
T #TEMP12
L B [AR1,P#0.0]
L B [AR2,P#0.0]
OW
L #TEMP12
AW
T B [AR1,P#0.0]
L DW#16#0
T #TEMP0
L MB 101
T #TEMP1
L MB 102
T #TEMP2
L #TEMP4
LAR1
JU M006
M011: +AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP7
L P#M 100.0
LAR2
L #TEMP7
L C#8
*I
+AR2
TAR2 #TEMP9
+AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP8
L P#M 100.0
LAR2
L #TEMP8
L C#8
*I
+AR2
TAR2 #TEMP10
TAR1 #TEMP4
LAR1 #TEMP9
LAR2 #TEMP10
L B [AR1,P#0.0]
L B [AR2,P#0.0]
-I
T B [AR1,P#0.0]
L DW#16#0
T #TEMP0
L MB 101
T #TEMP1
L MB 102
T #TEMP2
L #TEMP4
LAR1
JU M006
M012: L #TEMP15
INC 1
T #TEMP15
+AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP7
L P#M 100.0
LAR2
L #TEMP7
L C#8
*I
+AR2
TAR2 #TEMP9
+AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP8
L P#M 100.0
LAR2
L #TEMP8
L C#8
*I
+AR2
TAR2 #TEMP10
TAR1 #TEMP4
LAR1 #TEMP9
LAR2 #TEMP10
L B [AR1,P#0.0]
L B [AR2,P#0.0]
==I
JCN M013
JU M014
M013: L P#DBX 0.0
LAR1
T #TEMP4
L B#16#0
T #TEMP6
JU M006
M014: L #TEMP4
LAR1
L #TEMP13
L L#1
+I
T #TEMP13
JU M006
M006: L #TEMP0
T MB 100
L #TEMP1
T MB 101
L #TEMP2
T MB 102
+AR1 P#1.0
L #TEMP6
+ 1
T #TEMP6
JU M005
M010: L P#DBX 0.0
LAR1
L 0
T #TEMP6
TAR1 #TEMP4
M005: TAR1 #TEMP4
CLR
= #TEMP16
L #TEMP13
L L#20
==I
S #TEMP16
L #TEMP15
==I
A #TEMP16
JC M017
L #TEMP13
L L#20
<I
S #TEMP16
L #TEMP15
==I
A #TEMP16
JC M018
JU M019
M017: SET
= #TEMP14
JU M016
M018: CLR
= #TEMP14
JU M016
M019: CLR
O #TEMP14
= #RET_VAL
JU M015
M016: CLR
O #TEMP14
= #RET_VAL
Tha an còd gu math fada agus dh’ fhaodadh gum bi e toinnte do chuideigin air nach eil eòlas air STL. Chan eil feum ann mion-sgrùdadh a dhèanamh air gach stiùireadh taobh a-staigh frèam an artaigil seo; gheibhear stiùireadh mionaideach agus comasan cànan STL anns an leabhar-làimhe co-fhreagarrach:
Còd an dèidh giollachd]
# Инициализация различных переменных
L B#16#0
T #CHECK_N # Счетчик успешно пройденных проверок
T #COUNTER_N # Счетчик общего количества проверок
L P#DBX 0.0
T #POINTER # Указатель на текущую инструкцию
CLR
= #PRE_RET_VAL
# Основной цикл работы интерпретатора байт-кода
LOOP: L #POINTER
LAR1
OPN DB 100
L DBLG
TAR1
<=D # Проверка выхода указателя за пределы программы
JC FINISH
L DW#16#0
T #REG0
L #TEMP6
L W#16#0
<>I
JC M00d
L P#DBX 0.0
LAR1
# Конструкция switch - case для обработки различных опкодов
M00d: L B [AR1,P#0.0]
T #OPCODE
L W#16#1
==I
JC OPCODE_1
L #OPCODE
L W#16#2
==I
JC OPCODE_2
L #OPCODE
L W#16#3
==I
JC OPCODE_3
L #OPCODE
L W#16#4
==I
JC OPCODE_4
L #OPCODE
L W#16#5
==I
JC OPCODE_5
L #OPCODE
L W#16#6
==I
JC OPCODE_6
JU OPCODE_OTHER
# Обработчик опкода 01: загрузка значения из DB101[X] в регистр Y
# OP01(X, Y): REG[Y] = DB101[X]
OPCODE_1: +AR1 P#1.0
L P#DBX 0.0
LAR2
L B [AR1,P#0.0] # Загрузка аргумента X (индекс в DB101)
L C#8
*I
+AR2
+AR1 P#1.0
L B [AR1,P#0.0] # Загрузка аргумента Y (индекс регистра)
JL M003 # Аналог switch - case на основе значения Y
JU M001 # для выбора необходимого регистра для записи.
JU M002 # Подобные конструкции используются и в других
JU M004 # операциях ниже для аналогичных целей
M003: JU LOOPEND
M001: OPN DB 101
L B [AR2,P#0.0]
T #REG0 # Запись значения DB101[X] в REG[0]
JU PRE_LOOPEND
M002: OPN DB 101
L B [AR2,P#0.0]
T #REG1 # Запись значения DB101[X] в REG[1]
JU PRE_LOOPEND
M004: OPN DB 101
L B [AR2,P#0.0]
T #REG2 # Запись значения DB101[X] в REG[2]
JU PRE_LOOPEND
# Обработчик опкода 02: загрузка значения X в регистр Y
# OP02(X, Y): REG[Y] = X
OPCODE_2: +AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP3
+AR1 P#1.0
L B [AR1,P#0.0]
JL M009
JU M00b
JU M00a
JU M00c
M009: JU LOOPEND
M00b: L #TEMP3
T #REG0
JU PRE_LOOPEND
M00a: L #TEMP3
T #REG1
JU PRE_LOOPEND
M00c: L #TEMP3
T #REG2
JU PRE_LOOPEND
# Опкод 03 не используется в программе, поэтому пропустим его
...
# Обработчик опкода 04: сравнение регистров X и Y
# OP04(X, Y): REG[0] = 0; REG[X] = (REG[X] == REG[Y])
OPCODE_4: +AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP7 # первый аргумент - X
L P#M 100.0
LAR2
L #TEMP7
L C#8
*I
+AR2
TAR2 #TEMP9 # REG[X]
+AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP8
L P#M 100.0
LAR2
L #TEMP8
L C#8
*I
+AR2
TAR2 #TEMP10 # REG[Y]
TAR1 #POINTER
LAR1 #TEMP9 # REG[X]
LAR2 #TEMP10 # REG[Y]
L B [AR1,P#0.0]
L B [AR2,P#0.0]
AW
INVI
T #TEMP12 # ~(REG[Y] & REG[X])
L B [AR1,P#0.0]
L B [AR2,P#0.0]
OW
L #TEMP12
AW # (~(REG[Y] & REG[X])) & (REG[Y] | REG[X]) - аналог проверки на равенство
T B [AR1,P#0.0]
L DW#16#0
T #REG0
L MB 101
T #REG1
L MB 102
T #REG2
L #POINTER
LAR1
JU PRE_LOOPEND
# Обработчик опкода 05: вычитание регистра Y из X
# OP05(X, Y): REG[0] = 0; REG[X] = REG[X] - REG[Y]
OPCODE_5: +AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP7
L P#M 100.0
LAR2
L #TEMP7
L C#8
*I
+AR2
TAR2 #TEMP9 # REG[X]
+AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP8
L P#M 100.0
LAR2
L #TEMP8
L C#8
*I
+AR2
TAR2 #TEMP10 # REG[Y]
TAR1 #POINTER
LAR1 #TEMP9
LAR2 #TEMP10
L B [AR1,P#0.0]
L B [AR2,P#0.0]
-I # ACCU1 = ACCU2 - ACCU1, REG[X] - REG[Y]
T B [AR1,P#0.0]
L DW#16#0
T #REG0
L MB 101
T #REG1
L MB 102
T #REG2
L #POINTER
LAR1
JU PRE_LOOPEND
# Обработчик опкода 06: инкремент #CHECK_N при равенстве регистров X и Y
# OP06(X, Y): #CHECK_N += (1 if REG[X] == REG[Y] else 0)
OPCODE_6: L #COUNTER_N
INC 1
T #COUNTER_N
+AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP7 # REG[X]
L P#M 100.0
LAR2
L #TEMP7
L C#8
*I
+AR2
TAR2 #TEMP9 # REG[X]
+AR1 P#1.0
L B [AR1,P#0.0]
T #TEMP8
L P#M 100.0
LAR2
L #TEMP8
L C#8
*I
+AR2
TAR2 #TEMP10 # REG[Y]
TAR1 #POINTER
LAR1 #TEMP9 # REG[Y]
LAR2 #TEMP10 # REG[X]
L B [AR1,P#0.0]
L B [AR2,P#0.0]
==I
JCN M013
JU M014
M013: L P#DBX 0.0
LAR1
T #POINTER
L B#16#0
T #TEMP6
JU PRE_LOOPEND
M014: L #POINTER
LAR1
# Инкремент значения #CHECK_N
L #CHECK_N
L L#1
+I
T #CHECK_N
JU PRE_LOOPEND
PRE_LOOPEND: L #REG0
T MB 100
L #REG1
T MB 101
L #REG2
T MB 102
+AR1 P#1.0
L #TEMP6
+ 1
T #TEMP6
JU LOOPEND
OPCODE_OTHER: L P#DBX 0.0
LAR1
L 0
T #TEMP6
TAR1 #POINTER
LOOPEND: TAR1 #POINTER
CLR
= #TEMP16
L #CHECK_N
L L#20
==I
S #TEMP16
L #COUNTER_N
==I
A #TEMP16
# Все проверки пройдены, если #CHECK_N == #COUNTER_N == 20
JC GOOD
L #CHECK_N
L L#20
<I
S #TEMP16
L #COUNTER_N
==I
A #TEMP16
JC FAIL
JU M019
GOOD: SET
= #PRE_RET_VAL
JU FINISH
FAIL: CLR
= #PRE_RET_VAL
JU FINISH
M019: CLR
O #PRE_RET_VAL
= #RET_VAL
JU LOOP
FINISH: CLR
O #PRE_RET_VAL
= #RET_VAL
Às deidh dhuinn beachd fhaighinn air an stiùireadh inneal brìgheil, sgrìobhamaid disassembler beag gus am bytecode a pharsadh anns a’ bhloc DB100:
import string
alph = string.ascii_letters + string.digits
with open('DB100.bin', 'rb') as f:
m = f.read()
pc = 0
while pc < len(m):
op = m[pc]
if op == 1:
print('R{} = DB101[{}]'.format(m[pc + 2], m[pc + 1]))
pc += 3
elif op == 2:
c = chr(m[pc + 1])
c = c if c in alph else '?'
print('R{} = {:02x} ({})'.format(m[pc + 2], m[pc + 1], c))
pc += 3
elif op == 4:
print('R0 = 0; R{} = (R{} == R{})'.format(
m[pc + 1], m[pc + 1], m[pc + 2]))
pc += 3
elif op == 5:
print('R0 = 0; R{} = R{} - R{}'.format(
m[pc + 1], m[pc + 1], m[pc + 2]))
pc += 3
elif op == 6:
print('CHECK (R{} == R{})n'.format(
m[pc + 1], m[pc + 2]))
pc += 3
else:
print('unk opcode {}'.format(op))
break
Mar thoradh air an sin, gheibh sinn an còd inneal brìgheil a leanas:
Còd mas-fhìor machine
R1 = DB101[0]
R2 = 6e (n)
R0 = 0; R1 = (R1 == R2)
CHECK (R1 == R0)
R1 = DB101[1]
R2 = 10 (?)
R0 = 0; R1 = R1 - R2
R2 = 20 (?)
R0 = 0; R1 = R1 - R2
CHECK (R1 == R0)
R1 = DB101[2]
R2 = 77 (w)
R0 = 0; R1 = (R1 == R2)
CHECK (R1 == R0)
R1 = DB101[3]
R2 = 0a (?)
R0 = 0; R1 = R1 - R2
R2 = 16 (?)
R0 = 0; R1 = R1 - R2
CHECK (R1 == R0)
R1 = DB101[4]
R2 = 75 (u)
R0 = 0; R1 = (R1 == R2)
CHECK (R1 == R0)
R1 = DB101[5]
R2 = 0a (?)
R0 = 0; R1 = R1 - R2
R2 = 16 (?)
R0 = 0; R1 = R1 - R2
CHECK (R1 == R0)
R1 = DB101[6]
R2 = 34 (4)
R0 = 0; R1 = (R1 == R2)
CHECK (R1 == R0)
R1 = DB101[7]
R2 = 26 (?)
R0 = 0; R1 = R1 - R2
R2 = 4c (L)
R0 = 0; R1 = R1 - R2
CHECK (R1 == R0)
R1 = DB101[8]
R2 = 33 (3)
R0 = 0; R1 = (R1 == R2)
CHECK (R1 == R0)
R1 = DB101[9]
R2 = 0a (?)
R0 = 0; R1 = R1 - R2
R2 = 16 (?)
R0 = 0; R1 = R1 - R2
CHECK (R1 == R0)
R1 = DB101[10]
R2 = 37 (7)
R0 = 0; R1 = (R1 == R2)
CHECK (R1 == R0)
R1 = DB101[11]
R2 = 22 (?)
R0 = 0; R1 = R1 - R2
R2 = 46 (F)
R0 = 0; R1 = R1 - R2
CHECK (R1 == R0)
R1 = DB101[12]
R2 = 33 (3)
R0 = 0; R1 = (R1 == R2)
CHECK (R1 == R0)
R1 = DB101[13]
R2 = 0a (?)
R0 = 0; R1 = R1 - R2
R2 = 16 (?)
R0 = 0; R1 = R1 - R2
CHECK (R1 == R0)
R1 = DB101[14]
R2 = 6d (m)
R0 = 0; R1 = (R1 == R2)
CHECK (R1 == R0)
R1 = DB101[15]
R2 = 11 (?)
R0 = 0; R1 = R1 - R2
R2 = 23 (?)
R0 = 0; R1 = R1 - R2
CHECK (R1 == R0)
R1 = DB101[16]
R2 = 35 (5)
R0 = 0; R1 = (R1 == R2)
CHECK (R1 == R0)
R1 = DB101[17]
R2 = 12 (?)
R0 = 0; R1 = R1 - R2
R2 = 25 (?)
R0 = 0; R1 = R1 - R2
CHECK (R1 == R0)
R1 = DB101[18]
R2 = 33 (3)
R0 = 0; R1 = (R1 == R2)
CHECK (R1 == R0)
R1 = DB101[19]
R2 = 26 (?)
R0 = 0; R1 = R1 - R2
R2 = 4c (L)
R0 = 0; R1 = R1 - R2
CHECK (R1 == R0)
Mar a chì thu, tha am prògram seo dìreach a’ sgrùdadh gach caractar bho DB101 airson co-ionannachd gu luach sònraichte. Is e an loidhne mu dheireadh airson a bhith a’ dol seachad air a h-uile seic: n0w u 4r3 7h3 m4573r. Ma thèid an loidhne seo a chuir ann am bloc DB101, thèid smachd làimhe PLC a chuir an gnìomh agus bidh e comasach am bailiùn a spreadhadh no a spreadhadh.
Sin e! Sheall Alexey ìre àrd de eòlas a bha airidh air ninja gnìomhachais :) Chuir sinn duaisean cuimhneachail chun bhuannaiche. Mòran taing dha na com-pàirtichean uile!
Source: www.habr.com