Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support exporting Viber stickers #146

Open
2 of 4 tasks
laggykiller opened this issue Apr 20, 2024 · 3 comments
Open
2 of 4 tasks

Support exporting Viber stickers #146

laggykiller opened this issue Apr 20, 2024 · 3 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@laggykiller
Copy link
Owner

laggykiller commented Apr 20, 2024

Stem from #144

I have attempted to reverse engineer Viber Android app. To export Viber stickers, we need to get member_id and udid, which should be the same for each user but not sure where they could be obtained. Even worse, we need to get m_token, which is changed everytime when app is restarted, and I have no idea how I can automatically get it.

This is best attempt for exporting Viber sticker, which obviously won't work works if you obtain member_id, m_token and m_ts and fill in:

import requests

viber_version = "22.4.3.0"
user_agent = f"Mozilla/5.0 (Linux; Android 11; Android SDK built for x86 Build/RSR1.210210.001.A1; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36 Viber/{viber_version}"

# upload.zip: Zip file containing 490x490 png images to upload (00.png, 01.png, ...)
# color_icon.png: 120x120 png image
with open("upload.zip", "rb") as f, open("color_icon.png", "rb") as g:
    result = requests.post(
        "https://market.api.viber.com/2/users/custom-sticker-packs/create",
        files={
            "file": ("upload.zip", f),
            "file_icon": ("color_icon.png", g)
        },
        data={
            "member_id": "REDACTED",  # Same for each user
            "m_token": "REDACTED",  # Changed when app is restarted or after 13800seconds (230minutes)
            "m_ts": "1700000000000", # Unix timestamp with milisecond precision when m_token is generated (not when request is posted)
            "title": "my-custom-pack",
            "description": "My custom viber sticker pack",
            "shareable": "1",
            # "udid": "REDACTED",  # Same for each user  # Actually not necessary
            # "phone_country": "US",  # Actually not necessary
            # "mcc": "310",  # Mobile Country Codes, see https://mcc-mnc.com/  # Actually not necessary
            # "mnc": "260",  # Mobile Network Codes, see https://mcc-mnc.com/  # Actually not necessary
            # "vv": viber_version,  # Actually not necessary
            # "sid": "1",  # Actually not necessary
            # "lang": "en",  # Actually not necessary
            # "privacy_flags": "7",  # Actually not necessary
        },
        # headers={
        #     "User-Agent": user_agent # Actually not necessary
        # }
    )

    print(result.text)  # status should be 1 if success

If anyone want to reverse the Android app, I recommend using PCAPdroid on rooted Android emulator with mitm addon, with MagiskTrustUserCerts. Jadx decompilation might also be useful.

We can also analyze Windows version of Viber, but I am not familiar with it. What makes matter worse, Viber Windows start to store database with encrypted SQLCipher encryption using 128bit openssh private key(?) (Russian forum, use Google translate: https://4pda.to/forum/index.php?showtopic=714685&view=findpost&p=125818765), which means things like udid might be locked behind a database that is decrypted with unknown way.

If someone has solution, please comment / submit PR, thank you.


To do:

  • How to obtain member_id?
    • Located in viber.db in %appdata%/ViberPC/<phone_number>/viber.db table Contact column MID row with ContactID of 1
    • Unfortunately viber.db is encrypted with 128bit openssh private key(?) in Viber PC 19.4.0+
    • How to get encryption key for viber.db?
    • Alternative solution 1: Dump memory from Viber desktop app and find member_id, which I have proved to work. However dumping memory on different OS requires different method, and it is slow.
    • Alternative solution 2: Ask user to install Viber PC with version 19.3.0 or lower. However this will no longer work when Viber make those versions obsolete.
  • How to obtain m_token?
    • Seems like it is generated by resources/lib/<architecture>/libVoipEngineNative.so on Android, possibly generateSequence() +/- handleSecureTokenRequest() (?)
    • Seems like it is generated from communicating with some server (aloha46.viber.com followed by some random ip) using TCP, with communication encrypted by some way
  • How to obtain udid?
    • From decompiling Viber Android with jadx, udid seems to be generated by sources.com.viber.voip.registration.x3.a. Is udid still required if we create sticker pack from Viber PC?
    • Actually not necessary for uploading stickers, let's just ignore it
@laggykiller
Copy link
Owner Author

laggykiller commented Apr 20, 2024

From decompiling Viber Android with jadx, udid seems to be generated by sources.com.viber.voip.registration.x3.a

sources.com.viber.voip.registration.ActivationController is also interesting

EDIT: udid is actually not necessary

@laggykiller laggykiller added enhancement New feature or request help wanted Extra attention is needed labels Apr 20, 2024
@princo1415

This comment was marked as off-topic.

@laggykiller

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants