ื‘ืขืงื‘ื•ืช ื”ื ื™ื ื’'ื” ื”ืชืขืฉื™ื™ืชื™: ืื™ืš PLC ื ืคืจืฅ ื‘-Positive Hack Days 9

ื‘ืขืงื‘ื•ืช ื”ื ื™ื ื’'ื” ื”ืชืขืฉื™ื™ืชื™: ืื™ืš PLC ื ืคืจืฅ ื‘-Positive Hack Days 9

ื‘-PHDays 9 ื”ืื—ืจื•ื ื™ื ืงื™ื™ืžื ื• ืชื—ืจื•ืช ืœืคืจื™ืฆืช ืžืคืขืœ ืœืฉืื™ื‘ืช ื’ื– - ืชื—ืจื•ืช ื ื™ื ื’'ื” ืชืขืฉื™ื™ืชื™. ื‘ืืชืจ ื”ื™ื• ืฉืœื•ืฉื” ื“ื•ื›ื ื™ื ืขื ืคืจืžื˜ืจื™ ืื‘ื˜ื—ื” ืฉื•ื ื™ื (No Security, Low Security, High Security), ื”ืžื“ืžื™ื ืืช ืื•ืชื• ืชื”ืœื™ืš ืชืขืฉื™ื™ืชื™: ืื•ื•ื™ืจ ื‘ืœื—ืฅ ื ืฉืื‘ ืœื‘ืœื•ืŸ (ื•ืื– ืฉื•ื—ืจืจ).

ืœืžืจื•ืช ืคืจืžื˜ืจื™ ื”ื‘ื˜ื™ื—ื•ืช ื”ืฉื•ื ื™ื, ื”ืจื›ื‘ ื”ื—ื•ืžืจื” ืฉืœ ื”ืžืขืžื“ื™ื ื”ื™ื” ื–ื”ื”: ืกื“ืจืช Siemens Simatic PLC S7-300; ืœื—ืฆืŸ ื ื™ืคื•ื— ื—ื™ืจื•ื ื•ืžื›ืฉื™ืจ ืžื“ื™ื“ืช ืœื—ืฅ (ืžื—ื•ื‘ืจ ืœื›ื ื™ืกื•ืช ื“ื™ื’ื™ื˜ืœื™ื•ืช ืฉืœ PLC (DI)); ืฉืกืชื•ืžื™ื ื”ืคื•ืขืœื™ื ืœื ื™ืคื•ื— ื•ื ื™ืคื•ื— ืื•ื•ื™ืจ (ืžื—ื•ื‘ืจื™ื ืœื™ืฆื™ืื•ืช ื”ื“ื™ื’ื™ื˜ืœื™ื•ืช ืฉืœ ื”-PLC (DO)) - ืจืื” ืืช ื”ืื™ื•ืจ ืฉืœื”ืœืŸ.

ื‘ืขืงื‘ื•ืช ื”ื ื™ื ื’'ื” ื”ืชืขืฉื™ื™ืชื™: ืื™ืš PLC ื ืคืจืฅ ื‘-Positive Hack Days 9

ื”-PLC, ื‘ื”ืชืื ืœืงืจื™ืืช ื”ืœื—ืฅ ื•ื‘ื”ืชืื ืœืชื•ื›ื ื™ืช ืฉืœื•, ืงื™ื‘ืœ ื”ื—ืœื˜ื” ืœืจื•ืงืŸ ืื• ืœื ืคื— ืืช ื”ื›ื“ื•ืจ (ืคืชื— ื•ืกื’ืจ ืืช ื”ืฉืกืชื•ืžื™ื ื”ืžืชืื™ืžื™ื). ืขื ื–ืืช, ืœื›ืœ ื”ื“ื•ื›ื ื™ื ื”ื™ื” ืžืฆื‘ ื‘ืงืจื” ื™ื“ื ื™, ืฉืื™ืคืฉืจ ืœืฉืœื•ื˜ ื‘ืžืฆื‘ื™ ื”ืฉืกืชื•ืžื™ื ืœืœื ื›ืœ ื”ื’ื‘ืœื”.

