Como fazer a engenharia reversa de um dispositivo USB (no caso um no-break APC)?


#1

Caros, comprei um no-break APC modelo Back-UPS BZ1200-BR, mas ele não é compatível com Mac OS.
Ele tem uma porta USB que permite que o mesmo seja ligado a um computador e que um software da APC desligue o computador caso falte energia e o no-break funcione por um determinado período de tempo. A idéia é impedir que o computador desligue de maneira segura ao invés de simplesmente ficar sem energia quando a bateria do no-break acabar.

Imagino que este tipo de dispositivo tenha um protocolo via USB bem simples e pensei em montar um pequeno programa no mac ou mesmo num Raspberry Pi rodando LINUX para ficar de olho no no-break e se ele indicar que está funcionando na bateria por um determinado tempo ele desligaria o Mac rodando um script que eu também desenvolverei.

Basicamente o que preciso é de ler as informações do no-break via o cabo USB dele.

Alguma dica de por onde começar?


#2

Com o wireshark no linux/windows é possível sniffar a USB. Nunca utilizei mas seria esse o meu passo após tentar identificar se o Nobreak resonde em alguma classe genérica.


#3

Como @Euripedes_Rocha mencionou, é preciso analisar o comportamento o dispositivo com um sniffer, isso vai levar um bom tempo escovando informações que podem ou não estar claras, creio que, após ou mesmo durante este passo, é preciso atacar o dispositivo e, por fim, escrever um driver para o aparelho.

Eu usaria um sniffer para USB qualquer e Python com PyUSB (mas claro que pode ser feito com qualquer linguagem).

Aqui tem um bom documento no Adafruit sobre o hacking do Kinect.
Aqui o autor hackeia um Joypad por tentativa e erro, baseado na postagem mandatória do Hack a Day.

Claro que nenhum trata especificamente sobre o No-break, mas é um bom ponto de partida.

Depois de tudo é só fazer o script do driver iniciar com o sistema.


#4

E para fazer o “sniffing” é preciso ter o software dele rodando ná maquina, certo? Tipo, precisarei de uma máquina com windows rodando o software da APC.

Fiquei pensando se não tem algo mais simples tipo… o no-break ficaria apenas enviando os dados, quase um streaming, não sei se este bixo é mais sofisticado do que isto.


#5

Bom, eu uso Windows apenas para jogar, mas não creio que seja necessário esse S.O. para fazer o que deseja, no artigo acima, o autor desenvolve o driver por tentativa e erro, ou seja… É possível que o dispositivo fique enviando sinais para o host, esses sinais só não são tratados porque não há um driver/software fazendo o tratamento desses dados.

O primeiro código desse artigo, o que o autor faz é justamento conectar na porta e ficar escutando, uma espécie de sniffer bem remoto:

#!/usr/bin/env python
import sys

pipe = open('/dev/input/by-id/usb-Logitech_Logitech_Dual_Action-event-joystick', 'r')
action = []

while 1:
    for character in pipe.read(1):
        action += ['%02X' % ord(character)]
        if len(action) == 8:
            print action
            action = []

O que ele faz é gerar uma lista com os comandos que são gerados a cada iteração com o joypad. Se ele aperta um botão, os comandos gerados são arquivados na lista “action” no formato de até 2 números hexadecimais considerando 0 e divide os blocos de comandos em lista de até 8 elementos, por isso a saída fica:

['B2', 'DD', 'E0', '4E', 'CF', 'DF', '0B', '00']
['04', '00', '04', '00', '01', '00', '09', '00']
['B2', 'DD', 'E0', '4E', 'D2', 'DF', '0B', '00']
['01', '00', '20', '01', '01', '00', '00', '00']
['B2', 'DD', 'E0', '4E', 'B4', 'E0', '0B', '00']
['00', '00', '00', '00', '00', '00', '00', '00']

Depois disso, ele apenas troca os dados de comandos por informação:

