Ag an PHDays deiridh 9 bhí comórtas againn chun gléasra pumpála gáis a hack - comórtas . Bhí trí sheastán ar an suíomh le paraiméadair slándála éagsúla (Gan Slándáil, Slándáil Íseal, Ard-Slándáil), ag déanamh aithrise ar an bpróiseas tionsclaíoch céanna: rinneadh aer faoi bhrú a phumpáil isteach i mbalún (agus ansin scaoileadh).
In ainneoin na paraiméadair sábháilteachta éagsúla, bhí comhdhéanamh crua-earraí na seastáin mar an gcéanna: sraith Siemens Simatic PLC S7-300; cnaipe díbhoilscithe éigeandála agus feiste tomhais brú (ceangailte le hionchuir dhigiteacha PLC (DI)); comhlaí ag feidhmiú le haghaidh boilscithe agus díbhoilsciú aeir (ceangailte le haschuir dhigiteacha an PLC (DO)) - féach an figiúr thíos.

Rinne an PLC, ag brath ar na léamha brú agus de réir a chláir, cinneadh an liathróid a dhíbhoilsciú nó a inflate (d'oscail agus dhún sé na comhlaí comhfhreagracha). Mar sin féin, bhí modh rialaithe láimhe ag gach seastán, rud a d'fhág gur féidir staid na comhla a rialú gan aon srianta.
Bhí difríocht idir na seastáin maidir leis an gcastacht a bhain leis an modh seo a chumasú: ag an seastán gan chosaint bhí sé níos éasca é seo a dhéanamh, agus ag an seastán Ard-Slándála bhí sé níos deacra dá réir.
Réitíodh cúig cinn de na sé fhadhb i dhá lá; Ghnóthaigh rannpháirtí an chéad áit 233 pointe (chaith sé seachtain ag ullmhú don chomórtas). Trí buaiteoirí: áitím - a1exdandy, II - Rubikoid, III - Ze.
Mar sin féin, le linn PHDays, ní raibh aon cheann de na rannpháirtithe in ann na trí sheastán a shárú, mar sin shocraigh muid a dhéanamh ar chomórtas ar líne agus d'fhoilsigh an tasc is deacra go luath i mí an Mheithimh. Bhí ar na rannpháirtithe an tasc a chríochnú laistigh de mhí, an bhratach a aimsiú, agus cur síos a dhéanamh ar an réiteach go mion agus ar bhealach suimiúil.
Faoi bhun an ghearrtha foilsímid anailís ar an réiteach is fearr ar an tasc uathu siúd a seoladh thar na míosa, fuair Alexey Kovrizhnykh (a1exdandy) ón gcuideachta Slándála Digiteach, a ghlac an XNUMXú áit sa chomórtas le linn PHDays é. Anseo thíos cuirimid a téacs i láthair lenár dtuairimí.
Anailís tosaigh
Mar sin, bhí cartlann leis na comhaid seo a leanas sa tasc:
- block_upload_traffic.pcapng
- DB100.bin
- leideanna.txt
Tá an fhaisnéis agus na leideanna riachtanacha sa chomhad hints.txt chun an tasc a réiteach. Seo a bhfuil ann:
- Dúirt Petrovich liom inné gur féidir leat bloic a luchtú ó PlcSim isteach i gCéim 7.
- Baineadh úsáid as an tsraith Siemens Simatic S7-300 PLC ag an seastán.
- Is aithriseoir PLC é PlcSim a ligeann duit cláir a rith agus a dhífhabhtú do Siemens S7 PLC.
Is cosúil go bhfuil an bloc sonraí DB100 PLC sa chomhad DB100.bin: 00000000: 0100 0102 6e02 0401 0206 0100 0101 0102 ....n......... 00000010: 1002 0501 0202 2002 0501 0206. .............. 0100: 0102 00000020 0102 7702 0401 0206 0100 0103a0102 ..w........... 0: 02 00000030 0501 0202 1602 0501 ...... 0206 0100............0104. 0102: 00000040 7502 0401 0206 0100 0105 0102 0 .........&.... 02: 0501c00000050 0202 1602 0501 0206 0100 0106 : 0102 3402 4 00000060 0401a0206 0100 0107 0102 ................ 2602: 0501 0202 00000070 4a 02 0501 0206 0100 ............ 0108a0102: 3302 0401b 3 00000080 0206 0100 0109 0102 ......".....F... 0b02: 0501 0202 1602c 00000090 0501...".....F... 0206b0100: 010 0102 3702c 0401 0206..." .. 7c000000: 0d 0100 010a0102 2202 0501 0202 4602 0501................ 000000d0: 0206 0100e 010 0102d3302 0401 0206 ... . .... 0100e3: 000000 0 010 0102 0 02 0501 0202 ........#...... 1602f0501: 0206 000000 0 0100 010 0102 ... . ..... 6: 02 0401 0206 0100 010 000000 0 0102 ...... %......... 1102: 0501 0202 2302 0501 0206 0100 ... . ....&. 000000: 0 0110 0102c3502 0401 0206 0100 ....L......
Mar a thugann an t-ainm le fios, tá dumpáil tráchta blocuaslódála chuig an PLC sa chomhad block_upload_traffic.pcapng.
Is fiú a thabhairt faoi deara go raibh an dumpáil tráchta seo ag láithreán an chomórtais le linn na comhdhála beagán níos deacra a fháil. Chun seo a dhéanamh, bhí sé riachtanach an script ón gcomhad tionscadail do TeslaSCADA2 a thuiscint. Bhíothas in ann a thuiscint cá háit a raibh an dumpáil criptithe ag baint úsáide as RC4 suite agus cén eochair ba ghá a úsáid chun é a dhíchriptiú. D’fhéadfaí dumpaí de bhloic sonraí ar an suíomh a fháil trí úsáid a bhaint as an gcliant prótacail S7. Chun seo a úsáid mé an cliant taispeána ón bpacáiste Snap7.
Bloic próiseála comhartha a bhaint as dumpáil tráchta
Ag féachaint ar a bhfuil sa dumpáil, is féidir leat a thuiscint go bhfuil bloic próiseála comhartha OB1, FC1, FC2 agus FC3 ann:

Ní mór na bloic seo a bhaint. Is féidir é seo a dhéanamh, mar shampla, leis an script seo a leanas, tar éis an trácht a thiontú ón bhformáid pcapng go pcap roimhe seo:
#!/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 = ''Tar éis duit na bloic mar thoradh air sin a scrúdú, tabharfaidh tú faoi deara go dtosaíonn siad i gcónaí le bearta 70 70 (pp). Anois ní mór duit a fháil amach conas anailís a dhéanamh orthu. Tugann leid an taisc le fios go gcaithfidh tú PlcSim a úsáid chuige seo.
Treoracha inléite daonna a fháil ó bhloic
Ar dtús, déanaimis iarracht S7-PlcSim a ríomh trí roinnt bloic a luchtú le treoracha athrá (= Q 0.0) isteach ann ag baint úsáide as bogearraí Bainisteoir Simatic, agus an PLC a fhaightear san aithriseoir a shábháil chuig an gcomhad example.plc. Trí bhreathnú ar ábhar an chomhaid, is féidir leat tús na mbloic íoslódála a chinneadh go héasca leis an síniú 70 70, a fuair muid amach níos luaithe. Roimh na bloic, is cosúil, tá an méid bloc scríofa mar luach beag-deireadh 4-beart.

Tar éis dúinn faisnéis a fháil faoi struchtúr na gcomhad cpt, tháinig an plean gníomhaíochta seo a leanas chun solais maidir le cláir PLC S7 a léamh:
- Ag baint úsáide as Simatic Manager, cruthaímid struchtúr bloc i S7-PlcSim cosúil leis an gceann a fuair muid ón dumpáil. Ní mór méideanna na mbloc a mheaitseáil (baintear é seo amach trí na bloic a líonadh leis an líon riachtanach treoracha) agus a n-aitheantóirí (OB1, FC1, FC2, FC3).
- Sábháil an PLC i gcomhad.
- Déanaimid na bloic ón dumpáil tráchta a chur in ionad ábhar na mbloic sa chomhad mar thoradh air. Is é an síniú a chinnfidh tús na mbloic.
- Déanaimid an comhad mar thoradh air a luchtú isteach i S7-PlcSim agus féachaimid ar a bhfuil sna bloic i Simatic Manager.
Is féidir an cód seo a leanas a chur in ionad bloic, mar shampla:
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)Ghlac Alexey cosán b'fhéidir níos deacra, ach fós ceart. Ghlacamar leis go n-úsáidfeadh rannpháirtithe an clár NetToPlcSim ionas go bhféadfadh PlcSim cumarsáid a dhéanamh thar an líonra, bloic a uaslódáil chuig PlcSim trí Snap7, agus ansin na bloic seo a íoslódáil mar thionscadal ó PlcSim ag baint úsáide as an timpeallacht forbartha.
Tríd an gcomhad mar thoradh air a oscailt in S7-PlcSim, is féidir leat na bloic fhorscríofa a léamh ag baint úsáide as an mBainisteoir Simatic. Déantar príomhfheidhmeanna rialaithe an fheiste a thaifeadadh i bloc FC1. Is díol suntais ar leith an athróg #TEMP0, agus nuair a chuirtear ar siúl é is cosúil go socraíonn sé an rialú PLC go mód láimhe bunaithe ar luachanna cuimhne giotán M2.2 agus M2.3. Tá an luach #TEMP0 socraithe ag feidhm FC3.