ื”ื“ื•ื›ื ื™ื ื”ื™ื• ืฉื•ื ื™ื ื‘ืžื•ืจื›ื‘ื•ืช ืฉืœ ื”ืคืขืœืช ืžืฆื‘ ื–ื”: ื‘ืขืžื“ื” ื”ื‘ืœืชื™ ืžื•ื’ื ืช ื–ื” ื”ื™ื” ื”ื›ื™ ืงืœ ืœืขืฉื•ืช ื–ืืช, ื•ื‘ื“ื•ื›ืŸ High Security ื–ื” ื”ื™ื” ื™ื•ืชืจ ืงืฉื” ื‘ื”ืชืื.

ื—ืžืฉ ืžืชื•ืš ืฉืฉ ื”ื‘ืขื™ื•ืช ื ืคืชืจื• ืชื•ืš ื™ื•ืžื™ื™ื; ื”ืžืฉืชืชืฃ ื‘ืžืงื•ื ื”ืจืืฉื•ืŸ ื–ื›ื” ื‘-233 ื ืงื•ื“ื•ืช (ื”ื•ื ื‘ื™ืœื” ืฉื‘ื•ืข ื‘ื”ื›ื ื•ืช ืœืชื—ืจื•ืช). ืฉืœื•ืฉื” ื–ื•ื›ื™ื: ืžืงื•ื I - a1exdandy, II - Rubikoid, III - Ze.

ืขื ื–ืืช, ื‘ืžื”ืœืš PHDays ืืฃ ืื—ื“ ืžื”ืžืฉืชืชืคื™ื ืœื ื”ืฆืœื™ื— ืœื”ืชื’ื‘ืจ ืขืœ ืฉืœื•ืฉืช ื”ื“ื•ื›ื ื™ื, ืื– ื”ื—ืœื˜ื ื• ืœืขืจื•ืš ืชื—ืจื•ืช ืžืงื•ื•ื ืช ื•ืคืจืกืžื ื• ืืช ื”ืžืฉื™ืžื” ื”ืงืฉื” ื‘ื™ื•ืชืจ ื‘ืชื—ื™ืœืช ื™ื•ื ื™. ื”ืžืฉืชืชืคื™ื ื”ื™ื• ืฆืจื™ื›ื™ื ืœื”ืฉืœื™ื ืืช ื”ืžืฉื™ืžื” ืชื•ืš ื—ื•ื“ืฉ, ืœืžืฆื•ื ืืช ื”ื“ื’ืœ, ื•ืœืชืืจ ืืช ื”ืคืชืจื•ืŸ ื‘ืคื™ืจื•ื˜ ื•ื‘ืฆื•ืจื” ืžืขื ื™ื™ื ืช.

ืžืชื—ืช ืœื’ื–ืจื” ืื ื• ืžืคืจืกืžื™ื ื ื™ืชื•ื— ืฉืœ ื”ืคืชืจื•ืŸ ื”ื˜ื•ื‘ ื‘ื™ื•ืชืจ ืœืžืฉื™ืžื” ืžืืœื” ืฉื ืฉืœื—ื• ื‘ืžื”ืœืš ื”ื—ื•ื“ืฉ, ื”ื•ื ื ืžืฆื ืขืœ ื™ื“ื™ Alexey Kovriznykh (a1exdandy) ืžื—ื‘ืจืช Digital Security, ืฉืชืคืก ืืช ื”ืžืงื•ื ื”ืจืืฉื•ืŸ ื‘ืชื—ืจื•ืช ื‘ืžื”ืœืš PHDays. ืœื”ืœืŸ ืื ื• ืžืฆื™ื’ื™ื ืืช ื”ื˜ืงืกื˜ ืฉืœื” ืขื ื”ืขืจื•ืชื™ื ื•.

ื ื™ืชื•ื— ืจืืฉื•ื ื™

ืื–, ื”ืžืฉื™ืžื” ื”ื›ื™ืœื” ืืจื›ื™ื•ืŸ ืขื ื”ืงื‘ืฆื™ื ื”ื‘ืื™ื:

  • block_upload_traffic.pcapng
  • DB100.bin
  • hints.txt

ืงื•ื‘ืฅ hints.txt ืžื›ื™ืœ ืืช ื”ืžื™ื“ืข ื•ื”ืจืžื–ื™ื ื”ื“ืจื•ืฉื™ื ืœืคืชืจื•ืŸ ื”ืžืฉื™ืžื”. ืœื”ืœืŸ ืชื•ื›ื ื•:

  1. ืคื˜ืจื•ื‘ื™ืฅ' ืืžืจ ืœื™ ืืชืžื•ืœ ืฉืืชื” ื™ื›ื•ืœ ืœื˜ืขื•ืŸ ื‘ืœื•ืงื™ื ืž- PlcSim ืœืฉืœื‘ 7.
  2. ื‘ื“ื•ื›ืŸ ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘-PLC ืžืกื“ืจืช Siemens Simatic S7-300.
  3. PlcSim ื”ื•ื ืืžื•ืœื˜ื•ืจ PLC ื”ืžืืคืฉืจ ืœืš ืœื”ืคืขื™ืœ ื•ืœืืคื•ืช ื‘ืื’ื™ื ื‘ืชื•ื›ื ื™ื•ืช ืขื‘ื•ืจ PLCs ืฉืœ ืกื™ืžื ืก S7.

ื ืจืื” ืฉื”ืงื•ื‘ืฅ DB100.bin ืžื›ื™ืœ ืืช ื‘ืœื•ืง ื”ื ืชื•ื ื™ื 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 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 L ......... 3402. 4 : 00000060 0401 0206 0100 0107a0102 2602 0501 0202 ................ 00000070: 4 02 0501 0206a 0100 0108 0102 3302 ........... 0401a3: 00000080 0206b 0100 0109 0102 0 02 0501 ......".....F... 0202b1602: 00000090 0501 0206c 0100 010 0102 ........... .. 3702c0401: 0206d 7 000000a0 0100 010 0102 2202 0501 ................ 0202d4602: 0501 000000e 0 0206d0100 010 0102 3302 . .... 0401e0206: 0100 3 000000 0 010 0102 0 02 ........#...... 0501f0202: 1602 0501 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......

ื›ืคื™ ืฉื”ืฉื ืžืจืžื–, ื”ืงื•ื‘ืฅ block_upload_traffic.pcapng ืžื›ื™ืœ dump ืฉืœ ืชืขื‘ื•ืจืช ื”ืขืœืื” ื‘ืœื•ืง ืœ-PLC.

ืจืื•ื™ ืœืฆื™ื™ืŸ ืฉื”ืžื–ื‘ืœื” ื”ื–ื• ื‘ืืชืจ ื”ืชื—ืจื•ืช ื‘ืžื”ืœืš ื”ื›ื ืก ื”ื™ื™ืชื” ืงืฆืช ื™ื•ืชืจ ืงืฉื” ืœื”ืฉื’ื”. ืœืฉื ื›ืš, ื”ื™ื” ืฆื•ืจืš ืœื”ื‘ื™ืŸ ืืช ื”ืกืงืจื™ืคื˜ ืžืงื•ื‘ืฅ ื”ืคืจื•ื™ืงื˜ ืขื‘ื•ืจ TeslaSCADA2. ืžืžื ื• ื ื™ืชืŸ ื”ื™ื” ืœื”ื‘ื™ืŸ ื”ื™ื›ืŸ ื ืžืฆื ื”-dump ื”ืžื•ืฆืคืŸ ื‘ืืžืฆืขื•ืช RC4 ื•ื‘ืื™ื–ื” ืžืคืชื— ืฆืจื™ืš ืœื”ืฉืชืžืฉ ื›ื“ื™ ืœืคืขื ื— ืื•ืชื•. ื ื™ืชืŸ ื”ื™ื” ืœื”ืฉื™ื’ ื”ืฉืœื›ื•ืช ืฉืœ ื‘ืœื•ืงื™ ื ืชื•ื ื™ื ื‘ืืชืจ ื‘ืืžืฆืขื•ืช ืœืงื•ื— ืคืจื•ื˜ื•ืงื•ืœ S7. ืœืฉื ื›ืš ื”ืฉืชืžืฉืชื™ ื‘ืœืงื•ื— ื”ื”ื“ื’ืžื” ืžื—ื‘ื™ืœืช Snap7.

