HENRY

De Garoa Hacker Clube
Ir para navegação Ir para pesquisar

Esta página documenta a máquina impressora de cheques HENRY, encontrada no lixo da Estação de Metareciclagem Samambaia (Distrito Federal).

Modelo da PCB: HENRY PINHAIS/PR REV.1

componentes

  • CPU: 80C31
  • RAM: UM62256B (RAM estática de 32k bytes)
  • EEPROM 27C512 (64k bytes) Marcada com um adesivo escrito "PROT V19 Henry Equipamentos e Sistemas LTDA"
  • glue logic: diversos chips TTL da família 74
  • display de cristal líquido de 2x16 caracteres (HD44780)
  • CHIP desconhecido na posição U2.

U2

  • hipótese: DS1307: 64 x 8 Serial Real-Time Clock

esquemático

Está sendo levantado o esquemático desta placa (rev1) no repositório https://github.com/GaroaHC/HENRY no subdiretório kicad.

emulação

No repositório https://github.com/GaroaHC/HENRY no subdiretório mess há um esboço de emulador deste equipamento (já parcialmente funcional).

Em Janeiro de 2014 este driver foi incorporado oficialmente ao código fonte do projeto MESS.

Comportamento do dispositivo real

  • Ao ligar, aparece a mensagem "Inicializando..."
  • Logo depois, "Verificando memória..."
  • E, enfim, "Ajuste a data:\n01/01/99 sex"
  • botão preto superior muda de campo ciclicamente da esquerda para a direita
  • botão preto inferior incrementa o campo selecionado (o dia da semana é calculado pela máquina e exibido à direita da data)
  • botão azul alterna entre ajuste de data e a mensagem "PROT Vrs. R19\n 01/02/02" o que nos leva a crer que o firmware R19 é de 1.o de fevereiro de 2002.
  • botão azul pressionado por algum tempo = OK, vai para próxima configuração: "Ajuste a hora" "01:14:00"
  • botão azul pressionado por algum tempo = mostra "Entrando em ajustes." e logo depois "Apagar a memoria e o horario ?" + cursor piscante
  • clique no botao azul = "PROTOC. A" "01:01 seg 1via"
  • Ao fechar o opto de detecção de papel, a cabeça de impressão se move para a direita e depois para a esquerda e em seguida, vemos a mensagem "Dificuldades :" "Movimento motor"

ligações

display

Display LCD de 2 linhas de caracteres compatível com HITACHI HD44780. Extremamente comum.

  • Pino 1 = marrom -> ligado ao pino 1 do display
  • pino 2 = não usado
  • pino 3 = vermelho
  • e assim por diante

Os pinos 15 e 16 do display não estão ligados a nada. Apesar de se pular o pino 2 no conector, a ligação dos pinos do display é sequencial, ou seja, pino 1 = marrom, pino 2 = vermelho, etc...

teclado

  • pino 1 = marrom -> botão preto de cima
  • pino 2 não usado
  • pino 3 = vermelho -> botão preto de baixo
  • pino 4 = laranja -> botão azul
  • pino 5 = amarelo -> GND: comum a todos os botões

motores

  • pino 1 = amarelo
  • pino 2 não usado
  • pino 3 = laranja
  • pino 4 não usado

impressora

  • pino 1 não usado
  • pino 2 = amarelo
  • pino 11 = roxo

Transistores TIP122 em encapsulamento TO-220.

jumper 1

Botão liga-desliga ? Aparentemente não tem polaridade.

Olhando para o silk da placa com o texto JP1 de pé:

  • pino da esquerda = marrom
  • pino da direita = vermelho

sensores

  • pino 1 não usado (o conector nem encaixa nesse pino)
  • pino 2 = marrom (Vcc) pino 0 dum sensor optico (de leitura da presença de um cheque?)
  • pino 3 não usado
  • pino 4 = vermelho -> pino 1 do opto do encoder
  • pino 5 = laranja -> pino 3 do opto do encoder
  • pino 6 = amarelo -> pino 1 do fim de curso
  • pino 7 = verde -> pino 3 do fim de curso
  • pino 8 = azul -> pino 1 do sensor de cheque
  • pino 9 = roxo -> pino 3 do sensor de cheque

Os pino 2 tanto do sensor do cheque e do fim de curso não é usado.

borne CN7

Olhando o silk com o texto GND, VAC, etc de pé:

  • GND -> BAT - da placa da fonte
  • VAC da esquerda -> BAT + da placa da fonte
  • VAC da direita -> não está ligado em nada
  • BAT + -> fio vermelho do soleníde
  • BAT - -> aterramento (na carcaça e na fiação da tomada)


borne CN8

  • C -> ligado em nada
  • NA -> fio preto do solenóide

dump da EEPROM

codigo de arduino para fazer o dump

Rodamos esse código 4 vezes (uma para cada par de bits) e o resultado foram 4 arquivos de dump lidos na porta serial.

