WhatPulse reverse engineered
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.
/dev/input/event*
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.
whatpulsed
in the same directory as "whatpulsed.conf"login
sectionwhatpulsed
in the same directory as "whatpulsed.json"SIGUSR1
, e.g. pkill -USR1 whatpulsed
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 intostate
- state options (optional, but recommended)
interval
(time) - state saving intervalinterfaces
- network interfaces
eth0
inputs
- evdev inputs
/dev/input/event2
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 onSome 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 state
userid
computerid
hash
token
stats
- unpulsed stats
keys
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.
login
section is required)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 keyCPUInfo
- CPU name
ComputerModel
- computer model name, usually empty
ComputerOS
- operating system name
ComputerPlatform
- computer platform identifier, usually i686
or x86_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 heightMouseInfo
- JSON object in unknown format, usually {}