ื—ื™ืœื•ืฅ ื‘ืœื•ืงื™ื ืœืขื™ื‘ื•ื“ ืื•ืชื•ืช ืžืžื–ื‘ืœื” ืฉืœ ืชื ื•ืขื”

ื‘ื”ืกืชื›ืœื•ืช ืขืœ ื”ืชื•ื›ืŸ ืฉืœ ื”-dump, ืืชื” ื™ื›ื•ืœ ืœื”ื‘ื™ืŸ ืฉื”ื•ื ืžื›ื™ืœ ื‘ืœื•ืงื™ื ืœืขื™ื‘ื•ื“ ืื•ืชื•ืช OB1, FC1, FC2 ื•-FC3:

ื‘ืขืงื‘ื•ืช ื”ื ื™ื ื’'ื” ื”ืชืขืฉื™ื™ืชื™: ืื™ืš PLC ื ืคืจืฅ ื‘-Positive Hack Days 9

ื™ืฉ ืœื”ืกื™ืจ ืืช ื”ื‘ืœื•ืงื™ื ื”ืœืœื•. ื ื™ืชืŸ ืœืขืฉื•ืช ื–ืืช, ืœืžืฉืœ, ืขื ื”ืกืงืจื™ืคื˜ ื”ื‘ื, ืœืื—ืจ ืฉื”ืžื™ืจ ื‘ืขื‘ืจ ืืช ื”ืชืขื‘ื•ืจื” ืžืคื•ืจืžื˜ pcapng ืœ-pcap:

#!/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 = ''

ืœืื—ืจ ื‘ื—ื™ื ืช ื”ื‘ืœื•ืงื™ื ื”ืžืชืงื‘ืœื™ื, ืชื‘ื—ื™ืŸ ืฉื”ื ืชืžื™ื“ ืžืชื—ื™ืœื™ื ืขื ื‘ืชื™ื 70 70 (ืขืžื•ื“). ืขื›ืฉื™ื• ืืชื” ืฆืจื™ืš ืœืœืžื•ื“ ืื™ืš ืœื ืชื— ืื•ืชื. ื”ืจืžื– ืœื”ืงืฆืื” ืžืฆื™ืข ืฉืขืœื™ืš ืœื”ืฉืชืžืฉ ื‘- PlcSim ืœืฉื ื›ืš.

ืงื‘ืœืช ื”ื•ืจืื•ืช ื”ื ื™ืชื ื•ืช ืœืงืจื™ืื” ืขืœ ื™ื“ื™ ืื“ื ืžื‘ืœื•ืงื™ื

