Emanyathelweni e-Industrial Ninja: indlela i-PLC eyagqekezwa ngayo kwiiNtsuku ze-9 ze-Positive Hack

Emanyathelweni e-Industrial Ninja: indlela i-PLC eyagqekezwa ngayo kwiiNtsuku ze-9 ze-Positive Hack

Kwi-PHDays ye-9 yokugqibela siye sabamba ukhuphiswano lokugqekeza iziko lokumpompa irhasi - ukhuphiswano I-Ninja yoShishino. Kwakukho izikhundla ezintathu kwisayithi kunye neeparitha zokhuseleko ezahlukeneyo (Akukho uKhuseleko, uKhuseleko oluPhantsi, uKhuseleko oluPhezulu), ukulinganisa inkqubo yoshishino efanayo: umoya ophantsi koxinzelelo waphonswa kwibhaluni (kwaye wakhululwa).

Nangona iiparitha ezahlukeneyo zokhuseleko, ukubunjwa kwe-hardware ye-stands kwakufana: i-Siemens Simatic PLC S7-300 series; iqhosha le-deflation likaxakeka kunye nesixhobo sokulinganisa uxinzelelo (uxhunywe kwi-PLC yamagalelo edijithali (DI)); iivalve ezisebenzela ukunyuka kwamaxabiso kunye ne-deflation of air (exhunywe kwiziphumo zedijithali ze-PLC (DO)) - jonga umfanekiso ongezantsi.

Emanyathelweni e-Industrial Ninja: indlela i-PLC eyagqekezwa ngayo kwiiNtsuku ze-9 ze-Positive Hack

I-PLC, ngokuxhomekeke kwimiba yoxinzelelo kwaye ngokuhambelana neprogram yayo, yenza isigqibo sokukhupha okanye ukukhupha ibhola (ivule kwaye ivale iivalve ezihambelanayo). Nangona kunjalo, zonke izikhundla zinendlela yokulawula i-manual, eyenza kube lula ukulawula i-valve ngaphandle kwemingcele.

Izitendi zahlukile kubunzima bokuvumela le ndlela: kwindawo yokuma engakhuselwanga bekulula ukuyenza le nto, kwaye kwindawo yoKhuseleko oluPhezulu kwakunzima ngokuhambelanayo.

Ezintlanu kwezintandathu iingxaki zasonjululwa ngeentsuku ezimbini; Umthathi-nxaxheba wokuqala ufumene amanqaku angama-233 (wachitha iveki elungiselela ukhuphiswano). Abaphumeleleyo abathathu: Ndibeka - a1exdandy, II - Rubikoid, III - Ze.

Nangona kunjalo, ngexesha le-PHDays, akukho namnye kubathathi-nxaxheba okwazileyo ukuzoyisa zontathu izikhundla, ngoko siye sagqiba ekubeni senze ukhuphiswano lwe-intanethi kwaye sapapasha owona msebenzi unzima ekuqaleni kukaJuni. Abathathi-nxaxheba kwafuneka bagqibe umsebenzi kwisithuba senyanga, bafumane iflegi, kwaye bachaze isisombululo ngokweenkcukacha nangendlela enomdla.

Ngezantsi kokusikwa sipapasha uhlalutyo lwesona sisombululo singcono kumsebenzi ovela kwabo bathunyelwe ngenyanga, yafunyanwa ngu-Alexey Kovrizhnykh (a1exdandy) kwinkampani yeDigital Security, eyathatha indawo ye-XNUMX kukhuphiswano ngexesha le-PHDays. Ngezantsi sinika isicatshulwa sayo kunye nezimvo zethu.

Uhlalutyo lokuqala

Ke, lo msebenzi ubuqulathe uvimba onezi fayile zilandelayo:

  • block_upload_traffic.pcapng
  • DB100.bin
  • iingcebiso.txt

Ifayile ye hints.txt iqulethe ulwazi oluyimfuneko kunye neengcebiso zokusombulula umsebenzi. Nantsi imixholo yayo:

  1. UPetrovich undixelele izolo ukuba ungalayisha iibhloko ukusuka kwiPlcSim ukuya kwiNyathelo7.
  2. I-Siemens Simatic S7-300 series PLC isetyenziswe kwindawo yokuma.
  3. I-PlcSim sisilinganisi se-PLC esikuvumela ukuba usebenzise kwaye ulungise iinkqubo ze-Siemens S7 PLCs.

