Skip to content

Instantly share code, notes, and snippets.

@yjwong
Last active January 18, 2026 14:23
Show Gist options
  • Select an option

  • Save yjwong/8893677b003f38559197ab55c2099ec2 to your computer and use it in GitHub Desktop.

Select an option

Save yjwong/8893677b003f38559197ab55c2099ec2 to your computer and use it in GitHub Desktop.
Lark client patch for Wayland

Version 7.59.12

The process to make this version work is similar to version 7.28.10. Simply modify /usr/share/applications/bytedance-lark.desktop, adding the --ozone-platform-hint=auto flag to the Exec line.

Set app_id

To fix this, look for this pattern in libframe.so at file offset 0x8c1bc8b (ui::XDGToplevelWrapperImpl::SetAppId):

80 7e 17 00 79 03 4d 8b 09

Replace with:

4c 8d 0d 1e 24 15 fa 90 90

This hardcodes the string lookup for SetAppId to the string bytedance-feishu.

To update it to bytedance-lark, go to offset 0x2d6f0b0, replacing the value:

62 79 74 65 64 61 6e 63 65 2d 66 65 69 73 68 75

With this:

62 79 74 65 64 61 6e 63 65 2d 6c 61 72 6b 00 00

Version 7.46.12

The process to make this version work is similar to version 7.28.10. Simply modify /usr/share/applications/bytedance-lark.desktop, adding the --ozone-platform-hint=auto flag to the Exec line.

Set app_id

The app_id patch has not been investigated for this version.

Version 7.42.17

The process to make this version work is similar to version 7.28.10. Simply modify /usr/share/applications/bytedance-lark.desktop, adding the --ozone-platform-hint=auto flag to the Exec line.

Set app_id

To fix this, look for this pattern in libframe.so (ui::XDGToplevelWrapperImpl::SetAppId):

55 48 89 e5 49 89 f1 48 8b 7f 20 80 7e 17 00 79 03 4d
8b 09

Replace with:

55 48 89 e5 49 89 f1 48 8b 7f 20 4c 8d 0d be b1 82 fa
90 90
                                 ^ Replacement starts here

This hardcodes the string lookup for SetAppId to the string bytedance-feishu.

To update it to bytedance-lark, go to offset 0x2a4ad70, replacing the value:

62 79 74 65 64 61 6e 63 65 2d 66 65 69 73 68 75

With this:

62 79 74 65 64 61 6e 63 65 2d 6c 61 72 6B

Version 7.36.11

The process to make this version work is similar to version 7.28.10. Simply modify /usr/share/applications/bytedance-lark.desktop, adding the --ozone-platform-hint=auto flag to the Exec line.

Set app_id

To fix this, look for this pattern in libframe.so (ui::XDGToplevelWrapperImpl::SetAppId):

55 48 89 e5 49 89 f1 48 8b 7f 20 80 7e 17 00 79 03 4d
8b 09

Replace with:

55 48 89 e5 49 89 f1 48 8b 7f 20 4c 8d 0d 0e 57 8b fa
90 90
                                 ^ Replacement starts here

This hardcodes the string lookup for SetAppId to the string bytedance-feishu.

To update it to bytedance-lark, go to offset 0x029fef30, replacing the value:

62 79 74 65 64 61 6e 63 65 2d 66 65 69 73 68 75

With this:

62 79 74 65 64 61 6e 63 65 2d 6c 61 72 6B

Version 7.28.10

As of version 7.28.10, Lark no longer crashes with SIGILL. In addition, the process of running in Wayland natively has been greatly simplified. It suffices to modify /usr/share/applications/bytedance-lark.desktop, adding the --ozone-platform-hint=auto flag to the Exec line.

However, the flag doesn't seem to propagate to the video meeting client, nor is app_id set correctly.

Unfortunately, it seems to be built on Chromium 121.0.6167.86. For Chinese text input to work, we probably need Chromium 129+ which adds the new --wayland-text-input-version=3 parameter. We will need to wait for ByteDance to update.

Set app_id

To fix this, look for this pattern in libframe.so (ui::XDGToplevelWrapperImpl::SetAppId):

55 48 89 e5 49 89 f1 48 8b 7f 20 80 7e 17 00 79 03 4d
8b 09

Replace with:

55 48 89 e5 49 89 f1 48 8b 7f 20 4c 8d 0d 1e c6 55 fa
90 90
                                 ^ Replacement starts here

