Mudanças entre as edições de "HENRY"

De Garoa Hacker Clube
Ir para navegação Ir para pesquisar
 
(14 revisões intermediárias por 2 usuários não estão sendo mostradas)
Linha 1: Linha 1:
Esta página documenta a máquina impressora de cheques HENRY, encontrada no lixo da Estação de Metareciclagem Samambaia.
+
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
 
Modelo da PCB: HENRY PINHAIS/PR REV.1
Linha 5: Linha 5:
 
==componentes==
 
==componentes==
   
* CPU: 8031
+
* CPU: 80C31
* RAM: UM62256B (32k bytes ?)
+
* RAM: UM62256B (RAM estática de 32k bytes)
* EEPROM 27C512 (64k bytes)
+
* EEPROM 27C512 (64k bytes) Marcada com um adesivo escrito "PROT V19 Henry Equipamentos e Sistemas LTDA"
* diversos chips TTL da família 74
+
* 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 ==
 
== ligações ==
Linha 14: Linha 43:
 
===display===
 
===display===
   
Parece um display padrão de duas linhas de caracteres como os vendidos no site da TATO.
+
Display LCD de 2 linhas de caracteres compatível com HITACHI HD44780. Extremamente comum.
   
 
* Pino 1 = marrom -> ligado ao pino 1 do display
 
* Pino 1 = marrom -> ligado ao pino 1 do display
Linha 21: Linha 50:
 
* e assim por diante
 
* e assim por diante
   
Os pinos 15 e 16 do display não estão ligados a nada
+
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 ===
 
=== teclado ===
Linha 29: Linha 58:
 
* pino 3 = vermelho -> botão preto de baixo
 
* pino 3 = vermelho -> botão preto de baixo
 
* pino 4 = laranja -> botão azul
 
* pino 4 = laranja -> botão azul
* pino 5 = amarelo -> comum a todos os botões
+
* pino 5 = amarelo -> GND: comum a todos os botões
   
 
=== motores ===
 
=== motores ===
Linha 43: Linha 72:
 
* pino 2 = amarelo
 
* pino 2 = amarelo
 
* pino 11 = roxo
 
* pino 11 = roxo
  +
  +
Transistores TIP122 em encapsulamento TO-220.
   
 
=== jumper 1 ===
 
=== jumper 1 ===
Linha 55: Linha 86:
   
 
* pino 1 não usado (o conector nem encaixa nesse pino)
 
* pino 1 não usado (o conector nem encaixa nesse pino)
* pino 2 = marrom (parece ser o terra?) pino 0 dum sensor optico (de leitura da presenção de um cheque?)
+
* pino 2 = marrom (Vcc) pino 0 dum sensor optico (de leitura da presença de um cheque?)
 
* pino 3 não usado
 
* pino 3 não usado
 
* pino 4 = vermelho -> pino 1 do opto do encoder
 
* pino 4 = vermelho -> pino 1 do opto do encoder
Linha 81: Linha 112:
 
* C -> ligado em nada
 
* C -> ligado em nada
 
* NA -> fio preto do solenóide
 
* 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.
  +
  +
<pre>
  +
#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++;
  +
}
  +
}
  +
</pre>
  +
  +
===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:
  +
  +
<pre>
  +
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)))
  +
</pre>
  +
  +
===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:
  +
  +
<pre>
  +
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()
  +
</pre>
  +
  +
[[Categoria:Projetos]]

Edição atual tal como às 17h41min de 5 de janeiro de 2014

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()