#define dado0 A0
#define dado1 A1
#define Addr0 2
#define Addr1 3
#define Addr2 4
#define Addr3 5
#define Addr4 6
#define Addr5 7
#define Addr6 8
#define Addr7 9
#define Addr8 10
#define Addr9 11
#define Addr10 12
#define Addr11 13
#define Addr12 A2
#define Addr13 A3
#define Addr14 A4
#define Addr15 A5

int endereco;

void setup(){
  endereco = 0;
  Serial.begin(9600);
  pinMode(Addr0, OUTPUT);
  pinMode(Addr1, OUTPUT);
  pinMode(Addr2, OUTPUT);
  pinMode(Addr3, OUTPUT);
  pinMode(Addr4, OUTPUT);
  pinMode(Addr5, OUTPUT);
  pinMode(Addr6, OUTPUT);
  pinMode(Addr7, OUTPUT);
  pinMode(Addr8, OUTPUT);
  pinMode(Addr9, OUTPUT);
  pinMode(Addr10, OUTPUT);
  pinMode(Addr11, OUTPUT);
  pinMode(Addr12, OUTPUT);
  pinMode(Addr13, OUTPUT);
  pinMode(Addr14, OUTPUT);
  pinMode(Addr15, OUTPUT);
  
  pinMode(dado0, INPUT);
  pinMode(dado1, INPUT);
}

void le_dado(int address){
  digitalWrite(Addr0, address & (1 << 0) ? HIGH : LOW);
  digitalWrite(Addr1, address & (1 << 1) ? HIGH : LOW);
  digitalWrite(Addr2, address & (1 << 2) ? HIGH : LOW);
  digitalWrite(Addr3, address & (1 << 3) ? HIGH : LOW);
  digitalWrite(Addr4, address & (1 << 4) ? HIGH : LOW);
  digitalWrite(Addr5, address & (1 << 5) ? HIGH : LOW);
  digitalWrite(Addr6, address & (1 << 6) ? HIGH : LOW);
  digitalWrite(Addr7, address & (1 << 7) ? HIGH : LOW);
  digitalWrite(Addr8, address & (1 << 8) ? HIGH : LOW);
  digitalWrite(Addr9, address & (1 << 9) ? HIGH : LOW);
  digitalWrite(Addr10, address & (1 << 10) ? HIGH : LOW);
  digitalWrite(Addr11, address & (1 << 11) ? HIGH : LOW);
  digitalWrite(Addr12, address & (1 << 12) ? HIGH : LOW);
  digitalWrite(Addr13, address & (1 << 13) ? HIGH : LOW);
  digitalWrite(Addr14, address & (1 << 14) ? HIGH : LOW);
  digitalWrite(Addr15, address & (1 << 15) ? HIGH : LOW);

//  delay(1);
  
  Serial.write(digitalRead(dado1) ? "1" : "0");
  Serial.write(digitalRead(dado0) ? "1" : "0");
}

void loop(){
  if (endereco<65536){
    Serial.print((endereco >> 8) & 0xff, HEX);
    Serial.print(endereco & 0xff, HEX);
    Serial.write(":");
    le_dado(endereco);
    Serial.write("\n");
    endereco++;
  }
}

script python para gerar a imagem

Depois de executar o comando

cut -d: -f2 dump0.txt > bits0.txt
cut -d: -f2 dump1.txt > bits1.txt
cut -d: -f2 dump2.txt > bits2.txt
cut -d: -f2 dump3.txt > bits3.txt

Usamos o script python abaixo para unir os dumps de pares de bits em uma única imagem dump.bin de 64kbytes:

b0 = open("bits0.txt").readlines()
b1 = open("bits1.txt").readlines()
b2 = open("bits2.txt").readlines()
b3 = open("bits3.txt").readlines()

dump = open("dump2.bin", "wb")

for i in range(0x100, 65536):
  valor = b3[i].strip() + b2[i].strip() + b1[i].strip() + b0[i].strip()
  print valor
  print int(valor, 2)
  dump.write(chr(int(valor,2)))

script para desembaralhar endereços

As 4 vias menos significativas do barramento de endereços estão embaralhadas.

Para gerar uma ROM desembaralhada, usamos o seguinte script:

b0 = open("bits0.txt").readlines()
b1 = open("bits1.txt").readlines()
b2 = open("bits2.txt").readlines()
b3 = open("bits3.txt").readlines()

dump = open("henry_protv19.bin", "wb")
desobfuscado = open("henry_protv19_desobfuscado.bin", "wb")

swap_rule = [7, 6, 5, 4, 0, 1, 2, 3]

for addr in range(65536):
  i = addr
  value_str = b3[i].strip() + b2[i].strip() + b1[i].strip() + b0[i].strip()
  value = int(value_str, 2)
  dump.write(chr(value))

  swapped_addr = addr & 0xff00
  for i in range(8):
    swapped_addr |= ((addr>>i) & 1) << swap_rule[i]

  i = swapped_addr
  value_str = b3[i].strip() + b2[i].strip() + b1[i].strip() + b0[i].strip()
  value = int(value_str, 2)
  desobfuscado.write(chr(value))

dump.close()
desobfuscado.close()