This hardcodes the string lookup for SetAppId to the string bytedance-feishu.

To update it to bytedance-lark, go to offset 0x29c0c10, replacing the value:

62 79 74 65 64 61 6e 63 65 2d 66 65 69 73 68 75

With this:

62 79 74 65 64 61 6e 63 65 2d 6c 61 72 6B

Version 7.22.9

When running the Lark/Feishu client under Linux using the flags:

--ozone-platform-hint=wayland

As of version 7.22.9, It crashes with SIGILL.

Crash fix

To fix this, look for this pattern in libframe.so:

48 8b 05 53 26 b7 09 48 89 87 90 00 00 00

Replace the two bytes before the pattern with:

90 90

I have no idea why this code path is being taken. However, replacing the path with no-ops seems to have no visible side effects.

Start via Wayland by default

To start without needing a wrapper script or CLI option, look for this pattern in libframe.so:

55 48 89 e5 41 57 41 56 41 55 41 54 53 48 81 ec 58 01
00 00 64 48 8b 04 25 28 00 00 00 48 89 45 d0 44 8b 35
00 39 bb 0c

Replace the 5th byte onwards with:

b8 02 00 00 00 5d c3

This is equivalent to:

mov eax, 2
pop rbp
ret

There is some code path in the video meeting client that calls XGetWindowProperty even under Wayland, causing a crash like:

X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  20 (X_GetProperty)
  Resource id in failed request:  0x0
  Serial number of failed request:  104
  Current serial number in output stream:  104

To fix this, look for this pattern in libframe.so:

55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 38 48
89 7d d0 8a 05 15 8b f3 00 84 c0 0f 84 ca 00 00 00

Replace the 5th byte onwards with:

b8 03 00 00 00 48 89 ec 5d c3

This is equivalent to:

mov eax, 3
pop rbp
ret

This stubs the call to XGetWindowProperty, hardcoding its return value to 3 (BadWindow).

Set app_id

This is needed for the tray icon to be correct.

To fix this, look for this pattern in libframe.so (ui::XDGToplevelWrapperImpl::SetAppId):

55 48 89 e5 49 89 f1 48 8b 7f 20 80 7e 17 00 79
03 4d 8b 09 8b 4f 40 be 03 00 00 00 31 d2 45 31
c0 31 c0

Replace the bytes that come after with:

4c 8d 0d c6 17 7f fa 5d e9 20 ce 9c 03

This hardcodes the string lookup for SetAppId to 0x2e97b00, which is the string bytedance-feishu. This string appears to be unused anywhere else.

To update it to bytedance-lark, go to offset 0x2d97b00, replacing the value:

62 79 74 65 64 61 6e 63 65 2d 66 65 69 73 68 75

With this:

62 79 74 65 64 61 6e 63 65 2d 6c 61 72 6B

Known issues

  • There is instability.
    • Sometimes, when dragging text, the Lark client will crash entirely.
    • Sometimes, when joining meetings, the meeting client disappears.
  • Hover state can sometimes get broken.
  • Tooltip positions in the video meeting client can be wrong.
  • Pop-up subtitles window in the video meeting client can't be dragged. However, using the drag modifier on the keyboard (usually Alt) works.
  • Chinese IME doesn't work. However, this applies to all Electron-based apps (electron/electron#33662).

Appendix

The following is for my own reference:

  • Memory address to file offsets:
    • .text: subtract 0x7FFFE5A01000 from the memory address.
    • .data: subtract 0x7FFFE5A00000 from the memory address.
  • Lark 7.22.9 seems to be built on Chromium 109.0.5414.128. This is found by attaching a remote debugger and checking the navigator object.
