WhatPulse reverse engineered
This project consists of three parts:
-
Reverse engineering WhatPulse Client API protocol.
The reverse engineering has been done using mitmproxy. The captures can be found in caps directory. All results have been thoroughly documented in API.md.
-
Implementing the protocol as a Python library.
The implementation of the protocol in Python 3 can be found in whatpulse directory.
-
Making a replacement client for WhatPulse using the library.
The replacement client is called whatpulsed. An additional tool whatpulse_computerinfo comes with it. Both are described below in more detail.
WhatPulse officially forbids the use of any unofficial clients, including the Python library and the replacement client provided here. Use them at your own risk, being fully aware that your WhatPulse account may be suspended for doing so.
There are known cases of WhatPulse accounts being suspended for using the client software provided here. Given library attempts to imitate the official client as closely as possible to be undetectable but no such guarantee is given. Beware that mentioning your use of software provided here (e.g. in the issues of this repository) may also lead to suspension.
As a condition for use of the Website and Services, you agree not to use the Website or Services for the following 7. To fake statistics with the intention of achieving higher ranks or other rewards.
WhatPulse Knowledge Base - Are there any rules?:
You are also not allowed to use any external programs to generate fake statistics. Detection of this will get your account (and statistics) removed. Only the official WhatPulse clients are allowed for statistics generation.
Dependencies will be installed by pip
automatically. Manual installation is only required in case of problems.
- python-daemon - used for running in the background
- python-evdev - used for parsing input from
/dev/input/event*
- lxml - used for communicating with the XML API
- requests - used for communicating with the API
Install from project directory (where "setup.py" is) with
sudo pip3 install .
This program is a replacement for WhatPulse client: it counts keys, clicks; measures download, upload, uptime and pulses that information manually or automatically. The idea is to provide pulsing features similar to the official client in a lightweight form, without the GUI and fancy visual statistics. Since whatpulsed is coded in Python 3 it can be run on platforms unsupported by the official client, e.g. headless systems and other architectures (e.g. ARM on Raspberry Pi). Currently it only works on Linux.
- Create "whatpulsed.conf":
- Write it based on the file description below
or - Copy and modify the example
- Write it based on the file description below
- Run with
whatpulsed
in the same directory as "whatpulsed.conf" - Wait for "whatpulsed.json" to be created
- (optional) Remove plaintext login details from "whatpulsed.conf" by deleting
login
section
- Run with
whatpulsed
in the same directory as "whatpulsed.json" - Manually pulse by sending the process a
SIGUSR1
, e.g.pkill -USR1 whatpulsed
- Gracefully stop whatpulsed by sending the process a
SIGTERM
, e.g.pkill whatpulsed
This is the configuration file for whatpulsed. It is in INI format and has the following sections:
login
- WhatPulse login details (optional, only required when no state file "whatpulsed.json" exists)email
- WhatPulse login emailpassword
- WhatPulse login passwordcomputer
- computer name to log into
state
- state options (optional, but recommended)interval
(time) - state saving interval
interfaces
- network interfaces- list of interfaces to measure (no INI values), e.g.
eth0
- list of interfaces to measure (no INI values), e.g.
inputs
- evdev inputs- list of input devices to count (no INI values), e.g.
/dev/input/event2
- list of input devices to count (no INI values), e.g.
pulse
- automatic pulsing conditions (any satisfied condition pulses)keys
(general) - key count to pulse onclicks
(general) - click count to pulse ondownload
(size) - download amount to pulse onupload
(size) - upload amount to pulse onuptime
(time) - uptime to pulse on
Some values can be in converted format, allowing more human-readable values:
-
(general) - generic magnitude units
unit meaning value k kilo 1000 m mega 1000k g giga 1000m t tera 1000g e.g. 1m500k
means "1.5 million" -
(size) - base 2 magnitude units
unit meaning value k kibi 1024 m mebi 1024k g gibi 1024m t tebi 1024g e.g. 1g500m
means "1.5 gigabytes" -
(time) - time magnitude units
unit meaning value s second 1 m minute 60s h hour 60m d day 24h w week 7d y year 52w e.g. 3d7h10m
means "3 days, 7 hours and 10 minutes"
This is the state file for whatpulsed and is not meant to be directly manipulated. It is in JSON format and is structured as follows:
login
- logged in stateuserid
computerid
hash
token
stats
- unpulsed statskeys
clicks
download
upload
upime
This program allows uploading computer information (specs) to WhatPulse website for others to see without needing to install the official client. It allows manually specifying all supported information and uploading it via this simple script.
- Provide WhatPulse login details:
- Have "whatpulsed.json" as the result of running whatpulsed
or - Create "whatpulsed.conf" as described above (only
login
section is required)
- Have "whatpulsed.json" as the result of running whatpulsed
- Create "computerinfo.json":
- Write it based on the file description below
or - Copy and modify the example
- Write it based on the file description below
- Run with
whatpulse_computerinfo
in the same directory as "whatpulsed.json"/"whatpulsed.conf" and "computerinfo.json"
This is the computer info file for upload_computerinfo. It is in JSON format and is structured similarly to the JSON object used for upload_computerinfo request in the API:
{
"VideoInfo": "NVIDIA GeForce GT 440",
"TrackpadInfo": {},
"NetworkInfo":
{
"isNetworkMonitorSupported":
{
"isNetworkMonitorSupported": true
}
},
"CPUInfo": "Intel Core i5-2310",
"ComputerModel": "",
"ComputerOS": "Arch Linux",
"ComputerPlatform": "x86_64",
"KeyboardInfo": {},
"MemoryInfo": 5955,
"MonitorInfo":
{
"0":
{
"id": 0,
"width": 1920,
"height": 1080,
},
"1":
{
"id": 1,
"width": 1280,
"height": 1024,
}
},
"MouseInfo": {}
}
where the values are:
-
VideoInfo
- GPU name -
TrackpadInfo
- JSON object in unknown format, usually{}
-
NetworkInfo
- JSON object in the following format:{ "isNetworkMonitorSupported": { "isNetworkMonitorSupported": true }, "Intel 82540EM Gigabit": { "is_wifi": false, "description": "Intel 82540EM Gigabit" }, ... }
where network cards as keys have values:
is_wifi
- network card Wi-Fi abilitydescription
- network card name, same as key
-
CPUInfo
- CPU name -
ComputerModel
- computer model name, usually empty -
ComputerOS
- operating system name -
ComputerPlatform
- computer platform identifier, usuallyi686
orx86_64
-
KeyboardInfo
- JSON object in unknown format, usually{}
-
MemoryInfo
- RAM amount in megabytes -
MonitorInfo
- JSON object in the following format:{ "0": { "id": 0, "width": 1920, "height": 1080, }, ... }
where monitor IDs as keys have values:
id
- monitor ID, same as keywidth
- monitor widthheight
- monitor height
-
MouseInfo
- JSON object in unknown format, usually{}