Ifayile yeDB100.bin ibonakala iqulathe ibhloko yedatha yeDB100 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 0103 0102 0a02 ..w............. 00000030: 0501 0202 1602 0501 0206 0100 ................ 0104: 0102 00000040 7502 0401 0206 0100 0105a0102 0 u............... 02: 0501 00000050 0202 1602 0501 0206 0100 0106..........0102. 3402: 4 00000060 0401 0206 0100 0107 0102 2602 .........&..... 0501: 0202c00000070 4 02 0501 0206 0100 0108 ......... : 0102 3302 0401 3 00000080a0206 0100 0109 0102 ................ 0: 02 0501 0202 1602a 00000090 0501 0206 0100 ............ 010a0102: 3702 0401b 0206 7 000000 0 0100 010 ......".....F... 0102b2202: 0501 0202 4602c 0501 000000 0 ... ... .... 0206e0100: 010 0102 3302 0401 0206 0100 3 000000 ........#...... 0f010: 0102 0 02 0501 0202 1602 0501 ........ ..... 0206: 000000 0 0100 010 0102 6 02 0401 ......%......... 0206: 0100 010 000000 0 0102 1102 ..... 0501 . ......&. 0202: 2302 0501 0206c0100 000000 0 0110 ....L......

Njengoko igama libonisa, ifayile ye-block_upload_traffic.pcapng iqulethe indawo yokulahla i-block upload traffic kwi-PLC.

Kuyaphawuleka ukuba le ndawo yokulahlwa kwetrafikhi kwindawo yokhuphiswano ngexesha lenkomfa bekunzima kakhulu ukuyifumana. Ukwenza oku, kwakuyimfuneko ukuqonda iskripthi kwifayile yeprojekthi yeTeslaSCADA2. Ukusuka kuyo kwakunokwenzeka ukuqonda ukuba indawo yokulahla efihliweyo kusetyenziswa i-RC4 ibekwe phi kwaye sesiphi isitshixo esifunekayo ukuze sisetyenziswe ukuyisusa. Ukulahlwa kweebhloko zedatha kwisiza kunokufunyanwa kusetyenziswa umxhasi weprotocol ye-S7. Kule nto ndisebenzise umxhasi wedemo ukusuka kwiphakheji ye-Snap7.

Ukutsalwa kweebhloko zokusetyenzwa komqondiso kwindawo yokulahla izithuthi

Ukujonga imixholo yokulahla, unokuqonda ukuba iqulethe iibhloko zokusetyenzwa komqondiso OB1, FC1, FC2 kunye neFC3:

Emanyathelweni e-Industrial Ninja: indlela i-PLC eyagqekezwa ngayo kwiiNtsuku ze-9 ze-Positive Hack

Ezi bloko kufuneka zisuswe. Oku kunokwenziwa, umzekelo, ngesi script silandelayo, emva kokuguqula itrafikhi kwifomati yepcapng ukuya kwipcap:

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

Emva kokuphonononga iibhloko ezibangelwayo, uya kuqaphela ukuba zihlala ziqala ngee-bytes 70 70 (pp). Ngoku kufuneka ufunde indlela yokuyihlalutya. Ingcebiso yesabelo icebisa ukuba kufuneka usebenzise i-PlcSim koku.

Ukufumana imiyalelo efundeka ngabantu kwiibhloko

Okokuqala, makhe sizame ukucwangcisa i-S7-PlcSim ngokulayisha iibhloko ezininzi ngemiyalelo ephindaphindayo (= Q 0.0) kuyo kusetyenziswa isoftware yoMphathi weSimatic, kunye nokugcina i-PLC efunyenwe kwi-emulator kwifayile ye-example.plc. Ngokujonga imixholo yefayile, unokumisela ngokulula ukuqala kweebhloko ezikhutshelweyo ngokutyikitya i-70 70, esiyifumene ngaphambili. Ngaphambi kweebhloko, ngokucacileyo, ubungakanani bebhloko bubhalwe njengexabiso le-4-byte encinci-endian.

Emanyathelweni e-Industrial Ninja: indlela i-PLC eyagqekezwa ngayo kwiiNtsuku ze-9 ze-Positive Hack

Emva kokuba sifumene ulwazi malunga nokwakheka kweefayile ze-plc, isicwangciso sokusebenza silandelayo sivele sokufunda iinkqubo ze-PLC S7:

  1. Ukusebenzisa uMphathi weSimatic, senza isakhiwo sebhloko kwi-S7-PlcSim efana naleyo esiyifumene kwindawo yokulahla. Ubungakanani beebhloko kufuneka buhambelane (oku kuphunyezwa ngokuzalisa iibhloko ngenani elifunekayo lemiyalelo) kunye nezazisi zazo (OB1, FC1, FC2, FC3).
  2. Gcina i-PLC kwifayile.
  3. Sitshintsha imixholo yeebhloko kwifayile esiphumo kunye neebhloko ezivela kwi-traffic dump. Ukuqala kweebhloko kugqitywa ngutyikityo.
  4. Silayisha ifayile esiphumo kwi-S7-PlcSim kwaye sijonge imixholo yeebhloko kuMphathi weSimatic.

Iibhloko zinokutshintshwa, umzekelo, ngale khowudi ilandelayo:

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)