#!/bin/bash
# Lark 7.59.12 - Set app_id patch
# Changes the Wayland app_id from "bytedance-feishu" to "bytedance-lark"
#
# This patch modifies libframe.so to:
# 1. Bypass the dynamic string lookup and use a hardcoded address
# 2. Change the string "bytedance-feishu" to "bytedance-lark"
set -euo pipefail
LIBFRAME="/opt/bytedance/lark/libframe.so"
BACKUP="${LIBFRAME}.bak"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
info() { echo -e "${GREEN}[INFO]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
# Check if running as root
if [[ $EUID -ne 0 ]]; then
error "This script must be run as root (try: sudo $0)"
fi
# Check if libframe.so exists
if [[ ! -f "$LIBFRAME" ]]; then
error "libframe.so not found at $LIBFRAME"
fi
# Verify Lark version
VERSION=$(dpkg -l bytedance-lark-stable 2>/dev/null | awk '/bytedance-lark-stable/ {print $3}' | cut -d'-' -f1)
if [[ "$VERSION" != "7.59.12" ]]; then
warn "This patch is designed for Lark 7.59.12, but you have version $VERSION"
read -p "Continue anyway? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
# Patch definitions
# Patch 1: Code modification at file offset 0x8c1bc8b
CODE_OFFSET=0x8c1bc8b
CODE_ORIGINAL="807e170079034d8b09"
CODE_PATCHED="4c8d0d1e2415fa9090"
# Patch 2: String modification at file offset 0x2d6f0b0
STRING_OFFSET=0x2d6f0b0
STRING_ORIGINAL="62797465 64616e63 652d6665 69736875" # bytedance-feishu
STRING_PATCHED="62797465 64616e63 652d6c61 726b0000" # bytedance-lark\0\0
# Remove spaces from hex strings
STRING_ORIGINAL="${STRING_ORIGINAL// /}"
STRING_PATCHED="${STRING_PATCHED// /}"
# Function to read hex bytes from file
read_hex() {
local file=$1
local offset=$2
local length=$3
xxd -s "$offset" -l "$length" -p "$file" | tr -d '\n'
}
# Function to verify bytes match expected
verify_bytes() {
local file=$1
local offset=$2
local expected=$3
local length=$((${#expected} / 2))
local actual
actual=$(read_hex "$file" "$offset" "$length")
if [[ "$actual" == "$expected" ]]; then
return 0
else
return 1
fi
}
# Function to patch bytes
patch_bytes() {
local file=$1
local offset=$2
local hex_bytes=$3
# Convert hex offset to decimal for dd
local decimal_offset=$((offset))
echo "$hex_bytes" | xxd -r -p | dd of="$file" bs=1 seek="$decimal_offset" conv=notrunc status=none
}
info "Checking current state of libframe.so..."
# Check if already patched
if verify_bytes "$LIBFRAME" "$CODE_OFFSET" "$CODE_PATCHED" && \
verify_bytes "$LIBFRAME" "$STRING_OFFSET" "$STRING_PATCHED"; then
info "libframe.so is already patched!"
exit 0
fi
# Verify original bytes are present
if ! verify_bytes "$LIBFRAME" "$CODE_OFFSET" "$CODE_ORIGINAL"; then
actual=$(read_hex "$LIBFRAME" "$CODE_OFFSET" 9)
error "Code bytes at offset $CODE_OFFSET don't match expected pattern.
Expected: $CODE_ORIGINAL
Actual: $actual
The binary may have been modified or this patch is not compatible."
fi
if ! verify_bytes "$LIBFRAME" "$STRING_OFFSET" "$STRING_ORIGINAL"; then
actual=$(read_hex "$LIBFRAME" "$STRING_OFFSET" 16)
error "String bytes at offset $STRING_OFFSET don't match expected pattern.
Expected: $STRING_ORIGINAL
Actual: $actual
The binary may have been modified or this patch is not compatible."
fi
info "Original bytes verified successfully."
# Create backup
if [[ ! -f "$BACKUP" ]]; then
info "Creating backup at $BACKUP..."
cp "$LIBFRAME" "$BACKUP"
else
warn "Backup already exists at $BACKUP, skipping backup creation."
fi
# Apply patches
info "Applying code patch at offset 0x$(printf '%x' $CODE_OFFSET)..."
patch_bytes "$LIBFRAME" "$CODE_OFFSET" "$CODE_PATCHED"
info "Applying string patch at offset 0x$(printf '%x' $STRING_OFFSET)..."
patch_bytes "$LIBFRAME" "$STRING_OFFSET" "$STRING_PATCHED"
# Verify patches were applied
if verify_bytes "$LIBFRAME" "$CODE_OFFSET" "$CODE_PATCHED" && \
verify_bytes "$LIBFRAME" "$STRING_OFFSET" "$STRING_PATCHED"; then
info "Patch applied successfully!"
info "The Wayland app_id is now 'bytedance-lark' instead of 'bytedance-feishu'."
echo
info "To restore the original file, run:"
echo " sudo cp '$BACKUP' '$LIBFRAME'"
else
error "Patch verification failed! Restoring backup..."
cp "$BACKUP" "$LIBFRAME"
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment