159 lines
6.4 KiB
Markdown
Raw Normal View History

2024-04-28 20:58:13 +02:00
+++
title = "Reverse Engineering of an Attendance Reader"
summary = "Step 1: Beginning to understand how everything works"
date = "2024-04-28"
tags = ["Reverse Engineering", "Attendance Reader", "Decompilation", "Codemerx"]
categories = ["Projects"]
series = ["Attendance Reader"]
series_order = 1
+++
One of the reasons I created this blog is to share my experiences with other
enthusiastic geeks who love this kind of niche content like me.
In this series of articles, I will explain to you how I reverse-engineered the
communication protocol used between an attendance reader and its (Windows-only)
client, and we will create an alternative client with
[Rust](https://rust-lang.org/) and [Tauri](https://tauri.app/) to replace the
proprietary one.
![I.P.S. Informatica's R701](images/01-r701.png "Here's the attendance reader
we're going to reverse-engineer")
## A bit of background
My dad wanted to update the old attendance reader for his small business, so he
went straight on Amazon and bought the
[R701](https://ipsattendant.it/rilevatore-presenze-r701/) from [I.P.S.
Informatica](https://ipsinformatica.info/).
Unlike the old reader, with this one employees can record their presence via
PIN, fingerprint, or RFID badge, then the records can be downloaded through the
official Windows client or via a USB stick.
![The old attendance reader](images/02-old-clock.png "The old attendance reader
looked something like this")
The problem is that the client, besides being installable only on Windows and
requiring an account to perform even offline actions, doesn't meet my dad's
requirements.
It would be appreciated if a report was generated every month for each
employee, with a table showing the hours worked each day. Instead, the official
software only allows you to download a list of presences, without any kind of
division by month or employee, and it doesn't allow exporting everything to a
`.ods` file.
So, in pure "[Stallman when the new Xerox printer
jams](https://oreilly.com/openbook/freedom/ch01.html)" mode, I decided that the
best solution was to rewrite everything in an open-source way.
## Dumping the records via USB
To begin, I tried to download the records using a USB stick, as this method
doesn't require a Windows PC. I formatted a USB stick in FAT32, and after
creating a test user and making a few records, I downloaded the data to my
laptop.
Once I opened the contents of the USB stick, I noticed that the reader had
created two files:
* `~tmp.tmp`: which contains the string `usb test!!` repeated 384 times;
* `AGLog_001.txt`: which contains the records.
I believe that the `~tmp.tmp` file is used by the reader only to check if the
USB stick is writable, so we can ignore it.
Opening the `AGLog_001.txt` file, we can start to look at the various fields
that the reader stores in memory:
```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` is the record ID
* `Mchn` is the reader ID
* `EnNo` is the employee ID who made the record (**En**ployee **No**mber?)
* `Name` is the employee's name
* `Mode` is the method by which the employee recorded their presence:
* `33` is via fingerprint
* `34` is using a PIN
* `35` is with the badge
* `IOMd` is the field containing the employee entrance or exit (**I**n/**O**ut
**M**o**d**e ?)
* `0` is the first entrance
* `1` is the first exit
* `2` is the second entrancance
* `3` is the second exit
* `Datetime` is the date and time of the record
Considering that I recorded the test records by passing through all the
entrance and exit modes in order, using the PIN the first time, the fingerprint
the second time, and the badge the last two times, we can be satisfied with the
result.
We could even write a Python program using the
[csv](https://docs.python.org/3/library/csv.html) library to extract the data
we need from this file.
But this wouldn't be interesting enough to be a blog post. I don't want to
enter the device's admin menu, press the `2`, `1`, and `2` keys in order to
make a dump, then take the resulting file and filter it with a Python script
without a graphical interface.
I want to create a program that runs natively on Windows and Linux and allows
me to download all the data I care about with a single click, in the format I
need.
Before pulling out [Wireshark](https://wireshark.org/) and trying to sniff some
packets, I want to try another technique...
## Decompiling the closed-source client
As [a wise man](https://twitter.com/DebugPrivilege/status/1531661046238388226)
once said, "All source code is open source if you can read Assembly".
Since the company that wrote the code is Italian and the client only works on
Windows, there's a high chance the code is written in C# on the .NET platform.
If this is the case, it should be pretty straightforward to get the source code
through a decompiler like
[CodemerxDecompile](https://decompiler.codemerx.com/).
So I created a virtual machine with [Windows 10
AME](https://archive.org/details/windows10-ame-21h1-2021-08-09/) and installed
the official client at [version
04.03.02](https://ipsattendant.it/download-programmi-e-manuali/).
{{< carousel images="images/03-official-client-installation/*"
aspectRatio="16-9" interval="1000" >}}
Once I installed the official client, I copied the `C:\Program Files
(x86)\ipsAttendant` directory onto my Linux machine and opened it with
CodemerxDecompile.
As I expected, the code is written in C#, so it's easily readable.
![CodemerxDecompile](images/04-codemerx-decompile.png "The executable code
opened with CodemerxDecompile")
Searching here and there, I found out the bitter truth: inside the
`Dichiarazioni.cs` file, there are many interesting methods, such as
`FK_ConnectNet()`. However, these methods are all imports from a library called
`FKAttend.dll`.
Searching the web, it seems this library has been around for many years, and I
highly doubt the company that made the reader wrote it themselves. I also found
the [official DDL
documentation](</posts/2024/04/reverse-engineering-an-attendance-clock-part-1/FKAttend User's Manual.pdf>),
but nothing else.
Since decompiling a library that even the creator didn't bother to implement
themselves is not something I'm willing to do, in the next article, we will try
to reverse-engineer the communication between the client and the device.