Skip to main content

Reversing the EVBox ChargeStation Tool

Project – current | Article by Maarten Tromp | Published , updated | 1829 words.

This article covers the reverse engineering of the EVBox ChargeStation Tool, a software/hardware bundle for configuring EVBox G2, G3, and G3 HomeLine, BusinessLine, and PublicLine chargers.

The project and this article are work in progress. More information will be added as it becomes available.

Background

After writing an article about getting my charger to work without the EVBox backend, I started receiving emails with all kinds of questions about EVBox chargers, especially now that EVBox has more or less gone under. However, I am by no means an expert on the subject; I am simply a hobbyist tinkering with my own charger.

To configure chargers and ChargePoint modules in larger installations, EVBox provides the ChargeStation Tool (part number 471050). This software is supplied with a proprietary USB-to-RS-485 adapter. Several people asked me whether I had a copy of this software and whether it would work with a generic USB-to-RS-485 adapter, but all I had were a few screenshots. Eventually, the team at Borentik IDF kindly provided me with a copy of the software, which sparked my interest in the proprietary adapter. What makes this adapter so special? Let’s see if we can find out.

My initial thought was that the adapter would be an off-the-shelf USB-to-serial adapter with a modified Vendor ID and Product ID. For some adapters, this can be achieved as simply as adding an EEPROM with the desired values, which would make it relatively easy to replicate. The project would, of course, be much easier if I had an actual adapter to experiment with.

This is my first experience reverse engineering software, and I often feel out of my depth while searching for and fumbling with the various tools involved. This project is very much a learning process for me.

The software

The software I received is EV-Box ChargeStation Tool Zero, version 1.1.6.271 (32-bit) and version 1.1.6.272 (64-bit). The screenshots I already had are from EV-Box ChargeStation Tool version 1.1.1.360.

The most noticeable differences are that the later version includes "Zero" in the name. In addition, this version uses blue interface elements, whereas the older version uses green. It is unclear whether the later version is a "lite" variant or whether these changes simply reflect normal evolution over time.

Running under Wine

As a Linux user, I wondered whether the software would work under Wine. This also seemed like a good platform for logging and general experimentation. Somewhat to my surprise, the software ran without issues under Wine on the first attempt.

Enabling Wine logging (WINEDEBUG=hid) revealed that the software is looking for a USB HID device with Vendor ID 0x845e and Product IDs 0x0001 and 0x0002. This Vendor ID does not appear in any list of known vendors, which was in line with my expectations. At this stage, I did not yet know that this was unrelated to the actual VID and PID.

I also noticed that the software has a separate window for logging USB HID events. Combined with the Wine logging results, this indicates that the adapter presents itself as a HID device rather than as a serial port. This strongly suggests a microcontroller-based solution rather than an off-the-shelf adapter, which would make it much harder to replicate.

Based on these observations, I updated my hypothesis and now expect the adapter to have been developed by the same party as the charger and ChargePoint modules. Consequently, I expect solid hardware but somewhat questionable software, reusing the same microcontroller, protocol, and implementation as found in the other modules. Luckily, I have some experience with these.

Strings and hexdump

The next step is to search the binary for strings. Fortunately, it does not appear to be stripped. Here are some of the more interesting strings I came across:

Embarcadero Delphi for Win32 compiler version 35.0 (28.0.46141.0937)
C:\Users\leon\Downloads\jvcl-master\jvcl-master\jvcl\run\JvStringGrid.pas
HID.dll
Device_VID
Device_PID
Device_Serialnumber
DevVID
DevPID
DevSerialnumber
1234hoedjevanpapier
chargestation.exe
ev-box_chargestation_config.ini
SPS-130212

From this, we can conclude that the software is written in Embarcadero Delphi 11 (previously known as Borland Delphi for Win32), using the JEDI Visual Component Library (JVCL).

Many of the strings reference HID.dll method calls, primarily focusing on Vendor ID, Product ID, and device serial number. This reinforces the hypothesis that security is based on VID/PID/serial number and that the adapter uses USB HID rather than USB serial.

After searching for strings, I converted the code to a hex dump, but this did not yield any new insights.

Decompiling

Wouldn't it be great if we could recover the original Delphi source code from the compiled binary? For this purpose, I found IDR, the Interactive Delphi Reconstructor.

IDR only supports 32-bit executables, which is fortunately what we have. However, Delphi 11 proved to be too recent, as the reconstructor only supports versions up to Delphi 10.

Static analysis

Next, I turned to Ghidra. It was able to decompile the binary to C, which is much easier for me to read than x64 assembler. I started by examining calls to HID.dll and using its methods to identify functions and variables in the reconstructed code. ChatGPT also proved useful for identifying functions, function signatures, and for de-spaghettifying the code. There were very long variables and frequent use of offsets within them, but I assume that is typical for a Delphi binary.

After a while, I came across a function that compared the Vendor ID, Product ID, and device serial number against predetermined values. I then turned to a debugger to inspect these values at runtime.

In hindsight, I was so focused on the comparison function that I initially overlooked the function that called it — which is exactly where all the relevant values were stored in plain sight. But of course, everything is obvious in hindsight.

Dynamic analysis

Since the binary runs under Wine, I needed a debugger that would also work under Wine. Running Ghidra itself under Wine is not trivial, but fortunately there is x64dbg. It can set breakpoints and inspect memory, although it only displays assembler code. As instruction addresses line up with those in Ghidra, I ran both tools side by side.

I set a breakpoint on the comparison function and read the whitelisted values directly from memory. This revealed that the Vendor ID is 0x04d8 (Microchip), the Product ID is 0x003f, and the serial number is "SPS-130212". Later, I also found the Product String "EV-BOX USB-to-ChargeStation-LM" in Ghidra.

These values did not match those observed earlier while logging Wine HID activity, but I have more confidence in the values obtained here. The Vendor ID matches the PIC32 microcontroller I expected to be used, and the serial number appears to consist of the manufacturer name (Small Processor Systems) followed by a timestamp that aligns with the copyright year. At this point, I have enough information to build a compatible adapter.

Simulating an adapter

Raspberry Pi as USB device

How could I create a fully configurable and programmable USB device to simulate the adapter? I wanted a quick and easy solution, and something hacky would be perfectly acceptable for development. This would not be the final product, just a prototype. I have various development boards lying around, but did not want to go through the hassle of setting everything up. Ideally, it would be as simple as writing a Python script.

I did have a few Raspberry Pis and wondered whether they could be used. They seemed to tick all the boxes for rapid development and should have a USB OTG port. However, after spending hours experimenting with different Pi models and images, and reading large amounts of documentation, it turned out that none of my Raspberry Pis could actually do this.

Linux USB gadget

It had never occurred to me that a USB device could be implemented entirely in software rather than hardware. However, that turned out to be a much simpler solution: the Linux USB gadget API. This is a kernel interface for creating software-defined USB devices.

I had ChatGPT generate a Python script, and I now have a software-defined USB device with full control over what goes in and out. This also integrated well with the Wine-based approach, although Wine must be run as root so that USB devices can be passed through.

Within the ChargeStation software, the VID and PID checks passed, but the adapter serial number was always reported as 0x00000000, regardless of the value actually configured. This turned out to be a limitation of Wine, which only implements a subset of the USB/HID stack. I therefore used the debugger to bypass this check, after which the ChargeStation software happily accepted my virtual adapter.

When I press "Read ChargeStation", the adapter outputs: 02 38 30 46 44 45 42 37 39 30 44 03 ff. This is even better than I had hoped: it appears to be the Max protocol, which I had already reversed in a previous project.

And with this, the HID reversing is complete.

Connecting a generic serial adapter

Next, I connected a generic USB-to-RS-485 adapter to the virtual adapter and forwarded all traffic between the two. The virtual adapter acts as a bridge (a man-in-the-middle), rewriting data from the generic adapter so that it works with the ChargeStation software.

There were a few details that needed tweaking. The ChargeStation software only functions correctly when USB reports are aligned with protocol frames, and when those frames contain no invalid values. As a result, the adapter buffers each incoming frame and filters out invalid ones. Aside from this, the adapter acts as a simple, transparent bridge.

With these changes in place, the virtual adapter worked a treat, and I am now able to read from and write to ChargePoint and ChargeBox devices using the ChargeStation software with a generic adapter. Milestone reached! I have updated the Max protocol documentation with the newly discovered information.

This solution is free of charge, but it does require some Linux experience to set up.

Building a physical adapter

Next up is building a physical adapter so that the ChargeStation software can run on a stock computer. My first impulse was, of course, to design a circuit board from scratch. This would involve a significant amount of development effort. In addition, selling counterfeit adapters from my website seemed like a bad idea. Let’s see what can be built using commonly available hardware instead.

The simplest and cheapest solution I could come up with is a Raspberry Pi Pico combined with a WaveShare RS-485 module. This comes to around 15 euros delivered and should be easy to flash. I have just ordered a pair.

This solution costs a small amount of money, and requires some electronics experience, but it works with a stock computer.

Patching the ChargeStation software

An alternative approach would be to modify the ChargeStation software so that it accepts a generic adapter. This would be the easiest solution for the user, but the most difficult for me. In addition, the patching process would need to be repeated each time a new software version is released.

Open source

Everything in this project is done using free and open source software and hardware where possible.

In turn, the software, article, and documentation for this project are released into the public domain. You can find relevant files in the downloads directory of this article.

Exception to this is anything I didn't create myself, since it's not mine to give away. This includes the EVBox software and protocol, which obviously remain subject to the original licenses and copyrights.