Hardware Hacking 101 - Bit-banging

지난 회 하드웨어 입문 JTAGContinuity Test를 통해서 스펙을 알수 없는 하드웨어에 대한 UART, JTAG 등의 핀들을 알아 내는 데에 필요한 장비와 테크닉에 대해서 알아 보았습니다. 이번에는 여러 테크닉 중에서 하드웨어 칩에 대한 소프트웨어적인 컨트롤을 가능하게 해 주는 bit-banging이라는 테크닉에 대해서 설명하겠습니다.

Bit-banging

Bit-banging은 하드웨어 컴포넌트에 대해서 소프트웨적으로 신호를 보내어 컨트롤하는 행위를 통칭합니다. Bit-banging을 통해서 전용 하드웨어를 사용하지 않고도 데이타 전송을 흉내내는 방식으로 원하는 작업을 수행할 수 있습니다.

깊은 하드웨어적으로 많은 배경을 가지고 있지 않은 소프트웨어 시큐리티 리서처가 하드웨어 부품들에 대해서 테스트하거나 조사하기 위해서 유용하게 사용할 수 있는 방법입니다. 예들 들어 플래쉬 메모리를 하드웨어적으로 덤프하기 위해서는 전문적인 고가의 장비를 구매하고 사용법을 배우든지, 아니면 FPGA, 전용 MCU 등에 대한 프로그래밍 지식을 배워야 타겟이 되는 칩들에 대한 컨트롤이 가능합니다. Bit-banging은 자신이 사용하는 운영체제를 통해서 소프트웨어적으로 비슷한 형태의 작업을 가능하게 해 줍니다. Bit-banging은 때로는 너무 비싼 전용 하드웨어 장치들을 대신하여 임시로 해당 칩을 컨트롤하기 위해서 사용될 수 있습니다.

데이타 전송, 수신

데이타 전송을 위하여 소프트웨어를 사용하여 데이타를 시그널과 펄스로 인코딩하여 마이크로컨트롤러의 I/O 중 Tx 핀을통해서 타겟 칩에 디지털 신호를 보낼 수 있습니다. 신호를 받기 위해서는 일정한 시간 간격으로 데이타를 샘플링하는 방식을 사용합니다. 소프트웨어를 통하여 다음과 같은 통신을 위한 파라메터들을 모두 세팅합니다.

  • synchronization
  • timing
  • levels

FT2232H

이러한 bit-banging은 Arduino 등의 보드를 사용할 수 있지만, 편리성으로 인해서 FT2232H를 자주 사용합니다. FT2232H는 FTDI의 5세대 USB 프로세서로서, USB 2.0 Hi-Speed (480Mb/s) 를 지원하고 UART/FIFO 등의 프로토콜로의 데이타 변환을 지원합니다. 또한 여러한 방법으로 범용적인 프로토콜을 지원하도록 프로그래밍할 수 있습니다.

FT2232H는 칩 자체로 사용되기 보다는 브레이크아웃 보드 형태로 사용하는 것이 편리합니다. 다음과 같은 형태의 보드를 사용하여 FT2232H의 여러 핀들의 기능을 사용할 수 있습니다.

FT2232H에서 bit-banging을 위해서 사용되는 기능은 “MCU Host Bus Emulation Mode”입니다. Multi-Protocol Synchronous Serial Engine (MPSSE) 을 사용하여 FT2232H를 8048/8051 MCU처럼 작동하게 할 수 있습니다. 8051 MCU는 1980년대 인텔에서 개발된 칩으로서 여러 임베디드 디바이스나 자동차등에 널리 사용되어 왔습니다.


FT2232H Commands

I/O 핀들을 통해서 데이타 전송을 수행하기 위해서 다음과 같은 전용 명령셋을 제공합니다. 이러한 명령을 통해서 특정 핀에 특정 신호를 쓰거나 읽는 것이 가능해집니다.

Commands Operation Address
0x90 Read 8 bit address
0x91 Read 16 bit address
0x92 Write 8 bit address
0x93 Write 16 bit address
0x82 Set High byte (BDBUS6, 7)
0x83 Read High byte (BDBUS6, 7)

Windows Setup

FT2232H의 특징은 USB 포트로 호스트 컴퓨터에 접속된 형태로 USB를 통해서 직접적인 컨트롤이 가능하다는 것입니다. libusb와 pyftdi 파이썬 라이브러리를 사용하여 다음과 같은 방식으로 직접 컨트롤이 가능합니다.

  • pyftdi supports Bit-banging, UART, i2C, SPI. JTAG mode
  • Pinouts for pyftdi is available at FTDI device pinout.

다음과 같은 절차를 통해서 윈도우즈 머신에서 libusb/PyUSB/pyftdi 환경을 셋업할 수 있습니다.

  1. Install libusb
  2. Install PyUSB
pip install pyusb
  1. Install pyftdi
pip install pyftdi

Case Study: NAND Flash Reader

FT2232H는 범용적으로 칩들을 컨트롤할 수 있고, 그러한 적용을 가장 잘 보여주는 예가 NAND Flash Reader입니다. SPriteMods는 FT2232H NAND flash reader - Hardware라는 아티클을 통해서 저가의 FT2232H를 사용하여 NAND Flash Reader를 제작할 수 있는지에 대한 자료를 공개합니다. 이후 조금더 발전된 형태의 Flash 메모리 덤프 툴을 다른그림에서 DumpFlash 프로젝트로 릴리즈하게 되었습니다. 이 툴을 사용하여 어떻게 임베디드 POS 디바이스등의 메모리를 덤프할 수 있었는지에 대해서는 Reverse Engineering Flash Memory for Fun and Benefit를 통하여 알아 보실수 있습니다.


pyftdi Example

pyftdi는 사용례는 DumpFlash를 통해서 확인할 수 있습니다.

예를 들어 DumpFlash flashdevice.py에는 다음과 같이 FTDI 디바이스를 오픈하는 코드가 존재합니다.

try:
      self.Ftdi.open(0x0403, 0x6010, interface = 1)
except:
      traceback.print_exc(file = sys.stdout)
  • FTDI 디바이스를 MCU 모드로 세팅합니다.
      self.Ftdi.set_bitmode(0, self.Ftdi.BITMODE_MCU)
  • 초기 클락 모드 등의 여러 파라메터를 세팅합니다.
      if self.Slow:
         # Clock FTDI chip at 12MHz instead of 60MHz
         self.Ftdi.write_data(Array('B', [ftdi.Ftdi.ENABLE_CLK_DIV5]))
      else:
         self.Ftdi.write_data(Array('B', [ftdi.Ftdi.DISABLE_CLK_DIV5]))

      self.Ftdi.set_latency_timer(self.Ftdi.LATENCY_MIN)
      self.Ftdi.purge_buffers()
  • 이후 특정 핀에 특정 시그널을 보내거나 읽는 것이 가능해집니다.
      self.Ftdi.write_data(Array('B', [ftdi.Ftdi.SET_BITS_HIGH, 0x0, 0x1]))

References


트레이닝 정보

  • 여기에 소개된 분석 기법을 비롯하여 실습을 통해서 하드웨어 리버스 엔지니어링 기법에 대해서 학습하고 분석하는 내용은 하드웨어 리버스 엔지니어링 코스를 통해서 수강하실 수 있습니다.