# ./game.py
Pressed Button 01
Released Button 01
Pressed Button 02
Released Button 02
Pressed Button 01
Pressed Button 02
Released Button 01
Released Button 02
Pressed Button 08
Released Button 08
Pressed Button 07
Released Button 07
Pressed Button 06
Released Button 06
Pressed Button 05
Released Button 05

A conclusão que chego é que é possível fazer a captação de dados sem a necessidade do software oficial, se assim fosse, era melhor desmontar o software e ver logo o que ocorre nele diretamente.

Por exemplo, deixe o No-break ligado na tomada e deixe um script escutando na porta USB, então retire o No-break da tomada e veja se algum comando foi enviado para a porta, esse comando seria, o “Battery Mode”, por exemplo… Ao reconectar na tomada, um outro comando é enviado? Há botões que podem ser pressionados para configuração? quais os comandos são enviados quando eles são pressionados? Quando ele está na bateria, fica enviando dados periodicamente? O que se pode interpretar desses dados? Percentual, nível ou algo assim? Esse seria um método bem bruto de fazer o detalhamento do comportamento do dispositivo.

Dei uma pesquisada também se alguém já não havia resolvido o problema com o Kernel do Linux e achei uma solução com FreeNAS: http://forums.freenas.org/index.php?threads/nobreak-bz1200-br-back-ups-rs-1200va-600w-bivolt-115-nt.20247/

Os dados que o cara encontrou na reversão dele, podem acabar sendo úteis para o MAC.


#6

Valeu Sandro!!! Vou brincar com isto logo que voltar de viagem!


#7

Eu acredito que usar o wireshark vai dar menos trabalho que escovar no python. Subir uma live distro e instalar o wireshark na parte persistente(nunca tentei esse cenário, mas não julgo ser complicado). Como o @sksdutra eu nem tenho o Windows aqui. É muito provável que o dispositivo suba em uma das classes genéricas( CDC por exemplo)


#8

@mlemos se o que você quer é apenas 1 feature, creio que você consiga fazer um script simples após algum tempo quebrando a cabeça, mas se quiser implementar mais coisas, acho melhor solicitar à fabricante que compile o programa oficial para o Mac OS, dei uma olhadinha hoje pela tarde no manual de instruções e o programa deles tem tantos features (até gerenciamento remoto) que acho uma tarefa deveras complexa implementar a maioria daquelas coisas só pela reversão de engenharia num S.O. diferente, pelo que vi já há drivers para Windows e Linux, acho que não deve ser problema para a fabricante compilar para Mac OS.


#9

Valeu @sksdutra, a idéia é um único feature mesmo.
Quero algo bem simples… o script ficaria num loop apenas detectando se o No-Break está em uso (via bateria) ou não (via rede elétrica). Se estiver via bateria ele roda um comando remoto no mac (ssh) e faz o shutdown. Simples assim.


#10

Bom, acho que isso dá pra fazer com tranquilidade.


#11

Hehe. O problema é a falta de tempo!
Valeu pelas dicas!


#12

Amigo tem um video bem simples mostrando passo a passo como fazer a engenharia reversa do USB :smiley:
Usando WireShark… http://www.youtube.com/watch?v=GdvmsWnZkyc
Usei uma lib quando programava Delphi, mais tem uns 4 anos e nao lembro qual era kkkk… mais pelo WiresShark da pra fazer isso mesmo :smiley: e ainda roda no mac, ai vc roda o virtualbox (free) com um os win qualquer so pra ele simular a conexao do USB, e pimba.


#13

Acho que instalar uma máquina virtual, instalar um SO nesta máquina e mais o WS para implementar só um feature, que é o objetivo do @mlemos, é como um trabalho de guerra para vencer uma só batalha. Ainda fico com a opção de usar a linguagem que gosta com uma lib para USB, para coleta de dados para, só então, criar o DD ou widget, se assim for necessário.


#14

Manoel,

Não sofra…rs


http://www.networkupstools.org/ups-protocols.html
https://www.google.com.br/?gws_rd=ssl#q=ups+usb+protocol

Boa sorte.

Atenciosamente,
Ronaldo Roledo.