Nokia Series 30+ backup recovery
Recover SMS messages and contacts from the .ib backup files written by Nokia feature phones running Series 30+ firmware.
The phone's built in backup tool creates a folder like All-backup_01-05-2017_00-01-25 containing:
ibphone_head.in
phonebook.ib
sms.ib
These files are not a database and they are not encrypted. They are flat dumps of the phone's internal record store, with fixed size records and plain UTF-16 text. This project decodes them and exports the content to CSV, TXT, HTML and vCard, with no third party dependencies.
What it does
- Parses
sms.ib, one record per stored message. - Detects incoming and outgoing messages.
- Decodes UCS-2 and GSM 03.38 bodies.
- Reassembles multipart messages using the concatenation UDH.
- Parses
phonebook.ib, including multiple numbers per contact and the two name fields. - Exports a phone style conversation browser grouped by contact.
- Reads the record table from the file header, so record counts and record sizes are not hard coded.
Tested on
A single Nokia TA-127B backup with 776 message records and 29 contacts. The same container layout is likely used by other Series 30+ devices, but other models and firmware revisions have not been verified. If the header values differ, pass --header-size and open an issue with the header bytes.
The format notes came from these threads, with several fields corrected and extended while working on the file above:
- Parsing/converting Nokia "Smart Feature OS" backup .ib files?
- Backup/access SMS on Nokia 3310 3g/2017 from Linux PC?
Install
Python 3.8 or newer. No dependencies.
git clone https://github.com/Tokisaki-Galaxy/nokia-ib-recovery.git
cd nokia-ib-recovery
pip install -e .
Using uv
The project is a standard pyproject.toml package, so uv needs no extra setup. Inside the checkout, uv run creates the environment and installs the project on first use:
uv run nokia-ib --help
uv run nokia-ib all "All-backup_01-05-2017_00-01-25" -o output
To run it from GitHub without cloning, use uvx:
uvx --from git+https://github.com/Tokisaki-Galaxy/nokia-ib-recovery.git nokia-ib --help
Or run it without installing at all:
python -m nokia_ib --help
Usage
Point the tool at the backup folder. It looks for sms.ib and phonebook.ib inside.
# Everything: messages, contacts and the conversation browser
nokia-ib all "All-backup_01-05-2017_00-01-25" -o output
# Messages only
nokia-ib sms "All-backup_01-05-2017_00-01-25" -o output
# Contacts only
nokia-ib contacts "All-backup_01-05-2017_00-01-25" -o output
# Conversation browser only
nokia-ib chat "All-backup_01-05-2017_00-01-25" -o output/chat.html
backup may also be the path to a single .ib file.
Example output:
messages: 659, received: 344, sent: 315
range: 2023-02-12 to 2025-08-16
contacts: 29, numbers: 33
written to output
Output files
| File | Contents |
|---|---|
sms.csv |
Time, direction, address, resolved name, text, part count, offset |
sms.txt |
Plain text log grouped by day |
sms.html |
Chronological message view with search |
contacts.csv |
Name, raw name fields, all numbers, matching message count |
contacts.txt |
Plain text contact list |
contacts.vcf |
vCard 3.0, importable on a phone |
contacts.html |
Searchable contact table |
chat.html |
Phone style conversation list and chat view, grouped by contact |
chat.html is a single self contained file. The sidebar lists conversations sorted by the last message, the search box filters on names and message text, and the layout collapses to a single column on narrow screens.
Custom names
Contacts are matched to messages by phone number. To override a name, pass a JSON file:
{
"8613800138000": "Alice",
"12345": "Family"
}
nokia-ib all backup/ --aliases aliases.json -o output
Notes on time
Two fields carry a timestamp and they disagree.
Incoming messages store the SMS centre timestamp inside the raw PDU. That value is used as is.
Outgoing messages store a seven byte binary timestamp whose first byte is the year offset from 1980. That value is also used as is.
Some records also contain a 32 bit Unix style timestamp near the start of the record. On the tested firmware it is exactly ten years early because the year was counted from 1980 but converted as if it started at 1970. The exporter ignores that field.
The backup folder name is not a reliable date either. A phone that lost power may name the folder with its default clock, which is why a backup full of 2023 messages can be called All-backup_01-05-2017_....
Limitations
- Deleted messages are not recoverable. The store is full and overwritten in place.
- Multipart reassembly relies on the concatenation UDH. Parts are matched by address, reference, total count and day.
- Messages with binary content, such as WAP pushes, are decoded as text and will look garbled.
- The phonebook name layout is inferred from one device. Contacts whose given name and family name are stored in separate fields are joined with the single character family name first.
- Only the fields listed in
docs/format.mdare decoded. Other parts of each record, such as the status flags and PDU leftovers, are ignored.
Privacy
Backups contain personal messages and phone numbers. The .gitignore in this repository excludes Backups/ and the default output folders so that real data is not committed by accident. Do not paste real .ib files, exported CSV files or screenshots of conversations into issues. When reporting a parsing problem, share only the header bytes and the offsets, or build a fake file with the same header values.
Development
python -m unittest discover -s tests -t .
The test suite builds synthetic sms.ib and phonebook.ib files, so it does not need real backup data.
Releasing
The version is derived from git tags by setuptools-scm. There is no version field in pyproject.toml.
One time setup on PyPI: add a pending publisher with these values.
| Field | Value |
|---|---|
| PyPI project name | nokia-ib-recovery |
| Owner | Tokisaki-Galaxy |
| Repository | nokia-ib-recovery |
| Workflow name | publish.yml |
| Environment | pypi |
No API token is needed. The workflow authenticates with OpenID Connect through the pypi environment.
To publish, push a tag that starts with v:
git tag v0.1.0
git push origin v0.1.0
The tag starts .github/workflows/publish.yml, which runs the tests, builds the sdist and the wheel, and uploads them to PyPI. Tags such as v0.1.0 and v0.2.0rc1 map to valid Python versions automatically. A build without any tag falls back to 0.0.0 and is not meant for release.
License
MIT. See LICENSE.
Metadata
Release files for nokia-ib-recovery 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| nokia_ib_recovery-0.1.0.tar.gz | 27.4 kB | With provenance | Details for nokia_ib_recovery-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| nokia_ib_recovery-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for nokia_ib_recovery-0.1.0-py3-none-any.whl |
Total release size: 47.4 kB
Release files / nokia_ib_recovery-0.1.0.tar.gz
| Download URL | nokia_ib_recovery-0.1.0.tar.gz |
|---|---|
| Size | 27.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
11229d24e0806e6347c63630a388696036f4258beb60bf9085816da492f96742
|
|
BLAKE2b-256 checksum How to use checksums |
4a583ab58e444dacb8e3c9870174e0005e255ce2cb4f9bb12fde813d4b9ca3cd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.
Transparency logRelease files / nokia_ib_recovery-0.1.0-py3-none-any.whl
| Download URL | nokia_ib_recovery-0.1.0-py3-none-any.whl |
|---|---|
| Size | 20.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2bb84e7469691e0f043bcf167a8132416c8dbf466977299ccf7bc85040cf4287
|
|
BLAKE2b-256 checksum How to use checksums |
bda74803386c37b1d32eae7162495ed6e97ede81d59e718692b012cc1f07226e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.
Transparency logSecurity for nokia-ib-recovery 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for nokia_ib_recovery-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.