ืจืืฉื™ืช, ื‘ื•ืื• ื ื ืกื” ืœืชื›ื ืช ืืช S7-PlcSim ืขืœ ื™ื“ื™ ื˜ืขื™ื ืช ืžืกืคืจ ื‘ืœื•ืงื™ื ืขื ื”ื•ืจืื•ืช ื—ื•ื–ืจื•ืช (= Q 0.0) ืœืชื•ื›ื• ื‘ืืžืฆืขื•ืช ืชื•ื›ื ืช Simatic Manager, ื•ืฉืžื™ืจืช ื”-PLC ืฉื”ืชืงื‘ืœ ื‘ืืžื•ืœื˜ื•ืจ ืœืงื•ื‘ืฅ example.plc. ืขืœ ื™ื“ื™ ื”ืชื‘ื•ื ื ื•ืช ื‘ืชื•ื›ืŸ ื”ืงื•ื‘ืฅ, ืชื•ื›ืœ ืœืงื‘ื•ืข ื‘ืงืœื•ืช ืืช ืชื—ื™ืœืช ื”ื‘ืœื•ืงื™ื ืฉื”ื•ืจื“ื• ืขืœ ื™ื“ื™ ื”ื—ืชื™ืžื” 70 70, ืฉื’ื™ืœื™ื ื• ืงื•ื“ื ืœื›ืŸ. ืœืคื ื™ ื”ื‘ืœื•ืงื™ื, ื›ื›ืœ ื”ื ืจืื”, ื’ื•ื“ืœ ื”ื‘ืœื•ืง ื ื›ืชื‘ ื›ืขืจืš ืื ื“ื™ืืŸ ืงื˜ืŸ ืฉืœ 4 ื‘ืชื™ื.

ื‘ืขืงื‘ื•ืช ื”ื ื™ื ื’'ื” ื”ืชืขืฉื™ื™ืชื™: ืื™ืš PLC ื ืคืจืฅ ื‘-Positive Hack Days 9

ืœืื—ืจ ืฉืงื™ื‘ืœื ื• ืžื™ื“ืข ืขืœ ืžื‘ื ื” ืงื‘ืฆื™ plc, ื”ื•ืคื™ืขื” ืชื•ื›ื ื™ืช ื”ืคืขื•ืœื” ื”ื‘ืื” ืœืงืจื™ืืช ืชื•ื›ื ื™ื•ืช PLC S7:

  1. ื‘ืืžืฆืขื•ืช Simatic Manager, ืื ื• ื™ื•ืฆืจื™ื ืžื‘ื ื” ื‘ืœื•ืง ื‘-S7-PlcSim ื“ื•ืžื” ืœื–ื” ืฉืงื™ื‘ืœื ื• ืžื”-dump. ื’ื“ืœื™ ื”ื‘ืœื•ืงื™ื ื—ื™ื™ื‘ื™ื ืœื”ืชืื™ื (ื–ื” ืžื•ืฉื’ ืขืœ ื™ื“ื™ ืžื™ืœื•ื™ ื”ื‘ืœื•ืงื™ื ื‘ืžืกืคืจ ื”ื”ื•ืจืื•ืช ื”ื ื“ืจืฉ) ื•ื”ืžื–ื”ื™ื ืฉืœื”ื (OB1, FC1, FC2, FC3).
  2. ืฉืžื•ืจ ืืช ื”-PLC ืœืงื•ื‘ืฅ.
  3. ืื ื• ืžื—ืœื™ืคื™ื ืืช ืชื•ื›ืŸ ื”ื‘ืœื•ืงื™ื ื‘ืงื•ื‘ืฅ ื”ืžืชืงื‘ืœ ื‘ื‘ืœื•ืงื™ื ืž-Traffic dump. ืชื—ื™ืœืช ื”ื‘ืœื•ืงื™ื ื ืงื‘ืขืช ืขืœ ื™ื“ื™ ื”ื—ืชื™ืžื”.
  4. ืื ื• ื˜ื•ืขื ื™ื ืืช ื”ืงื•ื‘ืฅ ื”ืžืชืงื‘ืœ ืœืชื•ืš S7-PlcSim ื•ืžืกืชื›ืœื™ื ืขืœ ืชื•ื›ืŸ ื”ื‘ืœื•ืงื™ื ื‘-Simatic Manager.

ื ื™ืชืŸ ืœื”ื—ืœื™ืฃ ื‘ืœื•ืงื™ื, ืœืžืฉืœ, ื‘ืงื•ื“ ื”ื‘ื:

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)

