현장 장비의 값을 받아야 했는데 규격 문서가 없었다. 만든 곳에 물어보니 담당자가 없다고 했고 찾아 준 예전 자료는 다른 모델 것이었다.
결국 직접 알아내야 했다.
Table of contents
Open Table of contents
일단 잡아서 본다
장비와 기존 프로그램 사이에 오가는 것을 그대로 떴다.
02 01 03 00 08 41 42 30 31 32 33 34 35 1A 03
02 01 03 00 08 41 42 30 31 32 33 34 36 1B 03
02 01 03 00 08 41 42 30 31 32 33 34 37 1C 03
세 줄이 거의 같고 뒤쪽 두 자리만 다른데 값이 하나씩 늘어나는 것을 보니 순번이나 측정값으로 보였다.
한 줄만 떠서는 아무것도 안 보인다. 02 로 시작해 03 으로 끝나는 바이트 열만 있다.
여러 번 주고받게 해 놓고 전부 모은 것이 출발점이었고 겹쳐 놓아야 고정된 자리와 변하는 자리가 갈린다.
규칙 찾기
같은 부분과 다른 부분을 갈라 적었다.
| 위치 | 값 | 추측 |
|---|---|---|
| 처음 | 02 | 시작 표시 |
| 그다음 | 01 03 | 장비 번호? 명령 종류? |
| 그다음 | 00 08 | 뒤에 오는 길이 (실제로 8바이트) |
| 가운데 | 41 42 30 31... | 내용 |
| 끝에서 둘째 | 1A 1B 1C | 검사값? |
| 마지막 | 03 | 끝 표시 |
00 08 이 실제 내용 길이와 맞았고 길이가 들어 있다는 것이 이 단계의 가장 큰 발견이었다.
길이를 믿으면 어디까지가 한 덩어리인지가 정해지므로 03 을 찾아 헤맬 필요가 없어진다.
가운데 41 42 30 31 을 문자로 바꾸니 AB012345 였다. 사람이 읽을 수 있는 값이라 여기가 내용이다.
검사값을 맞혀 봤다
끝에서 둘째 바이트가 계속 걸렸는데 내용이 1씩 늘 때 1A 가 1B 로 같이 늘었다.
몇 가지를 시도했다.
1. 다 더하기 앞부터 끝까지 더해서 하위 한 바이트만 보기
2. 다 XOR 하기 하나씩 배타적 논리합
3. 일부만 더하기 시작 표시를 빼고 더하기
셋째가 맞았고 시작 표시 02 를 뺀 나머지를 더한 값의 하위 한 바이트였다.
값이 몇 개 맞았다고 답이라고 하기에는 일렀고 우연히 맞거나 다른 방법이 같은 값을 낼 수도 있다.
검증 — 틀린 값으로 확인
그래서 일부러 틀린 검사값을 넣어 보냈다. 계산이 맞다면 장비가 그것을 거부해야 한다.
실제로 거부했고 이것으로 그 자리가 검사에 쓰인다는 것이 확정됐다. 맞는 값 세 개보다 틀린 값 하나가 더 많은 것을 말해 줬다.
맞는 값만 넣어 보는 것으로는 그 자리가 검사값인지 그냥 무시되는 자리인지가 안 갈린다. 통과가 나오면 실패해야 하는 입력으로 한 번 더 돌려 봐야 그 확인이 무엇을 가른 것인지 안다.
안 맞는 게 나온다
며칠 잘 되다가 이상한 것이 들어왔다.
02 01 03 00 0A 41 42 30 31 32 33 34 35 02 03 5F 03
^^ ^^
내용 안에 02 와 03 이 들어 있는데 시작 표시와 끝 표시로 쓰는 값이라 그대로 읽으면 여기서 끊긴다.
찾아보니 내용에 표시 값이 들어갈 때 다르게 바꿔 보내는 방법이 있었고 실제 자료에 그런 흔적이 있었다.
여기서 앞의 발견이 값을 했다. 길이가 먼저 오므로 그것을 믿고 그만큼 읽으면 끝 표시를 찾을 이유가 없다.
00 0A 를 읽고 열 바이트를 가져오면 안에 03 이 있어도 상관없다. 길이 자리를 먼저 찾아 둔 것이 예외를 만난 날 쓰였다.
전체 흐름 — 정리한 방법
돌아보니 순서가 이렇게 정리됐다.
1. 오가는 것을 그대로 뜬다
2. 여러 줄을 나란히 놓고 같은 부분과 다른 부분을 가른다
3. 길이 자리를 먼저 찾는다 — 있으면 덩어리 나누기가 쉬워진다
4. 사람이 읽을 수 있는 부분을 찾는다 — 문자로 바꿔 본다
5. 검사값은 몇 가지 흔한 방법을 시도한다
6. 틀린 값을 넣어 거부되는지 확인한다
7. 예외 경우를 계속 모은다 — 처음 며칠에는 안 나온다
셋째가 그 뒤 전부를 쉽게 만들었다. 넷째와 여섯째는 추측을 사실로 바꾸는 단계다.
주의 — 아직 모르는 것
알아낸 것으로 쓰고는 있는데 모르는 것이 셋 남았다. 01 03 이 무엇인지 모른다.
장비가 한 대뿐이라 01 03 이 변하는 것을 못 봤다. 두 대가 되면 장비 번호인지 명령 종류인지 갈릴 것이다.
모든 명령을 다 본 것도 아니다. 지금은 값을 읽는 것만 봤고 설정을 바꾸는 명령이 있을 텐데 기존 프로그램이 그것을 안 해서 못 봤다.
다른 모델에서 통할지도 모르는데 이 모델에서 알아낸 것이라 다른 모델은 처음부터 다시 해 봐야 한다.
문서가 있으면 이 셋을 5분이면 안다. 없어서 계속 모르는 채로 쓰고 있다.
정리
- 문서가 없으면 오가는 것을 그대로 떠서 여러 줄을 나란히 놓고 비교한다
- 한 줄만 봐서는 고정된 자리와 변하는 자리가 안 갈린다
- 길이 자리를 먼저 찾으면 끝 표시를 찾아 헤매지 않아도 된다
- 내용을 문자로 바꿔 보면 읽을 수 있는 구간이 드러난다
- 검사값은 합과 배타적 논리합과 일부 합 순으로 시도한다
- 틀린 값을 넣어 거부되는지로 확인해야 우연과 갈린다
- 내용에 표시와 같은 값이 들어가면 바꿔 보내는 방식이 쓰인다
- 그때도 길이를 믿고 그만큼 읽으면 된다
- 예외는 처음 며칠에 안 나오므로 계속 모은다