Chun an fhadhb a réiteach, ní mór duit anailís a dhéanamh ar fheidhm FC3 agus tuiscint a fháil ar cad is gá a dhéanamh ionas go dtiocfaidh sé ar ais ar cheann loighciúil.
Socraíodh na bloic próiseála comhartha PLC ag an seastán Slándála Íseal ag an suíomh comórtais ar bhealach comhchosúil, ach chun luach an athróg #TEMP0 a shocrú, bhí sé go leor chun an líne mo bhealach ninja a scríobh isteach sa bhloc DB1. Bhí sé simplí an luach i mbloc a sheiceáil agus ní raibh gá le heolas domhain ar theanga ríomhchlárúcháin na mbloc. Ar ndóigh, ag an leibhéal Ard-Slándála, beidh sé i bhfad níos deacra rialú láimhe a bhaint amach agus is gá tuiscint a fháil ar intricacies na teanga STL (ceann de na bealaí chun an S7 PLC a ríomh).
Bloc droim ar ais FC3
Ábhar an bhloc FC3 i léiriú 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_VALTá an cód sách fada agus d’fhéadfadh cuma casta air ag duine nach bhfuil cur amach aige ar STL. Níl aon chiall le hanailís a dhéanamh ar gach treoir faoi chuimsiú an ailt seo; tá treoracha mionsonraithe agus cumais na teanga STL le fáil sa lámhleabhar comhfhreagrach: . Anseo cuirfidh mé an cód céanna i láthair tar éis próiseála - ag athainmniú na lipéid agus na n-athróg agus ag cur tuairimí leis ag cur síos ar algartam na hoibríochta agus roinnt tógálacha teanga STL. Tabhair faoi deara láithreach go bhfuil meaisín fíorúil sa bhloc atá i gceist a fhorghníomhaíonn roinnt bytecode atá suite sa bhloc DB100, a bhfuil a fhios againn a bhfuil ann. Tá treoracha meaisín fíorúil comhdhéanta de bheart amháin de chód oibriúcháin agus beart argóintí, beart amháin do gach argóint. Tá dhá argóint ag gach treoir mheas; d'ainmnigh mé a luachanna sna tuairimí mar X agus Y.
Cód tar éis próiseála]
# Инициализация различных переменных
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_VALTar éis smaoineamh a fháil ar threoracha an mheaisín fhíorúil, scríobhaimis díchumadóir beag chun an bytecode a pharsáil sa 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))
breakMar thoradh air sin, faigheann muid an cód meaisín fíorúil seo a leanas:
Cóid meaisín fíorúil
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 fheiceann tú, ní dhéanann an clár seo ach seiceáil ar gach carachtar ó DB101 le haghaidh comhionannais go luach áirithe. Is í an líne dheireanach chun gach seiceáil a rith ná: n0w u 4r3 7h3 m4573r. Má chuirtear an líne seo i mbloc DB101, ansin cuirtear rialú láimhe PLC i ngníomh agus beifear in ann an balún a phléascadh nó a dhíbhoilsciú.
Sin é an méid! Léirigh Alexey leibhéal ard eolais ar fiú ninja tionsclaíochta :) Chuireamar duaiseanna cuimhneacha chuig an mbuaiteoir. Míle buíochas do na rannpháirtithe ar fad!
Foinse: will.com
