์ง๋ PHDays 9์์ ๊ฐ์ค ํํ์ฅ ํดํน ๋ํ๋ฅผ ์ด์์ต๋๋ค.
๋ค์ํ ์์ ๋งค๊ฐ๋ณ์์๋ ๋ถ๊ตฌํ๊ณ ์คํ ๋์ ํ๋์จ์ด ๊ตฌ์ฑ์ ๋์ผํ์ต๋๋ค. Siemens Simatic PLC S7-300 ์๋ฆฌ์ฆ; ๋น์ ์์ถ ๋ฒํผ ๋ฐ ์๋ ฅ ์ธก์ ์ฅ์น(PLC ๋์งํธ ์ ๋ ฅ(DI)์ ์ฐ๊ฒฐ๋จ) ๊ณต๊ธฐ ํฝ์ฐฝ ๋ฐ ์์ถ์ ์ํด ์๋ํ๋ ๋ฐธ๋ธ(PLC(DO)์ ๋์งํธ ์ถ๋ ฅ์ ์ฐ๊ฒฐ๋จ) - ์๋ ๊ทธ๋ฆผ์ ์ฐธ์กฐํ์ธ์.
PLC๋ ์๋ ฅ ํ๋
๊ฐ๊ณผ ํด๋น ํ๋ก๊ทธ๋จ์ ๋ฐ๋ผ ๋ณผ์ ์์ถ ๋๋ ํฝ์ฐฝ์ ๊ฒฐ์ ํ์ต๋๋ค(ํด๋น ๋ฐธ๋ธ๋ฅผ ์ด๊ณ ๋ซ์). ํ์ง๋ง ๋ชจ๋ ์คํ ๋์๋ ์๋ ์ ์ด ๋ชจ๋๊ฐ ์์ด์ ์๋ฌด๋ฐ ์ ์ฝ ์์ด ๋ฐธ๋ธ์ ์ํ๋ฅผ ์ ์ดํ ์ ์์๋ค.
์คํ ๋๋ ์ด ๋ชจ๋๋ฅผ ํ์ฑํํ๋ ๋ณต์ก์ฑ์ด ๋ฌ๋์ต๋๋ค. ๋ณดํธ๋์ง ์์ ์คํ ๋์์๋ ์ด ์์ ์ด ๊ฐ์ฅ ์ฌ์ ๊ณ , ๋์ ๋ณด์ ์คํ ๋์์๋ ์ด์ ๋ฐ๋ผ ๋ ์ด๋ ค์ ์ต๋๋ค.
233๊ฐ ๋ฌธ์ ์ค 1๊ฐ ๋ฌธ์ ๊ฐ ์ดํ ๋ง์ ํด๊ฒฐ๋์์ต๋๋ค. XNUMX์ ์ฐธ๊ฐ์๋ XNUMX์ ์ ํ๋ํ๋ค. (๊ทธ๋ ๋ํ ์ค๋น์ ์ผ์ฃผ์ผ์ ๋ณด๋๋ค.) ์ธ ๋ช ์ ์ฐ์น์: I ์์น - aXNUMXexdandy, II - Rubikoid, III - Ze.
๊ทธ๋ฌ๋ PHDays ๋์ ์ฐธ๊ฐ์ ์ค ์ธ ๊ฐ์ง ์คํ ๋๋ฅผ ๋ชจ๋ ํต๊ณผํ์ง ๋ชปํ ์ฐธ๊ฐ์๊ฐ ์์ด ์จ๋ผ์ธ ๋ํ๋ฅผ ์ด๊ธฐ๋ก ๊ฒฐ์ ํ๊ณ XNUMX์ ์ด์ ๊ฐ์ฅ ์ด๋ ค์ด ๊ณผ์ ๋ฅผ ๋ฐํํ์ต๋๋ค. ์ฐธ๊ฐ์๋ค์ ํ ๋ฌ ์์ ๊ณผ์ ๋ฅผ ์์ํ๊ณ , ๊น๋ฐ์ ์ฐพ๊ณ , ํด๊ฒฐ์ฑ ์ ์์ธํ๊ณ ํฅ๋ฏธ๋กญ๊ฒ ์ค๋ช ํด์ผ ํ์ต๋๋ค.
์ปท ์๋์๋ ํ ๋ฌ ๋์ ์ ์ก๋ ์์
์ ๋ํ ์ต์์ ์๋ฃจ์
์ ๋ํ ๋ถ์์ด ๊ฒ์๋์ด ์์ผ๋ฉฐ, ์ด๋ PHDays ๋์ ๊ฒฝ์์์ 1์๋ฅผ ์ฐจ์งํ Digital Security ํ์ฌ์ Alexey Kovrizhnykh(aXNUMXexdandy)๊ฐ ๋ฐ๊ฒฌํ ๊ฒ์
๋๋ค. ์๋์๋ ์๊ฒฌ๊ณผ ํจ๊ป ํด๋น ํ
์คํธ๋ฅผ ์ ์ํฉ๋๋ค.
์ด๊ธฐ ๋ถ์
๋ฐ๋ผ์ ์์ ์๋ ๋ค์ ํ์ผ์ด ํฌํจ๋ ์์นด์ด๋ธ๊ฐ ํฌํจ๋์์ต๋๋ค.
- block_upload_traffic.pcapng
- DB100.bin
- ํํธ.txt
ํํธ.txt ํ์ผ์๋ ์์ ์ ํด๊ฒฐํ๋ ๋ฐ ํ์ํ ์ ๋ณด์ ํํธ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ๊ทธ ๋ด์ฉ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- Petrovich๋ ์ด์ ๋์๊ฒ PlcSim์ ๋ธ๋ก์ Step7๋ก ๋ก๋ํ ์ ์๋ค๊ณ ๋งํ์ต๋๋ค.
- ๋ถ์ค์๋ Siemens Simatic S7-300 ์๋ฆฌ์ฆ PLC๊ฐ ์ฌ์ฉ๋์์ต๋๋ค.
- PlcSim์ Siemens S7 PLC์ฉ ํ๋ก๊ทธ๋จ์ ์คํํ๊ณ ๋๋ฒ๊น ํ ์ ์๋ PLC ์๋ฎฌ๋ ์ดํฐ์ ๋๋ค.
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 0103 0102 0 02a00000030 ..w............ 0501: 0202 1602 0501 0206 0100 0104 0102 00000040 ................ 7502: 0401 0206 0100 0105 0102 0 02a0501 00000050 ์ ............... 0202: 1602 0501 0206 0100 0106 0102 3402 4..........00000060. 0401 : 0206 0100 0107 0102 2602 0501 0202 00000070 ......... & ..... 4 : 02C0501 0206 0100 0108 0102 3302 0401 3 L ......... 00000080. .. 0206 : 0100 0109 0102 0 02a0501 0202 1602 00000090 .......... 0501: 0206 0100 010 0102a 3702 0401 0206 7 ..........000000. .... 0a0100: 010 0102b 2202 0501 0202 4602 0501 000000 ......".....F... 0b0206: 0100 010 0102c 3302 0401 0206 0100 3 .......000000. .... .. 0c010: 0102d 0 02a0501 0202 1602 0501 0206 000000 .......... 0d0100: 010 0102e 6 02d0401 0206 0100 010 000000f ......m. .... .... 0e0102: 1102 0501 0202 2302 0501 0206 0100 000000 ........#...... 0f0110: 0102 3502 0401 0206 0100 0111 0102 5 ....00000100. ..... ..... 1202: 0501 0202 2502 0501 0206 0100 0112 00000110 ......%..... 0102: 3302 0401 0206 0100 0113 0102 2602 3 ..00000120. ..... .....&.0501:0202 4 02c0501 0206 0100 XNUMX .....L......
์ด๋ฆ์์ ์ ์ ์๋ฏ์ด block_upload_traffic.pcapng ํ์ผ์๋ PLC์ ๋ํ ๋ธ๋ก ์ ๋ก๋ ํธ๋ํฝ ๋คํ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
์ปจํผ๋ฐ์ค ๊ธฐ๊ฐ ๋์ ๋ํ ํ์ฅ์์ ๋ฐ์ํ ํธ๋ํฝ ๋คํ๋ฅผ ํ๋ณดํ๊ธฐ๊ฐ ์กฐ๊ธ ๋ ์ด๋ ค์ ๋ค๋ ์ ์ ์ฃผ๋ชฉํ ๊ฐ์น๊ฐ ์์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ TeslaSCADA2์ฉ ํ๋ก์ ํธ ํ์ผ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ดํดํด์ผ ํ์ต๋๋ค. ์ด๋ฅผ ํตํด RC4๋ฅผ ์ฌ์ฉํ์ฌ ์ํธํ๋ ๋คํ์ ์์น์ ์ด๋ฅผ ํด๋ ํ๋ ๋ฐ ์ด๋ค ํค๋ฅผ ์ฌ์ฉํด์ผ ํ๋์ง ์ดํดํ ์ ์์์ต๋๋ค. S7 ํ๋กํ ์ฝ ํด๋ผ์ด์ธํธ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ดํธ์ ๋ฐ์ดํฐ ๋ธ๋ก ๋คํ๋ฅผ ์ป์ ์ ์์ต๋๋ค. ์ด๋ฅผ ์ํด Snap7 ํจํค์ง์ ๋ฐ๋ชจ ํด๋ผ์ด์ธํธ๋ฅผ ์ฌ์ฉํ์ต๋๋ค.
ํธ๋ํฝ ๋คํ์์ ์ ํธ ์ฒ๋ฆฌ ๋ธ๋ก ์ถ์ถ
๋คํ ๋ด์ฉ์ ๋ณด๋ฉด ์ ํธ ์ฒ๋ฆฌ ๋ธ๋ก OB1, FC1, FC2 ๋ฐ FC3์ด ํฌํจ๋์ด ์์์ ์ ์ ์์ต๋๋ค.
์ด๋ฌํ ๋ธ๋ก์ ์ ๊ฑฐํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์ด์ ์ ํธ๋ํฝ์ 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(pp)์ผ๋ก ์์ํ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ์ด์ ์ด๋ฅผ ๋ถ์ํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์์ผ ํฉ๋๋ค. ํ ๋น ํํธ์์๋ ์ด๋ฅผ ์ํด PlcSim์ ์ฌ์ฉํด์ผ ํ๋ค๊ณ ์ ์ํฉ๋๋ค.
๋ธ๋ก์์ ์ฌ๋์ด ์ฝ์ ์ ์๋ ๋ช ๋ น์ด ์ป๊ธฐ
๋จผ์ Simatic Manager ์ํํธ์จ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ๋ณต ๋ช ๋ น(= Q 7)์ด ํฌํจ๋ ์ฌ๋ฌ ๋ธ๋ก์ ๋ก๋ํ๊ณ ์๋ฎฌ๋ ์ดํฐ์์ ์ป์ PLC๋ฅผ example.plc ํ์ผ์ ์ ์ฅํ์ฌ S0.0-PlcSim์ ํ๋ก๊ทธ๋๋ฐํด ๋ณด๊ฒ ์ต๋๋ค. ํ์ผ์ ๋ด์ฉ์ ๋ณด๋ฉด ์์ ๋ฐ๊ฒฌํ ์๋ช 70 70์ผ๋ก ๋ค์ด๋ก๋๋ ๋ธ๋ก์ ์์์ ์ฝ๊ฒ ํ์ธํ ์ ์์ต๋๋ค. ๋ธ๋ก ์์๋ ๋ถ๋ช ํ ๋ธ๋ก ํฌ๊ธฐ๊ฐ 4๋ฐ์ดํธ ๋ฆฌํ ์๋์ ๊ฐ์ผ๋ก ๊ธฐ๋ก๋์ด ์์ต๋๋ค.
plc ํ์ผ์ ๊ตฌ์กฐ์ ๋ํ ์ ๋ณด๋ฅผ ๋ฐ์ ํ PLC S7 ํ๋ก๊ทธ๋จ์ ์ฝ๊ธฐ ์ํ ๋ค์ ์์
๊ณํ์ด ๋ํ๋ฌ์ต๋๋ค.
- Simatic Manager๋ฅผ ์ฌ์ฉํ์ฌ ๋คํ์์ ๋ฐ์ ๊ฒ๊ณผ ์ ์ฌํ ๋ธ๋ก ๊ตฌ์กฐ๋ฅผ S7-PlcSim์ ์์ฑํฉ๋๋ค. ๋ธ๋ก ํฌ๊ธฐ(ํ์ํ ๋ช ๋ น์ด ์๋ก ๋ธ๋ก์ ์ฑ์์ ๋ฌ์ฑ๋จ)์ ํด๋น ์๋ณ์(OB1, FC1, FC2, FC3)๊ฐ ์ผ์นํด์ผ ํฉ๋๋ค.
- PLC๋ฅผ ํ์ผ๋ก ์ ์ฅํฉ๋๋ค.
- ๊ฒฐ๊ณผ ํ์ผ์ ๋ธ๋ก ๋ด์ฉ์ ํธ๋ํฝ ๋คํ์ ๋ธ๋ก์ผ๋ก ๋ฐ๊ฟ๋๋ค. ๋ธ๋ก์ ์์์ ์๋ช ์ ์ํด ๊ฒฐ์ ๋ฉ๋๋ค.
- ๊ฒฐ๊ณผ ํ์ผ์ 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)
Alexey๋ ์๋ง๋ ๋ ์ด๋ ต์ง๋ง ์ฌ์ ํ ์ฌ๋ฐ๋ฅธ ๊ธธ์ ํํ์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ฐธ๊ฐ์๋ค์ด NetToPlcSim ํ๋ก๊ทธ๋จ์ ์ฌ์ฉํ์ฌ PlcSim์ด ๋คํธ์ํฌ๋ฅผ ํตํด ํต์ ํ๊ณ Snap7์ ํตํด PlcSim์ ๋ธ๋ก์ ์ ๋ก๋ํ ๋ค์ ๊ฐ๋ฐ ํ๊ฒฝ์ ์ฌ์ฉํ์ฌ PlcSim์์ ํด๋น ๋ธ๋ก์ ํ๋ก์ ํธ๋ก ๋ค์ด๋ก๋ํ ์ ์๋ค๊ณ ๊ฐ์ ํ์ต๋๋ค.
S7-PlcSim์์ ๊ฒฐ๊ณผ ํ์ผ์ ์ด๋ฉด Simatic Manager๋ฅผ ์ฌ์ฉํ์ฌ ๋ฎ์ด์ด ๋ธ๋ก์ ์ฝ์ ์ ์์ต๋๋ค. ์ฃผ์ ์ฅ์น ์ ์ด ๊ธฐ๋ฅ์ ๋ธ๋ก FC1์ ๊ธฐ๋ก๋ฉ๋๋ค. ํนํ ์ฃผ๋ชฉํ ์ ์ #TEMP0 ๋ณ์์ ๋๋ค. ์ด ๋ณ์๋ ์ผ์ง ๋ M2.2 ๋ฐ M2.3 ๋นํธ ๋ฉ๋ชจ๋ฆฌ ๊ฐ์ ๊ธฐ๋ฐ์ผ๋ก PLC ์ ์ด๋ฅผ ์๋ ๋ชจ๋๋ก ์ค์ ํ๋ ๊ฒ์ผ๋ก ๋ํ๋ฉ๋๋ค. #TEMP0 ๊ฐ์ FC3 ๊ธฐ๋ฅ์ ์ํด ์ค์ ๋ฉ๋๋ค.
๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด FC3 ํจ์๋ฅผ ๋ถ์ํ๊ณ ๋
ผ๋ฆฌ์ ํจ์๋ฅผ ๋ฐํํ๊ธฐ ์ํด ์ํํด์ผ ํ ์์
์ ์ดํดํด์ผ ํฉ๋๋ค.
๋ํ์ฅ Low Security ์คํ ๋์ PLC ์ ํธ ์ฒ๋ฆฌ ๋ธ๋ก๋ ๋น์ทํ ๋ฐฉ์์ผ๋ก ๋ฐฐ์นํ์ง๋ง, #TEMP0 ๋ณ์์ ๊ฐ์ ์ค์ ํ๋ ค๋ฉด DB1 ๋ธ๋ก์ my ninja way๋ผ๋ ๋ผ์ธ์ ์จ๋ฃ์ผ๋ฉด ์ถฉ๋ถํ์ต๋๋ค. ๋ธ๋ก์ ๊ฐ์ ํ์ธํ๋ ๊ฒ์ ๊ฐ๋จํ์ผ๋ฉฐ ๋ธ๋ก ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋ํ ๊น์ ์ง์์ด ํ์ํ์ง ์์์ต๋๋ค. ๋ถ๋ช ํ ๋์ ๋ณด์ ์์ค์์๋ ์๋ ์ ์ด๋ฅผ ๋ฌ์ฑํ๋ ๊ฒ์ด ํจ์ฌ ๋ ์ด๋ ค์ธ ๊ฒ์ด๋ฉฐ STL ์ธ์ด(S7 PLC๋ฅผ ํ๋ก๊ทธ๋๋ฐํ๋ ๋ฐฉ๋ฒ ์ค ํ๋)์ ๋ณต์ก์ฑ์ ์ดํดํ๋ ๊ฒ์ด ํ์ํฉ๋๋ค.
์ญ๋ฐฉํฅ ๋ธ๋ก FC3
STL ํํ์ FC3 ๋ธ๋ก ๋ด์ฉ:
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 ์ธ์ด์ ์์ธํ ์ง์นจ๊ณผ ๊ธฐ๋ฅ์ ํด๋น ๋งค๋ด์ผ์์ ์ฐพ์ ์ ์์ต๋๋ค.
์ฒ๋ฆฌ ํ ์ฝ๋]
# ะะฝะธัะธะฐะปะธะทะฐัะธั ัะฐะทะปะธัะฝัั
ะฟะตัะตะผะตะฝะฝัั
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 ์ ์ด๊ฐ ํ์ฑํ๋๊ณ ํ์ ์ ๋ถํดํ๊ฑฐ๋ ์์ถ์ํฌ ์ ์์ต๋๋ค.โจ
๊ทธ๊ฒ ๋ค์ผ! Alexey๋ ์ฐ์
๋์์ ๊ฑธ๋ง์ ๋์ ์์ค์ ์ง์์ ๋ณด์ฌ์ฃผ์์ต๋๋ค :) ์ฐ์น์์๊ฒ๋ ๊ธฐ์ต์ ๋จ๋ ์ํ์ ๋ณด๋์ต๋๋ค. ๋ชจ๋ ์ฐธ๊ฐ์๋ค์๊ฒ ๊น์ ๊ฐ์ฌ๋ฅผ ๋๋ฆฝ๋๋ค!
์ถ์ฒ : habr.com