+++
title = "Reverse engineering di un lettore di presenze"
summary = "Step 1: incominciare a capire come funziona il tutto"
date = "2024-04-28"

tags = ["Reverse Engineering", "Lettore di Presenze", "Decompilazione", "Codemerx"]
categories = ["Progetti"]
series = ["Lettore di presenze"]
series_order = 1
+++

Uno dei motivi per cui ho creato questo blog è per condividere le mie
esperienze con altri pazzi entusiasti che adorano questo tipo di contenuti di
nicchia come me.

In questa serie di articoli andrò a spiegare come ho eseguito il reverse
engineering del protocollo di comunicazione usato tra un lettore di presenze ed
il suo client (ovviamente creato solo per Windows) ed andremo a creare un
client alternativo con [Rust](https://rust-lang.org/) e
[Tauri](https://tauri.app/) per rimpiazzare quello proprietario.

![L'R701 di I.P.S. Informatica](images/01-r701.png "Ecco il lettore di presenze
che andremo a reverse-enginerizzare")

## Un po' di background

Mio padre ha voluto aggiornare il vecchio lettore di presenze per la sua
attività: è volato su Amazon e ha comprato
l'[R701](https://ipsattendant.it/rilevatore-presenze-r701/) di [I.P.S.
Informatica](https://ipsinformatica.info/).

A differenza del vecchio lettore, con questo i dipendenti possono registrare la
loro presenza tramite PIN, impronta digitale o tramite un badge RFID, poi le
registrazioni possono essere scaricate tramite il client ufficiale per Windows
o tramite una chiavetta USB.

![Il vecchio lettore di presenze](images/02-old-clock.png "Il vecchio lettore
di presenze assomigliava a questo")

Il problema è che il client, oltre ad essere installabile solo su Windows e
richiedere un'account per eseguire azioni offline, non risponde ai requisiti
dell'azienda.

Sarebbe gradito che ogni mese venisse fatto un report per ogni dipendente, con
una tabella che permetta di vedere le ore lavorate ogni giorno. Invece il
software ufficiale permette di scaricare solo una lista di presenze, senza
alcun tipo di divisione per mese o per dipendente, e non permette di esportare
il tutto in un file `.ods`.

Così, in pura modalità "[Stallman quando la nuova stampante Xerox si
inceppa](https://oreilly.com/openbook/freedom/ch01.html)", ho deciso che la
soluzione migliore è riscrivere il tutto in modo *open-source*.

## Dump delle registrazioni tramite USB

Come prima cosa ho provato a scaricare le registrazioni tramite una chiavetta
USB, dato che questo metodo non necessita di un PC Windows. Così ho formattato
una chiavetta in FAT32 e, dopo aver creato un utente di test e aver creato
qualche registrazione, ho scaricato i dati sul mio laptop.

Una volta aperto il contenuto della chiavetta ho notato che il lettore ha
creato due file:

* `~tmp.tmp`: che contiene la stringa `usb test!!` ripetuta 384 volte;
* `AGLog_001.txt`: che contiene le registrazioni.

Credo che il file `~tmp.tmp` venga usato dal registratore solo per vedere se la
chiavetta USB è scrivibile, quindi possoiamo ignorarlo.

Aprendo il file `AGLog_001.txt` possiamo andare ad intuire i vari campi che il
lettore si salva in memoria:

```csv
No	Mchn	EnNo		Name		Mode	IOMd	DateTime	
000001	1	000000001	test      	34	0	2024/04/28  16:04:23
000002	1	000000001	test      	33	1	2024/04/28  16:05:28
000003	1	000000001	test      	35	2	2024/04/28  16:08:49
000004	1	000000001	test     	35	3	2024/04/28  16:09:01
```

* `No` è l'ID della registrazione
* `Mchn` è l'ID del registratore
* `EnNo` è l'ID del dipendente che ha effettuato la registrazione
  (**En**ployee**No**mber ?)
* `Name` è il nome del dipendente
* `Mode` è la modalità con coi il dipendente ha registrato la presenza:
  * `33` è tramite l'impronta digitale
  * `34` è usando il PIN
  * `35` è con il badge
* `IOMd` è il campo che simboleggia l'ingresso o l'uscita del dipendente
  (**I**n/**O**ut **M**o**d**e ?):
  * `0` è il primo ingresso
  * `1` è la prima uscita
  * `2` è il secondo ingresso
  * `3` è la seconda uscita
* `Datetime` è la data e l'ora della registrazione

Considerando che ho registrato le presenze passando per tutte le modalità di
ingresso e di uscita in ordine e che ho usato il PIN la prima volta, l'impronta
digitale la seconda ed il badge le ultime due, possiamo ritenerci soddisfatti
del risultato.

Potremmo addirittura scrivere un programma in Python che usi la libreria
[csv](https://docs.python.org/3/library/csv.html) per estrarre i dati che ci
servono da questo file.

Ma questo non sarebbe così interessante da essere un post sul mio blog. Non
voglio entrare nel menù di amministrazione del dispositivo per poi premere in
ordine i tasti `2`, `1` e `2` per fare il dump, poi prendere il file risultante
e filtrarlo con uno script Python senza interfaccia grafica.

Voglio creare un programma che funzioni nativamente su Windows e Linux e che mi
permetta di scaricare tutti i dati che mi interessano con un singolo click, già
formattati correttamente.

Prima di tirare fuori [Wireshark](https://wireshark.org/) e provare a sniffare
dei pacchetti però, voglio provare un'altra tecnica...

## Decompilare il client closed-source

Come disse una volta [un
saggio](https://twitter.com/DebugPrivilege/status/1531661046238388226): "Tutto
il codice è *open-source* se sai leggere Assembly".

Dato che la compagnia che ha scritto il codice è italiana e che il client
funziona solo su Windows, c'è un alta probabilità che il codice sia stato
scritto in C# su piattaforma .NET.

Se questo è il caso, dovrebbe essere abbastanza semplice ottenere il codice
sorgente tramite un decompilatore come
[CodemerxDecompile](https://decompiler.codemerx.com/).

Quindi ho creato una macchina virtuale con [Windows 10
AME](https://archive.org/details/windows10-ame-21h1-2021-08-09/) e ho
installato il client ufficiale alla [versione
04.03.02](https://ipsattendant.it/download-programmi-e-manuali/).

{{< carousel images="images/03-official-client-installation/*"
aspectRatio="16-9" interval="1000" >}}

Una volta installato il client ufficiale ho copiato la directory `C:\Program
Files (x86)\ipsAttendant` sulla mia macchina Linux e l'ho aperta con
CodemerxDecompile.

Come avevo previsto il codice è scritto in C#, quindi è facilmente leggibile.

![CodemerxDecompile](images/04-codemerx-decompile.png "Il codice
dell'eseguibile aperto con CodemerxDecompile")

Cercando di qua e di là ho scoperto l'amara verità: dentro al file
`Dichiarazioni.cs` sono presenti molti metodi interessanti, come
`FK_ConnectNet()`. Questi metodi però sono tutti import da una libreria
chiamata `FKAttend.dll`.

Cercando sul web, sembra che questa libreria sia in giro da molti anni e dubito
altamente che l'abbia scritta la compagnia del lettore. Ho trovato anche [la
documentazione ufficiale del
DLL](</posts/2024/04/reverse-engineering-an-attendance-clock-part-1/FKAttend User's Manual.pdf>),
ma nient'altro.

Dato che decompilare una libreria che manco il creatore ha avuto voglia di
implementare da se non è una cosa che sono disposto a fare, nel prossimo
articolo proveremo a fare il reverse engineering della comunicazione che
avviene tra client e dispositivo.