ืืœื›ืกื™ื™ ืœืงื— ื“ืจืš ืื•ืœื™ ืงืฉื” ื™ื•ืชืจ, ืื‘ืœ ืขื“ื™ื™ืŸ ื ื›ื•ื ื”. ื”ื ื—ื ื• ืฉื”ืžืฉืชืชืคื™ื ื™ืฉืชืžืฉื• ื‘ืชื•ื›ื ื™ืช NetToPlcSim ื›ื“ื™ ืฉ- PlcSim ืชื•ื›ืœ ืœืชืงืฉืจ ื“ืจืš ื”ืจืฉืช, ืœื”ืขืœื•ืช ื‘ืœื•ืงื™ื ืœ- PlcSim ื“ืจืš Snap7, ื•ืื– ืœื”ื•ืจื™ื“ ืืช ื”ื‘ืœื•ืงื™ื ื”ืืœื” ื›ืคืจื•ื™ืงื˜ ืž- PlcSim ื‘ืืžืฆืขื•ืช ืกื‘ื™ื‘ืช ื”ืคื™ืชื•ื—.

ืขืœ ื™ื“ื™ ืคืชื™ื—ืช ื”ืงื•ื‘ืฅ ืฉื ื•ืฆืจ ื‘-S7-PlcSim, ืืชื” ื™ื›ื•ืœ ืœืงืจื•ื ืืช ื”ื‘ืœื•ืงื™ื ืฉื”ื•ื—ืœืคื• ื‘ืืžืฆืขื•ืช ื”-Simatic Manager. ืคื•ื ืงืฆื™ื•ืช ื‘ืงืจืช ื”ื”ืชืงืŸ ื”ืขื™ืงืจื™ื•ืช ื ืจืฉืžื•ืช ื‘ื‘ืœื•ืง FC1. ืจืื•ื™ ืœืฆื™ื™ืŸ ื‘ืžื™ื•ื—ื“ ืืช ื”ืžืฉืชื ื” #TEMP0, ืฉื›ืืฉืจ ืžื•ืคืขืœ ื ืจืื” ื›ื™ ื”ื•ื ืžื’ื“ื™ืจ ืืช ื‘ืงืจืช ื”-PLC ืœืžืฆื‘ ื™ื“ื ื™ ื‘ื”ืชื‘ืกืก ืขืœ ืขืจื›ื™ ื”ื–ื™ื›ืจื•ืŸ M2.2 ื•-M2.3. ื”ืขืจืš #TEMP0 ื ืงื‘ืข ืขืœ ื™ื“ื™ ื”ืคื•ื ืงืฆื™ื” FC3.

ื‘ืขืงื‘ื•ืช ื”ื ื™ื ื’'ื” ื”ืชืขืฉื™ื™ืชื™: ืื™ืš PLC ื ืคืจืฅ ื‘-Positive Hack Days 9

ื›ื“ื™ ืœืคืชื•ืจ ืืช ื”ื‘ืขื™ื”, ืขืœื™ืš ืœื ืชื— ืืช ืคื•ื ืงืฆื™ื™ืช FC3 ื•ืœื”ื‘ื™ืŸ ืžื” ืฆืจื™ืš ืœืขืฉื•ืช ื›ื“ื™ ืฉื”ื™ื ืชื—ื–ื™ืจ ืคื•ื ืงืฆื™ื” ื”ื’ื™ื•ื ื™ืช.

ื‘ืœื•ืงื™ื ืœืขื™ื‘ื•ื“ ืื•ืชื•ืช PLC ื‘ื“ื•ื›ืŸ Low Security ื‘ืืชืจ ื”ืชื—ืจื•ืช ื”ื™ื• ืžืกื•ื“ืจื™ื ื‘ืฆื•ืจื” ื“ื•ืžื”, ืื‘ืœ ื›ื“ื™ ืœื”ื’ื“ื™ืจ ืืช ื”ืขืจืš ืฉืœ ื”ืžืฉืชื ื” #TEMP0, ื–ื” ื”ื™ื” ืžืกืคื™ืง ืœื›ืชื•ื‘ ืืช ื”ืฉื•ืจื” ืฉืœื™ ื“ืจืš ื”ื ื™ื ื’'ื” ืœืชื•ืš ื‘ืœื•ืง DB1. ื‘ื“ื™ืงืช ื”ืขืจืš ื‘ื‘ืœื•ืง ื”ื™ื™ืชื” ืคืฉื•ื˜ื” ื•ืœื ื“ืจืฉื” ื™ื“ืข ืžืขืžื™ืง ื‘ืฉืคืช ื”ืชื›ื ื•ืช ื”ื‘ืœื•ืง. ื‘ืจื•ืจ ืฉื‘ืจืžืช ื”ืื‘ื˜ื—ื” ื”ื’ื‘ื•ื”ื”, ื”ืฉื’ืช ืฉืœื™ื˜ื” ื™ื“ื ื™ืช ืชื”ื™ื” ื”ืจื‘ื” ื™ื•ืชืจ ืงืฉื” ื•ื™ืฉ ืฆื•ืจืš ืœื”ื‘ื™ืŸ ืืช ื”ืžื•ืจื›ื‘ื•ื™ื•ืช ืฉืœ ืฉืคืช STL (ืื—ืช ื”ื“ืจื›ื™ื ืœืชื›ื ืช ืืช ื”-S7 PLC).

ื‘ืœื•ืง ื”ืคื•ืš FC3

ื”ืชื•ื›ืŸ ืฉืœ ื‘ืœื•ืง FC3 ื‘ื™ื™ืฆื•ื’ 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

ื”ืงื•ื“ ื“ื™ ืืจื•ืš ื•ืขืฉื•ื™ ืœื”ื™ืจืื•ืช ืžืกื•ื‘ืš ืœืžื™ ืฉืœื ืžื›ื™ืจ ืืช STL. ืื™ืŸ ื˜ืขื ืœื ืชื— ื›ืœ ื”ื•ืจืื” ื‘ืžืกื’ืจืช ืžืืžืจ ื–ื”; ื ื™ืชืŸ ืœืžืฆื•ื ื”ื•ืจืื•ืช ื•ื™ื›ื•ืœื•ืช ืžืคื•ืจื˜ื•ืช ืฉืœ ืฉืคืช STL ื‘ืžื“ืจื™ืš ื”ืžืชืื™ื: ืจืฉื™ืžืช ื”ืฆื”ืจื•ืช (STL) ืขื‘ื•ืจ ืชื›ื ื•ืช S7-300 ื•-S7-400. ื›ืืŸ ืืฆื™ื’ ืืช ืื•ืชื• ื”ืงื•ื“ ืœืื—ืจ ืขื™ื‘ื•ื“ - ืฉื™ื ื•ื™ ืฉืžื•ืช ื”ืชื•ื•ื™ื•ืช ื•ื”ืžืฉืชื ื™ื ื•ื”ื•ืกืคืช ื”ืขืจื•ืช ื”ืžืชืืจื•ืช ืืช ืืœื’ื•ืจื™ืชื ื”ืคืขื•ืœื” ื•ื›ืžื” ืžื‘ื ื™ ืฉืคืช STL. ื”ืจืฉื• ืœื™ ืžื™ื“ ืœืฆื™ื™ืŸ ื›ื™ ื”ื‘ืœื•ืง ื”ืžื“ื•ื‘ืจ ืžื›ื™ืœ ืžื›ื•ื ื” ื•ื™ืจื˜ื•ืืœื™ืช ืฉืžื‘ืฆืขืช ืงื•ื“ ื‘ืชื™ื ื›ืœืฉื”ื• ื”ื ืžืฆื ื‘ื‘ืœื•ืง DB100, ืฉืืช ืชื•ื›ื ื• ืื ื• ื™ื•ื“ืขื™ื. ื”ื•ืจืื•ืช ืžื›ื•ื ื” ื•ื™ืจื˜ื•ืืœื™ืช ืžื•ืจื›ื‘ื•ืช ืžื‘ื™ื™ื˜ ืื—ื“ ืฉืœ ืงื•ื“ ื”ืคืขืœื” ื•ื‘ื™ื™ื˜ื™ื ืฉืœ ืืจื’ื•ืžื ื˜ื™ื, ื‘ื™ื™ื˜ ืื—ื“ ืœื›ืœ ืืจื’ื•ืžื ื˜. ืœื›ืœ ื”ื”ื•ืจืื•ืช ื”ื ื—ืฉื‘ื•ืช ื™ืฉ ืฉื ื™ ื˜ื™ืขื•ื ื™ื; ืฆื™ื™ื ืชื™ ืืช ื”ืขืจื›ื™ื ืฉืœื”ืŸ ื‘ื”ืขืจื•ืช ื›-X ื•-Y.

ืงื•ื“ ืœืื—ืจ ืขื™ื‘ื•ื“]

# ะ˜ะฝะธั†ะธะฐะปะธะทะฐั†ะธั ั€ะฐะทะปะธั‡ะฝั‹ั… ะฟะตั€ะตะผะตะฝะฝั‹ั…
      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

ืœืื—ืจ ืฉืงื™ื‘ืœื ื• ืžื•ืฉื’ ืขืœ ื”ื•ืจืื•ืช ื”ืžื›ื•ื ื” ื”ื•ื™ืจื˜ื•ืืœื™ืช, ื‘ื•ื ื ื›ืชื•ื‘ ืžืคืจืง ืงื˜ืŸ ื›ื“ื™ ืœื ืชื— ืืช ืงื•ื“ ื”ื‘ืชื™ื ื‘ื‘ืœื•ืง 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

ื›ืชื•ืฆืื” ืžื›ืš, ืื ื• ืžืงื‘ืœื™ื ืืช ืงื•ื“ ื”ืžื—ืฉื‘ ื”ื•ื•ื™ืจื˜ื•ืืœื™ ื”ื‘ื:

ืงื•ื“ ืžื›ื•ื ื” ื•ื™ืจื˜ื•ืืœื™ืช

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)

ื›ืคื™ ืฉืืชื” ื™ื›ื•ืœ ืœืจืื•ืช, ืชื•ื›ื ื™ืช ื–ื• ืคืฉื•ื˜ ื‘ื•ื“ืงืช ื›ืœ ืชื• ืž-DB101 ืขื‘ื•ืจ ืฉื•ื•ื™ื•ืŸ ืœืขืจืš ืžืกื•ื™ื. ื”ืฉื•ืจื” ื”ืื—ืจื•ื ื” ืœืžืขื‘ืจ ื›ืœ ื”ืžื—ืื•ืช ื”ื™ื: n0w u 4r3 7h3 m4573r. ืื ื”ืงื• ื”ื–ื” ืžืžื•ืงื ื‘ื‘ืœื•ืง DB101, ืื–ื™ ืžื•ืคืขืœืช ื‘ืงืจืช PLC ื™ื“ื ื™ืช ื•ื ื™ืชืŸ ื™ื”ื™ื” ืœืคื•ืฆืฅ ืื• ืœืจื•ืงืŸ ืืช ื”ื‘ืœื•ืŸ.โ€จ

ื–ื” ื”ื›ืœ! ืืœื›ืกื™ื™ ื”ืคื’ื™ืŸ ืจืžืช ื™ื“ืข ื’ื‘ื•ื”ื” ื”ืจืื•ื™ื” ืœื ื™ื ื’'ื” ืชืขืฉื™ื™ืชื™ :) ืฉืœื—ื ื• ืคืจืกื™ื ื‘ืœืชื™ ื ืฉื›ื—ื™ื ืœื–ื•ื›ื”. ืชื•ื“ื” ืจื‘ื” ืœื›ืœ ื”ืžืฉืชืชืคื™ื!

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”