U-Alexey wathatha indlela enzima ngakumbi, kodwa echanekileyo. Sicinge ukuba abathathi-nxaxheba baya kusebenzisa inkqubo ye-NetToPlcSim ukuze i-PlcSim inxibelelane ngothungelwano, ifake iibhloko kwi-PlcSim nge-Snap7, emva koko ikhuphele ezi bhloko njengeprojekthi esuka kwi-PlcSim isebenzisa imeko-bume yophuhliso.

Ngokuvula ifayile enesiphumo kwi-S7-PlcSim, unokufunda iibhloko ezibhalwe ngaphezulu usebenzisa iSimatic Manager. Eyona misebenzi yolawulo lwesixhobo irekhodwa kwibhloko FC1. Eyona nto ibalulekileyo yi-#TEMP0 eguquguqukayo, ethi xa ivuliwe ibonakala ibeka ulawulo lwe-PLC kwimowudi ye-manual esekelwe kumaxabiso ememori ye-M2.2 kunye ne-M2.3 bit. #TEMP0 ixabiso limiselwe ngumsebenzi FC3.

Emanyathelweni e-Industrial Ninja: indlela i-PLC eyagqekezwa ngayo kwiiNtsuku ze-9 ze-Positive Hack

Ukusombulula ingxaki, kufuneka uhlalutye umsebenzi weFC3 kwaye uqonde ukuba yintoni ekufuneka yenziwe ukuze ibuyise ingqiqo.

Iibhloko ze-PLC zokucwangcisa izibonakaliso kwi-Low Security stand kwindawo yokhuphiswano zilungiselelwe ngendlela efanayo, kodwa ukubeka ixabiso le- #TEMP0 variable, kwakwanele ukubhala umgca indlela yam ye-ninja kwi-block ye-DB1. Ukujonga ixabiso kwibhloko kwakuthe ngqo kwaye akuzange kufune ulwazi olunzulu lwebhloko yolwimi lweprogram. Ngokucacileyo, kwinqanaba loKhuseleko oluPhezulu, ukufezekisa ulawulo lwezandla kuya kuba nzima kakhulu kwaye kuyimfuneko ukuqonda ubuqhetseba bolwimi lwe-STL (enye yeendlela zokucwangcisa i-S7 PLC).

Buyela umva ibloko FC3

Imixholo yebloko yeFC3 kumelo lwe-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

Ikhowudi inde kwaye inokubonakala inzima kumntu ongayaziyo nge-STL. Akukho sizathu sokuhlalutya umyalelo ngamnye kwisakhelo seli nqaku; imiyalelo eneenkcukacha kunye nobuchule bolwimi lwe-STL inokufumaneka kwincwadana ehambelana nayo: Uluhlu lweNgxelo (STL) ye-S7-300 kunye ne-S7-400 yeNkqubo. Apha ndiya kubonisa ikhowudi efanayo emva kokucubungula - ukuqamba ngokutsha iilebhile kunye neziguquko kunye nokongeza izimvo ezichaza i-algorithm yokusebenza kunye nolwakhiwo oluthile lwe-STL yolwimi. Makhe ndiqaphele ngokukhawuleza ukuba ibhloko ekuthethwa ngayo iqulethe umatshini obonakalayo owenza i-bytecode ethile ebekwe kwibhloko ye-DB100, imixholo esiyaziyo. Imiyalelo kumatshini obonakalayo iquka i-byte enye yekhowudi yokusebenza kunye nee-byte zeengxabano, ibhayithi enye kwimpikiswano nganye. Yonke imiyalelo eqwalaselweyo ineengxoxo ezimbini; Ndikhethe amaxabiso abo kumagqabantshintshi njengo-X kunye no-Y.

Ikhowudi emva kokucubungula]

# Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…
      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

Ukuba unombono wemiyalelo yomatshini obonakalayo, masibhale i-disassembler encinci yokwahlula i-bytecode kwibhloko ye-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

Ngenxa yoko, sifumana le khowudi yomatshini ilandelayo:

Ikhowudi yomatshini wenyani

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)

Njengoko ubona, le nkqubo ijonga ngokulula umlinganiswa ngamnye ukusuka kwi-DB101 ngokulingana kwixabiso elithile. Umgca wokugqibela wokudlula zonke iitshekhi ngu: n0w u 4r3 7h3 m4573r. Ukuba lo mgca ubekwe kwibhloko ye-DB101, ngoko ulawulo lwe-PLC lwe-manual luyasebenza kwaye kuya kwenzeka ukuba uqhume okanye udibanise ibhaluni.


Kuko konke! U-Alexey ubonise umgangatho ophezulu wolwazi olufanelekileyo kwi-industrial ninja :) Sithumele amabhaso akhumbulekayo kulowo uphumeleleyo. Enkosi kakhulu kubo bonke abathathi-nxaxheba!

umthombo: www.habr.com

Yongeza izimvo